- Big catchup commit to make sure we are up to beta7.
This includes a number of single patches, ranging from the vista fix with the buffers, to the start of many new minor features.
This commit is contained in:
parent
5882548643
commit
1542d65def
1
gui/.gitignore
vendored
Normal file
1
gui/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.pyc
|
@ -11,6 +11,8 @@ import os.path
|
|||||||
|
|
||||||
""" Import scyther-gui components """
|
""" Import scyther-gui components """
|
||||||
|
|
||||||
|
import Scyther
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
""" Globals """
|
""" Globals """
|
||||||
@ -19,9 +21,17 @@ basedir = ""
|
|||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def setBaseDir(mybasedir):
|
||||||
|
global basedir
|
||||||
|
|
||||||
|
basedir = mybasedir
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
class AboutScyther(wx.Dialog):
|
class AboutScyther(wx.Dialog):
|
||||||
def __init__(self,parent,mybasedir=None):
|
def __init__(self,parent,mybasedir=None):
|
||||||
|
|
||||||
|
from Version import SCYTHER_GUI_VERSION
|
||||||
global basedir
|
global basedir
|
||||||
|
|
||||||
self.text = '''
|
self.text = '''
|
||||||
@ -29,6 +39,7 @@ class AboutScyther(wx.Dialog):
|
|||||||
<body bgcolor="#ffffff">
|
<body bgcolor="#ffffff">
|
||||||
<img src="$SPLASH">
|
<img src="$SPLASH">
|
||||||
<p align="right"><b>Scyther : $VERSION</b></p>
|
<p align="right"><b>Scyther : $VERSION</b></p>
|
||||||
|
<small>
|
||||||
<p>
|
<p>
|
||||||
<b>Scyther</b> is an automatic tool for the verification and
|
<b>Scyther</b> is an automatic tool for the verification and
|
||||||
falsification of security protocols.
|
falsification of security protocols.
|
||||||
@ -42,21 +53,31 @@ class AboutScyther(wx.Dialog):
|
|||||||
<a target="_blank" href="http://people.inf.ethz.ch/cremersc/scyther/index.html">
|
<a target="_blank" href="http://people.inf.ethz.ch/cremersc/scyther/index.html">
|
||||||
http://people.inf.ethz.ch/cremersc/scyther/index.html</a>
|
http://people.inf.ethz.ch/cremersc/scyther/index.html</a>
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
$DETAILS
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Credits: Cas Cremers (Scyther theory, backend, and main GUI
|
Credits: Cas Cremers (Scyther theory, backend, and main GUI
|
||||||
code), Gijs Hollestelle (Python parser for Scyther XML output).
|
code), Gijs Hollestelle (Python parser for Scyther XML output).
|
||||||
</p>
|
</p>
|
||||||
|
</small>
|
||||||
'''
|
'''
|
||||||
|
|
||||||
if mybasedir:
|
if mybasedir:
|
||||||
basedir = mybasedir
|
basedir = mybasedir
|
||||||
|
|
||||||
|
# Debugging output of some parameters
|
||||||
|
|
||||||
splashdir = os.path.join(basedir,"Images")
|
splashdir = os.path.join(basedir,"Images")
|
||||||
splashimage = os.path.join(splashdir,"scyther-splash.png")
|
splashimage = os.path.join(splashdir,"scyther-splash.png")
|
||||||
|
details_html = "Base directory: %s<br>\n" % (basedir)
|
||||||
|
details_html += Scyther.Scyther.GetInfo(html=True)
|
||||||
|
|
||||||
self.text = self.text.replace("$SPLASH",splashimage)
|
self.text = self.text.replace("$SPLASH",splashimage)
|
||||||
|
self.text = self.text.replace("$DETAILS",details_html)
|
||||||
|
|
||||||
# version information
|
# version information
|
||||||
self.text = self.text.replace("$VERSION", "1.0-beta6")
|
self.text = self.text.replace("$VERSION", SCYTHER_GUI_VERSION)
|
||||||
|
|
||||||
wx.Dialog.__init__(self, parent, -1, 'About Scyther',
|
wx.Dialog.__init__(self, parent, -1, 'About Scyther',
|
||||||
size=(660,620))
|
size=(660,620))
|
||||||
|
@ -183,6 +183,7 @@ class AttackWindow(wx.Frame):
|
|||||||
# Add attacks (possible with tabs)
|
# Add attacks (possible with tabs)
|
||||||
self.displays=[]
|
self.displays=[]
|
||||||
attacks = self.claim.attacks
|
attacks = self.claim.attacks
|
||||||
|
|
||||||
n = len(attacks)
|
n = len(attacks)
|
||||||
if n <= 1:
|
if n <= 1:
|
||||||
# Just a single window
|
# Just a single window
|
||||||
|
@ -71,10 +71,35 @@ class Editor(object):
|
|||||||
def __init__(self, parent):
|
def __init__(self, parent):
|
||||||
# Empty start
|
# Empty start
|
||||||
self.SetText("")
|
self.SetText("")
|
||||||
|
self.SetChanged(False)
|
||||||
|
|
||||||
|
def SetText(self):
|
||||||
|
pass
|
||||||
|
|
||||||
def SetErrors(self,errors):
|
def SetErrors(self,errors):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def GetChanged(self):
|
||||||
|
"""
|
||||||
|
Return true if file was changed
|
||||||
|
"""
|
||||||
|
return self.savedtext != self.GetText()
|
||||||
|
|
||||||
|
def SetChanged(self,nowchanged=False):
|
||||||
|
"""
|
||||||
|
Set changed status
|
||||||
|
"""
|
||||||
|
if nowchanged:
|
||||||
|
self.savedtext = ""
|
||||||
|
else:
|
||||||
|
self.SetSaved()
|
||||||
|
|
||||||
|
def SetSaved(self):
|
||||||
|
self.savedtext = self.GetText()
|
||||||
|
|
||||||
|
def SetOpened(self):
|
||||||
|
self.SetSaved()
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
class EditorNormal(Editor):
|
class EditorNormal(Editor):
|
||||||
|
@ -20,7 +20,7 @@ import Editor
|
|||||||
""" Some constants """
|
""" Some constants """
|
||||||
ID_VERIFY = 100
|
ID_VERIFY = 100
|
||||||
ID_AUTOVERIFY = 101
|
ID_AUTOVERIFY = 101
|
||||||
ID_STATESPACE = 102
|
ID_CHARACTERIZE = 102
|
||||||
ID_CHECK = 103
|
ID_CHECK = 103
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@ -47,7 +47,7 @@ class MainWindow(wx.Frame):
|
|||||||
if len(args) > 0:
|
if len(args) > 0:
|
||||||
filename = args[0]
|
filename = args[0]
|
||||||
if filename != '' and os.path.isfile(filename):
|
if filename != '' and os.path.isfile(filename):
|
||||||
self.filename = filename
|
(self.dirname,self.filename) = os.path.split(filename)
|
||||||
self.load = True
|
self.load = True
|
||||||
|
|
||||||
Icon.ScytherIcon(self)
|
Icon.ScytherIcon(self)
|
||||||
@ -60,7 +60,7 @@ class MainWindow(wx.Frame):
|
|||||||
(wx.ACCEL_NORMAL, wx.WXK_F1,
|
(wx.ACCEL_NORMAL, wx.WXK_F1,
|
||||||
ID_VERIFY),
|
ID_VERIFY),
|
||||||
(wx.ACCEL_NORMAL, wx.WXK_F2,
|
(wx.ACCEL_NORMAL, wx.WXK_F2,
|
||||||
ID_STATESPACE),
|
ID_CHARACTERIZE),
|
||||||
(wx.ACCEL_NORMAL, wx.WXK_F5,
|
(wx.ACCEL_NORMAL, wx.WXK_F5,
|
||||||
ID_CHECK),
|
ID_CHECK),
|
||||||
(wx.ACCEL_NORMAL, wx.WXK_F6,
|
(wx.ACCEL_NORMAL, wx.WXK_F6,
|
||||||
@ -85,9 +85,9 @@ class MainWindow(wx.Frame):
|
|||||||
#bt = wx.Button(self,ID_VERIFY)
|
#bt = wx.Button(self,ID_VERIFY)
|
||||||
#buttons.Add(bt,0)
|
#buttons.Add(bt,0)
|
||||||
#self.Bind(wx.EVT_BUTTON, self.OnVerify, bt)
|
#self.Bind(wx.EVT_BUTTON, self.OnVerify, bt)
|
||||||
#bt = wx.Button(self,ID_STATESPACE)
|
#bt = wx.Button(self,ID_CHARACTERIZE)
|
||||||
#buttons.Add(bt,0)
|
#buttons.Add(bt,0)
|
||||||
#self.Bind(wx.EVT_BUTTON, self.OnStatespace, bt)
|
#self.Bind(wx.EVT_BUTTON, self.OnCharacterize, bt)
|
||||||
#sizer.Add(buttons, 0, wx.ALIGN_LEFT)
|
#sizer.Add(buttons, 0, wx.ALIGN_LEFT)
|
||||||
|
|
||||||
# Top: input
|
# Top: input
|
||||||
@ -98,8 +98,11 @@ class MainWindow(wx.Frame):
|
|||||||
if self.load:
|
if self.load:
|
||||||
textfile = open(os.path.join(self.dirname, self.filename), 'r')
|
textfile = open(os.path.join(self.dirname, self.filename), 'r')
|
||||||
self.editor.SetText(textfile.read())
|
self.editor.SetText(textfile.read())
|
||||||
|
if self.dirname != "":
|
||||||
os.chdir(self.dirname)
|
os.chdir(self.dirname)
|
||||||
textfile.close()
|
textfile.close()
|
||||||
|
self.editor.SetOpened()
|
||||||
|
|
||||||
self.top.AddPage(self.editor.control,"Protocol description")
|
self.top.AddPage(self.editor.control,"Protocol description")
|
||||||
self.settings = Settingswindow.SettingsWindow(self.top,self)
|
self.settings = Settingswindow.SettingsWindow(self.top,self)
|
||||||
self.top.AddPage(self.settings,"Settings")
|
self.top.AddPage(self.settings,"Settings")
|
||||||
@ -138,8 +141,8 @@ class MainWindow(wx.Frame):
|
|||||||
self.CreateMenu(menuBar, '&Verify',
|
self.CreateMenu(menuBar, '&Verify',
|
||||||
[(ID_VERIFY, '&Verify protocol\tF1','Verify the protocol in the buffer using Scyther',
|
[(ID_VERIFY, '&Verify protocol\tF1','Verify the protocol in the buffer using Scyther',
|
||||||
self.OnVerify) ,
|
self.OnVerify) ,
|
||||||
(ID_STATESPACE, 'Generate &statespace\tF2','TODO' ,
|
(ID_CHARACTERIZE, '&Characterize roles\tF2','TODO' ,
|
||||||
self.OnStatespace) ,
|
self.OnCharacterize) ,
|
||||||
(None, None, None, None),
|
(None, None, None, None),
|
||||||
### Disabled for now (given that it is not reliable enough yet)
|
### Disabled for now (given that it is not reliable enough yet)
|
||||||
#(ID_CHECK, '&Check protocol\tF5','TODO',
|
#(ID_CHECK, '&Check protocol\tF5','TODO',
|
||||||
@ -179,7 +182,49 @@ class MainWindow(wx.Frame):
|
|||||||
dialog.Destroy()
|
dialog.Destroy()
|
||||||
return userProvidedFilename
|
return userProvidedFilename
|
||||||
|
|
||||||
# Event handlers:
|
# Are we dropping a changed file?
|
||||||
|
|
||||||
|
def ConfirmLoss(self,text=None):
|
||||||
|
"""
|
||||||
|
Try to drop the current file. If it was changed, try to save
|
||||||
|
(as)
|
||||||
|
|
||||||
|
Returns true after the user seems to be happy either way, false
|
||||||
|
if we need to cancel this.
|
||||||
|
"""
|
||||||
|
if self.editor.GetChanged():
|
||||||
|
# File changed, we need to confirm this
|
||||||
|
title = "Unsaved changes"
|
||||||
|
if text:
|
||||||
|
title = "%s - " + title
|
||||||
|
txt = "The protocol file '%s' has been modified.\n\n" % (self.filename)
|
||||||
|
txt = txt + "Do you want to"
|
||||||
|
txt = txt + " save your changes (Yes)"
|
||||||
|
txt = txt + " or"
|
||||||
|
txt = txt + " discard them (No)"
|
||||||
|
txt = txt + "?"
|
||||||
|
dialog = wx.MessageDialog(self,txt,title,wx.YES_NO | wx.CANCEL | wx.ICON_EXCLAMATION)
|
||||||
|
result = dialog.ShowModal()
|
||||||
|
dialog.Destroy()
|
||||||
|
if result == wx.ID_NO:
|
||||||
|
# Drop changes
|
||||||
|
return True
|
||||||
|
elif result == wx.ID_YES:
|
||||||
|
# First save(as)!
|
||||||
|
if self.OnSaveAs(None):
|
||||||
|
# Succeeded, we can continue with the operation
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
# Save did not succeed
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# Assume cancel (wx.ID_CANCEL) otherwise
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
# File was not changed, so we can just proceed
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Event handlers
|
||||||
|
|
||||||
def OnAbout(self, event):
|
def OnAbout(self, event):
|
||||||
dlg = About.AboutScyther(self)
|
dlg = About.AboutScyther(self)
|
||||||
@ -187,25 +232,36 @@ class MainWindow(wx.Frame):
|
|||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
|
|
||||||
def OnExit(self, event):
|
def OnExit(self, event):
|
||||||
|
if self.ConfirmLoss("Exit"):
|
||||||
self.Close() # Close the main window.
|
self.Close() # Close the main window.
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def OnSave(self, event):
|
def OnSave(self, event):
|
||||||
textfile = open(os.path.join(self.dirname, self.filename), 'w')
|
textfile = open(os.path.join(self.dirname, self.filename), 'w')
|
||||||
textfile.write(self.editor.GetText())
|
textfile.write(self.editor.GetText())
|
||||||
textfile.close()
|
textfile.close()
|
||||||
|
self.editor.SetSaved()
|
||||||
|
return True
|
||||||
|
|
||||||
def OnOpen(self, event):
|
def OnOpen(self, event):
|
||||||
|
if self.ConfirmLoss("Open"):
|
||||||
if self.askUserForFilename(style=wx.OPEN,
|
if self.askUserForFilename(style=wx.OPEN,
|
||||||
**self.defaultFileDialogOptions()):
|
**self.defaultFileDialogOptions()):
|
||||||
textfile = open(os.path.join(self.dirname, self.filename), 'r')
|
textfile = open(os.path.join(self.dirname, self.filename), 'r')
|
||||||
self.editor.SetText(textfile.read())
|
self.editor.SetText(textfile.read())
|
||||||
textfile.close()
|
textfile.close()
|
||||||
|
self.editor.SetOpened()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def OnSaveAs(self, event):
|
def OnSaveAs(self, event):
|
||||||
if self.askUserForFilename(defaultFile=self.filename, style=wx.SAVE,
|
if self.askUserForFilename(defaultFile=self.filename, style=wx.SAVE,
|
||||||
**self.defaultFileDialogOptions()):
|
**self.defaultFileDialogOptions()):
|
||||||
self.OnSave(event)
|
self.OnSave(event)
|
||||||
os.chdir(self.dirname)
|
os.chdir(self.dirname)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def RunScyther(self, mode):
|
def RunScyther(self, mode):
|
||||||
# Clear errors before verification
|
# Clear errors before verification
|
||||||
@ -220,8 +276,8 @@ class MainWindow(wx.Frame):
|
|||||||
def OnAutoVerify(self, event):
|
def OnAutoVerify(self, event):
|
||||||
self.RunScyther("autoverify")
|
self.RunScyther("autoverify")
|
||||||
|
|
||||||
def OnStatespace(self, event):
|
def OnCharacterize(self, event):
|
||||||
self.RunScyther("statespace")
|
self.RunScyther("characterize")
|
||||||
|
|
||||||
def OnCheck(self, event):
|
def OnCheck(self, event):
|
||||||
self.RunScyther("check")
|
self.RunScyther("check")
|
||||||
|
@ -34,11 +34,12 @@ class ScytherThread(threading.Thread):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Override Thread's __init__ method to accept the parameters needed:
|
# Override Thread's __init__ method to accept the parameters needed:
|
||||||
def __init__ ( self, spdl, options="", callback=None ):
|
def __init__ ( self, spdl, options="", callback=None, mode=None ):
|
||||||
|
|
||||||
self.spdl = spdl
|
self.spdl = spdl
|
||||||
self.options = options
|
self.options = options
|
||||||
self.callback = callback
|
self.callback = callback
|
||||||
|
self.mode = mode
|
||||||
threading.Thread.__init__ ( self )
|
threading.Thread.__init__ ( self )
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
@ -49,6 +50,17 @@ class ScytherThread(threading.Thread):
|
|||||||
if self.callback:
|
if self.callback:
|
||||||
wx.CallAfter(self.callback, scyther, claims, summary)
|
wx.CallAfter(self.callback, scyther, claims, summary)
|
||||||
|
|
||||||
|
def claimFixViewOne(self,claims):
|
||||||
|
if claims:
|
||||||
|
for cl in claims:
|
||||||
|
if len(cl.attacks) > 1:
|
||||||
|
# Fix it such that by default, only the best attack is
|
||||||
|
# shown, unless we are in characterize or check mode
|
||||||
|
# TODO [X] [CC] make switch-dependant.
|
||||||
|
if not self.mode in ["characterize","check"]:
|
||||||
|
cl.attacks = [cl.attacks[-1]]
|
||||||
|
|
||||||
|
return claims
|
||||||
|
|
||||||
def claimResults(self):
|
def claimResults(self):
|
||||||
""" Convert spdl to result (using Scyther)
|
""" Convert spdl to result (using Scyther)
|
||||||
@ -68,6 +80,8 @@ class ScytherThread(threading.Thread):
|
|||||||
|
|
||||||
summary = str(scyther)
|
summary = str(scyther)
|
||||||
|
|
||||||
|
claims = self.claimFixViewOne(claims)
|
||||||
|
|
||||||
return (scyther, claims, summary)
|
return (scyther, claims, summary)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
@ -123,6 +137,7 @@ class AttackThread(threading.Thread):
|
|||||||
|
|
||||||
def graphLine(txt):
|
def graphLine(txt):
|
||||||
fp.write("\t%s;\n" % (txt))
|
fp.write("\t%s;\n" % (txt))
|
||||||
|
print txt # DEBUG ONLY
|
||||||
|
|
||||||
def setAttr(atxt,EdgeNodeDefAll=ALL):
|
def setAttr(atxt,EdgeNodeDefAll=ALL):
|
||||||
if EdgeNodeDefAll == ALL:
|
if EdgeNodeDefAll == ALL:
|
||||||
@ -139,6 +154,13 @@ class AttackThread(threading.Thread):
|
|||||||
return
|
return
|
||||||
graphLine("%s [%s]" % (edge,atxt))
|
graphLine("%s [%s]" % (edge,atxt))
|
||||||
|
|
||||||
|
# Precompute font name
|
||||||
|
# Set a font with sans
|
||||||
|
# We only retrieve the name, so the size '9' here is
|
||||||
|
# irrelevant.
|
||||||
|
font = wx.Font(9,wx.SWISS,wx.NORMAL,wx.NORMAL)
|
||||||
|
self.fontname = font.GetFaceName()
|
||||||
|
|
||||||
# write all graph lines but add layout modifiers
|
# write all graph lines but add layout modifiers
|
||||||
for l in txt.splitlines():
|
for l in txt.splitlines():
|
||||||
fp.write(l)
|
fp.write(l)
|
||||||
@ -151,23 +173,22 @@ class AttackThread(threading.Thread):
|
|||||||
#graphLine("nodesep=0.1")
|
#graphLine("nodesep=0.1")
|
||||||
#graphLine("ranksep=0.001")
|
#graphLine("ranksep=0.001")
|
||||||
#graphLine("mindist=0.1")
|
#graphLine("mindist=0.1")
|
||||||
if sys.platform.startswith("lin"):
|
|
||||||
# For Linux, choose Helvetica
|
# Set fontname
|
||||||
# TODO
|
fontstring = "fontname=%s" % (self.fontname)
|
||||||
# This is really a Mac font so it might not be
|
setAttr(fontstring,EDGE)
|
||||||
# available. Still, it works better on my Ubuntu
|
|
||||||
# than Verdana, and finding a good sans default for
|
# Stupid Mac <> Graphviz bug fix
|
||||||
# linux seems problematic.
|
if (sys.platform.startswith("mac")) or (sys.platform.startswith("darwin")):
|
||||||
setAttr("fontname=\"Helvetica\"")
|
# Note that dot on Mac cannot find the fonts by default,
|
||||||
if sys.platform.startswith("mac"):
|
# and we have to set them accordingly.
|
||||||
# For Mac choose Helvetica
|
os.environ["DOTFONTPATH"]="~/Library/Fonts:/Library/Fonts:/System/Library/Fonts"
|
||||||
setAttr("fontname=\"Helvetica\"")
|
|
||||||
if sys.platform.startswith("win"):
|
# Select font size
|
||||||
# For Windows choose Verdana
|
|
||||||
setAttr("fontname=\"Verdana\"")
|
|
||||||
if self.parent and self.parent.mainwin:
|
if self.parent and self.parent.mainwin:
|
||||||
fontsize = self.parent.mainwin.settings.fontsize
|
fontsize = self.parent.mainwin.settings.fontsize
|
||||||
setAttr("fontsize=%s" % fontsize)
|
setAttr("fontsize=%s" % fontsize)
|
||||||
|
|
||||||
#setAttr("height=\"0.1\"",NODE)
|
#setAttr("height=\"0.1\"",NODE)
|
||||||
#setAttr("width=\"1.0\"",NODE)
|
#setAttr("width=\"1.0\"",NODE)
|
||||||
#setAttr("margin=\"0.3,0.03\"",NODE)
|
#setAttr("margin=\"0.3,0.03\"",NODE)
|
||||||
@ -188,25 +209,29 @@ class AttackThread(threading.Thread):
|
|||||||
(fd2,fpname2) = Tempfile.tempcleaned(ext)
|
(fd2,fpname2) = Tempfile.tempcleaned(ext)
|
||||||
f = os.fdopen(fd2,'w')
|
f = os.fdopen(fd2,'w')
|
||||||
|
|
||||||
cmd = "dot -T%s" % (type)
|
cmd = "dot -T%s >%s" % (type,fpname2)
|
||||||
|
|
||||||
# execute command
|
# execute command
|
||||||
cin,cout = os.popen2(cmd,'b')
|
cin,cout = os.popen2(cmd,'b')
|
||||||
|
|
||||||
self.writeGraph(attack.scytherDot,cin)
|
self.writeGraph(attack.scytherDot,cin)
|
||||||
|
cin.flush()
|
||||||
cin.close()
|
cin.close()
|
||||||
|
|
||||||
for l in cout.read():
|
|
||||||
f.write(l)
|
|
||||||
|
|
||||||
cout.close()
|
cout.close()
|
||||||
|
|
||||||
f.flush()
|
f.flush()
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
# Print
|
||||||
|
print fpname2
|
||||||
|
raw_input()
|
||||||
|
|
||||||
# if this is done, store and report
|
# if this is done, store and report
|
||||||
attack.filetype = type
|
attack.filetype = type
|
||||||
attack.file = fpname2 # this is where the file name is stored
|
attack.file = fpname2 # this is where the file name is stored
|
||||||
|
|
||||||
|
# Maybe we should remove the temporary file... TODO
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
class VerificationWindow(wx.Dialog):
|
class VerificationWindow(wx.Dialog):
|
||||||
@ -344,7 +369,7 @@ class ResultWindow(wx.Frame):
|
|||||||
views += self.BuildClaim(grid,claims[index],index+1)
|
views += self.BuildClaim(grid,claims[index],index+1)
|
||||||
|
|
||||||
if views > 0:
|
if views > 0:
|
||||||
titlebar(7,"Classes",1)
|
titlebar(7,"Patterns",1)
|
||||||
|
|
||||||
self.SetSizer(grid)
|
self.SetSizer(grid)
|
||||||
self.Fit()
|
self.Fit()
|
||||||
@ -480,7 +505,7 @@ class ScytherRun(object):
|
|||||||
# start the thread
|
# start the thread
|
||||||
|
|
||||||
self.verifywin.SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
self.verifywin.SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||||
t = ScytherThread(self.spdl, self.options, self.verificationDone)
|
t = ScytherThread(self.spdl, self.options, self.verificationDone, self.mode)
|
||||||
t.start()
|
t.start()
|
||||||
|
|
||||||
# after verification, we proceed to the callback below...
|
# after verification, we proceed to the callback below...
|
||||||
|
@ -150,13 +150,13 @@ class SettingsWindow(wx.Panel):
|
|||||||
tstr += "--check "
|
tstr += "--check "
|
||||||
elif mode == "autoverify":
|
elif mode == "autoverify":
|
||||||
tstr += "--auto-claims "
|
tstr += "--auto-claims "
|
||||||
elif mode == "statespace":
|
elif mode == "characterize":
|
||||||
tstr += "--state-space "
|
tstr += "--state-space "
|
||||||
|
|
||||||
# Anything else?
|
# Anything else?
|
||||||
if self.misc != "":
|
if self.misc != "":
|
||||||
tstr += " " + self.misc + " "
|
tstr += " " + self.misc + " "
|
||||||
|
|
||||||
return tstr
|
return str(tstr) # turn it into a str (might have been unicode weirdness)
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
@ -6,9 +6,9 @@ import Term
|
|||||||
|
|
||||||
def stateDescription(okay,n=1,caps=False):
|
def stateDescription(okay,n=1,caps=False):
|
||||||
if okay:
|
if okay:
|
||||||
s = "trace class"
|
s = "trace pattern"
|
||||||
if n != 1:
|
if n != 1:
|
||||||
s += "es"
|
s += "s"
|
||||||
else:
|
else:
|
||||||
s = "attack"
|
s = "attack"
|
||||||
if n != 1:
|
if n != 1:
|
||||||
|
@ -86,6 +86,6 @@ class StringListError(Error):
|
|||||||
self.obj = obj
|
self.obj = obj
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "Got %s instead of a (list of) string." % self.obj
|
return "Got '%s', which is type '%s' instead of a (list of) string." % (self.obj, type(self.obj))
|
||||||
|
|
||||||
# vim: set ts=4 sw=4 et list lcs=tab\:>-:
|
# vim: set ts=4 sw=4 et list lcs=tab\:>-:
|
||||||
|
@ -68,6 +68,7 @@ def Check():
|
|||||||
program = getScytherBackend()
|
program = getScytherBackend()
|
||||||
CheckSanity(program)
|
CheckSanity(program)
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
def CheckSanity(program):
|
def CheckSanity(program):
|
||||||
@ -85,6 +86,9 @@ def EnsureString(x,sep=" "):
|
|||||||
Takes a thing that is either a list or a string.
|
Takes a thing that is either a list or a string.
|
||||||
Turns it into a string. If it was a list, <sep> is inserted, and the
|
Turns it into a string. If it was a list, <sep> is inserted, and the
|
||||||
process iterats.
|
process iterats.
|
||||||
|
|
||||||
|
TODO does not accept unicode yet, that is something that must be
|
||||||
|
handled to or we run into wxPython problems eventually.
|
||||||
"""
|
"""
|
||||||
if type(x) is str:
|
if type(x) is str:
|
||||||
return x
|
return x
|
||||||
@ -362,4 +366,29 @@ class Scyther(object):
|
|||||||
else:
|
else:
|
||||||
return "Scyther has not been run yet."
|
return "Scyther has not been run yet."
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def GetInfo(html=False):
|
||||||
|
"""
|
||||||
|
Retrieve a tuple (location,string) with information about the tool,
|
||||||
|
retrieved from the --expert --version data
|
||||||
|
"""
|
||||||
|
|
||||||
|
program = getScytherBackend()
|
||||||
|
arg = "--expert --version"
|
||||||
|
sc = Scyther()
|
||||||
|
(output,errors) = sc.doScytherCommand(spdl=None, args=arg)
|
||||||
|
if not html:
|
||||||
|
return (program,output)
|
||||||
|
else:
|
||||||
|
sep = "<br>\n"
|
||||||
|
html = "Backend: %s%s" % (program,sep)
|
||||||
|
for l in output.splitlines():
|
||||||
|
l.strip()
|
||||||
|
html += "%s%s" % (l,sep)
|
||||||
|
return html
|
||||||
|
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------------
|
||||||
|
|
||||||
# vim: set ts=4 sw=4 et list lcs=tab\:>-:
|
# vim: set ts=4 sw=4 et list lcs=tab\:>-:
|
||||||
|
@ -5,11 +5,18 @@
|
|||||||
################################################################
|
################################################################
|
||||||
|
|
||||||
message (STATUS "Building W32 version")
|
message (STATUS "Building W32 version")
|
||||||
|
|
||||||
# This should work on win32 platform, but also when the compiler
|
# This should work on win32 platform, but also when the compiler
|
||||||
# is available anyway under linux
|
# is available anyway under linux
|
||||||
set (CMAKE_C_COMPILER "i586-mingw32msvc-gcc")
|
set (CMAKE_C_COMPILER "i586-mingw32msvc-gcc")
|
||||||
set (CMAKE_CXX_COMPILER "i586-mingw32msvc-g++")
|
set (CMAKE_CXX_COMPILER "i586-mingw32msvc-g++")
|
||||||
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) # to get rid of -rdynamic
|
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS) # to get rid of -rdynamic
|
||||||
|
# Signal for windows
|
||||||
|
set (CMAKE_C_FLAGS "-DFORWINDOWS")
|
||||||
|
|
||||||
|
# Static where possible (i.e. only not on the APPLE)
|
||||||
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
|
||||||
|
|
||||||
set (scythername "scyther-w32.exe")
|
set (scythername "scyther-w32.exe")
|
||||||
add_executable (${scythername} ${Scyther_sources})
|
add_executable (${scythername} ${Scyther_sources})
|
||||||
|
|
||||||
|
@ -7,6 +7,10 @@
|
|||||||
# We call it linux, because that is what de-facto is the case.
|
# We call it linux, because that is what de-facto is the case.
|
||||||
|
|
||||||
message (STATUS "Building Linux version")
|
message (STATUS "Building Linux version")
|
||||||
|
|
||||||
|
# Static where possible (i.e. only not on the APPLE)
|
||||||
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
|
||||||
|
|
||||||
set (scythername "scyther-linux")
|
set (scythername "scyther-linux")
|
||||||
add_executable (${scythername} ${Scyther_sources})
|
add_executable (${scythername} ${Scyther_sources})
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ set (Scyther_sources
|
|||||||
intruderknowledge.c knowledge.c label.c list.c main.c mgu.c
|
intruderknowledge.c knowledge.c label.c list.c main.c mgu.c
|
||||||
prune_bounds.c prune_theorems.c role.c
|
prune_bounds.c prune_theorems.c role.c
|
||||||
specialterm.c states.c switches.c symbol.c system.c tac.c
|
specialterm.c states.c switches.c symbol.c system.c tac.c
|
||||||
|
tempfile.c
|
||||||
termlist.c termmap.c term.c timer.c type.c warshall.c xmlout.c
|
termlist.c termmap.c term.c timer.c type.c warshall.c xmlout.c
|
||||||
parser.c scanner.c
|
parser.c scanner.c
|
||||||
)
|
)
|
||||||
@ -23,9 +24,6 @@ set (Scyther_sources
|
|||||||
# If we are in a debug mode we want to be strict
|
# If we are in a debug mode we want to be strict
|
||||||
set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -DDEBUG")
|
set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wall -DDEBUG")
|
||||||
|
|
||||||
# Usual static
|
|
||||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")
|
|
||||||
|
|
||||||
# Determine version number
|
# Determine version number
|
||||||
include (SVNVersion.cmake)
|
include (SVNVersion.cmake)
|
||||||
|
|
||||||
|
135
src/arachne.c
135
src/arachne.c
@ -11,12 +11,8 @@
|
|||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#if !defined(__APPLE__)
|
|
||||||
#ifdef DEBUG
|
|
||||||
#include <malloc.h>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#include "mymalloc.h"
|
||||||
#include "term.h"
|
#include "term.h"
|
||||||
#include "termlist.h"
|
#include "termlist.h"
|
||||||
#include "role.h"
|
#include "role.h"
|
||||||
@ -580,13 +576,6 @@ proof_suppose_binding (Binding b)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Create a new temporary file and return the pointer.
|
|
||||||
FILE *
|
|
||||||
scyther_tempfile (void)
|
|
||||||
{
|
|
||||||
return tmpfile ();
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
// Sub
|
// Sub
|
||||||
//------------------------------------------------------------------------
|
//------------------------------------------------------------------------
|
||||||
@ -1925,11 +1914,27 @@ makeTraceClass (const System sys, Termlist varlist)
|
|||||||
termlistDelete (varlist);
|
termlistDelete (varlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Determine whether to filter to a single attack
|
||||||
|
int
|
||||||
|
useAttackBuffer (void)
|
||||||
|
{
|
||||||
|
if (switches.useAttackBuffer)
|
||||||
|
{
|
||||||
|
// it is possible
|
||||||
|
if (switches.prune != 0)
|
||||||
|
{
|
||||||
|
// it is also desired
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//! Start attack output
|
//! Start attack output
|
||||||
void
|
void
|
||||||
attackOutputStart (void)
|
attackOutputStart (void)
|
||||||
{
|
{
|
||||||
if (switches.prune != 0)
|
if (useAttackBuffer ())
|
||||||
{
|
{
|
||||||
FILE *fd;
|
FILE *fd;
|
||||||
|
|
||||||
@ -2153,20 +2158,101 @@ iterateOneBinding (void)
|
|||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Unfold this particular name in this way
|
||||||
|
void
|
||||||
|
iterateAgentUnfoldThis (const Term rolevar, const Term agent)
|
||||||
|
{
|
||||||
|
Term buffer;
|
||||||
|
|
||||||
|
buffer = rolevar->subst;
|
||||||
|
rolevar->subst = agent;
|
||||||
|
iterate ();
|
||||||
|
rolevar->subst = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Unfold this particular name
|
||||||
|
void
|
||||||
|
iterateAgentUnfolding (const System sys, const Term rolevar)
|
||||||
|
{
|
||||||
|
Termlist kl;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
iterateAgentUnfoldThis (rolevar, AGENT_Eve);
|
||||||
|
kl = knowledgeSet (sys->know);
|
||||||
|
count = 0;
|
||||||
|
while (kl != NULL && count < switches.agentUnfold)
|
||||||
|
{
|
||||||
|
Term t;
|
||||||
|
|
||||||
|
t = deVar (kl->term);
|
||||||
|
if (realTermLeaf (t) && inTermlist (t->stype, TERM_Agent))
|
||||||
|
{
|
||||||
|
if (!inTermlist (sys->untrusted, t))
|
||||||
|
{
|
||||||
|
iterateAgentUnfoldThis (rolevar, t);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kl = kl->next;
|
||||||
|
}
|
||||||
|
termlistDelete (kl);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Unfold names
|
||||||
|
/**
|
||||||
|
* Returns true if nothing was unfolded and the iteration must be done.
|
||||||
|
* Returns false when the iteration should not be done.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
doAgentUnfolding (const System sys)
|
||||||
|
{
|
||||||
|
int run;
|
||||||
|
|
||||||
|
for (run = 0; run < sys->maxruns; run++)
|
||||||
|
{
|
||||||
|
Termlist tl;
|
||||||
|
|
||||||
|
tl = sys->runs[run].rho;
|
||||||
|
while (tl != NULL)
|
||||||
|
{
|
||||||
|
Term t;
|
||||||
|
|
||||||
|
t = deVar (tl->term);
|
||||||
|
if (realTermVariable (t))
|
||||||
|
{
|
||||||
|
// Hey, this role name is still a variable.
|
||||||
|
// We don't want that and so we unfold it as expected.
|
||||||
|
iterateAgentUnfolding (sys, t);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
tl = tl->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//! Main recursive procedure for Arachne
|
//! Main recursive procedure for Arachne
|
||||||
int
|
int
|
||||||
iterate ()
|
iterate ()
|
||||||
{
|
{
|
||||||
int flag;
|
int flag;
|
||||||
|
|
||||||
|
|
||||||
flag = 1;
|
flag = 1;
|
||||||
|
|
||||||
|
// check unfolding agent names
|
||||||
|
if (switches.agentUnfold > 0)
|
||||||
|
{
|
||||||
|
if (!doAgentUnfolding (sys))
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
if (!prune_theorems (sys))
|
if (!prune_theorems (sys))
|
||||||
{
|
{
|
||||||
if (!prune_claim_specifics (sys))
|
if (!prune_claim_specifics (sys))
|
||||||
{
|
{
|
||||||
if (!prune_bounds (sys))
|
if (!prune_bounds (sys))
|
||||||
{
|
{
|
||||||
|
|
||||||
// Go and pick a binding for iteration
|
// Go and pick a binding for iteration
|
||||||
flag = iterateOneBinding ();
|
flag = iterateOneBinding ();
|
||||||
}
|
}
|
||||||
@ -2194,11 +2280,7 @@ iterate ()
|
|||||||
int
|
int
|
||||||
iterate_buffer_attacks (void)
|
iterate_buffer_attacks (void)
|
||||||
{
|
{
|
||||||
if (switches.prune == 0)
|
if (useAttackBuffer ())
|
||||||
{
|
|
||||||
return iterate ();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// We are pruning attacks, so they should go into a temporary file.
|
// We are pruning attacks, so they should go into a temporary file.
|
||||||
/*
|
/*
|
||||||
@ -2230,6 +2312,11 @@ iterate_buffer_attacks (void)
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// No attack buffering, just output all of them
|
||||||
|
return iterate ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Arachne single claim test
|
//! Arachne single claim test
|
||||||
@ -2291,6 +2378,8 @@ arachneClaimTest (Claimlist cl)
|
|||||||
int m0run;
|
int m0run;
|
||||||
|
|
||||||
m0tl = knowledgeSet (sys->know);
|
m0tl = knowledgeSet (sys->know);
|
||||||
|
if (m0tl != NULL)
|
||||||
|
{
|
||||||
m0t = termlist_to_tuple (m0tl);
|
m0t = termlist_to_tuple (m0tl);
|
||||||
// eprintf("Initial intruder knowledge node for ");
|
// eprintf("Initial intruder knowledge node for ");
|
||||||
// termPrint(m0t);
|
// termPrint(m0t);
|
||||||
@ -2300,6 +2389,11 @@ arachneClaimTest (Claimlist cl)
|
|||||||
newruns++;
|
newruns++;
|
||||||
proof_suppose_run (m0run, 0, 1);
|
proof_suppose_run (m0run, 0, 1);
|
||||||
sys->runs[m0run].height = 1;
|
sys->runs[m0run].height = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m0run = -1;
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -2311,12 +2405,15 @@ arachneClaimTest (Claimlist cl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (m0run != -1)
|
||||||
|
{
|
||||||
// remove initial knowledge node
|
// remove initial knowledge node
|
||||||
termDelete (m0t);
|
termDelete (m0t);
|
||||||
termlistDelete (m0tl);
|
termlistDelete (m0tl);
|
||||||
semiRunDestroy ();
|
semiRunDestroy ();
|
||||||
newruns--;
|
newruns--;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// remove claiming run goals
|
// remove claiming run goals
|
||||||
goal_remove_last (newgoals);
|
goal_remove_last (newgoals);
|
||||||
semiRunDestroy ();
|
semiRunDestroy ();
|
||||||
|
@ -15,9 +15,7 @@
|
|||||||
#include "switches.h"
|
#include "switches.h"
|
||||||
#include "depend.h"
|
#include "depend.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#if !defined(__APPLE__)
|
#include "mymalloc.h"
|
||||||
#include <malloc.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static System sys; //!< local storage of system pointer
|
static System sys; //!< local storage of system pointer
|
||||||
|
|
||||||
|
39
src/bugs.txt
39
src/bugs.txt
@ -1,7 +1,13 @@
|
|||||||
--+++ Crititcal Bugs
|
--+++ Crititcal Bugs
|
||||||
|
|
||||||
|
* soph segfaults at no switch or -r4 (-r3 is okay??) using non-debug version.
|
||||||
|
* './scyther -a ../spdl/nsl3.spdl --increment-runs' segfaults. The main reason is that the Archne engine uses runs in a different way.
|
||||||
|
Maybe it is best to disable --increment rules for non-ModelChecker verification.
|
||||||
|
|
||||||
---+++ Bugs
|
---+++ Bugs
|
||||||
|
|
||||||
|
* Problem with goal bindings: instantiation of variable with a tuple might
|
||||||
|
introduce a tuple goal, which is forbidden. We must find a way to deal with this. This typically occurs in type flaw searches.
|
||||||
* Arachne seems to trip over claims with empty prec sets. Maybe we
|
* Arachne seems to trip over claims with empty prec sets. Maybe we
|
||||||
simply should not test these.
|
simply should not test these.
|
||||||
* Splice/AS does not work well because priority key search stumbles over the
|
* Splice/AS does not work well because priority key search stumbles over the
|
||||||
@ -21,9 +27,19 @@
|
|||||||
|
|
||||||
---++++ ArachneEngine
|
---++++ ArachneEngine
|
||||||
|
|
||||||
|
* There is no good test on the correct workings of
|
||||||
|
add_goals/destruction of these. We can test this if after
|
||||||
|
termination, we have 0 goals; for this we need to store the
|
||||||
|
initially added goals as well. Furthermore, we can generate an
|
||||||
|
error when <0 goals occur.
|
||||||
* Consider where in Arachne dependency graph is used. If this is only for
|
* Consider where in Arachne dependency graph is used. If this is only for
|
||||||
pruning states, we can construct it there only. However, the base 'role
|
pruning states, we can construct it there only. However, the base 'role
|
||||||
defs/bindings' graph might be re-used.
|
defs/bindings' graph might be re-used.
|
||||||
|
* Add switch for arachne to prune encryption levels when using -m2.
|
||||||
|
* To store attacks for arachne, maybe the following is needed:
|
||||||
|
* The roles for each run
|
||||||
|
* The variable bindings for all (local) variables
|
||||||
|
* The goal bindings
|
||||||
* Agent terms must have keylevel 0; enforce this!
|
* Agent terms must have keylevel 0; enforce this!
|
||||||
* Select_goal should consider, for singular variables, whether their
|
* Select_goal should consider, for singular variables, whether their
|
||||||
type can be found in M_0. If so, the goal can be ignored.
|
type can be found in M_0. If so, the goal can be ignored.
|
||||||
@ -35,11 +51,19 @@
|
|||||||
Note that there can be multiple solutions; for now, simply try to take the
|
Note that there can be multiple solutions; for now, simply try to take the
|
||||||
shortest one.
|
shortest one.
|
||||||
|
|
||||||
|
---++++ ModelChecker
|
||||||
|
|
||||||
|
* For secrecy, one trusted agent and one untrusted agent suffices.
|
||||||
|
Implement this in the modelchecker.
|
||||||
|
* Implement delayed protocol compiler (on run demand only) for the modelchecker?
|
||||||
|
|
||||||
---++++ Misc
|
---++++ Misc
|
||||||
|
|
||||||
* Make different error codes for compilation error/ other error. This can be
|
* Make different error codes for compilation error/ other error. This can be
|
||||||
useful for scripts. However, it might shift some constants for the Elegast
|
useful for scripts. However, it might shift some constants for the Elegast
|
||||||
scripts.
|
scripts.
|
||||||
|
* Rewrite termMguTerm such that it iterates and adapt all functions
|
||||||
|
using it. This is to allow for associative tupling later.
|
||||||
* Fix constants in intruder knowledge. Auto add single one of each type,
|
* Fix constants in intruder knowledge. Auto add single one of each type,
|
||||||
when typed expl. Add single constant when untyped. Fix this also in
|
when typed expl. Add single constant when untyped. Fix this also in
|
||||||
semantics, and add proof to establish sufficiency.
|
semantics, and add proof to establish sufficiency.
|
||||||
@ -78,3 +102,18 @@
|
|||||||
* How is % notation handled in Casper?
|
* How is % notation handled in Casper?
|
||||||
* Vernam encryption?
|
* Vernam encryption?
|
||||||
|
|
||||||
|
---++++ ConstraintLogic (and thus obsolete)
|
||||||
|
|
||||||
|
* CLP: variables in keys must be branched: maybe even in three situations
|
||||||
|
(have key and contents, have inverse key and content, nothing)
|
||||||
|
* How should claims behave (trusted/untrusted) wrt uninstantiated
|
||||||
|
agents? Branch again? That's what is causing the nsl3-var problem.
|
||||||
|
* Constraints might be a part of a knowledge thing, because with we
|
||||||
|
might now have a number of local knowledge sets, each with their own
|
||||||
|
constraint sets. That doesn't make it easier though :( and will cause
|
||||||
|
some performance loss I suppose. Each local set has to remain
|
||||||
|
solveable as well.
|
||||||
|
* Issue: how do untrusted claims work in the context of an intruder?
|
||||||
|
Claim must be checked if it can be solved such that at least one of
|
||||||
|
the agents is trusted.
|
||||||
|
|
||||||
|
@ -1,10 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
|
||||||
# The big unifying build script, which builds all binaries it can on a
|
|
||||||
# given platform.
|
|
||||||
#
|
|
||||||
# Effectively, if this script is run both on Darwin and Linux systems,
|
|
||||||
# all binaries can be constructed.
|
|
||||||
|
|
||||||
PLATFORM=`uname`
|
PLATFORM=`uname`
|
||||||
echo $PLATFORM
|
echo $PLATFORM
|
||||||
|
@ -139,8 +139,8 @@ compile (Tac tc, int maxrunsset)
|
|||||||
/* process the tac */
|
/* process the tac */
|
||||||
tacProcess (tac_root);
|
tacProcess (tac_root);
|
||||||
|
|
||||||
/* Clean up keylevels */
|
/* Preprocess the result */
|
||||||
symbol_fix_keylevels ();
|
preprocess (sys);
|
||||||
|
|
||||||
/* cleanup */
|
/* cleanup */
|
||||||
levelDone ();
|
levelDone ();
|
||||||
@ -562,6 +562,9 @@ claimCreate (const System sys, const Protocol protocol, const Role role,
|
|||||||
readvars = compute_read_variables (thisRole);
|
readvars = compute_read_variables (thisRole);
|
||||||
while (claimvars != NULL)
|
while (claimvars != NULL)
|
||||||
{
|
{
|
||||||
|
if (!inTermlist(protocol->rolenames, claimvars->term))
|
||||||
|
{
|
||||||
|
/* only if it is not a role */
|
||||||
if (!inTermlist (readvars, claimvars->term))
|
if (!inTermlist (readvars, claimvars->term))
|
||||||
{
|
{
|
||||||
/* this claimvar does not occur in the reads? */
|
/* this claimvar does not occur in the reads? */
|
||||||
@ -579,8 +582,11 @@ claimCreate (const System sys, const Protocol protocol, const Role role,
|
|||||||
(" which is never read; therefore the claim will be true.\n");
|
(" which is never read; therefore the claim will be true.\n");
|
||||||
globalError--;
|
globalError--;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
claimvars = claimvars->next;
|
claimvars = claimvars->next;
|
||||||
}
|
}
|
||||||
|
termlistDelete (claimvars);
|
||||||
|
termlistDelete (readvars);
|
||||||
}
|
}
|
||||||
return cl;
|
return cl;
|
||||||
}
|
}
|
||||||
@ -2123,6 +2129,16 @@ checkLabelMatching (const System sys)
|
|||||||
void
|
void
|
||||||
preprocess (const System sys)
|
preprocess (const System sys)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Add default terms afterwards
|
||||||
|
*/
|
||||||
|
specialTermInitAfter (sys);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clean up keylevels
|
||||||
|
* */
|
||||||
|
symbol_fix_keylevels ();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* init some counters
|
* init some counters
|
||||||
*/
|
*/
|
||||||
@ -2143,10 +2159,6 @@ preprocess (const System sys)
|
|||||||
{
|
{
|
||||||
checkUnusedVariables (sys);
|
checkUnusedVariables (sys);
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
* compute hidelevels
|
|
||||||
*/
|
|
||||||
hidelevelCompute (sys);
|
|
||||||
/*
|
/*
|
||||||
* Initial knowledge
|
* Initial knowledge
|
||||||
*/
|
*/
|
||||||
@ -2154,6 +2166,12 @@ preprocess (const System sys)
|
|||||||
{
|
{
|
||||||
initialIntruderKnowledge (sys);
|
initialIntruderKnowledge (sys);
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* compute hidelevels
|
||||||
|
*
|
||||||
|
* Needs to be done *after* the initial intruder knowledge derivation.
|
||||||
|
*/
|
||||||
|
hidelevelCompute (sys);
|
||||||
/*
|
/*
|
||||||
* Check well-formedness
|
* Check well-formedness
|
||||||
*/
|
*/
|
||||||
|
@ -20,6 +20,8 @@ addSTerm (const System sys, Term t, Termlist fromlist, Termlist tolist)
|
|||||||
eprintf (" to the initial intruder knowledge]\n");
|
eprintf (" to the initial intruder knowledge]\n");
|
||||||
globalError--;
|
globalError--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
knowledgeAddTerm (sys->know, t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Unfold the term for all possible options
|
//! Unfold the term for all possible options
|
||||||
|
@ -5,12 +5,11 @@
|
|||||||
* A doubly linked list with void* as data type.
|
* A doubly linked list with void* as data type.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "list.h"
|
|
||||||
#if !defined(__APPLE__)
|
|
||||||
#include <malloc.h>
|
|
||||||
#endif
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
#include "mymalloc.h"
|
||||||
|
|
||||||
//! Make a node
|
//! Make a node
|
||||||
List
|
List
|
||||||
list_create (const void *data)
|
list_create (const void *data)
|
||||||
|
13
src/mgu.c
13
src/mgu.c
@ -16,21 +16,12 @@
|
|||||||
New version yields a termlist with substituted variables, which can later be reset to NULL.
|
New version yields a termlist with substituted variables, which can later be reset to NULL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//! Internal constant. If true, typed checking
|
|
||||||
/**
|
/**
|
||||||
* Analoguous to switches.match
|
* switches.match
|
||||||
* 0 typed
|
* 0 typed
|
||||||
* 1 basic typeflaws
|
* 1 basic typeflaws
|
||||||
* 2 all typeflaws
|
* 2 all typeflaws
|
||||||
*/
|
*/
|
||||||
static int mgu_match = 0;
|
|
||||||
|
|
||||||
//! Set mgu mode (basically switches.match)
|
|
||||||
void
|
|
||||||
setMguMode (const int match)
|
|
||||||
{
|
|
||||||
mgu_match = match;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
showSubst (Term t)
|
showSubst (Term t)
|
||||||
@ -90,7 +81,7 @@ goodsubst (Term tvar, Term tsubst)
|
|||||||
tbuf = tvar->subst;
|
tbuf = tvar->subst;
|
||||||
tvar->subst = tsubst;
|
tvar->subst = tsubst;
|
||||||
|
|
||||||
res = checkTypeTerm (mgu_match, tvar);
|
res = checkTypeTerm (tvar);
|
||||||
|
|
||||||
tvar->subst = tbuf;
|
tvar->subst = tbuf;
|
||||||
return res;
|
return res;
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
*/
|
*/
|
||||||
#define MGUFAIL (Termlist) -1
|
#define MGUFAIL (Termlist) -1
|
||||||
|
|
||||||
void setMguMode (const int mgu);
|
|
||||||
Termlist termMguTerm (Term t1, Term t2);
|
Termlist termMguTerm (Term t1, Term t2);
|
||||||
int termMguInTerm (Term t1, Term t2, int (*iterator) (Termlist));
|
int termMguInTerm (Term t1, Term t2, int (*iterator) (Termlist));
|
||||||
int termMguSubTerm (Term t1, Term t2, int (*iterator) (Termlist, Termlist),
|
int termMguSubTerm (Term t1, Term t2, int (*iterator) (Termlist, Termlist),
|
||||||
|
@ -15,9 +15,9 @@ protocol yahalomBan(A,B,S)
|
|||||||
var na;
|
var na;
|
||||||
var kab;
|
var kab;
|
||||||
|
|
||||||
read_1(A,B, A,na,B,S);
|
read_!1(A,B, A,na,B,S);
|
||||||
send_2(B,S, B,nb, {A,na}k(B,S) );
|
send_!2(B,S, B,nb, {A,na}k(B,S) );
|
||||||
read_4(A,B, {A,kab,nb}k(B,S) , {nb}kab );
|
read_!4(A,B, {A,kab,nb}k(B,S) , {nb}kab );
|
||||||
claim_6(B, Secret,kab);
|
claim_6(B, Secret,kab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,4 @@
|
|||||||
#
|
#
|
||||||
# Indent any changed files, ending in .c or .h
|
# Indent any changed files, ending in .c or .h
|
||||||
#
|
#
|
||||||
# TODO: Needs to be rewritten as svn of course is no longer used.
|
|
||||||
#
|
|
||||||
svn st | grep "^[MA].*\.[ch]$"| awk '{print $2}' | xargs indent
|
svn st | grep "^[MA].*\.[ch]$"| awk '{print $2}' | xargs indent
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* Some macros
|
* Some macros
|
||||||
*/
|
*/
|
||||||
#define langhide(x,y) x = levelConst(symbolSysConst(" _" y "_ "))
|
#define langhide(x,y) x = levelConst(symbolSysConst(" _" y "_ "))
|
||||||
#define langtype(x,y) x->stype = termlistAdd(x->stype,y);
|
#define langtype(x,y) x->stype = termlistAdd(x->stype,y)
|
||||||
#define langcons(x,y,z) x = levelConst(symbolSysConst(y)); langtype(x,z)
|
#define langcons(x,y,z) x = levelConst(symbolSysConst(y)); langtype(x,z)
|
||||||
|
|
||||||
/* externally used:
|
/* externally used:
|
||||||
@ -30,6 +30,12 @@ Term CLAIM_Niagree;
|
|||||||
Term CLAIM_Empty;
|
Term CLAIM_Empty;
|
||||||
Term CLAIM_Reachable;
|
Term CLAIM_Reachable;
|
||||||
|
|
||||||
|
Term AGENT_Alice;
|
||||||
|
Term AGENT_Bob;
|
||||||
|
Term AGENT_Charlie;
|
||||||
|
Term AGENT_Dave;
|
||||||
|
Term AGENT_Eve;
|
||||||
|
|
||||||
Termlist CLAIMS_dep_prec;
|
Termlist CLAIMS_dep_prec;
|
||||||
|
|
||||||
//! Init special terms
|
//! Init special terms
|
||||||
@ -64,6 +70,25 @@ specialTermInit (const System sys)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! After compilation (so the user gets the first choice)
|
||||||
|
void
|
||||||
|
specialTermInitAfter (const System sys)
|
||||||
|
{
|
||||||
|
langcons (AGENT_Alice, "Alice", TERM_Agent);
|
||||||
|
langcons (AGENT_Bob, "Bob", TERM_Agent);
|
||||||
|
langcons (AGENT_Charlie, "Charlie", TERM_Agent);
|
||||||
|
langcons (AGENT_Dave, "Dave", TERM_Agent);
|
||||||
|
langcons (AGENT_Eve, "Eve", TERM_Agent);
|
||||||
|
|
||||||
|
knowledgeAddTerm (sys->know, AGENT_Alice);
|
||||||
|
knowledgeAddTerm (sys->know, AGENT_Bob);
|
||||||
|
knowledgeAddTerm (sys->know, AGENT_Charlie);
|
||||||
|
knowledgeAddTerm (sys->know, AGENT_Dave);
|
||||||
|
knowledgeAddTerm (sys->know, AGENT_Eve);
|
||||||
|
|
||||||
|
sys->untrusted = termlistAddNew (sys->untrusted, AGENT_Eve);
|
||||||
|
}
|
||||||
|
|
||||||
//! Determine whether this is a leaf construct with a ticket in it
|
//! Determine whether this is a leaf construct with a ticket in it
|
||||||
int
|
int
|
||||||
isTicketTerm (Term t)
|
isTicketTerm (Term t)
|
||||||
|
@ -24,9 +24,16 @@ extern Term CLAIM_Niagree;
|
|||||||
extern Term CLAIM_Empty;
|
extern Term CLAIM_Empty;
|
||||||
extern Term CLAIM_Reachable;
|
extern Term CLAIM_Reachable;
|
||||||
|
|
||||||
|
extern Term AGENT_Alice;
|
||||||
|
extern Term AGENT_Bob;
|
||||||
|
extern Term AGENT_Charlie;
|
||||||
|
extern Term AGENT_Dave;
|
||||||
|
extern Term AGENT_Eve;
|
||||||
|
|
||||||
extern Termlist CLAIMS_dep_prec;
|
extern Termlist CLAIMS_dep_prec;
|
||||||
|
|
||||||
void specialTermInit (const System sys);
|
void specialTermInit (const System sys);
|
||||||
|
void specialTermInitAfter (const System sys);
|
||||||
int isTicketTerm (Term t);
|
int isTicketTerm (Term t);
|
||||||
int hasTicketSubterm (Term t);
|
int hasTicketSubterm (Term t);
|
||||||
|
|
||||||
|
@ -108,10 +108,6 @@ systemReset (const System sys)
|
|||||||
|
|
||||||
/* transfer switches */
|
/* transfer switches */
|
||||||
sys->maxtracelength = switches.maxtracelength;
|
sys->maxtracelength = switches.maxtracelength;
|
||||||
|
|
||||||
/* propagate mgu_mode */
|
|
||||||
|
|
||||||
setMguMode (switches.match);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//! Initialize runtime system (according to cut traces, limited runs)
|
//! Initialize runtime system (according to cut traces, limited runs)
|
||||||
@ -555,6 +551,7 @@ roleInstanceArachne (const System sys, const Protocol protocol,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! The next function makes locals for all in the list. Flags denote whether it is a variable or role.
|
||||||
void createLocals (Termlist list, int isvariable, int isrole)
|
void createLocals (Termlist list, int isvariable, int isrole)
|
||||||
{
|
{
|
||||||
while (list != NULL)
|
while (list != NULL)
|
||||||
|
@ -2,9 +2,7 @@
|
|||||||
#define TERMS
|
#define TERMS
|
||||||
|
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
|
#include "bool.h"
|
||||||
#define false 0
|
|
||||||
#define true 1
|
|
||||||
|
|
||||||
// type <= LEAF means it's a leaf, nkay?
|
// type <= LEAF means it's a leaf, nkay?
|
||||||
enum termtypes
|
enum termtypes
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "specialterm.h"
|
#include "specialterm.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
|
#include "switches.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Shared stuff
|
* Shared stuff
|
||||||
@ -746,20 +747,19 @@ termlistContained (const Termlist tlbig, Termlist tlsmall)
|
|||||||
/**
|
/**
|
||||||
* Determine whether a variable has been substituted with something with
|
* Determine whether a variable has been substituted with something with
|
||||||
* the right type.
|
* the right type.
|
||||||
*@param matchmode The system matching mode, typically system::match
|
|
||||||
*@param term The closed variable term.
|
*@param term The closed variable term.
|
||||||
*@return True iff the substitution is valid in the current mode.
|
*@return True iff the substitution is valid in the current mode.
|
||||||
*\sa system::match
|
*\sa system::match
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int
|
int
|
||||||
validSubst (const int matchmode, const Term term)
|
validSubst (const Term term)
|
||||||
{
|
{
|
||||||
if (!realTermVariable (term) || term->subst == NULL)
|
if (!realTermVariable (term) || term->subst == NULL)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (matchmode)
|
switch (switches.match)
|
||||||
{
|
{
|
||||||
case 0: /* real type match */
|
case 0: /* real type match */
|
||||||
return realTermLeaf (term->subst)
|
return realTermLeaf (term->subst)
|
||||||
|
@ -52,7 +52,6 @@ Term termLocal (const Term t, Termlist fromlist, Termlist tolist);
|
|||||||
Termlist termlistLocal (Termlist tl, const Termlist fromlist,
|
Termlist termlistLocal (Termlist tl, const Termlist fromlist,
|
||||||
const Termlist tolist);
|
const Termlist tolist);
|
||||||
int termlistContained (const Termlist tlbig, Termlist tlsmall);
|
int termlistContained (const Termlist tlbig, Termlist tlsmall);
|
||||||
int validSubst (const int matchmode, const Term term);
|
|
||||||
Term termFunction (Termlist fromlist, Termlist tolist, Term tx);
|
Term termFunction (Termlist fromlist, Termlist tolist, Term tx);
|
||||||
Termlist termlistForward (Termlist tl);
|
Termlist termlistForward (Termlist tl);
|
||||||
int termlistOrder (Termlist tl1, Termlist tl2);
|
int termlistOrder (Termlist tl1, Termlist tl2);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
- Version number should be retrieved from git now (as opposed to
|
- When saving a file after 'file changed' warning, an overwrite of the
|
||||||
subversion, so it should give the sha1 thing, and possibly a tag).
|
same file should not necessarily generate a warning.
|
||||||
|
- Output (claim summary) might have a parameter summary somewhere.
|
||||||
- Error should have an additional line number parameter (that might be
|
- Error should have an additional line number parameter (that might be
|
||||||
-1 to ignore it) forcing people to use numbers :)
|
-1 to ignore it) forcing people to use numbers :)
|
||||||
Format: "error: [%i] %s\n"
|
Format: "error: [%i] %s\n"
|
||||||
|
35
src/type.c
35
src/type.c
@ -66,10 +66,10 @@ isTypelistGeneric (const Termlist typelist)
|
|||||||
* Non-variables etc. imply true.
|
* Non-variables etc. imply true.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
checkTypeTerm (const int mgumode, const Term tvar)
|
checkTypeTerm (const Term tvar)
|
||||||
{
|
{
|
||||||
// Checks are only needed for mgumode < 2 etc.
|
// Checks are only needed for match < 2 etc.
|
||||||
if (mgumode < 2 && tvar != NULL && realTermVariable (tvar))
|
if (switches.match < 2 && tvar != NULL && realTermVariable (tvar))
|
||||||
{
|
{
|
||||||
// Non-instantiated terms are fine.
|
// Non-instantiated terms are fine.
|
||||||
if (tvar->subst != NULL)
|
if (tvar->subst != NULL)
|
||||||
@ -90,7 +90,7 @@ checkTypeTerm (const int mgumode, const Term tvar)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// It is a leaf
|
// It is a leaf
|
||||||
if (mgumode == 0)
|
if (switches.match == 0)
|
||||||
{
|
{
|
||||||
/* Types must match exactly. Thus, one of the variable type should match a type of the constant.
|
/* Types must match exactly. Thus, one of the variable type should match a type of the constant.
|
||||||
*/
|
*/
|
||||||
@ -122,11 +122,11 @@ checkTypeTerm (const int mgumode, const Term tvar)
|
|||||||
* Empty list implies true.
|
* Empty list implies true.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
checkTypeTermlist (const int mgumode, Termlist tl)
|
checkTypeTermlist (Termlist tl)
|
||||||
{
|
{
|
||||||
while (tl != NULL)
|
while (tl != NULL)
|
||||||
{
|
{
|
||||||
if (!checkTypeTerm (mgumode, tl->term))
|
if (!checkTypeTerm (tl->term))
|
||||||
return false;
|
return false;
|
||||||
tl = tl->next;
|
tl = tl->next;
|
||||||
}
|
}
|
||||||
@ -144,7 +144,7 @@ checkTypeLocals (const System sys)
|
|||||||
{
|
{
|
||||||
if (sys->runs[run].protocol != INTRUDER)
|
if (sys->runs[run].protocol != INTRUDER)
|
||||||
{
|
{
|
||||||
if (!checkTypeTermlist (switches.match, sys->runs[run].locals))
|
if (!checkTypeTermlist (sys->runs[run].locals))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
run++;
|
run++;
|
||||||
@ -178,14 +178,13 @@ agentCompatible (Termlist tl)
|
|||||||
/**
|
/**
|
||||||
* Depends on some input:
|
* Depends on some input:
|
||||||
*
|
*
|
||||||
* mgumode type of matching
|
|
||||||
* agentcheck true if agent type is always restrictive
|
* agentcheck true if agent type is always restrictive
|
||||||
*
|
*
|
||||||
* returns the new type list (needs to be deleted!) or TERMLISTERROR (should
|
* returns the new type list (needs to be deleted!) or TERMLISTERROR (should
|
||||||
* not be deleted!)
|
* not be deleted!)
|
||||||
*/
|
*/
|
||||||
Termlist
|
Termlist
|
||||||
typelistConjunct (Termlist typelist1, Termlist typelist2, const int mgumode,
|
typelistConjunct (Termlist typelist1, Termlist typelist2,
|
||||||
const int agentcheck)
|
const int agentcheck)
|
||||||
{
|
{
|
||||||
if (typelist1 != TERMLISTERROR && typelist2 != TERMLISTERROR)
|
if (typelist1 != TERMLISTERROR && typelist2 != TERMLISTERROR)
|
||||||
@ -202,7 +201,9 @@ typelistConjunct (Termlist typelist1, Termlist typelist2, const int mgumode,
|
|||||||
/* Now, the result must surely accept agents. Thus, it must be
|
/* Now, the result must surely accept agents. Thus, it must be
|
||||||
* NULL or accept agents.
|
* NULL or accept agents.
|
||||||
*/
|
*/
|
||||||
|
if (switches.match == 0)
|
||||||
|
{
|
||||||
|
// only if we are doing matching, otherwise it is always agent-compatible
|
||||||
if (!
|
if (!
|
||||||
(agentCompatible (typelist1)
|
(agentCompatible (typelist1)
|
||||||
&& agentCompatible (typelist2)))
|
&& agentCompatible (typelist2)))
|
||||||
@ -210,17 +211,15 @@ typelistConjunct (Termlist typelist1, Termlist typelist2, const int mgumode,
|
|||||||
// Not good: one of them cannot
|
// Not good: one of them cannot
|
||||||
return TERMLISTERROR;
|
return TERMLISTERROR;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
// Good: but because an agent is involved, the type reduces to the simple Agent type only.
|
// Good: but because an agent is involved, the type reduces to the simple Agent type only.
|
||||||
return termlistAdd (NULL, TERM_Agent);
|
return termlistAdd (NULL, TERM_Agent);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Not the simple agent variable case. Now other things come in to play.
|
/* Not the simple agent variable case. Now other things come in to play.
|
||||||
*/
|
*/
|
||||||
if (mgumode == 0)
|
if (switches.match == 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Strict match: (-m0) conjunct of the types must be non-empty.
|
* Strict match: (-m0) conjunct of the types must be non-empty.
|
||||||
@ -287,6 +286,8 @@ checkGroundVariable (const System sys, const Term groundvar)
|
|||||||
int allvalid;
|
int allvalid;
|
||||||
|
|
||||||
allvalid = 1;
|
allvalid = 1;
|
||||||
|
if (switches.match < 2)
|
||||||
|
{
|
||||||
if (realTermVariable (groundvar))
|
if (realTermVariable (groundvar))
|
||||||
{
|
{
|
||||||
Termlist tl;
|
Termlist tl;
|
||||||
@ -313,7 +314,7 @@ checkGroundVariable (const System sys, const Term groundvar)
|
|||||||
// Take conjunct
|
// Take conjunct
|
||||||
tlprev = typelist;
|
tlprev = typelist;
|
||||||
typelist =
|
typelist =
|
||||||
typelistConjunct (tlprev, term->stype, switches.match,
|
typelistConjunct (tlprev, term->stype,
|
||||||
switches.agentTypecheck);
|
switches.agentTypecheck);
|
||||||
termlistDelete (tlprev);
|
termlistDelete (tlprev);
|
||||||
|
|
||||||
@ -331,6 +332,7 @@ checkGroundVariable (const System sys, const Term groundvar)
|
|||||||
termlistDelete (typelist);
|
termlistDelete (typelist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return allvalid;
|
return allvalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,8 +410,7 @@ checkAllSubstitutions (const System sys)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Consider match
|
// Consider match
|
||||||
allvalid = allvalid
|
allvalid = allvalid && checkTypeTerm (tvar);
|
||||||
&& checkTypeTerm (switches.match, tvar);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
#include "term.h"
|
#include "term.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
int checkTypeTerm (const int mgumode, const Term t);
|
int checkTypeTerm (const Term t);
|
||||||
int checkTypeTermlist (const int mgumode, Termlist tl);
|
int checkTypeTermlist (Termlist tl);
|
||||||
int checkTypeLocals (const System sys);
|
int checkTypeLocals (const System sys);
|
||||||
Termlist typelistConjunct (Termlist typelist1, Termlist Typelist2);
|
Termlist typelistConjunct (Termlist typelist1, Termlist Typelist2);
|
||||||
int checkAllSubstitutions (const System sys);
|
int checkAllSubstitutions (const System sys);
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "mymalloc.h"
|
||||||
|
|
||||||
/* machine-dependent definitions */
|
/* machine-dependent definitions */
|
||||||
/* the following definitions are for the Tahoe */
|
/* the following definitions are for the Tahoe */
|
||||||
/* they might have to be changed for other machines */
|
/* they might have to be changed for other machines */
|
||||||
|
@ -317,7 +317,9 @@ xmlVariable (const System sys, const Term variable, const int run)
|
|||||||
{
|
{
|
||||||
xmlIndentPrint ();
|
xmlIndentPrint ();
|
||||||
eprintf ("<variable typeflaw=\"");
|
eprintf ("<variable typeflaw=\"");
|
||||||
if (!checkTypeTerm (0, variable))
|
/* TODO this is now wrong, because it does not switch the matching more
|
||||||
|
* anymore */
|
||||||
|
if (!checkTypeTerm (variable))
|
||||||
{
|
{
|
||||||
eprintf ("true");
|
eprintf ("true");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user