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
not written to a file.
"""
p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
p = Popen(cmd, shell=getShell(), stdout=PIPE, stderr=PIPE)
(sout,serr) = p.communicate()
return (p.returncode,sout,serr)
@ -115,7 +114,7 @@ def safeCommand(cmd):
""" Execute a command with some arguments. Safe cross-platform
version, I hope. """
p = Popen(cmd, shell=True)
p = Popen(cmd, shell=getShell())
sts = p.wait()
return sts

View File

@ -1,7 +1,7 @@
#!/usr/bin/python
"""
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
modify it under the terms of the GNU General Public License
@ -241,14 +241,19 @@ class Scyther(object):
for arg in arglist:
self.options += " %s" % (arg)
def doScytherCommand(self, spdl, args):
def doScytherCommand(self, spdl, args, checkKnown=False):
"""
Cached version of the 'real' below
"""
global 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
m = hashlib.sha256()
@ -288,11 +293,20 @@ class Scyther(object):
fh2 = open(fname2,"r")
err = fh2.read()
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:
"""
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)
# Store result in cache
@ -380,8 +394,9 @@ class Scyther(object):
""" Sanitize some of the input """
self.options = EnsureString(self.options)
def verify(self,extraoptions=None):
def verify(self,extraoptions=None,checkKnown=False):
""" 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
self.sanitize()
@ -395,6 +410,10 @@ class Scyther(object):
# extraoptions might need sanitizing
args += " %s" % EnsureString(extraoptions)
# Are we only checking the cache?
if checkKnown == True:
return self.doScytherCommand(self.spdl, args, checkKnown=checkKnown)
# execute
(output,errors) = self.doScytherCommand(self.spdl, args)
self.run = True
@ -442,19 +461,21 @@ class Scyther(object):
else:
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
procedure below, 'scanClaims', or a full claim object
If checkKnown is True, return if the result is already known (but never recompute).
"""
if cl:
# We accept either a claim or a claim id
if isinstance(cl,Claim.Claim):
cl = cl.id
return self.verify("--filter=%s" % cl)
return self.verify("--filter=%s" % cl, checkKnown=checkKnown)
else:
# If no claim, then its just normal verification
return self.verify()
return self.verify(checkKnown=checkKnown)
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):
"""
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):
s.addFile(protocol)
if checkpickle and OPTS.pickle:
# Do not really verify! Just dump request
PICKLEDATA.add((tuple(sorted(protocollist)),s.options,filt))
# Do not really verify! Just dump request if not already known
if s.verifyOne(filt, checkKnown=True) == False:
PICKLEDATA.add((tuple(sorted(protocollist)),s.options,filt))
else:
# Verify results
s.verifyOne(filt)