1 // Copyright (c) 2012 The Chromium 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
5 #ifndef CHROMEOS_TPM_INSTALL_ATTRIBUTES_H_
6 #define CHROMEOS_TPM_INSTALL_ATTRIBUTES_H_
7
8 #include <map>
9 #include <string>
10
11 #include "base/callback.h"
12 #include "base/compiler_specific.h"
13 #include "base/component_export.h"
14 #include "base/files/file_path.h"
15 #include "base/gtest_prod_util.h"
16 #include "base/macros.h"
17 #include "base/memory/weak_ptr.h"
18 #include "base/optional.h"
19 #include "chromeos/dbus/cryptohome/cryptohome_client.h"
20 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
21
22 namespace chromeos {
23
24 // Brokers access to the installation-time attributes on Chrome OS. When
25 // initialized with kInstallAttributesFileName, the attributes are fully trusted
26 // (signature has been verified by lockbox-cache).
COMPONENT_EXPORT(CHROMEOS_TPM)27 class COMPONENT_EXPORT(CHROMEOS_TPM) InstallAttributes {
28 public:
29 // InstallAttributes status codes. Do not change the numeric ids or the
30 // meaning of the existing codes to preserve the interpretability of old
31 // logfiles.
32 enum LockResult {
33 LOCK_SUCCESS = 0, // Success.
34 LOCK_NOT_READY = 1, // Backend/TPM still initializing.
35 LOCK_TIMEOUT = 2, // Backend/TPM timed out.
36 LOCK_BACKEND_INVALID = 3, // Backend failed to initialize.
37 LOCK_ALREADY_LOCKED = 4, // TPM has already been locked.
38 LOCK_SET_ERROR = 5, // Failed to set attributes.
39 LOCK_FINALIZE_ERROR = 6, // Backend failed to lock.
40 LOCK_READBACK_ERROR = 7, // Inconsistency reading back registration data.
41 LOCK_WRONG_DOMAIN = 8, // Device already registered to another domain or
42 // other mismatch of other attributes.
43 LOCK_WRONG_MODE = 9, // Device already locked to a different mode.
44 };
45
46 // A callback to handle responses of methods returning a LockResult value.
47 using LockResultCallback = base::OnceCallback<void(LockResult lock_result)>;
48
49 // Manage singleton instance.
50 static void Initialize();
51 static bool IsInitialized();
52 static void Shutdown();
53 static InstallAttributes* Get();
54
55 // Sets the singleton to |test_instance|. Does not take ownership of the
56 // instance. Should be matched with a call to |ShutdownForTesting| once the
57 // test is finished and before the instance is deleted.
58 static void SetForTesting(InstallAttributes* test_instance);
59 static void ShutdownForTesting();
60
61 explicit InstallAttributes(CryptohomeClient* cryptohome_client);
62 ~InstallAttributes();
63
64 // Tries to read install attributes from |cache_file| to work around slow
65 // cryptohome startup which takes a while to register its D-Bus interface.
66 // (See http://crosbug.com/37367 for background on this.) When called with
67 // kInstallAttributesFileName (created early during the boot process by
68 // lockbox-cache) the install attributes are fully trusted.
69 void Init(const base::FilePath& cache_file);
70
71 // Makes sure the local caches for enterprise-related install attributes are
72 // up to date with what cryptohome has. This method checks the readiness of
73 // attributes and read them if ready. Actual read will be performed in
74 // ReadAttributesIfReady().
75 void ReadImmutableAttributes(base::OnceClosure callback);
76
77 // Updates the firmware management parameters from TPM, storing the devmode
78 // flag according to |block_devmode|. Invokes |callback| when done. Must be
79 // called before LockDevice is done. Used to update TPM on enrollment.
80 void SetBlockDevmodeInTpm(bool block_devmode,
81 DBusMethodCallback<cryptohome::BaseReply> callback);
82
83 // Locks the device into |device_mode|. Depending on |device_mode|, a
84 // specific subset of |domain|, |realm| and |device_id| must be set. Can also
85 // be called after the lock has already been taken, in which case it checks
86 // that the passed parameters fully agree with the locked attributes.
87 // |callback| must not be null and is called with the result. Must not be
88 // called while a previous LockDevice() invocation is still pending.
89 void LockDevice(policy::DeviceMode device_mode,
90 const std::string& domain,
91 const std::string& realm,
92 const std::string& device_id,
93 LockResultCallback callback);
94
95 // Checks whether this devices is under any kind of enterprise management.
96 bool IsEnterpriseManaged() const;
97
98 // Checks whether this is a cloud (DM server) managed enterprise device.
99 bool IsCloudManaged() const;
100
101 // Checks whether this is an Active Directory managed enterprise device.
102 bool IsActiveDirectoryManaged() const;
103
104 // Checks whether this is a consumer kiosk enabled device.
105 bool IsConsumerKioskDeviceWithAutoLaunch();
106
107 // Return the mode the device was enrolled to. The return value for devices
108 // that are not locked yet is DEVICE_MODE_UNKNOWN.
109 policy::DeviceMode GetMode() const { return registration_mode_; }
110
111 // Return the domain this device belongs to or an empty string if the device
112 // is not a cloud-managed enterprise device.
113 std::string GetDomain() const { return registration_domain_; }
114
115 // Return the realm this device belongs to or an empty string if the device is
116 // not an AD enterprise device.
117 std::string GetRealm() const { return registration_realm_; }
118
119 // Return the device id that was generated when the device was registered.
120 // Returns an empty string if the device is not an enterprise device or the
121 // device id was not stored in the lockbox (prior to R19).
122 std::string GetDeviceId() const { return registration_device_id_; }
123
124 // Return whether TPM is locked.
125 bool IsDeviceLocked() const { return device_locked_; }
126
127 protected:
128 // True if install attributes have been read successfully. False if read
129 // failed or no read attempt was made.
130 bool device_locked_ = false;
131
132 // Whether the TPM / install attributes consistency check is running.
133 bool consistency_check_running_ = false;
134
135 // To be run after the consistency check has finished.
136 base::OnceClosure post_check_action_;
137
138 // Wether the LockDevice() initiated TPM calls are running.
139 bool device_lock_running_ = false;
140
141 // The actual install attributes. Populated by DecodeInstallAttributes()
142 // exclusively.
143 policy::DeviceMode registration_mode_ = policy::DEVICE_MODE_PENDING;
144 std::string registration_domain_;
145 std::string registration_realm_;
146 std::string registration_device_id_;
147
148 private:
149 FRIEND_TEST_ALL_PREFIXES(InstallAttributesTest, DeviceLockedFromOlderVersion);
150 FRIEND_TEST_ALL_PREFIXES(InstallAttributesTest, Init);
151 FRIEND_TEST_ALL_PREFIXES(InstallAttributesTest, InitForConsumerKiosk);
152 FRIEND_TEST_ALL_PREFIXES(InstallAttributesTest, LockCanonicalize);
153 FRIEND_TEST_ALL_PREFIXES(InstallAttributesTest,
154 VerifyFakeInstallAttributesCache);
155
156 // Constants for the possible device modes that can be stored in the lockbox.
157 static const char kConsumerDeviceMode[];
158 static const char kEnterpriseDeviceMode[];
159 static const char kEnterpriseADDeviceMode[];
160 static const char kLegacyRetailDeviceMode[];
161 static const char kConsumerKioskDeviceMode[];
162 static const char kDemoDeviceMode[];
163
164 // Field names in the lockbox.
165 static const char kAttrEnterpriseDeviceId[];
166 static const char kAttrEnterpriseDomain[];
167 static const char kAttrEnterpriseRealm[];
168 static const char kAttrEnterpriseMode[];
169 static const char kAttrEnterpriseOwned[];
170 static const char kAttrEnterpriseUser[];
171 static const char kAttrConsumerKioskEnabled[];
172
173 // Called by |cryptohome_client_| when the cryptohome service becomes
174 // initially available over D-Bus.
175 void OnCryptohomeServiceInitiallyAvailable(bool service_is_ready);
176
177 // Translates DeviceMode constants to strings used in the lockbox.
178 std::string GetDeviceModeString(policy::DeviceMode mode);
179
180 // Translates strings used in the lockbox to DeviceMode values.
181 policy::DeviceMode GetDeviceModeFromString(const std::string& mode);
182
183 // Decode the install attributes provided in |attr_map| (including some
184 // normalization and processing for backward compatibility) and guarantee that
185 // |registration_*| members are set self-consistently.
186 void DecodeInstallAttributes(
187 const std::map<std::string, std::string>& attr_map);
188
189 // Helper for ReadImmutableAttributes.
190 void ReadAttributesIfReady(base::OnceClosure callback,
191 base::Optional<bool> response);
192
193 // Helper for LockDevice(). Handles the result of InstallAttributesIsReady()
194 // and continue processing LockDevice if the result is true.
195 void LockDeviceIfAttributesIsReady(policy::DeviceMode device_mode,
196 const std::string& domain,
197 const std::string& realm,
198 const std::string& device_id,
199 LockResultCallback callback,
200 base::Optional<bool> response);
201
202 // Confirms the registered user and invoke the callback.
203 void OnReadImmutableAttributes(policy::DeviceMode mode,
204 const std::string& domain,
205 const std::string& realm,
206 const std::string& device_id,
207 LockResultCallback callback);
208
209 // Check state of install attributes against TPM lock state and generate UMA
210 // for the result. Asynchronously retry |dbus_retries| times in case of DBUS
211 // errors (cryptohomed startup is slow).
212 void TriggerConsistencyCheck(int dbus_retries);
213
214 // Callback for TpmGetPassword() DBUS call. Generates UMA or schedules retry
215 // in case of DBUS error.
216 void OnTpmGetPasswordCompleted(int dbus_retries_remaining,
217 base::Optional<std::string> result);
218
219 CryptohomeClient* cryptohome_client_;
220
221 base::WeakPtrFactory<InstallAttributes> weak_ptr_factory_{this};
222
223 DISALLOW_COPY_AND_ASSIGN(InstallAttributes);
224 };
225
226 } // namespace chromeos
227
228 #endif // CHROMEOS_TPM_INSTALL_ATTRIBUTES_H_
229