Changeset af25848


Ignore:
Timestamp:
Sep 15, 2010 2:25:01 AM (14 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master
Children:
87c0fc1
Parents:
5a721ed
Message:

Comments

File:
1 edited

Legend:

Unmodified
Added
Removed
  • fedd/access_to_abac.py

    r5a721ed raf25848  
    88
    99class attribute:
     10    '''
     11    Encapculate a principal/attribute pair.
     12    '''
    1013    def __init__(self, p, a):
    1114        self.principal = p
     
    1316
    1417    def __str__(self):
    15         return "%s.%s" % (self.principal, self.attr)
     18        if self.attr:
     19            return "%s.%s" % (self.principal, self.attr)
     20        else:
     21            return "%s" % self.principal
    1622
    1723class credential:
     24    '''
     25    A Credential, that is the requisites (as attributes) and the assigned
     26    attribute (as principal, attr).   If req is iterable, the requirements are
     27    an intersection/conjunction.
     28    '''
    1829    def __init__(self, p, a, req):
    1930        self.principal = p
     
    3142            return "%s.%s <- %s" % (self.principal, self.attr, self.req)
    3243
     44# Mappinng generation functiona and the access parser throw these when there is
     45# a parsing problem.
    3346class parse_error(RuntimeError): pass
    3447
     48# Functions to parse the individual access maps as well as an overall function
     49# to parse generic ones.  The specific ones create a credential to local
     50# attributes mapping and the global one creates the access policy credentials.
     51
     52#  All the local parsing functions get the unparsed remainder of the line
     53#  (after the three-name and the attribute it maps to), the credential list to
     54#  add the new ABAC credential(s) that will be mapped into the loacl
     55#  credentials, the fedid of this entity, a dict mapping the local credentials
     56#  to ABAC credentials that are required to exercise those local rights and the
     57#  three-name (p, gp, gu) that is being mapped.
    3558def parse_emulab(l, creds, me, to_id, p, gp, gu):
     59    '''
     60    Parse the emulab (project, allocation_user, access_user) format.  Access
     61    users are deprecates and allocation users used for both.  This fuction
     62    collapses them.
     63    '''
    3664    right_side_str = '\s*,\s*\(\s*%s\s*,\s*%s\s*,\s*%s\s*\)' % \
    3765            (id_same_str, id_same_str,id_same_str)
     
    4068    if m:
    4169        project, user = m.group(1,2)
     70        # Resolve "<same>"s in project and user
    4271        if project == '<same>':
    4372            if gp  is not None:
     
    5079            else:
    5180                raise parse_error("User cannot be decisively mapped: %s" % l)
     81
     82        # Create a semi-mnemonic name for the destination credential (the one
     83        # that will be mapped to the local attributes
    5284        if project and user:
    5385            a = 'project_%s_user_%s' % (project, user)
     
    5991            raise parse_error("No mapping for %s/%s!?" % (gp, gu))
    6092
     93        # Store the creds and map entries
    6194        c = credential(me, a,
    6295                [attribute(p, x) for x in (gp, gu) if x is not None])
     
    69102
    70103def parse_protogeni(l, creds, me, to_id, p, gp, gu):
     104    '''
     105    Parse the protoGENI (cert, user, user_key, cert_pw) format.
     106    '''
    71107    right_side_str = '\s*,\s*\(\s*(%s)\s*,\s*(%s)\s*,\s*(%s)\s*,\s*(%s)\s*\)' \
    72108            % (path_str, id_str, path_str, id_str)
     
    75111    if m:
    76112        cert, user, key, pw = m.group(1,2,3,4)
     113        # The credential is formed from just the path (with / mapped to _) and
     114        # the username.
    77115        acert = re.sub('/', '_', cert)
    78116
    79117        a = "cert_%s_user_%s" % (acert, user)
     118
     119        # Store em
    80120        c = credential(me, a,
    81121                [attribute(p, x) for x in (gp, gu) if x is not None])
     
    89129
    90130def parse_dragon(l, creds, me, to_id, p, gp, gu):
     131    '''
     132    Parse the dragon (repository_name) version.
     133    '''
    91134    right_side_str = '\s*,\s*\(\s*(%s)\s*\)' % \
    92135            (id_str)
     
    103146        raise parse_error("Badly formatted local mapping: %s" % l)
    104147
    105 parse_skel = parse_dragon
    106 
     148def parse_skel(l, creds, me, to_id, p, gp, gu):
     149    '''
     150    Parse the skeleton (local_attr) version.
     151    '''
     152    right_side_str = '\s*,\s*\(\s*(%s)\s*\)' % \
     153            (id_str)
     154
     155    m = re.match(right_side_str, l)
     156    if m:
     157        lattr = m.group(1)
     158        c = credential(me, 'lattr_%s' % lattr,
     159                [attribute(p, x) for x in (gp, gu) if x is not None])
     160        creds.add(c)
     161        if lattr in to_id: to_id[lattr].append(c)
     162        else: to_id[lattr] = [ c ]
     163    else:
     164        raise parse_error("Badly formatted local mapping: %s" % l)
     165
     166# internal plug-ins have no local attributes.
    107167def parse_internal(l, creds, me, to_id, p, gp, gu): pass
    108168
    109169
    110170class access_opts(OptionParser):
     171    '''
     172    Parse the options for this program.  Most are straightforward, but the
     173    mapper uses a callback to convert from a string to a local mapper function.
     174    '''
     175    # Valid mappers
    111176    mappers = {
    112177            'emulab': parse_emulab,
     
    149214
    150215def create_creds(creds, cert, key, dir, creddy='/usr/local/bin/creddy'):
     216    '''
     217    Make the creddy calls to create the attributes from the list of credential
     218    objects in the creds parameter.
     219    '''
    151220    def attrs(r):
     221        '''
     222        Convert an attribute into creddy --subject-id and --subject-role
     223        parameters
     224        '''
    152225        if r.principal and r.attr:
    153226            return ['--subject-id=%s' % r.principal,
     
    158231            raise parse_error('Attribute without a principal?')
    159232
     233    # main line of create_creds
    160234    for i, c in enumerate(creds):
    161235        cmd = [creddy, '--attribute', '--issuer=%s' % cert, '--key=%s' % key,
     
    165239        print " ".join(cmd)
    166240
     241# Regular expressions and parts thereof for parsing
    167242comment_re = re.compile('^\s*#|^$')
    168243fedid_str = 'fedid:([0-9a-fA-F]{40})'
     
    179254opts, args = p.parse_args()
    180255
     256# Validate arguments
    181257if len(args) < 1:
    182258    sys.exit('No filenames given to parse')
     
    202278mapper = opts.mapper
    203279
     280# Do the parsing
    204281for fn in args:
    205282    creds = set()
     
    227304                        raise parse_error('Syntax error')
    228305            except parse_error, e:
     306                f.close()
    229307                raise parse_error('Error on line %d of %s: %s' % \
    230308                        (i, fn, e.message))
     
    240318        continue
    241319
     320    # Credential output
    242321    if opts.create_creds:
    243322        if all([opts.cert, opts.key, opts.dir]):
     
    247326            print >>sys.stderr, 'Cannot create credentials.  Missing parameter'
    248327
     328    # Local map output
    249329    if not opts.quiet:
    250330        for k, c in to_id.items():
Note: See TracChangeset for help on using the changeset viewer.