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 #include "chromeos/tpm/install_attributes.h"
6 
7 #include <memory>
8 
9 #include "base/bind.h"
10 #include "base/callback_helpers.h"
11 #include "base/files/file_util.h"
12 #include "base/files/scoped_temp_dir.h"
13 #include "base/path_service.h"
14 #include "base/run_loop.h"
15 #include "base/test/metrics/histogram_tester.h"
16 #include "base/test/task_environment.h"
17 #include "chromeos/dbus/constants/dbus_paths.h"
18 #include "chromeos/dbus/cryptohome/cryptohome_client.h"
19 #include "chromeos/dbus/cryptohome/rpc.pb.h"
20 #include "chromeos/dbus/cryptohome/tpm_util.h"
21 #include "components/policy/proto/install_attributes.pb.h"
22 #include "google_apis/gaia/gaia_auth_util.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 
25 namespace chromeos {
26 
27 namespace {
28 
CopyLockResult(base::RunLoop * loop,InstallAttributes::LockResult * out,InstallAttributes::LockResult result)29 void CopyLockResult(base::RunLoop* loop,
30                     InstallAttributes::LockResult* out,
31                     InstallAttributes::LockResult result) {
32   *out = result;
33   loop->Quit();
34 }
35 
36 }  // namespace
37 
38 static const char kTestDomain[] = "example.com";
39 static const char kTestRealm[] = "realm.example.com";
40 static const char kTestDeviceId[] = "133750519";
41 static const char kTestUserDeprecated[] = "test@example.com";
42 
43 class InstallAttributesTest : public testing::Test {
44  protected:
InstallAttributesTest()45   InstallAttributesTest()
46       : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {}
47 
SetUp()48   void SetUp() override {
49     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
50     ASSERT_TRUE(base::PathService::OverrideAndCreateIfNeeded(
51         dbus_paths::FILE_INSTALL_ATTRIBUTES, GetTempPath(), true, false));
52     CryptohomeClient::InitializeFake();
53     install_attributes_ =
54         std::make_unique<InstallAttributes>(CryptohomeClient::Get());
55   }
56 
TearDown()57   void TearDown() override { CryptohomeClient::Shutdown(); }
58 
GetTempPath() const59   base::FilePath GetTempPath() const {
60     base::FilePath temp_path = base::MakeAbsoluteFilePath(temp_dir_.GetPath());
61     return temp_path.Append("install_attrs_test");
62   }
63 
SetAttribute(cryptohome::SerializedInstallAttributes * install_attrs_proto,const std::string & name,const std::string & value)64   void SetAttribute(
65       cryptohome::SerializedInstallAttributes* install_attrs_proto,
66       const std::string& name,
67       const std::string& value) {
68     cryptohome::SerializedInstallAttributes::Attribute* attribute;
69     attribute = install_attrs_proto->add_attributes();
70     attribute->set_name(name);
71     attribute->set_value(value);
72   }
73 
74   base::test::TaskEnvironment task_environment_;
75   base::ScopedTempDir temp_dir_;
76   std::unique_ptr<InstallAttributes> install_attributes_;
77 
LockDeviceAndWaitForResult(policy::DeviceMode device_mode,const std::string & domain,const std::string & realm,const std::string & device_id)78   InstallAttributes::LockResult LockDeviceAndWaitForResult(
79       policy::DeviceMode device_mode,
80       const std::string& domain,
81       const std::string& realm,
82       const std::string& device_id) {
83     base::RunLoop loop;
84     InstallAttributes::LockResult result;
85     install_attributes_->LockDevice(
86         device_mode, domain, realm, device_id,
87         base::BindOnce(&CopyLockResult, &loop, &result));
88     loop.Run();
89     return result;
90   }
91 };
92 
TEST_F(InstallAttributesTest,Lock)93 TEST_F(InstallAttributesTest, Lock) {
94   {
95     base::HistogramTester histogram_tester;
96     EXPECT_EQ(
97         InstallAttributes::LOCK_SUCCESS,
98         LockDeviceAndWaitForResult(policy::DEVICE_MODE_ENTERPRISE, kTestDomain,
99                                    std::string(),  // realm
100                                    kTestDeviceId));
101     histogram_tester.ExpectUniqueSample(
102         "Enterprise.ExistingInstallAttributesLock", 0, 1);
103   }
104 
105   {
106     // Locking an already locked device should succeed if the parameters match.
107     base::HistogramTester histogram_tester;
108     EXPECT_EQ(
109         InstallAttributes::LOCK_SUCCESS,
110         LockDeviceAndWaitForResult(policy::DEVICE_MODE_ENTERPRISE, kTestDomain,
111                                    std::string(),  // realm
112                                    kTestDeviceId));
113     histogram_tester.ExpectUniqueSample(
114         "Enterprise.ExistingInstallAttributesLock", 1, 1);
115   }
116 
117   {
118     // But another domain should fail.
119     base::HistogramTester histogram_tester;
120     EXPECT_EQ(InstallAttributes::LOCK_WRONG_DOMAIN,
121               LockDeviceAndWaitForResult(policy::DEVICE_MODE_ENTERPRISE,
122                                          "anotherexample.com",
123                                          std::string(),  // realm
124                                          kTestDeviceId));
125     histogram_tester.ExpectTotalCount(
126         "Enterprise.ExistingInstallAttributesLock", 0);
127   }
128 
129   {
130     // A non-matching mode should fail as well.
131     base::HistogramTester histogram_tester;
132     EXPECT_EQ(InstallAttributes::LOCK_WRONG_MODE,
133               LockDeviceAndWaitForResult(
134                   policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH,
135                   std::string(),    // domain
136                   std::string(),    // realm
137                   std::string()));  // device id
138     histogram_tester.ExpectTotalCount(
139         "Enterprise.ExistingInstallAttributesLock", 0);
140   }
141 }
142 
TEST_F(InstallAttributesTest,IsEnterpriseManagedCloud)143 TEST_F(InstallAttributesTest, IsEnterpriseManagedCloud) {
144   install_attributes_->Init(GetTempPath());
145   EXPECT_FALSE(install_attributes_->IsEnterpriseManaged());
146   ASSERT_EQ(
147       InstallAttributes::LOCK_SUCCESS,
148       LockDeviceAndWaitForResult(policy::DEVICE_MODE_ENTERPRISE, kTestDomain,
149                                  std::string(),  // realm
150                                  kTestDeviceId));
151   EXPECT_TRUE(install_attributes_->IsEnterpriseManaged());
152   EXPECT_TRUE(install_attributes_->IsCloudManaged());
153   EXPECT_FALSE(install_attributes_->IsActiveDirectoryManaged());
154 }
155 
TEST_F(InstallAttributesTest,IsEnterpriseManagedRealm)156 TEST_F(InstallAttributesTest, IsEnterpriseManagedRealm) {
157   install_attributes_->Init(GetTempPath());
158   EXPECT_FALSE(install_attributes_->IsEnterpriseManaged());
159   ASSERT_EQ(InstallAttributes::LOCK_SUCCESS,
160             LockDeviceAndWaitForResult(policy::DEVICE_MODE_ENTERPRISE_AD,
161                                        std::string(),  // domain
162                                        kTestRealm, kTestDeviceId));
163   EXPECT_TRUE(install_attributes_->IsEnterpriseManaged());
164   EXPECT_FALSE(install_attributes_->IsCloudManaged());
165   EXPECT_TRUE(install_attributes_->IsActiveDirectoryManaged());
166 }
167 
TEST_F(InstallAttributesTest,IsEnterpriseManagedDemoMode)168 TEST_F(InstallAttributesTest, IsEnterpriseManagedDemoMode) {
169   install_attributes_->Init(GetTempPath());
170   EXPECT_FALSE(install_attributes_->IsEnterpriseManaged());
171   ASSERT_EQ(InstallAttributes::LOCK_SUCCESS,
172             LockDeviceAndWaitForResult(policy::DEVICE_MODE_DEMO, kTestDomain,
173                                        std::string(),  // realm
174                                        kTestDeviceId));
175   EXPECT_TRUE(install_attributes_->IsEnterpriseManaged());
176   EXPECT_TRUE(install_attributes_->IsCloudManaged());
177   EXPECT_FALSE(install_attributes_->IsActiveDirectoryManaged());
178 }
179 
TEST_F(InstallAttributesTest,GettersCloud)180 TEST_F(InstallAttributesTest, GettersCloud) {
181   install_attributes_->Init(GetTempPath());
182   EXPECT_EQ(policy::DEVICE_MODE_PENDING, install_attributes_->GetMode());
183   EXPECT_EQ(std::string(), install_attributes_->GetDomain());
184   EXPECT_EQ(std::string(), install_attributes_->GetRealm());
185   EXPECT_EQ(std::string(), install_attributes_->GetDeviceId());
186   ASSERT_EQ(
187       InstallAttributes::LOCK_SUCCESS,
188       LockDeviceAndWaitForResult(policy::DEVICE_MODE_ENTERPRISE, kTestDomain,
189                                  std::string(),  // realm
190                                  kTestDeviceId));
191   EXPECT_EQ(policy::DEVICE_MODE_ENTERPRISE, install_attributes_->GetMode());
192   EXPECT_EQ(kTestDomain, install_attributes_->GetDomain());
193   EXPECT_EQ(std::string(), install_attributes_->GetRealm());
194   EXPECT_EQ(kTestDeviceId, install_attributes_->GetDeviceId());
195 }
196 
TEST_F(InstallAttributesTest,GettersAD)197 TEST_F(InstallAttributesTest, GettersAD) {
198   install_attributes_->Init(GetTempPath());
199   EXPECT_EQ(policy::DEVICE_MODE_PENDING, install_attributes_->GetMode());
200   EXPECT_EQ(std::string(), install_attributes_->GetDomain());
201   EXPECT_EQ(std::string(), install_attributes_->GetRealm());
202   EXPECT_EQ(std::string(), install_attributes_->GetDeviceId());
203   ASSERT_EQ(InstallAttributes::LOCK_SUCCESS,
204             LockDeviceAndWaitForResult(policy::DEVICE_MODE_ENTERPRISE_AD,
205                                        std::string(),  // domain
206                                        kTestRealm, kTestDeviceId));
207   EXPECT_EQ(policy::DEVICE_MODE_ENTERPRISE_AD, install_attributes_->GetMode());
208   EXPECT_EQ(std::string(), install_attributes_->GetDomain());
209   EXPECT_EQ(kTestRealm, install_attributes_->GetRealm());
210   EXPECT_EQ(kTestDeviceId, install_attributes_->GetDeviceId());
211 }
212 
TEST_F(InstallAttributesTest,GettersDemoMode)213 TEST_F(InstallAttributesTest, GettersDemoMode) {
214   install_attributes_->Init(GetTempPath());
215   EXPECT_EQ(policy::DEVICE_MODE_PENDING, install_attributes_->GetMode());
216   EXPECT_EQ(std::string(), install_attributes_->GetDomain());
217   EXPECT_EQ(std::string(), install_attributes_->GetRealm());
218   EXPECT_EQ(std::string(), install_attributes_->GetDeviceId());
219   ASSERT_EQ(InstallAttributes::LOCK_SUCCESS,
220             LockDeviceAndWaitForResult(policy::DEVICE_MODE_DEMO, kTestDomain,
221                                        std::string(),  // realm
222                                        kTestDeviceId));
223   EXPECT_EQ(policy::DEVICE_MODE_DEMO, install_attributes_->GetMode());
224   EXPECT_EQ(kTestDomain, install_attributes_->GetDomain());
225   EXPECT_EQ(std::string(), install_attributes_->GetRealm());
226   EXPECT_EQ(kTestDeviceId, install_attributes_->GetDeviceId());
227 }
228 
TEST_F(InstallAttributesTest,ConsumerDevice)229 TEST_F(InstallAttributesTest, ConsumerDevice) {
230   install_attributes_->Init(GetTempPath());
231   EXPECT_EQ(policy::DEVICE_MODE_PENDING, install_attributes_->GetMode());
232   // Lock the attributes empty.
233   ASSERT_TRUE(tpm_util::InstallAttributesFinalize());
234   base::RunLoop loop;
235   install_attributes_->ReadImmutableAttributes(loop.QuitClosure());
236   loop.Run();
237 
238   ASSERT_FALSE(tpm_util::InstallAttributesIsFirstInstall());
239   EXPECT_EQ(policy::DEVICE_MODE_CONSUMER, install_attributes_->GetMode());
240   EXPECT_EQ(std::string(), install_attributes_->GetDomain());
241   EXPECT_EQ(std::string(), install_attributes_->GetRealm());
242   EXPECT_EQ(std::string(), install_attributes_->GetDeviceId());
243 }
244 
TEST_F(InstallAttributesTest,ConsumerKioskDevice)245 TEST_F(InstallAttributesTest, ConsumerKioskDevice) {
246   install_attributes_->Init(GetTempPath());
247   EXPECT_EQ(policy::DEVICE_MODE_PENDING, install_attributes_->GetMode());
248   // Lock the attributes for consumer kiosk.
249   ASSERT_EQ(
250       InstallAttributes::LOCK_SUCCESS,
251       LockDeviceAndWaitForResult(policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH,
252                                  std::string(), std::string(), std::string()));
253 
254   ASSERT_FALSE(tpm_util::InstallAttributesIsFirstInstall());
255   EXPECT_EQ(policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH,
256             install_attributes_->GetMode());
257   EXPECT_EQ(std::string(), install_attributes_->GetDomain());
258   EXPECT_EQ(std::string(), install_attributes_->GetRealm());
259   EXPECT_EQ(std::string(), install_attributes_->GetDeviceId());
260   ASSERT_TRUE(install_attributes_->IsConsumerKioskDeviceWithAutoLaunch());
261 }
262 
TEST_F(InstallAttributesTest,DeviceLockedFromOlderVersion)263 TEST_F(InstallAttributesTest, DeviceLockedFromOlderVersion) {
264   install_attributes_->Init(GetTempPath());
265   EXPECT_EQ(policy::DEVICE_MODE_PENDING, install_attributes_->GetMode());
266   // Lock the attributes as if it was done from older Chrome version.
267   ASSERT_TRUE(tpm_util::InstallAttributesSet(
268       InstallAttributes::kAttrEnterpriseOwned, "true"));
269   ASSERT_TRUE(tpm_util::InstallAttributesSet(
270       InstallAttributes::kAttrEnterpriseUser, kTestUserDeprecated));
271   ASSERT_TRUE(tpm_util::InstallAttributesFinalize());
272   base::RunLoop loop;
273   install_attributes_->ReadImmutableAttributes(loop.QuitClosure());
274   loop.Run();
275 
276   ASSERT_FALSE(tpm_util::InstallAttributesIsFirstInstall());
277   EXPECT_EQ(policy::DEVICE_MODE_ENTERPRISE, install_attributes_->GetMode());
278   EXPECT_EQ(kTestDomain, install_attributes_->GetDomain());
279   EXPECT_EQ(std::string(), install_attributes_->GetRealm());
280   EXPECT_EQ(std::string(), install_attributes_->GetDeviceId());
281 }
282 
TEST_F(InstallAttributesTest,Init)283 TEST_F(InstallAttributesTest, Init) {
284   cryptohome::SerializedInstallAttributes install_attrs_proto;
285   SetAttribute(&install_attrs_proto, InstallAttributes::kAttrEnterpriseOwned,
286                "true");
287   SetAttribute(&install_attrs_proto, InstallAttributes::kAttrEnterpriseUser,
288                kTestUserDeprecated);
289   const std::string blob(install_attrs_proto.SerializeAsString());
290   ASSERT_EQ(static_cast<int>(blob.size()),
291             base::WriteFile(GetTempPath(), blob.c_str(), blob.size()));
292   install_attributes_->Init(GetTempPath());
293   EXPECT_EQ(policy::DEVICE_MODE_ENTERPRISE, install_attributes_->GetMode());
294   EXPECT_EQ(kTestDomain, install_attributes_->GetDomain());
295   EXPECT_EQ(std::string(), install_attributes_->GetRealm());
296   EXPECT_EQ(std::string(), install_attributes_->GetDeviceId());
297 }
298 
TEST_F(InstallAttributesTest,InitForConsumerKiosk)299 TEST_F(InstallAttributesTest, InitForConsumerKiosk) {
300   cryptohome::SerializedInstallAttributes install_attrs_proto;
301   SetAttribute(&install_attrs_proto,
302                InstallAttributes::kAttrConsumerKioskEnabled, "true");
303   const std::string blob(install_attrs_proto.SerializeAsString());
304   ASSERT_EQ(static_cast<int>(blob.size()),
305             base::WriteFile(GetTempPath(), blob.c_str(), blob.size()));
306   install_attributes_->Init(GetTempPath());
307   EXPECT_EQ(policy::DEVICE_MODE_CONSUMER_KIOSK_AUTOLAUNCH,
308             install_attributes_->GetMode());
309   EXPECT_EQ(std::string(), install_attributes_->GetDomain());
310   EXPECT_EQ(std::string(), install_attributes_->GetRealm());
311   EXPECT_EQ(std::string(), install_attributes_->GetDeviceId());
312 }
313 
TEST_F(InstallAttributesTest,VerifyFakeInstallAttributesCache)314 TEST_F(InstallAttributesTest, VerifyFakeInstallAttributesCache) {
315   // This test verifies that FakeCryptohomeClient::InstallAttributesFinalize
316   // writes a cache that InstallAttributes::Init accepts.
317 
318   // Verify that no attributes are initially set.
319   install_attributes_->Init(GetTempPath());
320   EXPECT_EQ(policy::DEVICE_MODE_PENDING, install_attributes_->GetMode());
321 
322   // Write test values.
323   ASSERT_TRUE(tpm_util::InstallAttributesSet(
324       InstallAttributes::kAttrEnterpriseOwned, "true"));
325   ASSERT_TRUE(tpm_util::InstallAttributesSet(
326       InstallAttributes::kAttrEnterpriseUser, kTestUserDeprecated));
327   ASSERT_TRUE(tpm_util::InstallAttributesFinalize());
328 
329   // Verify that InstallAttributes correctly decodes the stub cache file.
330   install_attributes_->Init(GetTempPath());
331   EXPECT_EQ(policy::DEVICE_MODE_ENTERPRISE, install_attributes_->GetMode());
332   EXPECT_EQ(kTestDomain, install_attributes_->GetDomain());
333   EXPECT_EQ(std::string(), install_attributes_->GetRealm());
334   EXPECT_EQ(std::string(), install_attributes_->GetDeviceId());
335 }
336 
TEST_F(InstallAttributesTest,CheckSetBlockDevmodeInTpm)337 TEST_F(InstallAttributesTest, CheckSetBlockDevmodeInTpm) {
338   bool succeeded = false;
339   install_attributes_->SetBlockDevmodeInTpm(
340       true,
341       base::BindOnce(
342           [](bool* succeeded, base::Optional<cryptohome::BaseReply> reply) {
343             *succeeded = reply.has_value();
344           },
345           &succeeded));
346   base::RunLoop().RunUntilIdle();
347 
348   EXPECT_TRUE(succeeded);
349 }
350 
351 }  // namespace chromeos
352