scyther/gui/test-delta.py

182 lines
4.6 KiB
Python
Raw Normal View History

#!/usr/bin/env python
"""
Scyther : An automatic verifier for security protocols.
2013-10-05 23:56:12 +01:00
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.
"""
"""
Example script to show how to perform large-scale tests using the
Scyther Python API (contained in the Scyther subdirectory)
In this example, we find the differences between two different switch
settings for a large set of protocols.
The notification triggers if claim lists differ, or when a claim is okay
in one test but not in the other. Hence, we ignore differences between
complete/bounded verification.
Author: Cas Cremers
Define the strings below.
TEST0 is used for both, TEST1/2 define the difference between
the tests.
"""
#---------------------------------------------------------------------------
TEST0 = ""
TEST1 = "--max-runs=1"
TEST2 = "--max-runs=4"
#---------------------------------------------------------------------------
""" Import externals """
import commands
#---------------------------------------------------------------------------
""" Import scyther components """
from Scyther import Scyther
#---------------------------------------------------------------------------
def filterProtocol(protocol):
"""
We may want to filter out some protocols.
This function allows that. Return True if it is okay (and should be
included) or False otherwise.
"""
include = True
return include
def simpleRun(args):
x = Scyther.Scyther()
x.options = args
x.verify()
return x
def ScytherRes(protocol,args=""):
"""
Run Scyther on a protocol and return a tuple with the
resulting object and claim list.
"""
global TEST0
args = "%s %s %s" % (TEST0, args, protocol)
s = simpleRun(args)
return (s,s.claims)
def findSameClaim(cl,claim):
"""
Find in claim list the claim that corresponds to claim
"""
for claim2 in cl:
if claim2.id == claim.id:
return claim2
return None
def ScytherDiff(protocol):
"""
Check whether the two different switch settings yield a different
result.
"""
global TEST1, TEST2
(s1,cl1) = ScytherRes(protocol,TEST1)
(s2,cl2) = ScytherRes(protocol,TEST2)
res = ""
if len(cl1) != len(cl2):
res += "Different claim lists:\n%s\n%s\n" % (cl1,cl2)
else:
for claim1 in cl1:
claim2 = findSameClaim(cl2,claim1)
if claim2 == None:
res += "%s not in second test.\n" % (claim1)
else:
if claim1.okay != claim2.okay:
res += "Different results:\n%s\n%s\n" % (claim1,claim2)
if res == "":
return None
else:
return res
def findProtocols():
"""
Find a list of protocol names
"""
cmd = "find -iname '*.spdl'"
plist = commands.getoutput(cmd).splitlines()
nlist = []
for prot in plist:
if filterProtocol(prot):
nlist.append(prot)
return nlist
def main():
"""
Simple test case with a few protocols
"""
global TEST0,TEST1,TEST2
list = findProtocols()
print "Performing delta analysis"
print
print "String 0 (used for both): '%s'" % TEST0
print "String 1: '%s'" % TEST1
print "String 2: '%s'" % TEST2
print
print "After filtering, we are left with the following protocols:", list
print
maxcount = len(list)
count = 1
delta = 0
for prot in list:
perc = (100 * count) / maxcount
print "[%i%%] %s: " % (perc,prot),
res = ScytherDiff(prot)
if res != None:
print
print "-" * 72
print prot
print "-" * 72
print res
delta = delta + 1
else:
print "No interesting delta found."
count = count + 1
print
print "Analysis complete."
print "%i out of %i protocols differed [%i%%]." % (delta,maxcount,(100 * delta)/maxcount)
if __name__ == '__main__':
main()
# vim: set ts=4 sw=4 et list lcs=tab\:>-: