Example #1
0
def export_gid(options):
    from sfa.util.table import SfaTable
    # lookup the record for the specified hrn 
    hrn = options.export
    type = options.type
    # check sfa table first
    filter = {'hrn': hrn}
    if type:
        filter['type'] = type                    
    table = SfaTable()
    records = table.find(filter)
    if not records:
        # check the authorities hierarchy 
        hierarchy = Hierarchy()
        try:
            auth_info = hierarchy.get_auth_info()
            gid = auth_info.gid_object 
        except:
            print "Record: %s not found" % hrn
            sys.exit(1)
    else:
        record = records[0]
        gid = GID(string=record['gid'])
        
    # get the outfile
    outfile = options.outfile
    if not outfile:
        outfile = os.path.abspath('./%s.gid' % gid.get_hrn())

    # save it
    if options.verbose:
        print "Writing %s gid to %s" % (gid.get_hrn(), outfile)
    gid.save_to_file(outfile, save_parents=True)
Example #2
0
def sign(options):
    """
    Sign the specified gid
    """
    hierarchy = Hierarchy()
    config = Config()
    default_authority = config.SFA_INTERFACE_HRN
    auth_info = hierarchy.get_auth_info(default_authority)

    # load the gid
    gidfile = os.path.abspath(options.sign)
    if not os.path.isfile(gidfile):
        print "no such gid: %s" % gidfile
        sys.exit(1)
    gid = GID(filename=gidfile)

    # extract pub_key and create new gid
    pkey = gid.get_pubkey()
    urn = gid.get_urn()
    gid = hierarchy.create_gid(urn, create_uuid(), pkey)

    # get the outfile
    outfile = options.outfile
    if not outfile:
        outfile = os.path.abspath('./signed-%s.gid' % gid.get_hrn())
   
    # save the signed gid
    if options.verbose:
        print "Writing signed gid %s" % outfile  
    gid.save_to_file(outfile, save_parents=True)
Example #3
0
def main():
    # Generate command line parser
    parser = OptionParser(usage="sfa-start.py [options]")
    parser.add_option("-r", "--registry", dest="registry", action="store_true",
         help="run registry server", default=False)
    parser.add_option("-s", "--slicemgr", dest="sm", action="store_true",
         help="run slice manager", default=False)
    parser.add_option("-a", "--aggregate", dest="am", action="store_true",
         help="run aggregate manager", default=False)
    parser.add_option("-c", "--component", dest="cm", action="store_true",
         help="run component server", default=False)
    parser.add_option("-t", "--trusted-certs", dest="trusted_certs", action="store_true",
         help="refresh trusted certs", default=False)
    parser.add_option("-d", "--daemon", dest="daemon", action="store_true",
         help="Run as daemon.", default=False)
    (options, args) = parser.parse_args()
    
    config = Config()
    logger.setLevelFromOptVerbose(config.SFA_API_LOGLEVEL)
    

    # ge the server's key and cert
    hierarchy = Hierarchy()
    auth_info = hierarchy.get_interface_auth_info()
    server_key_file = auth_info.get_privkey_filename()
    server_cert_file = auth_info.get_gid_filename()

    # ensure interface cert is present in trusted roots dir
    trusted_roots = TrustedRoots(config.get_trustedroots_dir())
    trusted_roots.add_gid(GID(filename=server_cert_file))
    if (options.daemon):  daemon()
    
    if options.trusted_certs:
        install_peer_certs(server_key_file, server_cert_file)   
    
    # start registry server
    if (options.registry):
        from sfa.server.registry import Registry
        r = Registry("", config.SFA_REGISTRY_PORT, server_key_file, server_cert_file)
        r.start()

    if (options.am):
        from sfa.server.aggregate import Aggregate
        a = Aggregate("", config.SFA_AGGREGATE_PORT, server_key_file, server_cert_file)
        a.start()

    # start slice manager
    if (options.sm):
        from sfa.server.slicemgr import SliceMgr
        s = SliceMgr("", config.SFA_SM_PORT, server_key_file, server_cert_file)
        s.start()

    if (options.cm):
        from sfa.server.component import Component
        c = Component("", config.component_port, server_key_file, server_cert_file)
#        c = Component("", config.SFA_COMPONENT_PORT, server_key_file, server_cert_file)
        c.start()
Example #4
0
    def __init__(self, auth_hierarchy=None, logger=None):
        self.config = Config()
        if auth_hierarchy is not None:
            self.auth_hierarchy = auth_hierarchy
        else:
            self.auth_hierarchy = Hierarchy()
        if logger is not None:
            self.logger = logger
        else:
            self.logger = _SfaLogger(logfile='/var/log/sfa_import.log',
                                     loggername='importlog')
            self.logger.setLevelFromOptVerbose(self.config.SFA_API_LOGLEVEL)
# ugly side effect so that other modules get it right
        import sfa.util.sfalogging
        sfa.util.sfalogging.logger = logger
Example #5
0
 def getDelegatedCredential(self, creds):
     """
     Attempt to find a credential delegated to us in
     the specified list of creds.
     """
     from sfa.trust.hierarchy import Hierarchy
     if creds and not isinstance(creds, list): 
         creds = [creds]
     hierarchy = Hierarchy()
             
     delegated_cred = None
     for cred in creds:
         if hierarchy.auth_exists(Credential(cred=cred).get_gid_caller().get_hrn()):
             delegated_cred = cred
             break
     return delegated_cred
Example #6
0
    def run(self, options=None):
        if not self.config.SFA_REGISTRY_ENABLED:
            self.logger.critical(
                "Importer: need SFA_REGISTRY_ENABLED to run import")

        # testbed-neutral : create local certificates and the like
        auth_hierarchy = Hierarchy()
        self.create_top_level_auth_records(self.config.SFA_INTERFACE_HRN)
        self.create_interface_records()

        # testbed-specific
        testbed_importer = None
        generic = Generic.the_flavour()
        importer_class = generic.importer_class()
        if importer_class:
            begin_time = datetime.now()
            self.logger.info ("Starting import on %s, using class %s from flavour %s"%\
                         (begin_time,importer_class.__name__,generic.flavour))
            testbed_importer = importer_class(auth_hierarchy, self.logger)
            if testbed_importer:
                testbed_importer.add_options(options)
                testbed_importer.run(options)
            end_time = datetime.now()
            duration = end_time - begin_time
            self.logger.info("Import took %s" % duration)
Example #7
0
    def getDelegatedCredential(self, creds):
        """
        Attempt to find a credential delegated to us in
        the specified list of creds.
        """
        from sfa.trust.hierarchy import Hierarchy
        if creds and not isinstance(creds, list):
            creds = [creds]
        hierarchy = Hierarchy()

        delegated_cred = None
        for cred in creds:
            if hierarchy.auth_exists(
                    Credential(cred=cred).get_gid_caller().get_hrn()):
                delegated_cred = cred
                break
        return delegated_cred
Example #8
0
 def server_proxy(self, interface, cred, timeout=30):
     """
     Returns a connection to the specified interface. Use the specified
     credential to determine the caller and look for the caller's key/cert 
     in the registry hierarchy cache. 
     """
     from sfa.trust.hierarchy import Hierarchy
     if not isinstance(cred, Credential):
         cred_obj = Credential(string=cred)
     else:
         cred_obj = cred
     caller_gid = cred_obj.get_gid_caller()
     hierarchy = Hierarchy()
     auth_info = hierarchy.get_auth_info(caller_gid.get_hrn())
     key_file = auth_info.get_privkey_filename()
     cert_file = auth_info.get_gid_filename()
     server = interface.server_proxy(key_file, cert_file, timeout)
     return server
Example #9
0
 def server_proxy(self, interface, cred, timeout=30):
     """
     Returns a connection to the specified interface. Use the specified
     credential to determine the caller and look for the caller's key/cert 
     in the registry hierarchy cache. 
     """       
     from sfa.trust.hierarchy import Hierarchy
     if not isinstance(cred, Credential):
         cred_obj = Credential(string=cred)
     else:
         cred_obj = cred
     caller_gid = cred_obj.get_gid_caller()
     hierarchy = Hierarchy()
     auth_info = hierarchy.get_auth_info(caller_gid.get_hrn())
     key_file = auth_info.get_privkey_filename()
     cert_file = auth_info.get_gid_filename()
     server = interface.server_proxy(key_file, cert_file, timeout)
     return server
Example #10
0
def import_gid(options):
    """
    Import the specified gid into the registry (db and authorities 
    hierarchy) overwriting any previous gid.
    """
    from sfa.util.table import SfaTable
    from sfa.util.record import SfaRecord
    # load the gid
    gidfile = os.path.abspath(options.importgid)
    if not gidfile or not os.path.isfile(gidfile):
        print "No such gid: %s" % gidfile
        sys.exit(1)
    gid = GID(filename=gidfile)
    
    # check if it exists within the hierarchy
    hierarchy = Hierarchy()
    if not hierarchy.auth_exists(gid.get_hrn()):
        print "%s not found in hierarchy" % gid.get_hrn()
        sys.exit(1)

    # check if record exists in db
    table = SfaTable()
    records = table.find({'hrn': gid.get_hrn(), 'type': 'authority'})
    if not records:
        print "%s not found in record database" % get.get_hrn()  
        sys.exit(1)

    # update the database record
    record = records[0]
    record['gid'] = gid.save_to_string(save_parents=True)
    table.update(record)
    if options.verbose:
        print "Imported %s gid into db" % record['hrn']

    # update the hierarchy
    auth_info = hierarchy.get_auth_info(gid.get_hrn())  
    filename = auth_info.gid_filename
    gid.save_to_file(filename, save_parents=True)
    if options.verbose:
        print "Writing %s gid to %s" % (gid.get_hrn(), filename)

    # ending here
    return
Example #11
0
def create_default_dirs():
    config = Config()
    hierarchy = Hierarchy()
    config_dir = config.config_path
    trusted_certs_dir = config.get_trustedroots_dir()
    authorities_dir = hierarchy.basedir
    all_dirs = [config_dir, trusted_certs_dir, authorities_dir]
    for dir in all_dirs:
        if not os.path.exists(dir):
            os.makedirs(dir)
Example #12
0
 def import_slice_to_registry(self, slicename):
     '''
     Method to import a slice created in the testbed to the SFA Registry
     
     :param slicename: name of the node being imported
     :type string        
     '''
     auth_hierarchy = Hierarchy()
     clab_importer = ClabImporter(auth_hierarchy, clab_logger)
     clab_importer.import_single_slice(slicename)
Example #13
0
def init_server_cert(hrn, key, server_cert_file, self_signed=False):
    """
    Setup the certificate for this server. Attempt to use gid before 
    creating a self signed cert 
    """
    if self_signed:
        init_self_signed_cert(hrn, key, server_cert_file)
    else:
        try:
            # look for gid file
            logger.debug("generating server cert from gid: %s" % hrn)
            hierarchy = Hierarchy()
            auth_info = hierarchy.get_auth_info(hrn)
            gid = GID(filename=auth_info.gid_filename)
            gid.save_to_file(filename=server_cert_file)
        except:
            # fall back to self signed cert
            logger.debug("gid for %s not found" % hrn)
            init_self_signed_cert(hrn, key, server_cert_file)
Example #14
0
 def export(self, xrn, type=None, outfile=None):
     """Fetch an object's GID from the Registry"""  
     from sfa.storage.model import RegRecord
     hrn = Xrn(xrn).get_hrn()
     request=self.api.dbsession().query(RegRecord).filter_by(hrn=hrn)
     if type: request = request.filter_by(type=type)
     record=request.first()
     if record:
         gid = GID(string=record.gid)
     else:
         # check the authorities hierarchy
         hierarchy = Hierarchy()
         try:
             auth_info = hierarchy.get_auth_info(hrn)
             gid = auth_info.gid_object
         except:
             print "Record: %s not found" % hrn
             sys.exit(1)
     # save to file
     if not outfile:
         outfile = os.path.abspath('./%s.gid' % gid.get_hrn())
     gid.save_to_file(outfile, save_parents=True)
Example #15
0
 def export(self, xrn, type=None, outfile=None):
     """Fetch an object's GID from the Registry"""
     from sfa.storage.model import RegRecord
     hrn = Xrn(xrn).get_hrn()
     request = self.api.dbsession().query(RegRecord).filter_by(hrn=hrn)
     if type: request = request.filter_by(type=type)
     record = request.first()
     if record:
         gid = GID(string=record.gid)
     else:
         # check the authorities hierarchy
         hierarchy = Hierarchy()
         try:
             auth_info = hierarchy.get_auth_info(hrn)
             gid = auth_info.gid_object
         except:
             print "Record: %s not found" % hrn
             sys.exit(1)
     # save to file
     if not outfile:
         outfile = os.path.abspath('./%s.gid' % gid.get_hrn())
     gid.save_to_file(outfile, save_parents=True)
Example #16
0
    def __init__(self,auth_hierarchy=None,logger=None):
        self.config = Config()
        if auth_hierarchy is not None:
            self.auth_hierarchy=auth_hierarchy
        else:
            self.auth_hierarchy = Hierarchy ()
        if logger is not None:
            self.logger=logger
        else:
            self.logger = _SfaLogger(logfile='/var/log/sfa_import.log', loggername='importlog')
            self.logger.setLevelFromOptVerbose(self.config.SFA_API_LOGLEVEL)
# ugly side effect so that other modules get it right
        import sfa.util.sfalogging
        sfa.util.sfalogging.logger=logger
Example #17
0
def GetCredential(registry=None, force=False, verbose=False):
    config = Config()
    hierarchy = Hierarchy()
    key_dir = hierarchy.basedir
    data_dir = config.data_path
    config_dir = config.config_path
    credfile = data_dir + os.sep + 'node.cred'
    # check for existing credential
    if not force and os.path.exists(credfile):
        if verbose:
            print "Loading Credential from %(credfile)s " % locals()
        cred = Credential(filename=credfile).save_to_string(save_parents=True)
    else:
        if verbose:
            print "Getting credential from registry"
        # make sure node private key exists
        node_pkey_file = config_dir + os.sep + "node.key"
        node_gid_file = config_dir + os.sep + "node.gid"
        if not os.path.exists(node_pkey_file) or \
           not os.path.exists(node_gid_file):
            get_node_key(registry=registry, verbose=verbose)

        gid = GID(filename=node_gid_file)
        hrn = gid.get_hrn()
        # create server key and certificate
        keyfile = data_dir + os.sep + "server.key"
        certfile = data_dir + os.sep + "server.cert"
        key = Keypair(filename=node_pkey_file)
        key.save_to_file(keyfile)
        create_server_keypair(keyfile, certfile, hrn, verbose)

        # get credential from registry
        registry = server_proxy(url=registry,
                                keyfile=keyfile,
                                certfile=certfile)
        cert = Certificate(filename=certfile)
        cert_str = cert.save_to_string(save_parents=True)
        cred = registry.GetSelfCredential(cert_str, 'node', hrn)
        Credential(string=cred).save_to_file(credfile, save_parents=True)

    return cred
Example #18
0
    def nuke(self, all=False, certs=False, reinit=True):
        """Cleanup local registry DB, plus various additional filesystem cleanups optionally"""
        from sfa.storage.dbschema import DBSchema
        from sfa.util.sfalogging import _SfaLogger
        logger = _SfaLogger(logfile='/var/log/sfa_import.log',
                            loggername='importlog')
        logger.setLevelFromOptVerbose(self.api.config.SFA_API_LOGLEVEL)
        logger.info("Purging SFA records from database")
        dbschema = DBSchema()
        dbschema.nuke()

        # for convenience we re-create the schema here, so there's no need for an explicit
        # service sfa restart
        # however in some (upgrade) scenarios this might be wrong
        if reinit:
            logger.info("re-creating empty schema")
            dbschema.init_or_upgrade()

        # remove the server certificate and all gids found in /var/lib/sfa/authorities
        if certs:
            logger.info("Purging cached certificates")
            for (dir, _, files) in os.walk('/var/lib/sfa/authorities'):
                for file in files:
                    if file.endswith('.gid') or file == 'server.cert':
                        path = dir + os.sep + file
                        os.unlink(path)

        # just remove all files that do not match 'server.key' or 'server.cert'
        if all:
            logger.info("Purging registry filesystem cache")
            preserved_files = ['server.key', 'server.cert']
            for (dir, _, files) in os.walk(Hierarchy().basedir):
                for file in files:
                    if file in preserved_files: continue
                    path = dir + os.sep + file
                    os.unlink(path)
Example #19
0
def main():
    # Generate command line parser
    parser = OptionParser(usage="sfa-start.py [options]")
    parser.add_option("-r",
                      "--registry",
                      dest="registry",
                      action="store_true",
                      help="run registry server",
                      default=False)
    parser.add_option("-s",
                      "--slicemgr",
                      dest="sm",
                      action="store_true",
                      help="run slice manager",
                      default=False)
    parser.add_option("-a",
                      "--aggregate",
                      dest="am",
                      action="store_true",
                      help="run aggregate manager",
                      default=False)
    parser.add_option("-c",
                      "--component",
                      dest="cm",
                      action="store_true",
                      help="run component server",
                      default=False)
    parser.add_option("-t",
                      "--trusted-certs",
                      dest="trusted_certs",
                      action="store_true",
                      help="refresh trusted certs",
                      default=False)
    parser.add_option("-d",
                      "--daemon",
                      dest="daemon",
                      action="store_true",
                      help="Run as daemon.",
                      default=False)
    (options, args) = parser.parse_args()

    config = Config()
    logger.setLevelFromOptVerbose(config.SFA_API_LOGLEVEL)

    # ge the server's key and cert
    hierarchy = Hierarchy()
    auth_info = hierarchy.get_interface_auth_info()
    server_key_file = auth_info.get_privkey_filename()
    server_cert_file = auth_info.get_gid_filename()

    # ensure interface cert is present in trusted roots dir
    trusted_roots = TrustedRoots(config.get_trustedroots_dir())
    trusted_roots.add_gid(GID(filename=server_cert_file))
    if (options.daemon): daemon()

    if options.trusted_certs:
        install_peer_certs(server_key_file, server_cert_file)

    # start registry server
    if (options.registry):
        from sfa.server.registry import Registry
        r = Registry("", config.SFA_REGISTRY_PORT, server_key_file,
                     server_cert_file)
        r.start()

    if (options.am):
        from sfa.server.aggregate import Aggregate
        a = Aggregate("", config.SFA_AGGREGATE_PORT, server_key_file,
                      server_cert_file)
        a.start()

    # start slice manager
    if (options.sm):
        from sfa.server.slicemgr import SliceMgr
        s = SliceMgr("", config.SFA_SM_PORT, server_key_file, server_cert_file)
        s.start()

    if (options.cm):
        from sfa.server.component import Component
        c = Component("", config.component_port, server_key_file,
                      server_cert_file)
        #        c = Component("", config.SFA_COMPONENT_PORT, server_key_file, server_cert_file)
        c.start()
Example #20
0
class Importer:
    def __init__(self, auth_hierarchy=None, logger=None):
        self.config = Config()
        if auth_hierarchy is not None:
            self.auth_hierarchy = auth_hierarchy
        else:
            self.auth_hierarchy = Hierarchy()
        if logger is not None:
            self.logger = logger
        else:
            self.logger = _SfaLogger(logfile='/var/log/sfa_import.log',
                                     loggername='importlog')
            self.logger.setLevelFromOptVerbose(self.config.SFA_API_LOGLEVEL)
# ugly side effect so that other modules get it right
        import sfa.util.sfalogging
        sfa.util.sfalogging.logger = logger
#        self.TrustedRoots = TrustedRoots(self.config.get_trustedroots_dir())

# check before creating a RegRecord entry as we run this over and over

    def record_exists(self, type, hrn):
        return global_dbsession.query(RegRecord).filter_by(
            hrn=hrn, type=type).count() != 0

    def create_top_level_auth_records(self, hrn):
        """
        Create top level db records (includes root and sub authorities (local/remote)
        """
        # make sure parent exists
        parent_hrn = get_authority(hrn)
        if not parent_hrn:
            parent_hrn = hrn
        if not parent_hrn == hrn:
            self.create_top_level_auth_records(parent_hrn)

        # ensure key and cert exists:
        self.auth_hierarchy.create_top_level_auth(hrn)
        # create the db record if it doesnt already exist
        if not self.record_exists('authority', hrn):
            auth_info = self.auth_hierarchy.get_auth_info(hrn)
            auth_record = RegAuthority(hrn=hrn,
                                       gid=auth_info.get_gid_object(),
                                       authority=get_authority(hrn))
            auth_record.just_created()
            global_dbsession.add(auth_record)
            global_dbsession.commit()
            self.logger.info("SfaImporter: imported authority (parent) %s " %
                             auth_record)

    def create_sm_client_record(self):
        """
        Create a user record for the Slicemanager service.
        """
        hrn = self.interface_hrn + '.slicemanager'
        urn = hrn_to_urn(hrn, 'user')
        if not self.auth_hierarchy.auth_exists(urn):
            self.logger.info("SfaImporter: creating Slice Manager user")
            self.auth_hierarchy.create_auth(urn)

        if self.record_exists('user', hrn): return
        auth_info = self.auth_hierarchy.get_auth_info(hrn)
        user_record = RegUser(hrn=hrn,
                              gid=auth_info.get_gid_object(),
                              authority=get_authority(hrn))
        user_record.just_created()
        global_dbsession.add(user_record)
        global_dbsession.commit()
        self.logger.info("SfaImporter: importing user (slicemanager) %s " %
                         user_record)

    def create_interface_records(self):
        """
        Create a record for each SFA interface
        """
        # just create certs for all sfa interfaces even if they
        # aren't enabled
        auth_info = self.auth_hierarchy.get_auth_info(
            self.config.SFA_INTERFACE_HRN)
        pkey = auth_info.get_pkey_object()
        hrn = self.config.SFA_INTERFACE_HRN
        for type in [
                'authority+sa',
                'authority+am',
                'authority+sm',
        ]:
            urn = hrn_to_urn(hrn, type)
            gid = self.auth_hierarchy.create_gid(urn, create_uuid(), pkey)
            # for now we have to preserve the authority+<> stuff
            if self.record_exists(type, hrn): continue
            interface_record = RegAuthority(type=type,
                                            hrn=hrn,
                                            gid=gid,
                                            authority=get_authority(hrn))
            interface_record.just_created()
            global_dbsession.add(interface_record)
            global_dbsession.commit()
            self.logger.info("SfaImporter: imported authority (%s) %s " %
                             (type, interface_record))

    def run(self, options=None):
        if not self.config.SFA_REGISTRY_ENABLED:
            self.logger.critical(
                "Importer: need SFA_REGISTRY_ENABLED to run import")

        # testbed-neutral : create local certificates and the like
        auth_hierarchy = Hierarchy()
        self.create_top_level_auth_records(self.config.SFA_INTERFACE_HRN)
        self.create_interface_records()

        # testbed-specific
        testbed_importer = None
        generic = Generic.the_flavour()
        importer_class = generic.importer_class()
        if importer_class:
            begin_time = datetime.now()
            self.logger.info ("Starting import on %s, using class %s from flavour %s"%\
                         (begin_time,importer_class.__name__,generic.flavour))
            testbed_importer = importer_class(auth_hierarchy, self.logger)
            if testbed_importer:
                testbed_importer.add_options(options)
                testbed_importer.run(options)
            end_time = datetime.now()
            duration = end_time - begin_time
            self.logger.info("Import took %s" % duration)
Example #21
0
class Importer:

    def __init__(self,auth_hierarchy=None,logger=None):
        self.config = Config()
        if auth_hierarchy is not None:
            self.auth_hierarchy=auth_hierarchy
        else:
            self.auth_hierarchy = Hierarchy ()
        if logger is not None:
            self.logger=logger
        else:
            self.logger = _SfaLogger(logfile='/var/log/sfa_import.log', loggername='importlog')
            self.logger.setLevelFromOptVerbose(self.config.SFA_API_LOGLEVEL)
# ugly side effect so that other modules get it right
        import sfa.util.sfalogging
        sfa.util.sfalogging.logger=logger
#        self.TrustedRoots = TrustedRoots(self.config.get_trustedroots_dir())    
   
    # check before creating a RegRecord entry as we run this over and over
    def record_exists (self, type, hrn):
       return dbsession.query(RegRecord).filter_by(hrn=hrn,type=type).count()!=0 

    def create_top_level_auth_records(self, hrn):
        """
        Create top level db records (includes root and sub authorities (local/remote)
        """
        # make sure parent exists
        parent_hrn = get_authority(hrn)
        if not parent_hrn:
            parent_hrn = hrn
        if not parent_hrn == hrn:
            self.create_top_level_auth_records(parent_hrn)

        # ensure key and cert exists:
        self.auth_hierarchy.create_top_level_auth(hrn)
        # create the db record if it doesnt already exist
        if not self.record_exists ('authority',hrn):
            auth_info = self.auth_hierarchy.get_auth_info(hrn)
            auth_record = RegAuthority(hrn=hrn, gid=auth_info.get_gid_object(),
                                       authority=get_authority(hrn))
            auth_record.just_created()
            dbsession.add (auth_record)
            dbsession.commit()
            self.logger.info("SfaImporter: imported authority (parent) %s " % auth_record)     
   

    def create_sm_client_record(self):
        """
        Create a user record for the Slicemanager service.
        """
        hrn = self.interface_hrn + '.slicemanager'
        urn = hrn_to_urn(hrn, 'user')
        if not self.auth_hierarchy.auth_exists(urn):
            self.logger.info("SfaImporter: creating Slice Manager user")
            self.auth_hierarchy.create_auth(urn)

        if self.record_exists ('user',hrn): return
        auth_info = self.auth_hierarchy.get_auth_info(hrn)
        user_record = RegUser(hrn=hrn, gid=auth_info.get_gid_object(),
                              authority=get_authority(hrn))
        user_record.just_created()
        dbsession.add (user_record)
        dbsession.commit()
        self.logger.info("SfaImporter: importing user (slicemanager) %s " % user_record)


    def create_interface_records(self):
        """
        Create a record for each SFA interface
        """
        # just create certs for all sfa interfaces even if they
        # aren't enabled
        auth_info = self.auth_hierarchy.get_auth_info(self.config.SFA_INTERFACE_HRN)
        pkey = auth_info.get_pkey_object()
        hrn=self.config.SFA_INTERFACE_HRN
        for type in  [ 'authority+sa', 'authority+am', 'authority+sm', ]:
            urn = hrn_to_urn(hrn, type)
            gid = self.auth_hierarchy.create_gid(urn, create_uuid(), pkey)
            # for now we have to preserve the authority+<> stuff
            if self.record_exists (type,hrn): continue
            interface_record = RegAuthority(type=type, hrn=hrn, gid=gid,
                                            authority=get_authority(hrn))
            interface_record.just_created()
            dbsession.add (interface_record)
            dbsession.commit()
            self.logger.info("SfaImporter: imported authority (%s) %s " % (type,interface_record))
 
    def run(self, options=None):
        if not self.config.SFA_REGISTRY_ENABLED:
            self.logger.critical("Importer: need SFA_REGISTRY_ENABLED to run import")

        # testbed-neutral : create local certificates and the like
        auth_hierarchy = Hierarchy ()
        self.create_top_level_auth_records(self.config.SFA_INTERFACE_HRN)
        self.create_interface_records()
 
        # testbed-specific
        testbed_importer = None
        generic=Generic.the_flavour()
        importer_class = generic.importer_class()
        if importer_class:
            begin_time=datetime.now()
            self.logger.info ("Starting import on %s, using class %s from flavour %s"%\
                         (begin_time,importer_class.__name__,generic.flavour))
            testbed_importer = importer_class (auth_hierarchy, self.logger)
            if testbed_importer:
                testbed_importer.add_options(options)
                testbed_importer.run (options)
            end_time=datetime.now()
            duration=end_time-begin_time
            self.logger.info("Import took %s"%duration)
Example #22
0
 def __init__(self, peer_cert = None, config = None ):
     self.peer_cert = peer_cert
     self.hierarchy = Hierarchy()
     if not config:
         self.config = Config()
     self.load_trusted_certs()
Example #23
0
class Auth:
    """
    Credential based authentication
    """

    def __init__(self, peer_cert = None, config = None ):
        self.peer_cert = peer_cert
        self.hierarchy = Hierarchy()
        if not config:
            self.config = Config()
        self.load_trusted_certs()

    def load_trusted_certs(self):
        self.trusted_cert_list = \
            TrustedRoots(self.config.get_trustedroots_dir()).get_list()
        self.trusted_cert_file_list = \
            TrustedRoots(self.config.get_trustedroots_dir()).get_file_list()

    # this convenience methods extracts speaking_for_xrn
    # from the passed options using 'geni_speaking_for'
    def checkCredentialsSpeaksFor (self, *args, **kwds):
        if 'options' not in kwds:
            logger.error ("checkCredentialsSpeaksFor was not passed options=options")
            return
        # remove the options arg
        options=kwds['options']; del kwds['options']
        # compute the speaking_for_xrn arg and pass it to checkCredentials
        if options is None: speaking_for_xrn=None
        else:               speaking_for_xrn=options.get('geni_speaking_for',None)
        kwds['speaking_for_xrn']=speaking_for_xrn
        return self.checkCredentials (*args, **kwds)

    # do not use mutable as default argument 
    # http://docs.python-guide.org/en/latest/writing/gotchas/#mutable-default-arguments
    def checkCredentials(self, creds, operation, xrns=None, 
                         check_sliver_callback=None, 
                         speaking_for_xrn=None):
        if xrns is None: xrns=[]
        def log_invalid_cred(cred):
            if not isinstance (cred, StringTypes):
                logger.info("cannot validate credential %s - expecting a string"%cred)
                error="checkCredentials: expected a string, received %s"%(type(cred))
            else:
                cred_obj=Credential(string=cred)
                logger.info("failed to validate credential - dump=%s"%\
                            cred_obj.dump_string(dump_parents=True))
                error = sys.exc_info()[:2]
            return error

        # if xrns are specified they cannot be None or empty string
        if xrns:
            for xrn in xrns:
                if not xrn:
                    raise BadArgs("Invalid urn or hrn")

        
        if not isinstance(xrns, list):
            xrns = [xrns]

        slice_xrns  = Xrn.filter_type(xrns, 'slice')
        sliver_xrns = Xrn.filter_type(xrns, 'sliver')

        # we are not able to validate slivers in the traditional way so 
        # we make sure not to include sliver urns/hrns in the core validation loop
        hrns = [Xrn(xrn).hrn for xrn in xrns if xrn not in sliver_xrns] 
        valid = []
        if not isinstance(creds, list):
            creds = [creds]
        logger.debug("Auth.checkCredentials with %d creds on hrns=%s"%(len(creds),hrns))
        # won't work if either creds or hrns is empty - let's make it more explicit
        if not creds: raise Forbidden("no credential provided")
        if not hrns: hrns = [None]
        error=[None,None]

        speaks_for_gid = determine_speaks_for(logger, creds, self.peer_cert,
                                              speaking_for_xrn, self.trusted_cert_list)

        if self.peer_cert and \
           not self.peer_cert.is_pubkey(speaks_for_gid.get_pubkey()):
            valid = creds
        else:
            for cred in creds:
                for hrn in hrns:
                    try:
                        self.check(cred, operation, hrn)
                        valid.append(cred)
                    except:
                        error = log_invalid_cred(cred)
        
        # make sure all sliver xrns are validated against the valid credentials
        if sliver_xrns:
            if not check_sliver_callback:
                msg = "sliver verification callback method not found." 
                msg += " Unable to validate sliver xrns: %s" % sliver_xrns
                raise Forbidden(msg)
            check_sliver_callback(valid, sliver_xrns)
                
        if not len(valid):
            raise Forbidden("Invalid credential %s -- %s"%(error[0],error[1]))
        
        return valid
        
        
    def check(self, credential, operation, hrn = None):
        """
        Check the credential against the peer cert (callerGID) included 
        in the credential matches the caller that is connected to the 
        HTTPS connection, check if the credential was signed by a 
        trusted cert and check if the credential is allowed to perform 
        the specified operation.    
        """
        cred = Credential(cred=credential)    
        self.client_cred = cred
        logger.debug("Auth.check: handling hrn=%s and credential=%s"%\
                         (hrn,cred.pretty_cred()))

        if cred.type not in ['geni_sfa']:
            raise CredentialNotVerifiable(cred.type, "%s not supported" % cred.type)
        self.client_gid = self.client_cred.get_gid_caller()
        self.object_gid = self.client_cred.get_gid_object()
        
        # make sure the client_gid is not blank
        if not self.client_gid:
            raise MissingCallerGID(self.client_cred.pretty_subject())
       
        # validate the client cert if it exists
        if self.peer_cert:
            self.verifyPeerCert(self.peer_cert, self.client_gid)                   

        # make sure the client is allowed to perform the operation
        if operation:
            if not self.client_cred.can_perform(operation):
                raise InsufficientRights(operation)

        if self.trusted_cert_list:
            self.client_cred.verify(self.trusted_cert_file_list,
                                    self.config.SFA_CREDENTIAL_SCHEMA)
        else:
           raise MissingTrustedRoots(self.config.get_trustedroots_dir())
       
        # Make sure the credential's target matches the specified hrn. 
        # This check does not apply to trusted peers 
        trusted_peers = [gid.get_hrn() for gid in self.trusted_cert_list]
        if hrn and self.client_gid.get_hrn() not in trusted_peers:
            target_hrn = self.object_gid.get_hrn()
            if not hrn == target_hrn:
                raise PermissionError("Target hrn: %s doesn't match specified hrn: %s " % \
                                       (target_hrn, hrn) )       
        return True

    def check_ticket(self, ticket):
        """
        Check if the ticket was signed by a trusted cert
        """
        if self.trusted_cert_list:
            client_ticket = SfaTicket(string=ticket)
            client_ticket.verify_chain(self.trusted_cert_list)
        else:
           raise MissingTrustedRoots(self.config.get_trustedroots_dir())

        return True 

    def verifyPeerCert(self, cert, gid):
        # make sure the client_gid matches client's certificate
        if not cert.is_pubkey(gid.get_pubkey()):
            raise ConnectionKeyGIDMismatch(gid.get_subject()+":"+cert.get_subject())            

    def verifyGidRequestHash(self, gid, hash, arglist):
        key = gid.get_pubkey()
        if not key.verify_string(str(arglist), hash):
            raise BadRequestHash(hash)

    def verifyCredRequestHash(self, cred, hash, arglist):
        gid = cred.get_gid_caller()
        self.verifyGidRequestHash(gid, hash, arglist)

    def validateGid(self, gid):
        if self.trusted_cert_list:
            gid.verify_chain(self.trusted_cert_list)

    def validateCred(self, cred):
        if self.trusted_cert_list:
            cred.verify(self.trusted_cert_file_list)

    def authenticateGid(self, gidStr, argList, requestHash=None):
        gid = GID(string = gidStr)
        self.validateGid(gid)
        # request_hash is optional
        if requestHash:
            self.verifyGidRequestHash(gid, requestHash, argList)
        return gid

    def authenticateCred(self, credStr, argList, requestHash=None):
        cred = Credential(string = credStr)
        self.validateCred(cred)
        # request hash is optional
        if requestHash:
            self.verifyCredRequestHash(cred, requestHash, argList)
        return cred

    def authenticateCert(self, certStr, requestHash):
        cert = Certificate(string=certStr)
        # xxx should be validateCred ??
        self.validateCred(cert)   

    def gidNoop(self, gidStr, value, requestHash):
        self.authenticateGid(gidStr, [gidStr, value], requestHash)
        return value

    def credNoop(self, credStr, value, requestHash):
        self.authenticateCred(credStr, [credStr, value], requestHash)
        return value

    def verify_cred_is_me(self, credential):
        is_me = False 
        cred = Credential(string=credential)
        caller_gid = cred.get_gid_caller()
        caller_hrn = caller_gid.get_hrn()
        if caller_hrn != self.config.SFA_INTERFACE_HRN:
            raise SfaPermissionDenied(self.config.SFA_INTEFACE_HRN)

        return   
        
    def get_auth_info(self, auth_hrn):
        """
        Given an authority name, return the information for that authority.
        This is basically a stub that calls the hierarchy module.
        
        @param auth_hrn human readable name of authority  
        """

        return self.hierarchy.get_auth_info(auth_hrn)


    def veriry_auth_belongs_to_me(self, name):
        """
        Verify that an authority belongs to our hierarchy. 
        This is basically left up to the implementation of the hierarchy
        module. If the specified name does not belong, ane exception is 
        thrown indicating the caller should contact someone else.

        @param auth_name human readable name of authority
        """

        # get auth info will throw an exception if the authority doesnt exist
        self.get_auth_info(name)


    def verify_object_belongs_to_me(self, name):
        """
        Verify that an object belongs to our hierarchy. By extension,
        this implies that the authority that owns the object belongs
        to our hierarchy. If it does not an exception is thrown.
    
        @param name human readable name of object        
        """
        auth_name = self.get_authority(name)
        if not auth_name:
            auth_name = name 
        if name == self.config.SFA_INTERFACE_HRN:
            return
        self.verify_auth_belongs_to_me(auth_name) 
             
    def verify_auth_belongs_to_me(self, name):
        # get auth info will throw an exception if the authority doesnt exist
        self.get_auth_info(name) 


    def verify_object_permission(self, name):
        """
        Verify that the object gid that was specified in the credential
        allows permission to the object 'name'. This is done by a simple
        prefix test. For example, an object_gid for plc.arizona would 
        match the objects plc.arizona.slice1 and plc.arizona.
    
        @param name human readable name to test  
        """
        object_hrn = self.object_gid.get_hrn()
        if object_hrn == name:
            return
        if name.startswith(object_hrn + "."):
            return
        #if name.startswith(get_authority(name)):
            #return
    
        raise PermissionError(name)

    def determine_user_rights(self, caller_hrn, reg_record):
        """
        Given a user credential and a record, determine what set of rights the
        user should have to that record.
        
        This is intended to replace determine_user_rights() and
        verify_cancreate_credential()
        """

        rl = Rights()
        type = reg_record.type

        logger.debug("entering determine_user_rights with record %s and caller_hrn %s"%\
                     (reg_record, caller_hrn))

        if type == 'slice':
            # researchers in the slice are in the DB as-is
            researcher_hrns = [ user.hrn for user in reg_record.reg_researchers ]
            # locating PIs attached to that slice
            slice_pis=reg_record.get_pis()
            pi_hrns = [ user.hrn for user in slice_pis ]
            if (caller_hrn in researcher_hrns + pi_hrns):
                rl.add('refresh')
                rl.add('embed')
                rl.add('bind')
                rl.add('control')
                rl.add('info')

        elif type == 'authority':
            pi_hrns = [ user.hrn for user in reg_record.reg_pis ]
            if (caller_hrn == self.config.SFA_INTERFACE_HRN):
                rl.add('authority')
                rl.add('sa')
                rl.add('ma')
            if (caller_hrn in pi_hrns):
                rl.add('authority')
                rl.add('sa')
            # NOTE: for the PL implementation, this 'operators' list 
            # amounted to users with 'tech' role in that site 
            # it seems like this is not needed any longer, so for now I just drop that
            # operator_hrns = reg_record.get('operator',[])
            # if (caller_hrn in operator_hrns):
            #    rl.add('authority')
            #    rl.add('ma')

        elif type == 'user':
            rl.add('refresh')
            rl.add('resolve')
            rl.add('info')

        elif type == 'node':
            rl.add('operator')

        return rl

    def get_authority(self, hrn):
        return get_authority(hrn)

    def filter_creds_by_caller(self, creds, caller_hrn_list):
        """
        Returns a list of creds who's gid caller matches the 
        specified caller hrn
        """
        if not isinstance(creds, list):
            creds = [creds]
        creds = []
        if not isinstance(caller_hrn_list, list):
            caller_hrn_list = [caller_hrn_list]
        for cred in creds:
            try:
                tmp_cred = Credential(string=cred)
                if tmp_cred.get_gid_caller().get_hrn() in [caller_hrn_list]:
                    creds.append(cred)
            except: pass
        return creds
Example #24
0
File: auth.py Project: tubav/sfa
class Auth:
    """
    Credential based authentication
    """

    def __init__(self, peer_cert = None, config = None ):
        self.peer_cert = peer_cert
        self.hierarchy = Hierarchy()
        if not config:
            self.config = Config()
        self.load_trusted_certs()

    def load_trusted_certs(self):
        self.trusted_cert_list = TrustedRoots(self.config.get_trustedroots_dir()).get_list()
        self.trusted_cert_file_list = TrustedRoots(self.config.get_trustedroots_dir()).get_file_list()

        
        
    def checkCredentials(self, creds, operation, hrn = None):
        valid = []
        if not isinstance(creds, list):
            creds = [creds]
        logger.debug("Auth.checkCredentials with %d creds"%len(creds))
        for cred in creds:
            try:
                self.check(cred, operation, hrn)
                valid.append(cred)
            except:
                cred_obj=Credential(string=cred)
                logger.debug("failed to validate credential - dump=%s"%cred_obj.dump_string(dump_parents=True))
                error = sys.exc_info()[:2]
                continue
            
        if not len(valid):
            raise InsufficientRights('Access denied: %s -- %s' % (error[0],error[1]))
        
        return valid
        
        
    def check(self, cred, operation, hrn = None):
        """
        Check the credential against the peer cert (callerGID included 
        in the credential matches the caller that is connected to the 
        HTTPS connection, check if the credential was signed by a 
        trusted cert and check if the credential is allowed to perform 
        the specified operation.    
        """
        self.client_cred = Credential(string = cred)
        self.client_gid = self.client_cred.get_gid_caller()
        self.object_gid = self.client_cred.get_gid_object()
        
        # make sure the client_gid is not blank
        if not self.client_gid:
            raise MissingCallerGID(self.client_cred.get_subject())
       
        # validate the client cert if it exists
        if self.peer_cert:
            self.verifyPeerCert(self.peer_cert, self.client_gid)                   

        # make sure the client is allowed to perform the operation
        if operation:
            if not self.client_cred.can_perform(operation):
                raise InsufficientRights(operation)

        if self.trusted_cert_list:
            self.client_cred.verify(self.trusted_cert_file_list, self.config.SFA_CREDENTIAL_SCHEMA)
        else:
           raise MissingTrustedRoots(self.config.get_trustedroots_dir())
       
        # Make sure the credential's target matches the specified hrn. 
        # This check does not apply to trusted peers 
        trusted_peers = [gid.get_hrn() for gid in self.trusted_cert_list]
        if hrn and self.client_gid.get_hrn() not in trusted_peers:
            target_hrn = self.object_gid.get_hrn()
            if not hrn == target_hrn:
                raise PermissionError("Target hrn: %s doesn't match specified hrn: %s " % \
                                       (target_hrn, hrn) )       
        return True

    def check_ticket(self, ticket):
        """
        Check if the tickt was signed by a trusted cert
        """
        if self.trusted_cert_list:
            client_ticket = SfaTicket(string=ticket)
            client_ticket.verify_chain(self.trusted_cert_list)
        else:
           raise MissingTrustedRoots(self.config.get_trustedroots_dir())

        return True 

    def verifyPeerCert(self, cert, gid):
        # make sure the client_gid matches client's certificate
        if not cert.is_pubkey(gid.get_pubkey()):
            raise ConnectionKeyGIDMismatch(gid.get_subject()+":"+cert.get_subject())            

    def verifyGidRequestHash(self, gid, hash, arglist):
        key = gid.get_pubkey()
        if not key.verify_string(str(arglist), hash):
            raise BadRequestHash(hash)

    def verifyCredRequestHash(self, cred, hash, arglist):
        gid = cred.get_gid_caller()
        self.verifyGidRequestHash(gid, hash, arglist)

    def validateGid(self, gid):
        if self.trusted_cert_list:
            gid.verify_chain(self.trusted_cert_list)

    def validateCred(self, cred):
        if self.trusted_cert_list:
            cred.verify(self.trusted_cert_file_list)

    def authenticateGid(self, gidStr, argList, requestHash=None):
        gid = GID(string = gidStr)
        self.validateGid(gid)
        # request_hash is optional
        if requestHash:
            self.verifyGidRequestHash(gid, requestHash, argList)
        return gid

    def authenticateCred(self, credStr, argList, requestHash=None):
        cred = Credential(string = credStr)
        self.validateCred(cred)
        # request hash is optional
        if requestHash:
            self.verifyCredRequestHash(cred, requestHash, argList)
        return cred

    def authenticateCert(self, certStr, requestHash):
        cert = Certificate(string=certStr)
        # xxx should be validateCred ??
        self.validateCred(cert)   

    def gidNoop(self, gidStr, value, requestHash):
        self.authenticateGid(gidStr, [gidStr, value], requestHash)
        return value

    def credNoop(self, credStr, value, requestHash):
        self.authenticateCred(credStr, [credStr, value], requestHash)
        return value

    def verify_cred_is_me(self, credential):
        is_me = False 
        cred = Credential(string=credential)
        caller_gid = cred.get_gid_caller()
        caller_hrn = caller_gid.get_hrn()
        if caller_hrn != self.config.SFA_INTERFACE_HRN:
            raise SfaPermissionDenied(self.config.SFA_INTEFACE_HRN)

        return   
        
    def get_auth_info(self, auth_hrn):
        """
        Given an authority name, return the information for that authority.
        This is basically a stub that calls the hierarchy module.
        
        @param auth_hrn human readable name of authority  
        """

        return self.hierarchy.get_auth_info(auth_hrn)


    def veriry_auth_belongs_to_me(self, name):
        """
        Verify that an authority belongs to our hierarchy. 
        This is basically left up to the implementation of the hierarchy
        module. If the specified name does not belong, ane exception is 
        thrown indicating the caller should contact someone else.

        @param auth_name human readable name of authority
        """

        # get auth info will throw an exception if the authority doesnt exist
        self.get_auth_info(name)


    def verify_object_belongs_to_me(self, name):
        """
        Verify that an object belongs to our hierarchy. By extension,
        this implies that the authority that owns the object belongs
        to our hierarchy. If it does not an exception is thrown.
    
        @param name human readable name of object        
        """
        auth_name = self.get_authority(name)
        if not auth_name:
            auth_name = name 
        if name == self.config.SFA_INTERFACE_HRN:
            return
        self.verify_auth_belongs_to_me(auth_name) 
             
    def verify_auth_belongs_to_me(self, name):
        # get auth info will throw an exception if the authority doesnt exist
        self.get_auth_info(name) 


    def verify_object_permission(self, name):
        """
        Verify that the object gid that was specified in the credential
        allows permission to the object 'name'. This is done by a simple
        prefix test. For example, an object_gid for plc.arizona would 
        match the objects plc.arizona.slice1 and plc.arizona.
    
        @param name human readable name to test  
        """
        object_hrn = self.object_gid.get_hrn()
        if object_hrn == name:
            return
        if name.startswith(object_hrn + "."):
            return
        #if name.startswith(get_authority(name)):
            #return
    
        raise PermissionError(name)

    def determine_user_rights(self, caller_hrn, reg_record):
        """
        Given a user credential and a record, determine what set of rights the
        user should have to that record.
        
        This is intended to replace determine_user_rights() and
        verify_cancreate_credential()
        """

        rl = Rights()
        type = reg_record.type

        logger.debug("entering determine_user_rights with record %s and caller_hrn %s"%(reg_record, caller_hrn))

        if type == 'slice':
            # researchers in the slice are in the DB as-is
            researcher_hrns = [ user.hrn for user in reg_record.reg_researchers ]
            # locating PIs attached to that slice
            slice_pis=reg_record.get_pis()
            pi_hrns = [ user.hrn for user in slice_pis ]
            if (caller_hrn in researcher_hrns + pi_hrns):
                rl.add('refresh')
                rl.add('embed')
                rl.add('bind')
                rl.add('control')
                rl.add('info')

        elif type == 'authority':
            pi_hrns = [ user.hrn for user in reg_record.reg_pis ]
            if (caller_hrn == self.config.SFA_INTERFACE_HRN):
                rl.add('authority')
                rl.add('sa')
                rl.add('ma')
            if (caller_hrn in pi_hrns):
                rl.add('authority')
                rl.add('sa')
            # NOTE: for the PL implementation, this 'operators' list 
            # amounted to users with 'tech' role in that site 
            # it seems like this is not needed any longer, so for now I just drop that
            # operator_hrns = reg_record.get('operator',[])
            # if (caller_hrn in operator_hrns):
            #    rl.add('authority')
            #    rl.add('ma')

        elif type == 'user':
            rl.add('refresh')
            rl.add('resolve')
            rl.add('info')

        elif type == 'node':
            rl.add('operator')

        return rl

    def get_authority(self, hrn):
        return get_authority(hrn)

    def filter_creds_by_caller(self, creds, caller_hrn_list):
        """
        Returns a list of creds who's gid caller matches the 
        specified caller hrn
        """
        if not isinstance(creds, list):
            creds = [creds]
        creds = []
        if not isinstance(caller_hrn_list, list):
            caller_hrn_list = [caller_hrn_list]
        for cred in creds:
            try:
                tmp_cred = Credential(string=cred)
                if tmp_cred.get_gid_caller().get_hrn() in [caller_hrn_list]:
                    creds.append(cred)
            except: pass
        return creds
Example #25
0
 def __init__(self, peer_cert=None, config=None):
     self.peer_cert = peer_cert
     self.hierarchy = Hierarchy()
     if not config:
         self.config = Config()
     self.load_trusted_certs()
Example #26
0
class Auth:
    """
    Credential based authentication
    """
    def __init__(self, peer_cert=None, config=None):
        self.peer_cert = peer_cert
        self.hierarchy = Hierarchy()
        if not config:
            self.config = Config()
        self.load_trusted_certs()

    def load_trusted_certs(self):
        self.trusted_cert_list = TrustedRoots(
            self.config.get_trustedroots_dir()).get_list()
        self.trusted_cert_file_list = TrustedRoots(
            self.config.get_trustedroots_dir()).get_file_list()

    def checkCredentials(self,
                         creds,
                         operation,
                         xrns=[],
                         check_sliver_callback=None,
                         speaking_for_hrn=None):
        def log_invalid_cred(cred):
            cred_obj = Credential(string=cred)
            logger.debug("failed to validate credential - dump=%s" %
                         cred_obj.dump_string(dump_parents=True))
            error = sys.exc_info()[:2]
            return error

        # if xrns are specified they cannot be None or empty string
        if xrns:
            for xrn in xrns:
                if not xrn:
                    raise BadArgs("Invalid urn or hrn")

        if not isinstance(xrns, list):
            xrns = [xrns]

        slice_xrns = Xrn.filter_type(xrns, 'slice')
        sliver_xrns = Xrn.filter_type(xrns, 'sliver')

        # we are not able to validate slivers in the traditional way so
        # we make sure not to include sliver urns/hrns in the core validation loop
        hrns = [Xrn(xrn).hrn for xrn in xrns if xrn not in sliver_xrns]
        valid = []
        speaks_for_cred = None
        if not isinstance(creds, list):
            creds = [creds]
        logger.debug("Auth.checkCredentials with %d creds on hrns=%s" %
                     (len(creds), hrns))
        # won't work if either creds or hrns is empty - let's make it more explicit
        if not creds:
            raise BadArgs(
                "no credential provided")  #Forbidden("no credential provided")
        if not hrns: hrns = [None]
        for cred in creds:
            for hrn in hrns:
                try:
                    self.check(cred, operation, hrn)
                    valid.append(cred)
                except:
                    if speaking_for_hrn:
                        try:
                            self.check(cred, operation, speaking_for_hrn)
                            speaks_for_cred = cred
                            valid.append(cred)
                        except:
                            error = log_invalid_cred(cred)
                    else:
                        error = log_invalid_cred(cred)
                    continue

        # make sure all sliver xrns are validated against the valid credentials
        if sliver_xrns:
            if not check_sliver_callback:
                msg = "sliver verification callback method not found."
                msg += " Unable to validate sliver xrns: %s" % sliver_xrns
                raise Forbidden(msg)
            check_sliver_callback(valid, sliver_xrns)

        if not len(valid):
            raise Forbidden("Invalid credential")

        if speaking_for_hrn and not speaks_for_cred:
            raise InsufficientRights(
                'Access denied: "geni_speaking_for" option specified but no valid speaks for credential found: %s -- %s'
                % (error[0], error[1]))

        return valid

    def check(self, credential, operation, hrn=None):
        """
        Check the credential against the peer cert (callerGID included 
        in the credential matches the caller that is connected to the 
        HTTPS connection, check if the credential was signed by a 
        trusted cert and check if the credential is allowed to perform 
        the specified operation.    
        """
        cred = Credential(cred=credential)
        self.client_cred = cred
        logger.debug("Auth.check: handling hrn=%s and credential=%s"%\
                         (hrn,cred.get_summary_tostring()))

        if cred.type not in ['geni_sfa']:
            raise CredentialNotVerifiable(cred.type,
                                          "%s not supported" % cred.type)
        self.client_gid = self.client_cred.get_gid_caller()
        self.object_gid = self.client_cred.get_gid_object()

        # make sure the client_gid is not blank
        if not self.client_gid:
            raise MissingCallerGID(self.client_cred.get_subject())

        # validate the client cert if it exists
        if self.peer_cert:
            self.verifyPeerCert(self.peer_cert, self.client_gid)

        # make sure the client is allowed to perform the operation
        if operation:
            if not self.client_cred.can_perform(operation):
                raise InsufficientRights(operation)

        if self.trusted_cert_list:
            self.client_cred.verify(self.trusted_cert_file_list,
                                    self.config.SFA_CREDENTIAL_SCHEMA)
        else:
            raise MissingTrustedRoots(self.config.get_trustedroots_dir())

        # Make sure the credential's target matches the specified hrn.
        # This check does not apply to trusted peers
        trusted_peers = [gid.get_hrn() for gid in self.trusted_cert_list]
        if hrn and self.client_gid.get_hrn() not in trusted_peers:
            target_hrn = self.object_gid.get_hrn()
            if not hrn == target_hrn:
                raise PermissionError("Target hrn: %s doesn't match specified hrn: %s " % \
                                       (target_hrn, hrn) )
        return True

    def check_ticket(self, ticket):
        """
        Check if the tickt was signed by a trusted cert
        """
        if self.trusted_cert_list:
            client_ticket = SfaTicket(string=ticket)
            client_ticket.verify_chain(self.trusted_cert_list)
        else:
            raise MissingTrustedRoots(self.config.get_trustedroots_dir())

        return True

    def verifyPeerCert(self, cert, gid):
        # make sure the client_gid matches client's certificate
        if not cert.is_pubkey(gid.get_pubkey()):
            raise ConnectionKeyGIDMismatch(gid.get_subject() + ":" +
                                           cert.get_subject())

    def verifyGidRequestHash(self, gid, hash, arglist):
        key = gid.get_pubkey()
        if not key.verify_string(str(arglist), hash):
            raise BadRequestHash(hash)

    def verifyCredRequestHash(self, cred, hash, arglist):
        gid = cred.get_gid_caller()
        self.verifyGidRequestHash(gid, hash, arglist)

    def validateGid(self, gid):
        if self.trusted_cert_list:
            gid.verify_chain(self.trusted_cert_list)

    def validateCred(self, cred):
        if self.trusted_cert_list:
            cred.verify(self.trusted_cert_file_list)

    def authenticateGid(self, gidStr, argList, requestHash=None):
        gid = GID(string=gidStr)
        self.validateGid(gid)
        # request_hash is optional
        if requestHash:
            self.verifyGidRequestHash(gid, requestHash, argList)
        return gid

    def authenticateCred(self, credStr, argList, requestHash=None):
        cred = Credential(string=credStr)
        self.validateCred(cred)
        # request hash is optional
        if requestHash:
            self.verifyCredRequestHash(cred, requestHash, argList)
        return cred

    def authenticateCert(self, certStr, requestHash):
        cert = Certificate(string=certStr)
        # xxx should be validateCred ??
        self.validateCred(cert)

    def gidNoop(self, gidStr, value, requestHash):
        self.authenticateGid(gidStr, [gidStr, value], requestHash)
        return value

    def credNoop(self, credStr, value, requestHash):
        self.authenticateCred(credStr, [credStr, value], requestHash)
        return value

    def verify_cred_is_me(self, credential):
        is_me = False
        cred = Credential(string=credential)
        caller_gid = cred.get_gid_caller()
        caller_hrn = caller_gid.get_hrn()
        if caller_hrn != self.config.SFA_INTERFACE_HRN:
            raise SfaPermissionDenied(self.config.SFA_INTEFACE_HRN)

        return

    def get_auth_info(self, auth_hrn):
        """
        Given an authority name, return the information for that authority.
        This is basically a stub that calls the hierarchy module.
        
        @param auth_hrn human readable name of authority  
        """

        return self.hierarchy.get_auth_info(auth_hrn)

    def veriry_auth_belongs_to_me(self, name):
        """
        Verify that an authority belongs to our hierarchy. 
        This is basically left up to the implementation of the hierarchy
        module. If the specified name does not belong, ane exception is 
        thrown indicating the caller should contact someone else.

        @param auth_name human readable name of authority
        """

        # get auth info will throw an exception if the authority doesnt exist
        self.get_auth_info(name)

    def verify_object_belongs_to_me(self, name):
        """
        Verify that an object belongs to our hierarchy. By extension,
        this implies that the authority that owns the object belongs
        to our hierarchy. If it does not an exception is thrown.
    
        @param name human readable name of object        
        """
        auth_name = self.get_authority(name)
        if not auth_name:
            auth_name = name
        if name == self.config.SFA_INTERFACE_HRN:
            return
        self.verify_auth_belongs_to_me(auth_name)

    def verify_auth_belongs_to_me(self, name):
        # get auth info will throw an exception if the authority doesnt exist
        self.get_auth_info(name)

    def verify_object_permission(self, name):
        """
        Verify that the object gid that was specified in the credential
        allows permission to the object 'name'. This is done by a simple
        prefix test. For example, an object_gid for plc.arizona would 
        match the objects plc.arizona.slice1 and plc.arizona.
    
        @param name human readable name to test  
        """
        object_hrn = self.object_gid.get_hrn()
        logger.debug(
            "VERIFY OBJECT PERMISSION. \n\n object_hrn: %s \n name: %s \n get_authority(name): %s"
            % (object_hrn, name, get_authority(name)))
        if object_hrn == name:
            return
        if name.startswith(object_hrn + "."):
            return
        #if name.startswith(get_authority(name)):
        #return

        raise PermissionError(name)

    def determine_user_rights(self, caller_hrn, reg_record):
        """
        Given a user credential and a record, determine what set of rights the
        user should have to that record.
        
        This is intended to replace determine_user_rights() and
        verify_cancreate_credential()
        """

        rl = Rights()
        type = reg_record.type

        logger.debug(
            "entering determine_user_rights with record %s and caller_hrn %s" %
            (reg_record, caller_hrn))

        if type == 'slice':
            # researchers in the slice are in the DB as-is
            researcher_hrns = [user.hrn for user in reg_record.reg_researchers]
            # locating PIs attached to that slice
            slice_pis = reg_record.get_pis()
            pi_hrns = [user.hrn for user in slice_pis]
            if (caller_hrn in researcher_hrns + pi_hrns):
                rl.add('refresh')
                rl.add('embed')
                rl.add('bind')
                rl.add('control')
                rl.add('info')

        elif type == 'authority':
            pi_hrns = [user.hrn for user in reg_record.reg_pis]
            if (caller_hrn == self.config.SFA_INTERFACE_HRN):
                rl.add('authority')
                rl.add('sa')
                rl.add('ma')
            if (caller_hrn in pi_hrns):
                rl.add('authority')
                rl.add('sa')
            # NOTE: for the PL implementation, this 'operators' list
            # amounted to users with 'tech' role in that site
            # it seems like this is not needed any longer, so for now I just drop that
            # operator_hrns = reg_record.get('operator',[])
            # if (caller_hrn in operator_hrns):
            #    rl.add('authority')
            #    rl.add('ma')

        elif type == 'user':
            rl.add('refresh')
            rl.add('resolve')
            rl.add('info')

        elif type == 'node':
            rl.add('operator')

        return rl

    def get_authority(self, hrn):
        return get_authority(hrn)

    def filter_creds_by_caller(self, creds, caller_hrn_list):
        """
        Returns a list of creds who's gid caller matches the 
        specified caller hrn
        """
        if not isinstance(creds, list):
            creds = [creds]
        creds = []
        if not isinstance(caller_hrn_list, list):
            caller_hrn_list = [caller_hrn_list]
        for cred in creds:
            try:
                tmp_cred = Credential(string=cred)
                if tmp_cred.get_gid_caller().get_hrn() in [caller_hrn_list]:
                    creds.append(cred)
            except:
                pass
        return creds
Example #27
0
from sfa.generic import Generic
from sfa.util.xrn import Xrn
from sfa.storage.record import Record
from sfa.client.sfi import save_records_to_file
from sfa.trust.hierarchy import Hierarchy
from sfa.trust.gid import GID
from sfa.trust.certificate import convert_public_key

from sfa.client.candidates import Candidates

from sfa.client.common import optparse_listvalue_callback, optparse_dictvalue_callback, terminal_render, filter_records

pprinter = PrettyPrinter(indent=4)

try:
    help_basedir = Hierarchy().basedir
except:
    help_basedir = '*unable to locate Hierarchy().basedir'


def args(*args, **kwargs):
    def _decorator(func):
        func.__dict__.setdefault('options', []).insert(0, (args, kwargs))
        return func

    return _decorator


class Commands(object):
    def _get_commands(self):
        command_names = []