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