Support for Remora enrollment.
* Methods for enterprise enrollment of Remora devices.
* Methods to save TPM password and clear TPM.
* utility function to read credentials from a file.
* sample test that exercises enrollment.
BUG=chromium:342884
TEST=enterprise_RemoraRequisition
Change-Id: Ie872e9ba0702474d9f605c5520577cf4e0ad21d2
Reviewed-on: https://chromium-review.googlesource.com/199560
Tested-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Mattias Nissler <mnissler@chromium.org>
Reviewed-by: Achuith Bhandarkar <achuith@chromium.org>
Commit-Queue: Achuith Bhandarkar <achuith@chromium.org>
diff --git a/client/common_lib/cros/enrollment.py b/client/common_lib/cros/enrollment.py
new file mode 100644
index 0000000..f4c8a35
--- /dev/null
+++ b/client/common_lib/cros/enrollment.py
@@ -0,0 +1,119 @@
+# 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
+
+from autotest_lib.client.bin import utils
+from autotest_lib.client.cros import cros_ui, cryptohome, ownership
+from telemetry.core import exceptions
+from telemetry.core.backends.chrome import cros_interface
+
+
+_PASSWD_FILE = '/var/tmp/tpm_passwd'
+
+
+def ClearTPM():
+ """Clears the TPM (if it is owned) using the password stored in
+ /var/tmp/tpm_passwd. Returns True if tpm was owned.
+
+ @return True if the TPM was owned - enrollment should not be attempted.
+ """
+ status = cryptohome.get_tpm_status()
+ if not status['Owned']:
+ logging.debug('TPM is not owned')
+ return False
+ password = status['Password']
+ if not password:
+ if not os.path.isfile(_PASSWD_FILE):
+ logging.warn('Password file %s doesn\'t exist, cannot clear TPM. '
+ 'You need to have the firmware clear the TPM, for '
+ 'instance using crossystem or by toggling the dev '
+ 'switch.', _PASSWD_FILE)
+ return True
+ with open(_PASSWD_FILE) as f:
+ password = f.read().rstrip()
+
+ if not password:
+ logging.warn('Password file %s empty, cannot clear TPM. '
+ 'You need to have the firmware clear the TPM, for '
+ 'instance using crossystem or by toggling the dev switch.',
+ _PASSWD_FILE)
+ return True
+
+ cros_ui.stop()
+ res = utils.system_output('tpm_clear --pass ' + password)
+ logging.warn(repr(res))
+
+ cryptohome.remove_all_vaults()
+ ownership.clear_ownership_files_no_restart()
+ logging.warn('Please reboot the system')
+ return True
+
+
+def _SaveTPMPassword():
+ """Save TPM Password to /var/tpm/tpm_passwd.
+
+ During enrollment, the TPM password becomes visible - we capture it and
+ save it in to a local file, so we can clear the TPM at the end of the test.
+ """
+ password = utils.poll_for_condition(
+ lambda: cryptohome.get_tpm_status()['Password'],
+ sleep_interval=0.5, timeout=60)
+ if password:
+ with open(_PASSWD_FILE, 'w') as f:
+ f.write(password)
+ else:
+ logging.warn('Could not save TPM password')
+ logging.info('TPM Password: ' + password)
+ return password
+
+
+def _ExecuteOobeCmd(browser, cmd):
+ logging.info('Invoking ' + cmd)
+ oobe = browser.oobe
+ oobe.WaitForJavaScriptExpression('typeof Oobe !== \'undefined\'', 10)
+ oobe.ExecuteJavaScript(cmd)
+
+
+def SwitchToRemora(browser):
+ """Switch to Remora enrollment.
+
+ @param browser: telemetry browser object.
+ """
+ _cri = cros_interface.CrOSInterface()
+ pid = _cri.GetChromePid()
+ try:
+ # This will restart the browser.
+ _ExecuteOobeCmd(browser, 'Oobe.remoraRequisitionForTesting();')
+ except (exceptions.BrowserConnectionGoneException,
+ exceptions.TabCrashException):
+ pass
+ utils.poll_for_condition(lambda: pid != _cri.GetChromePid(), timeout=60)
+ utils.poll_for_condition(lambda: browser.oobe_exists, timeout=30)
+
+ _ExecuteOobeCmd(browser, 'Oobe.skipToLoginForTesting();')
+ _SaveTPMPassword()
+
+
+def FinishEnrollment(oobe):
+ """Wait for enrollment to finish and dismiss the last enrollment screen.
+
+ @param oobe: telemetry oobe object.
+ """
+ oobe.WaitForJavaScriptExpression(
+ "document.getElementById('oauth-enrollment').className."
+ "search('oauth-enroll-state-success') != -1", 30)
+ oobe.EvaluateJavaScript('Oobe.enterpriseEnrollmentDone();')
+
+
+def RemoraEnrollment(browser, user_id, password):
+ """Enterprise login for a Remora device.
+
+ @param browser: telemetry browser object.
+ @param user_id: login credentials user_id.
+ @param password: login credentials password.
+ """
+ SwitchToRemora(browser)
+ browser.oobe.NavigateGaiaLogin(user_id, password)
+ FinishEnrollment(browser.oobe)