scyther/gui/Gui/Makeimage.py
2020-10-27 23:38:48 +01:00

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\:>-: