#!/usr/local/bin/python import sys ; sys.path = ['../../../'] + sys.path import imp, os from sys import modules # Secure import: def secimport(name, globals=None, locals=None, fromlist=None): # Fast path: let's see if it's already in sys.modules. # Two speed optimizations are worth mentioning: # - We use 'modules' instead of 'sys.modules'; this saves a # dictionary look-up per call. # - It's also faster to use a try-except statement than # to use modules.has_key(name) to check if it's there. try: return modules[name] except KeyError: pass # See if it's a built-in module m = imp.init_builtin(name) if m: return m # See if it's a frozen module m = imp.init_frozen(name) if m: return m # Search the default path (i.e. sys.path). # If this raises an exception, the module is not found -- # let the caller handle the exception. fp, pathname, (suffix, mode, type) = imp.find_module(name) # See what we got... # Note that fp will be closed automatically when we return. # Extensions are written in C, and can just be loaded. if type == imp.C_EXTENSION: return imp.load_dynamic(name, pathname) # For a compiled or source file, we'll check if there is a *.pys file # present in the same directory. if type == imp.PY_COMPILED or type == imp.PY_SOURCE: root, ext = os.path.splitext(pathname) testfile = root + '.pys' try: print testfile secfile=open(testfile, 'rb') except IOError, tuple: if (tuple[0]==2): pass # Ignore 'file not found' error else: raise IOError, tuple else: # Check the signature (a signed hash of the code object). # We could sign the whole code object, but that would # require a huge key and would double the size of the # *.pys file. import marshal from Crypto.Hash import MD5 fp.close() # Close the original *.pyc file from testkey import * # Get the key for verification signature=marshal.load(secfile) # Read signature position=secfile.tell() # Save position data=secfile.read() # Read code object hash=MD5.new(data).digest() # Compute its hash value ##print 'sigcheck:', key.verify(hash, signature) if (not key.verify(hash, signature)): raise ImportError, 'Signature check of '+ testfile + ' failed' secfile.seek(position) # Rewind pointer to the # beginning of the code object fp=secfile del secfile # Now we can happily import the compiled code object. return imp.load_compiled(name, pathname, fp) # Shouldn't get here at all. raise ImportError, '%s: unknown module type (%d)' % (name, type) if __name__=='__main__': # A sample invocation of the secure import looks like this: print 'Attempting secure import' r=secimport('testkey') print 'Secure import succeeded'