import tempfile import os from cert import * from gid import * from geniserver import * from excep import * from hierarchy import * from misc import * def get_pl_object_by_hrn(hrn): # find the object in the planetlab database pointer = None if (type=="sa") or (type=="ma"): authname = hrn_to_pl_authname(name): pl_res = shell.GetSites(pl_auth, {'name': authname) if pl_res: site_info = pl_res[0] pointer = auth_info['auth_id'] return (site_info, pointer) elif (type=="slice"): slicename = hrn_to_pl_slicename(name) pl_res = shell.GetSlices(pl_auth, {'name': slicename) if pl_res: slice_info = pl_res[0] pointer = slice_info['slice_id'] return (slice_info, pointer) elif (type=="user"): username = hrn_to_pl_username(name) pl_res = shell.GetPersons(pl_auth, {'name': slicename) if pl_res: person_info = pl_res[0] pointer = slice_info['person_id'] return (person_info, pointer) elif (type=="component"): node_name = hrn_to_pl_nodename(hrn) pl_res = shell.GetNodes(pl_auth, {'name': nodename) if pl_res: node_info = pl_res[0] pointer = node_info['node_id'] return (node_info, pointer) else: raise UnknownGeniType(type) return (None, None) class Registry(GeniServer): def __init__(self, ip, port, key_file, cert_file): GeniServer.__init__(self, ip, port, key_file, cert_file) def register_functions(self): GeniServer.register_functions(self) self.server.register_function(self.get_self_credential) self.server.register_function(self.get_credential) self.server.register_function(self.get_gid) def get_auth_info(name): return Hierarchy.get_auth_info(name) def get_auth_table(self, auth_name): auth_info = get_auth_info(name, can_create=False) table = GeniTable(hrn = auth_name, auth_info.get_cninfo() auth_info.get_privkey_object() auth_info.get_gid_object()) # if the table doesn't exist, then it means we haven't put any records # into this authority yet. if not table.exists(): table.create() return table def verify_auth_belongs_to_me(self, name): # get_auth_info will throw an exception if the authority does not # exist self.get_auth_info(name) def verify_object_belongs_to_me(self, name): auth_name = get_authority(name) self.verify_auth_belongs_to_me(auth_name) def register(self, cred, name, record_dict): self.decode_authentication(cred) auth_name = get_authority(name) auth_info = self.get_auth_info(auth_name) table = self.get_auth_table(auth_name) record = GeniRecord(dict = record_dict) type = record.get_type() pkey = None # check if record already exists existing_records = table.resolve(name, type) if existing_records: raise ExistingRecord(name) if (type == "sa") or (type=="ma"): # update the tree if not Hierarchy.auth_exists(name): Hierarchy.create_auth(name) # get the public key from the newly created authority child_auth_info = self.get_auth_info(name) pkey = child_auth_info.get_pkey_object() site_fields = record.get_pl_info() pointer = shell.AddSite(pl_auth, site_fields) record.set_pointer(pointer) elif (type == "slice"): slice_fields = record.get_pl_info() pointer = shell.AddSlice(pl_auth, slice_fields) record.set_pointer(pointer) elif (type == "user"): # TODO: extract pkey from user_fields user_fields = record.get_pl_info() pointer = shell.AddPerson(pl_auth, user_fields) record.set_pointer(pointer) elif (type == "node"): node_fields = record.get_pl_info() pointer = shell.AddNode(pl_auth, login_base, node_fields) record.set_pointer(pointer) else: raise UnknownGeniType(type) gid = Hierarchy.create_gid(name, create_uuid(), pkey) record.set_gid(gid.save_to_string()) table.insert(record) def remove(self, cred, record_dict): self.decode_authentication(cred) record = GeniRecord(dict = record_dict) type = record.get_type() auth_name = get_authority(record.get_name()) table = self.get_auth_table(auth_name) # let's not trust that the caller has a well-formed record (a forged # pointer field could be a disaster), so look it up ourselves record = table.resolve(type, record.get_name(), must_exist=True)[0] # TODO: sa, ma if type == "user": shell.DeletePerson(pl_auth, record.get_pointer()) elif type == "slice": shell.DeleteSlice(pl_auth, record.get_pointer()) elif type == "node": shell.DeleteNode(pl_auth, record.get_pointer()) else: raise UnknownGeniType(type) table.remove(record_dict) def update(self, cred, record_dict): self.decode_authentication(cred) record = GeniRecord(dict = record_dict) type = record.get_type() auth_name = get_authority(record.get_name()) table = self.get_auth_table(auth_name) # make sure the record exists existing_record = table.resolve(type, record.get_name(), must_exist=True)[0] pointer = existing_record.get_pointer() if (type == "sa") or (type == "ma"): shell.UpdateSite(pl_auth, pointer, record.get_pl_info()) elif type == "slice": shell.UpdateSlice(pl_auth, pointer, record.get_pl_info()) elif type == "user": shell.UpdatePerson(pl_auth, pointer, record.get_pl_info()) elif type == "node": shell.UpdateNode(pl_auth, pointer, record.get_pl_info()) else: raise UnknownGeniType(type) def list(self, cred): self.decode_authentication(cred) auth_name = self.object_gid.get_hrn() table = self.get_auth_table(auth_name) dict_list = table.list_dict() return dict_list def resolve_raw(self, type, name, must_exist=True): auth_name = get_authority(name) table = get_auth_table(auth_name) records = table.resolve(type, name) if (not records) and must_exist: raise RecordNotFound(name) return records def resolve(self, name): self.decode_authentication(cred) records = self.resolve("*", name) dicts = [] for record in records: dicts.append(record.as_dict()) return dicts def get_gid(self, name): self.verify_object_belongs_to_me(name) # XXX Fixme records = self.resolve_raw("*", name) gid_string_list = [] for record in records: gid = record.get_gid() gid_string_list.append(gid.save_to_string()) return gid_string_list def get_self_credential(self, type, name): self.verify_object_belongs_to_me(name) # find a record that matches records = self.resolve_raw(type, name, must_exist=True) record = records[0] gid = record.get_gid() peer_cert = self.server.peer_cert if not peer_cert.is_pubkey(gid.get_pubkey()): raise ConnectionKeyGIDMismatch(gid.get_subject()) # create the credential gid = found_record.get_gid() cred = Credential(subject = gid.get_subject()) cred.set_gid_caller(gid) cred.set_gid_object(gid) cred.set_issuer(key=self.key, subject=auth_hrn) cred.set_pubkey(gid.get_pubkey()) cred.encode() cred.sign() return cred.save_to_string() def get_credential(self, cred, type, name): if not cred: return get_self_credential(self, type, name) self.decode_authentication(cred) self.verify_object_belongs_to_me(name) records = self.resolve(type, name, must_exist=True) record = records[0] object_gid = record.get_gid() new_cred = Credential(subject = object_gid.get_subject()) new_cred.set_gid_caller(self.client_gid) new_cred.set_gid_object(object_gid) new_cred.set_issuer(key=self.key, cert=self.cert) new_cred.set_pubkey(object_gid.get_pubkey()) new_cred.encode() new_cred.sign() return new_cred.save_to_string() if __name__ == "__main__": key_file = "server.key" cert_file = "server.cert" # if no key is specified, then make one up if (not os.path.exists(key_file)) or (not os.path.exists(cert_file)): key = Keypair(create=True) key.save_to_file(key_file) cert = Certificate(subject="registry") cert.set_issuer(key=key, subject="registry") cert.set_pubkey(key) cert.sign() cert.save_to_file(cert_file) s = Registry("localhost", 12345, key_file, cert_file) s.run()