Пример #1
0
    def __init__(self, creds, options, **kwargs):
       
        # 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')
 
        # get slice's hrn from options    
        xrn = options.get('geni_slice_urn', '')
        (hrn, _) = urn_to_hrn(xrn)

        # Find the valid credentials
        #valid_creds = self.api.auth.checkCredentials(creds, 'listnodes', hrn)
        valid_creds = Auth().checkCredentials(creds, 'listnodes', hrn)
        # get hrn of the original caller 
        origin_hrn = options.get('origin_hrn', None)
        if not origin_hrn:
            origin_hrn = Credential(string=valid_creds[0]).get_gid_caller().get_hrn()
        origin_gid = Credential(string=valid_creds[0]).get_gid_caller()

        #rspec = AggregateManager(None).ListResources(self.api, creds, options)

        #chain_name = 'OUTGOING'
        #if options.has_key('geni_compressed') and options['geni_compressed'] == True:
        #    rspec = zlib.compress(rspec).encode('base64')

        #return rspec  
        #return True
        return
Пример #2
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   
Пример #3
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
Пример #4
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()

        # log
        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)
Пример #5
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
Пример #6
0
    def __init__(self, xrn, creds, options, **kwargs):
        (hrn, type) = urn_to_hrn(xrn)
        valid_creds = Auth().checkCredentials(creds, 'deletesliver', hrn)
        origin_hrn = Credential(
            string=valid_creds[0]).get_gid_caller().get_hrn()

        return  #self.api.manager.DeleteSliver(self.api, xrn, creds, options)
Пример #7
0
    def __init__(self, xrn, creds, **kwargs):
        hrn, type = urn_to_hrn(xrn)
        valid_creds = Auth().checkCredentials(creds, 'startslice', hrn)
        origin_hrn = Credential(string=valid_creds[0]).get_gid_caller().get_hrn()

 
        return  
Пример #8
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
Пример #9
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
Пример #10
0
    def call(self, creds, options):
        valid_creds = self.api.auth.checkCredentials(creds, 'listslices')

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

        return self.api.manager.ListSlices(self.api, creds, options)
Пример #11
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)
Пример #12
0
   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
Пример #13
0
    def __init__(self, slice_xrn, creds, users, options, **kwargs):

        hrn, type = urn_to_hrn(slice_xrn)

        # Find the valid credentials
        valid_creds = Auth().checkCredentials(creds, 'createsliver', hrn)
        origin_hrn = Credential(string=valid_creds[0]).get_gid_caller().get_hrn()

        # make sure users info is specified
        if not users:
            msg = "'users' must be specified and cannot be null. You may need to update your client." 
            raise SfaInvalidArgument(name='users', extra=msg)  

        return 
Пример #14
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)
Пример #15
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)
Пример #16
0
    def call(self, xrns, creds):
        # validate the credential
        valid_creds = self.api.auth.checkCredentials(creds, 'getgids')
        # xxxpylintxxx origin_hrn is unused..
        origin_hrn = Credential(string=valid_creds[0]).get_gid_caller().get_hrn()
        
        # resolve the record
        records = self.api.manager.Resolve(self.api, xrns, details = False)
        if not records:
            raise RecordNotFound(xrns)

        allowed_fields =  ['hrn', 'type', 'gid']
        for record in records:
            for key in record.keys():
                if key not in allowed_fields:
                    del(record[key])
        return records    
Пример #17
0
    def call(self, xrn, creds, rspec, users, options):
        hrn, type = urn_to_hrn(xrn)
        # Find the valid credentials
        valid_creds = self.api.auth.checkCredentials(creds, 'getticket', hrn)
        origin_hrn = Credential(string=valid_creds[0]).get_gid_caller().get_hrn() 

        #log the call
        self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, hrn, self.name))

        # filter rspec through foam.sfa.ables
        if self.api.interface in ['aggregate']:
            chain_name = 'OUTGOING'
        elif self.api.interface in ['slicemgr']:
            chain_name = 'FORWARD-OUTGOING'
        rspec = run_foam.sfa.ables(chain_name, hrn, origin_hrn, rspec)
        
        # remove nodes that are not available at this interface from the rspec
        return self.api.manager.GetTicket(self.api, xrn, creds, rspec, users, options)
Пример #18
0
 def checkCredentials(self, creds, operation, hrn = None):
     valid = []
     error = None
     if not isinstance(creds, list):
         creds = [creds]
     for cred in creds:
         try:
             self.check(cred, operation, hrn)
             valid.append(cred)
         except Exception as e:
             cred_obj=Credential(string=cred)
             error = e#sys.exc_info()[:2]
             continue
     if not len(valid):
         if not error:
             error = "No valid credentials found" 
         raise InsufficientRights('Access denied: %s' % (str(error)))
     
     return valid
Пример #19
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())
Пример #20
0
    def call(self, xrns, creds, options={}):
        # use details=False by default, only when explicitly specified do we want
        # to mess with the testbed details
        if 'details' in options: details = options['details']
        else: details = False
        type = None
        if not isinstance(xrns, types.ListType):
            type = Xrn(xrns).get_type()
            xrns = [xrns]
        hrns = [urn_to_hrn(xrn)[0] for xrn in xrns]
        #find valid credentials
        valid_creds = self.api.auth.checkCredentials(creds, 'resolve')

        #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, hrns, self.name))

        # send the call to the right manager
        return self.api.manager.Resolve(self.api, xrns, type, details=details)
Пример #21
0
    def call(self, slice_xrn, creds, expiration_time, options):

        (hrn, type) = urn_to_hrn(slice_xrn)

        self.api.logger.info(
            "interface: %s\ttarget-hrn: %s\tcaller-creds: %s\tmethod-name: %s"
            % (self.api.interface, hrn, creds, self.name))

        # Find the valid credentials
        valid_creds = self.api.auth.checkCredentials(creds, 'renewsliver', hrn)

        # Validate that the time does not go beyond the credential's expiration time
        requested_time = utcparse(expiration_time)
        max_renew_days = int(self.api.config.SFA_MAX_SLICE_RENEW)
        if requested_time > Credential(string=valid_creds[0]).get_expiration():
            raise InsufficientRights(
                'Renewsliver: Credential expires before requested expiration time'
            )
        if requested_time > datetime.datetime.utcnow() + datetime.timedelta(
                days=max_renew_days):
            raise Exception('Cannot renew > %s days from now' % max_renew_days)
        return self.api.manager.RenewSliver(self.api, slice_xrn, valid_creds,
                                            expiration_time, options)
Пример #22
0
    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
Пример #23
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
Пример #24
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  # Config()
        self.load_trusted_certs()

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

    def checkCredentials(self, creds, operation, hrn=None):
        valid = []
        error = None
        if not isinstance(creds, list):
            creds = [creds]
        for cred in creds:
            try:
                self.check(cred, operation, hrn)
                valid.append(cred)
            except Exception as e:
                cred_obj = Credential(string=cred)
                error = e  # sys.exc_info()[:2]
                continue
        if not len(valid):
            if not error:
                error = "No valid credentials found"
            raise InsufficientRights("Access denied: %s" % (str(error)))

        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

        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
Пример #25
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
Пример #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#Config()
        self.load_trusted_certs()

    def load_trusted_certs(self):
        self.trusted_cert_list = TrustedRoots(self.config.TRUSTED_ROOTS_DIR).get_list()
        self.trusted_cert_file_list = TrustedRoots(self.config.TRUSTED_ROOTS_DIR).get_file_list()
         
        
    def checkCredentials(self, creds, operation, hrn = None):
        valid = []
        error = None
        if not isinstance(creds, list):
            creds = [creds]
        for cred in creds:
            try:
                self.check(cred, operation, hrn)
                valid.append(cred)
            except Exception as e:
                cred_obj=Credential(string=cred)
                error = e#sys.exc_info()[:2]
                continue
        if not len(valid):
            if not error:
                error = "No valid credentials found" 
            raise InsufficientRights('Access denied: %s' % (str(error)))
        
        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


        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