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
def check_gid(self, xrn=None, type=None, all=None, verbose=None): """Check the correspondance between the GID and the PubKey""" # db records from sfa.storage.model import RegRecord db_query = self.api.dbsession().query(RegRecord).filter_by(type=type) if xrn and not all: hrn = Xrn(xrn).get_hrn() db_query = db_query.filter_by(hrn=hrn) elif all and xrn: print "Use either -a or -x <xrn>, not both !!!" sys.exit(1) elif not all and not xrn: print "Use either -a or -x <xrn>, one of them is mandatory !!!" sys.exit(1) records = db_query.all() if not records: print "No Record found" sys.exit(1) OK = [] NOK = [] ERROR = [] NOKEY = [] for record in records: # get the pubkey stored in SFA DB if record.reg_keys: db_pubkey_str = record.reg_keys[0].key try: db_pubkey_obj = convert_public_key(db_pubkey_str) except: ERROR.append(record.hrn) continue else: NOKEY.append(record.hrn) continue # get the pubkey from the gid gid_str = record.gid gid_obj = GID(string = gid_str) gid_pubkey_obj = gid_obj.get_pubkey() # Check if gid_pubkey_obj and db_pubkey_obj are the same check = gid_pubkey_obj.is_same(db_pubkey_obj) if check : OK.append(record.hrn) else: NOK.append(record.hrn) if not verbose: print "Users NOT having a PubKey: %s\n\ Users having a non RSA PubKey: %s\n\ Users having a GID/PubKey correpondence OK: %s\n\ Users having a GID/PubKey correpondence Not OK: %s\n"%(len(NOKEY), len(ERROR), len(OK), len(NOK)) else: print "Users NOT having a PubKey: %s and are: \n%s\n\n\ Users having a non RSA PubKey: %s and are: \n%s\n\n\ Users having a GID/PubKey correpondence OK: %s and are: \n%s\n\n\ Users having a GID/PubKey correpondence NOT OK: %s and are: \n%s\n\n"%(len(NOKEY),NOKEY, len(ERROR), ERROR, len(OK), OK, len(NOK), NOK)
def delegate(self, delegee_gidfile, caller_keyfile, caller_gidfile): """ Return a delegated copy of this credential, delegated to the specified gid's user. """ # get the gid of the object we are delegating object_gid = self.get_gid_object() object_hrn = object_gid.get_hrn() # the hrn of the user who will be delegated to delegee_gid = GID(filename=delegee_gidfile) delegee_hrn = delegee_gid.get_hrn() #user_key = Keypair(filename=keyfile) #user_hrn = self.get_gid_caller().get_hrn() subject_string = "%s delegated to %s" % (object_hrn, delegee_hrn) dcred = Credential(subject=subject_string) dcred.set_gid_caller(delegee_gid) dcred.set_gid_object(object_gid) dcred.set_parent(self) dcred.set_expiration(self.get_expiration()) dcred.set_privileges(self.get_privileges()) dcred.get_privileges().delegate_all_privileges(True) #dcred.set_issuer_keys(keyfile, delegee_gidfile) dcred.set_issuer_keys(caller_keyfile, caller_gidfile) dcred.encode() dcred.sign() return dcred
def export_gid(options): from sfa.util.table import SfaTable # lookup the record for the specified hrn hrn = options.export type = options.type # check sfa table first filter = {'hrn': hrn} if type: filter['type'] = type table = SfaTable() records = table.find(filter) if not records: # check the authorities hierarchy hierarchy = Hierarchy() try: auth_info = hierarchy.get_auth_info() gid = auth_info.gid_object except: print "Record: %s not found" % hrn sys.exit(1) else: record = records[0] gid = GID(string=record['gid']) # get the outfile outfile = options.outfile if not outfile: outfile = os.path.abspath('./%s.gid' % gid.get_hrn()) # save it if options.verbose: print "Writing %s gid to %s" % (gid.get_hrn(), outfile) gid.save_to_file(outfile, save_parents=True)
def get_username_from_cert(cert_string): try: gid = GID(string=cert_string) # extract the URN in the subjectAltName urn_str = gid.get_urn() logger.debug("URN: %s" % urn_str) except: logger.warn("Failed to get certificate from string.") logger.warn(traceback.format_exc()) return cert_string try: urn = URN(urn=str(urn_str)) except ValueError: return cert_string # check if this user is one of ours home_urn = get_user_urn(urn.getName()) if home_urn == urn.urn_string(): username = urn.getName() else: username = urn_to_username(urn.urn_string()) logger.debug("Returning username %s" % username) return username
def clean(self): """Check that the cert file is signed by the key file and is trusted.""" logger.debug("cleaned_data %s" % self.cleaned_data) if self.files: self.key = Keypair(string=self.files["key_file"].read()) self.cert = GID(string=self.files["cert_file"].read()) cert_pubkey = self.cert.get_pubkey().get_pubkey_string() if cert_pubkey != self.key.get_pubkey_string(): raise forms.ValidationError( "Error: The certificate was not signed " "by the uploaded key. Please use a key " "that matches the certificate.") try: certs = [GID(filename=f) for f in get_trusted_cert_filenames()] self.cert.verify_chain(certs) except Exception as e: logger.error(traceback.format_exc()) raise forms.ValidationError( "Could not verify that the uploaded certificate is " "trusted. This could be because none of the certificate's " "ancestors have been installed as trusted. The error was: " "%s" % e) return self.cleaned_data
def get_cert_file(self, key_file): cert_file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cert") if (os.path.isfile(cert_file)): # we'd perfer to use Registry issued certs instead of self signed certs. # if this is a Registry cert (GID) then we are done gid = GID(filename=cert_file) if gid.get_urn(): return cert_file # generate self signed certificate k = Keypair(filename=key_file) cert = Certificate(subject=self.user) cert.set_pubkey(k) cert.set_issuer(k, self.user) cert.sign() self.logger.info("Writing self-signed certificate to %s"%cert_file) cert.save_to_file(cert_file) self.cert = cert # try to get registry issued cert try: self.logger.info("Getting Registry issued cert") self.read_config() # *hack. need to set registyr before _get_gid() is called self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug) gid = self._get_gid(type='user') self.registry = None self.logger.info("Writing certificate to %s"%cert_file) gid.save_to_file(cert_file) except: self.logger.info("Failed to download Registry issued cert") return cert_file
def decode(self): data = self.get_data().lstrip('URI:http://') if data: dict = xmlrpclib.loads(data)[0][0] else: dict = {} self.lifeTime = dict.get("lifeTime", None) self.delegate = dict.get("delegate", None) privStr = dict.get("privileges", None) if privStr: self.privileges = Rights(string=privStr) else: self.privileges = None gidCallerStr = dict.get("gidCaller", None) if gidCallerStr: self.gidCaller = GID(string=gidCallerStr) else: self.gidCaller = None gidObjectStr = dict.get("gidObject", None) if gidObjectStr: self.gidObject = GID(string=gidObjectStr) else: self.gidObject = None
def _get_gid(self, hrn=None, type=None): """ git_gid helper. Retrive the gid from the registry and save it to file. """ if not hrn: hrn = self.user gidfile = os.path.join(self.options.sfi_dir, hrn + ".gid") gid = self.get_cached_gid(gidfile) if not gid: user_cred = self.get_user_cred() records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True)) if not records: raise RecordNotFound(args[0]) record = records[0] if type: record=None for rec in records: if type == rec['type']: record = rec if not record: raise RecordNotFound(args[0]) gid = GID(string=record['gid']) self.logger.info("Writing gid to %s"%gidfile) gid.save_to_file(filename=gidfile) return gid
def install_peer_certs(server_key_file, server_cert_file): """ Attempt to install missing trusted gids and db records for our federated interfaces """ # Attempt to get any missing peer gids # There should be a gid file in /etc/sfa/trusted_roots for every # peer registry found in in the registries.xml config file. If there # are any missing gids, request a new one from the peer registry. api = SfaAPI(key_file=server_key_file, cert_file=server_cert_file) registries = Registries() aggregates = Aggregates() interfaces = dict(registries.items() + aggregates.items()) gids_current = api.auth.trusted_cert_list hrns_current = [gid.get_hrn() for gid in gids_current] hrns_expected = set([hrn for hrn in interfaces]) new_hrns = set(hrns_expected).difference(hrns_current) # gids = self.get_peer_gids(new_hrns) + gids_current peer_gids = [] if not new_hrns: return trusted_certs_dir = api.config.get_trustedroots_dir() for new_hrn in new_hrns: if not new_hrn: continue # the gid for this interface should already be installed if new_hrn == api.config.SFA_INTERFACE_HRN: continue try: # get gid from the registry url = interfaces[new_hrn].get_url() interface = interfaces[new_hrn].get_server(server_key_file, server_cert_file, timeout=30) # skip non sfa aggregates server_version = api.get_cached_server_version(interface) if "sfa" not in server_version: logger.info("get_trusted_certs: skipping non sfa aggregate: %s" % new_hrn) continue trusted_gids = interface.get_trusted_certs() if trusted_gids: # the gid we want should be the first one in the list, # but lets make sure for trusted_gid in trusted_gids: # default message message = "interface: %s\t" % (api.interface) message += "unable to install trusted gid for %s" % (new_hrn) gid = GID(string=trusted_gids[0]) peer_gids.append(gid) if gid.get_hrn() == new_hrn: gid_filename = os.path.join(trusted_certs_dir, "%s.gid" % new_hrn) gid.save_to_file(gid_filename, save_parents=True) message = "installed trusted cert for %s" % new_hrn # log the message api.logger.info(message) except: message = "interface: %s\tunable to install trusted gid for %s" % (api.interface, new_hrn) api.logger.log_exc(message) # doesnt matter witch one update_cert_records(peer_gids)
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
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)
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) 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)
def display(self, gidfile): """Print contents of a GID file""" gid_path = os.path.abspath(gidfile) if not gid_path or not os.path.isfile(gid_path): print "No such gid file: %s" % gidfile sys.exit(1) gid = GID(filename=gid_path) gid.dump(dump_parents=True)
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)
def display(options): """ Display the sepcified GID """ gidfile = os.path.abspath(options.display) if not gidfile or not os.path.isfile(gidfile): print "No such gid: %s" % gidfile sys.exit(1) gid = GID(filename=gidfile) gid.dump(dump_parents=True)
def get_trusted_certs(self, opts, args): """ return uhe trusted certs at this interface """ trusted_certs = self.registry.get_trusted_certs() for trusted_cert in trusted_certs: gid = GID(string=trusted_cert) gid.dump() cert = Certificate(string=trusted_cert) self.logger.debug('Sfi.get_trusted_certs -> %r'%cert.get_subject()) return
class UploadCertForm(forms.Form): """Form to upload a certificate and its corresponding key.""" key_file = forms.FileField( help_text="Select the file that contains the key for the "\ "certificate to upload.") cert_file = forms.FileField( help_text="Select the file that contains the "\ "certificate to upload. The certificate must be signed "\ "with the uploaded key.") clean_key_file = _clean_x_file_factory("key") clean_cert_file = _clean_x_file_factory("cert") def clean(self): """Check that the cert file is signed by the key file and is trusted.""" logger.debug("cleaned_data %s" % self.cleaned_data) if self.files: self.key = Keypair(string=self.files["key_file"].read()) self.cert = GID(string=self.files["cert_file"].read()) cert_pubkey = self.cert.get_pubkey().get_pubkey_string() if cert_pubkey != self.key.get_pubkey_string(): raise forms.ValidationError( "Error: The certificate was not signed " "by the uploaded key. Please use a key " "that matches the certificate.") try: certs = [GID(filename=f) for f in get_trusted_cert_filenames()] self.cert.verify_chain(certs) except Exception as e: logger.error(traceback.format_exc()) raise forms.ValidationError( "Could not verify that the uploaded certificate is " "trusted. This could be because none of the certificate's " "ancestors have been installed as trusted. The error was: " "%s" % e ) return self.cleaned_data def save(self, user): """Write the key and cert into files. @param user: the user to save the cert and key for. @type user: C{django.contrib.auth.models.User} """ key_fname = get_user_key_fname(user) cert_fname = get_user_cert_fname(user) self.key.save_to_file(key_fname) self.cert.save_to_file(cert_fname)
class UploadCertForm(forms.Form): """Form to upload a certificate and its corresponding key.""" key_file = forms.FileField( help_text="Select the file that contains the key for the "\ "certificate to upload.") cert_file = forms.FileField( help_text="Select the file that contains the "\ "certificate to upload. The certificate must be signed "\ "with the uploaded key.") clean_key_file = _clean_x_file_factory("key") clean_cert_file = _clean_x_file_factory("cert") def clean(self): """Check that the cert file is signed by the key file and is trusted.""" logger.debug("cleaned_data %s" % self.cleaned_data) if self.files: self.key = Keypair(string=self.files["key_file"].read()) self.cert = GID(string=self.files["cert_file"].read()) cert_pubkey = self.cert.get_pubkey().get_pubkey_string() if cert_pubkey != self.key.get_pubkey_string(): raise forms.ValidationError( "Error: The certificate was not signed " "by the uploaded key. Please use a key " "that matches the certificate.") try: certs = [GID(filename=f) for f in get_trusted_cert_filenames()] self.cert.verify_chain(certs) except Exception as e: logger.error(traceback.format_exc()) raise forms.ValidationError( "Could not verify that the uploaded certificate is " "trusted. This could be because none of the certificate's " "ancestors have been installed as trusted. The error was: " "%s" % e) return self.cleaned_data def save(self, user): """Write the key and cert into files. @param user: the user to save the cert and key for. @type user: C{django.contrib.auth.models.User} """ key_fname = get_user_key_fname(user) cert_fname = get_user_cert_fname(user) self.key.save_to_file(key_fname) self.cert.save_to_file(cert_fname)
def install_gids(api, slivers): # install node gid node_gid_file = api.config.config_path + os.sep + "node.gid" node_gid = GID(filename=node_gid_file) node_gid_str = node_gid.save_to_string(save_parents=True) node_hrn = node_gid.get_hrn() # get currently installed slice and node gids interface_hrn = api.config.SFA_INTERFACE_HRN slice_gids = {} node_gids = {} for slicename in slivers: slice_gid_filename = "/vservers/%s/etc/slice.gid" % slicename node_gid_filename = "/vservers/%s/etc/node.gid" % slicename if os.path.isfile(slice_gid_filename): gid_file = open(slice_gid_filename, 'r') slice_gids[sliver] = gid_file.read() gid_file.close() if os.path.isfile(node_gid_filename): gid_file = open(node_gid_filename, 'r') node_gids[sliver] = gid_file.read() gid_file.close() # convert slicenames to hrns hrns = [slicename_to_hrn(interface_hrn, slicename) \ for slicename in slivers] # get current gids from registry cred = api.getCredential() registry = api.get_registry() #records = registry.GetGids(cred, hrns) records = registry.get_gids(cred, hrns) for record in records: # skip if this isnt a slice record if not record['type'] == 'slice': continue vserver_path = "/vservers/%(slicename)s" % locals() # skip if the slice isnt instantiated if not os.path.exists(vserver_path): continue # install slice gid if it doesnt already exist or has changed slice_gid_str = record['gid'] slicename = hrn_to_pl_slicename(record['hrn']) if slicename not in slice_gids or slice_gids[slicename] != slice_gid_str: gid_filename = os.sep.join([vserver_path, "etc", "slice.gid"]) GID(string=slice_gid_str).save_to_file(gid_filename, save_parents=True) # install slice gid if it doesnt already exist or has changed if slicename not in node_gids or node_gids[slicename] != node_gid_str: gid_filename = os.sep.join([vserver_path, "etc", "node.gid"]) GID(string=node_gid_str).save_to_file(gid_filename, save_parents=True)
def sign(self): if not self.issuer_privkey: logger.warn("Cannot sign credential (no private key)") return if not self.issuer_gid: logger.warn("Cannot sign credential (no issuer gid)") return doc = parseString(self.get_xml()) sigs = doc.getElementsByTagName("signatures")[0] # Create the signature template to be signed signature = Signature() signature.set_refid(self.get_refid()) sdoc = parseString(signature.get_xml()) sig_ele = doc.importNode(sdoc.getElementsByTagName("Signature")[0], True) sigs.appendChild(sig_ele) self.xml = doc.toxml() # Split the issuer GID into multiple certificates if it's a chain chain = GID(filename=self.issuer_gid) gid_files = [] while chain: gid_files.append(chain.save_to_random_tmp_file(False)) if chain.get_parent(): chain = chain.get_parent() else: chain = None # Call out to xmlsec1 to sign it ref = 'Sig_%s' % self.get_refid() filename = self.save_to_random_tmp_file() command='%s --sign --node-id "%s" --privkey-pem %s,%s %s' \ % (self.xmlsec_path, ref, self.issuer_privkey, ",".join(gid_files), filename) # print 'command',command signed = os.popen(command).read() os.remove(filename) for gid_file in gid_files: os.remove(gid_file) self.xml = signed # This is no longer a legacy credential if self.legacy: self.legacy = None # Update signatures self.decode()
def read_cert_from_file(cert_fname): """Read a GCF certificate from a file. Read the certificate from a file and put it into a C{sfa.trust.gid.GID} object. The returned certificate is already decoded. @param cert_fname: The filename to read the cert from @type cert_fname: C{str} @return: The certificate stored in the file at C{cert_fname} @rtype: C{sfa.trust.gid.GID} """ cert = GID(filename=cert_fname) cert.decode() return cert
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)
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"
def clean(self): """Check that the cert file is signed by the key file and is trusted.""" logger.debug("cleaned_data %s" % self.cleaned_data) if self.files: self.key = Keypair(string=self.files["key_file"].read()) self.cert = GID(string=self.files["cert_file"].read()) cert_pubkey = self.cert.get_pubkey().get_pubkey_string() if cert_pubkey != self.key.get_pubkey_string(): raise forms.ValidationError( "Error: The certificate was not signed " "by the uploaded key. Please use a key " "that matches the certificate.") try: certs = [GID(filename=f) for f in get_trusted_cert_filenames()] self.cert.verify_chain(certs) except Exception as e: logger.error(traceback.format_exc()) raise forms.ValidationError( "Could not verify that the uploaded certificate is " "trusted. This could be because none of the certificate's " "ancestors have been installed as trusted. The error was: " "%s" % e ) return self.cleaned_data
def create_null_slice_cred(): """Create a slice cred that can be used to list resources.""" slice_urn = create_slice_urn() slice_gid, _ = create_x509_cert(slice_urn) user_gid = GID(filename=settings.GCF_X509_CH_CERT) ucred = create_slice_credential(user_gid, slice_gid) ucred.save_to_file(settings.GCF_NULL_SLICE_CRED)
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 sign(self): if not self.issuer_privkey or not self.issuer_gid: return doc = parseString(self.get_xml()) sigs = doc.getElementsByTagName("signatures")[0] # Create the signature template to be signed signature = Signature() signature.set_refid(self.get_refid()) sdoc = parseString(signature.get_xml()) sig_ele = doc.importNode( sdoc.getElementsByTagName("Signature")[0], True) sigs.appendChild(sig_ele) self.xml = doc.toxml() # Split the issuer GID into multiple certificates if it's a chain chain = GID(filename=self.issuer_gid) gid_files = [] while chain: gid_files.append(chain.save_to_random_tmp_file(False)) if chain.get_parent(): chain = chain.get_parent() else: chain = None # Call out to xmlsec1 to sign it ref = 'Sig_%s' % self.get_refid() filename = self.save_to_random_tmp_file() signed = os.popen('%s --sign --node-id "%s" --privkey-pem %s,%s %s' \ % (self.xmlsec_path, ref, self.issuer_privkey, ",".join(gid_files), filename)).read() os.remove(filename) for gid_file in gid_files: os.remove(gid_file) self.xml = signed # This is no longer a legacy credential if self.legacy: self.legacy = None # Update signatures self.decode()
def init_server_cert(hrn, key, server_cert_file, self_signed=False): """ Setup the certificate for this server. Attempt to use gid before creating a self signed cert """ if self_signed: init_self_signed_cert(hrn, key, server_cert_file) else: try: # look for gid file logger.debug("generating server cert from gid: %s" % hrn) hierarchy = Hierarchy() auth_info = hierarchy.get_auth_info(hrn) gid = GID(filename=auth_info.gid_filename) gid.save_to_file(filename=server_cert_file) except: # fall back to self signed cert logger.debug("gid for %s not found" % hrn) init_self_signed_cert(hrn, key, server_cert_file)
def get_am_cred(cls): """ Get the slice authority credentials to use for AM calls. @return: GENI credential string. """ slice_urn = create_slice_urn() slice_gid, _ = create_x509_cert(slice_urn) user_gid = GID(filename=settings.GCF_X509_CH_CERT) ucred = create_slice_credential(user_gid, slice_gid) return ucred.save_to_string()
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
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)
def sign(options): """ Sign the specified gid """ hierarchy = Hierarchy() config = Config() default_authority = config.SFA_INTERFACE_HRN auth_info = hierarchy.get_auth_info(default_authority) # load the gid gidfile = os.path.abspath(options.sign) if not os.path.isfile(gidfile): print "no such gid: %s" % gidfile sys.exit(1) gid = GID(filename=gidfile) # extract pub_key and create new gid pkey = gid.get_pubkey() urn = gid.get_urn() gid = hierarchy.create_gid(urn, create_uuid(), pkey) # get the outfile outfile = options.outfile if not outfile: outfile = os.path.abspath('./signed-%s.gid' % gid.get_hrn()) # save the signed gid if options.verbose: print "Writing signed gid %s" % outfile gid.save_to_file(outfile, save_parents=True)
def decode(self): data = self.get_data() if data: dict = xmlrpclib.loads(self.get_data()[4:])[0][0] else: dict = {} self.attributes = dict.get("attributes", {}) self.rspec = dict.get("rspec", {}) self.delegate = dict.get("delegate", False) gidCallerStr = dict.get("gidCaller", None) if gidCallerStr: self.gidCaller = GID(string=gidCallerStr) else: self.gidCaller = None gidObjectStr = dict.get("gidObject", None) if gidObjectStr: self.gidObject = GID(string=gidObjectStr) else: self.gidObject = None
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
def export(self, xrn, type=None, outfile=None): """Fetch an object's GID from the Registry""" from sfa.storage.model import RegRecord hrn = Xrn(xrn).get_hrn() request=self.api.dbsession().query(RegRecord).filter_by(hrn=hrn) if type: request = request.filter_by(type=type) record=request.first() if record: gid = GID(string=record.gid) else: # check the authorities hierarchy hierarchy = Hierarchy() try: auth_info = hierarchy.get_auth_info(hrn) gid = auth_info.gid_object except: print "Record: %s not found" % hrn sys.exit(1) # save to file if not outfile: outfile = os.path.abspath('./%s.gid' % gid.get_hrn()) gid.save_to_file(outfile, save_parents=True)
def export(self, xrn, type=None, outfile=None): """Fetch an object's GID from the Registry""" from sfa.storage.model import RegRecord hrn = Xrn(xrn).get_hrn() request = self.api.dbsession().query(RegRecord).filter_by(hrn=hrn) if type: request = request.filter_by(type=type) record = request.first() if record: gid = GID(string=record.gid) else: # check the authorities hierarchy hierarchy = Hierarchy() try: auth_info = hierarchy.get_auth_info(hrn) gid = auth_info.gid_object except: print "Record: %s not found" % hrn sys.exit(1) # save to file if not outfile: outfile = os.path.abspath('./%s.gid' % gid.get_hrn()) gid.save_to_file(outfile, save_parents=True)
def import_gid(options): """ Import the specified gid into the registry (db and authorities hierarchy) overwriting any previous gid. """ from sfa.util.table import SfaTable from sfa.util.record import SfaRecord # load the gid gidfile = os.path.abspath(options.importgid) if not gidfile or not os.path.isfile(gidfile): print "No such gid: %s" % gidfile sys.exit(1) gid = GID(filename=gidfile) # check if it exists within the hierarchy hierarchy = Hierarchy() if not hierarchy.auth_exists(gid.get_hrn()): print "%s not found in hierarchy" % gid.get_hrn() sys.exit(1) # check if record exists in db table = SfaTable() records = table.find({'hrn': gid.get_hrn(), 'type': 'authority'}) if not records: print "%s not found in record database" % get.get_hrn() sys.exit(1) # update the database record record = records[0] record['gid'] = gid.save_to_string(save_parents=True) table.update(record) if options.verbose: print "Imported %s gid into db" % record['hrn'] # update the hierarchy auth_info = hierarchy.get_auth_info(gid.get_hrn()) filename = auth_info.gid_filename gid.save_to_file(filename, save_parents=True) if options.verbose: print "Writing %s gid to %s" % (gid.get_hrn(), filename) # ending here return
def set_servers(self): self.read_config() # Get key and certificate key_file = self.get_key_file() cert_file = self.get_cert_file(key_file) self.key = Keypair(filename=key_file) self.key_file = key_file self.cert_file = cert_file self.cert = GID(filename=cert_file) self.logger.info("Contacting Registry at: %s"%self.reg_url) self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug) self.logger.info("Contacting Slice Manager at: %s"%self.sm_url) self.slicemgr = xmlrpcprotocol.get_server(self.sm_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug) return
def get_trusted_certs(registry=None, verbose=False): """ refresh our list of trusted certs. """ # define useful variables config = Config() data_dir = config.SFA_DATA_DIR config_dir = config.SFA_CONFIG_DIR trusted_certs_dir = config.get_trustedroots_dir() keyfile = data_dir + os.sep + "server.key" certfile = data_dir + os.sep + "server.cert" node_gid_file = config_dir + os.sep + "node.gid" node_gid = GID(filename=node_gid_file) hrn = node_gid.get_hrn() # get credential cred = GetCredential(registry=registry, verbose=verbose) # make sure server key cert pair exists create_server_keypair(keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose) registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile) # get the trusted certs and save them in the right place if verbose: print "Getting trusted certs from registry" trusted_certs = registry.get_trusted_certs(cred) trusted_gid_names = [] for gid_str in trusted_certs: gid = GID(string=gid_str) gid.decode() relative_filename = gid.get_hrn() + ".gid" trusted_gid_names.append(relative_filename) gid_filename = trusted_certs_dir + os.sep + relative_filename if verbose: print "Writing GID for %s as %s" % (gid.get_hrn(), gid_filename) gid.save_to_file(gid_filename, save_parents=True) # remove old certs all_gids_names = os.listdir(trusted_certs_dir) for gid_name in all_gids_names: if gid_name not in trusted_gid_names: if verbose: print "Removing old gid ", gid_name os.unlink(trusted_certs_dir + os.sep + gid_name)
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)
class Signature(object): def __init__(self, string=None): self.refid = None self.issuer_gid = None self.xml = None if string: self.xml = string self.decode() def get_refid(self): if not self.refid: self.decode() return self.refid def get_xml(self): if not self.xml: self.encode() return self.xml def set_refid(self, id): self.refid = id def get_issuer_gid(self): if not self.gid: self.decode() return self.gid def set_issuer_gid(self, gid): self.gid = gid def decode(self): try: doc = parseString(self.xml) except ExpatError, e: logger.log_exc("Failed to parse credential, %s" % self.xml) raise sig = doc.getElementsByTagName("Signature")[0] self.set_refid(sig.getAttribute("xml:id").strip("Sig_")) keyinfo = sig.getElementsByTagName("X509Data")[0] szgid = getTextNode(keyinfo, "X509Certificate") szgid = "-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----" % szgid self.set_issuer_gid(GID(string=szgid))
def dump_text(self, dump_parents=False, sort=False): print 40*'=' print "RECORD" # print remaining fields fields=self.fields() if sort: fields.sort() for attrib_name in fields: attrib = getattr(self, attrib_name) # skip internals if attrib_name.startswith('_'): continue # skip callables if callable (attrib): continue # handle gid if attrib_name == 'gid': print " gid:" print GID(string=attrib).dump_string(8, dump_parents) elif attrib_name in ['date created', 'last updated']: print " %s: %s" % (attrib_name, self.date_repr(attrib_name)) else: print " %s: %s" % (attrib_name, attrib)
def verify(self, trusted_certs=None, schema=None, trusted_certs_required=True): if not self.xml: self.decode() # validate against RelaxNG schema if HAVELXML and not self.legacy: if schema and os.path.exists(schema): tree = etree.parse(StringIO(self.xml)) schema_doc = etree.parse(schema) xmlschema = etree.XMLSchema(schema_doc) if not xmlschema.validate(tree): error = xmlschema.error_log.last_error message = "%s: %s (line %s)" % ( self.get_summary_tostring(), error.message, error.line) raise CredentialNotVerifiable(message) if trusted_certs_required and trusted_certs is None: trusted_certs = [] # trusted_cert_objects = [GID(filename=f) for f in trusted_certs] trusted_cert_objects = [] ok_trusted_certs = [] # If caller explicitly passed in None that means skip cert chain validation. # Strange and not typical if trusted_certs is not None: for f in trusted_certs: try: # Failures here include unreadable files # or non PEM files trusted_cert_objects.append(GID(filename=f)) ok_trusted_certs.append(f) except Exception, exc: logger.error("Failed to load trusted cert from %s: %r" % (f, exc)) trusted_certs = ok_trusted_certs
def install_trusted_certs(api): cred = api.getCredential() registry = api.get_registry() trusted_certs = registry.get_trusted_certs(cred) trusted_gid_names = [] for gid_str in trusted_certs: gid = GID(string=gid_str) gid.decode() relative_filename = gid.get_hrn() + ".gid" trusted_gid_names.append(relative_filename) gid_filename = trusted_certs_dir + os.sep + relative_filename if verbose: print("Writing GID for %s as %s" % (gid.get_hrn(), gid_filename)) gid.save_to_file(gid_filename, save_parents=True) # remove old certs all_gids_names = os.listdir(trusted_certs_dir) for gid_name in all_gids_names: if gid_name not in trusted_gid_names: if verbose: print("Removing old gid ", gid_name) os.unlink(trusted_certs_dir + os.sep + gid_name)
def _get_client(self, cert_fname, key_fname): try: u = self.url except AttributeError: raise self.URLNotDefined("URL not set.") if not u: raise self.URLNotDefined("URL not set.") parsed = urlparse(u.lower()) if parsed.scheme == "test": user_cert = GID(filename=cert_fname).save_to_string() transport = TestClientTransport(defaults={ "REMOTE_USER": user_cert, "SSL_CLIENT_CERT": user_cert }) proxy = xmlrpclib.ServerProxy( test_to_http(u), transport=transport, ) else: transport = certtransport.SafeTransportWithCert( keyfile=key_fname, certfile=cert_fname) proxy = xmlrpclib.ServerProxy(u, transport=transport) return proxy
def get_list(self): gid_list = [GID(filename=cert_file) for cert_file in self.get_file_list()] return gid_list
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()) self.driver.augment_records_with_testbed_info(record.__dict__) logger.debug("get credential after augment dict, keys=%s" % record.__dict__.keys()) if not self.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.todict()) # 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)
def get_gid_object(self): if not self.gid: return None else: return GID(string=self.gid)
def check_gid(self, xrn=None, type=None, all=None, verbose=None): """Check the correspondance between the GID and the PubKey""" # db records from sfa.storage.model import RegRecord db_query = self.api.dbsession().query(RegRecord).filter_by(type=type) if xrn and not all: hrn = Xrn(xrn).get_hrn() db_query = db_query.filter_by(hrn=hrn) elif all and xrn: print "Use either -a or -x <xrn>, not both !!!" sys.exit(1) elif not all and not xrn: print "Use either -a or -x <xrn>, one of them is mandatory !!!" sys.exit(1) records = db_query.all() if not records: print "No Record found" sys.exit(1) OK = [] NOK = [] ERROR = [] NOKEY = [] for record in records: # get the pubkey stored in SFA DB if record.reg_keys: db_pubkey_str = record.reg_keys[0].key try: db_pubkey_obj = convert_public_key(db_pubkey_str) except: ERROR.append(record.hrn) continue else: NOKEY.append(record.hrn) continue # get the pubkey from the gid gid_str = record.gid gid_obj = GID(string=gid_str) gid_pubkey_obj = gid_obj.get_pubkey() # Check if gid_pubkey_obj and db_pubkey_obj are the same check = gid_pubkey_obj.is_same(db_pubkey_obj) if check: OK.append(record.hrn) else: NOK.append(record.hrn) if not verbose: print "Users NOT having a PubKey: %s\n\ Users having a non RSA PubKey: %s\n\ Users having a GID/PubKey correpondence OK: %s\n\ Users having a GID/PubKey correpondence Not OK: %s\n" % ( len(NOKEY), len(ERROR), len(OK), len(NOK)) else: print "Users NOT having a PubKey: %s and are: \n%s\n\n\ Users having a non RSA PubKey: %s and are: \n%s\n\n\ Users having a GID/PubKey correpondence OK: %s and are: \n%s\n\n\ Users having a GID/PubKey correpondence NOT OK: %s and are: \n%s\n\n" % (len( NOKEY), NOKEY, len(ERROR), ERROR, len(OK), OK, len(NOK), NOK)
class Sfi: required_options=['verbose', 'debug', 'registry', 'sm', 'auth', 'user'] # dummy to meet Sfi's expectations for its 'options' field # i.e. s/t we can do setattr on class DummyOptions: pass def __init__ (self,options=None): if options is None: options=Sfi.DummyOptions() for opt in Sfi.required_options: if not hasattr(options,opt): setattr(options,opt,None) if not hasattr(options,'sfi_dir'): options.sfi_dir=os.path.expanduser("~/.sfi/") # xxx oops, this is dangerous, sounds like ww sometimes have discrepency # would be safer to remove self.sfi_dir altogether self.sfi_dir = options.sfi_dir self.options = options self.slicemgr = None self.registry = None self.user = None self.authority = None self.hashrequest = False self.logger = sfi_logger self.logger.enable_console() def create_cmd_parser(self, command, additional_cmdargs=None): cmdargs = {"list": "authority", "show": "name", "remove": "name", "add": "record", "update": "record", "aggregates": "[name]", "registries": "[name]", "create_gid": "[name]", "get_gid": [], "get_trusted_certs": "cred", "slices": "", "resources": "[name]", "create": "name rspec", "get_ticket": "name rspec", "redeem_ticket": "ticket", "delete": "name", "reset": "name", "start": "name", "stop": "name", "delegate": "name", "status": "name", "renew": "name", "shutdown": "name", "version": "", } if additional_cmdargs: cmdargs.update(additional_cmdargs) if command not in cmdargs: msg="Invalid command\n" msg+="Commands: " msg += ','.join(cmdargs.keys()) self.logger.critical(msg) sys.exit(2) parser = OptionParser(usage="sfi [sfi_options] %s [options] %s" \ % (command, cmdargs[command])) # user specifies remote aggregate/sm/component if command in ("resources", "slices", "create", "delete", "start", "stop", "restart", "shutdown", "get_ticket", "renew", "status"): parser.add_option("-a", "--aggregate", dest="aggregate", default=None, help="aggregate host") parser.add_option("-p", "--port", dest="port", default=AGGREGATE_PORT, help="aggregate port") parser.add_option("-c", "--component", dest="component", default=None, help="component hrn") parser.add_option("-d", "--delegate", dest="delegate", default=None, action="store_true", help="Include a credential delegated to the user's root"+\ "authority in set of credentials for this call") # registy filter option if command in ("list", "show", "remove"): parser.add_option("-t", "--type", dest="type", type="choice", help="type filter ([all]|user|slice|authority|node|aggregate)", choices=("all", "user", "slice", "authority", "node", "aggregate"), default="all") # display formats if command in ("resources"): parser.add_option("-r", "--rspec-version", dest="rspec_version", default="SFA 1", help="schema type and version of resulting RSpec") parser.add_option("-f", "--format", dest="format", type="choice", help="display format ([xml]|dns|ip)", default="xml", choices=("xml", "dns", "ip")) #panos: a new option to define the type of information about resources a user is interested in parser.add_option("-i", "--info", dest="info", help="optional component information", default=None) # 'create' does return the new rspec, makes sense to save that too if command in ("resources", "show", "list", "create_gid", 'create'): parser.add_option("-o", "--output", dest="file", help="output XML to file", metavar="FILE", default=None) if command in ("show", "list"): parser.add_option("-f", "--format", dest="format", type="choice", help="display format ([text]|xml)", default="text", choices=("text", "xml")) parser.add_option("-F", "--fileformat", dest="fileformat", type="choice", help="output file format ([xml]|xmllist|hrnlist)", default="xml", choices=("xml", "xmllist", "hrnlist")) if command in ("status"): parser.add_option("-o", "--output", dest="file", help="output dictionary to file", metavar="FILE", default=None) parser.add_option("-F", "--fileformat", dest="fileformat", type="choice", help="output file format ([text]|pickled)", default="text", choices=("text","pickled")) if command in ("delegate"): parser.add_option("-u", "--user", action="store_true", dest="delegate_user", default=False, help="delegate user credential") parser.add_option("-s", "--slice", dest="delegate_slice", help="delegate slice credential", metavar="HRN", default=None) if command in ("version"): parser.add_option("-a", "--aggregate", dest="aggregate", default=None, help="aggregate host") parser.add_option("-p", "--port", dest="port", default=AGGREGATE_PORT, help="aggregate port") parser.add_option("-R","--registry-version", action="store_true", dest="version_registry", default=False, help="probe registry version instead of slicemgr") parser.add_option("-l","--local", action="store_true", dest="version_local", default=False, help="display version of the local client") return parser def create_parser(self): # Generate command line parser parser = OptionParser(usage="sfi [options] command [command_options] [command_args]", description="Commands: gid,list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset") parser.add_option("-r", "--registry", dest="registry", help="root registry", metavar="URL", default=None) parser.add_option("-s", "--slicemgr", dest="sm", help="slice manager", metavar="URL", default=None) default_sfi_dir = os.path.expanduser("~/.sfi/") parser.add_option("-d", "--dir", dest="sfi_dir", help="config & working directory - default is " + default_sfi_dir, metavar="PATH", default=default_sfi_dir) parser.add_option("-u", "--user", dest="user", help="user name", metavar="HRN", default=None) parser.add_option("-a", "--auth", dest="auth", help="authority name", metavar="HRN", default=None) parser.add_option("-v", "--verbose", action="count", dest="verbose", default=0, help="verbose mode - cumulative") parser.add_option("-D", "--debug", action="store_true", dest="debug", default=False, help="Debug (xml-rpc) protocol messages") parser.add_option("-p", "--protocol", dest="protocol", default="xmlrpc", help="RPC protocol (xmlrpc or soap)") parser.add_option("-k", "--hashrequest", action="store_true", dest="hashrequest", default=False, help="Create a hash of the request that will be authenticated on the server") parser.add_option("-t", "--timeout", dest="timeout", default=None, help="Amout of time tom wait before timing out the request") parser.disable_interspersed_args() return parser def read_config(self): config_file = os.path.join(self.options.sfi_dir,"sfi_config") try: config = Config (config_file) except: self.logger.critical("Failed to read configuration file %s"%config_file) self.logger.info("Make sure to remove the export clauses and to add quotes") if self.options.verbose==0: self.logger.info("Re-run with -v for more details") else: self.logger.log_exc("Could not read config file %s"%config_file) sys.exit(1) errors = 0 # Set SliceMgr URL if (self.options.sm is not None): self.sm_url = self.options.sm elif hasattr(config, "SFI_SM"): self.sm_url = config.SFI_SM else: self.logger.error("You need to set e.g. SFI_SM='http://your.slicemanager.url:12347/' in %s" % config_file) errors += 1 # Set Registry URL if (self.options.registry is not None): self.reg_url = self.options.registry elif hasattr(config, "SFI_REGISTRY"): self.reg_url = config.SFI_REGISTRY else: self.logger.errors("You need to set e.g. SFI_REGISTRY='http://your.registry.url:12345/' in %s" % config_file) errors += 1 # Set user HRN if (self.options.user is not None): self.user = self.options.user elif hasattr(config, "SFI_USER"): self.user = config.SFI_USER else: self.logger.errors("You need to set e.g. SFI_USER='******' in %s" % config_file) errors += 1 # Set authority HRN if (self.options.auth is not None): self.authority = self.options.auth elif hasattr(config, "SFI_AUTH"): self.authority = config.SFI_AUTH else: self.logger.error("You need to set e.g. SFI_AUTH='plc.princeton' in %s" % config_file) errors += 1 if errors: sys.exit(1) # # Establish Connection to SliceMgr and Registry Servers # def set_servers(self): self.read_config() # Get key and certificate key_file = self.get_key_file() cert_file = self.get_cert_file(key_file) self.key = Keypair(filename=key_file) self.key_file = key_file self.cert_file = cert_file self.cert = GID(filename=cert_file) self.logger.info("Contacting Registry at: %s"%self.reg_url) self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug) self.logger.info("Contacting Slice Manager at: %s"%self.sm_url) self.slicemgr = xmlrpcprotocol.get_server(self.sm_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug) return def get_cached_server_version(self, server): # check local cache first cache = None version = None cache_file = os.path.join(self.options.sfi_dir,'sfi_cache.dat') cache_key = server.url + "-version" try: cache = Cache(cache_file) except IOError: cache = Cache() self.logger.info("Local cache not found at: %s" % cache_file) if cache: version = cache.get(cache_key) if not version: version = server.GetVersion() # cache version for 24 hours cache.add(cache_key, version, ttl= 60*60*24) self.logger.info("Updating cache file %s" % cache_file) cache.save_to_file(cache_file) return version def server_supports_call_id_arg(self, server): """ Returns true if server support the optional call_id arg, false otherwise. """ server_version = self.get_cached_server_version(server) if 'sfa' in server_version and 'code_tag' in server_version: code_tag = server_version['code_tag'] code_tag_parts = code_tag.split("-") version_parts = code_tag_parts[0].split(".") major, minor = version_parts[0], version_parts[1] rev = code_tag_parts[1] if int(major) > 1: if int(minor) > 0 or int(rev) > 20: return True return False # # Get various credential and spec files # # Establishes limiting conventions # - conflates MAs and SAs # - assumes last token in slice name is unique # # Bootstraps credentials # - bootstrap user credential from self-signed certificate # - bootstrap authority credential from user credential # - bootstrap slice credential from user credential # def get_key_file(self): file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".pkey") if (os.path.isfile(file)): return file else: self.logger.error("Key file %s does not exist"%file) sys.exit(-1) return def get_cert_file(self, key_file): cert_file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cert") if (os.path.isfile(cert_file)): # we'd perfer to use Registry issued certs instead of self signed certs. # if this is a Registry cert (GID) then we are done gid = GID(filename=cert_file) if gid.get_urn(): return cert_file # generate self signed certificate k = Keypair(filename=key_file) cert = Certificate(subject=self.user) cert.set_pubkey(k) cert.set_issuer(k, self.user) cert.sign() self.logger.info("Writing self-signed certificate to %s"%cert_file) cert.save_to_file(cert_file) self.cert = cert # try to get registry issued cert try: self.logger.info("Getting Registry issued cert") self.read_config() # *hack. need to set registyr before _get_gid() is called self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug) gid = self._get_gid(type='user') self.registry = None self.logger.info("Writing certificate to %s"%cert_file) gid.save_to_file(cert_file) except: self.logger.info("Failed to download Registry issued cert") return cert_file def get_cached_gid(self, file): """ Return a cached gid """ gid = None if (os.path.isfile(file)): gid = GID(filename=file) return gid # xxx opts unused def get_gid(self, opts, args): """ Get the specify gid and save it to file """ hrn = None if args: hrn = args[0] gid = self._get_gid(hrn) self.logger.debug("Sfi.get_gid-> %s",gid.save_to_string(save_parents=True)) return gid def _get_gid(self, hrn=None, type=None): """ git_gid helper. Retrive the gid from the registry and save it to file. """ if not hrn: hrn = self.user gidfile = os.path.join(self.options.sfi_dir, hrn + ".gid") gid = self.get_cached_gid(gidfile) if not gid: user_cred = self.get_user_cred() records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True)) if not records: raise RecordNotFound(args[0]) record = records[0] if type: record=None for rec in records: if type == rec['type']: record = rec if not record: raise RecordNotFound(args[0]) gid = GID(string=record['gid']) self.logger.info("Writing gid to %s"%gidfile) gid.save_to_file(filename=gidfile) return gid 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 def get_user_cred(self): file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cred") return self.get_cred(file, 'user', self.user) def get_auth_cred(self): if not self.authority: self.logger.critical("no authority specified. Use -a or set SF_AUTH") sys.exit(-1) file = os.path.join(self.options.sfi_dir, self.authority + ".cred") return self.get_cred(file, 'authority', self.authority) def get_slice_cred(self, name): file = os.path.join(self.options.sfi_dir, "slice_" + get_leaf(name) + ".cred") return self.get_cred(file, 'slice', name) 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 def get_rspec_file(self, rspec): if (os.path.isabs(rspec)): file = rspec else: file = os.path.join(self.options.sfi_dir, rspec) if (os.path.isfile(file)): return file else: self.logger.critical("No such rspec file %s"%rspec) sys.exit(1) def get_record_file(self, record): if (os.path.isabs(record)): file = record else: file = os.path.join(self.options.sfi_dir, record) if (os.path.isfile(file)): return file else: self.logger.critical("No such registry record file %s"%record) sys.exit(1) def load_publickey_string(self, fn): f = file(fn, "r") key_string = f.read() # if the filename is a private key file, then extract the public key if "PRIVATE KEY" in key_string: outfn = tempfile.mktemp() cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn os.system(cmd) f = file(outfn, "r") key_string = f.read() os.remove(outfn) return key_string # xxx opts undefined def get_component_server_from_hrn(self, hrn): # direct connection to the nodes component manager interface user_cred = self.get_user_cred().save_to_string(save_parents=True) records = self.registry.Resolve(hrn, user_cred) records = filter_records('node', records) if not records: self.logger.warning("No such component:%r"% opts.component) record = records[0] return self.get_server(record['hostname'], CM_PORT, self.key_file, self.cert_file) def get_server(self, host, port, keyfile, certfile): """ Return an instance of an xmlrpc server connection """ # port is appended onto the domain, before the path. Should look like: # http://domain:port/path host_parts = host.split('/') host_parts[0] = host_parts[0] + ":" + str(port) url = "http://%s" % "/".join(host_parts) return xmlrpcprotocol.get_server(url, keyfile, certfile, timeout=self.options.timeout, verbose=self.options.debug) # xxx opts could be retrieved in self.options def get_server_from_opts(self, opts): """ Return instance of an xmlrpc connection to a slice manager, aggregate or component server depending on the specified opts """ server = self.slicemgr # direct connection to an aggregate if hasattr(opts, 'aggregate') and opts.aggregate: server = self.get_server(opts.aggregate, opts.port, self.key_file, self.cert_file) # direct connection to the nodes component manager interface if hasattr(opts, 'component') and opts.component: server = self.get_component_server_from_hrn(opts.component) return server #========================================================================== # Following functions implement the commands # # Registry-related commands #========================================================================== def dispatch(self, command, cmd_opts, cmd_args): return getattr(self, command)(cmd_opts, cmd_args) def create_gid(self, opts, args): if len(args) < 1: self.print_help() sys.exit(1) target_hrn = args[0] user_cred = self.get_user_cred().save_to_string(save_parents=True) gid = self.registry.CreateGid(user_cred, target_hrn, self.cert.save_to_string()) if opts.file: filename = opts.file else: filename = os.sep.join([self.sfi_dir, '%s.gid' % target_hrn]) self.logger.info("writing %s gid to %s" % (target_hrn, filename)) GID(string=gid).save_to_file(filename) # list entires in named authority registry def list(self, opts, args): if len(args)!= 1: self.print_help() sys.exit(1) hrn = args[0] user_cred = self.get_user_cred().save_to_string(save_parents=True) try: list = self.registry.List(hrn, user_cred) except IndexError: raise Exception, "Not enough parameters for the 'list' command" # filter on person, slice, site, node, etc. # THis really should be in the self.filter_records funct def comment... list = filter_records(opts.type, list) for record in list: print "%s (%s)" % (record['hrn'], record['type']) if opts.file: save_records_to_file(opts.file, list, opts.fileformat) return # show named registry record def show(self, opts, args): if len(args)!= 1: self.print_help() sys.exit(1) hrn = args[0] user_cred = self.get_user_cred().save_to_string(save_parents=True) records = self.registry.Resolve(hrn, user_cred) records = filter_records(opts.type, records) if not records: print "No record of type", opts.type for record in records: if record['type'] in ['user']: record = UserRecord(dict=record) elif record['type'] in ['slice']: record = SliceRecord(dict=record) elif record['type'] in ['node']: record = NodeRecord(dict=record) elif record['type'].startswith('authority'): record = AuthorityRecord(dict=record) else: record = SfaRecord(dict=record) if (opts.format == "text"): record.dump() else: print record.save_to_string() if opts.file: save_records_to_file(opts.file, records, opts.fileformat) return 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)) 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) # removed named registry record # - have to first retrieve the record to be removed def remove(self, opts, args): auth_cred = self.get_auth_cred().save_to_string(save_parents=True) if len(args)!=1: self.print_help() sys.exit(1) hrn = args[0] type = opts.type if type in ['all']: type = '*' return self.registry.Remove(hrn, auth_cred, type) # add named registry record def add(self, opts, args): auth_cred = self.get_auth_cred().save_to_string(save_parents=True) if len(args)!=1: self.print_help() sys.exit(1) record_filepath = args[0] rec_file = self.get_record_file(record_filepath) record = load_record_from_file(rec_file).as_dict() return self.registry.Register(record, auth_cred) # update named registry entry def update(self, opts, args): user_cred = self.get_user_cred() if len(args)!=1: self.print_help() sys.exit(1) rec_file = self.get_record_file(args[0]) record = load_record_from_file(rec_file) if record['type'] == "user": if record.get_name() == user_cred.get_gid_object().get_hrn(): cred = user_cred.save_to_string(save_parents=True) else: cred = self.get_auth_cred().save_to_string(save_parents=True) elif record['type'] in ["slice"]: try: cred = self.get_slice_cred(record.get_name()).save_to_string(save_parents=True) except xmlrpcprotocol.ServerException, e: # XXX smbaker -- once we have better error return codes, update this # to do something better than a string compare if "Permission error" in e.args[0]: cred = self.get_auth_cred().save_to_string(save_parents=True) else: raise elif record.get_type() in ["authority"]: cred = self.get_auth_cred().save_to_string(save_parents=True)
def create_gid(self, xrn, uuid, pkey, CA=False): hrn, type = urn_to_hrn(xrn) 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) gid = GID(subject=hrn, uuid=uuid, hrn=hrn, urn=urn) # 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(True) 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, hrn) else: # we need the parent's private key in order to sign this GID parent_auth_info = self.get_auth_info(parent_hrn) gid.set_issuer(parent_auth_info.get_pkey_object(), parent_auth_info.hrn) gid.set_parent(parent_auth_info.get_gid_object()) gid.set_pubkey(pkey) gid.encode() gid.sign() return gid
def create_cert(urn, issuer_key=None, issuer_cert=None, intermediate=False): '''Create a new certificate and return it and the associated keys. If issuer cert and key are given, they sign the certificate. Otherwise it is a self-signed certificate. If intermediate then mark this as an intermediate CA certificate (can sign). Certificate URN must be supplied. CN of the cert will be dotted notation authority.type.name from the URN. ''' # Note the below throws a ValueError if it wasnt a valid URN c_urn = URN(urn=urn) dotted = '%s.%s.%s' % (c_urn.getAuthority(), c_urn.getType(), c_urn.getName()) newgid = GID(create=True, subject=dotted[:64], urn=urn) keys = Keypair(create=True) newgid.set_pubkey(keys) if intermediate: # This cert will be able to sign certificates newgid.set_intermediate_ca(intermediate) if issuer_key and issuer_cert: # the given issuer will issue this cert if isinstance(issuer_key,str): issuer_key = Keypair(filename=issuer_key) if isinstance(issuer_cert,str): issuer_cert = GID(filename=issuer_cert) newgid.set_issuer(issuer_key, cert=issuer_cert) newgid.set_parent(issuer_cert) else: # create a self-signed cert newgid.set_issuer(keys, subject=dotted) newgid.encode() newgid.sign() return newgid, keys
def create_cert(urn, issuer_key=None, issuer_cert=None, ca=False, public_key=None, lifeDays=1825, email=None): '''Create a new certificate and return it and the associated keys. If issuer cert and key are given, they sign the certificate. Otherwise it is a self-signed certificate. If ca then mark this as a CA certificate (can sign other certs). lifeDays is the lifetime of the supplied cert - default is 1825 (5 years). Certificate URN must be supplied. CN of the cert will be dotted notation authority.type.name from the URN. ''' # Note the below throws a ValueError if it wasnt a valid URN c_urn = URN(urn=urn) dotted = '%s.%s.%s' % (c_urn.getAuthority(), c_urn.getType(), c_urn.getName()) subject = dict() subject['CN'] = dotted[:64] if email: subject['emailAddress'] = email newgid = GID(create=True, subject=subject, urn=urn, lifeDays=lifeDays) if public_key is None: # create a new key pair keys = Keypair(create=True) else: # use the specified public key file keys = Keypair() keys.load_pubkey_from_file(public_key) newgid.set_pubkey(keys) newgid.set_is_ca(ca) if issuer_key and issuer_cert: # the given issuer will issue this cert if isinstance(issuer_key, str): issuer_key = Keypair(filename=issuer_key) if isinstance(issuer_cert, str): issuer_cert = GID(filename=issuer_cert) newgid.set_issuer(issuer_key, cert=issuer_cert) newgid.set_parent(issuer_cert) else: # create a self-signed cert newgid.set_issuer(keys, subject=dotted) newgid.encode() newgid.sign() return newgid, keys
def get_gid_object(self): if not self.gid_object: self.gid_object = GID(filename = self.gid_filename) return self.gid_object
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) gid = GID(subject=hrn, 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(True) 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, hrn) else: # we need the parent's private key in order to sign this GID parent_auth_info = self.get_auth_info(parent_hrn) gid.set_issuer(parent_auth_info.get_pkey_object(), parent_auth_info.hrn) gid.set_parent(parent_auth_info.get_gid_object()) gid.set_pubkey(pkey) gid.encode() gid.sign() return gid