source: tools/policy/util.py @ 1d9b9cb

gec13
Last change on this file since 1d9b9cb was 25f26f5, checked in by Ted Faber <faber@…>, 12 years ago

Whoops. Forgot to add

  • Property mode set to 100755
File size: 3.4 KB
Line 
1#!/usr/local/bin/python
2
3import re
4import os
5import string
6
7from tempfile import mkstemp
8
9def abac_pem_type(cert):
10    key_re = re.compile('\s*-----BEGIN RSA PRIVATE KEY-----$')
11    cert_re = re.compile('\s*-----BEGIN CERTIFICATE-----$') 
12    type = None
13
14    f = open(cert, 'r')
15    for line in f:
16        if key_re.match(line):
17            if type is None: type = 'key'
18            elif type == 'cert': type = 'both'
19        elif cert_re.match(line):
20            if type is None: type = 'cert'
21            elif type == 'key': type = 'both'
22        if type == 'both': break
23    f.close()
24    return type
25
26def abac_split_cert(cert, keyfile=None, certfile=None):
27    """
28    Split the certificate file in cert into a certificate file and a key file
29    in cf and kf respectively.  The ABAC tools generally cannot handle combined
30    certificates/keys.  If kf anc cf are given, they are used, otherwise tmp
31    files are created.  Created tmp files must be deleted.  Problems opening or
32    writing files will cause exceptions.
33    """
34    class diversion:
35        '''
36        Wraps up the reqular expression to start and end a diversion, as well as
37        the open file that gets the lines.  If fd is passed in, use that system
38        file (probably from a mkstemp.  Otherwise open the given filename.
39        '''
40        def __init__(self, start, end, fn=None, fd=None):
41            self.start = re.compile(start)
42            self.end = re.compile(end)
43
44            if not fd:
45                # Open the file securely with minimal permissions. NB file
46                # cannot exist before this call.
47                fd = os.open(fn,
48                    (os.O_WRONLY | os.O_CREAT | os.O_TRUNC | os.O_EXCL), 0600)
49
50            self.f = os.fdopen(fd, 'w')
51
52        def close(self):
53            self.f.close()
54
55    if not keyfile:
56        kf, rkeyfile = mkstemp(suffix=".pem")
57    else:
58        kf, rkeyfile = None, keyfile
59
60    if not certfile:
61        cf, rcertfile = mkstemp(suffix=".pem")
62    else:
63        cf, rcertfile = None, certfile
64
65    # Initialize the diversions
66    divs = [diversion(s, e, fn=pfn, fd=pfd ) for s, e, pfn, pfd in (
67        ('\s*-----BEGIN RSA PRIVATE KEY-----$', 
68            '\s*-----END RSA PRIVATE KEY-----$',
69            keyfile, kf),
70        ('\s*-----BEGIN CERTIFICATE-----$', 
71            '\s*-----END CERTIFICATE-----$',
72            certfile, cf))]
73
74    # walk through the file, beginning a diversion when a start regexp
75    # matches until the end regexp matches.  While in the two regexps,
76    # print each line to the open diversion file (including the two
77    # matches).
78    active = None
79    f = open(cert, 'r')
80    for l in f:
81        if active:
82            if active.end.match(l):
83                print >>active.f, l,
84                active = None
85        else:
86            for d in divs:
87                if d.start.match(l):
88                    active = d
89                    break
90        if active: print >>active.f, l,
91
92    # This is probably unnecessary.  Close all the diversion files.
93    for d in divs: d.close()
94    return rkeyfile, rcertfile
95
96def abac_context_to_creds(context):
97    """
98    Pull all the credentials out of the context and return 2  lists of the
99    underlying credentials in an exportable format, IDs and attributes.
100    There are no duplicates in the lists.
101    """
102    ids, attrs = set(), set()
103    # This should be a one-iteration loop
104    for c in context.credentials():
105        ids.add(str(c.issuer_cert()))
106        attrs.add(str(c.attribute_cert()))
107
108    return list(ids), list(attrs)
109
110
111
112def remove_dirs(dname):
113    """
114    Remove the directory tree and all files rooted at dir.  Log any errors,
115    but continue.
116    """
117    for path, dirs, files in os.walk(dname, topdown=False):
118        for f in files:
119            os.remove(os.path.join(path, f))
120        for d in dirs:
121            os.rmdir(os.path.join(path, d))
122    os.rmdir(dname)
123
Note: See TracBrowser for help on using the repository browser.