merge master again (2.0-10 changelog only)
[sfa.git] / sfa / server / sfa-ca.py
index 84b7ea3..9ab75e7 100755 (executable)
@@ -1,16 +1,34 @@
 #!/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 sfa.storage.alchemy import dbsession
+from sfa.storage.model import RegRecord
 
 def main():
     args = sys.argv
@@ -22,14 +40,18 @@ def main():
                       help="gid to sign" )
     parser.add_option("-k", "--key", dest="key", default=None, 
                       help="keyfile to use for signing")
+    parser.add_option("-a", "--authority", dest="authority", default=None, 
+                      help="sign the gid using the specified authority ")
     parser.add_option("-i", "--import", dest="importgid", default=None,
                       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()
 
@@ -48,20 +70,24 @@ def main():
 
 
 def display(options):
+    """
+    Display the sepcified GID
+    """
     gidfile = os.path.abspath(options.display)
-    print gidfile
     if not gidfile or not os.path.isfile(gidfile):
         print "No such gid: %s" % gidfile
-        sys.exit(1) 
+        sys.exit(1)
     gid = GID(filename=gidfile)
     gid.dump(dump_parents=True)
 
 def sign(options):
-    from sfa.util.table import SfaTable
+    """
+    Sign the specified gid
+    """
     hierarchy = Hierarchy()
     config = Config()
-    parent_hrn = config.SFA_INTERFACE_HRN
-    auth_info = hierarchy.get_auth_info(parent_hrn)
+    default_authority = config.SFA_INTERFACE_HRN
+    auth_info = hierarchy.get_auth_info(default_authority)
 
     # load the gid
     gidfile = os.path.abspath(options.sign)
@@ -70,40 +96,91 @@ def sign(options):
         sys.exit(1)
     gid = GID(filename=gidfile)
 
-    # load the parent private key
-    pkeyfile = options.key
-    # if no pkey was specified, then use the this authority's key
-    if not pkeyfile:
-        pkeyfile = auth_info.privkey_filename
-    if not os.path.isfile(pkeyfile):
-        print "no such pkey: %s.\nPlease specify a valid private key" % pkeyfile
-        sys.exit(1)
-    parent_key = Keypair(filename=pkeyfile)
-
-    # load the parent gid
-    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
-    gid.set_issuer(parent_key, parent_hrn)
-    gid.set_parent(parent_gid)
-    gid.sign()
-    gid.save_to_file(outfile, save_parents=True)            
+    # save the signed gid
+    if options.verbose:
+        print "Writing signed gid %s" % outfile  
+    gid.save_to_file(outfile, save_parents=True)
     
 
-def export(options):
-    from sfa.util.table import SfaTable
-    pass
+def export_gid(options):
+    # lookup the record for the specified hrn 
+    hrn = options.export
+    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:
+            auth_info = hierarchy.get_auth_info(hrn)
+            gid = auth_info.gid_object 
+        except:
+            print "Record: %s not found" % hrn
+            sys.exit(1)
+    else:
+        gid = GID(string=record.gid)
+        
+    # get the outfile
+    outfile = options.outfile
+    if not outfile:
+        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):
-    from sfa.util.table import SfaTable
-    pass
+    """
+    Import the specified gid into the registry (db and authorities 
+    hierarchy) overwriting any previous gid.
+    """
+    # load the gid
+    gidfile = os.path.abspath(options.importgid)
+    if not gidfile or not os.path.isfile(gidfile):
+        print "No such gid: %s" % gidfile
+        sys.exit(1)
+    gid = GID(filename=gidfile)
+    
+    # check if it exists within the hierarchy
+    hierarchy = Hierarchy()
+    if not hierarchy.auth_exists(gid.get_hrn()):
+        print "%s not found in hierarchy" % gid.get_hrn()
+        sys.exit(1)
+
+    # check if record exists in db
+    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
+    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)
+    if options.verbose:
+        print "Writing %s gid to %s" % (gid.get_hrn(), filename)
+
+    # ending here
+    return
 
 if __name__ == '__main__':
     main()