Пример #1
0
    def getCredential(self):
        """
        Get our credential from a remote registry
        """
        path = self.config.SFA_DATA_DIR
        config_dir = self.config.config_path
        cred_filename = path + os.sep + 'node.cred'
        try:
            credential = Credential(filename = cred_filename)
            return credential.save_to_string(save_parents=True)
        except IOError:
            node_pkey_file = config_dir + os.sep + "node.key"
            node_gid_file = config_dir + os.sep + "node.gid"
            cert_filename = path + os.sep + 'server.cert'
            if not os.path.exists(node_pkey_file) or \
               not os.path.exists(node_gid_file):
                self.get_node_key()

            # get node's hrn
            gid = GID(filename=node_gid_file)
            hrn = gid.get_hrn()
            # get credential from registry
            cert_str = Certificate(filename=cert_filename).save_to_string(save_parents=True)
            registry = self.get_registry()
            cred = registry.GetSelfCredential(cert_str, hrn, 'node')
            # xxx credfile is undefined
            Credential(string=cred).save_to_file(credfile, save_parents=True)            

            return cred
Пример #2
0
    def check_gid(self, xrn=None, type=None, all=None, verbose=None):
        """Check the correspondance between the GID and the PubKey"""

        # db records
        from sfa.storage.model import RegRecord
        db_query = self.api.dbsession().query(RegRecord).filter_by(type=type)
        if xrn and not all:
            hrn = Xrn(xrn).get_hrn()
            db_query = db_query.filter_by(hrn=hrn)
        elif all and xrn:
            print "Use either -a or -x <xrn>, not both !!!"
            sys.exit(1)
        elif not all and not xrn:
            print "Use either -a or -x <xrn>, one of them is mandatory !!!"
            sys.exit(1)

        records = db_query.all()
        if not records:
            print "No Record found"
            sys.exit(1)

        OK = []
        NOK = []
        ERROR = []
        NOKEY = []
        for record in records:
             # get the pubkey stored in SFA DB
             if record.reg_keys:
                 db_pubkey_str = record.reg_keys[0].key
                 try:
                   db_pubkey_obj = convert_public_key(db_pubkey_str)
                 except:
                   ERROR.append(record.hrn)
                   continue
             else:
                 NOKEY.append(record.hrn)
                 continue

             # get the pubkey from the gid
             gid_str = record.gid
             gid_obj = GID(string = gid_str)
             gid_pubkey_obj = gid_obj.get_pubkey()

             # Check if gid_pubkey_obj and db_pubkey_obj are the same
             check = gid_pubkey_obj.is_same(db_pubkey_obj)
             if check :
                 OK.append(record.hrn)
             else:
                 NOK.append(record.hrn)

        if not verbose:
            print "Users NOT having a PubKey: %s\n\
Users having a non RSA PubKey: %s\n\
Users having a GID/PubKey correpondence OK: %s\n\
Users having a GID/PubKey correpondence Not OK: %s\n"%(len(NOKEY), len(ERROR), len(OK), len(NOK))
        else:
            print "Users NOT having a PubKey: %s and are: \n%s\n\n\
Users having a non RSA PubKey: %s and are: \n%s\n\n\
Users having a GID/PubKey correpondence OK: %s and are: \n%s\n\n\
Users having a GID/PubKey correpondence NOT OK: %s and are: \n%s\n\n"%(len(NOKEY),NOKEY, len(ERROR), ERROR, len(OK), OK, len(NOK), NOK)
Пример #3
0
    def delegate(self, delegee_gidfile, caller_keyfile, caller_gidfile):
        """
        Return a delegated copy of this credential, delegated to the 
        specified gid's user.    
        """
        # get the gid of the object we are delegating
        object_gid = self.get_gid_object()
        object_hrn = object_gid.get_hrn()

        # the hrn of the user who will be delegated to
        delegee_gid = GID(filename=delegee_gidfile)
        delegee_hrn = delegee_gid.get_hrn()

        #user_key = Keypair(filename=keyfile)
        #user_hrn = self.get_gid_caller().get_hrn()
        subject_string = "%s delegated to %s" % (object_hrn, delegee_hrn)
        dcred = Credential(subject=subject_string)
        dcred.set_gid_caller(delegee_gid)
        dcred.set_gid_object(object_gid)
        dcred.set_parent(self)
        dcred.set_expiration(self.get_expiration())
        dcred.set_privileges(self.get_privileges())
        dcred.get_privileges().delegate_all_privileges(True)
        #dcred.set_issuer_keys(keyfile, delegee_gidfile)
        dcred.set_issuer_keys(caller_keyfile, caller_gidfile)
        dcred.encode()
        dcred.sign()

        return dcred
Пример #4
0
    def delegate(self, delegee_gidfile, caller_keyfile, caller_gidfile):
        """
        Return a delegated copy of this credential, delegated to the 
        specified gid's user.    
        """
        # get the gid of the object we are delegating
        object_gid = self.get_gid_object()
        object_hrn = object_gid.get_hrn()        
 
        # the hrn of the user who will be delegated to
        delegee_gid = GID(filename=delegee_gidfile)
        delegee_hrn = delegee_gid.get_hrn()
  
        #user_key = Keypair(filename=keyfile)
        #user_hrn = self.get_gid_caller().get_hrn()
        subject_string = "%s delegated to %s" % (object_hrn, delegee_hrn)
        dcred = Credential(subject=subject_string)
        dcred.set_gid_caller(delegee_gid)
        dcred.set_gid_object(object_gid)
        dcred.set_parent(self)
        dcred.set_expiration(self.get_expiration())
        dcred.set_privileges(self.get_privileges())
        dcred.get_privileges().delegate_all_privileges(True)
        #dcred.set_issuer_keys(keyfile, delegee_gidfile)
        dcred.set_issuer_keys(caller_keyfile, caller_gidfile)
        dcred.encode()
        dcred.sign()

        return dcred
Пример #5
0
def export_gid(options):
    from sfa.util.table import SfaTable
    # lookup the record for the specified hrn 
    hrn = options.export
    type = options.type
    # check sfa table first
    filter = {'hrn': hrn}
    if type:
        filter['type'] = type                    
    table = SfaTable()
    records = table.find(filter)
    if not records:
        # check the authorities hierarchy 
        hierarchy = Hierarchy()
        try:
            auth_info = hierarchy.get_auth_info()
            gid = auth_info.gid_object 
        except:
            print "Record: %s not found" % hrn
            sys.exit(1)
    else:
        record = records[0]
        gid = GID(string=record['gid'])
        
    # get the outfile
    outfile = options.outfile
    if not outfile:
        outfile = os.path.abspath('./%s.gid' % gid.get_hrn())

    # save it
    if options.verbose:
        print "Writing %s gid to %s" % (gid.get_hrn(), outfile)
    gid.save_to_file(outfile, save_parents=True)
Пример #6
0
def get_username_from_cert(cert_string):
    try:
        gid = GID(string=cert_string)
        
        # extract the URN in the subjectAltName
        urn_str = gid.get_urn()
        
        logger.debug("URN: %s" % urn_str)
        
    except:
        logger.warn("Failed to get certificate from string.")
        logger.warn(traceback.format_exc())
        return cert_string
    
    try:
        urn = URN(urn=str(urn_str))
    except ValueError:
        return cert_string
    
    # check if this user is one of ours
    home_urn = get_user_urn(urn.getName())
    if home_urn == urn.urn_string():
        username = urn.getName()
    else:
        username = urn_to_username(urn.urn_string())
        
    logger.debug("Returning username %s" % username)
    
    return username
Пример #7
0
    def clean(self):
        """Check that the cert file is signed by the key file and is trusted."""
        logger.debug("cleaned_data %s" % self.cleaned_data)
        if self.files:
            self.key = Keypair(string=self.files["key_file"].read())
            self.cert = GID(string=self.files["cert_file"].read())

            cert_pubkey = self.cert.get_pubkey().get_pubkey_string()
            if cert_pubkey != self.key.get_pubkey_string():
                raise forms.ValidationError(
                    "Error: The certificate was not signed "
                    "by the uploaded key. Please use a key "
                    "that matches the certificate.")

            try:
                certs = [GID(filename=f) for f in get_trusted_cert_filenames()]
                self.cert.verify_chain(certs)
            except Exception as e:
                logger.error(traceback.format_exc())
                raise forms.ValidationError(
                    "Could not verify that the uploaded certificate is "
                    "trusted. This could be because none of the certificate's "
                    "ancestors have been installed as trusted. The error was: "
                    "%s" % e)

        return self.cleaned_data
Пример #8
0
    def get_cert_file(self, key_file):
    
        cert_file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cert")
        if (os.path.isfile(cert_file)):
            # we'd perfer to use Registry issued certs instead of self signed certs. 
            # if this is a Registry cert (GID) then we are done 
            gid = GID(filename=cert_file)
            if gid.get_urn():
                return cert_file

        # generate self signed certificate
        k = Keypair(filename=key_file)
        cert = Certificate(subject=self.user)
        cert.set_pubkey(k)
        cert.set_issuer(k, self.user)
        cert.sign()
        self.logger.info("Writing self-signed certificate to %s"%cert_file)
        cert.save_to_file(cert_file)
        self.cert = cert
        # try to get registry issued cert
        try:
            self.logger.info("Getting Registry issued cert")
            self.read_config()
            # *hack.  need to set registyr before _get_gid() is called 
            self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug)
            gid = self._get_gid(type='user')
            self.registry = None 
            self.logger.info("Writing certificate to %s"%cert_file)
            gid.save_to_file(cert_file)
        except:
            self.logger.info("Failed to download Registry issued cert")

        return cert_file
Пример #9
0
    def decode(self):
        data = self.get_data().lstrip('URI:http://')

        if data:
            dict = xmlrpclib.loads(data)[0][0]
        else:
            dict = {}

        self.lifeTime = dict.get("lifeTime", None)
        self.delegate = dict.get("delegate", None)

        privStr = dict.get("privileges", None)
        if privStr:
            self.privileges = Rights(string=privStr)
        else:
            self.privileges = None

        gidCallerStr = dict.get("gidCaller", None)
        if gidCallerStr:
            self.gidCaller = GID(string=gidCallerStr)
        else:
            self.gidCaller = None

        gidObjectStr = dict.get("gidObject", None)
        if gidObjectStr:
            self.gidObject = GID(string=gidObjectStr)
        else:
            self.gidObject = None
Пример #10
0
    def _get_gid(self, hrn=None, type=None):
        """
        git_gid helper. Retrive the gid from the registry and save it to file.
        """
        
        if not hrn:
            hrn = self.user
 
        gidfile = os.path.join(self.options.sfi_dir, hrn + ".gid")
        gid = self.get_cached_gid(gidfile)
        if not gid:
            user_cred = self.get_user_cred()
            records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True))
            if not records:
                raise RecordNotFound(args[0])
            record = records[0]
            if type:
                record=None
                for rec in records:
                   if type == rec['type']:
                        record = rec 
            if not record:
                raise RecordNotFound(args[0])
            
            gid = GID(string=record['gid'])
            self.logger.info("Writing gid to %s"%gidfile)
            gid.save_to_file(filename=gidfile)
        return gid   
Пример #11
0
def install_peer_certs(server_key_file, server_cert_file):
    """
    Attempt to install missing trusted gids and db records for 
    our federated interfaces
    """
    # Attempt to get any missing peer gids
    # There should be a gid file in /etc/sfa/trusted_roots for every
    # peer registry found in in the registries.xml config file. If there
    # are any missing gids, request a new one from the peer registry.
    api = SfaAPI(key_file=server_key_file, cert_file=server_cert_file)
    registries = Registries()
    aggregates = Aggregates()
    interfaces = dict(registries.items() + aggregates.items())
    gids_current = api.auth.trusted_cert_list
    hrns_current = [gid.get_hrn() for gid in gids_current]
    hrns_expected = set([hrn for hrn in interfaces])
    new_hrns = set(hrns_expected).difference(hrns_current)
    # gids = self.get_peer_gids(new_hrns) + gids_current
    peer_gids = []
    if not new_hrns:
        return

    trusted_certs_dir = api.config.get_trustedroots_dir()
    for new_hrn in new_hrns:
        if not new_hrn:
            continue
        # the gid for this interface should already be installed
        if new_hrn == api.config.SFA_INTERFACE_HRN:
            continue
        try:
            # get gid from the registry
            url = interfaces[new_hrn].get_url()
            interface = interfaces[new_hrn].get_server(server_key_file, server_cert_file, timeout=30)
            # skip non sfa aggregates
            server_version = api.get_cached_server_version(interface)
            if "sfa" not in server_version:
                logger.info("get_trusted_certs: skipping non sfa aggregate: %s" % new_hrn)
                continue

            trusted_gids = interface.get_trusted_certs()
            if trusted_gids:
                # the gid we want should be the first one in the list,
                # but lets make sure
                for trusted_gid in trusted_gids:
                    # default message
                    message = "interface: %s\t" % (api.interface)
                    message += "unable to install trusted gid for %s" % (new_hrn)
                    gid = GID(string=trusted_gids[0])
                    peer_gids.append(gid)
                    if gid.get_hrn() == new_hrn:
                        gid_filename = os.path.join(trusted_certs_dir, "%s.gid" % new_hrn)
                        gid.save_to_file(gid_filename, save_parents=True)
                        message = "installed trusted cert for %s" % new_hrn
                    # log the message
                    api.logger.info(message)
        except:
            message = "interface: %s\tunable to install trusted gid for %s" % (api.interface, new_hrn)
            api.logger.log_exc(message)
    # doesnt matter witch one
    update_cert_records(peer_gids)
Пример #12
0
    def getCredential(self):
        """
        Get our credential from a remote registry
        """
        path = self.config.SFA_DATA_DIR
        config_dir = self.config.config_path
        cred_filename = path + os.sep + 'node.cred'
        try:
            credential = Credential(filename=cred_filename)
            return credential.save_to_string(save_parents=True)
        except IOError:
            node_pkey_file = config_dir + os.sep + "node.key"
            node_gid_file = config_dir + os.sep + "node.gid"
            cert_filename = path + os.sep + 'server.cert'
            if not os.path.exists(node_pkey_file) or \
               not os.path.exists(node_gid_file):
                self.get_node_key()

            # get node's hrn
            gid = GID(filename=node_gid_file)
            hrn = gid.get_hrn()
            # get credential from registry
            cert_str = Certificate(filename=cert_filename).save_to_string(
                save_parents=True)
            registry = self.get_registry()
            cred = registry.GetSelfCredential(cert_str, hrn, 'node')
            # xxx credfile is undefined
            Credential(string=cred).save_to_file(credfile, save_parents=True)

            return cred
Пример #13
0
    def GetCredential(self, api, xrn, type, caller_xrn=None):
        # convert xrn to hrn     
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        # Is this a root or sub authority
        auth_hrn = api.auth.get_authority(hrn)
        if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = api.auth.get_auth_info(auth_hrn)
        # get record info
        record=dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s"%(hrn,type))

        # get the callers gid
        # if caller_xrn is not specified assume the caller is the record
        # object itself.
        if not caller_xrn:
            caller_hrn = hrn
            caller_gid = record.get_gid_object()
        else:
            caller_hrn, caller_type = urn_to_hrn(caller_xrn)
            if caller_type:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn,type=caller_type).first()
            else:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn).first()
            if not caller_record:
                raise RecordNotFound("Unable to associated caller (hrn=%s, type=%s) with credential for (hrn: %s, type: %s)"%(caller_hrn, caller_type, hrn, type))
            caller_gid = GID(string=caller_record.gid)i

        object_hrn = record.get_gid_object().get_hrn()
        # call the builtin authorization/credential generation engine
        rights = api.auth.determine_user_rights(caller_hrn, record)
        # make sure caller has rights to this object
        if rights.is_empty():
            raise PermissionError("%s has no rights to %s (%s)" % \
                                  (caller_hrn, object_hrn, xrn))
        object_gid = GID(string=record.gid)
        new_cred = Credential(subject = object_gid.get_subject())
        new_cred.set_gid_caller(caller_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
        #new_cred.set_pubkey(object_gid.get_pubkey())
        new_cred.set_privileges(rights)
        new_cred.get_privileges().delegate_all_privileges(True)
        if hasattr(record,'expires'):
            date = utcparse(record.expires)
            expires = datetime_to_epoch(date)
            new_cred.set_expiration(int(expires))
        auth_kind = "authority,ma,sa"
        # Parent not necessary, verify with certs
        #new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
        new_cred.encode()
        new_cred.sign()

        return new_cred.save_to_string(save_parents=True)
Пример #14
0
    def GetCredential(self, api, xrn, type, caller_xrn=None):
        # convert xrn to hrn     
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        # Is this a root or sub authority
        auth_hrn = api.auth.get_authority(hrn)
        if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = api.auth.get_auth_info(auth_hrn)
        # get record info
        record=dbsession.query(RegRecord).filter_by(type=type,hrn=hrn).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s"%(hrn,type))

        # get the callers gid
        # if caller_xrn is not specified assume the caller is the record
        # object itself.
        if not caller_xrn:
            caller_hrn = hrn
            caller_gid = record.get_gid_object()
        else:
            caller_hrn, caller_type = urn_to_hrn(caller_xrn)
            if caller_type:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn,type=caller_type).first()
            else:
                caller_record = dbsession.query(RegRecord).filter_by(hrn=caller_hrn).first()
            if not caller_record:
                raise RecordNotFound("Unable to associated caller (hrn=%s, type=%s) with credential for (hrn: %s, type: %s)"%(caller_hrn, caller_type, hrn, type))
            caller_gid = GID(string=caller_record.gid)

        object_hrn = record.get_gid_object().get_hrn()
        # call the builtin authorization/credential generation engine
        rights = api.auth.determine_user_rights(caller_hrn, record)
        # make sure caller has rights to this object
        if rights.is_empty():
            raise PermissionError("%s has no rights to %s (%s)" % \
                                  (caller_hrn, object_hrn, xrn))
        object_gid = GID(string=record.gid)
        new_cred = Credential(subject = object_gid.get_subject())
        new_cred.set_gid_caller(caller_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
        #new_cred.set_pubkey(object_gid.get_pubkey())
        new_cred.set_privileges(rights)
        new_cred.get_privileges().delegate_all_privileges(True)
        if hasattr(record,'expires'):
            date = utcparse(record.expires)
            expires = datetime_to_epoch(date)
            new_cred.set_expiration(int(expires))
        auth_kind = "authority,ma,sa"
        # Parent not necessary, verify with certs
        #new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
        new_cred.encode()
        new_cred.sign()

        return new_cred.save_to_string(save_parents=True)
Пример #15
0
 def display(self, gidfile):
     """Print contents of a GID file"""
     gid_path = os.path.abspath(gidfile)
     if not gid_path or not os.path.isfile(gid_path):
         print "No such gid file: %s" % gidfile
         sys.exit(1)
     gid = GID(filename=gid_path)
     gid.dump(dump_parents=True)
Пример #16
0
 def display(self, gidfile):
     """Print contents of a GID file"""
     gid_path = os.path.abspath(gidfile)
     if not gid_path or not os.path.isfile(gid_path):
         print "No such gid file: %s" % gidfile
         sys.exit(1)
     gid = GID(filename=gid_path)
     gid.dump(dump_parents=True)
Пример #17
0
def get_credential(api, xrn, type, is_self=False):
    # convert xrn to hrn     
    if type:
        hrn = urn_to_hrn(xrn)[0]
    else:
        hrn, type = urn_to_hrn(xrn)
        
    # Is this a root or sub authority
    auth_hrn = api.auth.get_authority(hrn)
    if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
        auth_hrn = hrn
    # get record info
    auth_info = api.auth.get_auth_info(auth_hrn)
    table = SfaTable()
    records = table.findObjects({'type': type, 'hrn': hrn})
    if not records:
        raise RecordNotFound(hrn)
    record = records[0]

    # verify_cancreate_credential requires that the member lists
    # (researchers, pis, etc) be filled in
    api.fill_record_info(record)
    if record['type']=='user':
       if not record['enabled']:
          raise AccountNotEnabled(": PlanetLab account %s is not enabled. Please contact your site PI" %(record['email']))

    # get the callers gid
    # if this is a self cred the record's gid is the caller's gid
    if is_self:
        caller_hrn = hrn
        caller_gid = record.get_gid_object()
    else:
        caller_gid = api.auth.client_cred.get_gid_caller() 
        caller_hrn = caller_gid.get_hrn()
    
    object_hrn = record.get_gid_object().get_hrn()
    rights = api.auth.determine_user_rights(caller_hrn, record)
    # make sure caller has rights to this object
    if rights.is_empty():
        raise PermissionError(caller_hrn + " has no rights to " + record['name'])

    object_gid = GID(string=record['gid'])
    new_cred = Credential(subject = object_gid.get_subject())
    new_cred.set_gid_caller(caller_gid)
    new_cred.set_gid_object(object_gid)
    new_cred.set_issuer_keys(auth_info.get_privkey_filename(), auth_info.get_gid_filename())
    #new_cred.set_pubkey(object_gid.get_pubkey())
    new_cred.set_privileges(rights)
    new_cred.get_privileges().delegate_all_privileges(True)
    if 'expires' in record:
        new_cred.set_expiration(int(record['expires']))
    auth_kind = "authority,ma,sa"
    # Parent not necessary, verify with certs
    #new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
    new_cred.encode()
    new_cred.sign()

    return new_cred.save_to_string(save_parents=True)
Пример #18
0
def display(options):
    """
    Display the sepcified GID
    """
    gidfile = os.path.abspath(options.display)
    if not gidfile or not os.path.isfile(gidfile):
        print "No such gid: %s" % gidfile
        sys.exit(1)
    gid = GID(filename=gidfile)
    gid.dump(dump_parents=True)
Пример #19
0
 def get_trusted_certs(self, opts, args):
     """
     return uhe trusted certs at this interface 
     """ 
     trusted_certs = self.registry.get_trusted_certs()
     for trusted_cert in trusted_certs:
         gid = GID(string=trusted_cert)
         gid.dump()
         cert = Certificate(string=trusted_cert)
         self.logger.debug('Sfi.get_trusted_certs -> %r'%cert.get_subject())
     return 
Пример #20
0
class UploadCertForm(forms.Form):
    """Form to upload a certificate and its corresponding key."""
    
    key_file = forms.FileField(
        help_text="Select the file that contains the key for the "\
            "certificate to upload.")
    cert_file = forms.FileField(
        help_text="Select the file that contains the "\
            "certificate to upload. The certificate must be signed "\
            "with the uploaded key.")
    
    clean_key_file = _clean_x_file_factory("key")
    clean_cert_file = _clean_x_file_factory("cert")
            
    def clean(self):
        """Check that the cert file is signed by the key file and is trusted."""
        logger.debug("cleaned_data %s" % self.cleaned_data)
        if self.files:
            self.key = Keypair(string=self.files["key_file"].read())
            self.cert = GID(string=self.files["cert_file"].read())
            
            cert_pubkey = self.cert.get_pubkey().get_pubkey_string()
            if cert_pubkey != self.key.get_pubkey_string():
                raise forms.ValidationError(
                    "Error: The certificate was not signed "
                    "by the uploaded key. Please use a key "
                    "that matches the certificate.")
    
            try:
                certs = [GID(filename=f) for f in get_trusted_cert_filenames()]
                self.cert.verify_chain(certs)
            except Exception as e:
                logger.error(traceback.format_exc())
                raise forms.ValidationError(
                    "Could not verify that the uploaded certificate is "
                    "trusted. This could be because none of the certificate's "
                    "ancestors have been installed as trusted. The error was: "
                    "%s" % e
                )

        return self.cleaned_data
    
    def save(self, user):
        """Write the key and cert into files.
        
        @param user: the user to save the cert and key for.
        @type user: C{django.contrib.auth.models.User}
        """
        
        key_fname = get_user_key_fname(user)
        cert_fname = get_user_cert_fname(user)
        
        self.key.save_to_file(key_fname)
        self.cert.save_to_file(cert_fname)
Пример #21
0
class UploadCertForm(forms.Form):
    """Form to upload a certificate and its corresponding key."""

    key_file = forms.FileField(
        help_text="Select the file that contains the key for the "\
            "certificate to upload.")
    cert_file = forms.FileField(
        help_text="Select the file that contains the "\
            "certificate to upload. The certificate must be signed "\
            "with the uploaded key.")

    clean_key_file = _clean_x_file_factory("key")
    clean_cert_file = _clean_x_file_factory("cert")

    def clean(self):
        """Check that the cert file is signed by the key file and is trusted."""
        logger.debug("cleaned_data %s" % self.cleaned_data)
        if self.files:
            self.key = Keypair(string=self.files["key_file"].read())
            self.cert = GID(string=self.files["cert_file"].read())

            cert_pubkey = self.cert.get_pubkey().get_pubkey_string()
            if cert_pubkey != self.key.get_pubkey_string():
                raise forms.ValidationError(
                    "Error: The certificate was not signed "
                    "by the uploaded key. Please use a key "
                    "that matches the certificate.")

            try:
                certs = [GID(filename=f) for f in get_trusted_cert_filenames()]
                self.cert.verify_chain(certs)
            except Exception as e:
                logger.error(traceback.format_exc())
                raise forms.ValidationError(
                    "Could not verify that the uploaded certificate is "
                    "trusted. This could be because none of the certificate's "
                    "ancestors have been installed as trusted. The error was: "
                    "%s" % e)

        return self.cleaned_data

    def save(self, user):
        """Write the key and cert into files.
        
        @param user: the user to save the cert and key for.
        @type user: C{django.contrib.auth.models.User}
        """

        key_fname = get_user_key_fname(user)
        cert_fname = get_user_cert_fname(user)

        self.key.save_to_file(key_fname)
        self.cert.save_to_file(cert_fname)
Пример #22
0
def install_gids(api, slivers):
    # install node gid
    node_gid_file = api.config.config_path + os.sep + "node.gid"
    node_gid = GID(filename=node_gid_file)
    node_gid_str = node_gid.save_to_string(save_parents=True)    
    node_hrn = node_gid.get_hrn()    

    # get currently installed slice and node gids 
    interface_hrn = api.config.SFA_INTERFACE_HRN
    slice_gids = {}
    node_gids = {}
    for slicename in slivers:
        slice_gid_filename = "/vservers/%s/etc/slice.gid" % slicename
        node_gid_filename = "/vservers/%s/etc/node.gid" % slicename
        if os.path.isfile(slice_gid_filename):
            gid_file = open(slice_gid_filename, 'r') 
            slice_gids[sliver] = gid_file.read()
            gid_file.close()
        if os.path.isfile(node_gid_filename):
            gid_file = open(node_gid_filename, 'r')
            node_gids[sliver] = gid_file.read()
            gid_file.close()

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

    # get current gids from registry
    cred = api.getCredential()
    registry = api.get_registry()
    #records = registry.GetGids(cred, hrns)
    records = registry.get_gids(cred, hrns)
    for record in records:
        # skip if this isnt a slice record 
        if not record['type'] == 'slice':
            continue
        vserver_path = "/vservers/%(slicename)s" % locals()
        # skip if the slice isnt instantiated
        if not os.path.exists(vserver_path):
            continue
        
        # install slice gid if it doesnt already exist or has changed
        slice_gid_str = record['gid']
        slicename = hrn_to_pl_slicename(record['hrn'])
        if slicename not in slice_gids or slice_gids[slicename] != slice_gid_str:
            gid_filename = os.sep.join([vserver_path, "etc", "slice.gid"])
            GID(string=slice_gid_str).save_to_file(gid_filename, save_parents=True)

        # install slice gid if it doesnt already exist or has changed
        if slicename not in node_gids or node_gids[slicename] != node_gid_str:
            gid_filename = os.sep.join([vserver_path, "etc", "node.gid"])
            GID(string=node_gid_str).save_to_file(gid_filename, save_parents=True) 
Пример #23
0
    def sign(self):
        if not self.issuer_privkey:
            logger.warn("Cannot sign credential (no private key)")
            return
        if not self.issuer_gid:
            logger.warn("Cannot sign credential (no issuer gid)")
            return
        doc = parseString(self.get_xml())
        sigs = doc.getElementsByTagName("signatures")[0]

        # Create the signature template to be signed
        signature = Signature()
        signature.set_refid(self.get_refid())
        sdoc = parseString(signature.get_xml())        
        sig_ele = doc.importNode(sdoc.getElementsByTagName("Signature")[0], True)
        sigs.appendChild(sig_ele)

        self.xml = doc.toxml()


        # Split the issuer GID into multiple certificates if it's a chain
        chain = GID(filename=self.issuer_gid)
        gid_files = []
        while chain:
            gid_files.append(chain.save_to_random_tmp_file(False))
            if chain.get_parent():
                chain = chain.get_parent()
            else:
                chain = None


        # Call out to xmlsec1 to sign it
        ref = 'Sig_%s' % self.get_refid()
        filename = self.save_to_random_tmp_file()
        command='%s --sign --node-id "%s" --privkey-pem %s,%s %s' \
            % (self.xmlsec_path, ref, self.issuer_privkey, ",".join(gid_files), filename)
#        print 'command',command
        signed = os.popen(command).read()
        os.remove(filename)

        for gid_file in gid_files:
            os.remove(gid_file)

        self.xml = signed

        # This is no longer a legacy credential
        if self.legacy:
            self.legacy = None

        # Update signatures
        self.decode()       
Пример #24
0
def read_cert_from_file(cert_fname):
    """Read a GCF certificate from a file.
    
    Read the certificate from a file and put it into a C{sfa.trust.gid.GID}
    object. The returned certificate is already decoded.
    
    @param cert_fname: The filename to read the cert from
    @type cert_fname: C{str}
    @return: The certificate stored in the file at C{cert_fname}
    @rtype: C{sfa.trust.gid.GID}
    """

    cert = GID(filename=cert_fname)
    cert.decode()
    return cert
Пример #25
0
def read_cert_from_file(cert_fname):
    """Read a GCF certificate from a file.
    
    Read the certificate from a file and put it into a C{sfa.trust.gid.GID}
    object. The returned certificate is already decoded.
    
    @param cert_fname: The filename to read the cert from
    @type cert_fname: C{str}
    @return: The certificate stored in the file at C{cert_fname}
    @rtype: C{sfa.trust.gid.GID}
    """
    
    cert = GID(filename=cert_fname)
    cert.decode()
    return cert
Пример #26
0
    def delegate_cred(self, object_cred, hrn, type='authority'):

        # the gid and hrn of the object we are delegating
        if isinstance(object_cred, str):  # XXX Yes here we give a string...
            object_cred = Credential(string=object_cred)
        object_gid = object_cred.get_gid_object()
        object_hrn = object_gid.get_hrn()

        if not object_cred.get_privileges().get_all_delegate():
            self.logger.error(
                "Object credential %s does not have delegate bit set" %
                object_hrn)
            return

        # the delegating user's gid # XXX done in bootstrap
        caller_gidfile = self.my_gid  # already a string # XXX ERROR tell thierry

        # the gid of the user who will be delegated to
        delegee_gid = self.bootstrap.gid(
            hrn, 'user')  # XXX bootstrap ERROR tell thierry
        delegee_hrn = GID(delegee_gid).get_hrn()
        # XXX pkey done in bootstrap
        dcred = object_cred.delegate(delegee_gid, self.private_key,
                                     caller_gidfile)
        return dcred.save_to_string(save_parents=True)
Пример #27
0
def determine_sfa_filekind(fn):

    if fn.endswith('.gid'): return 'gid'
    elif fn.endswith('.cert'): return 'certificate'
    elif fn.endswith('cred'): return 'credential'

    try:
        cred=Credential(filename=fn)
        return 'credential'
    except: pass

    try: 
        gid=GID(filename=fn)
        if gid.uuid: return 'gid'
    except: pass

    try:
        cert = Certificate(filename = fn)
        return 'certificate'
    except: pass

    # to be completed
#    if "gidCaller" in dict:
#        return "credential"
#
#    if "uuid" in dict:
#        return "gid"

    return "unknown"
Пример #28
0
    def clean(self):
        """Check that the cert file is signed by the key file and is trusted."""
        logger.debug("cleaned_data %s" % self.cleaned_data)
        if self.files:
            self.key = Keypair(string=self.files["key_file"].read())
            self.cert = GID(string=self.files["cert_file"].read())
            
            cert_pubkey = self.cert.get_pubkey().get_pubkey_string()
            if cert_pubkey != self.key.get_pubkey_string():
                raise forms.ValidationError(
                    "Error: The certificate was not signed "
                    "by the uploaded key. Please use a key "
                    "that matches the certificate.")
    
            try:
                certs = [GID(filename=f) for f in get_trusted_cert_filenames()]
                self.cert.verify_chain(certs)
            except Exception as e:
                logger.error(traceback.format_exc())
                raise forms.ValidationError(
                    "Could not verify that the uploaded certificate is "
                    "trusted. This could be because none of the certificate's "
                    "ancestors have been installed as trusted. The error was: "
                    "%s" % e
                )

        return self.cleaned_data
Пример #29
0
def create_null_slice_cred():
    """Create a slice cred that can be used to list resources."""
    slice_urn = create_slice_urn()
    slice_gid, _ = create_x509_cert(slice_urn) 
    user_gid = GID(filename=settings.GCF_X509_CH_CERT)
    ucred = create_slice_credential(user_gid, slice_gid)
    ucred.save_to_file(settings.GCF_NULL_SLICE_CRED)
Пример #30
0
 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
Пример #31
0
    def sign(self):
        if not self.issuer_privkey or not self.issuer_gid:
            return
        doc = parseString(self.get_xml())
        sigs = doc.getElementsByTagName("signatures")[0]

        # Create the signature template to be signed
        signature = Signature()
        signature.set_refid(self.get_refid())
        sdoc = parseString(signature.get_xml())
        sig_ele = doc.importNode(
            sdoc.getElementsByTagName("Signature")[0], True)
        sigs.appendChild(sig_ele)

        self.xml = doc.toxml()

        # Split the issuer GID into multiple certificates if it's a chain
        chain = GID(filename=self.issuer_gid)
        gid_files = []
        while chain:
            gid_files.append(chain.save_to_random_tmp_file(False))
            if chain.get_parent():
                chain = chain.get_parent()
            else:
                chain = None

        # Call out to xmlsec1 to sign it
        ref = 'Sig_%s' % self.get_refid()
        filename = self.save_to_random_tmp_file()
        signed = os.popen('%s --sign --node-id "%s" --privkey-pem %s,%s %s' \
                 % (self.xmlsec_path, ref, self.issuer_privkey, ",".join(gid_files), filename)).read()
        os.remove(filename)

        for gid_file in gid_files:
            os.remove(gid_file)

        self.xml = signed

        # This is no longer a legacy credential
        if self.legacy:
            self.legacy = None

        # Update signatures
        self.decode()
Пример #32
0
def init_server_cert(hrn, key, server_cert_file, self_signed=False):
    """
    Setup the certificate for this server. Attempt to use gid before 
    creating a self signed cert 
    """
    if self_signed:
        init_self_signed_cert(hrn, key, server_cert_file)
    else:
        try:
            # look for gid file
            logger.debug("generating server cert from gid: %s" % hrn)
            hierarchy = Hierarchy()
            auth_info = hierarchy.get_auth_info(hrn)
            gid = GID(filename=auth_info.gid_filename)
            gid.save_to_file(filename=server_cert_file)
        except:
            # fall back to self signed cert
            logger.debug("gid for %s not found" % hrn)
            init_self_signed_cert(hrn, key, server_cert_file)
Пример #33
0
 def get_am_cred(cls):
     """
     Get the slice authority credentials to use for AM calls.
     
     @return: GENI credential string.
     """
     slice_urn = create_slice_urn()
     slice_gid, _ = create_x509_cert(slice_urn)
     user_gid = GID(filename=settings.GCF_X509_CH_CERT)
     ucred = create_slice_credential(user_gid, slice_gid)
     return ucred.save_to_string()
Пример #34
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
Пример #35
0
def handle_input_kind (filename, options, kind):
    

# dump methods current do 'print' so let's go this road for now
    if kind=="certificate":
        cert=Certificate (filename=filename)
        print '--------------------',filename,'IS A',kind
        cert.dump(show_extensions=options.show_extensions)
    elif kind=="credential":
        cred = Credential(filename = filename)
        print '--------------------',filename,'IS A',kind
        cred.dump(dump_parents = options.dump_parents, show_xml=options.show_xml)
        if options.extract_gids:
            print '--------------------',filename,'embedded GIDS'
            extract_gids(cred, extract_parents = options.dump_parents)
    elif kind=="gid":
        gid = GID(filename = filename)
        print '--------------------',filename,'IS A',kind
        gid.dump(dump_parents = options.dump_parents)
    else:
        print "%s: unknown filekind '%s'"% (filename,kind)
Пример #36
0
def sign(options):
    """
    Sign the specified gid
    """
    hierarchy = Hierarchy()
    config = Config()
    default_authority = config.SFA_INTERFACE_HRN
    auth_info = hierarchy.get_auth_info(default_authority)

    # load the gid
    gidfile = os.path.abspath(options.sign)
    if not os.path.isfile(gidfile):
        print "no such gid: %s" % gidfile
        sys.exit(1)
    gid = GID(filename=gidfile)

    # extract pub_key and create new gid
    pkey = gid.get_pubkey()
    urn = gid.get_urn()
    gid = hierarchy.create_gid(urn, create_uuid(), pkey)

    # get the outfile
    outfile = options.outfile
    if not outfile:
        outfile = os.path.abspath('./signed-%s.gid' % gid.get_hrn())
   
    # save the signed gid
    if options.verbose:
        print "Writing signed gid %s" % outfile  
    gid.save_to_file(outfile, save_parents=True)
Пример #37
0
    def decode(self):
        data = self.get_data()
        if data:
            dict = xmlrpclib.loads(self.get_data()[4:])[0][0]
        else:
            dict = {}

        self.attributes = dict.get("attributes", {})
        self.rspec = dict.get("rspec", {})
        self.delegate = dict.get("delegate", False)

        gidCallerStr = dict.get("gidCaller", None)
        if gidCallerStr:
            self.gidCaller = GID(string=gidCallerStr)
        else:
            self.gidCaller = None

        gidObjectStr = dict.get("gidObject", None)
        if gidObjectStr:
            self.gidObject = GID(string=gidObjectStr)
        else:
            self.gidObject = None
Пример #38
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
Пример #39
0
 def export(self, xrn, type=None, outfile=None):
     """Fetch an object's GID from the Registry"""  
     from sfa.storage.model import RegRecord
     hrn = Xrn(xrn).get_hrn()
     request=self.api.dbsession().query(RegRecord).filter_by(hrn=hrn)
     if type: request = request.filter_by(type=type)
     record=request.first()
     if record:
         gid = GID(string=record.gid)
     else:
         # check the authorities hierarchy
         hierarchy = Hierarchy()
         try:
             auth_info = hierarchy.get_auth_info(hrn)
             gid = auth_info.gid_object
         except:
             print "Record: %s not found" % hrn
             sys.exit(1)
     # save to file
     if not outfile:
         outfile = os.path.abspath('./%s.gid' % gid.get_hrn())
     gid.save_to_file(outfile, save_parents=True)
Пример #40
0
 def export(self, xrn, type=None, outfile=None):
     """Fetch an object's GID from the Registry"""
     from sfa.storage.model import RegRecord
     hrn = Xrn(xrn).get_hrn()
     request = self.api.dbsession().query(RegRecord).filter_by(hrn=hrn)
     if type: request = request.filter_by(type=type)
     record = request.first()
     if record:
         gid = GID(string=record.gid)
     else:
         # check the authorities hierarchy
         hierarchy = Hierarchy()
         try:
             auth_info = hierarchy.get_auth_info(hrn)
             gid = auth_info.gid_object
         except:
             print "Record: %s not found" % hrn
             sys.exit(1)
     # save to file
     if not outfile:
         outfile = os.path.abspath('./%s.gid' % gid.get_hrn())
     gid.save_to_file(outfile, save_parents=True)
Пример #41
0
def import_gid(options):
    """
    Import the specified gid into the registry (db and authorities 
    hierarchy) overwriting any previous gid.
    """
    from sfa.util.table import SfaTable
    from sfa.util.record import SfaRecord
    # load the gid
    gidfile = os.path.abspath(options.importgid)
    if not gidfile or not os.path.isfile(gidfile):
        print "No such gid: %s" % gidfile
        sys.exit(1)
    gid = GID(filename=gidfile)
    
    # check if it exists within the hierarchy
    hierarchy = Hierarchy()
    if not hierarchy.auth_exists(gid.get_hrn()):
        print "%s not found in hierarchy" % gid.get_hrn()
        sys.exit(1)

    # check if record exists in db
    table = SfaTable()
    records = table.find({'hrn': gid.get_hrn(), 'type': 'authority'})
    if not records:
        print "%s not found in record database" % get.get_hrn()  
        sys.exit(1)

    # update the database record
    record = records[0]
    record['gid'] = gid.save_to_string(save_parents=True)
    table.update(record)
    if options.verbose:
        print "Imported %s gid into db" % record['hrn']

    # update the hierarchy
    auth_info = hierarchy.get_auth_info(gid.get_hrn())  
    filename = auth_info.gid_filename
    gid.save_to_file(filename, save_parents=True)
    if options.verbose:
        print "Writing %s gid to %s" % (gid.get_hrn(), filename)

    # ending here
    return
Пример #42
0
    def set_servers(self):

       self.read_config() 
       # Get key and certificate
       key_file = self.get_key_file()
       cert_file = self.get_cert_file(key_file)
       self.key = Keypair(filename=key_file) 
       self.key_file = key_file
       self.cert_file = cert_file
       self.cert = GID(filename=cert_file)
       self.logger.info("Contacting Registry at: %s"%self.reg_url)
       self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug)  
       self.logger.info("Contacting Slice Manager at: %s"%self.sm_url)
       self.slicemgr = xmlrpcprotocol.get_server(self.sm_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug)
       return
Пример #43
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)                     
Пример #44
0
def handle_input (filename, options):
    kind = determine_sfa_filekind(filename)

    # dump methods current do 'print' so let's go this road for now
    if kind=="certificate":
        cert=Certificate (filename=filename)
        print '--------------------',filename,'IS A',kind
        cert.dump(show_extensions=options.show_extensions)
        verify_input_object (cert, kind, options)
    elif kind=="credential":
        cred = Credential(filename = filename)
        print '--------------------',filename,'IS A',kind
        cred.dump(dump_parents = options.dump_parents, show_xml=options.show_xml)
        if options.extract_gids:
            print '--------------------',filename,'embedded GIDs'
            extract_gids(cred, extract_parents = options.dump_parents)
        verify_input_object (cred, kind, options)
    elif kind=="gid":
        gid = GID(filename = filename)
        print '--------------------',filename,'IS A',kind
        gid.dump(dump_parents = options.dump_parents)
        verify_input_object (gid, kind, options)
    else:
        print "%s: unknown filekind '%s'"% (filename,kind)
Пример #45
0
class Signature(object):
    def __init__(self, string=None):
        self.refid = None
        self.issuer_gid = None
        self.xml = None
        if string:
            self.xml = string
            self.decode()

    def get_refid(self):
        if not self.refid:
            self.decode()
        return self.refid

    def get_xml(self):
        if not self.xml:
            self.encode()
        return self.xml

    def set_refid(self, id):
        self.refid = id

    def get_issuer_gid(self):
        if not self.gid:
            self.decode()
        return self.gid

    def set_issuer_gid(self, gid):
        self.gid = gid

    def decode(self):
        try:
            doc = parseString(self.xml)
        except ExpatError, e:
            logger.log_exc("Failed to parse credential, %s" % self.xml)
            raise
        sig = doc.getElementsByTagName("Signature")[0]
        self.set_refid(sig.getAttribute("xml:id").strip("Sig_"))
        keyinfo = sig.getElementsByTagName("X509Data")[0]
        szgid = getTextNode(keyinfo, "X509Certificate")
        szgid = "-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----" % szgid
        self.set_issuer_gid(GID(string=szgid))
Пример #46
0
 def dump_text(self, dump_parents=False, sort=False):
     print 40*'='
     print "RECORD"
     # print remaining fields
     fields=self.fields()
     if sort: fields.sort()
     for attrib_name in fields:
         attrib = getattr(self, attrib_name)
         # skip internals
         if attrib_name.startswith('_'):     continue
         # skip callables
         if callable (attrib):               continue
         # handle gid 
         if attrib_name == 'gid':
             print "    gid:"      
             print GID(string=attrib).dump_string(8, dump_parents)
         elif attrib_name in ['date created', 'last updated']:
             print "    %s: %s" % (attrib_name, self.date_repr(attrib_name))
         else:
             print "    %s: %s" % (attrib_name, attrib)
Пример #47
0
    def verify(self,
               trusted_certs=None,
               schema=None,
               trusted_certs_required=True):
        if not self.xml:
            self.decode()

        # validate against RelaxNG schema
        if HAVELXML and not self.legacy:
            if schema and os.path.exists(schema):
                tree = etree.parse(StringIO(self.xml))
                schema_doc = etree.parse(schema)
                xmlschema = etree.XMLSchema(schema_doc)
                if not xmlschema.validate(tree):
                    error = xmlschema.error_log.last_error
                    message = "%s: %s (line %s)" % (
                        self.get_summary_tostring(), error.message, error.line)
                    raise CredentialNotVerifiable(message)

        if trusted_certs_required and trusted_certs is None:
            trusted_certs = []

#        trusted_cert_objects = [GID(filename=f) for f in trusted_certs]
        trusted_cert_objects = []
        ok_trusted_certs = []
        # If caller explicitly passed in None that means skip cert chain validation.
        # Strange and not typical
        if trusted_certs is not None:
            for f in trusted_certs:
                try:
                    # Failures here include unreadable files
                    # or non PEM files
                    trusted_cert_objects.append(GID(filename=f))
                    ok_trusted_certs.append(f)
                except Exception, exc:
                    logger.error("Failed to load trusted cert from %s: %r" %
                                 (f, exc))
            trusted_certs = ok_trusted_certs
Пример #48
0
def install_trusted_certs(api):
    cred = api.getCredential()
    registry = api.get_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)
Пример #49
0
    def _get_client(self, cert_fname, key_fname):
        try:
            u = self.url
        except AttributeError:
            raise self.URLNotDefined("URL not set.")
        if not u:
            raise self.URLNotDefined("URL not set.")

        parsed = urlparse(u.lower())
        if parsed.scheme == "test":
            user_cert = GID(filename=cert_fname).save_to_string()
            transport = TestClientTransport(defaults={
                "REMOTE_USER": user_cert,
                "SSL_CLIENT_CERT": user_cert
            })
            proxy = xmlrpclib.ServerProxy(
                test_to_http(u),
                transport=transport,
            )
        else:
            transport = certtransport.SafeTransportWithCert(
                keyfile=key_fname, certfile=cert_fname)
            proxy = xmlrpclib.ServerProxy(u, transport=transport)
        return proxy
Пример #50
0
 def get_list(self):
     gid_list = [GID(filename=cert_file) for cert_file in self.get_file_list()]
     return gid_list
Пример #51
0
    def GetCredential(self, api, xrn, type, caller_xrn=None):
        # convert xrn to hrn
        if type:
            hrn = urn_to_hrn(xrn)[0]
        else:
            hrn, type = urn_to_hrn(xrn)

        # Is this a root or sub authority
        auth_hrn = api.auth.get_authority(hrn)
        if not auth_hrn or hrn == api.config.SFA_INTERFACE_HRN:
            auth_hrn = hrn
        auth_info = api.auth.get_auth_info(auth_hrn)
        # get record info
        filter = {'hrn': hrn}
        if type:
            filter['type'] = type
        record = dbsession.query(RegRecord).filter_by(**filter).first()
        if not record:
            raise RecordNotFound("hrn=%s, type=%s" % (hrn, type))

        # verify_cancreate_credential requires that the member lists
        # (researchers, pis, etc) be filled in
        logger.debug("get credential before augment dict, keys=%s" %
                     record.__dict__.keys())
        self.driver.augment_records_with_testbed_info(record.__dict__)
        logger.debug("get credential after augment dict, keys=%s" %
                     record.__dict__.keys())
        if not self.driver.is_enabled(record.__dict__):
            raise AccountNotEnabled(
                ": PlanetLab account %s is not enabled. Please contact your site PI"
                % (record.email))

        # get the callers gid
        # if caller_xrn is not specified assume the caller is the record
        # object itself.
        if not caller_xrn:
            caller_hrn = hrn
            caller_gid = record.get_gid_object()
        else:
            caller_hrn, caller_type = urn_to_hrn(caller_xrn)
            caller_filter = {'hrn': caller_hrn}
            if caller_type:
                caller_filter['type'] = caller_type
            caller_record = dbsession.query(RegRecord).filter_by(
                **caller_filter).first()
            if not caller_record:
                raise RecordNotFound(
                    "Unable to associated caller (hrn=%s, type=%s) with credential for (hrn: %s, type: %s)"
                    % (caller_hrn, caller_type, hrn, type))
            caller_gid = GID(string=caller_record.gid)

        object_hrn = record.get_gid_object().get_hrn()
        rights = api.auth.determine_user_rights(caller_hrn, record.todict())
        # make sure caller has rights to this object
        if rights.is_empty():
            raise PermissionError(caller_hrn + " has no rights to " +
                                  record.hrn)

        object_gid = GID(string=record.gid)
        new_cred = Credential(subject=object_gid.get_subject())
        new_cred.set_gid_caller(caller_gid)
        new_cred.set_gid_object(object_gid)
        new_cred.set_issuer_keys(auth_info.get_privkey_filename(),
                                 auth_info.get_gid_filename())
        #new_cred.set_pubkey(object_gid.get_pubkey())
        new_cred.set_privileges(rights)
        new_cred.get_privileges().delegate_all_privileges(True)
        if hasattr(record, 'expires'):
            date = utcparse(record.expires)
            expires = datetime_to_epoch(date)
            new_cred.set_expiration(int(expires))
        auth_kind = "authority,ma,sa"
        # Parent not necessary, verify with certs
        #new_cred.set_parent(api.auth.hierarchy.get_auth_cred(auth_hrn, kind=auth_kind))
        new_cred.encode()
        new_cred.sign()

        return new_cred.save_to_string(save_parents=True)
Пример #52
0
 def get_gid_object(self):
     if not self.gid: return None
     else: return GID(string=self.gid)
Пример #53
0
    def check_gid(self, xrn=None, type=None, all=None, verbose=None):
        """Check the correspondance between the GID and the PubKey"""

        # db records
        from sfa.storage.model import RegRecord
        db_query = self.api.dbsession().query(RegRecord).filter_by(type=type)
        if xrn and not all:
            hrn = Xrn(xrn).get_hrn()
            db_query = db_query.filter_by(hrn=hrn)
        elif all and xrn:
            print "Use either -a or -x <xrn>, not both !!!"
            sys.exit(1)
        elif not all and not xrn:
            print "Use either -a or -x <xrn>, one of them is mandatory !!!"
            sys.exit(1)

        records = db_query.all()
        if not records:
            print "No Record found"
            sys.exit(1)

        OK = []
        NOK = []
        ERROR = []
        NOKEY = []
        for record in records:
            # get the pubkey stored in SFA DB
            if record.reg_keys:
                db_pubkey_str = record.reg_keys[0].key
                try:
                    db_pubkey_obj = convert_public_key(db_pubkey_str)
                except:
                    ERROR.append(record.hrn)
                    continue
            else:
                NOKEY.append(record.hrn)
                continue

            # get the pubkey from the gid
            gid_str = record.gid
            gid_obj = GID(string=gid_str)
            gid_pubkey_obj = gid_obj.get_pubkey()

            # Check if gid_pubkey_obj and db_pubkey_obj are the same
            check = gid_pubkey_obj.is_same(db_pubkey_obj)
            if check:
                OK.append(record.hrn)
            else:
                NOK.append(record.hrn)

        if not verbose:
            print "Users NOT having a PubKey: %s\n\
Users having a non RSA PubKey: %s\n\
Users having a GID/PubKey correpondence OK: %s\n\
Users having a GID/PubKey correpondence Not OK: %s\n" % (
                len(NOKEY), len(ERROR), len(OK), len(NOK))
        else:
            print "Users NOT having a PubKey: %s and are: \n%s\n\n\
Users having a non RSA PubKey: %s and are: \n%s\n\n\
Users having a GID/PubKey correpondence OK: %s and are: \n%s\n\n\
Users having a GID/PubKey correpondence NOT OK: %s and are: \n%s\n\n" % (len(
                NOKEY), NOKEY, len(ERROR), ERROR, len(OK), OK, len(NOK), NOK)
Пример #54
0
class Sfi:
    
    required_options=['verbose',  'debug',  'registry',  'sm',  'auth',  'user']

    # dummy to meet Sfi's expectations for its 'options' field
    # i.e. s/t we can do setattr on
    class DummyOptions:
        pass

    def __init__ (self,options=None):
        if options is None: options=Sfi.DummyOptions()
        for opt in Sfi.required_options:
            if not hasattr(options,opt): setattr(options,opt,None)
        if not hasattr(options,'sfi_dir'): options.sfi_dir=os.path.expanduser("~/.sfi/")
        # xxx oops, this is dangerous, sounds like ww sometimes have discrepency
        # would be safer to remove self.sfi_dir altogether
        self.sfi_dir = options.sfi_dir
        self.options = options
        self.slicemgr = None
        self.registry = None
        self.user = None
        self.authority = None
        self.hashrequest = False
        self.logger = sfi_logger
        self.logger.enable_console()
   
    def create_cmd_parser(self, command, additional_cmdargs=None):
        cmdargs = {"list": "authority",
                  "show": "name",
                  "remove": "name",
                  "add": "record",
                  "update": "record",
                  "aggregates": "[name]",
                  "registries": "[name]",
                  "create_gid": "[name]",
                  "get_gid": [],  
                  "get_trusted_certs": "cred",
                  "slices": "",
                  "resources": "[name]",
                  "create": "name rspec",
                  "get_ticket": "name rspec",
                  "redeem_ticket": "ticket",
                  "delete": "name",
                  "reset": "name",
                  "start": "name",
                  "stop": "name",
                  "delegate": "name",
                  "status": "name",
                  "renew": "name",
                  "shutdown": "name",
                  "version": "",  
                 }

        if additional_cmdargs:
            cmdargs.update(additional_cmdargs)

        if command not in cmdargs:
            msg="Invalid command\n"
            msg+="Commands: "
            msg += ','.join(cmdargs.keys())            
            self.logger.critical(msg)
            sys.exit(2)

        parser = OptionParser(usage="sfi [sfi_options] %s [options] %s" \
                                     % (command, cmdargs[command]))

        # user specifies remote aggregate/sm/component                          
        if command in ("resources", "slices", "create", "delete", "start", "stop", 
                       "restart", "shutdown",  "get_ticket", "renew", "status"):
            parser.add_option("-a", "--aggregate", dest="aggregate",
                             default=None, help="aggregate host")
            parser.add_option("-p", "--port", dest="port",
                             default=AGGREGATE_PORT, help="aggregate port")
            parser.add_option("-c", "--component", dest="component", default=None,
                             help="component hrn")
            parser.add_option("-d", "--delegate", dest="delegate", default=None, 
                             action="store_true",
                             help="Include a credential delegated to the user's root"+\
                                  "authority in set of credentials for this call")  
        
        # registy filter option    
        if command in ("list", "show", "remove"):
            parser.add_option("-t", "--type", dest="type", type="choice",
                            help="type filter ([all]|user|slice|authority|node|aggregate)",
                            choices=("all", "user", "slice", "authority", "node", "aggregate"),
                            default="all")
        # display formats
        if command in ("resources"):
            parser.add_option("-r", "--rspec-version", dest="rspec_version", default="SFA 1",
                              help="schema type and version of resulting RSpec")
            parser.add_option("-f", "--format", dest="format", type="choice",
                             help="display format ([xml]|dns|ip)", default="xml",
                             choices=("xml", "dns", "ip"))
            #panos: a new option to define the type of information about resources a user is interested in
	    parser.add_option("-i", "--info", dest="info",
                                help="optional component information", default=None)


        # 'create' does return the new rspec, makes sense to save that too
        if command in ("resources", "show", "list", "create_gid", 'create'):
           parser.add_option("-o", "--output", dest="file",
                            help="output XML to file", metavar="FILE", default=None)

        if command in ("show", "list"):
           parser.add_option("-f", "--format", dest="format", type="choice",
                             help="display format ([text]|xml)", default="text",
                             choices=("text", "xml"))

           parser.add_option("-F", "--fileformat", dest="fileformat", type="choice",
                             help="output file format ([xml]|xmllist|hrnlist)", default="xml",
                             choices=("xml", "xmllist", "hrnlist"))

        if command in ("status"):
           parser.add_option("-o", "--output", dest="file",
                            help="output dictionary to file", metavar="FILE", default=None)
           parser.add_option("-F", "--fileformat", dest="fileformat", type="choice",
                             help="output file format ([text]|pickled)", default="text",
                             choices=("text","pickled"))

        if command in ("delegate"):
           parser.add_option("-u", "--user",
                            action="store_true", dest="delegate_user", default=False,
                            help="delegate user credential")
           parser.add_option("-s", "--slice", dest="delegate_slice",
                            help="delegate slice credential", metavar="HRN", default=None)
        
        if command in ("version"):
            parser.add_option("-a", "--aggregate", dest="aggregate",
                             default=None, help="aggregate host")
            parser.add_option("-p", "--port", dest="port",
                             default=AGGREGATE_PORT, help="aggregate port")
            parser.add_option("-R","--registry-version",
                              action="store_true", dest="version_registry", default=False,
                              help="probe registry version instead of slicemgr")
            parser.add_option("-l","--local",
                              action="store_true", dest="version_local", default=False,
                              help="display version of the local client")

        return parser

        
    def create_parser(self):

        # Generate command line parser
        parser = OptionParser(usage="sfi [options] command [command_options] [command_args]",
                             description="Commands: gid,list,show,remove,add,update,nodes,slices,resources,create,delete,start,stop,reset")
        parser.add_option("-r", "--registry", dest="registry",
                         help="root registry", metavar="URL", default=None)
        parser.add_option("-s", "--slicemgr", dest="sm",
                         help="slice manager", metavar="URL", default=None)
        default_sfi_dir = os.path.expanduser("~/.sfi/")
        parser.add_option("-d", "--dir", dest="sfi_dir",
                         help="config & working directory - default is " + default_sfi_dir,
                         metavar="PATH", default=default_sfi_dir)
        parser.add_option("-u", "--user", dest="user",
                         help="user name", metavar="HRN", default=None)
        parser.add_option("-a", "--auth", dest="auth",
                         help="authority name", metavar="HRN", default=None)
        parser.add_option("-v", "--verbose", action="count", dest="verbose", default=0,
                         help="verbose mode - cumulative")
        parser.add_option("-D", "--debug",
                          action="store_true", dest="debug", default=False,
                          help="Debug (xml-rpc) protocol messages")
        parser.add_option("-p", "--protocol", dest="protocol", default="xmlrpc",
                         help="RPC protocol (xmlrpc or soap)")
        parser.add_option("-k", "--hashrequest",
                         action="store_true", dest="hashrequest", default=False,
                         help="Create a hash of the request that will be authenticated on the server")
        parser.add_option("-t", "--timeout", dest="timeout", default=None,
                         help="Amout of time tom wait before timing out the request")
        parser.disable_interspersed_args()

        return parser
        

    def read_config(self):
       config_file = os.path.join(self.options.sfi_dir,"sfi_config")
       try:
          config = Config (config_file)
       except:
          self.logger.critical("Failed to read configuration file %s"%config_file)
          self.logger.info("Make sure to remove the export clauses and to add quotes")
          if self.options.verbose==0:
              self.logger.info("Re-run with -v for more details")
          else:
              self.logger.log_exc("Could not read config file %s"%config_file)
          sys.exit(1)
    
       errors = 0
       # Set SliceMgr URL
       if (self.options.sm is not None):
          self.sm_url = self.options.sm
       elif hasattr(config, "SFI_SM"):
          self.sm_url = config.SFI_SM
       else:
          self.logger.error("You need to set e.g. SFI_SM='http://your.slicemanager.url:12347/' in %s" % config_file)
          errors += 1 
    
       # Set Registry URL
       if (self.options.registry is not None):
          self.reg_url = self.options.registry
       elif hasattr(config, "SFI_REGISTRY"):
          self.reg_url = config.SFI_REGISTRY
       else:
          self.logger.errors("You need to set e.g. SFI_REGISTRY='http://your.registry.url:12345/' in %s" % config_file)
          errors += 1 
          

       # Set user HRN
       if (self.options.user is not None):
          self.user = self.options.user
       elif hasattr(config, "SFI_USER"):
          self.user = config.SFI_USER
       else:
          self.logger.errors("You need to set e.g. SFI_USER='******' in %s" % config_file)
          errors += 1 
    
       # Set authority HRN
       if (self.options.auth is not None):
          self.authority = self.options.auth
       elif hasattr(config, "SFI_AUTH"):
          self.authority = config.SFI_AUTH
       else:
          self.logger.error("You need to set e.g. SFI_AUTH='plc.princeton' in %s" % config_file)
          errors += 1 
    
       if errors:
          sys.exit(1)


    #
    # Establish Connection to SliceMgr and Registry Servers
    #
    def set_servers(self):

       self.read_config() 
       # Get key and certificate
       key_file = self.get_key_file()
       cert_file = self.get_cert_file(key_file)
       self.key = Keypair(filename=key_file) 
       self.key_file = key_file
       self.cert_file = cert_file
       self.cert = GID(filename=cert_file)
       self.logger.info("Contacting Registry at: %s"%self.reg_url)
       self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug)  
       self.logger.info("Contacting Slice Manager at: %s"%self.sm_url)
       self.slicemgr = xmlrpcprotocol.get_server(self.sm_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug)
       return

    def get_cached_server_version(self, server):
        # check local cache first
        cache = None
        version = None 
        cache_file = os.path.join(self.options.sfi_dir,'sfi_cache.dat')
        cache_key = server.url + "-version"
        try:
            cache = Cache(cache_file)
        except IOError:
            cache = Cache()
            self.logger.info("Local cache not found at: %s" % cache_file)

        if cache:
            version = cache.get(cache_key)
            
        if not version: 
            version = server.GetVersion()
            # cache version for 24 hours
            cache.add(cache_key, version, ttl= 60*60*24)
            self.logger.info("Updating cache file %s" % cache_file)
            cache.save_to_file(cache_file)


        return version   
        

    def server_supports_call_id_arg(self, server):
        """
        Returns true if server support the optional call_id arg, false otherwise. 
        """
        server_version = self.get_cached_server_version(server)
        if 'sfa' in server_version and 'code_tag' in server_version:
            code_tag = server_version['code_tag']
            code_tag_parts = code_tag.split("-")
            
            version_parts = code_tag_parts[0].split(".")
            major, minor = version_parts[0], version_parts[1]
            rev = code_tag_parts[1]
            if int(major) > 1:
                if int(minor) > 0 or int(rev) > 20:
                    return True
        return False                
             
    #
    # Get various credential and spec files
    #
    # Establishes limiting conventions
    #   - conflates MAs and SAs
    #   - assumes last token in slice name is unique
    #
    # Bootstraps credentials
    #   - bootstrap user credential from self-signed certificate
    #   - bootstrap authority credential from user credential
    #   - bootstrap slice credential from user credential
    #
    
    
    def get_key_file(self):
       file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".pkey")
       if (os.path.isfile(file)):
          return file
       else:
          self.logger.error("Key file %s does not exist"%file)
          sys.exit(-1)
       return
    
    def get_cert_file(self, key_file):
    
        cert_file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cert")
        if (os.path.isfile(cert_file)):
            # we'd perfer to use Registry issued certs instead of self signed certs. 
            # if this is a Registry cert (GID) then we are done 
            gid = GID(filename=cert_file)
            if gid.get_urn():
                return cert_file

        # generate self signed certificate
        k = Keypair(filename=key_file)
        cert = Certificate(subject=self.user)
        cert.set_pubkey(k)
        cert.set_issuer(k, self.user)
        cert.sign()
        self.logger.info("Writing self-signed certificate to %s"%cert_file)
        cert.save_to_file(cert_file)
        self.cert = cert
        # try to get registry issued cert
        try:
            self.logger.info("Getting Registry issued cert")
            self.read_config()
            # *hack.  need to set registyr before _get_gid() is called 
            self.registry = xmlrpcprotocol.get_server(self.reg_url, key_file, cert_file, timeout=self.options.timeout, verbose=self.options.debug)
            gid = self._get_gid(type='user')
            self.registry = None 
            self.logger.info("Writing certificate to %s"%cert_file)
            gid.save_to_file(cert_file)
        except:
            self.logger.info("Failed to download Registry issued cert")

        return cert_file

    def get_cached_gid(self, file):
        """
        Return a cached gid    
        """
        gid = None 
        if (os.path.isfile(file)):
            gid = GID(filename=file)
        return gid

    # xxx opts unused
    def get_gid(self, opts, args):
        """
        Get the specify gid and save it to file
        """
        hrn = None
        if args:
            hrn = args[0]
        gid = self._get_gid(hrn)
        self.logger.debug("Sfi.get_gid-> %s",gid.save_to_string(save_parents=True))
        return gid

    def _get_gid(self, hrn=None, type=None):
        """
        git_gid helper. Retrive the gid from the registry and save it to file.
        """
        
        if not hrn:
            hrn = self.user
 
        gidfile = os.path.join(self.options.sfi_dir, hrn + ".gid")
        gid = self.get_cached_gid(gidfile)
        if not gid:
            user_cred = self.get_user_cred()
            records = self.registry.Resolve(hrn, user_cred.save_to_string(save_parents=True))
            if not records:
                raise RecordNotFound(args[0])
            record = records[0]
            if type:
                record=None
                for rec in records:
                   if type == rec['type']:
                        record = rec 
            if not record:
                raise RecordNotFound(args[0])
            
            gid = GID(string=record['gid'])
            self.logger.info("Writing gid to %s"%gidfile)
            gid.save_to_file(filename=gidfile)
        return gid   
                
     
    def get_cached_credential(self, file):
        """
        Return a cached credential only if it hasn't expired.
        """
        if (os.path.isfile(file)):
            credential = Credential(filename=file)
            # make sure it isnt expired 
            if not credential.get_expiration or \
               datetime.datetime.today() < credential.get_expiration():
                return credential
        return None 
 
    def get_user_cred(self):
        file = os.path.join(self.options.sfi_dir, self.user.replace(self.authority + '.', '') + ".cred")
        return self.get_cred(file, 'user', self.user)

    def get_auth_cred(self):
        if not self.authority:
            self.logger.critical("no authority specified. Use -a or set SF_AUTH")
            sys.exit(-1)
        file = os.path.join(self.options.sfi_dir, self.authority + ".cred")
        return self.get_cred(file, 'authority', self.authority)

    def get_slice_cred(self, name):
        file = os.path.join(self.options.sfi_dir, "slice_" + get_leaf(name) + ".cred")
        return self.get_cred(file, 'slice', name)
 
    def get_cred(self, file, type, hrn):
        # attempt to load a cached credential 
        cred = self.get_cached_credential(file)    
        if not cred:
            if type in ['user']:
                cert_string = self.cert.save_to_string(save_parents=True)
                user_name = self.user.replace(self.authority + ".", '')
                if user_name.count(".") > 0:
                    user_name = user_name.replace(".", '_')
                    self.user = self.authority + "." + user_name
                cred_str = self.registry.GetSelfCredential(cert_string, hrn, "user")
            else:
                # bootstrap slice credential from user credential
                user_cred = self.get_user_cred().save_to_string(save_parents=True)
                cred_str = self.registry.GetCredential(user_cred, hrn, type)
            
            if not cred_str:
                self.logger.critical("Failed to get %s credential" % type)
                sys.exit(-1)
                
            cred = Credential(string=cred_str)
            cred.save_to_file(file, save_parents=True)
            self.logger.info("Writing %s credential to %s" %(type, file))

        return cred
 
    
    def get_rspec_file(self, rspec):
       if (os.path.isabs(rspec)):
          file = rspec
       else:
          file = os.path.join(self.options.sfi_dir, rspec)
       if (os.path.isfile(file)):
          return file
       else:
          self.logger.critical("No such rspec file %s"%rspec)
          sys.exit(1)
    
    def get_record_file(self, record):
       if (os.path.isabs(record)):
          file = record
       else:
          file = os.path.join(self.options.sfi_dir, record)
       if (os.path.isfile(file)):
          return file
       else:
          self.logger.critical("No such registry record file %s"%record)
          sys.exit(1)
    
    def load_publickey_string(self, fn):
       f = file(fn, "r")
       key_string = f.read()
    
       # if the filename is a private key file, then extract the public key
       if "PRIVATE KEY" in key_string:
           outfn = tempfile.mktemp()
           cmd = "openssl rsa -in " + fn + " -pubout -outform PEM -out " + outfn
           os.system(cmd)
           f = file(outfn, "r")
           key_string = f.read()
           os.remove(outfn)
    
       return key_string

    # xxx opts undefined
    def get_component_server_from_hrn(self, hrn):
        # direct connection to the nodes component manager interface
        user_cred = self.get_user_cred().save_to_string(save_parents=True)
        records = self.registry.Resolve(hrn, user_cred)
        records = filter_records('node', records)
        if not records:
            self.logger.warning("No such component:%r"% opts.component)
        record = records[0]
  
        return self.get_server(record['hostname'], CM_PORT, self.key_file, self.cert_file)
 
    def get_server(self, host, port, keyfile, certfile):
        """
        Return an instance of an xmlrpc server connection    
        """
        # port is appended onto the domain, before the path. Should look like:
        # http://domain:port/path
        host_parts = host.split('/')
        host_parts[0] = host_parts[0] + ":" + str(port)
        url =  "http://%s" %  "/".join(host_parts)    
        return xmlrpcprotocol.get_server(url, keyfile, certfile, timeout=self.options.timeout, verbose=self.options.debug)

    # xxx opts could be retrieved in self.options
    def get_server_from_opts(self, opts):
        """
        Return instance of an xmlrpc connection to a slice manager, aggregate
        or component server depending on the specified opts
        """
        server = self.slicemgr
        # direct connection to an aggregate
        if hasattr(opts, 'aggregate') and opts.aggregate:
            server = self.get_server(opts.aggregate, opts.port, self.key_file, self.cert_file)
        # direct connection to the nodes component manager interface
        if hasattr(opts, 'component') and opts.component:
            server = self.get_component_server_from_hrn(opts.component)    
 
        return server
    #==========================================================================
    # Following functions implement the commands
    #
    # Registry-related commands
    #==========================================================================
  
    def dispatch(self, command, cmd_opts, cmd_args):
        return getattr(self, command)(cmd_opts, cmd_args)

    def create_gid(self, opts, args):
        if len(args) < 1:
            self.print_help()
            sys.exit(1)
        target_hrn = args[0]
        user_cred = self.get_user_cred().save_to_string(save_parents=True)
        gid = self.registry.CreateGid(user_cred, target_hrn, self.cert.save_to_string())
        if opts.file:
            filename = opts.file
        else:
            filename = os.sep.join([self.sfi_dir, '%s.gid' % target_hrn])
        self.logger.info("writing %s gid to %s" % (target_hrn, filename))
        GID(string=gid).save_to_file(filename)
         
     
    # list entires in named authority registry
    def list(self, opts, args):
        if len(args)!= 1:
            self.print_help()
            sys.exit(1)
        hrn = args[0]
        user_cred = self.get_user_cred().save_to_string(save_parents=True)
        try:
            list = self.registry.List(hrn, user_cred)
        except IndexError:
            raise Exception, "Not enough parameters for the 'list' command"

        # filter on person, slice, site, node, etc.
        # THis really should be in the self.filter_records funct def comment...
        list = filter_records(opts.type, list)
        for record in list:
            print "%s (%s)" % (record['hrn'], record['type'])
        if opts.file:
            save_records_to_file(opts.file, list, opts.fileformat)
        return
    
    # show named registry record
    def show(self, opts, args):
        if len(args)!= 1:
            self.print_help()
            sys.exit(1)
        hrn = args[0]
        user_cred = self.get_user_cred().save_to_string(save_parents=True)
        records = self.registry.Resolve(hrn, user_cred)
        records = filter_records(opts.type, records)
        if not records:
            print "No record of type", opts.type
        for record in records:
            if record['type'] in ['user']:
                record = UserRecord(dict=record)
            elif record['type'] in ['slice']:
                record = SliceRecord(dict=record)
            elif record['type'] in ['node']:
                record = NodeRecord(dict=record)
            elif record['type'].startswith('authority'):
                record = AuthorityRecord(dict=record)
            else:
                record = SfaRecord(dict=record)
            if (opts.format == "text"): 
                record.dump()  
            else:
                print record.save_to_string() 
        if opts.file:
            save_records_to_file(opts.file, records, opts.fileformat)
        return
    
    def delegate(self, opts, args):

        delegee_hrn = args[0]
        if opts.delegate_user:
            user_cred = self.get_user_cred()
            cred = self.delegate_cred(user_cred, delegee_hrn)
        elif opts.delegate_slice:
            slice_cred = self.get_slice_cred(opts.delegate_slice)
            cred = self.delegate_cred(slice_cred, delegee_hrn)
        else:
            self.logger.warning("Must specify either --user or --slice <hrn>")
            return
        delegated_cred = Credential(string=cred)
        object_hrn = delegated_cred.get_gid_object().get_hrn()
        if opts.delegate_user:
            dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_"
                                  + get_leaf(object_hrn) + ".cred")
        elif opts.delegate_slice:
            dest_fn = os.path.join(self.options.sfi_dir, get_leaf(delegee_hrn) + "_slice_"
                                  + get_leaf(object_hrn) + ".cred")

        delegated_cred.save_to_file(dest_fn, save_parents=True)

        self.logger.info("delegated credential for %s to %s and wrote to %s"%(object_hrn, delegee_hrn,dest_fn))
    
    def delegate_cred(self, object_cred, hrn):
        # the gid and hrn of the object we are delegating
        if isinstance(object_cred, str):
            object_cred = Credential(string=object_cred) 
        object_gid = object_cred.get_gid_object()
        object_hrn = object_gid.get_hrn()
    
        if not object_cred.get_privileges().get_all_delegate():
            self.logger.error("Object credential %s does not have delegate bit set"%object_hrn)
            return

        # the delegating user's gid
        caller_gid = self._get_gid(self.user)
        caller_gidfile = os.path.join(self.options.sfi_dir, self.user + ".gid")
  
        # the gid of the user who will be delegated to
        delegee_gid = self._get_gid(hrn)
        delegee_hrn = delegee_gid.get_hrn()
        delegee_gidfile = os.path.join(self.options.sfi_dir, delegee_hrn + ".gid")
        delegee_gid.save_to_file(filename=delegee_gidfile)
        dcred = object_cred.delegate(delegee_gidfile, self.get_key_file(), caller_gidfile)
        return dcred.save_to_string(save_parents=True)
     
    # removed named registry record
    #   - have to first retrieve the record to be removed
    def remove(self, opts, args):
        auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
        if len(args)!=1:
            self.print_help()
            sys.exit(1)
        hrn = args[0]
        type = opts.type 
        if type in ['all']:
            type = '*'
        return self.registry.Remove(hrn, auth_cred, type)
    
    # add named registry record
    def add(self, opts, args):
        auth_cred = self.get_auth_cred().save_to_string(save_parents=True)
        if len(args)!=1:
            self.print_help()
            sys.exit(1)
        record_filepath = args[0]
        rec_file = self.get_record_file(record_filepath)
        record = load_record_from_file(rec_file).as_dict()
        return self.registry.Register(record, auth_cred)
    
    # update named registry entry
    def update(self, opts, args):
        user_cred = self.get_user_cred()
        if len(args)!=1:
            self.print_help()
            sys.exit(1)
        rec_file = self.get_record_file(args[0])
        record = load_record_from_file(rec_file)
        if record['type'] == "user":
            if record.get_name() == user_cred.get_gid_object().get_hrn():
                cred = user_cred.save_to_string(save_parents=True)
            else:
                cred = self.get_auth_cred().save_to_string(save_parents=True)
        elif record['type'] in ["slice"]:
            try:
                cred = self.get_slice_cred(record.get_name()).save_to_string(save_parents=True)
            except xmlrpcprotocol.ServerException, e:
               # XXX smbaker -- once we have better error return codes, update this
               # to do something better than a string compare
               if "Permission error" in e.args[0]:
                   cred = self.get_auth_cred().save_to_string(save_parents=True)
               else:
                   raise
        elif record.get_type() in ["authority"]:
            cred = self.get_auth_cred().save_to_string(save_parents=True)
Пример #55
0
    def create_gid(self, xrn, uuid, pkey, CA=False):
        hrn, type = urn_to_hrn(xrn)
        parent_hrn = get_authority(hrn)
        # Using hrn_to_urn() here to make sure the urn is in the right format
        # If xrn was a hrn instead of a urn, then the gid's urn will be
        # of type None 
        urn = hrn_to_urn(hrn, type)
        gid = GID(subject=hrn, uuid=uuid, hrn=hrn, urn=urn)

        # is this a CA cert
        if hrn == self.config.SFA_INTERFACE_HRN or not parent_hrn:
            # root or sub authority  
            gid.set_intermediate_ca(True)
        elif type and 'authority' in type:
            # authority type
            gid.set_intermediate_ca(True)
        elif CA:
            gid.set_intermediate_ca(True)
        else:
            gid.set_intermediate_ca(False)

        # set issuer
        if not parent_hrn or hrn == self.config.SFA_INTERFACE_HRN:
            # if there is no parent hrn, then it must be self-signed. this
            # is where we terminate the recursion
            gid.set_issuer(pkey, hrn)
        else:
            # we need the parent's private key in order to sign this GID
            parent_auth_info = self.get_auth_info(parent_hrn)
            gid.set_issuer(parent_auth_info.get_pkey_object(), parent_auth_info.hrn)
            gid.set_parent(parent_auth_info.get_gid_object())

        gid.set_pubkey(pkey)
        gid.encode()
        gid.sign()

        return gid
Пример #56
0
def create_cert(urn, issuer_key=None, issuer_cert=None, intermediate=False):
    '''Create a new certificate and return it and the associated keys.
    If issuer cert and key are given, they sign the certificate. Otherwise
    it is a self-signed certificate. 
    
    If intermediate then mark this 
    as an intermediate CA certificate (can sign).
    
    Certificate URN must be supplied.
    CN of the cert will be dotted notation authority.type.name from the URN.
    '''
    # Note the below throws a ValueError if it wasnt a valid URN
    c_urn = URN(urn=urn)
    dotted = '%s.%s.%s' % (c_urn.getAuthority(), c_urn.getType(), c_urn.getName())
    

    newgid = GID(create=True, subject=dotted[:64],
                     urn=urn)
    
    keys = Keypair(create=True)
    newgid.set_pubkey(keys)
    if intermediate:
        # This cert will be able to sign certificates
        newgid.set_intermediate_ca(intermediate)
        
    if issuer_key and issuer_cert:
        # the given issuer will issue this cert
        if isinstance(issuer_key,str):
            issuer_key = Keypair(filename=issuer_key)
        if isinstance(issuer_cert,str):
            issuer_cert = GID(filename=issuer_cert)
        newgid.set_issuer(issuer_key, cert=issuer_cert)
        newgid.set_parent(issuer_cert)
    else:
        # create a self-signed cert
        newgid.set_issuer(keys, subject=dotted)

    newgid.encode()
    newgid.sign()
    return newgid, keys
Пример #57
0
def create_cert(urn,
                issuer_key=None,
                issuer_cert=None,
                ca=False,
                public_key=None,
                lifeDays=1825,
                email=None):
    '''Create a new certificate and return it and the associated keys.
    If issuer cert and key are given, they sign the certificate. Otherwise
    it is a self-signed certificate. 
    
    If ca then mark this as a CA certificate (can sign other certs).
    
    lifeDays is the lifetime of the supplied cert - default is 1825 (5 years).

    Certificate URN must be supplied.
    CN of the cert will be dotted notation authority.type.name from the URN.
    '''
    # Note the below throws a ValueError if it wasnt a valid URN
    c_urn = URN(urn=urn)
    dotted = '%s.%s.%s' % (c_urn.getAuthority(), c_urn.getType(),
                           c_urn.getName())

    subject = dict()
    subject['CN'] = dotted[:64]
    if email:
        subject['emailAddress'] = email
    newgid = GID(create=True, subject=subject, urn=urn, lifeDays=lifeDays)

    if public_key is None:
        # create a new key pair
        keys = Keypair(create=True)
    else:
        # use the specified public key file
        keys = Keypair()
        keys.load_pubkey_from_file(public_key)
    newgid.set_pubkey(keys)
    newgid.set_is_ca(ca)

    if issuer_key and issuer_cert:
        # the given issuer will issue this cert
        if isinstance(issuer_key, str):
            issuer_key = Keypair(filename=issuer_key)
        if isinstance(issuer_cert, str):
            issuer_cert = GID(filename=issuer_cert)
        newgid.set_issuer(issuer_key, cert=issuer_cert)
        newgid.set_parent(issuer_cert)
    else:
        # create a self-signed cert
        newgid.set_issuer(keys, subject=dotted)

    newgid.encode()
    newgid.sign()
    return newgid, keys
Пример #58
0
 def get_gid_object(self):
     if not self.gid_object:
         self.gid_object = GID(filename = self.gid_filename)
     return self.gid_object
Пример #59
0
    def create_gid(self, xrn, uuid, pkey, CA=False, email=None):
        hrn, type = urn_to_hrn(xrn)
        if not type:
            type = 'authority'
        parent_hrn = get_authority(hrn)
        # Using hrn_to_urn() here to make sure the urn is in the right format
        # If xrn was a hrn instead of a urn, then the gid's urn will be
        # of type None 
        urn = hrn_to_urn(hrn, type)
        gid = GID(subject=hrn, uuid=uuid, hrn=hrn, urn=urn, email=email)
        # is this a CA cert
        if hrn == self.config.SFA_INTERFACE_HRN or not parent_hrn:
            # root or sub authority  
            gid.set_intermediate_ca(True)
        elif type and 'authority' in type:
            # authority type
            gid.set_intermediate_ca(True)
        elif CA:
            gid.set_intermediate_ca(True)
        else:
            gid.set_intermediate_ca(False)

        # set issuer
        if not parent_hrn or hrn == self.config.SFA_INTERFACE_HRN:
            # if there is no parent hrn, then it must be self-signed. this
            # is where we terminate the recursion
            gid.set_issuer(pkey, hrn)
        else:
            # we need the parent's private key in order to sign this GID
            parent_auth_info = self.get_auth_info(parent_hrn)
            gid.set_issuer(parent_auth_info.get_pkey_object(), parent_auth_info.hrn)
            gid.set_parent(parent_auth_info.get_gid_object())

        gid.set_pubkey(pkey)
        gid.encode()
        gid.sign()

        return gid