Exemple #1
0
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
Exemple #2
0
 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
Exemple #3
0
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
Exemple #4
0
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)
Exemple #5
0
    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