You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
3.7 KiB
119 lines
3.7 KiB
# Copyright 2014 The Chromium OS Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
|
|
import logging, os
|
|
import time
|
|
|
|
from autotest_lib.client.common_lib import error
|
|
from autotest_lib.client.cros import constants
|
|
|
|
|
|
_RM_FILES = ['/home/chronos/.oobe_completed',
|
|
'/home/chronos/Local\ State',
|
|
'/var/cache/shill/default.profile']
|
|
_RM_DIRS = ['/home/.shadow/*',
|
|
os.path.join(constants.ALLOWLIST_DIR, '*'),
|
|
'/var/cache/app_pack',
|
|
'/var/lib/tpm']
|
|
|
|
|
|
class NoTPMPasswordException(Exception):
|
|
"""No TPM Password could be found."""
|
|
pass
|
|
|
|
|
|
def TPMStatus(client):
|
|
"""Returns a dictionary with TPM status.
|
|
|
|
@param client: client object to run commands on.
|
|
"""
|
|
out = client.run('tpm_manager_client status --nonsensitive').stdout.strip()
|
|
lines = out.split('\n')[1:-1]
|
|
status = {}
|
|
for item in lines:
|
|
item = item.split(':')
|
|
if not item[0]:
|
|
continue
|
|
if len(item) == 1:
|
|
item.append('')
|
|
item = map(lambda x : x.strip(), item)
|
|
item[1] = True if item[1] == 'true' else item[1]
|
|
item[1] = False if item[1] == 'false' else item[1]
|
|
status[item[0]] = item[1]
|
|
return status
|
|
|
|
|
|
def IsTPMAvailable(client):
|
|
"""Returns True if the TPM is unowned and enabled.
|
|
|
|
@param client: client object to run commands on.
|
|
"""
|
|
status = TPMStatus(client)
|
|
return status['is_enabled'] and not status['is_owned']
|
|
|
|
|
|
def ClearTPMServer(client, out_dir):
|
|
"""Clears the TPM and reboots from a server-side autotest.
|
|
|
|
@param client: client object to run commands on.
|
|
@param out_dir: temporary directory.
|
|
"""
|
|
if IsTPMAvailable(client):
|
|
logging.debug('TPM is not owned')
|
|
return
|
|
|
|
client.run('stop ui')
|
|
client.run('crossystem clear_tpm_owner_request=1')
|
|
CleanupAndReboot(client)
|
|
|
|
def ClearTPMOwnerRequest(client, wait_for_ready=False, timeout=60):
|
|
"""Clears the TPM using crossystem command.
|
|
|
|
@param client: client object to run commands on.
|
|
@param wait_for_ready: wait until the TPM status is ready
|
|
@param timeout: number of seconds to wait for the TPM to become ready.
|
|
"""
|
|
if not client.run('crossystem clear_tpm_owner_request=1',
|
|
ignore_status=True).exit_status == 0:
|
|
raise error.TestFail('Unable to clear TPM.')
|
|
|
|
CleanupAndReboot(client)
|
|
|
|
if wait_for_ready:
|
|
status = ''
|
|
end_time = time.time() + timeout
|
|
# Wait for tpm_manager to send a successful reply.
|
|
while 'STATUS_SUCCESS' not in status and time.time() < end_time:
|
|
status = client.run('tpm_manager_client status --nonsensitive',
|
|
ignore_status=True).stdout.strip()
|
|
logging.debug(status)
|
|
time.sleep(1)
|
|
# Verify if the TPM is unowned.
|
|
tpm_status = TPMStatus(client)
|
|
logging.info('TPM status: %s', tpm_status)
|
|
if tpm_status['is_owned']:
|
|
raise error.TestFail('Failed to clear TPM.')
|
|
|
|
|
|
def ClearTPMIfOwned(client):
|
|
"""Clear the TPM only if device is already owned.
|
|
|
|
@param client: client object to run commands on."""
|
|
tpm_status = TPMStatus(client)
|
|
logging.info('TPM status: %s', tpm_status)
|
|
if tpm_status['is_owned']:
|
|
logging.info('Clearing TPM because this device is owned.')
|
|
ClearTPMOwnerRequest(client)
|
|
|
|
|
|
def CleanupAndReboot(client):
|
|
"""Cleanup and reboot the device.
|
|
|
|
@param client: client object to run commands on.
|
|
"""
|
|
full_rm = 'sudo rm -rf ' + ' '.join(_RM_FILES + _RM_DIRS)
|
|
client.run(full_rm, ignore_status=True)
|
|
client.run('sync', ignore_status=True)
|
|
client.reboot()
|