Ejemplo n.º 1
0
    def getCredential(self):
        """
        Get our credential from a remote registry
        """
        path = self.config.SFA_DATA_DIR
        config_dir = self.config.config_path
        cred_filename = path + os.sep + 'node.cred'
        try:
            credential = Credential(filename=cred_filename)
            return credential.save_to_string(save_parents=True)
        except IOError:
            node_pkey_file = config_dir + os.sep + "node.key"
            node_gid_file = config_dir + os.sep + "node.gid"
            cert_filename = path + os.sep + 'server.cert'
            if not os.path.exists(node_pkey_file) or \
               not os.path.exists(node_gid_file):
                self.get_node_key()

            # get node's hrn
            gid = GID(filename=node_gid_file)
            hrn = gid.get_hrn()
            # get credential from registry
            cert_str = Certificate(filename=cert_filename).save_to_string(
                save_parents=True)
            registry = self.get_registry()
            cred = registry.GetSelfCredential(cert_str, hrn, 'node')
            # xxx credfile is undefined
            Credential(string=cred).save_to_file(credfile, save_parents=True)

            return cred
Ejemplo n.º 2
0
    def delegate_credential_string (self, original_credential, to_hrn, to_type='authority'):
        """
        sign a delegation credential to someone else

        original_credential : typically one's user- or slice- credential to be delegated to s/b else
        to_hrn : the hrn of the person that will be allowed to do stuff on our behalf
        to_type : goes with to_hrn, usually 'user' or 'authority'

        returns a string with the delegated credential

        this internally uses self.my_gid()
        it also retrieves the gid for to_hrn/to_type
        and uses Credential.delegate()"""

        # the gid and hrn of the object we are delegating
        if isinstance (original_credential, str):
            original_credential = Credential (string=original_credential)
        original_gid = original_credential.get_gid_object()
        original_hrn = original_gid.get_hrn()

        if not original_credential.get_privileges().get_all_delegate():
            self.logger.error("delegate_credential_string: original credential %s does not have delegate bit set"%original_hrn)
            return

        # the delegating user's gid
        my_gid = self.my_gid()

        # retrieve the GID for the entity that we're delegating to
        to_gidfile = self.gid (to_hrn,to_type)
#        to_gid = GID ( to_gidfile )
#        to_hrn = delegee_gid.get_hrn()
#        print 'to_hrn',to_hrn
        delegated_credential = original_credential.delegate(to_gidfile, self.private_key(), my_gid)
        return delegated_credential.save_to_string(save_parents=True)
Ejemplo n.º 3
0
Archivo: api.py Proyecto: planetlab/sfa
    def getCredential(self):
        """
        Get our credential from a remote registry
        """
        path = self.config.SFA_DATA_DIR
        config_dir = self.config.config_path
        cred_filename = path + os.sep + 'node.cred'
        try:
            credential = Credential(filename = cred_filename)
            return credential.save_to_string(save_parents=True)
        except IOError:
            node_pkey_file = config_dir + os.sep + "node.key"
            node_gid_file = config_dir + os.sep + "node.gid"
            cert_filename = path + os.sep + 'server.cert'
            if not os.path.exists(node_pkey_file) or \
               not os.path.exists(node_gid_file):
                self.get_node_key()

            # get node's hrn
            gid = GID(filename=node_gid_file)
            hrn = gid.get_hrn()
            # get credential from registry
            cert_str = Certificate(filename=cert_filename).save_to_string(save_parents=True)
            registry = self.get_registry()
            cred = registry.GetSelfCredential(cert_str, hrn, 'node')
            Credential(string=cred).save_to_file(credfile, save_parents=True)            

            return cred
Ejemplo n.º 4
0
Archivo: sfi.py Proyecto: planetlab/sfa
    def get_cred(self, file, type, hrn):
        # attempt to load a cached credential 
        cred = self.get_cached_credential(file)    
        if not cred:
            if type in ['user']:
                cert_string = self.cert.save_to_string(save_parents=True)
                user_name = self.user.replace(self.authority + ".", '')
                if user_name.count(".") > 0:
                    user_name = user_name.replace(".", '_')
                    self.user = self.authority + "." + user_name
                cred_str = self.registry.GetSelfCredential(cert_string, hrn, "user")
            else:
                # bootstrap slice credential from user credential
                user_cred = self.get_user_cred().save_to_string(save_parents=True)
                cred_str = self.registry.GetCredential(user_cred, hrn, type)
            
            if not cred_str:
                self.logger.critical("Failed to get %s credential" % type)
                sys.exit(-1)
                
            cred = Credential(string=cred_str)
            cred.save_to_file(file, save_parents=True)
            self.logger.info("Writing %s credential to %s" %(type, file))

        return cred
Ejemplo n.º 5
0
    def call(self, cred, record_dict, origin_hrn=None):
        user_cred = Credential(string=cred)

        #log the call
        if not origin_hrn:
            origin_hrn = user_cred.get_gid_caller().get_hrn()    
        self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, None, self.name))

        # validate the cred
        self.api.auth.check(cred, "register")

        # make sure this is a peer record
        if 'peer_authority' not in record_dict or \
           not record_dict['peer_authority']: 
            raise SfaInvalidArgument, "peer_authority must be specified" 

        record = SfaRecord(dict = record_dict)
        type, hrn, peer_authority = record['type'], record['hrn'], record['peer_authority']
        record['authority'] = get_authority(record['hrn'])
        # verify permissions
        self.api.auth.verify_cred_is_me(cred)

        # check if record already exists
        table = SfaTable()
        existing_records = table.find({'type': type, 'hrn': hrn, 'peer_authority': peer_authority})
        if existing_records:
            for existing_record in existing_records:
                if existing_record['pointer'] != record['pointer']:
                    record['record_id'] = existing_record['record_id']
                    table.update(record)
        else:
            record_id = table.insert(record)
 
        return 1
Ejemplo n.º 6
0
    def delegate_cred(self, object_cred, hrn, type='authority'):

        # the gid and hrn of the object we are delegating
        if isinstance(object_cred, str):  # XXX Yes here we give a string...
            object_cred = Credential(string=object_cred)
        object_gid = object_cred.get_gid_object()
        object_hrn = object_gid.get_hrn()

        if not object_cred.get_privileges().get_all_delegate():
            self.logger.error(
                "Object credential %s does not have delegate bit set" %
                object_hrn)
            return

        # the delegating user's gid # XXX done in bootstrap
        caller_gidfile = self.my_gid  # already a string # XXX ERROR tell thierry

        # the gid of the user who will be delegated to
        delegee_gid = self.bootstrap.gid(
            hrn, 'user')  # XXX bootstrap ERROR tell thierry
        delegee_hrn = GID(delegee_gid).get_hrn()
        # XXX pkey done in bootstrap
        dcred = object_cred.delegate(delegee_gid, self.private_key,
                                     caller_gidfile)
        return dcred.save_to_string(save_parents=True)
Ejemplo n.º 7
0
 def validate_credential(self, filename):
     valid = True
     cred = Credential(filename=filename)
     # check if credential is expires
     if cred.get_expiration() < datetime.now():
         valid = False
     return valid
Ejemplo n.º 8
0
 def validate_credential(self, filename):
     valid = True
     cred = Credential(filename=filename)
     # check if credential is expires
     if cred.get_expiration() < datetime.utcnow():
         valid = False
     return valid
Ejemplo n.º 9
0
def __get_registry_objects(slice_xrn, creds, users):
    """

    """
    hrn, type = urn_to_hrn(slice_xrn)

    hrn_auth = get_authority(hrn)

    # Build up objects that an SFA registry would return if SFA
    # could contact the slice's registry directly
    reg_objects = None

    if users:
        # dont allow special characters in the site login base
        #only_alphanumeric = re.compile('[^a-zA-Z0-9]+')
        #login_base = only_alphanumeric.sub('', hrn_auth[:20]).lower()
        slicename = hrn_to_pl_slicename(hrn)
        login_base = slicename.split('_')[0]
        reg_objects = {}
        site = {}
        site['site_id'] = 0
        site['name'] = 'geni.%s' % login_base 
        site['enabled'] = True
        site['max_slices'] = 100

        # Note:
        # Is it okay if this login base is the same as one already at this myplc site?
        # Do we need uniqueness?  Should use hrn_auth instead of just the leaf perhaps?
        site['login_base'] = login_base
        site['abbreviated_name'] = login_base
        site['max_slivers'] = 1000
        reg_objects['site'] = site

        slice = {}
        
        # get_expiration always returns a normalized datetime - no need to utcparse
        extime = Credential(string=creds[0]).get_expiration()
        # If the expiration time is > 60 days from now, set the expiration time to 60 days from now
        if extime > datetime.datetime.utcnow() + datetime.timedelta(days=60):
            extime = datetime.datetime.utcnow() + datetime.timedelta(days=60)
        slice['expires'] = int(time.mktime(extime.timetuple()))
        slice['hrn'] = hrn
        slice['name'] = hrn_to_pl_slicename(hrn)
        slice['url'] = hrn
        slice['description'] = hrn
        slice['pointer'] = 0
        reg_objects['slice_record'] = slice

        reg_objects['users'] = {}
        for user in users:
            user['key_ids'] = []
            hrn, _ = urn_to_hrn(user['urn'])
            user['email'] = hrn_to_pl_slicename(hrn) + "@geni.net"
            user['first_name'] = hrn
            user['last_name'] = hrn
            reg_objects['users'][user['email']] = user

        return reg_objects
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
    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   
Ejemplo n.º 12
0
 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
Ejemplo n.º 13
0
Archivo: sfi.py Proyecto: planetlab/sfa
 def get_cached_credential(self, file):
     """
     Return a cached credential only if it hasn't expired.
     """
     if (os.path.isfile(file)):
         credential = Credential(filename=file)
         # make sure it isnt expired 
         if not credential.get_expiration or \
            datetime.datetime.today() < credential.get_expiration():
             return credential
     return None 
Ejemplo n.º 14
0
    def Delete(self, api, xrn, creds, options):
        call_id = options.get('call_id')
        if Callids().already_handled(call_id): return ""

        def _Delete(server, xrn, creds, options):
            return server.Delete(xrn, creds, options)

        (hrn, type) = urn_to_hrn(xrn[0])
        # get the callers hrn
        valid_cred = api.auth.checkCredentials(creds, 'deletesliver', hrn)[0]
        caller_hrn = Credential(cred=valid_cred).get_gid_caller().get_hrn()

        # attempt to use delegated credential first
        cred = api.getDelegatedCredential(creds)
        if not cred:
            cred = api.getCredential()
        multiclient = MultiClient()
        for aggregate in api.aggregates:
            # prevent infinite loop. Dont send request back to caller
            # unless the caller is the aggregate's SM
            if caller_hrn == aggregate and aggregate != api.hrn:
                continue
            interface = api.aggregates[aggregate]
            server = api.server_proxy(interface, cred)
            multiclient.run(_Delete, server, xrn, [cred], options)
        
        results = []
        for result in multiclient.get_results():
            results += ReturnValue.get_value(result)
        return results
Ejemplo n.º 15
0
    def call(self, urns, creds, options):
        self.api.logger.info("interface: %s\tmethod-name: %s" % (self.api.interface, self.name))
       
        # client must specify a version
        if not options.get('geni_rspec_version'):
            if options.get('rspec_version'):
                options['geni_rspec_version'] = options['rspec_version']
            else:
                raise SfaInvalidArgument('Must specify an rspec version option. geni_rspec_version cannot be null')
        (speaking_for, _) = urn_to_hrn(options.get('geni_speaking_for'))
        valid_creds = self.api.auth.checkCredentials(creds, 'listnodes', urns, \
                      check_sliver_callback = self.api.driver.check_sliver_credentials,
                      speaking_for_hrn=speaking_for)

        # get hrn of the original caller 
        origin_hrn = options.get('origin_hrn', None)
        if not origin_hrn:
            origin_hrn = Credential(cred=valid_creds[0]).get_gid_caller().get_hrn()
        desc = self.api.manager.Describe(self.api, creds, urns, options)

        # filter rspec through sfatables 
        if self.api.interface in ['aggregate']:
            chain_name = 'OUTGOING'
        elif self.api.interface in ['slicemgr']: 
            chain_name = 'FORWARD-OUTGOING'
        self.api.logger.debug("ListResources: sfatables on chain %s"%chain_name)
        desc['geni_rspec'] = run_sfatables(chain_name, '', origin_hrn, desc['geni_rspec']) 
 
        if options.has_key('geni_compressed') and options['geni_compressed'] == True:
            desc['geni_rspec'] = zlib.compress(desc['geni_rspec']).encode('base64')

        return desc  
Ejemplo n.º 16
0
def determine_sfa_filekind(fn):

    if fn.endswith('.gid'): return 'gid'
    elif fn.endswith('.cert'): return 'certificate'
    elif fn.endswith('cred'): return 'credential'

    try:
        cred=Credential(filename=fn)
        return 'credential'
    except: pass

    try: 
        gid=GID(filename=fn)
        if gid.uuid: return 'gid'
    except: pass

    try:
        cert = Certificate(filename = fn)
        return 'certificate'
    except: pass

    # to be completed
#    if "gidCaller" in dict:
#        return "credential"
#
#    if "uuid" in dict:
#        return "gid"

    return "unknown"
Ejemplo n.º 17
0
    def check_sliver_credentials(self, creds, urns):
        # build list of cred object hrns
        slice_cred_names = []
        for cred in creds:
            slice_cred_hrn = Credential(cred=cred).get_gid_object().get_hrn()
            slice_cred_names.append(
                DummyXrn(xrn=slice_cred_hrn).dummy_slicename())

        # look up slice name of slivers listed in urns arg
        slice_ids = []
        for urn in urns:
            sliver_id_parts = Xrn(xrn=urn).get_sliver_id_parts()
            try:
                slice_ids.append(int(sliver_id_parts[0]))
            except ValueError:
                pass

        if not slice_ids:
            raise Forbidden("sliver urn not provided")

        slices = self.shell.GetSlices({'slice_ids': slice_ids})
        sliver_names = [slice['slice_name'] for slice in slices]

        # make sure we have a credential for every specified sliver ierd
        for sliver_name in sliver_names:
            if sliver_name not in slice_cred_names:
                msg = "Valid credential not found for target: %s" % sliver_name
                raise Forbidden(msg)
Ejemplo n.º 18
0
    def check_sliver_credentials(self, creds, urns):
        # build list of cred object hrns
        slice_cred_names = []
        for cred in creds:
            slice_cred_hrn = Credential(cred=cred).get_gid_object().get_hrn()
            slice_cred_names.append(OSXrn(xrn=slice_cred_hrn).get_slicename())

        # look up slice name of slivers listed in urns arg
        slice_ids = []
        for urn in urns:
            sliver_id_parts = Xrn(xrn=urn).get_sliver_id_parts()
            slice_ids.append(sliver_id_parts[0])

        if not slice_ids:
            raise Forbidden("sliver urn not provided")

        sliver_names = []
        for slice_id in slice_ids:
            slice = self.shell.auth_manager.tenants.find(slice_id)
            sliver_names.append(slice['name'])

        # make sure we have a credential for every specified sliver ierd
        for sliver_name in sliver_names:
            if sliver_name not in slice_cred_names:
                msg = "Valid credential not found for target: %s" % sliver_name
                raise Forbidden(msg)
Ejemplo n.º 19
0
 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
Ejemplo n.º 20
0
    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
Ejemplo n.º 21
0
 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
Ejemplo n.º 22
0
    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
Ejemplo n.º 23
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
Ejemplo n.º 24
0
 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
Ejemplo n.º 25
0
    def Provision(self, api, xrn, creds, options):
        call_id = options.get('call_id')
        if Callids().already_handled(call_id): return ""

        version_manager = VersionManager()
        def _Provision(aggregate, server, xrn, credential, options):
            tStart = time.time()
            try:
                # Need to call GetVersion at an aggregate to determine the supported
                # rspec type/format beofre calling CreateSliver at an Aggregate.
                server_version = api.get_cached_server_version(server)
                result = server.Provision(xrn, credential, options)
                return {"aggregate": aggregate, "result": result, "elapsed": time.time()-tStart, "status": "success"}
            except:
                logger.log_exc('Something wrong in _Allocate with URL %s'%server.url)
                return {"aggregate": aggregate, "elapsed": time.time()-tStart, "status": "exception", "exc_info": sys.exc_info()}

        # attempt to use delegated credential first
        cred = api.getDelegatedCredential(creds)
        if not cred:
            cred = api.getCredential()

        # get the callers hrn
        valid_cred = api.auth.checkCredentials(creds, 'createsliver', xrn)[0]
        caller_hrn = Credential(cred=valid_cred).get_gid_caller().get_hrn()
        multiclient = MultiClient()
        for aggregate in api.aggregates:
            # prevent infinite loop. Dont send request back to caller
            # unless the caller is the aggregate's SM
            if caller_hrn == aggregate and aggregate != api.hrn:
                continue
            interface = api.aggregates[aggregate]
            server = api.server_proxy(interface, cred)
            # Just send entire RSpec to each aggregate
            multiclient.run(_Provision, aggregate, server, xrn, [cred], options)

        results = multiclient.get_results()
        manifest_version = version_manager._get_version('GENI', '3', 'manifest')
        result_rspec = RSpec(version=manifest_version)
        geni_slivers = []
        geni_urn  = None  
        for result in results:
            self.add_slicemgr_stat(result_rspec, "Provision", result["aggregate"], result["elapsed"],
                                   result["status"], result.get("exc_info",None))
            if result["status"]=="success":
                try:
                    res = result['result']['value']
                    geni_urn = res['geni_urn']
                    result_rspec.version.merge(ReturnValue.get_value(res['geni_rspec']))
                    geni_slivers.extend(res['geni_slivers'])
                except:
                    api.logger.log_exc("SM.Provision: Failed to merge aggregate rspec")
        return {
            'geni_urn': geni_urn,
            'geni_rspec': result_rspec.toxml(),
            'geni_slivers': geni_slivers
        }            
Ejemplo n.º 26
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
Ejemplo n.º 27
0
Archivo: auth.py Proyecto: tubav/sfa
 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
Ejemplo n.º 28
0
    def call(self, xrn, creds, rspec, options):
        xrn = Xrn(xrn, type='slice')
        self.api.logger.info("interface: %s\ttarget-hrn: %s\tmethod-name: %s" %
                             (self.api.interface, xrn.get_hrn(), self.name))
        (speaking_for, _) = urn_to_hrn(options.get('geni_speaking_for'))

        # Find the valid credentials
        valid_creds = self.api.auth.checkCredentials(
            creds,
            'createsliver',
            xrn.get_hrn(),
            speaking_for_hrn=speaking_for)
        # use the expiration from the first valid credential to determine when
        # the slivers should expire.
        expiration = datetime_to_string(
            Credential(cred=valid_creds[0]).expiration)

        # make sure request is not empty
        slivers = RSpec(rspec).version.get_nodes_with_slivers()
        if not slivers:
            raise InvalidRSpec(
                "Missing <sliver_type> or <sliver> element. Request rspec must explicitly allocate slivers"
            )

        # flter rspec through sfatables
        if self.api.interface in ['aggregate']:
            chain_name = 'INCOMING'
        elif self.api.interface in ['slicemgr']:
            chain_name = 'FORWARD-INCOMING'
        self.api.logger.debug("Allocate: sfatables on chain %s" % chain_name)
        origin_hrn = Credential(cred=valid_creds[0]).get_gid_caller().get_hrn()
        self.api.logger.info(
            "interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s" %
            (self.api.interface, origin_hrn, xrn, self.name))
        rspec = run_sfatables(chain_name, xrn.get_hrn(), origin_hrn, rspec)
        slivers = RSpec(rspec).version.get_nodes_with_slivers()
        if not slivers:
            raise SfatablesRejected(slice_xrn)

        result = self.api.manager.Allocate(self.api, xrn.get_urn(), creds,
                                           rspec, expiration, options)
        return result
Ejemplo n.º 29
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
Ejemplo n.º 30
0
Archivo: sfadump.py Proyecto: tubav/sfa
def handle_input_kind (filename, options, kind):
    

# dump methods current do 'print' so let's go this road for now
    if kind=="certificate":
        cert=Certificate (filename=filename)
        print '--------------------',filename,'IS A',kind
        cert.dump(show_extensions=options.show_extensions)
    elif kind=="credential":
        cred = Credential(filename = filename)
        print '--------------------',filename,'IS A',kind
        cred.dump(dump_parents = options.dump_parents, show_xml=options.show_xml)
        if options.extract_gids:
            print '--------------------',filename,'embedded GIDS'
            extract_gids(cred, extract_parents = options.dump_parents)
    elif kind=="gid":
        gid = GID(filename = filename)
        print '--------------------',filename,'IS A',kind
        gid.dump(dump_parents = options.dump_parents)
    else:
        print "%s: unknown filekind '%s'"% (filename,kind)
Ejemplo n.º 31
0
    def call(self, xrn, creds, options={}):
        hrn, type = urn_to_hrn(xrn)
        valid_creds = self.api.auth.checkCredentials(creds, 'list')

        #log the call
        origin_hrn = Credential(
            string=valid_creds[0]).get_gid_caller().get_hrn()
        self.api.logger.info(
            "interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s" %
            (self.api.interface, origin_hrn, hrn, self.name))

        return self.api.manager.List(self.api, xrn, options=options)
Ejemplo n.º 32
0
Archivo: sfi.py Proyecto: planetlab/sfa
    def delegate_cred(self, object_cred, hrn):
        # the gid and hrn of the object we are delegating
        if isinstance(object_cred, str):
            object_cred = Credential(string=object_cred) 
        object_gid = object_cred.get_gid_object()
        object_hrn = object_gid.get_hrn()
    
        if not object_cred.get_privileges().get_all_delegate():
            self.logger.error("Object credential %s does not have delegate bit set"%object_hrn)
            return

        # the delegating user's gid
        caller_gid = self._get_gid(self.user)
        caller_gidfile = os.path.join(self.options.sfi_dir, self.user + ".gid")
  
        # the gid of the user who will be delegated to
        delegee_gid = self._get_gid(hrn)
        delegee_hrn = delegee_gid.get_hrn()
        delegee_gidfile = os.path.join(self.options.sfi_dir, delegee_hrn + ".gid")
        delegee_gid.save_to_file(filename=delegee_gidfile)
        dcred = object_cred.delegate(delegee_gidfile, self.get_key_file(), caller_gidfile)
        return dcred.save_to_string(save_parents=True)
Ejemplo n.º 33
0
    def delegate_credential_string(self,
                                   original_credential,
                                   to_hrn,
                                   to_type='authority'):
        """
        sign a delegation credential to someone else

        original_credential : typically one's user- or slice- credential to be delegated to s/b else
        to_hrn : the hrn of the person that will be allowed to do stuff on our behalf
        to_type : goes with to_hrn, usually 'user' or 'authority'

        returns a string with the delegated credential

        this internally uses self.my_gid()
        it also retrieves the gid for to_hrn/to_type
        and uses Credential.delegate()"""

        # the gid and hrn of the object we are delegating
        if isinstance(original_credential, str):
            original_credential = Credential(string=original_credential)
        original_gid = original_credential.get_gid_object()
        original_hrn = original_gid.get_hrn()

        if not original_credential.get_privileges().get_all_delegate():
            #self.logger.error("delegate_credential_string: original credential %s does not have delegate bit set"%original_hrn)
            return

        # the delegating user's gid
        my_gid = self.my_gid()

        # retrieve the GID for the entity that we're delegating to
        to_gidfile = self.gid(to_hrn, to_type)
        #        to_gid = GID ( to_gidfile )
        #        to_hrn = delegee_gid.get_hrn()
        #        print 'to_hrn',to_hrn
        delegated_credential = original_credential.delegate(
            to_gidfile, self.private_key(), my_gid)
        return delegated_credential.save_to_string(save_parents=True)
Ejemplo n.º 34
0
    def call(self, cred, record, origin_hrn=None):
        user_cred = Credential(string=cred)

        #log the call
        if not origin_hrn:
            origin_hrn = user_cred.get_gid_caller().get_hrn()
        self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, record['hrn'], self.name))

        self.api.auth.check(cred, "remove")

        # Only allow the local interface or record owner to delete peer_records 
        try: self.api.auth.verify_object_permission(record['hrn'])
        except: self.api.auth.verify_cred_is_me(cred)
        
        table = SfaTable()
        hrn, type = record['hrn'], record['type']
        records = table.find({'hrn': hrn, 'type': type })
        for record in records:
            if record['peer_authority']:
                self.remove_plc_record(record)
                table.remove(record)
            
        return 1
Ejemplo n.º 35
0
    def call(self, xrn, creds):

        valid_creds = self.api.auth.checkCredentials(
            creds,
            'stopslice',
            xrn,
            check_sliver_callback=self.api.driver.check_sliver_credentials)
        #log the call
        origin_hrn = Credential(cred=valid_creds[0]).get_gid_caller().get_hrn()
        self.api.logger.info(
            "interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s" %
            (self.api.interface, origin_hrn, xrn, self.name))

        return self.api.manager.Shutdown(self.api, xrn, creds)
Ejemplo n.º 36
0
    def call(self, xrn, creds, rspec, options):
        xrn = Xrn(xrn, type='slice')

        # Find the valid credentials
        valid_creds = self.api.auth.checkCredentialsSpeaksFor(creds, 'createsliver', xrn.get_hrn(), options=options)
        the_credential = Credential(cred=valid_creds[0])

        # use the expiration from the first valid credential to determine when 
        # the slivers should expire.
        expiration = datetime_to_string(the_credential.expiration)
        
        self.api.logger.debug("Allocate, received expiration from credential: %s"%expiration)

# turned off, as passing an empty rspec is indeed useful for cleaning up the slice
#        # make sure request is not empty
#        slivers = RSpec(rspec).version.get_nodes_with_slivers()
#        if not slivers:
#            raise InvalidRSpec("Missing <sliver_type> or <sliver> element. Request rspec must explicitly allocate slivers")    

        # flter rspec through sfatables
        if self.api.interface in ['aggregate']:
            chain_name = 'INCOMING'
        elif self.api.interface in ['slicemgr']:
            chain_name = 'FORWARD-INCOMING'
        self.api.logger.debug("Allocate: sfatables on chain %s"%chain_name)
        actual_caller_hrn = the_credential.actual_caller_hrn()
        self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, actual_caller_hrn, xrn.get_hrn(), self.name)) 
        rspec = run_sfatables(chain_name, xrn.get_hrn(), actual_caller_hrn, rspec)
# turned off, as passing an empty rspec is indeed useful for cleaning up the slice
#        slivers = RSpec(rspec).version.get_nodes_with_slivers()
#        if not slivers:
#            raise SfatablesRejected(slice_xrn)

        # pass this to the driver code in case they need it
        options['actual_caller_hrn'] = actual_caller_hrn
        result = self.api.manager.Allocate(self.api, xrn.get_urn(), creds, rspec, expiration, options)
        return result
Ejemplo n.º 37
0
    def call(self, urns, creds, expiration_time, options):


        # Find the valid credentials
        valid_creds = self.api.auth.checkCredentialsSpeaksFor(creds, 'renewsliver', urns,
                                                              check_sliver_callback = self.api.driver.check_sliver_credentials,
                                                              options=options)
        the_credential = Credential(cred=valid_creds[0])
        actual_caller_hrn = the_credential.actual_caller_hrn()
        self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-urns: %s\texpiration:%s\tmethod-name: %s"%\
                             (self.api.interface, actual_caller_hrn, urns, expiration_time,self.name))


        # extend as long as possible : take the min of requested and now+SFA_MAX_SLICE_RENEW
        if options.get('geni_extend_alap'):
            # ignore requested time and set to max
            expiration_time = add_datetime(datetime.datetime.utcnow(), days=int(self.api.config.SFA_MAX_SLICE_RENEW))

        # Validate that the time does not go beyond the credential's expiration time
        requested_expire = utcparse(expiration_time)
        self.api.logger.info("requested_expire = %s"%requested_expire)
        credential_expire = the_credential.get_expiration()
        self.api.logger.info("credential_expire = %s"%credential_expire)
        max_renew_days = int(self.api.config.SFA_MAX_SLICE_RENEW)
        max_expire = datetime.datetime.utcnow() + datetime.timedelta (days=max_renew_days)
        if requested_expire > credential_expire:
            # used to throw an InsufficientRights exception here, this was not right
            self.api.logger.warning("Requested expiration %s, after credential expiration (%s) -> trimming to the latter/sooner"%\
                                    (requested_expire, credential_expire))
            requested_expire = credential_expire
        if requested_expire > max_expire:
            # likewise
            self.api.logger.warning("Requested expiration %s, after maximal expiration %s days (%s) -> trimming to the latter/sooner"%\
                                    (requested_expire, self.api.config.SFA_MAX_SLICE_RENEW,max_expire))
            requested_expire = max_expire

        return self.api.manager.Renew(self.api, urns, creds, requested_expire, options)
Ejemplo n.º 38
0
 def _getCredential(self):
     """ 
     Get our credential from a remote registry 
     """
     from sfa.server.registry import Registries
     registries = Registries()
     registry = registries.server_proxy(self.hrn, self.key_file,
                                        self.cert_file)
     cert_string = self.cert.save_to_string(save_parents=True)
     # get self credential
     self_cred = registry.GetSelfCredential(cert_string, self.hrn,
                                            'authority')
     # get credential
     cred = registry.GetCredential(self_cred, self.hrn, 'authority')
     return Credential(string=cred)
Ejemplo n.º 39
0
    def call(self, xrn, creds, type):
        xrn = Xrn(xrn, type=type)

        # validate the cred
        valid_creds = self.api.auth.checkCredentials(creds, "remove")
        self.api.auth.verify_object_permission(xrn.get_hrn())

        #log the call
        origin_hrn = Credential(
            string=valid_creds[0]).get_gid_caller().get_hrn()
        self.api.logger.info(
            "interface: %s\tmethod-name: %s\tcaller-hrn: %s\ttarget-urn: %s" %
            (self.api.interface, self.name, origin_hrn, xrn.get_urn()))

        return self.api.manager.Remove(self.api, xrn)
Ejemplo n.º 40
0
    def check_sliver_credentials(self, creds, urns):
        # build list of cred object hrns
        slice_cred_names = []
        for cred in creds:
            slice_cred_hrn = Credential(cred=cred).get_gid_object().get_hrn() 
            top_auth_hrn = top_auth(slice_cred_hrn)
            site_hrn = '.'.join(slice_cred_hrn.split('.')[:-1])
            slice_part = slice_cred_hrn.split('.')[-1]
            if top_auth_hrn == self.hrn:
                login_base = slice_cred_hrn.split('.')[-2][:12]
            else:
                login_base = hash_loginbase(site_hrn)

            slicename = '_'.join([login_base, slice_part])   
            slice_cred_names.append(slicename) 

        # look up slice name of slivers listed in urns arg
        slice_ids = []
        for urn in urns:
            sliver_id_parts = Xrn(xrn=urn).get_sliver_id_parts()
            try:
                slice_ids.append(int(sliver_id_parts[0]))
            except ValueError: 
                pass

        if not slice_ids:
             raise Forbidden("sliver urn not provided")

        slices = self.shell.GetSlices(slice_ids)
        sliver_names = [slice['name'] for slice in slices]

        # make sure we have a credential for every specified sliver ierd
        for sliver_name in sliver_names:
            if sliver_name not in slice_cred_names:
                msg = "Valid credential not found for target: %s" % sliver_name
                raise Forbidden(msg)
Ejemplo n.º 41
0
    def loadCredential(self):
        """
        Attempt to load credential from file if it exists. If it doesnt get
        credential from registry.
        """

        # see if this file exists
        # XX This is really the aggregate's credential. Using this is easier than getting
        # the registry's credential from iteslf (ssl errors).
        filename = self.interface + self.hrn + ".ma.cred"
        ma_cred_path = os.path.join(self.config.SFA_DATA_DIR, filename)
        try:
            self.credential = Credential(filename=ma_cred_path)
        except IOError:
            self.credential = self.getCredentialFromRegistry()
Ejemplo n.º 42
0
    def check_sliver_credentials(self, creds, urns):
        # build list of cred object hrns
        slice_cred_names = []
        for cred in creds:
            slice_cred_hrn = Credential(cred=cred).get_gid_object().get_hrn()
            top_auth_hrn = top_auth(slice_cred_hrn)
            site_hrn = '.'.join(slice_cred_hrn.split('.')[:-1])
            slice_part = slice_cred_hrn.split('.')[-1]
            if top_auth_hrn == self.hrn:
                login_base = slice_cred_hrn.split('.')[-2][:12]
            else:
                login_base = hash_loginbase(site_hrn)

            slicename = '_'.join([login_base, slice_part])
            slice_cred_names.append(slicename)

        # look up slice name of slivers listed in urns arg
        slice_ids = []
        for urn in urns:
            sliver_id_parts = Xrn(xrn=urn).get_sliver_id_parts()
            try:
                slice_ids.append(int(sliver_id_parts[0]))
            except ValueError:
                pass

        if not slice_ids:
            raise Forbidden("sliver urn not provided")

        slices = self.shell.GetSlices(slice_ids)
        sliver_names = [slice['name'] for slice in slices]

        # make sure we have a credential for every specified sliver ierd
        for sliver_name in sliver_names:
            if sliver_name not in slice_cred_names:
                msg = "Valid credential not found for target: %s" % sliver_name
                raise Forbidden(msg)
Ejemplo n.º 43
0
    def getCredential(self, minimumExpiration=0):
        """
        Return a valid credential for this interface.
        """
        type = 'authority'
        path = self.config.SFA_DATA_DIR
        filename = ".".join([self.interface, self.hrn, type, "cred"])
        cred_filename = os.path.join(path,filename)
        cred = None
        if os.path.isfile(cred_filename):
            cred = Credential(filename = cred_filename)
            # make sure cred isnt expired
            if not cred.get_expiration or \
               datetime.datetime.utcnow() + datetime.timedelta(seconds=minimumExpiration) < cred.get_expiration():
                return cred.save_to_string(save_parents=True)

        # get a new credential
        if self.interface in ['registry']:
            cred =  self._getCredentialRaw()
        else:
            cred =  self._getCredential()
        cred.save_to_file(cred_filename, save_parents=True)

        return cred.save_to_string(save_parents=True)
Ejemplo n.º 44
0
def handle_input (filename, options):
    kind = determine_sfa_filekind(filename)

    # dump methods current do 'print' so let's go this road for now
    if kind=="certificate":
        cert=Certificate (filename=filename)
        print '--------------------',filename,'IS A',kind
        cert.dump(show_extensions=options.show_extensions)
        verify_input_object (cert, kind, options)
    elif kind=="credential":
        cred = Credential(filename = filename)
        print '--------------------',filename,'IS A',kind
        cred.dump(dump_parents = options.dump_parents, show_xml=options.show_xml)
        if options.extract_gids:
            print '--------------------',filename,'embedded GIDs'
            extract_gids(cred, extract_parents = options.dump_parents)
        verify_input_object (cred, kind, options)
    elif kind=="gid":
        gid = GID(filename = filename)
        print '--------------------',filename,'IS A',kind
        gid.dump(dump_parents = options.dump_parents)
        verify_input_object (gid, kind, options)
    else:
        print "%s: unknown filekind '%s'"% (filename,kind)
Ejemplo n.º 45
0
Archivo: sfi.py Proyecto: planetlab/sfa
    def delegate(self, opts, args):

        delegee_hrn = args[0]
        if opts.delegate_user:
            user_cred = self.get_user_cred()
            cred = self.delegate_cred(user_cred, delegee_hrn)
        elif opts.delegate_slice:
            slice_cred = self.get_slice_cred(opts.delegate_slice)
            cred = self.delegate_cred(slice_cred, delegee_hrn)
        else:
            self.logger.warning("Must specify either --user or --slice <hrn>")
            return
        delegated_cred = Credential(string=cred)
        object_hrn = delegated_cred.get_gid_object().get_hrn()
        if opts.delegate_user:
            dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_"
                                  + get_leaf(object_hrn) + ".cred")
        elif opts.delegate_slice:
            dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_slice_"
                                  + get_leaf(object_hrn) + ".cred")

        delegated_cred.save_to_file(dest_fn, save_parents=True)

        self.logger.info("delegated credential for %s to %s and wrote to %s"%(object_hrn, delegee_hrn,dest_fn))
Ejemplo n.º 46
0
    def Renew(self, api, xrn, creds, expiration_time, options):
        call_id = options.get('call_id')
        if Callids().already_handled(call_id): return True

        def _Renew(aggregate, server, xrn, creds, expiration_time, options):
            try:
                result=server.Renew(xrn, creds, expiration_time, options)
                if type(result)!=dict:
                    result = {'code': {'geni_code': 0}, 'value': result}
                result['aggregate'] = aggregate
                return result
            except:
                logger.log_exc('Something wrong in _Renew with URL %s'%server.url)
                return {'aggregate': aggregate, 'exc_info': traceback.format_exc(),
                        'code': {'geni_code': -1},
                        'value': False, 'output': ""}

        # get the callers hrn
        valid_cred = api.auth.checkCredentials(creds, 'renewsliver', xrn)[0]
        caller_hrn = Credential(cred=valid_cred).get_gid_caller().get_hrn()

        # attempt to use delegated credential first
        cred = api.getDelegatedCredential(creds)
        if not cred:
            cred = api.getCredential(minimumExpiration=31*86400)
        multiclient = MultiClient()
        for aggregate in api.aggregates:
            # prevent infinite loop. Dont send request back to caller
            # unless the caller is the aggregate's SM
            if caller_hrn == aggregate and aggregate != api.hrn:
                continue
            interface = api.aggregates[aggregate]
            server = api.server_proxy(interface, cred)
            multiclient.run(_Renew, aggregate, server, xrn, [cred], expiration_time, options)

        results = multiclient.get_results()

        geni_code = 0
        geni_output = ",".join([x.get('output',"") for x in results])
        geni_value = reduce (lambda x,y: x and y, [result.get('value',False) for result in results], True)
        for agg_result in results:
            agg_geni_code = agg_result['code'].get('geni_code',0)
            if agg_geni_code:
                geni_code = agg_geni_code

        results = {'aggregates': results, 'code': {'geni_code': geni_code}, 'value': geni_value, 'output': geni_output}

        return results
Ejemplo n.º 47
0
    def call(self, record, creds):
        # validate cred
        valid_creds = self.api.auth.checkCredentials(creds, 'register')

        # verify permissions
        hrn = record.get('hrn', '')
        self.api.auth.verify_object_permission(hrn)

        #log the call
        origin_hrn = Credential(
            string=valid_creds[0]).get_gid_caller().get_hrn()
        self.api.logger.info(
            "interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s" %
            (self.api.interface, origin_hrn, hrn, self.name))

        return self.api.manager.Register(self.api, record)
Ejemplo n.º 48
0
    def call(self, creds, xrn, cert=None):
        # TODO: is there a better right to check for or is 'update good enough?
        valid_creds = self.api.auth.checkCredentials(creds, 'update')

        # verify permissions
        hrn, type = urn_to_hrn(xrn)
        self.api.auth.verify_object_permission(hrn)

        #log the call
        origin_hrn = Credential(
            string=valid_creds[0]).get_gid_caller().get_hrn()
        self.api.logger.info(
            "interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s" %
            (self.api.interface, origin_hrn, xrn, self.name))

        return self.api.manager.CreateGid(self.api, xrn, cert)
Ejemplo n.º 49
0
    def call(self, creds, xrn, type):
    
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        # check creds
        valid_creds = self.api.auth.checkCredentials(creds, 'getcredential')
        self.api.auth.verify_object_belongs_to_me(hrn)

        #log the call
        origin_hrn = Credential(string=valid_creds[0]).get_gid_caller().get_hrn()
        self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, hrn, self.name))	

        return self.api.manager.GetCredential(self.api, xrn, type, self.api.auth.client_gid.get_urn())
Ejemplo n.º 50
0
    def call(self, xrns, creds, options):
        (speaking_for, _) = urn_to_hrn(options.get('geni_speaking_for'))
        valid_creds = self.api.auth.checkCredentials(
            creds,
            'deletesliver',
            xrns,
            check_sliver_callback=self.api.driver.check_sliver_credentials,
            speaking_for_hrn=speaking_for)

        #log the call
        origin_hrn = Credential(cred=valid_creds[0]).get_gid_caller().get_hrn()
        self.api.logger.info(
            "interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s" %
            (self.api.interface, origin_hrn, xrns, self.name))

        return self.api.manager.Delete(self.api, xrns, creds, options)
Ejemplo n.º 51
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
Ejemplo n.º 52
0
Archivo: api.py Proyecto: planetlab/sfa
    def __getCredentialRaw(self):
        """
        Get our current credential directly from the local registry.
        """

        hrn = self.hrn
        auth_hrn = self.auth.get_authority(hrn)
    
        # is this a root or sub authority
        if not auth_hrn or hrn == self.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = self.auth.get_auth_info(auth_hrn)
        table = self.SfaTable()
        records = table.findObjects({'hrn': hrn, 'type': 'authority+sa'})
        if not records:
            raise RecordNotFound
        record = records[0]
        type = record['type']
        object_gid = record.get_gid_object()
        new_cred = Credential(subject = object_gid.get_subject())
        new_cred.set_gid_caller(object_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
        
        r1 = determine_rights(type, hrn)
        new_cred.set_privileges(r1)
        new_cred.encode()
        new_cred.sign()

        return new_cred
Ejemplo n.º 53
0
    def GetCredential(self, api, xrn, type, caller_xrn=None):
        # convert xrn to hrn
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        # Is this a root or sub authority
        auth_hrn = api.auth.get_authority(hrn)
        if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = api.auth.get_auth_info(auth_hrn)
        # get record info
        filter = {"hrn": hrn}
        if type:
            filter["type"] = type
        record = dbsession.query(RegRecord).filter_by(**filter).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s" % (hrn, type))

        # verify_cancreate_credential requires that the member lists
        # (researchers, pis, etc) be filled in
        logger.debug("get credential before augment dict, keys=%s" % record.__dict__.keys())
        api.driver.augment_records_with_testbed_info(record.__dict__)
        logger.debug("get credential after augment dict, keys=%s" % record.__dict__.keys())
        if not api.driver.is_enabled(record.__dict__):
            raise AccountNotEnabled(
                ": PlanetLab account %s is not enabled. Please contact your site PI" % (record.email)
            )

        # get the callers gid
        # if caller_xrn is not specified assume the caller is the record
        # object itself.
        if not caller_xrn:
            caller_hrn = hrn
            caller_gid = record.get_gid_object()
        else:
            caller_hrn, caller_type = urn_to_hrn(caller_xrn)
            caller_filter = {"hrn": caller_hrn}
            if caller_type:
                caller_filter["type"] = caller_type
            caller_record = dbsession.query(RegRecord).filter_by(**caller_filter).first()
            if not caller_record:
                raise RecordNotFound(
                    "Unable to associated caller (hrn=%s, type=%s) with credential for (hrn: %s, type: %s)"
                    % (caller_hrn, caller_type, hrn, type)
                )
            caller_gid = GID(string=caller_record.gid)

        object_hrn = record.get_gid_object().get_hrn()
        rights = api.auth.determine_user_rights(caller_hrn, record)
        # make sure caller has rights to this object
        if rights.is_empty():
            raise PermissionError(caller_hrn + " has no rights to " + record.hrn)

        object_gid = GID(string=record.gid)
        new_cred = Credential(subject=object_gid.get_subject())
        new_cred.set_gid_caller(caller_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
        # new_cred.set_pubkey(object_gid.get_pubkey())
        new_cred.set_privileges(rights)
        new_cred.get_privileges().delegate_all_privileges(True)
        if hasattr(record, "expires"):
            date = utcparse(record.expires)
            expires = datetime_to_epoch(date)
            new_cred.set_expiration(int(expires))
        auth_kind = "authority,ma,sa"
        # Parent not necessary, verify with certs
        # new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
        new_cred.encode()
        new_cred.sign()

        return new_cred.save_to_string(save_parents=True)
Ejemplo n.º 54
0
    def _getCredentialRaw(self):
        """
        Get our current credential directly from the local registry.
        """

        hrn = self.hrn
        auth_hrn = self.auth.get_authority(hrn)
    
        # is this a root or sub authority
        if not auth_hrn or hrn == self.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = self.auth.get_auth_info(auth_hrn)
        # xxx although unlikely we might want to check for a potential leak
        dbsession=self.dbsession()
        from sfa.storage.model import RegRecord
        record = dbsession.query(RegRecord).filter_by(type='authority+sa', hrn=hrn).first()
        if not record:
            raise RecordNotFound(hrn)
        type = record.type
        object_gid = record.get_gid_object()
        new_cred = Credential(subject = object_gid.get_subject())
        new_cred.set_gid_caller(object_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
        
        r1 = determine_rights(type, hrn)
        new_cred.set_privileges(r1)
        new_cred.encode()
        new_cred.sign()

        return new_cred
Ejemplo n.º 55
0
    def get_auth_cred(self, xrn, kind="authority"):
        hrn, type = urn_to_hrn(xrn) 
        auth_info = self.get_auth_info(hrn)
        gid = auth_info.get_gid_object()

        cred = Credential(subject=hrn)
        cred.set_gid_caller(gid)
        cred.set_gid_object(gid)
        cred.set_privileges(kind)
        cred.get_privileges().delegate_all_privileges(True)
        #cred.set_pubkey(auth_info.get_gid_object().get_pubkey())

        parent_hrn = get_authority(hrn)
        if not parent_hrn or hrn == self.config.SFA_INTERFACE_HRN:
            # if there is no parent hrn, then it must be self-signed. this
            # is where we terminate the recursion
            cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
        else:
            # we need the parent's private key in order to sign this GID
            parent_auth_info = self.get_auth_info(parent_hrn)
            cred.set_issuer_keys(parent_auth_info.get_privkey_filename(), parent_auth_info.get_gid_filename())

            
            cred.set_parent(self.get_auth_cred(parent_hrn, kind))

        cred.encode()
        cred.sign()

        return cred
Ejemplo n.º 56
0
    def GetCredential(self, api, xrn, type, caller_xrn=None):
        # convert xrn to hrn     
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        # Is this a root or sub authority
        auth_hrn = api.auth.get_authority(hrn)
        if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = api.auth.get_auth_info(auth_hrn)
        # get record info
        record=dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s"%(hrn,type))

        # get the callers gid
        # if caller_xrn is not specified assume the caller is the record
        # object itself.
        if not caller_xrn:
            caller_hrn = hrn
            caller_gid = record.get_gid_object()
        else:
            caller_hrn, caller_type = urn_to_hrn(caller_xrn)
            if caller_type:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn,type=caller_type).first()
            else:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn).first()
            if not caller_record:
                raise RecordNotFound("Unable to associated caller (hrn=%s, type=%s) with credential for (hrn: %s, type: %s)"%(caller_hrn, caller_type, hrn, type))
            caller_gid = GID(string=caller_record.gid)i

        object_hrn = record.get_gid_object().get_hrn()
        # call the builtin authorization/credential generation engine
        rights = api.auth.determine_user_rights(caller_hrn, record)
        # make sure caller has rights to this object
        if rights.is_empty():
            raise PermissionError("%s has no rights to %s (%s)" % \
                                  (caller_hrn, object_hrn, xrn))
        object_gid = GID(string=record.gid)
        new_cred = Credential(subject = object_gid.get_subject())
        new_cred.set_gid_caller(caller_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
        #new_cred.set_pubkey(object_gid.get_pubkey())
        new_cred.set_privileges(rights)
        new_cred.get_privileges().delegate_all_privileges(True)
        if hasattr(record,'expires'):
            date = utcparse(record.expires)
            expires = datetime_to_epoch(date)
            new_cred.set_expiration(int(expires))
        auth_kind = "authority,ma,sa"
        # Parent not necessary, verify with certs
        #new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
        new_cred.encode()
        new_cred.sign()

        return new_cred.save_to_string(save_parents=True)
Ejemplo n.º 57
0
def get_credential(api, xrn, type, is_self=False):
    # convert xrn to hrn     
    if type:
        hrn = urn_to_hrn(xrn)[0]
    else:
        hrn, type = urn_to_hrn(xrn)
        
    # Is this a root or sub authority
    auth_hrn = api.auth.get_authority(hrn)
    if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
        auth_hrn = hrn
    # get record info
    auth_info = api.auth.get_auth_info(auth_hrn)
    table = SfaTable()
    records = table.findObjects({'type': type, 'hrn': hrn})
    if not records:
        raise RecordNotFound(hrn)
    record = records[0]

    # verify_cancreate_credential requires that the member lists
    # (researchers, pis, etc) be filled in
    api.fill_record_info(record)
    if record['type']=='user':
       if not record['enabled']:
          raise AccountNotEnabled(": PlanetLab account %s is not enabled. Please contact your site PI" %(record['email']))

    # get the callers gid
    # if this is a self cred the record's gid is the caller's gid
    if is_self:
        caller_hrn = hrn
        caller_gid = record.get_gid_object()
    else:
        caller_gid = api.auth.client_cred.get_gid_caller() 
        caller_hrn = caller_gid.get_hrn()
    
    object_hrn = record.get_gid_object().get_hrn()
    rights = api.auth.determine_user_rights(caller_hrn, record)
    # make sure caller has rights to this object
    if rights.is_empty():
        raise PermissionError(caller_hrn + " has no rights to " + record['name'])

    object_gid = GID(string=record['gid'])
    new_cred = Credential(subject = object_gid.get_subject())
    new_cred.set_gid_caller(caller_gid)
    new_cred.set_gid_object(object_gid)
    new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
    #new_cred.set_pubkey(object_gid.get_pubkey())
    new_cred.set_privileges(rights)
    new_cred.get_privileges().delegate_all_privileges(True)
    if 'expires' in record:
        new_cred.set_expiration(int(record['expires']))
    auth_kind = "authority,ma,sa"
    # Parent not necessary, verify with certs
    #new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
    new_cred.encode()
    new_cred.sign()

    return new_cred.save_to_string(save_parents=True)
Ejemplo n.º 58
0
Archivo: auth.py Proyecto: 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
Ejemplo n.º 59
0
Archivo: auth.py Proyecto: aquila/sfa
 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