def call(self, cert, xrn, type): """ GetSelfCredential a degenerate version of GetCredential used by a client to get his initial credential when de doesnt have one. This is the same as GetCredential(..., cred = None, ...) The registry ensures that the client is the principal that is named by (type, name) by comparing the public key in the record's GID to the private key used to encrypt the client side of the HTTPS connection. Thus it is impossible for one principal to retrieve another principal's credential without having the appropriate private key. @param type type of object (user | slice | sa | ma | node) @param hrn human readable name of authority to list @return string representation of a credential object """ if type: hrn = urn_to_hrn(xrn)[0] else: hrn, type = urn_to_hrn(xrn) self.api.auth.verify_object_belongs_to_me(hrn) origin_hrn = Certificate(string=cert).get_subject() self.api.logger.info("interface: %s\tcaller-hrn: %s\ttarget-hrn: %s\tmethod-name: %s"%(self.api.interface, origin_hrn, hrn, self.name)) ### authenticate the gid # import here so we can load this module at build-time for vt_manager_kvm.communication.sfa.wsdl #from vt_manager_kvm.communication.sfa.storage.alchemy import dbsession from vt_manager_kvm.communication.sfa.storage.model import RegRecord # xxx-local - the current code runs Resolve, which would forward to # another registry if needed # I wonder if this is truly the intention, or shouldn't we instead # only look in the local db ? records = self.api.manager.Resolve(self.api, xrn, type, details=False) if not records: raise RecordNotFound(hrn) record_obj = RegRecord (dict=records[0]) # xxx-local the local-only version would read #record_obj = dbsession.query(RegRecord).filter_by(hrn=hrn).first() #if not record_obj: raise RecordNotFound(hrn) gid = record_obj.get_gid_object() gid_str = gid.save_to_string(save_parents=True) self.api.auth.authenticateGid(gid_str, [cert, type, hrn]) # authenticate the certificate against the gid in the db certificate = Certificate(string=cert) if not certificate.is_pubkey(gid.get_pubkey()): for (obj,name) in [ (certificate,"CERT"), (gid,"GID"), ]: self.api.logger.debug("ConnectionKeyGIDMismatch, %s pubkey: %s"%(name,obj.get_pubkey().get_pubkey_string())) self.api.logger.debug("ConnectionKeyGIDMismatch, %s dump: %s"%(name,obj.dump_string())) if hasattr (obj,'filename'): self.api.logger.debug("ConnectionKeyGIDMismatch, %s filename: %s"%(name,obj.filename)) raise ConnectionKeyGIDMismatch(gid.get_subject()) return self.api.manager.GetCredential(self.api, xrn, type)
def auth_exists(self, xrn): hrn, type = urn_to_hrn(xrn) (directory, gid_filename, privkey_filename) = \ self.get_auth_filenames(hrn) print directory, gid_filename, privkey_filename return os.path.exists(gid_filename) and os.path.exists(privkey_filename)
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())
def __init__(self, xrn, creds, **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)
def __init__(self, credentials, 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(credentials, '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
def get_auth_ticket(self, xrn): hrn, type = urn_to_hrn(xrn) auth_info = self.get_auth_info(hrn) gid = auth_info.get_gid_object() ticket = SfaTicket(subject=hrn) ticket.set_gid_caller(gid) ticket.set_gid_object(gid) ticket.set_delegate(True) ticket.set_pubkey(auth_info.get_gid_object().get_pubkey()) parent_hrn = get_authority(hrn) if not parent_hrn: # if there is no parent hrn, then it must be self-signed. this # is where we terminate the recursion ticket.set_issuer(auth_info.get_pkey_object(), hrn) else: # we need the parent's private key in order to sign this GID parent_auth_info = self.get_auth_info(parent_hrn) ticket.set_issuer(parent_auth_info.get_pkey_object(), parent_auth_info.hrn) ticket.set_parent(self.get_auth_cred(parent_hrn)) ticket.encode() ticket.sign() return ticket
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
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)
def get_auth_filenames(self, xrn): hrn, type = urn_to_hrn(xrn) leaf = get_leaf(hrn) parent_hrn = get_authority(hrn) directory = os.path.join(self.basedir, hrn.replace(".", "/")) gid_filename = os.path.join(directory, leaf+".gid") privkey_filename = os.path.join(directory, leaf+".pkey") return (directory, gid_filename, privkey_filename)
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
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)
def get_auth_info(self, xrn): hrn, type = urn_to_hrn(xrn) if not self.auth_exists(hrn): raise MissingAuthority(hrn) (directory, gid_filename, privkey_filename, ) = \ self.get_auth_filenames(hrn) auth_info = AuthInfo(hrn, gid_filename, privkey_filename) # check the GID and see if it needs to be refreshed gid = auth_info.get_gid_object() gid_refreshed = self.refresh_gid(gid) if gid != gid_refreshed: auth_info.update_gid_object(gid_refreshed) return auth_info
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 vt_manager_kvm.communication.sfa.ables if self.api.interface in ['aggregate']: chain_name = 'OUTGOING' elif self.api.interface in ['slicemgr']: chain_name = 'FORWARD-OUTGOING' rspec = run_vt_manager_kvm.communication.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)
def create_auth(self, xrn, create_parents=False): hrn, type = urn_to_hrn(str(xrn)) # create the parent authority if necessary parent_hrn = get_authority(hrn) parent_urn = hrn_to_urn(parent_hrn, 'authority') if (parent_hrn) and (not self.auth_exists(parent_urn)) and (create_parents): self.create_auth(parent_urn, create_parents) (directory, gid_filename, privkey_filename,) = \ self.get_auth_filenames(hrn) # create the directory to hold the files try: os.makedirs(directory) # if the path already exists then pass except OSError, (errno, strerr): if errno == 17: pass
def __init__(self, create=False, subject=None, string=None, filename=None, uuid=None, hrn=None, urn=None, lifeDays=1825, email=None): self.uuid = None self.hrn = None self.urn = None self.email = None # for adding to the SubjectAltName Certificate.__init__(self, lifeDays, create, subject, string, filename) if subject: print "Creating GID for subject: %s" % subject if uuid: self.uuid = int(uuid) if hrn: self.hrn = hrn self.urn = hrn_to_urn(hrn, 'unknown') if urn: self.urn = urn self.hrn, type = urn_to_hrn(urn) if email: self.set_email(email)
def create_gid(self, xrn, uuid, pkey, CA=False, email=None): hrn, type = urn_to_hrn(xrn) if not type: type = 'authority' parent_hrn = get_authority(hrn) # Using hrn_to_urn() here to make sure the urn is in the right format # If xrn was a hrn instead of a urn, then the gid's urn will be # of type None urn = hrn_to_urn(hrn, type) subject = self.get_subject(hrn) if not subject: subject = hrn gid = GID(subject=subject, uuid=uuid, hrn=hrn, urn=urn, email=email) # is this a CA cert if hrn == self.config.SFA_INTERFACE_HRN or not parent_hrn: # root or sub authority gid.set_intermediate_ca(True) elif type and 'authority' in type: # authority type gid.set_intermediate_ca(False) elif CA: gid.set_intermediate_ca(True) else: gid.set_intermediate_ca(False) # set issuer 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 gid.set_issuer(pkey, subject) else: # we need the parent's private key in order to sign this GID parent_auth_info = self.get_auth_info(parent_hrn) parent_gid = parent_auth_info.get_gid_object() gid.set_issuer(parent_auth_info.get_pkey_object(), parent_gid.get_extended_subject()) gid.set_parent(parent_auth_info.get_gid_object()) gid.set_pubkey(pkey) gid.encode() gid.sign() return gid
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)
def decode(self): data = self.get_data('subjectAltName') dict = {} if data: if data.lower().startswith('uri:http://<params>'): dict = xmlrpclib.loads(data[11:])[0][0] else: spl = data.split(', ') for val in spl: if val.lower().startswith('uri:urn:uuid:'): dict['uuid'] = uuid.UUID(val[4:]).int elif val.lower().startswith('uri:urn:publicid:idn+'): dict['urn'] = val[4:] elif val.lower().startswith('email:'): # FIXME: Ensure there isn't cruft in that address... # EG look for email:copy,.... dict['email'] = val[6:] self.uuid = dict.get("uuid", None) self.urn = dict.get("urn", None) self.hrn = dict.get("hrn", None) self.email = dict.get("email", None) if self.urn: self.hrn = urn_to_hrn(self.urn)[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"))) self.gidCaller = GID(string=getTextNode(cred, "owner_gid")) self.gidObject = GID(string=getTextNode(cred, "target_gid")) # Process privileges privs = cred.getElementsByTagName("privileges")[0] rlist = Rights() 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() self.parent = Credential(string=parent_xml) self.updateRefID() # Assign the signatures to the credentials for sig in sigs: Sig = Signature(string=sig.toxml()) for cur_cred in self.get_credential_list(): if cur_cred.get_refid() == Sig.get_refid(): cur_cred.set_signature(Sig)
def call(self, cred, xrn, origin_hrn=None): hrn, type = urn_to_hrn(xrn) self.api.auth.check(cred, 'resetslice', hrn) self.api.manager.reset_slice (self.api, xrn) return 1
def __init__(self, slice_xrn, creds, options, **kwargs): hrn, type = urn_to_hrn(slice_xrn) valid_creds = Auth().checkCredentials(creds, 'sliverstatus', hrn) return
def __init__(self, xrn, gid_filename, privkey_filename): hrn, type = urn_to_hrn(xrn) self.hrn = hrn self.set_gid_filename(gid_filename) self.privkey_filename = privkey_filename
def get_type(self): if not self.urn: self.decode() _, t = urn_to_hrn(self.urn) return t
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
def set_urn(self, urn): self.urn = urn self.hrn, type = urn_to_hrn(urn)