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)
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)