added tickets
[sfa.git] / util / hierarchy.py
index f76f819..e83b4d4 100644 (file)
 import os
 import report
 from cert import *
+from credential import *
 from gid import *
 from misc import *
 from config import *
+from geniticket import *
 
 class AuthInfo():
     hrn = None
+    gid_object = None
     gid_filename = None
     privkey_filename = None
     dbinfo_filename = None
 
     def __init__(self, hrn, gid_filename, privkey_filename, dbinfo_filename):
         self.hrn = hrn
-        self.gid_filename = gid_filename
+        self.set_gid_filename(gid_filename)
         self.privkey_filename = privkey_filename
         self.dbinfo_filename = dbinfo_filename
 
+    def set_gid_filename(self, fn):
+        self.gid_filename = fn
+        self.gid_object = None
+
     def get_gid_object(self):
-        return GID(filename = self.gid_filename)
+        if not self.gid_object:
+            self.gid_object = GID(filename = self.gid_filename)
+        return self.gid_object
 
     def get_pkey_object(self):
         return Keypair(filename = self.privkey_filename)
@@ -39,10 +48,14 @@ class AuthInfo():
         dict = eval(f.read())\r
         f.close()\r
         return dict\r
+\r
+    def update_gid_object(self, gid):\r
+        gid.save_to_file(self.gid_filename)\r
+        self.gid_object = gid\r
 
 class Hierarchy():
     def __init__(self, basedir="."):
-        self.basedir = basedir
+        self.basedir = os.path.join(basedir, "authorities")
 
     def get_auth_filenames(self, hrn):
         leaf = get_leaf(hrn)
@@ -86,7 +99,7 @@ class Hierarchy():
         pkey.save_to_file(privkey_filename)
 
         gid = self.create_gid(hrn, create_uuid(), pkey)
-        gid.save_to_file(gid_filename)
+        gid.save_to_file(gid_filename, save_parents=True)
 
         # XXX TODO: think up a better way for the dbinfo to work
 
@@ -106,13 +119,18 @@ class Hierarchy():
 
         auth_info = AuthInfo(hrn, gid_filename, privkey_filename, dbinfo_filename)
 
+        # check the GID and see if it needs to be refreshed
+        gid = auth_info.get_gid_object()
+        gid_refreshed = self.refresh_gid(gid)
+        if gid != gid_refreshed:
+            auth_info.update_gid_object(gid_refreshed)
+
         return auth_info
 
     def create_gid(self, hrn, uuid, pkey):
-        parent_hrn = get_authority(hrn)
-
         gid = GID(subject=hrn, uuid=uuid, hrn=hrn)
 
+        parent_hrn = get_authority(hrn)
         if not parent_hrn:
             # if there is no parent hrn, then it must be self-signed. this
             # is where we terminate the recursion
@@ -146,3 +164,58 @@ class Hierarchy():
 
         return gid
 
+    def get_auth_cred(self, hrn):
+        auth_info = self.get_auth_info(hrn)
+        gid = auth_info.get_gid_object()
+
+        cred = Credential(subject=hrn)
+        cred.set_gid_caller(gid)
+        cred.set_gid_object(gid)
+        cred.set_privileges("authority")
+        cred.set_delegate(True)
+        cred.set_pubkey(auth_info.get_gid_object().get_pubkey())
+
+        parent_hrn = get_authority(hrn)
+        if not parent_hrn:
+            # if there is no parent hrn, then it must be self-signed. this
+            # is where we terminate the recursion
+            cred.set_issuer(auth_info.get_pkey_object(), hrn)
+        else:
+            # we need the parent's private key in order to sign this GID
+            parent_auth_info = self.get_auth_info(parent_hrn)
+            cred.set_issuer(parent_auth_info.get_pkey_object(), parent_auth_info.hrn)
+            cred.set_parent(self.get_auth_cred(parent_hrn))
+
+        cred.encode()
+        cred.sign()
+
+        return cred
+
+    # this looks almost the same as get_auth_cred, but works for tickets
+    # XXX does similarity imply there should be more code re-use?
+    def get_auth_ticket(self, hrn):
+        auth_info = self.get_auth_info(hrn)
+        gid = auth_info.get_gid_object()
+
+        ticket = Ticket(subject=hrn)
+        ticket.set_gid_caller(gid)
+        ticket.set_gid_object(gid)
+        ticket.set_delegate(True)
+        ticket.set_pubkey(auth_info.get_gid_object().get_pubkey())
+
+        parent_hrn = get_authority(hrn)
+        if not parent_hrn:
+            # if there is no parent hrn, then it must be self-signed. this
+            # is where we terminate the recursion
+            ticket.set_issuer(auth_info.get_pkey_object(), hrn)
+        else:
+            # we need the parent's private key in order to sign this GID
+            parent_auth_info = self.get_auth_info(parent_hrn)
+            ticket.set_issuer(parent_auth_info.get_pkey_object(), parent_auth_info.hrn)
+            ticket.set_parent(self.get_auth_cred(parent_hrn))
+
+        ticket.encode()
+        ticket.sign()
+
+        return ticket
+