예제 #1
0
파일: registry.py 프로젝트: gnogueras/sfa
 def __init__(self, ip, port, key_file, cert_file):
     SfaServer.__init__(self, ip, port, key_file, cert_file, 'registry')
     sfa_config = Config()
     if Config().SFA_REGISTRY_ENABLED:
         from sfa.storage.alchemy import engine
         from sfa.storage.dbschema import DBSchema
         DBSchema().init_or_upgrade()
예제 #2
0
파일: server.py 프로젝트: planetlab/sfa
    def __init__(self, server_address, HandlerClass, key_file, cert_file, logRequests=True):
        """Secure XML-RPC server.

        It it very similar to SimpleXMLRPCServer but it uses HTTPS for transporting XML data.
        """
        logger.debug("SecureXMLRPCServer.__init__, server_address=%s, cert_file=%s"%(server_address,cert_file))
        self.logRequests = logRequests
        self.interface = None
        self.key_file = key_file
        self.cert_file = cert_file
        self.method_map = {}
        # add cache to the request handler
        HandlerClass.cache = Cache()
        #for compatibility with python 2.4 (centos53)
        if sys.version_info < (2, 5):
            SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self)
        else:
           SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self, True, None)
        SocketServer.BaseServer.__init__(self, server_address, HandlerClass)
        ctx = SSL.Context(SSL.SSLv23_METHOD)
        ctx.use_privatekey_file(key_file)        
        ctx.use_certificate_file(cert_file)
        # If you wanted to verify certs against known CAs.. this is how you would do it
        #ctx.load_verify_locations('/etc/sfa/trusted_roots/plc.gpo.gid')
        config = Config()
        trusted_cert_files = TrustedRoots(config.get_trustedroots_dir()).get_file_list()
        for cert_file in trusted_cert_files:
            ctx.load_verify_locations(cert_file)
        ctx.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT, verify_callback)
        ctx.set_verify_depth(5)
        ctx.set_app_data(self)
        self.socket = SSL.Connection(ctx, socket.socket(self.address_family,
                                                        self.socket_type))
        self.server_bind()
        self.server_activate()
예제 #3
0
파일: sfa-start.py 프로젝트: tubav/sfa
def main():
    # Generate command line parser
    parser = OptionParser(usage="sfa-start.py [options]")
    parser.add_option("-r", "--registry", dest="registry", action="store_true",
         help="run registry server", default=False)
    parser.add_option("-s", "--slicemgr", dest="sm", action="store_true",
         help="run slice manager", default=False)
    parser.add_option("-a", "--aggregate", dest="am", action="store_true",
         help="run aggregate manager", default=False)
    parser.add_option("-c", "--component", dest="cm", action="store_true",
         help="run component server", default=False)
    parser.add_option("-t", "--trusted-certs", dest="trusted_certs", action="store_true",
         help="refresh trusted certs", default=False)
    parser.add_option("-d", "--daemon", dest="daemon", action="store_true",
         help="Run as daemon.", default=False)
    (options, args) = parser.parse_args()
    
    config = Config()
    logger.setLevelFromOptVerbose(config.SFA_API_LOGLEVEL)
    

    # ge the server's key and cert
    hierarchy = Hierarchy()
    auth_info = hierarchy.get_interface_auth_info()
    server_key_file = auth_info.get_privkey_filename()
    server_cert_file = auth_info.get_gid_filename()

    # ensure interface cert is present in trusted roots dir
    trusted_roots = TrustedRoots(config.get_trustedroots_dir())
    trusted_roots.add_gid(GID(filename=server_cert_file))
    if (options.daemon):  daemon()
    
    if options.trusted_certs:
        install_peer_certs(server_key_file, server_cert_file)   
    
    # start registry server
    if (options.registry):
        from sfa.server.registry import Registry
        r = Registry("", config.SFA_REGISTRY_PORT, server_key_file, server_cert_file)
        r.start()

    if (options.am):
        from sfa.server.aggregate import Aggregate
        a = Aggregate("", config.SFA_AGGREGATE_PORT, server_key_file, server_cert_file)
        a.start()

    # start slice manager
    if (options.sm):
        from sfa.server.slicemgr import SliceMgr
        s = SliceMgr("", config.SFA_SM_PORT, server_key_file, server_cert_file)
        s.start()

    if (options.cm):
        from sfa.server.component import Component
        c = Component("", config.component_port, server_key_file, server_cert_file)
#        c = Component("", config.SFA_COMPONENT_PORT, server_key_file, server_cert_file)
        c.start()
예제 #4
0
def create_default_dirs():
    config = Config()
    hierarchy = Hierarchy()
    config_dir = config.config_path
    trusted_certs_dir = config.get_trustedroots_dir()
    authorities_dir = hierarchy.basedir
    all_dirs = [config_dir, trusted_certs_dir, authorities_dir]
    for dir in all_dirs:
        if not os.path.exists(dir):
            os.makedirs(dir)
예제 #5
0
def create_default_dirs():
    config = Config()
    hierarchy = Hierarchy()
    config_dir = config.config_path
    trusted_certs_dir = config.get_trustedroots_dir()
    authorities_dir = hierarchy.basedir
    all_dirs = [config_dir, trusted_certs_dir, authorities_dir]
    for dir in all_dirs:
        if not os.path.exists(dir):
            os.makedirs(dir)
예제 #6
0
def server_proxy(url=None,
                 port=None,
                 keyfile=None,
                 certfile=None,
                 verbose=False):
    """
    returns an xmlrpc connection to the service a the specified 
    address
    """
    if url:
        url_parts = url.split(":")
        if len(url_parts) > 1:
            pass
        else:
            url = "http://%(url)s:%(port)s" % locals()
    else:
        # connect to registry by default
        config = Config()
        addr, port = config.SFA_REGISTRY_HOST, config.SFA_REGISTRY_PORT
        url = "http://%(addr)s:%(port)s" % locals()

    if verbose:
        print "Contacting registry at: %(url)s" % locals()

    server = SfaServerProxy(url, keyfile, certfile)
    return server
예제 #7
0
 def get_rspec(self, api, cred, slice_urn):
     logger.debug("#### called max-get_rspec")
     #geni_slice_urn: urn:publicid:IDN+plc:maxpl+slice+xi_rspec_test1
     if slice_urn == None:
         (ret, output) = self.call_am_apiclient("GetResourceTopology",
                                                ['all', '\"\"'], 5)
     else:
         slice_id = self.get_plc_slice_id(cred, slice_urn)
         (ret, output) = self.call_am_apiclient("GetResourceTopology", [
             'all',
             slice_id,
         ], 5)
     # parse output into rspec XML
     if output.find("No resouce found") > 0:
         rspec = "<RSpec type=\"SFA\"> <Fault>No resource found</Fault> </RSpec>"
     else:
         comp_rspec = self.get_xml_by_tag(output, 'computeResource')
         logger.debug("#### computeResource %s" % comp_rspec)
         topo_rspec = self.get_xml_by_tag(output, 'topology')
         logger.debug("#### topology %s" % topo_rspec)
         rspec = "<RSpec type=\"SFA\"> <network name=\"" + Config(
         ).get_interface_hrn() + "\">"
         if comp_rspec != None:
             rspec = rspec + self.get_xml_by_tag(output, 'computeResource')
         if topo_rspec != None:
             rspec = rspec + self.get_xml_by_tag(output, 'topology')
         rspec = rspec + "</network> </RSpec>"
     return (rspec)
예제 #8
0
 def __init__(self, auth_hierarchy, logger):
     self.auth_hierarchy = auth_hierarchy
     self.logger = logger
     self.config = Config()
     self.interface_hrn = self.config.SFA_INTERFACE_HRN
     self.root_auth = self.config.SFA_REGISTRY_ROOT_AUTH
     self.shell = Shell(self.config)
예제 #9
0
파일: sfaImport.py 프로젝트: planetlab/sfa
 def __init__(self):
    self.logger = _SfaLogger(logfile='/var/log/sfa_import.log', loggername='importlog')
    self.AuthHierarchy = Hierarchy()
    self.config = Config()
    self.TrustedRoots = TrustedRoots(Config.get_trustedroots_dir(self.config))
    self.plc_auth = self.config.get_plc_auth()
    self.root_auth = self.config.SFA_REGISTRY_ROOT_AUTH
     
    # connect to planetlab
    self.shell = None
    if "Url" in self.plc_auth:
       from sfa.plc.remoteshell import RemoteShell
       self.shell = RemoteShell(self.logger)
    else:
       import PLC.Shell
       self.shell = PLC.Shell.Shell(globals = globals())        
예제 #10
0
    def __init__(self, srv):
        self.version_json_dict = {
            'api_version': None,
            'apilib_version': None,
            'api_timezone': None,
            'api_timestamp': None,
            'oar_version': None
        }
        self.config = Config()
        self.interface_hrn = self.config.SFA_INTERFACE_HRN
        self.timezone_json_dict = {
            'timezone': None,
            'api_timestamp': None,
        }
        #self.jobs_json_dict = {
        #'total' : None, 'links' : [],\
        #'offset':None , 'items' : [], }
        #self.jobs_table_json_dict = self.jobs_json_dict
        #self.jobs_details_json_dict = self.jobs_json_dict
        self.server = srv
        self.node_dictlist = {}

        self.json_page = JsonPage()
        self.parsing_resourcesfull = ParsingResourcesFull()
        self.site_dict = {}
        self.jobs_list = []
        self.SendRequest("GET_version")
예제 #11
0
def TestIotlabshell(param = None):

    config = Config()
    shell = IotlabShell(config)

    message_and_wait("\r\n \r\n GetReservedNodes")
    nodes = shell.GetReservedNodes()
    print nodes

    message_and_wait("\r\n GetPersons")
    persons = shell.GetPersons()
    print "\r\n \r\n  GetPersons", persons


    message_and_wait("\r\n GetLeases for the login avakian")
    leases = shell.GetLeases(login='******')
    print  leases

    message_and_wait("\r\n GetLeases for slice iotlab.avakian_slice")
    leases = shell.GetLeases(lease_filter_dict=
                        {'slice_hrn':'iotlab.avakian_slice'})
    print leases

    message_and_wait("\r\n GetLeases t_from 1405070000 ")
    leases = shell.GetLeases(lease_filter_dict={'t_from':1405070000})
    print leases
예제 #12
0
    def __init__(self,
                 server_address,
                 HandlerClass,
                 key_file,
                 cert_file,
                 logRequests=True):
        """Secure XML-RPC server.

        It it very similar to SimpleXMLRPCServer but it uses HTTPS for transporting XML data.
        """
        logger.debug(
            "SecureXMLRPCServer.__init__, server_address=%s, cert_file=%s, key_file=%s"
            % (server_address, cert_file, key_file))
        logger.debug("SecureXMLRPCServer HandlerClass=%s" % (HandlerClass))
        self.logRequests = logRequests
        self.interface = None
        self.key_file = key_file
        self.cert_file = cert_file
        self.method_map = {}
        # add cache to the request handler
        HandlerClass.cache = Cache()
        #for compatibility with python 2.4 (centos53)
        if sys.version_info < (2, 5):
            SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(self)
        else:
            SimpleXMLRPCServer.SimpleXMLRPCDispatcher.__init__(
                self, True, None)
        SocketServer.BaseServer.__init__(self, server_address, HandlerClass)
        ctx = SSL.Context(SSL.SSLv23_METHOD)
        ctx.use_privatekey_file(key_file)
        ctx.use_certificate_file(cert_file)
        # If you wanted to verify certs against known CAs.. this is how you would do it
        #ctx.load_verify_locations('/etc/sfa/trusted_roots/plc.gpo.gid')
        config = Config()
        trusted_cert_files = TrustedRoots(
            config.get_trustedroots_dir()).get_file_list()
        for cert_file in trusted_cert_files:
            ctx.load_verify_locations(cert_file)
        ctx.set_verify(SSL.VERIFY_PEER | SSL.VERIFY_FAIL_IF_NO_PEER_CERT,
                       verify_callback)
        ctx.set_verify_depth(5)
        ctx.set_app_data(self)
        self.socket = SSL.Connection(
            ctx, socket.socket(self.address_family, self.socket_type))
        self.server_bind()
        self.server_activate()
예제 #13
0
 def __init__(self, config=None):
     if not config:
         config = Config()
     opts = parse_novarc(config.SFA_NOVA_NOVARC)
     self.client = glance_client.get_client(host='0.0.0.0',
                                            username=opts.get('OS_USERNAME'),
                                            password=opts.get('OS_PASSWORD'),
                                            tenant=opts.get('OS_TENANT_NAME'),
                                            auth_url=opts.get('OS_AUTH_URL'))
예제 #14
0
파일: registry.py 프로젝트: gnogueras/sfa
 def __init__(self, conf_file="/etc/sfa/registries.xml"):
     Interfaces.__init__(self, conf_file)
     sfa_config = Config()
     if sfa_config.SFA_REGISTRY_ENABLED:
         addr = sfa_config.SFA_REGISTRY_HOST
         port = sfa_config.SFA_REGISTRY_PORT
         hrn = sfa_config.SFA_INTERFACE_HRN
         interface = Interface(hrn, addr, port)
         self[hrn] = interface
예제 #15
0
    def run(self, options):
        """
        Create the special iotlab table, lease_table, in the SFA database.
        Import everything (users, slices, nodes and sites from OAR
        and LDAP) into the SFA database.
        Delete stale records that are no longer in OAR or LDAP.
        :param options:
        :type options:
        """

        config = Config()
        interface_hrn = config.SFA_INTERFACE_HRN
        root_auth = config.SFA_REGISTRY_ROOT_AUTH

        testbed_shell = IotlabShell(config)
        # leases_db = TestbedAdditionalSfaDB(config)
        #Create special slice table for iotlab

        if not self.exists('lease_table'):
            init_tables(engine)
            self.logger.info("IotlabImporter.run:  lease_table table created ")

        # import site and node records in site into the SFA db.
        self.import_sites_and_nodes(testbed_shell)
        #import users and slice into the SFA DB.
        self.import_persons_and_slices(testbed_shell)

        ### remove stale records
        # special records must be preserved
        system_hrns = [
            interface_hrn, root_auth, interface_hrn + '.slicemanager'
        ]
        for record in self.all_records:
            if record.hrn in system_hrns:
                record.stale = False
            if record.peer_authority:
                record.stale = False

        for record in self.all_records:
            if record.type == 'user':
                self.logger.info("IotlabImporter: stale records: hrn %s %s" %
                                 (record.hrn, record.stale))
            try:
                stale = record.stale
            except:
                stale = True
                self.logger.warning("stale not found with %s" % record)
            if stale:
                self.logger.info("IotlabImporter: deleting stale record: %s" %
                                 (record))

                try:
                    global_dbsession.delete(record)
                    global_dbsession.commit()
                except SQLAlchemyError:
                    self.logger.log_exc("IotlabImporter: failed to delete \
                        stale record %s" % (record))
예제 #16
0
def get_trusted_certs(registry=None, verbose=False):
    """
    refresh our list of trusted certs.
    """
    # define useful variables
    config = Config()
    data_dir = config.SFA_DATA_DIR
    config_dir = config.SFA_CONFIG_DIR
    trusted_certs_dir = config.get_trustedroots_dir()
    keyfile = data_dir + os.sep + "server.key"
    certfile = data_dir + os.sep + "server.cert"
    node_gid_file = config_dir + os.sep + "node.gid"
    node_gid = GID(filename=node_gid_file)
    hrn = node_gid.get_hrn()
    # get credential
    cred = GetCredential(registry=registry, verbose=verbose)
    # make sure server key cert pair exists
    create_server_keypair(keyfile=keyfile,
                          certfile=certfile,
                          hrn=hrn,
                          verbose=verbose)
    registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
    # get the trusted certs and save them in the right place
    if verbose:
        print "Getting trusted certs from registry"
    trusted_certs = registry.get_trusted_certs(cred)
    trusted_gid_names = []
    for gid_str in trusted_certs:
        gid = GID(string=gid_str)
        gid.decode()
        relative_filename = gid.get_hrn() + ".gid"
        trusted_gid_names.append(relative_filename)
        gid_filename = trusted_certs_dir + os.sep + relative_filename
        if verbose:
            print "Writing GID for %s as %s" % (gid.get_hrn(), gid_filename)
        gid.save_to_file(gid_filename, save_parents=True)

    # remove old certs
    all_gids_names = os.listdir(trusted_certs_dir)
    for gid_name in all_gids_names:
        if gid_name not in trusted_gid_names:
            if verbose:
                print "Removing old gid ", gid_name
            os.unlink(trusted_certs_dir + os.sep + gid_name)
예제 #17
0
파일: aggregate.py 프로젝트: gnogueras/sfa
 def __init__(self, conf_file="/etc/sfa/aggregates.xml"):
     Interfaces.__init__(self, conf_file)
     sfa_config = Config()
     # set up a connection to the local aggregate
     if sfa_config.SFA_AGGREGATE_ENABLED:
         addr = sfa_config.SFA_AGGREGATE_HOST
         port = sfa_config.SFA_AGGREGATE_PORT
         hrn = sfa_config.SFA_INTERFACE_HRN
         interface = Interface(hrn, addr, port)
         self[hrn] = interface
예제 #18
0
파일: shell.py 프로젝트: gnogueras/sfa
 def __init__(self, config=None):
     if not config:
         config = Config()
     if has_nova:
         # instantiate managers
         self.auth_manager = KeystoneClient(config=config)
         self.image_manager = GlanceClient(config=config)
         self.nova_manager = NovaClient(config=config)
     else:
         logger.debug('nova access - REST')
         raise SfaNotImplemented('nova access - Rest')
예제 #19
0
def get_trusted_certs(registry=None, verbose=False):
    """
    refresh our list of trusted certs.
    """
    # define useful variables
    config = Config()
    data_dir = config.SFA_DATA_DIR
    config_dir = config.SFA_CONFIG_DIR
    trusted_certs_dir = config.get_trustedroots_dir()
    keyfile = data_dir + os.sep + "server.key"
    certfile = data_dir + os.sep + "server.cert"
    node_gid_file = config_dir + os.sep + "node.gid"
    node_gid = GID(filename=node_gid_file)
    hrn = node_gid.get_hrn()
    # get credential
    cred = GetCredential(registry=registry, verbose=verbose)
    # make sure server key cert pair exists
    create_server_keypair(keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose)
    registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
    # get the trusted certs and save them in the right place
    if verbose:
        print "Getting trusted certs from registry"
    trusted_certs = registry.get_trusted_certs(cred)
    trusted_gid_names = [] 
    for gid_str in trusted_certs:
        gid = GID(string=gid_str)
        gid.decode()
        relative_filename = gid.get_hrn() + ".gid"
        trusted_gid_names.append(relative_filename)
        gid_filename = trusted_certs_dir + os.sep + relative_filename
        if verbose:
            print "Writing GID for %s as %s" % (gid.get_hrn(), gid_filename) 
        gid.save_to_file(gid_filename, save_parents=True)

    # remove old certs
    all_gids_names = os.listdir(trusted_certs_dir)
    for gid_name in all_gids_names:
        if gid_name not in trusted_gid_names:
            if verbose:
                print "Removing old gid ", gid_name
            os.unlink(trusted_certs_dir + os.sep + gid_name)                     
예제 #20
0
    def ParseSites(self):
        """ Returns a list of dictionnaries containing the sites' attributes."""

        nodes_per_site = {}
        config = Config()
        #logger.debug(" OARrestapi.py \tParseSites  self.node_dictlist %s"\
        #%(self.node_dictlist))
        # Create a list of nodes per site_id
        for node_id in self.node_dictlist:
            node = self.node_dictlist[node_id]

            if node['site'] not in nodes_per_site:
                nodes_per_site[node['site']] = []
                nodes_per_site[node['site']].append(node['node_id'])
            else:
                if node['node_id'] not in nodes_per_site[node['site']]:
                    nodes_per_site[node['site']].append(node['node_id'])

        #Create a site dictionary whose key is site_login_base
        # (name of the site) and value is a dictionary of properties,
        # including the list of the node_ids
        for node_id in self.node_dictlist:
            node = self.node_dictlist[node_id]
            node.update({
                'hrn':
                self.iotlab_hostname_to_hrn(self.interface_hrn,
                                            node['hostname'])
            })
            self.node_dictlist.update({node_id: node})

            if node['site'] not in self.site_dict:
                self.site_dict[node['site']] = {
                    'site': node['site'],
                    'node_ids': nodes_per_site[node['site']],
                    'latitude': "48.83726",
                    'longitude': "- 2.10336",
                    'name': config.SFA_REGISTRY_ROOT_AUTH,
                    'pcu_ids': [],
                    'max_slices': None,
                    'ext_consortium_id': None,
                    'max_slivers': None,
                    'is_public': True,
                    'peer_site_id': None,
                    'abbreviated_name': "iotlab",
                    'address_ids': [],
                    'url': "https://portal.senslab.info",
                    'person_ids': [],
                    'site_tag_ids': [],
                    'enabled': True,
                    'slice_ids': [],
                    'date_created': None,
                    'peer_id': None
                }
예제 #21
0
파일: __init__.py 프로젝트: gnogueras/sfa
 def the_flavour(flavour=None, config=None):
     if config is None: config = Config()
     if flavour is None: flavour = config.SFA_GENERIC_FLAVOUR
     flavour = flavour.lower()
     #mixed = flavour.capitalize()
     module_path = "sfa.generic.%s" % flavour
     classname = "%s" % flavour
     logger.debug("Generic.the_flavour with flavour=%s" % flavour)
     try:
         module = __import__(module_path, globals(), locals(), [classname])
         return getattr(module, classname)(flavour, config)
     except:
         logger.log_exc("Cannot locate generic instance with flavour=%s" %
                        flavour)
예제 #22
0
 def call_am_apiclient(self, client_app, params, timeout):
     """
     call AM API client with command like in the following example:
     cd aggregate_client; java -classpath AggregateWS-client-api.jar:lib/* \
       net.geni.aggregate.client.examples.CreateSliceNetworkClient \
       ./repo https://geni:8443/axis2/services/AggregateGENI \
       ... params ...
     """
     (client_path, am_url) = Config().get_max_aggrMgr_info()
     sys_cmd = "cd " + client_path + "; java -classpath AggregateWS-client-api.jar:lib/* net.geni.aggregate.client.examples." + client_app + " ./repo " + am_url + " " + ' '.join(
         params)
     ret = self.shell_execute(sys_cmd, timeout)
     logger.debug("shell_execute cmd: %s returns %s" % (sys_cmd, ret))
     return ret
예제 #23
0
    def __init__(self, string=None, filename=None, create=False):
        self.xml = None

        if create:
            self.create()
        elif string:
            self.load(string)
        elif filename:
            self.load(filename)
        else:
            # load the default file
            c = Config()
            api_versions_file = os.path.sep.join([c.config_path, 'api_versions.xml'])
            self.load(api_versions_file)
예제 #24
0
파일: __init__.py 프로젝트: gnogueras/sfa
    def __init__(self, auth_hierarchy=None, logger=None):
        self.config = Config()
        if auth_hierarchy is not None:
            self.auth_hierarchy = auth_hierarchy
        else:
            self.auth_hierarchy = Hierarchy()
        if logger is not None:
            self.logger = logger
        else:
            self.logger = _SfaLogger(logfile='/var/log/sfa_import.log',
                                     loggername='importlog')
            self.logger.setLevelFromOptVerbose(self.config.SFA_API_LOGLEVEL)
# ugly side effect so that other modules get it right
        import sfa.util.sfalogging
        sfa.util.sfalogging.logger = logger
예제 #25
0
    def __init__(self):
        logger.setLevelDebug()

        #SFA related config

        config = Config()
        self.login_pwd = LoginPassword()
        self.authname = config.SFA_REGISTRY_ROOT_AUTH
        self.conn =  ldap_co()
        self.ldapUserQuotaNFS = self.conn.config.LDAP_USER_QUOTA_NFS
        self.ldapUserUidNumberMin = self.conn.config.LDAP_USER_UID_NUMBER_MIN
        self.ldapUserGidNumber = self.conn.config.LDAP_USER_GID_NUMBER
        self.ldapUserHomePath = self.conn.config.LDAP_USER_HOME_PATH
        self.baseDN = self.conn.ldapPeopleDN
        self.ldapShell = '/bin/bash'
예제 #26
0
    def __init__(self, name=None, auth=None, **kwds):

        config = Config()
        self.id = id
        if name is not None:
            Xrn.__init__(self, **kwds)
            if 'type' in kwds:
                self.type = kwds['type']
            if auth is not None:
                self.hrn = '.'.join([auth, cleanup_name(name)])
            else:
                self.hrn = name.replace('_', '.')
            self.hrn_to_urn()
        else:
            Xrn.__init__(self, **kwds)

        self.name = self.get_name()
예제 #27
0
 def __init__(self, username=None, password=None, tenant=None, url=None, config=None):
     if not config:
         config = Config()
     opts = parse_novarc(config.SFA_NOVA_NOVARC)
     if username:
         opts['OS_USERNAME'] = username
     if password:
         opts['OS_PASSWORD'] = password
     if tenant:
         opts['OS_TENANT_NAME'] = tenant
     if url:
         opts['OS_AUTH_URL'] = url
     self.opts = opts 
     self.client = keystone_client.Client(username=opts.get('OS_USERNAME'),
                                          password=opts.get('OS_PASSWORD'),
                                          tenant_name=opts.get('OS_TENANT_NAME'),
                                          auth_url=opts.get('OS_AUTH_URL'))
예제 #28
0
def GetCredential(registry=None, force=False, verbose=False):
    config = Config()
    hierarchy = Hierarchy()
    key_dir = hierarchy.basedir
    data_dir = config.data_path
    config_dir = config.config_path
    credfile = data_dir + os.sep + 'node.cred'
    # check for existing credential
    if not force and os.path.exists(credfile):
        if verbose:
            print "Loading Credential from %(credfile)s " % locals()
        cred = Credential(filename=credfile).save_to_string(save_parents=True)
    else:
        if verbose:
            print "Getting credential from registry"
        # make sure node private key exists
        node_pkey_file = config_dir + os.sep + "node.key"
        node_gid_file = config_dir + os.sep + "node.gid"
        if not os.path.exists(node_pkey_file) or \
           not os.path.exists(node_gid_file):
            get_node_key(registry=registry, verbose=verbose)

        gid = GID(filename=node_gid_file)
        hrn = gid.get_hrn()
        # create server key and certificate
        keyfile = data_dir + os.sep + "server.key"
        certfile = data_dir + os.sep + "server.cert"
        key = Keypair(filename=node_pkey_file)
        key.save_to_file(keyfile)
        create_server_keypair(keyfile, certfile, hrn, verbose)

        # get credential from registry
        registry = server_proxy(url=registry,
                                keyfile=keyfile,
                                certfile=certfile)
        cert = Certificate(filename=certfile)
        cert_str = cert.save_to_string(save_parents=True)
        cred = registry.GetSelfCredential(cert_str, 'node', hrn)
        Credential(string=cred).save_to_file(credfile, save_parents=True)

    return cred
예제 #29
0
    def __init__(self,
                 encoding="utf-8",
                 methods='sfa.methods',
                 config="/etc/sfa/sfa_config",
                 peer_cert=None,
                 interface=None,
                 key_file=None,
                 cert_file=None,
                 cache=None):

        XmlrpcApi.__init__(self, encoding)

        # we may be just be documenting the API
        if config is None:
            return
        # Load configuration
        self.config = Config(config)
        self.credential = None
        self.auth = Auth(peer_cert)
        self.interface = interface
        self.hrn = self.config.SFA_INTERFACE_HRN
        self.key_file = key_file
        self.key = Keypair(filename=self.key_file)
        self.cert_file = cert_file
        self.cert = Certificate(filename=self.cert_file)
        self.cache = cache
        if self.cache is None:
            self.cache = Cache()

        # load registries
        from sfa.server.registry import Registries
        self.registries = Registries()

        # load aggregates
        from sfa.server.aggregate import Aggregates
        self.aggregates = Aggregates()

        # filled later on by generic/Generic
        self.manager = None
        self._dbsession = None
예제 #30
0
 def __init__(self, username=None, password=None, tenant=None, url=None, config=None):
     if not config:
         config = Config()
     opts = parse_novarc(config.SFA_NOVA_NOVARC)
     if username:
         opts['OS_USERNAME'] = username
     if password:
         opts['OS_PASSWORD'] = password
     if tenant:
         opts['OS_TENANT_NAME'] = tenant
     if url:
         opts['OS_AUTH_URL'] = url
     self.opts = opts
     self.client = nova_client.Client(username=opts.get('OS_USERNAME'),
                                      api_key=opts.get('OS_PASSWORD'),
                                      project_id=opts.get('OS_TENANT_NAME'),
                                      auth_url=opts.get('OS_AUTH_URL'),
                                      region_name='',
                                      extensions=[],
                                      service_type='compute',
                                      service_name='',  
                                      )
예제 #31
0
파일: auth.py 프로젝트: kongseokhwan/sfa
 def __init__(self, peer_cert = None, config = None ):
     self.peer_cert = peer_cert
     self.hierarchy = Hierarchy()
     if not config:
         self.config = Config()
     self.load_trusted_certs()
예제 #32
0
파일: auth.py 프로젝트: kongseokhwan/sfa
class Auth:
    """
    Credential based authentication
    """

    def __init__(self, peer_cert = None, config = None ):
        self.peer_cert = peer_cert
        self.hierarchy = Hierarchy()
        if not config:
            self.config = Config()
        self.load_trusted_certs()

    def load_trusted_certs(self):
        self.trusted_cert_list = \
            TrustedRoots(self.config.get_trustedroots_dir()).get_list()
        self.trusted_cert_file_list = \
            TrustedRoots(self.config.get_trustedroots_dir()).get_file_list()

    # this convenience methods extracts speaking_for_xrn
    # from the passed options using 'geni_speaking_for'
    def checkCredentialsSpeaksFor (self, *args, **kwds):
        if 'options' not in kwds:
            logger.error ("checkCredentialsSpeaksFor was not passed options=options")
            return
        # remove the options arg
        options=kwds['options']; del kwds['options']
        # compute the speaking_for_xrn arg and pass it to checkCredentials
        if options is None: speaking_for_xrn=None
        else:               speaking_for_xrn=options.get('geni_speaking_for',None)
        kwds['speaking_for_xrn']=speaking_for_xrn
        return self.checkCredentials (*args, **kwds)

    # do not use mutable as default argument 
    # http://docs.python-guide.org/en/latest/writing/gotchas/#mutable-default-arguments
    def checkCredentials(self, creds, operation, xrns=None, 
                         check_sliver_callback=None, 
                         speaking_for_xrn=None):
        if xrns is None: xrns=[]
        def log_invalid_cred(cred):
            if not isinstance (cred, StringTypes):
                logger.info("cannot validate credential %s - expecting a string"%cred)
                error="checkCredentials: expected a string, received %s"%(type(cred))
            else:
                cred_obj=Credential(string=cred)
                logger.info("failed to validate credential - dump=%s"%\
                            cred_obj.dump_string(dump_parents=True))
                error = sys.exc_info()[:2]
            return error

        # if xrns are specified they cannot be None or empty string
        if xrns:
            for xrn in xrns:
                if not xrn:
                    raise BadArgs("Invalid urn or hrn")

        
        if not isinstance(xrns, list):
            xrns = [xrns]

        slice_xrns  = Xrn.filter_type(xrns, 'slice')
        sliver_xrns = Xrn.filter_type(xrns, 'sliver')

        # we are not able to validate slivers in the traditional way so 
        # we make sure not to include sliver urns/hrns in the core validation loop
        hrns = [Xrn(xrn).hrn for xrn in xrns if xrn not in sliver_xrns] 
        valid = []
        if not isinstance(creds, list):
            creds = [creds]
        logger.debug("Auth.checkCredentials with %d creds on hrns=%s"%(len(creds),hrns))
        # won't work if either creds or hrns is empty - let's make it more explicit
        if not creds: raise Forbidden("no credential provided")
        if not hrns: hrns = [None]
        error=[None,None]

        speaks_for_gid = determine_speaks_for(logger, creds, self.peer_cert,
                                              speaking_for_xrn, self.trusted_cert_list)

        if self.peer_cert and \
           not self.peer_cert.is_pubkey(speaks_for_gid.get_pubkey()):
            valid = creds
        else:
            for cred in creds:
                for hrn in hrns:
                    try:
                        self.check(cred, operation, hrn)
                        valid.append(cred)
                    except:
                        error = log_invalid_cred(cred)
        
        # make sure all sliver xrns are validated against the valid credentials
        if sliver_xrns:
            if not check_sliver_callback:
                msg = "sliver verification callback method not found." 
                msg += " Unable to validate sliver xrns: %s" % sliver_xrns
                raise Forbidden(msg)
            check_sliver_callback(valid, sliver_xrns)
                
        if not len(valid):
            raise Forbidden("Invalid credential %s -- %s"%(error[0],error[1]))
        
        return valid
        
        
    def check(self, credential, operation, hrn = None):
        """
        Check the credential against the peer cert (callerGID) included 
        in the credential matches the caller that is connected to the 
        HTTPS connection, check if the credential was signed by a 
        trusted cert and check if the credential is allowed to perform 
        the specified operation.    
        """
        cred = Credential(cred=credential)    
        self.client_cred = cred
        logger.debug("Auth.check: handling hrn=%s and credential=%s"%\
                         (hrn,cred.pretty_cred()))

        if cred.type not in ['geni_sfa']:
            raise CredentialNotVerifiable(cred.type, "%s not supported" % cred.type)
        self.client_gid = self.client_cred.get_gid_caller()
        self.object_gid = self.client_cred.get_gid_object()
        
        # make sure the client_gid is not blank
        if not self.client_gid:
            raise MissingCallerGID(self.client_cred.pretty_subject())
       
        # validate the client cert if it exists
        if self.peer_cert:
            self.verifyPeerCert(self.peer_cert, self.client_gid)                   

        # make sure the client is allowed to perform the operation
        if operation:
            if not self.client_cred.can_perform(operation):
                raise InsufficientRights(operation)

        if self.trusted_cert_list:
            self.client_cred.verify(self.trusted_cert_file_list,
                                    self.config.SFA_CREDENTIAL_SCHEMA)
        else:
           raise MissingTrustedRoots(self.config.get_trustedroots_dir())
       
        # Make sure the credential's target matches the specified hrn. 
        # This check does not apply to trusted peers 
        trusted_peers = [gid.get_hrn() for gid in self.trusted_cert_list]
        if hrn and self.client_gid.get_hrn() not in trusted_peers:
            target_hrn = self.object_gid.get_hrn()
            if not hrn == target_hrn:
                raise PermissionError("Target hrn: %s doesn't match specified hrn: %s " % \
                                       (target_hrn, hrn) )       
        return True

    def check_ticket(self, ticket):
        """
        Check if the ticket was signed by a trusted cert
        """
        if self.trusted_cert_list:
            client_ticket = SfaTicket(string=ticket)
            client_ticket.verify_chain(self.trusted_cert_list)
        else:
           raise MissingTrustedRoots(self.config.get_trustedroots_dir())

        return True 

    def verifyPeerCert(self, cert, gid):
        # make sure the client_gid matches client's certificate
        if not cert.is_pubkey(gid.get_pubkey()):
            raise ConnectionKeyGIDMismatch(gid.get_subject()+":"+cert.get_subject())            

    def verifyGidRequestHash(self, gid, hash, arglist):
        key = gid.get_pubkey()
        if not key.verify_string(str(arglist), hash):
            raise BadRequestHash(hash)

    def verifyCredRequestHash(self, cred, hash, arglist):
        gid = cred.get_gid_caller()
        self.verifyGidRequestHash(gid, hash, arglist)

    def validateGid(self, gid):
        if self.trusted_cert_list:
            gid.verify_chain(self.trusted_cert_list)

    def validateCred(self, cred):
        if self.trusted_cert_list:
            cred.verify(self.trusted_cert_file_list)

    def authenticateGid(self, gidStr, argList, requestHash=None):
        gid = GID(string = gidStr)
        self.validateGid(gid)
        # request_hash is optional
        if requestHash:
            self.verifyGidRequestHash(gid, requestHash, argList)
        return gid

    def authenticateCred(self, credStr, argList, requestHash=None):
        cred = Credential(string = credStr)
        self.validateCred(cred)
        # request hash is optional
        if requestHash:
            self.verifyCredRequestHash(cred, requestHash, argList)
        return cred

    def authenticateCert(self, certStr, requestHash):
        cert = Certificate(string=certStr)
        # xxx should be validateCred ??
        self.validateCred(cert)   

    def gidNoop(self, gidStr, value, requestHash):
        self.authenticateGid(gidStr, [gidStr, value], requestHash)
        return value

    def credNoop(self, credStr, value, requestHash):
        self.authenticateCred(credStr, [credStr, value], requestHash)
        return value

    def verify_cred_is_me(self, credential):
        is_me = False 
        cred = Credential(string=credential)
        caller_gid = cred.get_gid_caller()
        caller_hrn = caller_gid.get_hrn()
        if caller_hrn != self.config.SFA_INTERFACE_HRN:
            raise SfaPermissionDenied(self.config.SFA_INTEFACE_HRN)

        return   
        
    def get_auth_info(self, auth_hrn):
        """
        Given an authority name, return the information for that authority.
        This is basically a stub that calls the hierarchy module.
        
        @param auth_hrn human readable name of authority  
        """

        return self.hierarchy.get_auth_info(auth_hrn)


    def veriry_auth_belongs_to_me(self, name):
        """
        Verify that an authority belongs to our hierarchy. 
        This is basically left up to the implementation of the hierarchy
        module. If the specified name does not belong, ane exception is 
        thrown indicating the caller should contact someone else.

        @param auth_name human readable name of authority
        """

        # get auth info will throw an exception if the authority doesnt exist
        self.get_auth_info(name)


    def verify_object_belongs_to_me(self, name):
        """
        Verify that an object belongs to our hierarchy. By extension,
        this implies that the authority that owns the object belongs
        to our hierarchy. If it does not an exception is thrown.
    
        @param name human readable name of object        
        """
        auth_name = self.get_authority(name)
        if not auth_name:
            auth_name = name 
        if name == self.config.SFA_INTERFACE_HRN:
            return
        self.verify_auth_belongs_to_me(auth_name) 
             
    def verify_auth_belongs_to_me(self, name):
        # get auth info will throw an exception if the authority doesnt exist
        self.get_auth_info(name) 


    def verify_object_permission(self, name):
        """
        Verify that the object gid that was specified in the credential
        allows permission to the object 'name'. This is done by a simple
        prefix test. For example, an object_gid for plc.arizona would 
        match the objects plc.arizona.slice1 and plc.arizona.
    
        @param name human readable name to test  
        """
        object_hrn = self.object_gid.get_hrn()
        if object_hrn == name:
            return
        if name.startswith(object_hrn + "."):
            return
        #if name.startswith(get_authority(name)):
            #return
    
        raise PermissionError(name)

    def determine_user_rights(self, caller_hrn, reg_record):
        """
        Given a user credential and a record, determine what set of rights the
        user should have to that record.
        
        This is intended to replace determine_user_rights() and
        verify_cancreate_credential()
        """

        rl = Rights()
        type = reg_record.type

        logger.debug("entering determine_user_rights with record %s and caller_hrn %s"%\
                     (reg_record, caller_hrn))

        if type == 'slice':
            # researchers in the slice are in the DB as-is
            researcher_hrns = [ user.hrn for user in reg_record.reg_researchers ]
            # locating PIs attached to that slice
            slice_pis=reg_record.get_pis()
            pi_hrns = [ user.hrn for user in slice_pis ]
            if (caller_hrn in researcher_hrns + pi_hrns):
                rl.add('refresh')
                rl.add('embed')
                rl.add('bind')
                rl.add('control')
                rl.add('info')

        elif type == 'authority':
            pi_hrns = [ user.hrn for user in reg_record.reg_pis ]
            if (caller_hrn == self.config.SFA_INTERFACE_HRN):
                rl.add('authority')
                rl.add('sa')
                rl.add('ma')
            if (caller_hrn in pi_hrns):
                rl.add('authority')
                rl.add('sa')
            # NOTE: for the PL implementation, this 'operators' list 
            # amounted to users with 'tech' role in that site 
            # it seems like this is not needed any longer, so for now I just drop that
            # operator_hrns = reg_record.get('operator',[])
            # if (caller_hrn in operator_hrns):
            #    rl.add('authority')
            #    rl.add('ma')

        elif type == 'user':
            rl.add('refresh')
            rl.add('resolve')
            rl.add('info')

        elif type == 'node':
            rl.add('operator')

        return rl

    def get_authority(self, hrn):
        return get_authority(hrn)

    def filter_creds_by_caller(self, creds, caller_hrn_list):
        """
        Returns a list of creds who's gid caller matches the 
        specified caller hrn
        """
        if not isinstance(creds, list):
            creds = [creds]
        creds = []
        if not isinstance(caller_hrn_list, list):
            caller_hrn_list = [caller_hrn_list]
        for cred in creds:
            try:
                tmp_cred = Credential(string=cred)
                if tmp_cred.get_gid_caller().get_hrn() in [caller_hrn_list]:
                    creds.append(cred)
            except: pass
        return creds
예제 #33
0
 def __init__(self, basedir = None):
     self.config = Config()
     if not basedir:
         basedir = os.path.join(self.config.SFA_DATA_DIR, "authorities")
     self.basedir = basedir
예제 #34
0
    def run (self, options):
        config = Config ()
        interface_hrn = config.SFA_INTERFACE_HRN
        root_auth = config.SFA_REGISTRY_ROOT_AUTH
        shell = DummyShell (config)

        ######## retrieve all existing SFA objects
        all_records = global_dbsession.query(RegRecord).all()

        # create hash by (type,hrn) 
        # we essentially use this to know if a given record is already known to SFA 
        self.records_by_type_hrn = \
            dict ( [ ( (record.type, record.hrn) , record ) for record in all_records ] )
        # create hash by (type,pointer) 
        self.records_by_type_pointer = \
            dict ( [ ( (record.type, record.pointer) , record ) for record in all_records 
                     if record.pointer != -1] )

        # initialize record.stale to True by default, then mark stale=False on the ones that are in use
        for record in all_records: record.stale=True
        
        # DEBUG
        #all_records = global_dbsession.query(RegRecord).all()
        #for record in all_records: print record

        ######## retrieve Dummy TB data
        # Get all plc sites
        # retrieve only required stuf
        sites = [shell.GetTestbedInfo()]
        print "sites: " + sites
        # create a hash of sites by login_base
#        sites_by_login_base = dict ( [ ( site['login_base'], site ) for site in sites ] )
        # Get all dummy TB users
        users = shell.GetUsers()
        # create a hash of users by user_id
        users_by_id = dict ( [ ( user['user_id'], user) for user in users ] )
        # Get all dummy TB public keys
        keys = []
        for user in users:
            if 'keys' in user:
                keys.extend(user['keys'])
        # create a dict user_id -> [ keys ]
        keys_by_person_id = {} 
        for user in users:
             if 'keys' in user:
                 keys_by_person_id[user['user_id']] = user['keys']
        # Get all dummy TB nodes  
        nodes = shell.GetNodes()
        # create hash by node_id
        nodes_by_id = dict ( [ ( node['node_id'], node, ) for node in nodes ] )
        # Get all dummy TB slices
        slices = shell.GetSlices()
        # create hash by slice_id
        slices_by_id = dict ( [ (slice['slice_id'], slice ) for slice in slices ] )


        # start importing
        print " STARTING FOR SITES" 
        for site in sites:
            site_hrn = _get_site_hrn(interface_hrn, site)
            # import if hrn is not in list of existing hrns or if the hrn exists
            # but its not a site record
            site_record=self.locate_by_type_hrn ('authority', site_hrn)
            print site_hrn
            print site_record
            if not site_record:
                try:
                    print "TRY TO CREATE SITE RECORD"
                    urn = hrn_to_urn(site_hrn, 'authority')
                    if not self.auth_hierarchy.auth_exists(urn):
                        print "create auth "+urn
                        self.auth_hierarchy.create_auth(urn)
                    auth_info = self.auth_hierarchy.get_auth_info(urn)
                    site_record = RegAuthority(hrn=site_hrn, gid=auth_info.get_gid_object(),
                                               pointer= -1,
                                               authority=get_authority(site_hrn))
                    site_record.just_created()
                    print "urn: "+urn
                    print "auth_info: " + auth_info
                    print site_record
                    global_dbsession.add(site_record)
                    global_dbsession.commit()
                    self.logger.info("DummyImporter: imported authority (site) : %s" % site_record) 
                    self.remember_record (site_record)
                except:
                    # if the site import fails then there is no point in trying to import the
                    # site's child records (node, slices, persons), so skip them.
                    self.logger.log_exc("DummyImporter: failed to import site. Skipping child records") 
                    continue 
            else:
                # xxx update the record ...
                pass
            site_record.stale=False
             
            # import node records
            for node in nodes:
                site_auth = get_authority(site_hrn)
                site_name = site['name']
                node_hrn =  hostname_to_hrn(site_auth, site_name, node['hostname'])
                # xxx this sounds suspicious
                if len(node_hrn) > 64: node_hrn = node_hrn[:64]
                node_record = self.locate_by_type_hrn ( 'node', node_hrn )
                if not node_record:
                    try:
                        pkey = Keypair(create=True)
                        urn = hrn_to_urn(node_hrn, 'node')
                        node_gid = self.auth_hierarchy.create_gid(urn, create_uuid(), pkey)
                        node_record = RegNode (hrn=node_hrn, gid=node_gid, 
                                               pointer =node['node_id'],
                                               authority=get_authority(node_hrn))
                        node_record.just_created()
                        global_dbsession.add(node_record)
                        global_dbsession.commit()
                        self.logger.info("DummyImporter: imported node: %s" % node_record)  
                        self.remember_record (node_record)
                    except:
                        self.logger.log_exc("DummyImporter: failed to import node") 
                else:
                    # xxx update the record ...
                    pass
                node_record.stale=False
            
            all_records = global_dbsession.query(RegRecord).all()
            for record in all_records: print record
            
            site_pis=[]
            # import users
            for user in users:
                user_hrn = email_to_hrn(site_hrn, user['email'])
                # xxx suspicious again
                if len(user_hrn) > 64: user_hrn = user_hrn[:64]
                user_urn = hrn_to_urn(user_hrn, 'user')

                user_record = self.locate_by_type_hrn ( 'user', user_hrn)

                # return a tuple pubkey (a dummy TB key object) and pkey (a Keypair object)

                def init_user_key (user):
                    pubkey = None
                    pkey = None
                    if  user['keys']:
                        # randomly pick first key in set
                        for key in user['keys']:
                             pubkey = key
                             try:
                                pkey = convert_public_key(pubkey)
                                break
                             except:
                                continue
                        if not pkey:
                            self.logger.warn('DummyImporter: unable to convert public key for %s' % user_hrn)
                            pkey = Keypair(create=True)
                    else:
                        # the user has no keys. Creating a random keypair for the user's gid
                        self.logger.warn("DummyImporter: user %s does not have a NITOS public key"%user_hrn)
                        pkey = Keypair(create=True)
                    return (pubkey, pkey)

                # new user
                try:
                    if not user_record:
                        (pubkey,pkey) = init_user_key (user)
                        user_gid = self.auth_hierarchy.create_gid(user_urn, create_uuid(), pkey)
                        user_gid.set_email(user['email'])
                        user_record = RegUser (hrn=user_hrn, gid=user_gid, 
                                                 pointer=user['user_id'], 
                                                 authority=get_authority(user_hrn),
                                                 email=user['email'])
                        if pubkey: 
                            user_record.reg_keys=[RegKey (pubkey)]
                        else:
                            self.logger.warning("No key found for user %s"%user_record)
                        user_record.just_created()
                        global_dbsession.add (user_record)
                        global_dbsession.commit()
                        self.logger.info("DummyImporter: imported person: %s" % user_record)
                        self.remember_record ( user_record )

                    else:
                        # update the record ?
                        # if user's primary key has changed then we need to update the 
                        # users gid by forcing an update here
                        sfa_keys = user_record.reg_keys
                        def key_in_list (key,sfa_keys):
                            for reg_key in sfa_keys:
                                if reg_key.key==key: return True
                            return False
                        # is there a new key in Dummy TB ?
                        new_keys=False
                        for key in user['keys']:
                            if not key_in_list (key,sfa_keys):
                                new_keys = True
                        if new_keys:
                            (pubkey,pkey) = init_user_key (user)
                            user_gid = self.auth_hierarchy.create_gid(user_urn, create_uuid(), pkey)
                            if not pubkey:
                                user_record.reg_keys=[]
                            else:
                                user_record.reg_keys=[ RegKey (pubkey)]
                            self.logger.info("DummyImporter: updated person: %s" % user_record)
                    user_record.email = user['email']
                    global_dbsession.commit()
                    user_record.stale=False
                except:
                    self.logger.log_exc("DummyImporter: failed to import user %d %s"%(user['user_id'],user['email']))
    

            # import slices
            for slice in slices:
                slice_hrn = slicename_to_hrn(site_hrn, slice['slice_name'])
                slice_record = self.locate_by_type_hrn ('slice', slice_hrn)
                if not slice_record:
                    try:
                        pkey = Keypair(create=True)
                        urn = hrn_to_urn(slice_hrn, 'slice')
                        slice_gid = self.auth_hierarchy.create_gid(urn, create_uuid(), pkey)
                        slice_record = RegSlice (hrn=slice_hrn, gid=slice_gid, 
                                                 pointer=slice['slice_id'],
                                                 authority=get_authority(slice_hrn))
                        slice_record.just_created()
                        global_dbsession.add(slice_record)
                        global_dbsession.commit()
                        self.logger.info("DummyImporter: imported slice: %s" % slice_record)  
                        self.remember_record ( slice_record )
                    except:
                        self.logger.log_exc("DummyImporter: failed to import slice")
                else:
                    # xxx update the record ...
                    self.logger.warning ("Slice update not yet implemented")
                    pass
                # record current users affiliated with the slice
                slice_record.reg_researchers = \
                    [ self.locate_by_type_pointer ('user',user_id) for user_id in slice['user_ids'] ]
                global_dbsession.commit()
                slice_record.stale=False

        ### remove stale records
        # special records must be preserved
        system_hrns = [interface_hrn, root_auth, interface_hrn + '.slicemanager']
        for record in all_records: 
            if record.hrn in system_hrns: 
                record.stale=False
            if record.peer_authority:
                record.stale=False

        for record in all_records:
            try:        stale=record.stale
            except:     
                stale=True
                self.logger.warning("stale not found with %s"%record)
            if stale:
                self.logger.info("DummyImporter: deleting stale record: %s" % record)
                global_dbsession.delete(record)
                global_dbsession.commit()
예제 #35
0
파일: auth.py 프로젝트: tubav/sfa
class Auth:
    """
    Credential based authentication
    """

    def __init__(self, peer_cert = None, config = None ):
        self.peer_cert = peer_cert
        self.hierarchy = Hierarchy()
        if not config:
            self.config = Config()
        self.load_trusted_certs()

    def load_trusted_certs(self):
        self.trusted_cert_list = TrustedRoots(self.config.get_trustedroots_dir()).get_list()
        self.trusted_cert_file_list = TrustedRoots(self.config.get_trustedroots_dir()).get_file_list()

        
        
    def checkCredentials(self, creds, operation, hrn = None):
        valid = []
        if not isinstance(creds, list):
            creds = [creds]
        logger.debug("Auth.checkCredentials with %d creds"%len(creds))
        for cred in creds:
            try:
                self.check(cred, operation, hrn)
                valid.append(cred)
            except:
                cred_obj=Credential(string=cred)
                logger.debug("failed to validate credential - dump=%s"%cred_obj.dump_string(dump_parents=True))
                error = sys.exc_info()[:2]
                continue
            
        if not len(valid):
            raise InsufficientRights('Access denied: %s -- %s' % (error[0],error[1]))
        
        return valid
        
        
    def check(self, cred, operation, hrn = None):
        """
        Check the credential against the peer cert (callerGID included 
        in the credential matches the caller that is connected to the 
        HTTPS connection, check if the credential was signed by a 
        trusted cert and check if the credential is allowed to perform 
        the specified operation.    
        """
        self.client_cred = Credential(string = cred)
        self.client_gid = self.client_cred.get_gid_caller()
        self.object_gid = self.client_cred.get_gid_object()
        
        # make sure the client_gid is not blank
        if not self.client_gid:
            raise MissingCallerGID(self.client_cred.get_subject())
       
        # validate the client cert if it exists
        if self.peer_cert:
            self.verifyPeerCert(self.peer_cert, self.client_gid)                   

        # make sure the client is allowed to perform the operation
        if operation:
            if not self.client_cred.can_perform(operation):
                raise InsufficientRights(operation)

        if self.trusted_cert_list:
            self.client_cred.verify(self.trusted_cert_file_list, self.config.SFA_CREDENTIAL_SCHEMA)
        else:
           raise MissingTrustedRoots(self.config.get_trustedroots_dir())
       
        # Make sure the credential's target matches the specified hrn. 
        # This check does not apply to trusted peers 
        trusted_peers = [gid.get_hrn() for gid in self.trusted_cert_list]
        if hrn and self.client_gid.get_hrn() not in trusted_peers:
            target_hrn = self.object_gid.get_hrn()
            if not hrn == target_hrn:
                raise PermissionError("Target hrn: %s doesn't match specified hrn: %s " % \
                                       (target_hrn, hrn) )       
        return True

    def check_ticket(self, ticket):
        """
        Check if the tickt was signed by a trusted cert
        """
        if self.trusted_cert_list:
            client_ticket = SfaTicket(string=ticket)
            client_ticket.verify_chain(self.trusted_cert_list)
        else:
           raise MissingTrustedRoots(self.config.get_trustedroots_dir())

        return True 

    def verifyPeerCert(self, cert, gid):
        # make sure the client_gid matches client's certificate
        if not cert.is_pubkey(gid.get_pubkey()):
            raise ConnectionKeyGIDMismatch(gid.get_subject()+":"+cert.get_subject())            

    def verifyGidRequestHash(self, gid, hash, arglist):
        key = gid.get_pubkey()
        if not key.verify_string(str(arglist), hash):
            raise BadRequestHash(hash)

    def verifyCredRequestHash(self, cred, hash, arglist):
        gid = cred.get_gid_caller()
        self.verifyGidRequestHash(gid, hash, arglist)

    def validateGid(self, gid):
        if self.trusted_cert_list:
            gid.verify_chain(self.trusted_cert_list)

    def validateCred(self, cred):
        if self.trusted_cert_list:
            cred.verify(self.trusted_cert_file_list)

    def authenticateGid(self, gidStr, argList, requestHash=None):
        gid = GID(string = gidStr)
        self.validateGid(gid)
        # request_hash is optional
        if requestHash:
            self.verifyGidRequestHash(gid, requestHash, argList)
        return gid

    def authenticateCred(self, credStr, argList, requestHash=None):
        cred = Credential(string = credStr)
        self.validateCred(cred)
        # request hash is optional
        if requestHash:
            self.verifyCredRequestHash(cred, requestHash, argList)
        return cred

    def authenticateCert(self, certStr, requestHash):
        cert = Certificate(string=certStr)
        # xxx should be validateCred ??
        self.validateCred(cert)   

    def gidNoop(self, gidStr, value, requestHash):
        self.authenticateGid(gidStr, [gidStr, value], requestHash)
        return value

    def credNoop(self, credStr, value, requestHash):
        self.authenticateCred(credStr, [credStr, value], requestHash)
        return value

    def verify_cred_is_me(self, credential):
        is_me = False 
        cred = Credential(string=credential)
        caller_gid = cred.get_gid_caller()
        caller_hrn = caller_gid.get_hrn()
        if caller_hrn != self.config.SFA_INTERFACE_HRN:
            raise SfaPermissionDenied(self.config.SFA_INTEFACE_HRN)

        return   
        
    def get_auth_info(self, auth_hrn):
        """
        Given an authority name, return the information for that authority.
        This is basically a stub that calls the hierarchy module.
        
        @param auth_hrn human readable name of authority  
        """

        return self.hierarchy.get_auth_info(auth_hrn)


    def veriry_auth_belongs_to_me(self, name):
        """
        Verify that an authority belongs to our hierarchy. 
        This is basically left up to the implementation of the hierarchy
        module. If the specified name does not belong, ane exception is 
        thrown indicating the caller should contact someone else.

        @param auth_name human readable name of authority
        """

        # get auth info will throw an exception if the authority doesnt exist
        self.get_auth_info(name)


    def verify_object_belongs_to_me(self, name):
        """
        Verify that an object belongs to our hierarchy. By extension,
        this implies that the authority that owns the object belongs
        to our hierarchy. If it does not an exception is thrown.
    
        @param name human readable name of object        
        """
        auth_name = self.get_authority(name)
        if not auth_name:
            auth_name = name 
        if name == self.config.SFA_INTERFACE_HRN:
            return
        self.verify_auth_belongs_to_me(auth_name) 
             
    def verify_auth_belongs_to_me(self, name):
        # get auth info will throw an exception if the authority doesnt exist
        self.get_auth_info(name) 


    def verify_object_permission(self, name):
        """
        Verify that the object gid that was specified in the credential
        allows permission to the object 'name'. This is done by a simple
        prefix test. For example, an object_gid for plc.arizona would 
        match the objects plc.arizona.slice1 and plc.arizona.
    
        @param name human readable name to test  
        """
        object_hrn = self.object_gid.get_hrn()
        if object_hrn == name:
            return
        if name.startswith(object_hrn + "."):
            return
        #if name.startswith(get_authority(name)):
            #return
    
        raise PermissionError(name)

    def determine_user_rights(self, caller_hrn, reg_record):
        """
        Given a user credential and a record, determine what set of rights the
        user should have to that record.
        
        This is intended to replace determine_user_rights() and
        verify_cancreate_credential()
        """

        rl = Rights()
        type = reg_record.type

        logger.debug("entering determine_user_rights with record %s and caller_hrn %s"%(reg_record, caller_hrn))

        if type == 'slice':
            # researchers in the slice are in the DB as-is
            researcher_hrns = [ user.hrn for user in reg_record.reg_researchers ]
            # locating PIs attached to that slice
            slice_pis=reg_record.get_pis()
            pi_hrns = [ user.hrn for user in slice_pis ]
            if (caller_hrn in researcher_hrns + pi_hrns):
                rl.add('refresh')
                rl.add('embed')
                rl.add('bind')
                rl.add('control')
                rl.add('info')

        elif type == 'authority':
            pi_hrns = [ user.hrn for user in reg_record.reg_pis ]
            if (caller_hrn == self.config.SFA_INTERFACE_HRN):
                rl.add('authority')
                rl.add('sa')
                rl.add('ma')
            if (caller_hrn in pi_hrns):
                rl.add('authority')
                rl.add('sa')
            # NOTE: for the PL implementation, this 'operators' list 
            # amounted to users with 'tech' role in that site 
            # it seems like this is not needed any longer, so for now I just drop that
            # operator_hrns = reg_record.get('operator',[])
            # if (caller_hrn in operator_hrns):
            #    rl.add('authority')
            #    rl.add('ma')

        elif type == 'user':
            rl.add('refresh')
            rl.add('resolve')
            rl.add('info')

        elif type == 'node':
            rl.add('operator')

        return rl

    def get_authority(self, hrn):
        return get_authority(hrn)

    def filter_creds_by_caller(self, creds, caller_hrn_list):
        """
        Returns a list of creds who's gid caller matches the 
        specified caller hrn
        """
        if not isinstance(creds, list):
            creds = [creds]
        creds = []
        if not isinstance(caller_hrn_list, list):
            caller_hrn_list = [caller_hrn_list]
        for cred in creds:
            try:
                tmp_cred = Credential(string=cred)
                if tmp_cred.get_gid_caller().get_hrn() in [caller_hrn_list]:
                    creds.append(cred)
            except: pass
        return creds
예제 #36
0
def get_gids(registry=None, verbose=False):
    """
    Get the gid for all instantiated slices on this node and store it
    in /etc/sfa/slice.gid in the slice's filesystem
    """
    # define useful variables
    config = Config()
    data_dir = config.data_path
    config_dir = config.SFA_CONFIG_DIR
    trusted_certs_dir = config.get_trustedroots_dir()
    keyfile = data_dir + os.sep + "server.key"
    certfile = data_dir + os.sep + "server.cert"
    node_gid_file = config_dir + os.sep + "node.gid"
    node_gid = GID(filename=node_gid_file)
    hrn = node_gid.get_hrn()
    interface_hrn = config.SFA_INTERFACE_HRN
    # get credential
    cred = GetCredential(registry=registry, verbose=verbose)
    # make sure server key cert pair exists
    create_server_keypair(keyfile=keyfile, certfile=certfile, hrn=hrn, verbose=verbose)
    registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)
            
    if verbose:
        print "Getting current slices on this node"
    # get a list of slices on this node
    from sfa.generic import Generic
    generic=Generic.the_flavour()
    api = generic.make_api(interface='component')
    xids_tuple = api.driver.nodemanager.GetXIDs()
    slices = eval(xids_tuple[1])
    slicenames = slices.keys()

    # generate a list of slices that dont have gids installed
    slices_without_gids = []
    for slicename in slicenames:
        if not os.path.isfile("/vservers/%s/etc/slice.gid" % slicename) \
        or not os.path.isfile("/vservers/%s/etc/node.gid" % slicename):
            slices_without_gids.append(slicename) 
    
    # convert slicenames to hrns
    hrns = [slicename_to_hrn(interface_hrn, slicename) \
            for slicename in slices_without_gids]
    
    # exit if there are no gids to install
    if not hrns:
        return
        
    if verbose:
        print "Getting gids for slices on this node from registry"  
    # get the gids
    # and save them in the right palce
    records = registry.GetGids(hrns, cred)
    for record in records:
        # if this isnt a slice record skip it
        if not record['type'] == 'slice':
            continue
        slicename = hrn_to_pl_slicename(record['hrn'])
        # if this slice isnt really instatiated skip it
        if not os.path.exists("/vservers/%(slicename)s" % locals()):
            continue
       
        # save the slice gid in /etc/sfa/ in the vservers filesystem
        vserver_path = "/vservers/%(slicename)s" % locals()
        gid = record['gid']
        slice_gid_filename = os.sep.join([vserver_path, "etc", "slice.gid"])
        if verbose:
            print "Saving GID for %(slicename)s as %(slice_gid_filename)s" % locals()
        GID(string=gid).save_to_file(slice_gid_filename, save_parents=True)
        # save the node gid in /etc/sfa
        node_gid_filename = os.sep.join([vserver_path, "etc", "node.gid"])
        if verbose:
            print "Saving node GID for %(slicename)s as %(node_gid_filename)s" % locals()
        node_gid.save_to_file(node_gid_filename, save_parents=True) 
예제 #37
0
파일: sfaImport.py 프로젝트: planetlab/sfa
class sfaImport:

    def __init__(self):
       self.logger = _SfaLogger(logfile='/var/log/sfa_import.log', loggername='importlog')
       self.AuthHierarchy = Hierarchy()
       self.config = Config()
       self.TrustedRoots = TrustedRoots(Config.get_trustedroots_dir(self.config))
       self.plc_auth = self.config.get_plc_auth()
       self.root_auth = self.config.SFA_REGISTRY_ROOT_AUTH
        
       # connect to planetlab
       self.shell = None
       if "Url" in self.plc_auth:
          from sfa.plc.remoteshell import RemoteShell
          self.shell = RemoteShell(self.logger)
       else:
          import PLC.Shell
          self.shell = PLC.Shell.Shell(globals = globals())        

    def create_top_level_auth_records(self, hrn):
        """
        Create top level records (includes root and sub authorities (local/remote)
        """
        urn = hrn_to_urn(hrn, 'authority')
        # make sure parent exists
        parent_hrn = get_authority(hrn)
        if not parent_hrn:
            parent_hrn = hrn
        if not parent_hrn == hrn:
            self.create_top_level_auth_records(parent_hrn)

        # create the authority if it doesnt already exist 
        if not self.AuthHierarchy.auth_exists(urn):
            self.logger.info("Import: creating top level authorities")
            self.AuthHierarchy.create_auth(urn)
        
        # create the db record if it doesnt already exist    
        auth_info = self.AuthHierarchy.get_auth_info(hrn)
        table = SfaTable()
        auth_record = table.find({'type': 'authority', 'hrn': hrn})

        if not auth_record:
            auth_record = SfaRecord(hrn=hrn, gid=auth_info.get_gid_object(), type="authority", pointer=-1)
            auth_record['authority'] = get_authority(auth_record['hrn'])
            self.logger.info("Import: inserting authority record for %s"%hrn)
            table.insert(auth_record)

    def create_sm_client_record(self):
        """
        Create a user record for the Slicemanager service.
        """
        hrn = self.config.SFA_INTERFACE_HRN + '.slicemanager'
        urn = hrn_to_urn(hrn, 'user')
        if not self.AuthHierarchy.auth_exists(urn):
            self.logger.info("Import: creating Slice Manager user")
            self.AuthHierarchy.create_auth(urn)

        auth_info = self.AuthHierarchy.get_auth_info(hrn)
        table = SfaTable()
        sm_user_record = table.find({'type': 'user', 'hrn': hrn})
        if not sm_user_record:
            record = SfaRecord(hrn=hrn, gid=auth_info.get_gid_object(), type="user", pointer=-1)
            record['authority'] = get_authority(record['hrn'])
            table.insert(record)    

    def create_interface_records(self):
        """
        Create a record for each SFA interface
        """
        # just create certs for all sfa interfaces even if they
        # arent enabled
        interface_hrn = self.config.SFA_INTERFACE_HRN
        interfaces = ['authority+sa', 'authority+am', 'authority+sm']
        table = SfaTable()
        auth_info = self.AuthHierarchy.get_auth_info(interface_hrn)
        pkey = auth_info.get_pkey_object()
        for interface in interfaces:
            interface_record = table.find({'type': interface, 'hrn': interface_hrn})
            if not interface_record:
                self.logger.info("Import: interface %s %s " % (interface_hrn, interface))
                urn = hrn_to_urn(interface_hrn, interface)
                gid = self.AuthHierarchy.create_gid(urn, create_uuid(), pkey)
                record = SfaRecord(hrn=interface_hrn, gid=gid, type=interface, pointer=-1)  
                record['authority'] = get_authority(interface_hrn)
                table.insert(record) 
                                

    
    def import_person(self, parent_hrn, person):
        """
        Register a user record 
        """
        hrn = email_to_hrn(parent_hrn, person['email'])

        # ASN.1 will have problems with hrn's longer than 64 characters
        if len(hrn) > 64:
            hrn = hrn[:64]

        self.logger.info("Import: person %s"%hrn)
        key_ids = []
        if 'key_ids' in person and person['key_ids']:
            key_ids = person["key_ids"]
            # get the user's private key from the SSH keys they have uploaded
            # to planetlab
            keys = self.shell.GetKeys(self.plc_auth, key_ids)
            key = keys[0]['key']
            pkey = None
            try:
                pkey = convert_public_key(key)
            except:
                self.logger.warn('unable to convert public key for %s' % hrn) 
            if not pkey:
                pkey = Keypair(create=True)
        else:
            # the user has no keys
            self.logger.warn("Import: person %s does not have a PL public key"%hrn)
            # if a key is unavailable, then we still need to put something in the
            # user's GID. So make one up.
            pkey = Keypair(create=True)

        # create the gid
        urn = hrn_to_urn(hrn, 'user')
        person_gid = self.AuthHierarchy.create_gid(urn, create_uuid(), pkey)
        table = SfaTable()
        person_record = SfaRecord(hrn=hrn, gid=person_gid, type="user", pointer=person['person_id'])
        person_record['authority'] = get_authority(person_record['hrn'])
        existing_records = table.find({'hrn': hrn, 'type': 'user', 'pointer': person['person_id']})
        if not existing_records:
            table.insert(person_record)
        else:
            self.logger.info("Import: %s exists, updating " % hrn)
            existing_record = existing_records[0]
            person_record['record_id'] = existing_record['record_id']
            table.update(person_record)

    def import_slice(self, parent_hrn, slice):
        slicename = slice['name'].split("_",1)[-1]
        slicename = _cleanup_string(slicename)

        if not slicename:
            self.logger.error("Import: failed to parse slice name %s" %slice['name'])
            return

        hrn = parent_hrn + "." + slicename
        self.logger.info("Import: slice %s"%hrn)

        pkey = Keypair(create=True)
        urn = hrn_to_urn(hrn, 'slice')
        slice_gid = self.AuthHierarchy.create_gid(urn, create_uuid(), pkey)
        slice_record = SfaRecord(hrn=hrn, gid=slice_gid, type="slice", pointer=slice['slice_id'])
        slice_record['authority'] = get_authority(slice_record['hrn'])
        table = SfaTable()
        existing_records = table.find({'hrn': hrn, 'type': 'slice', 'pointer': slice['slice_id']})
        if not existing_records:
            table.insert(slice_record)
        else:
            self.logger.info("Import: %s exists, updating " % hrn)
            existing_record = existing_records[0]
            slice_record['record_id'] = existing_record['record_id']
            table.update(slice_record)

    def import_node(self, hrn, node):
        self.logger.info("Import: node %s" % hrn)
        # ASN.1 will have problems with hrn's longer than 64 characters
        if len(hrn) > 64:
            hrn = hrn[:64]

        table = SfaTable()
        node_record = table.find({'type': 'node', 'hrn': hrn})
        pkey = Keypair(create=True)
        urn = hrn_to_urn(hrn, 'node')
        node_gid = self.AuthHierarchy.create_gid(urn, create_uuid(), pkey)
        node_record = SfaRecord(hrn=hrn, gid=node_gid, type="node", pointer=node['node_id'])
        node_record['authority'] = get_authority(node_record['hrn'])
        existing_records = table.find({'hrn': hrn, 'type': 'node', 'pointer': node['node_id']})
        if not existing_records:
            table.insert(node_record)
        else:
            self.logger.info("Import: %s exists, updating " % hrn)
            existing_record = existing_records[0]
            node_record['record_id'] = existing_record['record_id']
            table.update(node_record)

    
    def import_site(self, hrn, site):
        shell = self.shell
        plc_auth = self.plc_auth
        urn = hrn_to_urn(hrn, 'authority')
        self.logger.info("Import: site %s"%hrn)

        # create the authority
        if not self.AuthHierarchy.auth_exists(urn):
            self.AuthHierarchy.create_auth(urn)

        auth_info = self.AuthHierarchy.get_auth_info(urn)

        table = SfaTable()
        auth_record = SfaRecord(hrn=hrn, gid=auth_info.get_gid_object(), type="authority", pointer=site['site_id'])
        auth_record['authority'] = get_authority(auth_record['hrn'])
        existing_records = table.find({'hrn': hrn, 'type': 'authority', 'pointer': site['site_id']})
        if not existing_records:
            table.insert(auth_record)
        else:
            self.logger.info("Import: %s exists, updating " % hrn)
            existing_record = existing_records[0]
            auth_record['record_id'] = existing_record['record_id']
            table.update(auth_record)

        return hrn


    def delete_record(self, hrn, type):
        # delete the record
        table = SfaTable()
        record_list = table.find({'type': type, 'hrn': hrn})
        for record in record_list:
            self.logger.info("Import: removing record %s %s" % (type, hrn))
            table.remove(record)        
예제 #38
0
 def __init__(self, peer_cert=None, config=None):
     self.peer_cert = peer_cert
     self.hierarchy = Hierarchy()
     if not config:
         self.config = Config()
     self.load_trusted_certs()
예제 #39
0
class Auth:
    """
    Credential based authentication
    """
    def __init__(self, peer_cert=None, config=None):
        self.peer_cert = peer_cert
        self.hierarchy = Hierarchy()
        if not config:
            self.config = Config()
        self.load_trusted_certs()

    def load_trusted_certs(self):
        self.trusted_cert_list = TrustedRoots(
            self.config.get_trustedroots_dir()).get_list()
        self.trusted_cert_file_list = TrustedRoots(
            self.config.get_trustedroots_dir()).get_file_list()

    def checkCredentials(self,
                         creds,
                         operation,
                         xrns=[],
                         check_sliver_callback=None,
                         speaking_for_hrn=None):
        def log_invalid_cred(cred):
            cred_obj = Credential(string=cred)
            logger.debug("failed to validate credential - dump=%s" %
                         cred_obj.dump_string(dump_parents=True))
            error = sys.exc_info()[:2]
            return error

        # if xrns are specified they cannot be None or empty string
        if xrns:
            for xrn in xrns:
                if not xrn:
                    raise BadArgs("Invalid urn or hrn")

        if not isinstance(xrns, list):
            xrns = [xrns]

        slice_xrns = Xrn.filter_type(xrns, 'slice')
        sliver_xrns = Xrn.filter_type(xrns, 'sliver')

        # we are not able to validate slivers in the traditional way so
        # we make sure not to include sliver urns/hrns in the core validation loop
        hrns = [Xrn(xrn).hrn for xrn in xrns if xrn not in sliver_xrns]
        valid = []
        speaks_for_cred = None
        if not isinstance(creds, list):
            creds = [creds]
        logger.debug("Auth.checkCredentials with %d creds on hrns=%s" %
                     (len(creds), hrns))
        # won't work if either creds or hrns is empty - let's make it more explicit
        if not creds:
            raise BadArgs(
                "no credential provided")  #Forbidden("no credential provided")
        if not hrns: hrns = [None]
        for cred in creds:
            for hrn in hrns:
                try:
                    self.check(cred, operation, hrn)
                    valid.append(cred)
                except:
                    if speaking_for_hrn:
                        try:
                            self.check(cred, operation, speaking_for_hrn)
                            speaks_for_cred = cred
                            valid.append(cred)
                        except:
                            error = log_invalid_cred(cred)
                    else:
                        error = log_invalid_cred(cred)
                    continue

        # make sure all sliver xrns are validated against the valid credentials
        if sliver_xrns:
            if not check_sliver_callback:
                msg = "sliver verification callback method not found."
                msg += " Unable to validate sliver xrns: %s" % sliver_xrns
                raise Forbidden(msg)
            check_sliver_callback(valid, sliver_xrns)

        if not len(valid):
            raise Forbidden("Invalid credential")

        if speaking_for_hrn and not speaks_for_cred:
            raise InsufficientRights(
                'Access denied: "geni_speaking_for" option specified but no valid speaks for credential found: %s -- %s'
                % (error[0], error[1]))

        return valid

    def check(self, credential, operation, hrn=None):
        """
        Check the credential against the peer cert (callerGID included 
        in the credential matches the caller that is connected to the 
        HTTPS connection, check if the credential was signed by a 
        trusted cert and check if the credential is allowed to perform 
        the specified operation.    
        """
        cred = Credential(cred=credential)
        self.client_cred = cred
        logger.debug("Auth.check: handling hrn=%s and credential=%s"%\
                         (hrn,cred.get_summary_tostring()))

        if cred.type not in ['geni_sfa']:
            raise CredentialNotVerifiable(cred.type,
                                          "%s not supported" % cred.type)
        self.client_gid = self.client_cred.get_gid_caller()
        self.object_gid = self.client_cred.get_gid_object()

        # make sure the client_gid is not blank
        if not self.client_gid:
            raise MissingCallerGID(self.client_cred.get_subject())

        # validate the client cert if it exists
        if self.peer_cert:
            self.verifyPeerCert(self.peer_cert, self.client_gid)

        # make sure the client is allowed to perform the operation
        if operation:
            if not self.client_cred.can_perform(operation):
                raise InsufficientRights(operation)

        if self.trusted_cert_list:
            self.client_cred.verify(self.trusted_cert_file_list,
                                    self.config.SFA_CREDENTIAL_SCHEMA)
        else:
            raise MissingTrustedRoots(self.config.get_trustedroots_dir())

        # Make sure the credential's target matches the specified hrn.
        # This check does not apply to trusted peers
        trusted_peers = [gid.get_hrn() for gid in self.trusted_cert_list]
        if hrn and self.client_gid.get_hrn() not in trusted_peers:
            target_hrn = self.object_gid.get_hrn()
            if not hrn == target_hrn:
                raise PermissionError("Target hrn: %s doesn't match specified hrn: %s " % \
                                       (target_hrn, hrn) )
        return True

    def check_ticket(self, ticket):
        """
        Check if the tickt was signed by a trusted cert
        """
        if self.trusted_cert_list:
            client_ticket = SfaTicket(string=ticket)
            client_ticket.verify_chain(self.trusted_cert_list)
        else:
            raise MissingTrustedRoots(self.config.get_trustedroots_dir())

        return True

    def verifyPeerCert(self, cert, gid):
        # make sure the client_gid matches client's certificate
        if not cert.is_pubkey(gid.get_pubkey()):
            raise ConnectionKeyGIDMismatch(gid.get_subject() + ":" +
                                           cert.get_subject())

    def verifyGidRequestHash(self, gid, hash, arglist):
        key = gid.get_pubkey()
        if not key.verify_string(str(arglist), hash):
            raise BadRequestHash(hash)

    def verifyCredRequestHash(self, cred, hash, arglist):
        gid = cred.get_gid_caller()
        self.verifyGidRequestHash(gid, hash, arglist)

    def validateGid(self, gid):
        if self.trusted_cert_list:
            gid.verify_chain(self.trusted_cert_list)

    def validateCred(self, cred):
        if self.trusted_cert_list:
            cred.verify(self.trusted_cert_file_list)

    def authenticateGid(self, gidStr, argList, requestHash=None):
        gid = GID(string=gidStr)
        self.validateGid(gid)
        # request_hash is optional
        if requestHash:
            self.verifyGidRequestHash(gid, requestHash, argList)
        return gid

    def authenticateCred(self, credStr, argList, requestHash=None):
        cred = Credential(string=credStr)
        self.validateCred(cred)
        # request hash is optional
        if requestHash:
            self.verifyCredRequestHash(cred, requestHash, argList)
        return cred

    def authenticateCert(self, certStr, requestHash):
        cert = Certificate(string=certStr)
        # xxx should be validateCred ??
        self.validateCred(cert)

    def gidNoop(self, gidStr, value, requestHash):
        self.authenticateGid(gidStr, [gidStr, value], requestHash)
        return value

    def credNoop(self, credStr, value, requestHash):
        self.authenticateCred(credStr, [credStr, value], requestHash)
        return value

    def verify_cred_is_me(self, credential):
        is_me = False
        cred = Credential(string=credential)
        caller_gid = cred.get_gid_caller()
        caller_hrn = caller_gid.get_hrn()
        if caller_hrn != self.config.SFA_INTERFACE_HRN:
            raise SfaPermissionDenied(self.config.SFA_INTEFACE_HRN)

        return

    def get_auth_info(self, auth_hrn):
        """
        Given an authority name, return the information for that authority.
        This is basically a stub that calls the hierarchy module.
        
        @param auth_hrn human readable name of authority  
        """

        return self.hierarchy.get_auth_info(auth_hrn)

    def veriry_auth_belongs_to_me(self, name):
        """
        Verify that an authority belongs to our hierarchy. 
        This is basically left up to the implementation of the hierarchy
        module. If the specified name does not belong, ane exception is 
        thrown indicating the caller should contact someone else.

        @param auth_name human readable name of authority
        """

        # get auth info will throw an exception if the authority doesnt exist
        self.get_auth_info(name)

    def verify_object_belongs_to_me(self, name):
        """
        Verify that an object belongs to our hierarchy. By extension,
        this implies that the authority that owns the object belongs
        to our hierarchy. If it does not an exception is thrown.
    
        @param name human readable name of object        
        """
        auth_name = self.get_authority(name)
        if not auth_name:
            auth_name = name
        if name == self.config.SFA_INTERFACE_HRN:
            return
        self.verify_auth_belongs_to_me(auth_name)

    def verify_auth_belongs_to_me(self, name):
        # get auth info will throw an exception if the authority doesnt exist
        self.get_auth_info(name)

    def verify_object_permission(self, name):
        """
        Verify that the object gid that was specified in the credential
        allows permission to the object 'name'. This is done by a simple
        prefix test. For example, an object_gid for plc.arizona would 
        match the objects plc.arizona.slice1 and plc.arizona.
    
        @param name human readable name to test  
        """
        object_hrn = self.object_gid.get_hrn()
        logger.debug(
            "VERIFY OBJECT PERMISSION. \n\n object_hrn: %s \n name: %s \n get_authority(name): %s"
            % (object_hrn, name, get_authority(name)))
        if object_hrn == name:
            return
        if name.startswith(object_hrn + "."):
            return
        #if name.startswith(get_authority(name)):
        #return

        raise PermissionError(name)

    def determine_user_rights(self, caller_hrn, reg_record):
        """
        Given a user credential and a record, determine what set of rights the
        user should have to that record.
        
        This is intended to replace determine_user_rights() and
        verify_cancreate_credential()
        """

        rl = Rights()
        type = reg_record.type

        logger.debug(
            "entering determine_user_rights with record %s and caller_hrn %s" %
            (reg_record, caller_hrn))

        if type == 'slice':
            # researchers in the slice are in the DB as-is
            researcher_hrns = [user.hrn for user in reg_record.reg_researchers]
            # locating PIs attached to that slice
            slice_pis = reg_record.get_pis()
            pi_hrns = [user.hrn for user in slice_pis]
            if (caller_hrn in researcher_hrns + pi_hrns):
                rl.add('refresh')
                rl.add('embed')
                rl.add('bind')
                rl.add('control')
                rl.add('info')

        elif type == 'authority':
            pi_hrns = [user.hrn for user in reg_record.reg_pis]
            if (caller_hrn == self.config.SFA_INTERFACE_HRN):
                rl.add('authority')
                rl.add('sa')
                rl.add('ma')
            if (caller_hrn in pi_hrns):
                rl.add('authority')
                rl.add('sa')
            # NOTE: for the PL implementation, this 'operators' list
            # amounted to users with 'tech' role in that site
            # it seems like this is not needed any longer, so for now I just drop that
            # operator_hrns = reg_record.get('operator',[])
            # if (caller_hrn in operator_hrns):
            #    rl.add('authority')
            #    rl.add('ma')

        elif type == 'user':
            rl.add('refresh')
            rl.add('resolve')
            rl.add('info')

        elif type == 'node':
            rl.add('operator')

        return rl

    def get_authority(self, hrn):
        return get_authority(hrn)

    def filter_creds_by_caller(self, creds, caller_hrn_list):
        """
        Returns a list of creds who's gid caller matches the 
        specified caller hrn
        """
        if not isinstance(creds, list):
            creds = [creds]
        creds = []
        if not isinstance(caller_hrn_list, list):
            caller_hrn_list = [caller_hrn_list]
        for cred in creds:
            try:
                tmp_cred = Credential(string=cred)
                if tmp_cred.get_gid_caller().get_hrn() in [caller_hrn_list]:
                    creds.append(cred)
            except:
                pass
        return creds
예제 #40
0
def get_gids(registry=None, verbose=False):
    """
    Get the gid for all instantiated slices on this node and store it
    in /etc/sfa/slice.gid in the slice's filesystem
    """
    # define useful variables
    config = Config()
    data_dir = config.data_path
    config_dir = config.SFA_CONFIG_DIR
    trusted_certs_dir = config.get_trustedroots_dir()
    keyfile = data_dir + os.sep + "server.key"
    certfile = data_dir + os.sep + "server.cert"
    node_gid_file = config_dir + os.sep + "node.gid"
    node_gid = GID(filename=node_gid_file)
    hrn = node_gid.get_hrn()
    interface_hrn = config.SFA_INTERFACE_HRN
    # get credential
    cred = GetCredential(registry=registry, verbose=verbose)
    # make sure server key cert pair exists
    create_server_keypair(keyfile=keyfile,
                          certfile=certfile,
                          hrn=hrn,
                          verbose=verbose)
    registry = server_proxy(url=registry, keyfile=keyfile, certfile=certfile)

    if verbose:
        print "Getting current slices on this node"
    # get a list of slices on this node
    from sfa.generic import Generic
    generic = Generic.the_flavour()
    api = generic.make_api(interface='component')
    xids_tuple = api.driver.nodemanager.GetXIDs()
    slices = eval(xids_tuple[1])
    slicenames = slices.keys()

    # generate a list of slices that dont have gids installed
    slices_without_gids = []
    for slicename in slicenames:
        if not os.path.isfile("/vservers/%s/etc/slice.gid" % slicename) \
        or not os.path.isfile("/vservers/%s/etc/node.gid" % slicename):
            slices_without_gids.append(slicename)

    # convert slicenames to hrns
    hrns = [slicename_to_hrn(interface_hrn, slicename) \
            for slicename in slices_without_gids]

    # exit if there are no gids to install
    if not hrns:
        return

    if verbose:
        print "Getting gids for slices on this node from registry"
    # get the gids
    # and save them in the right palce
    records = registry.GetGids(hrns, cred)
    for record in records:
        # if this isnt a slice record skip it
        if not record['type'] == 'slice':
            continue
        slicename = hrn_to_pl_slicename(record['hrn'])
        # if this slice isnt really instatiated skip it
        if not os.path.exists("/vservers/%(slicename)s" % locals()):
            continue

        # save the slice gid in /etc/sfa/ in the vservers filesystem
        vserver_path = "/vservers/%(slicename)s" % locals()
        gid = record['gid']
        slice_gid_filename = os.sep.join([vserver_path, "etc", "slice.gid"])
        if verbose:
            print "Saving GID for %(slicename)s as %(slice_gid_filename)s" % locals(
            )
        GID(string=gid).save_to_file(slice_gid_filename, save_parents=True)
        # save the node gid in /etc/sfa
        node_gid_filename = os.sep.join([vserver_path, "etc", "node.gid"])
        if verbose:
            print "Saving node GID for %(slicename)s as %(node_gid_filename)s" % locals(
            )
        node_gid.save_to_file(node_gid_filename, save_parents=True)