Changeset 87807f42 for fedd


Ignore:
Timestamp:
Sep 21, 2010 2:33:47 PM (14 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master
Children:
5d854e1
Parents:
aba14f4
Message:

actual creddy output

File:
1 edited

Legend:

Unmodified
Added
Removed
  • fedd/access_to_abac.py

    raba14f4 r87807f42  
    33import sys, os
    44import re
    5 
     5import subprocess
     6
     7from string import join
    68from federation.fedid import fedid
    79from optparse import OptionParser, OptionValueError
    810
     11
    912class attribute:
    1013    '''
    11     Encapculate a principal/attribute pair.
    12     '''
    13     def __init__(self, p, a):
     14    Encapculate a principal/attribute/link tuple.
     15    '''
     16    bad_attr = re.compile('[^a-zA-Z0-9_]+')
     17    def __init__(self, p, a, l=None):
    1418        self.principal = p
    15         self.attr = a
     19        self.attr = attribute.bad_attr.sub('_', a)
     20        if l: self.link = attribute.bad_attr.sub('_', l)
     21        else: self.link = None
    1622
    1723    def __str__(self):
    18         if self.attr:
     24        if self.link:
     25            return "%s.%s.%s" % (self.principal, self.attr, self.link)
     26        elif self.attr:
    1927            return "%s.%s" % (self.principal, self.attr)
    2028        else:
     
    2735    an intersection/conjunction.
    2836    '''
     37    bad_attr = re.compile('[^a-zA-Z0-9_]+')
    2938    def __init__(self, p, a, req):
    3039        self.principal = p
    3140        if isinstance(a, (tuple, list, set)) and len(a) == 1:
    32             self.attr = a[0]
    33         else:
    34             self.attr = a
     41            self.attr = credential.bad_attr.sub('_', a[0])
     42        else:
     43            self.attr = credential.bad_attr.sub('_', a)
    3544        self.req = req
    3645
     
    3847        if isinstance(self.req, (tuple, list, set)):
    3948            return "%s.%s <- %s" % (self.principal, self.attr,
    40                     " & ".join(["%s" % r for r in self.req]))
     49                    join(["%s" % r for r in self.req], ' & '))
    4150        else:
    4251            return "%s.%s <- %s" % (self.principal, self.attr, self.req)
     
    4554# a parsing problem.
    4655class parse_error(RuntimeError): pass
     56
     57# Error creating a credential
     58class credential_error(RuntimeError): pass
    4759
    4860# Functions to parse the individual access maps as well as an overall function
     
    5668#  to ABAC credentials that are required to exercise those local rights and the
    5769#  three-name (p, gp, gu) that is being mapped.
    58 def parse_emulab(l, creds, me, to_id, p, gp, gu):
     70def parse_emulab(l, creds, me, to_id, p, gp, gu, lr):
    5971    '''
    6072    Parse the emulab (project, allocation_user, access_user) format.  Access
     
    93105        # Store the creds and map entries
    94106        c = credential(me, a,
    95                 [attribute(p, x) for x in (gp, gu) if x is not None])
     107                [attribute(p, x, lr) for x in (gp, gu) if x is not None])
    96108        creds.add(c)
    97109        if (project, user) in to_id: to_id[(project,user)].append(c)
     
    101113
    102114
    103 def parse_protogeni(l, creds, me, to_id, p, gp, gu):
     115def parse_protogeni(l, creds, me, to_id, p, gp, gu, lr):
    104116    '''
    105117    Parse the protoGENI (cert, user, user_key, cert_pw) format.
     
    119131        # Store em
    120132        c = credential(me, a,
    121                 [attribute(p, x) for x in (gp, gu) if x is not None])
     133                [attribute(p, x, lr) for x in (gp, gu) if x is not None])
    122134        creds.add(c)
    123135        if (cert, user, key, pw) in to_id:
     
    128140        raise parse_error("Badly formatted local mapping: %s" % l)
    129141
    130 def parse_dragon(l, creds, me, to_id, p, gp, gu):
     142def parse_dragon(l, creds, me, to_id, p, gp, gu, lr):
    131143    '''
    132144    Parse the dragon (repository_name) version.
     
    139151        repo= m.group(1)
    140152        c = credential(me, 'repo_%s' % repo,
    141                 [attribute(p, x) for x in (gp, gu) if x is not None])
     153                [attribute(p, x, lr) for x in (gp, gu) if x is not None])
    142154        creds.add(c)
    143155        if repo in to_id: to_id[repo].append(c)
     
    146158        raise parse_error("Badly formatted local mapping: %s" % l)
    147159
    148 def parse_skel(l, creds, me, to_id, p, gp, gu):
     160def parse_skel(l, creds, me, to_id, p, gp, gu, lr):
    149161    '''
    150162    Parse the skeleton (local_attr) version.
     
    157169        lattr = m.group(1)
    158170        c = credential(me, 'lattr_%s' % lattr,
    159                 [attribute(p, x) for x in (gp, gu) if x is not None])
     171                [attribute(p, x, lr) for x in (gp, gu) if x is not None])
    160172        creds.add(c)
    161173        if lattr in to_id: to_id[lattr].append(c)
     
    165177
    166178# internal plug-ins have no local attributes.
    167 def parse_internal(l, creds, me, to_id, p, gp, gu): pass
     179def parse_internal(l, creds, me, to_id, p, gp, gu, lr): pass
    168180
    169181
     
    188200        else:
    189201            raise OptionValueError('%s must be one of %s' % \
    190                     (s, ", ".join(access_opts.mappers.keys())))
     202                    (s, join(access_opts.mappers.keys(), ', ')))
    191203
    192204    def __init__(self):
     
    202214                callback_kwargs = { 'dest': 'mapper'},
    203215                help='Type of access file to parse.  One of %s. ' %\
    204                         ", ".join(access_opts.mappers.keys()) + \
     216                        join(access_opts.mappers.keys(), ', ') + \
    205217                        'Omit for generic parsing.')
    206218        self.add_option('--quiet', dest='quiet', action='store_true',
     
    211223                help='create credentials for rules.  Requires ' + \
    212224                        '--cert, --key, and --dir to be given.')
     225        self.add_option('--file', dest='file', default=None,
     226                help='Access DB to parse.  If this is present, ' + \
     227                        'omit the positional filename')
     228        self.add_option('--mapfile', dest='map', default=None,
     229                help='File for the attribute to local authorization data')
     230        self.add_option('--no-delegate', action='store_false', dest='delegate',
     231                default=True,
     232                help='do not accept delegated attributes with the ' +\
     233                        'acting_for linking role')
     234        self.add_option('--debug', action='store_true', dest='debug',
     235                default=False, help='Just print actions')
    213236        self.set_defaults(mapper=None)
    214237
    215 def create_creds(creds, cert, key, dir, creddy='/usr/local/bin/creddy'):
     238def create_creds(creds, cert, key, dir, debug=False,
     239        creddy='/usr/local/bin/creddy'):
    216240    '''
    217241    Make the creddy calls to create the attributes from the list of credential
     
    223247        parameters
    224248        '''
    225         if r.principal and r.attr:
     249        if r.principal and r.link and r.attr:
     250            return ['--subject-id=%s' % r.principal,
     251                    '--subject-role=%s.%s' % (r.attr, r.link),
     252                    ]
     253        elif r.principal and r.attr:
    226254            return ['--subject-id=%s' % r.principal,
    227255                    '--subject-role=%s' %r.attr]
     
    237265        for r in c.req:
    238266            cmd.extend(attrs(r))
    239         print " ".join(cmd)
     267        if debug:
     268            print join(cmd)
     269        else:
     270            rv = subprocess.call(cmd)
     271            if rv != 0:
     272                raise credential_error("%s: %d" % (join(cmd), rv))
    240273
    241274# Regular expressions and parts thereof for parsing
     
    254287opts, args = p.parse_args()
    255288
     289if opts.file:
     290    args.append(opts.file)
     291
    256292# Validate arguments
    257293if len(args) < 1:
     
    275311    elif not os.access(opts.dir, os.W_OK):
    276312        sys.exit('%s is not writable' % opts.dir)
     313
     314if opts.delegate: delegation_link = 'acting_for'
     315else: delegation_link = None
    277316
    278317mapper = opts.mapper
     
    297336
    298337                        creds.add(credential(me, da,
    299                                 [attribute(p, x) for x in (gp, gu) \
    300                                     if x is not None]))
     338                                [attribute(p, x, delegation_link) \
     339                                        for x in (gp, gu) \
     340                                            if x is not None]))
    301341                        if m.group(5) and mapper:
    302                             mapper(m.group(5), creds, me, to_id, p, gp, gu)
     342                            mapper(m.group(5), creds, me, to_id, p, gp, gu,
     343                                    delegation_link)
    303344                    else:
    304345                        raise parse_error('Syntax error')
     
    321362    if opts.create_creds:
    322363        if all([opts.cert, opts.key, opts.dir]):
    323             create_creds([c for c in creds if c.principal == me],
    324                     opts.cert, opts.key, opts.dir)
     364            try:
     365                create_creds([c for c in creds if c.principal == me],
     366                        opts.cert, opts.key, opts.dir, opts.debug)
     367            except credential_error, e:
     368                sys.exit('Credential creation failed: %s' % e)
    325369        else:
    326370            print >>sys.stderr, 'Cannot create credentials.  Missing parameter'
    327371
    328372    # Local map output
    329     if not opts.quiet:
    330         for k, c in to_id.items():
    331             for a in set(["%s.%s" % (x.principal, x.attr) for x in c]):
    332                 print "%s -> (%s)" % ( a, ", ".join(k))
     373    if opts.map or opts.debug:
     374        try:
     375            if opts.map and opts.map != '-' and not opts.debug:
     376                f = open(opts.map, 'w')
     377            else:
     378                f = sys.stdout
     379            for k, c in to_id.items():
     380                for a in set(["%s.%s" % (x.principal, x.attr) for x in c]):
     381                    print >>f, "%s -> (%s)" % ( a, join(k, ', '))
     382        except EnvironmentError, e:
     383            sys.exit("Cannot open %s: %s" % (e.filename or '!?', e.strerror))
Note: See TracChangeset for help on using the changeset viewer.