• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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