Improving some scripts; exploit cache better.

This commit is contained in:
Cas Cremers 2011-03-31 15:02:49 +02:00
parent c2662abaef
commit bc667f3f32
4 changed files with 89 additions and 13 deletions

View File

@ -105,8 +105,7 @@ def safeCommandOutput(cmd):
Meant for short outputs, as output is stored in memory and Meant for short outputs, as output is stored in memory and
not written to a file. not written to a file.
""" """
p = Popen(cmd, shell=getShell(), stdout=PIPE, stderr=PIPE)
p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
(sout,serr) = p.communicate() (sout,serr) = p.communicate()
return (p.returncode,sout,serr) return (p.returncode,sout,serr)
@ -115,7 +114,7 @@ def safeCommand(cmd):
""" Execute a command with some arguments. Safe cross-platform """ Execute a command with some arguments. Safe cross-platform
version, I hope. """ version, I hope. """
p = Popen(cmd, shell=True) p = Popen(cmd, shell=getShell())
sts = p.wait() sts = p.wait()
return sts return sts

View File

@ -1,7 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
""" """
Scyther : An automatic verifier for security protocols. Scyther : An automatic verifier for security protocols.
Copyright (C) 2007 Cas Cremers Copyright (C) 2007-2009 Cas Cremers
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
@ -241,14 +241,19 @@ class Scyther(object):
for arg in arglist: for arg in arglist:
self.options += " %s" % (arg) self.options += " %s" % (arg)
def doScytherCommand(self, spdl, args): def doScytherCommand(self, spdl, args, checkKnown=False):
""" """
Cached version of the 'real' below Cached version of the 'real' below
""" """
global HASHLIB global HASHLIB
if not HASHLIB: if not HASHLIB:
return self.doScytherCommandReal(spdl,args) if checkKnown == True:
# No hashlib, so we don't have it already
return False
else:
# Need to compute
return self.doScytherCommandReal(spdl,args)
# So we have the hashing libs # So we have the hashing libs
m = hashlib.sha256() m = hashlib.sha256()
@ -288,11 +293,20 @@ class Scyther(object):
fh2 = open(fname2,"r") fh2 = open(fname2,"r")
err = fh2.read() err = fh2.read()
fh2.close() fh2.close()
return (out,err) if checkKnown == True:
# We got to here, so we have it
return True
else:
# Not checking cache, we need the result
return (out,err)
except: except:
""" """
Something went wrong, do the real thing and cache afterwards Something went wrong, do the real thing and cache afterwards
""" """
if checkKnown == True:
# We were only checking, abort
return False
(out,err) = self.doScytherCommandReal(spdl,args) (out,err) = self.doScytherCommandReal(spdl,args)
# Store result in cache # Store result in cache
@ -380,8 +394,9 @@ class Scyther(object):
""" Sanitize some of the input """ """ Sanitize some of the input """
self.options = EnsureString(self.options) self.options = EnsureString(self.options)
def verify(self,extraoptions=None): def verify(self,extraoptions=None,checkKnown=False):
""" Should return a list of results """ """ Should return a list of results """
""" If checkKnown == True, we do not call Scyther, but just check the cache, and return True iff the result is in the cache """
# Cleanup first # Cleanup first
self.sanitize() self.sanitize()
@ -395,6 +410,10 @@ class Scyther(object):
# extraoptions might need sanitizing # extraoptions might need sanitizing
args += " %s" % EnsureString(extraoptions) args += " %s" % EnsureString(extraoptions)
# Are we only checking the cache?
if checkKnown == True:
return self.doScytherCommand(self.spdl, args, checkKnown=checkKnown)
# execute # execute
(output,errors) = self.doScytherCommand(self.spdl, args) (output,errors) = self.doScytherCommand(self.spdl, args)
self.run = True self.run = True
@ -442,19 +461,21 @@ class Scyther(object):
else: else:
return self.output return self.output
def verifyOne(self,cl=None): def verifyOne(self,cl=None,checkKnown=False):
""" """
Verify just a single claim with an ID retrieved from the Verify just a single claim with an ID retrieved from the
procedure below, 'scanClaims', or a full claim object procedure below, 'scanClaims', or a full claim object
If checkKnown is True, return if the result is already known (but never recompute).
""" """
if cl: if cl:
# We accept either a claim or a claim id # We accept either a claim or a claim id
if isinstance(cl,Claim.Claim): if isinstance(cl,Claim.Claim):
cl = cl.id cl = cl.id
return self.verify("--filter=%s" % cl) return self.verify("--filter=%s" % cl, checkKnown=checkKnown)
else: else:
# If no claim, then its just normal verification # If no claim, then its just normal verification
return self.verify() return self.verify(checkKnown=checkKnown)
def scanClaims(self): def scanClaims(self):
""" """
@ -493,6 +514,58 @@ class Scyther(object):
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
def GetClaims(filelist, filterlist=None):
"""
Given a list of file names in filelist,
returns a dictionary of filenames to lists claim names.
Filenames which yielded no claims are filtered out.
Filterlist may be None or a list of claim names (Secret, SKR, Niagree etc).
"""
dict = {}
for fname in filelist:
try:
sc = Scyther()
sc.setFile(fname)
l = sc.scanClaims()
if l != None:
cl = []
for claim in l:
if filterlist == None:
cl.append(claim.id)
else:
if claim.claimtype in filterlist:
cl.append(claim.id)
dict[fname] = cl
except:
pass
return dict
#---------------------------------------------------------------------------
def FindProtocols(path="",filterProtocol=None):
"""
Find a list of protocol names
Note: Unix only! Will not work under windows.
"""
import commands
cmd = "find %s -iname '*.spdl'" % (path)
plist = commands.getoutput(cmd).splitlines()
nlist = []
for prot in plist:
if filterProtocol != None:
if filterProtocol(prot):
nlist.append(prot)
else:
nlist.append(prot)
return nlist
#---------------------------------------------------------------------------
def GetInfo(html=False): def GetInfo(html=False):
""" """
Retrieve a tuple (location,string) with information about the tool, Retrieve a tuple (location,string) with information about the tool,

View File

@ -176,3 +176,6 @@ Mon Jan 24 14:55:23 CET 2011
Sat Jan 29 13:35:22 CET 2011
./batcher.sh -m 2 -A --self-communication Protocols/MultiProtocolAttacks/*.spdl

View File

@ -232,8 +232,9 @@ def MyScyther(protocollist,filt=None,options=[],checkpickle=True):
for protocol in sorted(protocollist): for protocol in sorted(protocollist):
s.addFile(protocol) s.addFile(protocol)
if checkpickle and OPTS.pickle: if checkpickle and OPTS.pickle:
# Do not really verify! Just dump request # Do not really verify! Just dump request if not already known
PICKLEDATA.add((tuple(sorted(protocollist)),s.options,filt)) if s.verifyOne(filt, checkKnown=True) == False:
PICKLEDATA.add((tuple(sorted(protocollist)),s.options,filt))
else: else:
# Verify results # Verify results
s.verifyOne(filt) s.verifyOne(filt)