Changeset 87807f42
- Timestamp:
- Sep 21, 2010 2:33:47 PM (14 years ago)
- Branches:
- axis_example, compt_changes, info-ops, master
- Children:
- 5d854e1
- Parents:
- aba14f4
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
fedd/access_to_abac.py
raba14f4 r87807f42 3 3 import sys, os 4 4 import re 5 5 import subprocess 6 7 from string import join 6 8 from federation.fedid import fedid 7 9 from optparse import OptionParser, OptionValueError 8 10 11 9 12 class attribute: 10 13 ''' 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): 14 18 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 16 22 17 23 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: 19 27 return "%s.%s" % (self.principal, self.attr) 20 28 else: … … 27 35 an intersection/conjunction. 28 36 ''' 37 bad_attr = re.compile('[^a-zA-Z0-9_]+') 29 38 def __init__(self, p, a, req): 30 39 self.principal = p 31 40 if isinstance(a, (tuple, list, set)) and len(a) == 1: 32 self.attr = a[0]33 else: 34 self.attr = a41 self.attr = credential.bad_attr.sub('_', a[0]) 42 else: 43 self.attr = credential.bad_attr.sub('_', a) 35 44 self.req = req 36 45 … … 38 47 if isinstance(self.req, (tuple, list, set)): 39 48 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], ' & ')) 41 50 else: 42 51 return "%s.%s <- %s" % (self.principal, self.attr, self.req) … … 45 54 # a parsing problem. 46 55 class parse_error(RuntimeError): pass 56 57 # Error creating a credential 58 class credential_error(RuntimeError): pass 47 59 48 60 # Functions to parse the individual access maps as well as an overall function … … 56 68 # to ABAC credentials that are required to exercise those local rights and the 57 69 # three-name (p, gp, gu) that is being mapped. 58 def parse_emulab(l, creds, me, to_id, p, gp, gu ):70 def parse_emulab(l, creds, me, to_id, p, gp, gu, lr): 59 71 ''' 60 72 Parse the emulab (project, allocation_user, access_user) format. Access … … 93 105 # Store the creds and map entries 94 106 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]) 96 108 creds.add(c) 97 109 if (project, user) in to_id: to_id[(project,user)].append(c) … … 101 113 102 114 103 def parse_protogeni(l, creds, me, to_id, p, gp, gu ):115 def parse_protogeni(l, creds, me, to_id, p, gp, gu, lr): 104 116 ''' 105 117 Parse the protoGENI (cert, user, user_key, cert_pw) format. … … 119 131 # Store em 120 132 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]) 122 134 creds.add(c) 123 135 if (cert, user, key, pw) in to_id: … … 128 140 raise parse_error("Badly formatted local mapping: %s" % l) 129 141 130 def parse_dragon(l, creds, me, to_id, p, gp, gu ):142 def parse_dragon(l, creds, me, to_id, p, gp, gu, lr): 131 143 ''' 132 144 Parse the dragon (repository_name) version. … … 139 151 repo= m.group(1) 140 152 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]) 142 154 creds.add(c) 143 155 if repo in to_id: to_id[repo].append(c) … … 146 158 raise parse_error("Badly formatted local mapping: %s" % l) 147 159 148 def parse_skel(l, creds, me, to_id, p, gp, gu ):160 def parse_skel(l, creds, me, to_id, p, gp, gu, lr): 149 161 ''' 150 162 Parse the skeleton (local_attr) version. … … 157 169 lattr = m.group(1) 158 170 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]) 160 172 creds.add(c) 161 173 if lattr in to_id: to_id[lattr].append(c) … … 165 177 166 178 # internal plug-ins have no local attributes. 167 def parse_internal(l, creds, me, to_id, p, gp, gu ): pass179 def parse_internal(l, creds, me, to_id, p, gp, gu, lr): pass 168 180 169 181 … … 188 200 else: 189 201 raise OptionValueError('%s must be one of %s' % \ 190 (s, ", ".join(access_opts.mappers.keys())))202 (s, join(access_opts.mappers.keys(), ', '))) 191 203 192 204 def __init__(self): … … 202 214 callback_kwargs = { 'dest': 'mapper'}, 203 215 help='Type of access file to parse. One of %s. ' %\ 204 ", ".join(access_opts.mappers.keys()) + \216 join(access_opts.mappers.keys(), ', ') + \ 205 217 'Omit for generic parsing.') 206 218 self.add_option('--quiet', dest='quiet', action='store_true', … … 211 223 help='create credentials for rules. Requires ' + \ 212 224 '--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') 213 236 self.set_defaults(mapper=None) 214 237 215 def create_creds(creds, cert, key, dir, creddy='/usr/local/bin/creddy'): 238 def create_creds(creds, cert, key, dir, debug=False, 239 creddy='/usr/local/bin/creddy'): 216 240 ''' 217 241 Make the creddy calls to create the attributes from the list of credential … … 223 247 parameters 224 248 ''' 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: 226 254 return ['--subject-id=%s' % r.principal, 227 255 '--subject-role=%s' %r.attr] … … 237 265 for r in c.req: 238 266 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)) 240 273 241 274 # Regular expressions and parts thereof for parsing … … 254 287 opts, args = p.parse_args() 255 288 289 if opts.file: 290 args.append(opts.file) 291 256 292 # Validate arguments 257 293 if len(args) < 1: … … 275 311 elif not os.access(opts.dir, os.W_OK): 276 312 sys.exit('%s is not writable' % opts.dir) 313 314 if opts.delegate: delegation_link = 'acting_for' 315 else: delegation_link = None 277 316 278 317 mapper = opts.mapper … … 297 336 298 337 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])) 301 341 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) 303 344 else: 304 345 raise parse_error('Syntax error') … … 321 362 if opts.create_creds: 322 363 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) 325 369 else: 326 370 print >>sys.stderr, 'Cannot create credentials. Missing parameter' 327 371 328 372 # 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.