2864751fcb21834218918c84cc8dbf511aa599da
[sfa.git] / sfa / server / sfa-ca.py
1 #!/usr/bin/python
2
3 #
4 # SFA Certificate Signing and management. Root authorities can use this script 
5 # to sign  the certificate of another authority and become its parent. Sub 
6 # authorities (authorities that have had their cert signed by another authority) 
7 # can use this script to update their registry hierarchy with the new cert    
8
9 # Example usage: 
10 #
11 ## sign a peer cert
12 # sfa-ca.py --sign PEER_CERT_FILENAME -o OUTPUT_FILENAME 
13 #
14 ## import a cert and update the registry hierarchy
15 # sfa-ca.py --import CERT_FILENAME   
16 #
17 ## display a cert
18 # sfa-ca.py --display CERT_FILENAME
19
20
21 import os
22 import sys
23 from optparse import OptionParser
24
25 from sfa.util.config import Config
26
27 from sfa.trust.gid import GID, create_uuid
28 from sfa.trust.hierarchy import Hierarchy
29
30 from sfa.storage.alchemy import dbsession
31 from sfa.storage.persistentobjs import RegRecord
32
33 def main():
34     args = sys.argv
35     script_name = args[0]
36     parser = OptionParser(usage="%(script_name)s [options]" % locals())
37     parser.add_option("-d", "--display", dest="display", default=None,
38                       help="print contents of specified gid")           
39     parser.add_option("-s", "--sign", dest="sign", default=None, 
40                       help="gid to sign" )
41     parser.add_option("-k", "--key", dest="key", default=None, 
42                       help="keyfile to use for signing")
43     parser.add_option("-a", "--authority", dest="authority", default=None, 
44                       help="sign the gid using the specified authority ")
45     parser.add_option("-i", "--import", dest="importgid", default=None,
46                       help="gid file to import into the registry")
47     parser.add_option("-e", "--export", dest="export", 
48                       help="name of gid to export from registry")
49     parser.add_option("-t", "--type", dest="type",
50                       help="record type", default=None)
51     parser.add_option("-o", "--outfile", dest="outfile",
52                       help="where to write the exprted gid") 
53     parser.add_option("-v", "--verbose", dest="verbose", default=False, 
54                       action="store_true", help="be verbose")           
55                 
56     (options, args) = parser.parse_args()
57
58
59     if options.display:
60         display(options)
61     elif options.sign:
62         sign(options)
63     elif options.importgid:
64         import_gid(options) 
65     elif options.export:
66         export_gid(options)  
67     else:
68         parser.print_help()
69         sys.exit(1)        
70
71
72 def display(options):
73     """
74     Display the sepcified GID
75     """
76     gidfile = os.path.abspath(options.display)
77     if not gidfile or not os.path.isfile(gidfile):
78         print "No such gid: %s" % gidfile
79         sys.exit(1)
80     gid = GID(filename=gidfile)
81     gid.dump(dump_parents=True)
82
83 def sign(options):
84     """
85     Sign the specified gid
86     """
87     hierarchy = Hierarchy()
88     config = Config()
89     default_authority = config.SFA_INTERFACE_HRN
90     auth_info = hierarchy.get_auth_info(default_authority)
91
92     # load the gid
93     gidfile = os.path.abspath(options.sign)
94     if not os.path.isfile(gidfile):
95         print "no such gid: %s" % gidfile
96         sys.exit(1)
97     gid = GID(filename=gidfile)
98
99     # extract pub_key and create new gid
100     pkey = gid.get_pubkey()
101     urn = gid.get_urn()
102     gid = hierarchy.create_gid(urn, create_uuid(), pkey)
103
104     # get the outfile
105     outfile = options.outfile
106     if not outfile:
107         outfile = os.path.abspath('./signed-%s.gid' % gid.get_hrn())
108    
109     # save the signed gid
110     if options.verbose:
111         print "Writing signed gid %s" % outfile  
112     gid.save_to_file(outfile, save_parents=True)
113     
114
115 def export_gid(options):
116     # lookup the record for the specified hrn 
117     hrn = options.export
118     type = options.type
119     # check sfa table first
120     request=dbsession.query(RegRecord).filter_by(hrn=hrn)
121     if type: request = request.filter_by(type=type)
122     record=request.first()
123     if not record:
124         # check the authorities hierarchy 
125         hierarchy = Hierarchy()
126         try:
127             auth_info = hierarchy.get_auth_info(hrn)
128             gid = auth_info.gid_object 
129         except:
130             print "Record: %s not found" % hrn
131             sys.exit(1)
132     else:
133         gid = GID(string=record.gid)
134         
135     # get the outfile
136     outfile = options.outfile
137     if not outfile:
138         outfile = os.path.abspath('./%s.gid' % gid.get_hrn())
139
140     # save it
141     if options.verbose:
142         print "Writing %s gid to %s" % (gid.get_hrn(), outfile)
143     gid.save_to_file(outfile, save_parents=True)
144
145 def import_gid(options):
146     """
147     Import the specified gid into the registry (db and authorities 
148     hierarchy) overwriting any previous gid.
149     """
150     # load the gid
151     gidfile = os.path.abspath(options.importgid)
152     if not gidfile or not os.path.isfile(gidfile):
153         print "No such gid: %s" % gidfile
154         sys.exit(1)
155     gid = GID(filename=gidfile)
156     
157     # check if it exists within the hierarchy
158     hierarchy = Hierarchy()
159     if not hierarchy.auth_exists(gid.get_hrn()):
160         print "%s not found in hierarchy" % gid.get_hrn()
161         sys.exit(1)
162
163     # check if record exists in db
164     record = dbsession.query(RegRecord).filter_by(type='authority',hrn=gid.get_hrn()).first()
165     if not record:
166         print "%s not found in record database" % gid.get_hrn()  
167         sys.exit(1)
168
169     # update the database record
170     record.gid = gid.save_to_string(save_parents=True)
171     dbsession.commit()
172     if options.verbose:
173         print "Imported %s gid into db" % record['hrn']
174
175     # update the hierarchy
176     auth_info = hierarchy.get_auth_info(gid.get_hrn())  
177     filename = auth_info.gid_filename
178     gid.save_to_file(filename, save_parents=True)
179     if options.verbose:
180         print "Writing %s gid to %s" % (gid.get_hrn(), filename)
181
182     # ending here
183     return
184
185 if __name__ == '__main__':
186     main()