示例#1
0
    def decode(self):
        if not self.xml:
            return
        doc = parseString(self.xml)
        sigs = []
        signed_cred = doc.getElementsByTagName("signed-credential")

        # Is this a signed-cred or just a cred?
        if len(signed_cred) > 0:
            creds = signed_cred[0].getElementsByTagName("credential")
            signatures = signed_cred[0].getElementsByTagName("signatures")
            if len(signatures) > 0:
                sigs = signatures[0].getElementsByTagName("Signature")
        else:
            creds = doc.getElementsByTagName("credential")
        
        if creds is None or len(creds) == 0:
            # malformed cred file
            raise CredentialNotVerifiable("Malformed XML: No credential tag found")

        # Just take the first cred if there are more than one
        cred = creds[0]

        self.set_refid(cred.getAttribute("xml:id"))
        self.set_expiration(utcparse(getTextNode(cred, "expires")))

#        import traceback
#        stack = traceback.extract_stack()

        og = getTextNode(cred, "owner_gid")
        # ABAC creds will have this be None and use this method
#        if og is None:
#            found = False
#            for frame in stack:
#                if 'super(ABACCredential, self).decode()' in frame:
#                    found = True
#                    break
#            if not found:
#                raise CredentialNotVerifiable("Malformed XML: No owner_gid found")
        self.gidCaller = GID(string=og)
        tg = getTextNode(cred, "target_gid")
#        if tg is None:
#            found = False
#            for frame in stack:
#                if 'super(ABACCredential, self).decode()' in frame:
#                    found = True
#                    break
#            if not found:
#                raise CredentialNotVerifiable("Malformed XML: No target_gid found")
        self.gidObject = GID(string=tg)

        # Process privileges
        rlist = Rights()
        priv_nodes = cred.getElementsByTagName("privileges")
        if len(priv_nodes) > 0:
            privs = priv_nodes[0]
            for priv in privs.getElementsByTagName("privilege"):
                kind = getTextNode(priv, "name")
                deleg = str2bool(getTextNode(priv, "can_delegate"))
                if kind == '*':
                    # Convert * into the default privileges for the credential's type
                    # Each inherits the delegatability from the * above
                    _ , type = urn_to_hrn(self.gidObject.get_urn())
                    rl = determine_rights(type, self.gidObject.get_urn())
                    for r in rl.rights:
                        r.delegate = deleg
                        rlist.add(r)
                else:
                    rlist.add(Right(kind.strip(), deleg))
        self.set_privileges(rlist)


        # Is there a parent?
        parent = cred.getElementsByTagName("parent")
        if len(parent) > 0:
            parent_doc = parent[0].getElementsByTagName("credential")[0]
            parent_xml = parent_doc.toxml("utf-8")
            if parent_xml is None or parent_xml.strip() == "":
                raise CredentialNotVerifiable("Malformed XML: Had parent tag but it is empty")
            self.parent = Credential(string=parent_xml)
            self.updateRefID()

        # Assign the signatures to the credentials
        for sig in sigs:
            Sig = Signature(string=sig.toxml("utf-8"))

            for cur_cred in self.get_credential_list():
                if cur_cred.get_refid() == Sig.get_refid():
                    cur_cred.set_signature(Sig)
示例#2
0
def create_credential(caller_gid, object_gid, expiration, typename, issuer_keyfile, issuer_certfile, trusted_roots, delegatable=False):
    '''Create and Return a Credential object issued by given key/cert for the given caller
    and object GID objects, given life in seconds, and given type.
    Privileges are determined by type per sfa/trust/rights.py
    Privileges are delegatable if requested.'''
    # FIXME: Validate args: my gids, >0 life,
    # type of cred one I can issue
    # and readable key and cert files
    if caller_gid is None:
        raise ValueError("Missing Caller GID")
    if object_gid is None:
        raise ValueError("Missing Object GID")
    if expiration is None:
        raise ValueError("Missing expiration")
    naive_expiration = naiveUTC(expiration)
    duration = naive_expiration - datetime.datetime.utcnow()
    life_secs = duration.seconds + duration.days * 24 * 3600
    if life_secs < 1:
        raise ValueError("Credential expiration is in the past")
    if trusted_roots is None:
        raise ValueError("Missing list of trusted roots")

    if typename is None or typename.strip() == '':
        raise ValueError("Missing credential type")
    typename = typename.strip().lower()
    if typename not in ("user", "sa", "ma", "authority", "slice", "component"):
        raise ValueError("Unknown credential type %s" % typename)

    if not os.path.isfile(issuer_keyfile):
        raise ValueError("Cant read issuer key file %s" % issuer_keyfile)

    if not os.path.isfile(issuer_certfile):
        raise ValueError("Cant read issuer cert file %s" % issuer_certfile)

    issuer_gid = gid.GID(filename=issuer_certfile)
    
    if not (object_gid.get_urn() == issuer_gid.get_urn() or 
        (issuer_gid.get_type().find('authority') == 0 and
         hrn_authfor_hrn(issuer_gid.get_hrn(), object_gid.get_hrn()))):
        raise ValueError("Issuer not authorized to issue credential: Issuer=%s  Target=%s" % (issuer_gid.get_urn(), object_gid.get_urn()))
    


    ucred = cred.Credential()
    # FIXME: Validate the caller_gid and object_gid
    # are my user and slice
    # Do get_issuer and compare to the issuer cert?
    # Or do gid.is_signed_by_cert(issuer_certfile)?
    ucred.set_gid_caller(caller_gid)
    ucred.set_gid_object(object_gid)
    ucred.set_expiration(expiration)
    # Use sfa/trust/rights.py to figure out what privileges
    # the credential should have.
    # user means refresh, resolve, info
    # per the privilege_table that lets users do
    # remove, update, resolve, list, getcredential,
    # listslices, listnodes, getpolicy
    # Note that it does not allow manipulating slivers

    # And every right is delegatable if any are delegatable (default False)
    privileges = rights.determine_rights(typename, None)
    privileges.delegate_all_privileges(delegatable)
    ucred.set_privileges(privileges)
    ucred.encode()
    ucred.set_issuer_keys(issuer_keyfile, issuer_certfile)
    ucred.sign()
    
    try:
        ucred.verify(trusted_roots)
    except Exception, exc:
        raise Exception("Create Credential failed to verify new credential from trusted roots: %s" % exc)