group db-related stuff in sfa/storage
[sfa.git] / sfa / server / sfa-ca.py
index aac0208..b87e119 100755 (executable)
@@ -1,17 +1,33 @@
 #!/usr/bin/python
 
 #
-# SFA Certificate Signing and management 
-#   
+# SFA Certificate Signing and management. Root authorities can use this script 
+# to sign  the certificate of another authority and become its parent. Sub 
+# authorities (authorities that have had their cert signed by another authority) 
+# can use this script to update their registry hierarchy with the new cert    
+# 
+# Example usage: 
+#
+## sign a peer cert
+# sfa-ca.py --sign PEER_CERT_FILENAME -o OUTPUT_FILENAME 
+#
+## import a cert and update the registry hierarchy
+# sfa-ca.py --import CERT_FILENAME   
+#
+## display a cert
+# sfa-ca.py --display CERT_FILENAME
+
 
 import os
 import sys
 from optparse import OptionParser
-from sfa.trust.certificate import Keypair, Certificate
+
+from sfa.util.config import Config
+
 from sfa.trust.gid import GID, create_uuid
 from sfa.trust.hierarchy import Hierarchy
-from sfa.util.config import Config
-from collections import defaultdict
+
+from sfa.storage.table import SfaTable
 
 def main():
     args = sys.argv
@@ -29,10 +45,12 @@ def main():
                       help="gid file to import into the registry")
     parser.add_option("-e", "--export", dest="export", 
                       help="name of gid to export from registry")
+    parser.add_option("-t", "--type", dest="type",
+                      help="record type", default=None)
     parser.add_option("-o", "--outfile", dest="outfile",
                       help="where to write the exprted gid") 
-    parser.add_option("-v", "--verbose", dest="verobse"
-                      help="be verbose")           
+    parser.add_option("-v", "--verbose", dest="verbose", default=False
+                      action="store_true", help="be verbose")           
                 
     (options, args) = parser.parse_args()
 
@@ -61,13 +79,6 @@ def display(options):
     gid = GID(filename=gidfile)
     gid.dump(dump_parents=True)
 
-def sign_gid(gid, parent_key, parent_gid):
-    gid.set_issuer(parent_key, parent_gid.get_hrn())
-    gid.set_parent(parent_gid)
-    gid.sign()
-    gid.save_to_file(outfile, save_parents=True)
-    return gid 
-
 def sign(options):
     """
     Sign the specified gid
@@ -75,7 +86,7 @@ def sign(options):
     hierarchy = Hierarchy()
     config = Config()
     default_authority = config.SFA_INTERFACE_HRN
-    auth_info = hierarchy.get_auth_info(parent_hrn)
+    auth_info = hierarchy.get_auth_info(default_authority)
 
     # load the gid
     gidfile = os.path.abspath(options.sign)
@@ -84,45 +95,37 @@ def sign(options):
         sys.exit(1)
     gid = GID(filename=gidfile)
 
-    # load the parent private info
-    authority = options.authority    
-    # if no pkey was specified, then use the this authority's key
-    if not authority:
-        authority = default_authority 
-    
-    if not hierarchy.auth_exists(authority):
-        print "no such authority: %s" % authority    
-
-    # load the parent gid and key 
-    auth_info = hierarchy.get_auth_info(authority)
-    pkeyfile = auth_info.privkey_filename
-    parent_key = Keypair(filename=pkeyfile)
-    parent_gid = auth_info.gid_object
+    # 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())
    
-    # check if gid already has a parent
-    # sign the gid
-    sign_gid(gid, parent_key, parent_gid)
+    # save the signed gid
+    if options.verbose:
+        print "Writing signed gid %s" % outfile  
+    gid.save_to_file(outfile, save_parents=True)
     
 
 def export_gid(options):
-    from sfa.util.table import SfaTable
     # lookup the record for the specified hrn 
     hrn = options.export
-
-    # check sfa table first    
+    type = options.type
+    # check sfa table first
+    filter = {'hrn': hrn}
+    if type:
+        filter['type'] = type                    
     table = SfaTable()
-    records = table.find({'hrn': hrn, type: 'authority'})
+    records = table.find(filter)
     if not records:
         # check the authorities hierarchy 
         hierarchy = Hierarchy()
         try:
-            auth_info = hierarchy.get_auth_info()
+            auth_info = hierarchy.get_auth_info(hrn)
             gid = auth_info.gid_object 
         except:
             print "Record: %s not found" % hrn
@@ -137,6 +140,8 @@ def export_gid(options):
         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 import_gid(options):
@@ -144,8 +149,6 @@ 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):
@@ -163,57 +166,25 @@ def import_gid(options):
     table = SfaTable()
     records = table.find({'hrn': gid.get_hrn(), 'type': 'authority'})
     if not records:
-        print "%s not found in record database" % get.get_hrn()  
+        print "%s not found in record database" % gid.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)
 
-    # re-sign all existing gids signed by this authority  
-    # create a dictionary of records keyed on the record's authority
-    record_dict = defaultdict(list)
-    # only get regords that belong to this authority 
-    # or any of its sub authorities   
-    all_records = table.find({'hrn': '%s*' % gid.get_hrn()})
-    for record in records:
-        record_dict[record['authority']].append(record) 
-
-    # start with the authority we just imported       
-    authorities = [gid.get_hrn()]
-    while authorities:
-        next_authorities = []
-        for authority in authorities:
-            # create a new signed gid for each record at this authority 
-            # and update the registry
-            auth_info = hierarchy.get_auth_info(authority)
-            records = record_dict[authority]
-            for record in records:
-                record_gid = GID(string=record['gid'])
-                parent_pkey = Keypair(filename=auth_info.privkey_filename)
-                parent_gid = GID(filename=auth_info.gid_filename)
-                signed_gid = sign_gid(record_gid, parent_pkey, parent_gid)
-                record['gid'] = signed_gid.save_to_string(save_parents=True)
-                table.update(record)
-                
-                # if this is an authority then update the hierarchy
-                if record['type'] == 'authority':
-                    record_info = hierarchy.get_auth_info(record['hrn'])
-                    signed_gid.save_to_file(filename=record_info.gid_filename, save_parents=True)
-
-             # update list of next authorities
-            tmp_authorities = set([record['hrn'] for record in records \
-                                   if record['type'] == 'authority'])
-            next_authorities.extend(tmp_authorities)
-
-        # move on to next set of authorities
-        authorities = next_authorities     
+    # ending here
+    return
 
 if __name__ == '__main__':
     main()