working copy of registry
authorScott Baker <bakers@cs.arizona.edu>
Mon, 11 Aug 2008 22:15:16 +0000 (22:15 +0000)
committerScott Baker <bakers@cs.arizona.edu>
Mon, 11 Aug 2008 22:15:16 +0000 (22:15 +0000)
registry/registry.py [new file with mode: 0644]

diff --git a/registry/registry.py b/registry/registry.py
new file mode 100644 (file)
index 0000000..60a63cc
--- /dev/null
@@ -0,0 +1,295 @@
+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()
+