def mount(): secdir = common.WORK_DIR + "/secure" if not common.MOUNT_SECURE: secdir = common.WORK_DIR + "/tmpfs-dev" if not os.path.isdir(secdir): os.makedirs(secdir) return secdir if not check_mounted(secdir): # ok now we know it isn't already mounted, go ahead and create and mount if not os.path.exists(secdir): os.makedirs(secdir, 0o700) common.chownroot(secdir, logger) size = config.get('cloud_agent', 'secure_size') logger.info("mounting secure storage location %s on tmpfs" % secdir) cmd_exec.run("mount -t tmpfs -o size=%s,mode=0700 tmpfs %s" % (size, secdir), lock=False) return secdir
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
def check_mounted(secdir): whatsmounted = cmd_exec.run("mount", lock=False)['retout'] for line in whatsmounted: tokens = line.split() tmpfs = False if len(tokens) < 3: continue if tokens[0] == 'tmpfs': tmpfs = True if tokens[2] == secdir: if not tmpfs: logger.error( "secure storage location %s already mounted on wrong file system type: %s. Unmount to continue." % (secdir, tokens[0])) raise Exception( "secure storage location %s already mounted on wrong file system type: %s. Unmount to continue." % (secdir, tokens[0])) logger.debug( "secure storage location %s already mounted on tmpfs" % secdir) return True logger.debug("secure storage location %s not mounted " % secdir) return False
def convert_crl_to_pem(derfile,pemfile): if config.get('general','ca_implementation')=='openssl': with open(pemfile,'w') as f: f.write("") else: cmd_exec.run("openssl crl -in %s -inform der -out %s"%(derfile,pemfile),lock=False)
def __run(self, cmd, expectedcode=AbstractTPM.EXIT_SUCESS, raiseOnError=True, lock=True, outputpaths=None): env = os.environ.copy() env['TPM_SERVER_PORT'] = '9998' env['TPM_SERVER_NAME'] = 'localhost' env['PATH'] = env['PATH'] + ":%s" % common.TPM_TOOLS_PATH # Backwards compat with string input (force all to be dict) if isinstance(outputpaths, basestring): outputpaths = [outputpaths] # Handle stubbing the TPM out fprt = tpm1.__fingerprint(cmd) if common.STUB_TPM and common.TPM_CANNED_VALUES is not None: # Use canned values for stubbing jsonIn = common.TPM_CANNED_VALUES if fprt in jsonIn: # The value we're looking for has been canned! thisTiming = jsonIn[fprt]['timing'] thisRetout = jsonIn[fprt]['retout'] thisCode = jsonIn[fprt]['code'] thisFileout = jsonIn[fprt]['fileout'] fileoutEncoded = {} # Decode files that are supplied if outputpaths is not None and len(outputpaths) == 1: if thisFileout != '': fileoutEncoded[outputpaths[0]] = base64.b64decode( thisFileout).decode("zlib") logger.debug( "TPM call '%s' was stubbed out, with a simulated delay of %f sec" % (fprt, thisTiming)) time.sleep(thisTiming) # Package for return returnDict = { 'retout': thisRetout, 'code': thisCode, 'fileouts': fileoutEncoded, 'timing': thisTiming, } return returnDict elif not lock: # non-lock calls don't go to the TPM (just let it pass through) pass else: # Our command hasn't been canned! raise Exception("Command %s not found in canned JSON!" % (fprt)) numtries = 0 while True: if lock: with self.tpmutilLock: retDict = cmd_exec.run(cmd=cmd, expectedcode=expectedcode, raiseOnError=False, lock=lock, outputpaths=outputpaths, env=env) else: retDict = cmd_exec.run(cmd=cmd, expectedcode=expectedcode, raiseOnError=False, lock=lock, outputpaths=outputpaths, env=env) t0 = retDict['timing']['t0'] t1 = retDict['timing']['t1'] code = retDict['code'] retout = retDict['retout'] fileouts = retDict['fileouts'] # keep trying to communicate with TPM if there was an I/O error if code == AbstractTPM.TPM_IO_ERR: numtries += 1 maxr = self.config.getint('cloud_agent', 'max_retries') if numtries >= maxr: logger.error( "TPM appears to be in use by another application. Keylime is incompatible with other TPM TSS applications like trousers/tpm-tools. Please uninstall or disable." ) break retry = self.config.getfloat('cloud_agent', 'retry_interval') logger.info( "Failed to call TPM %d/%d times, trying again in %f seconds..." % (numtries, maxr, retry)) time.sleep(retry) continue else: break # Don't bother continuing if TPM call failed and we're raising on error if code != expectedcode and raiseOnError: raise Exception("Command: %s returned %d, expected %d, output %s" % (cmd, code, expectedcode, retout)) # Metric output if lock or self.tpmutilLock.locked(): pad = "" if len(fprt) < 8: pad += "\t" if len(fprt) < 16: pad += "\t" if len(fprt) < 24: pad += "\t" filelen = 0 if fileouts is not None: filelen = len(fileouts) # Print out benchmarking information for TPM (if requested) #print "\033[95mTIMING: %s%s\t:%f\toutlines:%d\tfilelines:%d\t%s\033[0m" % (fprt,pad,t1-t0,len(retout),filelen,cmd) if common.TPM_BENCHMARK_PATH is not None: with open(common.TPM_BENCHMARK_PATH, "ab") as bench: bench.write( "TIMING: %s%s\ttime:%f\toutlines:%d\tfilecount:%d\t%s\n" % (fprt, pad, t1 - t0, len(retout), filelen, cmd)) # Print out JSON canned values (if requested) # NOTE: resulting file will be missing the surrounding braces! (must add '{' and '}' for reading) if common.TPM_CANNED_VALUES_PATH is not None: with open(common.TPM_CANNED_VALUES_PATH, "ab") as can: fileoutEncoded = "" if outputpaths is not None and len(outputpaths) > 0: if len(fileouts) == 1 and len(outputpaths) == 1: fileoutEncoded = base64.b64encode( fileouts.itervalues().next().encode("zlib")) else: raise Exception( "Command %s is using multiple files unexpectedly!" % (fprt)) # tpm_cexec will need to know the nonce nonce = "" match = re.search("-nonce ([\w]+)", cmd) if match: nonce = match.group(1) jsonObj = { 'type': fprt, 'retout': retout, 'fileout': fileoutEncoded, 'cmd': cmd, 'timing': t1 - t0, 'code': code, 'nonce': nonce } can.write( "\"%s\": %s,\n" % (fprt, json.dumps(jsonObj, indent=4, sort_keys=True))) return retDict