Пример #1
0
def cmd_listen(workingdir, cert_path):
    #just load up the password for later
    read_private()

    serveraddr = ('', common.CRL_PORT)
    server = ThreadedCRLServer(serveraddr, CRLHandler)
    if os.path.exists('%s/cacrl.der' % workingdir):
        with open('%s/cacrl.der' % workingdir, 'r') as f:
            server.setcrl(f.read())
    t = threading.Thread(target=server.serve_forever)
    logger.info("Hosting CRL on %s:%d" % (socket.getfqdn(), common.CRL_PORT))
    t.start()

    def revoke_callback(revocation):
        serial = revocation.get("metadata", {}).get("cert_serial", None)
        if revocation.get('type', None) != 'revocation' or serial is None:
            logger.error("Unsupported revocation message: %s" % revocation)
            return

        logger.info("Revoking certificate: %s" % serial)
        server.setcrl(cmd_revoke(workingdir, None, serial))

    try:
        while True:
            try:
                revocation_notifier.await_notifications(
                    revoke_callback, revocation_cert_path=cert_path)
            except Exception as e:
                logger.exception(e)
                logger.warn(
                    "No connection to revocation server, retrying in 10s...")
                time.sleep(10)
    except KeyboardInterrupt:
        logger.info("TERM Signal received, shutting down...")
        server.shutdown()
Пример #2
0
def main(argv=sys.argv):
    if os.getuid()!=0 and common.REQUIRE_ROOT:
        logger.critical("This process must be run as root.")
        return

    # get params for initialization
    registrar_ip = config.get('general', 'registrar_ip')
    registrar_port = config.get('general', 'registrar_port')
    
    # initialize the tmpfs partition to store keys if it isn't already available
    secdir = secure_mount.mount()

    # change dir to working dir
    common.ch_dir(common.WORK_DIR,logger)
    
    #initialize tpm 
    (ek,ekcert,aik,ek_tpm,aik_name) = tpm.tpm_init(self_activate=False,config_pw=config.get('cloud_agent','tpm_ownerpassword')) # this tells initialize not to self activate the AIK
    virtual_agent = tpm.is_vtpm()
    
    # try to get some TPM randomness into the system entropy pool
    tpm.init_system_rand()
        
    if ekcert is None:
        if virtual_agent:
            ekcert = 'virtual'
        elif tpm.is_emulator():
            ekcert = 'emulator'
        
    # now we need the UUID
    try:
        agent_uuid = config.get('cloud_agent','agent_uuid')
    except ConfigParser.NoOptionError:
        agent_uuid = None
    if agent_uuid == 'openstack':
        agent_uuid = openstack.get_openstack_uuid()
    elif agent_uuid == 'hash_ek':
        agent_uuid = hashlib.sha256(ek).hexdigest()
    elif agent_uuid == 'generate' or agent_uuid is None:
        agent_uuid = str(uuid.uuid4())
    if common.DEVELOP_IN_ECLIPSE:
        agent_uuid = "C432FBB3-D2F1-4A97-9EF7-75BD81C866E9"
    if common.STUB_VTPM and common.TPM_CANNED_VALUES is not None:
        # Use canned values for stubbing 
        jsonIn = common.TPM_CANNED_VALUES
        if "add_vtpm_to_group" in jsonIn:
            # The value we're looking for has been canned! 
            agent_uuid = jsonIn['add_vtpm_to_group']['retout']
        else:
            # Our command hasn't been canned!
            raise Exception("Command %s not found in canned JSON!"%("add_vtpm_to_group"))
    
    logger.info("Agent UUID: %s"%agent_uuid)
    
    # register it and get back a blob
    keyblob = registrar_client.doRegisterAgent(registrar_ip,registrar_port,agent_uuid,tpm_version,ek,ekcert,aik,ek_tpm,aik_name)
    
    if keyblob is None:
        raise Exception("Registration failed")
    
    # get the ephemeral registrar key
    key = tpm.activate_identity(keyblob)
    
    # tell the registrar server we know the key
    retval=False
    if virtual_agent:
        deepquote = tpm.create_deep_quote(hashlib.sha1(key).hexdigest(),agent_uuid+aik+ek)
        retval = registrar_client.doActivateVirtualAgent(registrar_ip, registrar_port, agent_uuid, deepquote)
    else:
        retval = registrar_client.doActivateAgent(registrar_ip,registrar_port,agent_uuid,key)

    if not retval:
        raise Exception("Registration failed on activate")
    
    serveraddr = ('', config.getint('general', 'cloudagent_port'))
    server = CloudAgentHTTPServer(serveraddr,Handler,agent_uuid)
    serverthread = threading.Thread(target=server.serve_forever)

    logger.info( 'Starting Cloud Agent on port %s use <Ctrl-C> to stop'%serveraddr[1])
    serverthread.start()
    
    # want to listen for revocations?
    if config.getboolean('cloud_agent','listen_notfications'):
        cert_path = config.get('cloud_agent','revocation_cert')
        if cert_path == "default":
            cert_path = '%s/unzipped/RevocationNotifier-cert.crt'%(secdir)
        elif cert_path[0]!='/':
            # if it is a relative, convert to absolute in work_dir
            cert_path = os.path.abspath('%s/%s'%(common.WORK_DIR,cert_path))
            
        def perform_actions(revocation):
            actionlist = []
            
            # load the actions from inside the keylime module
            actionlisttxt = config.get('cloud_agent','revocation_actions')
            if actionlisttxt.strip() != "":
                actionlist = actionlisttxt.split(',')
                actionlist = ["revocation_actions.%s"%i for i in actionlist]
                
            # load actions from unzipped
            if os.path.exists("%s/unzipped/action_list"%secdir):
                with open("%s/unzipped/action_list"%secdir,'r') as f:
                    actionlisttxt = f.read()
                if actionlisttxt.strip()!="":
                    localactions = actionlisttxt.strip().split(',')
                    for action in localactions:
                        if not action.startswith('local_action_'):
                            logger.warning("invalid local action: %s.  must start with local_action_"%action)
                        else:
                            actionlist.append(action)
                    
                    uzpath = "%s/unzipped"%secdir
                    if uzpath not in sys.path:
                        sys.path.append(uzpath)

            for action in actionlist:
                logger.debug("executing revocation action %s"%action)
                try:
                    module = importlib.import_module(action)
                    execute = getattr(module,'execute')
                    execute(revocation)
                except Exception as e:
                    logger.warn("Exception during execution of revocation action %s: %s"%(action,e))
        try:
            while True:
                try:
                    revocation_notifier.await_notifications(perform_actions,revocation_cert_path=cert_path)
                except Exception as e:
                    logger.exception(e)
                    logger.warn("No connection to revocation server, retrying in 10s...")
                    time.sleep(10)
        except KeyboardInterrupt:
            logger.info("TERM Signal received, shutting down...")
            tpm.flush_keys()
            server.shutdown()
    else:  
        try:
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            logger.info("TERM Signal received, shutting down...")
            tpm.flush_keys()
            server.shutdown()
Пример #3
0
def cmd_listen(workingdir,cert_path):
    #just load up the password for later
    read_private()
    
    serveraddr = ('', common.CRL_PORT)
    server = ThreadedCRLServer(serveraddr,CRLHandler)
    if os.path.exists('%s/cacrl.der'%workingdir):
        logger.info("Loading existing crl: %s/cacrl.der"%workingdir)
        with open('%s/cacrl.der'%workingdir,'r') as f:
            server.setcrl(f.read())
    t = threading.Thread(target=server.serve_forever)
    logger.info("Hosting CRL on %s:%d"%(socket.getfqdn(),common.CRL_PORT))
    t.start()
    
    def check_expiration():
        logger.info("checking CRL for expiration every hour")
        while True:
            try:
                if os.path.exists('%s/cacrl.der'%workingdir):
                    retout = cmd_exec.run("openssl crl -inform der -in %s/cacrl.der -text -noout"%workingdir,lock=False)['retout']
                    for line in retout:
                        line = line.strip()
                        if line.startswith("Next Update:"):
                            expire = datetime.datetime.strptime(line[13:],"%b %d %H:%M:%S %Y %Z")
                            # check expiration within 6 hours
                            in1hour = datetime.datetime.utcnow()+datetime.timedelta(hours=6)
                            if expire<=in1hour:
                                logger.info("Certificate to expire soon %s, re-issuing"%expire)
                                cmd_regencrl(workingdir)
                # check a little less than every hour
                time.sleep(3540)
                
            except KeyboardInterrupt:
                logger.info("TERM Signal received, shutting down...")
                #server.shutdown()
                break
    
    t2 = threading.Thread(target=check_expiration)
    t2.setDaemon(True)
    t2.start()

    def revoke_callback(revocation):
        serial = revocation.get("metadata",{}).get("cert_serial",None)
        if revocation.get('type',None) != 'revocation' or serial is None:
            logger.error("Unsupported revocation message: %s"%revocation)
            return
        
        logger.info("Revoking certificate: %s"%serial)
        server.setcrl(cmd_revoke(workingdir, None, serial))
        
    try:
        while True:
            try:
                revocation_notifier.await_notifications(revoke_callback,revocation_cert_path=cert_path)
            except Exception as e:
                logger.exception(e)
                logger.warn("No connection to revocation server, retrying in 10s...")
                time.sleep(10)
    except KeyboardInterrupt:
        logger.info("TERM Signal received, shutting down...")
        server.shutdown()
        sys.exit()