Changeset 7206e5a


Ignore:
Timestamp:
Sep 23, 2010 5:44:47 PM (14 years ago)
Author:
Ted Faber <faber@…>
Branches:
axis_example, compt_changes, info-ops, master
Children:
835cf55
Parents:
09b1e9d
Message:

checkpoint: new works pretty well

Location:
fedd
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • fedd/fedd_new.py

    r09b1e9d r7206e5a  
    33import sys
    44
     5from federation.fedid import fedid, generate_fedid
    56from federation.remote_service import service_caller
    67from federation.client_lib import client_opts, exit_with_fault, RPCException, \
    7         wrangle_standard_options, do_rpc, get_experiment_names, save_certfile
     8        wrangle_standard_options, do_rpc, get_experiment_names, \
     9        save_certfile, get_abac_certs
    810
    911
     
    1517        self.add_option("--experiment_name", dest="exp_name",
    1618                type="string", help="Suggested experiment name")
     19        self.add_option('--gen-cert', action='store_true', dest='gen_cert',
     20                default=False,
     21                help='generate a cert to which to delegate rights')
    1722
    1823parser = new_opts()
     
    2025
    2126cert, fid, url = wrangle_standard_options(opts)
     27try:
     28    acerts = get_abac_certs(opts.abac_dir)
     29except EnvironmentError, e:
     30    sys.exit('%s: %s' % (e.filename, e.strerror))
    2231
    2332out_certfile = opts.out_certfile
     
    2534msg = { }
    2635
     36if opts.gen_cert:
     37    expid, expcert = generate_fedid(opts.exp_name or 'dummy')
     38    print expid
     39    msg['experimentAccess'] = { 'X509': expcert }
     40else:
     41    expcert = None
     42
    2743if opts.exp_name:
    2844    msg['experimentID'] = { 'localname': opts.exp_name }
     45
     46if acerts:
     47    msg['credential'] = acerts
    2948
    3049if opts.debug > 1: print >>sys.stderr, msg
     
    4463
    4564try:
    46     save_certfile(opts.out_certfile, resp_dict.get('experimentAccess', None))
    47 except EnvironmentError:
    48     sys.exit('Could not write to %s' %  out_certfile)
     65    save_certfile(opts.out_certfile, resp_dict.get('experimentAccess', None),
     66            expcert)
     67except EnvironmentError, e:
     68    sys.exit('Could not write to %s:' %  (e.strerror, e.filename))
     69except CertificateMismatchError:
     70    printf >>sys.stderr, "Fedid of created experiment does not match generated"
     71
    4972
    5073e_fedid, e_local = get_experiment_names(resp_dict.get('experimentID', None))
  • fedd/federation/authorizer.py

    r09b1e9d r7206e5a  
    152152        self.globals.discard(attr)
    153153
     154    def import_credentials(self, file_list=None, data_list=None):
     155        return False
     156
    154157    def __str__(self):
    155158        rv = ""
     
    182185    """
    183186
    184     clean_attr_re = re.compile('[^A-Za-z_]+')
     187    clean_attr_re = re.compile('[^A-Za-z0-9_]+')
    185188    cred_file_re = re.compile('.*\.der$')
    186189    bad_name = authorizer_base.bad_name
    187190    attribute_error = authorizer_base.attribute_error
    188     ABAC.libabac_init()
    189 
    190     def __init__(self, certs=None, me=None, key=None, loadfile=None):
     191    class no_file(RuntimeError): pass
     192
     193    def __init__(self, certs=None, me=None, key=None, load=None):
    191194        self.creddy = '/usr/local/bin/creddy'
    192195        self.globals = set()
     
    207210            self.context.load_directory(dir)
    208211
    209         if loadfile:
    210             self.load(loadfile)
     212        if load:
     213            self.save_dir = load
     214            self.load(load)
     215        else:
     216            self.save_dir = None
    211217
    212218    @staticmethod
    213219    def clean_attr(attr):
    214220        return abac_authorizer.clean_attr_re.sub('_', attr)
     221
     222    def import_credentials(self, file_list=None, data_list=None):
     223        if data_list:
     224            return any([self.import_credential(data=d) for d in data_list])
     225        elif file_list:
     226            return any([self.import_credential(file=f) for f in file_list])
     227        else:
     228            return False
     229
     230    def import_credential(self, file=None, data=None):
     231        if data:
     232            if self.context.load_id_chunk(data) != ABAC.ABAC_CERT_SUCCESS:
     233                return self.context.load_attribute_chunk(data) == \
     234                        ABAC.ABAC_CERT_SUCCESS
     235            else:
     236                return True
     237        elif file:
     238            if self.context.load_id_file(file) != ABAC.ABAC_CERT_SUCCESS:
     239                return self.context.load_attribute_file(file) == \
     240                        ABAC.ABAC_CERT_SUCCESS
     241            else:
     242                return True
     243        else:
     244            return False
    215245
    216246    def set_attribute(self, name=None, attr=None, cert=None):
     
    219249                raise abac_authorizer.bad_name(
    220250                        "ABAC doesn't understand three-names")
     251            # Convert non-string attributes to strings
     252            if not isinstance(attr, basestring):
     253                attr = "%s" % attr
    221254            if self.me and self.key:
    222255                # Create a credential and insert it into context
     
    261294            raise abac_authorizer.bad_name(
    262295                    "ABAC doesn't understand three-names")
     296        # Convert non-string attributes to strings
     297        if not isinstance(attr, basestring):
     298            attr = "%s" % attr
    263299        cattr = self.clean_attr(attr)
    264300        self.lock.acquire()
     
    289325                    "ABAC doesn't understand three-names")
    290326        else:
     327            # Convert non-string attributes to strings
     328            if not isinstance(attr, basestring):
     329                attr = "%s" % attr
    291330            # Naked attributes are attested by this principal
    292331            if attr.find('.') == -1:
     
    297336
    298337            self.lock.acquire()
    299             proof, rv = self.context.query(a, name)
     338            rv, proof = self.context.query(a, "%s" % name)
    300339            # XXX delete soon
    301340            if not rv and attr in self.globals: rv = True
     
    330369        return rv
    331370
    332     def save(self, dir):
    333         self.lock.acquire()
     371    def save(self, dir=None):
     372        self.lock.acquire()
     373        if dir:
     374            self.save_dir = dir
     375        else:
     376            dir = self.save_dir
     377        if dir is None:
     378            self.lock.release()
     379            raise abac_authorizer.no_file_error("No load directory specified")
    334380        try:
    335381            if not os.access(dir, os.F_OK):
     
    347393            if not os.access("%s/certs" %dir, os.F_OK):
    348394                os.mkdir("%s/certs" % dir)
    349             seenit = set()
     395            seenid = set()
     396            seenattr = set()
    350397
    351398            #restore unpicklable state
     
    363410                # NB: file naming conventions matter here.  The trailing_ID and
    364411                # _attr are required by ABAC.COntext.load_directory()
    365                 if id not in seenit:
     412                if id and id not in seenid:
    366413                    f = open("%s/certs/ID_%03d_ID.der" % (dir, ii), "w")
    367                     print >>f, id
     414                    f.write(id)
    368415                    f.close()
    369416                    ii += 1
    370                     seenit.add(id)
    371                 if attr:
     417                    seenid.add(id)
     418                if attr and attr not in seenattr:
    372419                    f = open("%s/certs/attr_%03d_attr.der" % (dir, ai), "w")
    373                     print >>f, attr
     420                    f.write(attr)
    374421                    f.close()
    375422                    ai += 1
     423                    seenattr.add(attr)
    376424        except EnvironmentError, e:
    377425            # If we've mislaid self.lock, release lock (they're the same object)
     
    386434        self.lock.release()
    387435
    388     def load(self, dir):
    389         self.lock.acquire()
     436    def load(self, dir=None):
     437        self.lock.acquire()
     438        if dir:
     439            self.save_dir = dir
     440        else:
     441            dir = self.save_dir
     442        if dir is None:
     443            self.lock.release()
     444            raise abac_authorizer.no_file_error("No load directory specified")
    390445        try:
    391446            if os.access("%s/state" % dir, os.R_OK):
     
    402457                self.context.load_id_file(self.me)
    403458            self.context.load_directory("%s/certs" % dir)
     459            self.save_dir = dir
    404460        except EnvironmentError, e:
    405461            self.lock.release()
  • fedd/federation/client_lib.py

    r09b1e9d r7206e5a  
    8080        self.errstr = errstr
    8181
     82class CertificateMismatchError(RuntimeError): pass
     83
    8284
    8385def get_user_cert():
     
    9799                if os.path.isfile("%s/%s" % (dir,p))]:
    98100            f = open(fn, 'r')
    99             rv.append(join(f))
     101            rv.append(f.read())
    100102            f.close()
    101103    return rv
     
    138140    return (cert, fid, url)
    139141
    140 def save_certfile(out_certfile, ea):
     142def save_certfile(out_certfile, ea, check_cert=None):
    141143    """
    142144    if the experiment authority section in ea has a certificate and the
    143145    out_certfile parameter has a place to put it, save the cert to the file.
    144     EnvronnemtError s can come from the file operations.
     146    EnvronmentError s can come from the file operations.  If check_cert is
     147    given, the certificate in ea is compared with it and if they are not equal,
     148    a CertificateMismatchError is raised.
    145149    """
    146150    if out_certfile and ea and 'X509' in ea:
     151        out_cert = ea['X509']
     152        if check_cert and check_cert != out_cert:
     153            raise CertificateMismatchError()
    147154        f = open(out_certfile, "w")
    148         print >>f, ea['X509']
     155        f.write(out_cert)
    149156        f.close()
    150157
  • fedd/federation/experiment_control.py

    r09b1e9d r7206e5a  
    3030from synch_store import synch_store
    3131from experiment_partition import experiment_partition
     32from authorizer import abac_authorizer
    3233
    3334import topdl
     
    282283                "ssh_privkey_file")
    283284        dt = config.get("experiment_control", "direct_transit")
     285        self.auth_type = config.get('experiment_control', 'auth_type') \
     286                or 'legacy'
     287        self.auth_dir = config.get('experiment_control', 'auth_dir')
    284288        if dt: self.direct_transit = [ tb.strip() for tb in dt.split(",")]
    285289        else: self.direct_transit = [ ]
     
    319323        self.local_access = { }
    320324
    321         if auth:
    322             self.auth = auth
    323         else:
    324             self.log.error(\
    325                     "[access]: No authorizer initialized, creating local one.")
    326             auth = authorizer()
     325        if self.auth_type == 'legacy':
     326            if auth:
     327                self.auth = auth
     328            else:
     329                self.log.error( "[access]: No authorizer initialized, " +\
     330                        "creating local one.")
     331                auth = authorizer()
     332        elif self.auth_type == 'abac':
     333            self.auth = abac_authorizer(load=self.auth_dir)
     334        else:
     335            raise service_error(service_error.internal,
     336                    "Unknown auth_type: %s" % self.auth_type)
    327337
    328338
     
    475485                eid = get_experiment_id(s)
    476486                if eid :
    477                     # Give the owner rights to the experiment
    478                     self.auth.set_attribute(s['owner'], eid)
    479                     # And holders of the eid as well
    480                     self.auth.set_attribute(eid, eid)
    481                     # allow overrides to control experiments as well
    482                     for o in self.overrides:
    483                         self.auth.set_attribute(o, eid)
    484                     # Set permissions to allow reading of the software repo, if
    485                     # any, as well.
    486                     for a in self.get_alloc_ids(s):
    487                         self.auth.set_attribute(a, 'repo/%s' % eid)
     487                    if self.auth_type == 'legacy':
     488                        # XXX: legacy
     489                        # Give the owner rights to the experiment
     490                        self.auth.set_attribute(s['owner'], eid)
     491                        # And holders of the eid as well
     492                        self.auth.set_attribute(eid, eid)
     493                        # allow overrides to control experiments as well
     494                        for o in self.overrides:
     495                            self.auth.set_attribute(o, eid)
     496                        # Set permissions to allow reading of the software
     497                        # repo, if any, as well.
     498                        for a in self.get_alloc_ids(s):
     499                            self.auth.set_attribute(a, 'repo/%s' % eid)
    488500                else:
    489501                    raise KeyError("No experiment id")
     
    546558
    547559        # Initialize the authorization attributes
    548         for fid in self.accessdb.keys():
    549             self.auth.set_attribute(fid, 'create')
    550             self.auth.set_attribute(fid, 'new')
     560        # XXX: legacy
     561        if self.auth_type == 'legacy':
     562            for fid in self.accessdb.keys():
     563                self.auth.set_attribute(fid, 'create')
     564                self.auth.set_attribute(fid, 'new')
    551565
    552566    def read_mapdb(self, file):
     
    589603        # Set the initial permissions on data in the store.  XXX: This ad hoc
    590604        # authorization attribute initialization is getting out of hand.
    591         for k in self.synch_store.all_keys():
    592             try:
    593                 if k.startswith('fedid:'):
    594                     fid = fedid(hexstr=k[6:46])
    595                     if self.state.has_key(fid):
    596                         for a in self.get_alloc_ids(self.state[fid]):
    597                             self.auth.set_attribute(a, k)
    598             except ValueError, e:
    599                 self.log.warn("Cannot deduce permissions for %s" % k)
     605        # XXX: legacy
     606        if self.auth_type == 'legacy':
     607            for k in self.synch_store.all_keys():
     608                try:
     609                    if k.startswith('fedid:'):
     610                        fid = fedid(hexstr=k[6:46])
     611                        if self.state.has_key(fid):
     612                            for a in self.get_alloc_ids(self.state[fid]):
     613                                self.auth.set_attribute(a, k)
     614                except ValueError, e:
     615                    self.log.warn("Cannot deduce permissions for %s" % k)
    600616
    601617
     
    13001316                if status and status == 'failed':
    13011317                    # remove the old access attribute
    1302                     self.auth.unset_attribute(fid, old_expid)
     1318                    self.auth.unset_attribute(fid, old_expid)
     1319                    self.auth.save()
    13031320                    overwrite = True
    13041321                    del self.state[eid]
     
    14971514                self.auth.set_attribute(tbparams[tb]['allocID']['fedid'],
    14981515                        "/%s/%s" % ( path, dest))
     1516            self.auth.save()
    14991517
    15001518        # Convert the software locations in the segments into the local
     
    15181536        to instantiate them and start it all up.
    15191537        """
     1538        req = req.get('NewRequestBody', None)
     1539        if not req:
     1540            raise service_error(service_error.req,
     1541                    "Bad request format (no NewRequestBody)")
     1542
     1543        if self.auth.import_credentials(data_list=req.get('credential', [])):
     1544            self.auth.save()
     1545       
    15201546        if not self.auth.check_attribute(fid, 'new'):
    15211547            raise service_error(service_error.access, "New access denied")
     
    15361562        gid = "dummy"
    15371563
    1538         req = req.get('NewRequestBody', None)
    1539         if not req:
    1540             raise service_error(service_error.req,
    1541                     "Bad request format (no NewRequestBody)")
    1542 
    15431564        # Generate an ID for the experiment (slice) and a certificate that the
    15441565        # allocator can use to prove they own it.  We'll ship it back through
    1545         # the encrypted connection.
    1546         (expid, expcert) = generate_fedid("test", dir=tmpdir, log=self.log)
     1566        # the encrypted connection.  If the requester supplied one, use it.
     1567        if 'experimentAccess' in req and 'X509' in req['experimentAccess']:
     1568            expcert = req['experimentAccess']['X509']
     1569            tf = tempfile.NamedTemporaryFile()
     1570            tf.write(expcert)
     1571            tf.flush()
     1572            expid = fedid(file=tf.name)
     1573            tf.close()
     1574            self.state_lock.acquire()
     1575            if expid in self.state:
     1576                self.state_lock.release()
     1577                raise service_error(service_error.req,
     1578                        'fedid %s identifies an existing experiment' % expid)
     1579            self.state_lock.release()
     1580        else:
     1581            (expid, expcert) = generate_fedid("test", dir=tmpdir, log=self.log)
    15471582
    15481583        #now we're done with the tmpdir, and it should be empty
     
    15571592
    15581593        # Let users touch the state
    1559         self.auth.set_attribute(fid, expid)
    1560         self.auth.set_attribute(expid, expid)
    1561         # Override fedids can manipulate state as well
    1562         for o in self.overrides:
    1563             self.auth.set_attribute(o, expid)
     1594        self.auth.set_attribute(fid, expid)
     1595        self.auth.set_attribute(expid, expid)
     1596        # Override fedids can manipulate state as well
     1597        for o in self.overrides:
     1598            self.auth.set_attribute(o, expid)
     1599        self.auth.save()
    15641600
    15651601        rv = {
     
    17931829                asignee = tbparams[tb]['allocID']['fedid']
    17941830                for f in ("hosts", gw_secretkey_base, gw_pubkey_base):
    1795                     self.auth.set_attribute(asignee, "%s/%s" % (configpath, f))
     1831                    self.auth.set_attribute(asignee, "%s/%s" % \
     1832                            (configpath, f))
    17961833
    17971834            part = experiment_partition(self.auth, self.store_url, tbmap,
     
    18091846                        self.auth.set_attribute(\
    18101847                                tbparams[tb]['allocID']['fedid'], sk)
     1848            self.auth.save()
    18111849
    18121850            self.wrangle_software(expid, top, topo, tbparams)
     
    18511889        # here on out, the state will stick around a while.
    18521890
    1853         # Let users touch the state
    1854         self.auth.set_attribute(fid, expid)
    1855         self.auth.set_attribute(expid, expid)
    1856         # Override fedids can manipulate state as well
    1857         for o in self.overrides:
    1858             self.auth.set_attribute(o, expid)
     1891        # Let users touch the state
     1892        self.auth.set_attribute(fid, expid)
     1893        self.auth.set_attribute(expid, expid)
     1894        # Override fedids can manipulate state as well
     1895        for o in self.overrides:
     1896            self.auth.set_attribute(o, expid)
     1897        self.auth.save()
    18591898
    18601899        # Create a logger that logs to the experiment's state object as well as
  • fedd/federation/fedid.py

    r09b1e9d r7206e5a  
    158158
    159159            rv = subprocess.call(cmd, stdout=call_out, stderr=call_out)
    160             log.debug("rv = %d" % rv)
     160            if log: log.debug("rv = %d" % rv)
    161161            if rv == 0:
    162162                cert = ""
Note: See TracChangeset for help on using the changeset viewer.