merge master again (2.0-10 changelog only)
[sfa.git] / sfa / server / sfa-ca.py
index 127a267..9ab75e7 100755 (executable)
@@ -1,17 +1,34 @@
 #!/usr/bin/python
 
 #
 #!/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
 
 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.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.alchemy import dbsession
+from sfa.storage.model import RegRecord
 
 def main():
     args = sys.argv
 
 def main():
     args = sys.argv
@@ -29,10 +46,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")
                       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("-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()
 
                 
     (options, args) = parser.parse_args()
 
@@ -61,12 +80,6 @@ def display(options):
     gid = GID(filename=gidfile)
     gid.dump(dump_parents=True)
 
     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()
-    return gid 
-
 def sign(options):
     """
     Sign the specified gid
 def sign(options):
     """
     Sign the specified gid
@@ -83,54 +96,41 @@ def sign(options):
         sys.exit(1)
     gid = GID(filename=gidfile)
 
         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())
    
 
     # 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
-    gid = sign_gid(gid, parent_key, parent_gid)
     # save the signed 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):
     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
     # lookup the record for the specified hrn 
     hrn = options.export
-
-    # check sfa table first    
-    table = SfaTable()
-    records = table.find({'hrn': hrn, type: 'authority'})
-    if not records:
+    type = options.type
+    # check sfa table first
+    request=dbsession.query(RegRecord).filter_by(hrn=hrn)
+    if type: request = request.filter_by(type=type)
+    record=request.first()
+    if not record:
         # check the authorities hierarchy 
         hierarchy = Hierarchy()
         try:
         # 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
             sys.exit(1)
     else:
             gid = auth_info.gid_object 
         except:
             print "Record: %s not found" % hrn
             sys.exit(1)
     else:
-        record = records[0]
-        gid = GID(string=record['gid'])
+        gid = GID(string=record.gid)
         
     # get the outfile
     outfile = options.outfile
         
     # get the outfile
     outfile = options.outfile
@@ -138,6 +138,8 @@ def export_gid(options):
         outfile = os.path.abspath('./%s.gid' % gid.get_hrn())
 
     # save it
         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):
     gid.save_to_file(outfile, save_parents=True)
 
 def import_gid(options):
@@ -145,8 +147,6 @@ def import_gid(options):
     Import the specified gid into the registry (db and authorities 
     hierarchy) overwriting any previous gid.
     """
     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):
     # load the gid
     gidfile = os.path.abspath(options.importgid)
     if not gidfile or not os.path.isfile(gidfile):
@@ -161,60 +161,26 @@ def import_gid(options):
         sys.exit(1)
 
     # check if record exists in db
         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()  
+    record = dbsession.query(RegRecord).filter_by(type='authority',hrn=gid.get_hrn()).first()
+    if not record:
+        print "%s not found in record database" % gid.get_hrn()  
         sys.exit(1)
 
     # update the database record
         sys.exit(1)
 
     # update the database record
-    record = records[0]
-    record['gid'] = gid.save_to_string(save_parents=True)
-    table.update(record)
+    record.gid = gid.save_to_string(save_parents=True)
+    dbsession.commit()
+    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)
 
     # 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()
 
 if __name__ == '__main__':
     main()