1# Copyright 2014 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging, os 6import time 7 8from autotest_lib.client.common_lib import error 9from autotest_lib.client.cros import constants 10 11 12_RM_FILES = ['/home/chronos/.oobe_completed', 13 '/home/chronos/Local\ State', 14 '/var/cache/shill/default.profile'] 15_RM_DIRS = ['/home/.shadow/*', 16 os.path.join(constants.ALLOWLIST_DIR, '*'), 17 '/var/cache/app_pack', 18 '/var/lib/tpm'] 19 20 21class NoTPMPasswordException(Exception): 22 """No TPM Password could be found.""" 23 pass 24 25 26def TPMStatus(client): 27 """Returns a dictionary with TPM status. 28 29 @param client: client object to run commands on. 30 """ 31 out = client.run('tpm_manager_client status --nonsensitive').stdout.strip() 32 lines = out.split('\n')[1:-1] 33 status = {} 34 for item in lines: 35 item = item.split(':') 36 if not item[0]: 37 continue 38 if len(item) == 1: 39 item.append('') 40 item = map(lambda x : x.strip(), item) 41 item[1] = True if item[1] == 'true' else item[1] 42 item[1] = False if item[1] == 'false' else item[1] 43 status[item[0]] = item[1] 44 return status 45 46 47def IsTPMAvailable(client): 48 """Returns True if the TPM is unowned and enabled. 49 50 @param client: client object to run commands on. 51 """ 52 status = TPMStatus(client) 53 return status['is_enabled'] and not status['is_owned'] 54 55 56def ClearTPMServer(client, out_dir): 57 """Clears the TPM and reboots from a server-side autotest. 58 59 @param client: client object to run commands on. 60 @param out_dir: temporary directory. 61 """ 62 if IsTPMAvailable(client): 63 logging.debug('TPM is not owned') 64 return 65 66 client.run('stop ui') 67 client.run('crossystem clear_tpm_owner_request=1') 68 CleanupAndReboot(client) 69 70def ClearTPMOwnerRequest(client, wait_for_ready=False, timeout=60): 71 """Clears the TPM using crossystem command. 72 73 @param client: client object to run commands on. 74 @param wait_for_ready: wait until the TPM status is ready 75 @param timeout: number of seconds to wait for the TPM to become ready. 76 """ 77 if not client.run('crossystem clear_tpm_owner_request=1', 78 ignore_status=True).exit_status == 0: 79 raise error.TestFail('Unable to clear TPM.') 80 81 CleanupAndReboot(client) 82 83 if wait_for_ready: 84 status = '' 85 end_time = time.time() + timeout 86 # Wait for tpm_manager to send a successful reply. 87 while 'STATUS_SUCCESS' not in status and time.time() < end_time: 88 status = client.run('tpm_manager_client status --nonsensitive', 89 ignore_status=True).stdout.strip() 90 logging.debug(status) 91 time.sleep(1) 92 # Verify if the TPM is unowned. 93 tpm_status = TPMStatus(client) 94 logging.info('TPM status: %s', tpm_status) 95 if tpm_status['is_owned']: 96 raise error.TestFail('Failed to clear TPM.') 97 98 99def ClearTPMIfOwned(client): 100 """Clear the TPM only if device is already owned. 101 102 @param client: client object to run commands on.""" 103 tpm_status = TPMStatus(client) 104 logging.info('TPM status: %s', tpm_status) 105 if tpm_status['is_owned']: 106 logging.info('Clearing TPM because this device is owned.') 107 ClearTPMOwnerRequest(client) 108 109 110def CleanupAndReboot(client): 111 """Cleanup and reboot the device. 112 113 @param client: client object to run commands on. 114 """ 115 full_rm = 'sudo rm -rf ' + ' '.join(_RM_FILES + _RM_DIRS) 116 client.run(full_rm, ignore_status=True) 117 client.run('sync', ignore_status=True) 118 client.reboot() 119