Ignore:
Timestamp:
Dec 10, 2010 3:27:05 PM (13 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master
Children:
3fa4328
Parents:
b67fd22
Message:

Make common ops use fewer options. Refactor.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • fedd/fedd_to_abac.py

    rb67fd22 re65150a  
    77import os.path
    88import subprocess
     9from tempfile import mkdtemp
    910
    1011from string import join
    1112
     13from federation.authorizer import abac_authorizer
    1214from federation.util import abac_pem_type, abac_split_cert, file_expanding_opts
    1315
     
    2830        self.add_option('--debug', action='store_true', dest='debug',
    2931                default=False, help='Just print the creddy commands')
     32        self.add_option('--policy_only', action='store_const', const=False,
     33                dest='make_authorizer', default=True,
     34                help='Only create the directory of certs, " + \
     35                        "do not create an authorizer')
     36        self.add_option('--update', action='store_const', const=True,
     37                dest='update_authorizer', default=False,
     38                help='Add the generated policy to an existing authorizer')
    3039
    3140class identity:
     
    4049        return "%s: %s" % (self.name, join(self.roles, ', '))
    4150
    42 comment_re = re.compile('^\s*#|^$')
    43 fedid_str = 'fedid:([0-9a-fA-F]{40})'
    44 id_str = '[a-zA-Z][\w_-]*'
    45 single_re = re.compile('\s*%s\s*->\s*(%s)' % (fedid_str, id_str))
    46 double_re = re.compile('\s*%s\s*->\s*\((%s)\s*,\s*(%s)\)' % \
    47         (fedid_str, id_str, id_str))
    48 bad_role = re.compile('[^a-zA-Z0-9_]+')
     51def clear_dir(dir):
     52    for path, dirs, files in os.walk(dir, topdown=False):
     53        for f in files: os.unlink(os.path.join(path, f))
     54        for d in dirs: os.rmdir(os.path.join(path, d))
     55
     56def parse_configs(files):
     57    """
     58    Step through each file pulling the roles out of the database lines, if any,
     59    and creating (or appending to) identity objects, one identity in a dict for
     60    each  fedid.  Return that dict.  May raise an exception when file
     61    difficulties occur.
     62    """
     63    comment_re = re.compile('^\s*#|^$')
     64    fedid_str = 'fedid:([0-9a-fA-F]{40})'
     65    id_str = '[a-zA-Z][\w_-]*'
     66    single_re = re.compile('\s*%s\s*->\s*(%s)' % (fedid_str, id_str))
     67    double_re = re.compile('\s*%s\s*->\s*\((%s)\s*,\s*(%s)\)' % \
     68            (fedid_str, id_str, id_str))
     69    bad_role = re.compile('[^a-zA-Z0-9_]+')
     70
     71    roles = { }
     72
     73    for fn in files:
     74        f = open(fn, "r")
     75        for l in f:
     76            id = None
     77            for r in (comment_re, single_re, double_re):
     78                m = r.match(l)
     79                if m:
     80                    # NB, the comment_re has no groups
     81                    if m.groups():
     82                        g = m.groups()
     83                        id = g[0]
     84                        r = [ bad_role.sub('_', x) for x in g[1:] ]
     85                    break
     86            else:
     87                print 'Unmatched line: %s' % l
     88
     89            if id:
     90                # New and create are implicit.  >sigh<
     91                r.extend(('new', 'create'))
     92                if id in roles: roles[id].add_roles(r)
     93                else: roles[id] = identity(r[0], r)
     94
     95    return roles
     96
     97def make_credentials(roles, cert, key, creds_dir, debug):
     98    """
     99    From the dict of identities, indexed by fedid, call creddy to create the
     100    ABAC certificates.  Return a list of the created files.  If debug is true,
     101    just print the creddy commands.
     102    """
     103    credfiles = []
     104    for k, id in roles.items():
     105        for i, r in enumerate(id.roles):
     106            cf = '%s/%s%03d_attr.der' % \
     107                    (creds_dir or 'new_cert_dir', id.name, i)
     108            cmd = ['creddy', '--attribute',
     109                    '--issuer=%s' % (cert or 'cert_file'),
     110                    '--key=%s' % (key or 'key_file'), '--role=%s' % r,
     111                    '--subject-id=%s' % k, '--out=%s' % cf ]
     112            if debug:
     113                print join(cmd)
     114            else:
     115                rv =  subprocess.call(cmd)
     116                if rv != 0:
     117                    raise RuntimeError('%s failed: %d' % (join(cmd), rv))
     118                else:
     119                    credfiles.append(cf)
     120    return credfiles
    49121
    50122parser = Parser()
     
    53125delete_certs = False
    54126
    55 
     127if not opts.make_authorizer and opts.update_authorizer:
     128    sys.exit('--policy_only and --update are in conflict.  Pick one.')
    56129
    57130if opts.key:
     
    72145            sys.exit('%s is not writable' % opts.dir)
    73146
     147if opts.make_authorizer:
     148    creds_dir = mkdtemp()
     149    delete_creds = True
     150else:
     151    creds_dir = opts.dir
     152    delete_creds = False
     153
    74154if opts.cert:
    75155    if os.access(opts.cert, os.R_OK):
     
    90170    debug = opts.debug
    91171
    92 roles = { }
    93172try:
    94     for fn in args:
    95         try:
    96             f = open(fn, "r")
    97             for l in f:
    98                 id = None
    99                 for r in (comment_re, single_re, double_re):
    100                     m = r.match(l)
    101                     if m:
    102                         if m.groups():
    103                             g = m.groups()
    104                             id = g[0]
    105                             r = [ bad_role.sub('_', x) for x in g[1:] ]
    106                         break
    107                 else:
    108                     print 'Unmatched line: %s' % l
    109                 if id:
    110                     # New and create are implicit.  >sigh<
    111                     r.extend(('new', 'create'))
    112                     if id in roles: roles[id].add_roles(r)
    113                     else: roles[id] = identity(r[0], r)
    114 
    115         except EnvironmentError, e:
    116             print >>sys.stderr, 'Cannot open file (%s): %s' % \
    117                     (e.filename, e.strerror)
    118 
     173    roles = parse_configs(args)
    119174    if not roles:
    120175        print >>sys.stderr, "No roles found.  Did you specify a configuration?"
    121176
    122     for k, id in roles.items():
    123         for i, r in enumerate(id.roles):
    124             cmd = ['creddy', '--attribute',
    125                     '--issuer=%s' % (cert or 'cert_file'),
    126                     '--key=%s' % (key or 'key_file'), '--role=%s' % r,
    127                     '--subject-id=%s' % k,
    128                     '--out=%s/%s%03d_attr.der' % \
    129                             (opts.dir or 'new_cert_dir', id.name, i)]
     177    try:
     178        credfiles = make_credentials(roles, cert, key, creds_dir, debug)
     179
     180        if opts.make_authorizer:
    130181            if debug:
    131                 print join(cmd)
     182                print >>sys.stderr, 'Debug mode, no authorizer created'
     183            elif opts.update_authorizer:
     184                operation = 'updat'
     185                a = abac_authorizer(load=opts.dir)
     186                a.import_credentials(file_list=credfiles)
     187                a.save()
    132188            else:
    133                 rv =  subprocess.call(cmd)
    134                 if rv != 0:
    135                     sys.exit('%s failed: %d' % (join(cmd), rv))
     189                operation = 'creat'
     190                a = abac_authorizer(key=opts.key, me=opts.cert,
     191                        certs=creds_dir, save=opts.dir)
     192                a.save()
     193    except EnvironmentError, e:
     194        sys.exit("Can't create or write %s: %s" % (e.filename,
     195            e.strerror))
     196    except abac_authorizer.bad_cert_error, e:
     197        sys.exit("Error %sing authorizer: %s" % (op, e))
     198    except RuntimeError, e:
     199        sys.exit('%s' % e)
     200
    136201finally:
    137202    if delete_certs:
    138203        if cert: os.unlink(cert)
    139204        if key: os.unlink(key)
     205    if delete_creds:
     206        clear_dir(creds_dir)
     207        os.rmdir(creds_dir)
Note: See TracChangeset for help on using the changeset viewer.