171 lines
5.2 KiB
Python
171 lines
5.2 KiB
Python
#!/usr/bin/python
|
|
"""
|
|
Scyther : An automatic verifier for security protocols.
|
|
Copyright (C) 2007-2013 Cas Cremers
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License
|
|
as published by the Free Software Foundation; either version 2
|
|
of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
"""
|
|
|
|
|
|
#---------------------------------------------------------------------------
|
|
|
|
""" Import externals """
|
|
import wx
|
|
import os
|
|
import sys
|
|
from subprocess import Popen, PIPE
|
|
|
|
#---------------------------------------------------------------------------
|
|
|
|
""" Import scyther components """
|
|
from Scyther import Misc as MiscScyther
|
|
from Scyther import FindDot
|
|
|
|
""" Import scyther-gui components """
|
|
from . import Temporary
|
|
from . import Preference
|
|
|
|
#---------------------------------------------------------------------------
|
|
try:
|
|
import Image
|
|
except ImportError:
|
|
pass
|
|
#---------------------------------------------------------------------------
|
|
|
|
|
|
def writeGraph(attackthread,txt,fp):
|
|
|
|
EDGE = 0
|
|
NODE = 1
|
|
DEFAULT = 2
|
|
ALL = 3
|
|
|
|
def graphLine(txt):
|
|
fp.write(("\t%s;\n" % (txt)).encode('utf-8'))
|
|
|
|
def setAttr(atxt,EdgeNodeDefAll=ALL):
|
|
if EdgeNodeDefAll == ALL:
|
|
setAttr(atxt,EDGE)
|
|
setAttr(atxt,NODE)
|
|
setAttr(atxt,DEFAULT)
|
|
else:
|
|
if EdgeNodeDefAll == EDGE:
|
|
edge = "edge"
|
|
elif EdgeNodeDefAll == NODE:
|
|
edge = "node"
|
|
else:
|
|
graphLine("%s" % atxt)
|
|
return
|
|
graphLine("%s [%s]" % (edge,atxt))
|
|
|
|
if sys.platform.startswith("darwin"):
|
|
attackthread.fontname = "Helvetica"
|
|
elif sys.platform.startswith("win"):
|
|
attackthread.fontname = "Courier"
|
|
else:
|
|
#font = wx.Font(9,wx.SWISS,wx.NORMAL,wx.NORMAL)
|
|
#attackthread.fontname = font.GetFaceName()
|
|
attackthread.fontname = "\"Helvetica\""
|
|
|
|
# write all graph lines but add layout modifiers
|
|
for l in txt.splitlines():
|
|
fp.write(l.encode('utf-8'))
|
|
if l.startswith("digraph"):
|
|
# Write additional stuff for this graph
|
|
#
|
|
# [CC][x] This dpi setting messed up quite a bit
|
|
#graphLine("dpi=96")
|
|
graphLine("rankdir=TB")
|
|
#graphLine("nodesep=0.1")
|
|
#graphLine("ranksep=0.001")
|
|
#graphLine("mindist=0.1")
|
|
|
|
# Set fontname
|
|
if attackthread.fontname:
|
|
fontstring = "fontname=%s" % (attackthread.fontname)
|
|
setAttr(fontstring)
|
|
|
|
# Stupid Mac <> Graphviz bug fix
|
|
if (sys.platform.startswith("mac")) or (sys.platform.startswith("darwin")):
|
|
# Note that dot on Mac cannot find the fonts by default,
|
|
# and we have to set them accordingly.
|
|
os.environ["DOTFONTPATH"]="~/Library/Fonts:/Library/Fonts:/System/Library/Fonts"
|
|
|
|
# Select font size
|
|
if attackthread.parent and attackthread.parent.mainwin:
|
|
fontsize = attackthread.parent.mainwin.settings.fontsize
|
|
setAttr("fontsize=%s" % fontsize)
|
|
#setAttr("height=\"0.1\"",NODE)
|
|
#setAttr("width=\"1.0\"",NODE)
|
|
#setAttr("margin=\"0.3,0.03\"",NODE)
|
|
|
|
|
|
def makeImageDot(dotdata,attackthread=None):
|
|
""" create image for this particular dot data """
|
|
|
|
if Preference.usePIL():
|
|
# If we have the PIL library, we can do postscript! great
|
|
# stuff.
|
|
imgtype = "ps"
|
|
ext = ".ps"
|
|
else:
|
|
# Ye olde pnge file
|
|
imgtype = "png"
|
|
ext = ".png"
|
|
|
|
# Write dot source file into temporary file to simplify dealing with graphviz invocation across platforms
|
|
(fd_in,fpname_in) = Temporary.tempcleaned(ext)
|
|
f_in = os.fdopen(fd_in,'w')
|
|
if attackthread:
|
|
writeGraph(attackthread,dotdata,f_in)
|
|
else:
|
|
f_in.write(dotdata)
|
|
f_in.close()
|
|
|
|
# Set up command
|
|
dotcommand = FindDot.findDot()
|
|
cmd = [dotcommand, "-T" + imgtype, fpname_in]
|
|
|
|
# execute command
|
|
(fd_out,fpname_out) = Temporary.tempcleaned(ext)
|
|
p = Popen(cmd, stdout=fd_out)
|
|
p.wait()
|
|
|
|
return (fpname_out, imgtype)
|
|
|
|
|
|
def makeImage(attack,attackthread=None):
|
|
""" create image for this particular attack """
|
|
|
|
""" This should clearly be a method of 'attack' """
|
|
|
|
(name,imgtype) = makeImageDot(attack.scytherDot,attackthread)
|
|
# if this is done, store and report
|
|
attack.file = name
|
|
attack.filetype = imgtype
|
|
|
|
|
|
def testImage():
|
|
"""
|
|
We generate a postscript file from a dot file, and see what happens.
|
|
"""
|
|
|
|
dotdata = "digraph X {\nA->B;\n}\n"
|
|
(filename,filetype) = makeImageDot(dotdata)
|
|
testimage = Image.open(filename)
|
|
|
|
#---------------------------------------------------------------------------
|
|
# vim: set ts=4 sw=4 et list lcs=tab\:>-:
|