File: secimp.py

package info (click to toggle)
python-crypto 2.0.1%2Bdfsg1-2.3%2Blenny0
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 744 kB
  • ctags: 935
  • sloc: ansic: 6,597; python: 3,598; makefile: 28; sh: 10
file content (84 lines) | stat: -rw-r--r-- 3,178 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/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'