source: fedd/fedd_to_abac.py @ 1f356d3

axis_examplecompt_changesinfo-ops
Last change on this file since 1f356d3 was c573278, checked in by Ted Faber <faber@…>, 13 years ago

Checkpoint. Still lots to do

  • Property mode set to 100755
File size: 3.6 KB
Line 
1#!/usr/local/bin/python
2
3import sys
4import re
5
6import os
7import os.path
8import subprocess
9
10from string import join
11from optparse import OptionParser
12
13from federation.util import abac_pem_type, abac_split_cert
14
15class Parser(OptionParser):
16    def __init__(self):
17        OptionParser.__init__(self)
18        self.add_option('--cert', dest='cert', default=None,
19                help='my fedid as an X.509 certificate')
20        self.add_option('--key', dest='key', default=None,
21                help='key for the certificate')
22        self.add_option('--dir', dest='dir', default=None,
23                help='Output directory for credentials')
24        self.add_option('--make-dir', action='store_true', dest='make_dir',
25                default=False, help='Create the --dir directory')
26        self.add_option('--debug', action='store_true', dest='debug',
27                default=False, help='Just print the creddy commands')
28
29class identity:
30    def __init__(self, name, roles=None):
31        self.name = name
32        if roles: self.roles = set(roles)
33
34    def add_roles(self, roles):
35        self.roles |= set(roles)
36
37    def __str__(self):
38        return "%s: %s" % (self.name, join(self.roles, ', '))
39
40comment_re = re.compile('^\s*#|^$')
41fedid_str = 'fedid:([0-9a-fA-F]{40})'
42id_str = '[a-zA-Z][\w_-]*'
43single_re = re.compile('\s*%s\s*->\s*(%s)' % (fedid_str, id_str))
44double_re = re.compile('\s*%s\s*->\s*\((%s)\s*,\s*(%s)\)' % \
45        (fedid_str, id_str, id_str))
46bad_role = re.compile('[^a-zA-Z0-9_]+')
47
48parser = Parser()
49opts, args = parser.parse_args()
50cert, key = None, None
51delete_certs = False
52
53
54
55if opts.key:
56    if os.access(opts.key, os.R_OK): key = opts.key
57    else: sys.exit('Cannot read %s (key file)' % opts.key)
58
59if opts.dir:
60    if opts.make_dir:
61        if not os.path.isdir(opts.dir) and not debug:
62            try:
63                os.mkdir(opts.dir, 0755)
64            except EnvironmentError, e:
65                sys.exit('Could not make %s: %s' % (opts.dir, e))
66    else:
67        if not os.path.isdir(opts.dir):
68            sys.exit('%s is not a directory' % opts.dir)
69        elif not os.access(opts.dir, os.W_OK):
70            sys.exit('%s is not writable' % opts.dir)
71
72if opts.cert:
73    if os.access(opts.cert, os.R_OK):
74        if not key:
75            if abac_pem_type(opts.cert) == 'both':
76                key, cert = abac_split_cert(opts.cert)
77                delete_certs = True
78        else:
79            cert = opts.cert
80    else:
81        sys.exit('Cannot read %s (certificate file)' % opts.cert)
82
83if any([ x is None for x in (cert, opts.dir, key)]):
84    print >>sys.stderr, "Need output dir, certificate and key to make creds"
85    print >>sys.stderr, "Reverting to debug mode"
86    debug = True
87else:
88    debug = opts.debug
89
90roles = { }
91try:
92    for fn in args:
93        try:
94            f = open(fn, "r")
95            for l in f:
96                id = None
97                for r in (comment_re, single_re, double_re):
98                    m = r.match(l)
99                    if m: 
100                        if m.groups():
101                            g = m.groups()
102                            id = g[0]
103                            r = [ bad_role.sub('_', x) for x in g[1:] ]
104                        break
105                else:
106                    print 'Unmatched line: %s' % l
107                if id:
108                    # New and create are implicit.  >sigh<
109                    r.extend(('new', 'create'))
110                    if id in roles: roles[id].add_roles(r)
111                    else: roles[id] = identity(r[0], r)
112
113        except EnvironmentError, e:
114            print >>sys.stderr, 'Cannot open file (%s): %s' % \
115                    (e.filename, e.strerror)
116
117    if not roles:
118        print >>sys.stderr, "No roles found.  Did you specify a configuration?"
119
120    for k, id in roles.items():
121        for i, r in enumerate(id.roles):
122            cmd = ['creddy', '--attribute', 
123                    '--issuer=%s' % (cert or 'cert_file'),
124                    '--key=%s' % (key or 'key_file'), '--role=%s' % r,
125                    '--subject-id=%s' % k,
126                    '--out=%s/%s%03d_attr.der' % \
127                            (opts.dir or 'new_cert_dir', id.name, i)]
128            if debug:
129                print join(cmd)
130            else:
131                rv =  subprocess.call(cmd)
132                if rv != 0:
133                    sys.exit('%s failed: %d' % (join(cmd), rv))
134finally:
135    if delete_certs:
136        if cert: os.unlink(cert)
137        if key: os.unlink(key)
Note: See TracBrowser for help on using the repository browser.