updated to trunk -r 17901:17994
authorJosh Karlin <jkarlin@bbn.com>
Tue, 11 May 2010 16:49:18 +0000 (16:49 +0000)
committerJosh Karlin <jkarlin@bbn.com>
Tue, 11 May 2010 16:49:18 +0000 (16:49 +0000)
19 files changed:
config/default_config.xml
config/sfa-config-tty
setup.py
sfa.spec
sfa/client/sfi.py
sfa/managers/component_manager_default.py
sfa/managers/component_manager_pl.py
sfa/managers/registry_manager_pl.py
sfa/plc/sfa-import-plc.py
sfa/plc/sfaImport.py
sfa/server/aggregate.py
sfa/server/interface.py
sfa/server/registry.py
sfa/server/sfa-ca.py [new file with mode: 0755]
sfa/server/sfa-server.py
sfa/trust/certificate.py
sfa/trust/gid.py
sfa/util/record.py
sfa/util/table.py

index a63b56b..37cd6cc 100644 (file)
@@ -76,14 +76,7 @@ $URL$
          <description>The hrn of the registry's root auth.</description>
        </variable>
 
-       <variable id="level1_auth" type="string">
-         <name>Level1 Authority</name>
-         <value></value>
-         <description>The hrn of the registry's level1 auth (sub
-         authority). The full name of this interface (only secify if
-         this interface is a sub authority).</description>
-       </variable>
-      </variablelist>
+    </variablelist>
     </category>
 
     <!-- ======================================== -->
index ed77fb1..9b2c439 100755 (executable)
@@ -15,7 +15,6 @@ def validator(validated_variables):
 usual_variables = [
     "SFA_INTERFACE_HRN",
     "SFA_REGISTRY_ROOT_AUTH",
-    "SFA_REGISTRY_LEVEL1_AUTH",
     "SFA_REGISTRY_HOST", 
     "SFA_AGGREGATE_HOST",
     "SFA_SM_HOST",
index 8d77792..e3d6f02 100755 (executable)
--- a/setup.py
+++ b/setup.py
@@ -14,6 +14,7 @@ bins = [
     'config/gen-sfa-cm-config.py',
     'sfa/plc/sfa-import-plc.py', 
     'sfa/plc/sfa-nuke-plc.py', 
+    'sfa/server/sfa-ca.py', 
     'sfa/server/sfa-server.py', 
     'sfa/server/sfa-clean-peer-records.py', 
     'sfa/server/sfa_component_setup.py', 
index 2e32acb..88e7883 100644 (file)
--- a/sfa.spec
+++ b/sfa.spec
@@ -34,6 +34,7 @@ Requires: libxslt-python
 Requires: python-ZSI
 # xmlbuilder depends on  lxml
 Requires: python-lxml
+Requires: python-setuptools
 
 # python 2.5 has uuid module added, for python 2.4 we still need it.
 # we can't really check for if we can load uuid as a python module,
index 5b79247..a27c3ff 100755 (executable)
@@ -9,6 +9,8 @@ import tempfile
 import traceback
 import socket
 import random
+from lxml import etree
+from StringIO import StringIO
 from types import StringTypes, ListType
 from optparse import OptionParser
 from sfa.trust.certificate import Keypair, Certificate
@@ -16,36 +18,25 @@ from sfa.trust.credential import Credential
 from sfa.util.sfaticket import SfaTicket
 from sfa.util.record import *
 from sfa.util.namespace import *
-from sfa.util.rspec import RSpec
 from sfa.util.xmlrpcprotocol import ServerException
 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
 from sfa.util.config import Config
 import zlib
 
+
 # utility methods here
 # display methods
 def display_rspec(rspec, format='rspec'):
     if format in ['dns']:
-        spec = RSpec()
-        spec.parseString(rspec)
-        hostnames = []
-        nodespecs = spec.getDictsByTagName('NodeSpec')
-        for nodespec in nodespecs:
-            if nodespec.has_key('name') and nodespec['name']:
-                if isinstance(nodespec['name'], ListType):
-                    hostnames.extend(nodespec['name'])
-                elif isinstance(nodespec['name'], StringTypes):
-                     hostnames.append(nodespec['name'])
-        result = hostnames
+        tree = etree.parse(StringIO(rspec))
+        root = tree.getroot()
+        result = root.xpath("./network/site/node/hostname/text()")
     elif format in ['ip']:
-        spec = RSpec()
-        spec.parseString(rspec)
-        ips = []
-        ifspecs = spec.getDictsByTagName('IfSpec')
-        for ifspec in ifspecs:
-            if ifspec.has_key('addr') and ifspec['addr']:
-                ips.append(ifspec['addr'])
-        result = ips
+        # The IP address is not yet part of the new RSpec
+        # so this doesn't do anything yet.
+        tree = etree.parse(StringIO(rspec))
+        root = tree.getroot()
+        result = root.xpath("./network/site/node/ipv4/text()")
     else:
         result = rspec
 
@@ -867,11 +858,10 @@ class Sfi:
         user_cred = self.get_user_cred()
         slice_cred = self.get_slice_cred(slice_hrn).save_to_string(save_parents=True)
         
-        # get a list node hostnames from the nodespecs in the rspec 
-        rspec = RSpec()
-        rspec.parseString(ticket.rspec)
-        nodespecs = rspec.getDictsByTagName('NodeSpec')
-        hostnames = [nodespec['name'] for nodespec in nodespecs]
+        # get a list of node hostnames from the RSpec 
+        tree = etree.parse(StringIO(ticket.rspec))
+        root = tree.getroot()
+        hostnames = root.xpath("./network/site/node/hostname/text()")
         
         # create an xmlrpc connection to the component manager at each of these
         # components and gall redeem_ticket
index 800857c..e6482d4 100644 (file)
@@ -14,7 +14,7 @@ def reset_slice(api, slicename):
 def get_slices(api):
     return 
 
-def roboot():
+def reboot():
     return
 
 def redeem_ticket(api, ticket_string):
index 2f79558..e9643ea 100644 (file)
@@ -46,7 +46,7 @@ def get_slices(api):
     slices = eval(xids[1])
     return slices.keys()
 
-def roboot():
+def reboot():
     os.system("/sbin/reboot")        
 
 def redeem_ticket(api, ticket_string):
index 8a97a3f..50776c0 100644 (file)
@@ -157,7 +157,7 @@ def list(api, xrn, origin_hrn=None):
     tree = prefixTree()
     tree.load(registry_hrns)
     registry_hrn = tree.best_match(hrn)
-    
+   
     #if there was no match then this record belongs to an unknow registry
     if not registry_hrn:
         raise MissingAuthority(xrn)
index 46593c7..39cb28c 100755 (executable)
@@ -74,7 +74,7 @@ def main():
     if not config.SFA_REGISTRY_ENABLED:
         sys.exit(0)
     root_auth = config.SFA_REGISTRY_ROOT_AUTH
-    level1_auth = config.SFA_REGISTRY_LEVEL1_AUTH
+    interface_hrn = config.SFA_INTERFACE_HRN
     keys_filename = config.config_path + os.sep + 'person_keys.py' 
     sfaImporter = sfaImport(logger)
     shell = sfaImporter.shell
@@ -86,27 +86,20 @@ def main():
     if not table.exists():
        table.create()
 
-    if not level1_auth or level1_auth in ['']:
-        level1_auth = None
-    
-    if not level1_auth:
-        sfaImporter.create_top_level_auth_records(root_auth)
-        import_auth = root_auth
-    else:
-        if not AuthHierarchy.auth_exists(level1_auth):
-            AuthHierarchy.create_auth(hrn_to_urn(level1_auth,'authority'))
-        sfaImporter.create_top_level_auth_records(level1_auth)
-        import_auth = level1_auth
+    # create root authority 
+    sfaImporter.create_top_level_auth_records(root_auth)
+    if not root_auth == interface_hrn:
+        sfaImporter.create_top_level_auth_records(interface_hrn)
 
-    trace("Import: adding " + import_auth + " to trusted list", logger)
-    authority = AuthHierarchy.get_auth_info(import_auth)
+    trace("Import: adding " + interface_hrn + " to trusted list", logger)
+    authority = AuthHierarchy.get_auth_info(interface_hrn)
     TrustedRoots.add_gid(authority.get_gid_object())
 
-    if ".vini" in import_auth and import_auth.endswith('vini'):
+    if ".vini" in interface_hrn and interface_hrn.endswith('vini'):
         # create a fake internet2 site first
         i2site = {'name': 'Internet2', 'abbreviated_name': 'I2',
                     'login_base': 'internet2', 'site_id': -1}
-        sfaImporter.import_site(import_auth, i2site)
+        sfaImporter.import_site(interface_hrn, i2site)
    
     # create dict of all existing sfa records
     existing_records = {}
@@ -158,21 +151,21 @@ def main():
         slices_dict[slice['slice_id']] = slice
     # start importing 
     for site in sites:
-        site_hrn = import_auth + "." + site['login_base']
+        site_hrn = interface_hrn + "." + site['login_base']
         print "Importing site: %s" % site_hrn
 
         # import if hrn is not in list of existing hrns or if the hrn exists
         # but its not a site record
         if site_hrn not in existing_hrns or \
            (site_hrn, 'authority') not in existing_records:
-            site_hrn = sfaImporter.import_site(import_auth, site)
+            site_hrn = sfaImporter.import_site(interface_hrn, site)
              
         # import node records
         for node_id in site['node_ids']:
             if node_id not in nodes_dict:
                 continue 
             node = nodes_dict[node_id]
-            hrn =  hostname_to_hrn(import_auth, site['login_base'], node['hostname'])
+            hrn =  hostname_to_hrn(interface_hrn, site['login_base'], node['hostname'])
             if hrn not in existing_hrns or \
                (hrn, 'node') not in existing_records:
                 sfaImporter.import_node(site_hrn, node)
@@ -182,7 +175,7 @@ def main():
             if slice_id not in slices_dict:
                 continue 
             slice = slices_dict[slice_id]
-            hrn = slicename_to_hrn(import_auth, slice['name'])
+            hrn = slicename_to_hrn(interface_hrn, slice['name'])
             if hrn not in existing_hrns or \
                (hrn, 'slice') not in existing_records:
                 sfaImporter.import_slice(site_hrn, slice)      
@@ -212,11 +205,13 @@ def main():
     for (record_hrn, type) in existing_records.keys():
         record = existing_records[(record_hrn, type)]
         # if this is the interface name dont do anything
-        if record_hrn == import_auth or record['peer_authority']:
+        if record_hrn == interface_hrn or \
+           record_hrn == root_auth or \
+           record['peer_authority']:
             continue
         # dont delete vini's internet2 placeholdder record
         # normally this would be deleted becuase it does not have a plc record 
-        if ".vini" in import_auth and import_auth.endswith('vini') and \
+        if ".vini" in interface_hrn and interface_hrn.endswith('vini') and \
            record_hrn.endswith("internet2"):     
             continue
 
@@ -224,7 +219,7 @@ def main():
         
         if type == 'authority':    
             for site in sites:
-                site_hrn = import_auth + "." + site['login_base']
+                site_hrn = interface_hrn + "." + site['login_base']
                 if site_hrn == record_hrn and site['site_id'] == record['pointer']:
                     found = True
                     break
index bf68b6c..84c00c7 100644 (file)
@@ -56,9 +56,6 @@ class sfaImport:
         self.TrustedRoots = TrustedRootList(Config.get_trustedroots_dir(self.config))
         self.plc_auth = self.config.get_plc_auth()
         self.root_auth = self.config.SFA_REGISTRY_ROOT_AUTH
-        self.level1_auth = self.config.SFA_REGISTRY_LEVEL1_AUTH
-        if not self.level1_auth or self.level1_auth in ['']:
-            self.level1_auth = None
         
         # connect to planetlab
         self.shell = None
@@ -71,25 +68,18 @@ class sfaImport:
 
 
     def create_top_level_auth_records(self, hrn):
+        # create the authority if it doesnt already exist 
         AuthHierarchy = self.AuthHierarchy
         urn = hrn_to_urn(hrn, 'authority')
-        # if auth records for this hrn dont exist, create it
         if not AuthHierarchy.auth_exists(urn):
             trace("Import: creating top level authorites", self.logger)
             AuthHierarchy.create_auth(urn)
-        
-
-        # get the auth info of the newly created root auth (parent)
-        # or level1_auth if it exists
-        if self.level1_auth:
-            auth_info = AuthHierarchy.get_auth_info(hrn)
+        parent_hrn = get_authority(hrn)
+        if not parent_hrn:
             parent_hrn = hrn
-        else:
-            parent_hrn = get_authority(hrn)
-            if not parent_hrn:
-                parent_hrn = hrn
-            auth_info = AuthHierarchy.get_auth_info(parent_hrn)
-            
+        auth_info = AuthHierarchy.get_auth_info(parent_hrn)
+        
+        # create the db record if it doesnt already exist    
         table = SfaTable()
         auth_record = table.find({'type': 'authority', 'hrn': hrn})
 
index aecc3b6..515b9e9 100644 (file)
@@ -30,21 +30,13 @@ class Aggregates(Interfaces):
     default_dict = {'aggregates': {'aggregate': [Interfaces.default_fields]}}
  
     def __init__(self, api, conf_file = "/etc/sfa/aggregates.xml"):
-        Interfaces.__init__(self, api, conf_file, 'ma')
-
-    def get_connections(self, interfaces):
-        """
-        Get connection details for the trusted peer aggregates from file and 
-        create an connection to each. 
-        """
-        connections = Interfaces.get_connections(self, interfaces)
-
+        Interfaces.__init__(self, api, conf_file)
         # set up a connection to the local registry
         address = self.api.config.SFA_AGGREGATE_HOST
         port = self.api.config.SFA_AGGREGATE_PORT
         url = 'http://%(address)s:%(port)s' % locals()
         local_aggregate = {'hrn': self.api.hrn, 'addr': address, 'port': port}
-        self.interfaces.append(local_aggregate) 
-        connections[self.api.hrn] = xmlrpcprotocol.get_server(url, self.api.key_file, self.api.cert_file)
-        return connections
+        self.interfaces[self.api.hrn] = local_aggregate
 
+        # get connections
+        self.update(self.get_connections())
index b01c87e..bbcebb0 100644 (file)
@@ -3,13 +3,13 @@
 ### $URL: https://svn.planet-lab.org/svn/sfa/trunk/sfa/server/interface.py $
 #
 
-
 from sfa.util.faults import *
 from sfa.util.storage import *
 from sfa.util.namespace import *
 from sfa.trust.gid import GID
 from sfa.util.table import SfaTable
 from sfa.util.record import SfaRecord
+import traceback
 import sfa.util.xmlrpcprotocol as xmlrpcprotocol
 import sfa.util.soapprotocol as soapprotocol
 
@@ -46,10 +46,9 @@ class Interfaces(dict):
     # defined by the class 
     default_dict = {}
 
-    # allowed types
-    types = ['sa', 'ma']
+    types = ['authority']
 
-    def __init__(self, api, conf_file, type):
+    def __init__(self, api, conf_file, type='authority'):
         if type not in self.types:
             raise SfaInfaildArgument('Invalid type %s: must be in %s' % (type, self.types))    
         dict.__init__(self, {})
@@ -58,11 +57,13 @@ class Interfaces(dict):
         # load config file
         self.interface_info = XmlStorage(conf_file, self.default_dict)
         self.interface_info.load()
-        self.interfaces = self.interface_info.values()[0].values()[0]
-        if not isinstance(self.interfaces, list):
-            self.interfaces = [self.interfaces]
-        # get connections
-        self.update(self.get_connections(self.interfaces))
+        interfaces = self.interface_info.values()[0].values()[0]
+        if not isinstance(interfaces, list):
+            interfaces = [self.interfaces]
+        self.interfaces = {}
+        for interface in interfaces:
+            self.interfaces[interface['hrn']] = interface
+
 
     def sync_interfaces(self):
         """
@@ -75,62 +76,71 @@ class Interfaces(dict):
         # are any missing gids, request a new one from the peer registry.
         gids_current = self.api.auth.trusted_cert_list
         hrns_current = [gid.get_hrn() for gid in gids_current] 
-        hrns_expected = [interface['hrn'] for interface in self.interfaces] 
+        hrns_expected = self.interfaces.keys() 
         new_hrns = set(hrns_expected).difference(hrns_current)
-        self.get_peer_gids(new_hrns)
-
+        gids = self.get_peer_gids(new_hrns)
         # update the local db records for these registries
-        self.update_db_records(self.type)
+        self.update_db_records(self.type, gids)
         
     def get_peer_gids(self, new_hrns):
         """
         Install trusted gids from the specified interfaces.  
         """
+        peer_gids = []
         if not new_hrns:
-            return
+            return peer_gids
         trusted_certs_dir = self.api.config.get_trustedroots_dir()
         for new_hrn in new_hrns:
+            if not new_hrn:
+                continue
             # the gid for this interface should already be installed  
             if new_hrn == self.api.config.SFA_INTERFACE_HRN:
                 continue
             try:
                 # get gid from the registry
-                interface = self.get_connections(self.interfaces[new_hrn])[new_hrn]
+                interface_info =  self.interfaces[new_hrn]
+                interface = self[new_hrn]
                 trusted_gids = interface.get_trusted_certs()
-                # default message
-                message = "interface: %s\tunable to install trusted gid for %s" % \
-                           (self.api.interface, new_hrn) 
                 if trusted_gids:
                     # the gid we want shoudl be the first one in the list, 
                     # but lets make sure
                     for trusted_gid in trusted_gids:
+                        # default message
+                        message = "interface: %s\t" % (self.api.interface)
+                        message += "unable to install trusted gid for %s" % \
+                                   (new_hrn) 
                         gid = GID(string=trusted_gids[0])
+                        peer_gids.append(gid) 
                         if gid.get_hrn() == new_hrn:
                             gid_filename = os.path.join(trusted_certs_dir, '%s.gid' % new_hrn)
                             gid.save_to_file(gid_filename, save_parents=True)
                             message = "interface: %s\tinstalled trusted gid for %s" % \
                                 (self.api.interface, new_hrn)
-                # log the message
-                self.api.logger.info(message)
+                        # log the message
+                        self.api.logger.info(message)
             except:
                 message = "interface: %s\tunable to install trusted gid for %s" % \
                             (self.api.interface, new_hrn) 
                 self.api.logger.info(message)
+                traceback.print_exc()
         
         # reload the trusted certs list
         self.api.auth.load_trusted_certs()
+        return peer_gids
 
-    def update_db_records(self, type):
+    def update_db_records(self, type, gids):
         """
         Make sure there is a record in the local db for allowed registries
         defined in the config file (registries.xml). Removes old records from
         the db.         
         """
+        if not gids: 
+            return
         # get hrns we expect to find
         # ignore records for local interfaces
         ignore_interfaces = [self.api.config.SFA_INTERFACE_HRN]
-        hrns_expected = [interface['hrn'] for interface in self.interfaces \
-                         if interface['hrn'] not in ignore_interfaces]
+        hrns_expected = [gid.get_hrn() for gid in gids \
+                         if gid.get_hrn() not in ignore_interfaces]
 
         # get hrns that actually exist in the db
         table = SfaTable()
@@ -143,29 +153,27 @@ class Interfaces(dict):
                 table.remove(record)
 
         # add new records
-        for hrn in hrns_expected:
+        for gid in gids:
+            hrn = gid.get_hrn()
             if hrn not in hrns_found:
                 record = {
                     'hrn': hrn,
                     'type': type,
                     'pointer': -1, 
                     'authority': get_authority(hrn),
+                    'gid': gid.save_to_string(save_parents=True),
                 }
                 record = SfaRecord(dict=record)
                 table.insert(record)
                         
-    def get_connections(self, interfaces):
+    def get_connections(self):
         """
         read connection details for the trusted peer registries from file return 
         a dictionary of connections keyed on interface hrn. 
         """
         connections = {}
         required_fields = self.default_fields.keys()
-        if not isinstance(interfaces, list):
-            interfaces = [interfaces]
-
-        for interface in interfaces:
+        for interface in self.interfaces.values():
             # make sure the required fields are present and not null
             if not all([interface.get(key) for key in required_fields]):
                 continue
index 5658f37..0b92f76 100644 (file)
@@ -37,19 +37,12 @@ class Registries(Interfaces):
     default_dict = {'registries': {'registry': [Interfaces.default_fields]}}
 
     def __init__(self, api, conf_file = "/etc/sfa/registries.xml"):
-        Interfaces.__init__(self, api, conf_file, 'sa') 
-
-    def get_connections(self, interfaces):
-        """
-        read connection details for the trusted peer registries from file return 
-        a dictionary of connections keyed on interface hrn. 
-        """
-        connections = Interfaces.get_connections(self, interfaces)
-
-        # set up a connection to the local registry
+        Interfaces.__init__(self, api, conf_file) 
         address = self.api.config.SFA_REGISTRY_HOST
         port = self.api.config.SFA_REGISTRY_PORT
         url = 'http://%(address)s:%(port)s' % locals()
         local_registry = {'hrn': self.api.hrn, 'addr': address, 'port': port}
-        connections[self.api.hrn] = xmlrpcprotocol.get_server(url, self.api.key_file, self.api.cert_file)            
-        return connections 
+        self.interfaces[self.api.hrn] = local_registry
+       
+        # get connections
+        self.update(self.get_connections()) 
diff --git a/sfa/server/sfa-ca.py b/sfa/server/sfa-ca.py
new file mode 100755 (executable)
index 0000000..c76b985
--- /dev/null
@@ -0,0 +1,242 @@
+#!/usr/bin/python
+
+#
+# SFA Certificate Signing and management 
+#   
+
+import os
+import sys
+from optparse import OptionParser
+from sfa.trust.certificate import Keypair, Certificate
+from sfa.trust.gid import GID, create_uuid
+from sfa.trust.hierarchy import Hierarchy
+from sfa.util.config import Config
+from collections import defaultdict
+
+def main():
+    args = sys.argv
+    script_name = args[0]
+    parser = OptionParser(usage="%(script_name)s [options]" % locals())
+    parser.add_option("-d", "--display", dest="display", default=None,
+                      help="print contents of specified gid")           
+    parser.add_option("-s", "--sign", dest="sign", default=None, 
+                      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("-o", "--outfile", dest="outfile",
+                      help="where to write the exprted gid") 
+    parser.add_option("-v", "--verbose", dest="verbose", default=False, 
+                      action="store_true", help="be verbose")           
+                
+    (options, args) = parser.parse_args()
+
+
+    if options.display:
+        display(options)
+    elif options.sign:
+        sign(options)
+    elif options.importgid:
+        import_gid(options) 
+    elif options.export:
+        export_gid(options)  
+    else:
+        parser.print_help()
+        sys.exit(1)        
+
+
+def display(options):
+    """
+    Display the sepcified GID
+    """
+    gidfile = os.path.abspath(options.display)
+    if not gidfile or not os.path.isfile(gidfile):
+        print "No such gid: %s" % gidfile
+        sys.exit(1)
+    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
+    """
+    hierarchy = Hierarchy()
+    config = Config()
+    default_authority = config.SFA_INTERFACE_HRN
+    auth_info = hierarchy.get_auth_info(default_authority)
+
+    # load the gid
+    gidfile = os.path.abspath(options.sign)
+    if not os.path.isfile(gidfile):
+        print "no such gid: %s" % gidfile
+        sys.exit(1)
+    gid = GID(filename=gidfile)
+
+    # remove previous parent
+    gid = GID(string=gid.save_to_string(save_parents=False))
+
+    # 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
+
+    # 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
+    if options.verbose:
+        print "Signing %s gid with parent %s" % \
+              (gid.get_hrn(), parent_gid.get_hrn())
+    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    
+    table = SfaTable()
+    records = table.find({'hrn': hrn, type: 'authority'})
+    if not records:
+        # check the authorities hierarchy 
+        hierarchy = Hierarchy()
+        try:
+            auth_info = hierarchy.get_auth_info()
+            gid = auth_info.gid_object 
+        except:
+            print "Record: %s not found" % hrn
+            sys.exit(1)
+    else:
+        record = records[0]
+        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):
+    """
+    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):
+        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
+    table = SfaTable()
+    records = table.find({'hrn': gid.get_hrn(), 'type': 'authority'})
+    if not records:
+        print "%s not found in record database" % get.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   
+    child_records = table.find({'hrn': '%s*' % gid.get_hrn()})
+    if not child_records:
+        return
+  
+    for record in child_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)
+                if options.verbose:
+                    print "re-signing %s gid with parent %s" % \
+                           (record['hrn'], parent_gid.get_hrn())  
+                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'])
+                    if options.verbose:
+                        print "Writing %s gid to %s" % (record['hrn'], record_info.gid_filename) 
+                    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     
+
+if __name__ == '__main__':
+    main()
index db78d5c..06393ce 100755 (executable)
@@ -157,12 +157,12 @@ def init_server(options, config):
             manager.init_server()
             
 
-def sync_interfaces():
+def sync_interfaces(server_key_file, server_cert_file):
     """
     Attempt to install missing trusted gids and db records for 
     our federated interfaces
     """
-    api = SfaAPI()
+    api = SfaAPI(key_file = server_key_file, cert_file = server_cert_file)
     registries = Registries(api)
     aggregates = Aggregates(api)
     registries.sync_interfaces()
@@ -194,7 +194,6 @@ def main():
          help="Run as daemon.", default=False)
     (options, args) = parser.parse_args()
 
-    if (options.daemon):  daemon()
 
     config = Config()
     hierarchy = Hierarchy()
@@ -203,8 +202,9 @@ def main():
 
     init_server_key(server_key_file, server_cert_file, config, hierarchy)
     init_server(options, config)
-    sync_interfaces()   
+    sync_interfaces(server_key_file, server_cert_file)   
  
+    if (options.daemon):  daemon()
     # start registry server
     if (options.registry):
         from sfa.server.registry import Registry
index 441acae..b82e256 100644 (file)
@@ -361,7 +361,7 @@ class Certificate:
              self.issuerReq = req
        if cert:
           # if a cert was supplied, then get the subject from the cert
-          subject = cert.cert.get_issuer()
+          subject = cert.cert.get_subject()
        assert(subject)
        self.issuerSubject = subject
 
index e51b328..db2cb44 100644 (file)
@@ -163,7 +163,7 @@ class GID(Certificate):
 
         if self.parent and dump_parents:
             print " "*indent, "parent:"
-            self.parent.dump(indent+4)
+            self.parent.dump(indent+4, dump_parents)
 
     ##
     # Verify the chain of authenticity of the GID. First perform the checks
index f9eaa09..6af3119 100644 (file)
@@ -355,7 +355,7 @@ class UserRecord(SfaRecord):
         'first_name': Parameter(str, 'First name'),
         'last_name': Parameter(str, 'Last name'),
         'phone': Parameter(str, 'Phone Number'),
-        'key': Parameter(str, 'Public key'),
+        'keys': Parameter(str, 'Public key'),
         'slices': Parameter([str], 'List of slices this user belongs to'),
         }
     fields.update(SfaRecord.fields)
index 892b72c..6c68776 100644 (file)
@@ -88,16 +88,17 @@ class SfaTable(list):
         self.db.commit()
     
     def remove(self, record):
-        query_str = "DELETE FROM %s WHERE record_id = %s" % \
-                    (self.tablename, record['record_id']) 
-        self.db.do(query_str)
+        params = {'record_id': record['record_id']}
+        template = "DELETE FROM %s " % self.tablename
+        sql = template + "WHERE record_id = %(record_id)s"
+        self.db.do(sql, params)
         
         # if this is a site, remove all records where 'authority' == the 
         # site's hrn
         if record['type'] == 'authority':
-            sql = " DELETE FROM %s WHERE authority = %s" % \
-                    (self.tablename, record['hrn'])
-            self.db.do(sql)
+            params = {'authority': record['hrn']}
+            sql = template + "WHERE authority = %(authority)s"
+            self.db.do(sql, params)
         self.db.commit() 
 
     def insert(self, record):