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 "chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos.h" 6 7 #include "base/basictypes.h" 8 #include "base/compiler_specific.h" 9 #include "base/memory/scoped_ptr.h" 10 #include "base/message_loop/message_loop.h" 11 #include "base/prefs/pref_registry_simple.h" 12 #include "base/prefs/testing_pref_service.h" 13 #include "base/run_loop.h" 14 #include "chrome/browser/chromeos/policy/device_cloud_policy_store_chromeos.h" 15 #include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" 16 #include "chrome/browser/chromeos/settings/cros_settings.h" 17 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" 18 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h" 19 #include "chrome/browser/chromeos/settings/device_settings_service.h" 20 #include "chrome/browser/chromeos/settings/device_settings_test_helper.h" 21 #include "chrome/browser/policy/cloud/cloud_policy_client.h" 22 #include "chrome/browser/policy/cloud/mock_device_management_service.h" 23 #include "chrome/browser/policy/external_data_fetcher.h" 24 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h" 25 #include "chrome/browser/policy/proto/cloud/device_management_backend.pb.h" 26 #include "chrome/browser/prefs/browser_prefs.h" 27 #include "chrome/test/base/testing_browser_process.h" 28 #include "chromeos/cryptohome/cryptohome_library.h" 29 #include "chromeos/cryptohome/mock_cryptohome_library.h" 30 #include "chromeos/dbus/cryptohome_client.h" 31 #include "chromeos/dbus/dbus_client_implementation_type.h" 32 #include "google_apis/gaia/gaia_oauth_client.h" 33 #include "net/url_request/test_url_fetcher_factory.h" 34 #include "net/url_request/url_request_test_util.h" 35 #include "policy/policy_constants.h" 36 #include "testing/gmock/include/gmock/gmock.h" 37 #include "testing/gtest/include/gtest/gtest.h" 38 39 using testing::AnyNumber; 40 using testing::AtMost; 41 using testing::DoAll; 42 using testing::Mock; 43 using testing::SaveArg; 44 using testing::_; 45 46 namespace em = enterprise_management; 47 48 namespace policy { 49 namespace { 50 51 void CopyLockResult(base::RunLoop* loop, 52 EnterpriseInstallAttributes::LockResult* out, 53 EnterpriseInstallAttributes::LockResult result) { 54 *out = result; 55 loop->Quit(); 56 } 57 58 class DeviceCloudPolicyManagerChromeOSTest 59 : public chromeos::DeviceSettingsTestBase { 60 protected: 61 DeviceCloudPolicyManagerChromeOSTest() 62 : cryptohome_library_(chromeos::CryptohomeLibrary::GetTestImpl()), 63 stub_cryptohome_client_(chromeos::CryptohomeClient::Create( 64 chromeos::STUB_DBUS_CLIENT_IMPLEMENTATION, NULL)), 65 install_attributes_(cryptohome_library_.get(), 66 stub_cryptohome_client_.get()), 67 store_(new DeviceCloudPolicyStoreChromeOS(&device_settings_service_, 68 &install_attributes_)), 69 manager_(make_scoped_ptr(store_), &install_attributes_) {} 70 71 virtual void SetUp() OVERRIDE { 72 DeviceSettingsTestBase::SetUp(); 73 chrome::RegisterLocalState(local_state_.registry()); 74 manager_.Init(); 75 76 // DeviceOAuth2TokenService uses the system request context to fetch 77 // OAuth tokens, then writes the token to local state, encrypting it 78 // first with methods in CryptohomeLibrary. 79 request_context_getter_ = new net::TestURLRequestContextGetter( 80 loop_.message_loop_proxy()); 81 TestingBrowserProcess::GetGlobal()->SetSystemRequestContext( 82 request_context_getter_.get()); 83 TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_); 84 chromeos::DeviceOAuth2TokenServiceFactory::Initialize(); 85 chromeos::CryptohomeLibrary::SetForTest(cryptohome_library_.get()); 86 url_fetcher_response_code_ = 200; 87 url_fetcher_response_string_ = "{\"access_token\":\"accessToken4Test\"," 88 "\"expires_in\":1234," 89 "\"refresh_token\":\"refreshToken4Test\"}"; 90 } 91 92 virtual void TearDown() OVERRIDE { 93 manager_.Shutdown(); 94 DeviceSettingsTestBase::TearDown(); 95 96 chromeos::DeviceOAuth2TokenServiceFactory::Shutdown(); 97 chromeos::CryptohomeLibrary::SetForTest(NULL); 98 TestingBrowserProcess::GetGlobal()->SetLocalState(NULL); 99 } 100 101 scoped_ptr<chromeos::CryptohomeLibrary> cryptohome_library_; 102 scoped_ptr<chromeos::CryptohomeClient> stub_cryptohome_client_; 103 EnterpriseInstallAttributes install_attributes_; 104 105 scoped_refptr<net::URLRequestContextGetter> request_context_getter_; 106 net::TestURLFetcherFactory url_fetcher_factory_; 107 int url_fetcher_response_code_; 108 string url_fetcher_response_string_; 109 TestingPrefServiceSimple local_state_; 110 MockDeviceManagementService device_management_service_; 111 chromeos::ScopedTestDeviceSettingsService test_device_settings_service_; 112 chromeos::ScopedTestCrosSettings test_cros_settings_; 113 114 DeviceCloudPolicyStoreChromeOS* store_; 115 DeviceCloudPolicyManagerChromeOS manager_; 116 117 private: 118 DISALLOW_COPY_AND_ASSIGN(DeviceCloudPolicyManagerChromeOSTest); 119 }; 120 121 TEST_F(DeviceCloudPolicyManagerChromeOSTest, FreshDevice) { 122 owner_key_util_->Clear(); 123 FlushDeviceSettings(); 124 EXPECT_TRUE(manager_.IsInitializationComplete(POLICY_DOMAIN_CHROME)); 125 126 manager_.Connect(&local_state_, 127 &device_management_service_, 128 scoped_ptr<CloudPolicyClient::StatusProvider>()); 129 130 PolicyBundle bundle; 131 EXPECT_TRUE(manager_.policies().Equals(bundle)); 132 } 133 134 TEST_F(DeviceCloudPolicyManagerChromeOSTest, EnrolledDevice) { 135 base::RunLoop loop; 136 EnterpriseInstallAttributes::LockResult result; 137 install_attributes_.LockDevice(PolicyBuilder::kFakeUsername, 138 DEVICE_MODE_ENTERPRISE, 139 PolicyBuilder::kFakeDeviceId, 140 base::Bind(&CopyLockResult, &loop, &result)); 141 loop.Run(); 142 ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS, result); 143 144 FlushDeviceSettings(); 145 EXPECT_EQ(CloudPolicyStore::STATUS_OK, store_->status()); 146 EXPECT_TRUE(manager_.IsInitializationComplete(POLICY_DOMAIN_CHROME)); 147 148 PolicyBundle bundle; 149 bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) 150 .Set(key::kDeviceMetricsReportingEnabled, 151 POLICY_LEVEL_MANDATORY, 152 POLICY_SCOPE_MACHINE, 153 Value::CreateBooleanValue(false), 154 NULL); 155 EXPECT_TRUE(manager_.policies().Equals(bundle)); 156 157 manager_.Connect(&local_state_, 158 &device_management_service_, 159 scoped_ptr<CloudPolicyClient::StatusProvider>()); 160 EXPECT_TRUE(manager_.policies().Equals(bundle)); 161 162 manager_.Shutdown(); 163 EXPECT_TRUE(manager_.policies().Equals(bundle)); 164 165 EXPECT_EQ(manager_.GetRobotAccountId(), 166 PolicyBuilder::kFakeServiceAccountIdentity); 167 } 168 169 TEST_F(DeviceCloudPolicyManagerChromeOSTest, ConsumerDevice) { 170 FlushDeviceSettings(); 171 EXPECT_EQ(CloudPolicyStore::STATUS_BAD_STATE, store_->status()); 172 EXPECT_TRUE(manager_.IsInitializationComplete(POLICY_DOMAIN_CHROME)); 173 174 PolicyBundle bundle; 175 EXPECT_TRUE(manager_.policies().Equals(bundle)); 176 177 manager_.Connect(&local_state_, 178 &device_management_service_, 179 scoped_ptr<CloudPolicyClient::StatusProvider>()); 180 EXPECT_TRUE(manager_.policies().Equals(bundle)); 181 182 manager_.Shutdown(); 183 EXPECT_TRUE(manager_.policies().Equals(bundle)); 184 } 185 186 class DeviceCloudPolicyManagerChromeOSEnrollmentTest 187 : public DeviceCloudPolicyManagerChromeOSTest { 188 public: 189 void Done(EnrollmentStatus status) { 190 status_ = status; 191 done_ = true; 192 } 193 194 protected: 195 DeviceCloudPolicyManagerChromeOSEnrollmentTest() 196 : is_auto_enrollment_(false), 197 register_status_(DM_STATUS_SUCCESS), 198 policy_fetch_status_(DM_STATUS_SUCCESS), 199 robot_auth_fetch_status_(DM_STATUS_SUCCESS), 200 store_result_(true), 201 status_(EnrollmentStatus::ForStatus(EnrollmentStatus::STATUS_SUCCESS)), 202 done_(false) {} 203 204 virtual void SetUp() OVERRIDE { 205 DeviceCloudPolicyManagerChromeOSTest::SetUp(); 206 207 // Set up test data. 208 device_policy_.SetDefaultNewSigningKey(); 209 device_policy_.policy_data().set_timestamp( 210 (base::Time::NowFromSystemTime() - 211 base::Time::UnixEpoch()).InMilliseconds()); 212 device_policy_.Build(); 213 214 register_response_.mutable_register_response()->set_device_management_token( 215 PolicyBuilder::kFakeToken); 216 policy_fetch_response_.mutable_policy_response()->add_response()->CopyFrom( 217 device_policy_.policy()); 218 robot_auth_fetch_response_.mutable_service_api_access_response() 219 ->set_auth_code("auth_code_for_test"); 220 loaded_blob_ = device_policy_.GetBlob(); 221 222 // Initialize the manager. 223 FlushDeviceSettings(); 224 EXPECT_EQ(CloudPolicyStore::STATUS_BAD_STATE, store_->status()); 225 EXPECT_TRUE(manager_.IsInitializationComplete(POLICY_DOMAIN_CHROME)); 226 227 PolicyBundle bundle; 228 EXPECT_TRUE(manager_.policies().Equals(bundle)); 229 230 manager_.Connect(&local_state_, 231 &device_management_service_, 232 scoped_ptr<CloudPolicyClient::StatusProvider>()); 233 } 234 235 void ExpectFailedEnrollment(EnrollmentStatus::Status status) { 236 EXPECT_EQ(status, status_.status()); 237 EXPECT_FALSE(store_->is_managed()); 238 PolicyBundle empty_bundle; 239 EXPECT_TRUE(manager_.policies().Equals(empty_bundle)); 240 } 241 242 void ExpectSuccessfulEnrollment() { 243 EXPECT_EQ(EnrollmentStatus::STATUS_SUCCESS, status_.status()); 244 EXPECT_EQ(DEVICE_MODE_ENTERPRISE, install_attributes_.GetMode()); 245 EXPECT_TRUE(store_->has_policy()); 246 EXPECT_TRUE(store_->is_managed()); 247 ASSERT_TRUE(manager_.core()->client()); 248 EXPECT_TRUE(manager_.core()->client()->is_registered()); 249 250 PolicyBundle bundle; 251 bundle.Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) 252 .Set(key::kDeviceMetricsReportingEnabled, 253 POLICY_LEVEL_MANDATORY, 254 POLICY_SCOPE_MACHINE, 255 Value::CreateBooleanValue(false), 256 NULL); 257 EXPECT_TRUE(manager_.policies().Equals(bundle)); 258 } 259 260 void RunTest() { 261 // Trigger enrollment. 262 MockDeviceManagementJob* register_job = NULL; 263 EXPECT_CALL(device_management_service_, 264 CreateJob(DeviceManagementRequestJob::TYPE_REGISTRATION)) 265 .Times(AtMost(1)) 266 .WillOnce(device_management_service_.CreateAsyncJob(®ister_job)); 267 EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _)) 268 .Times(AtMost(1)) 269 .WillOnce(DoAll(SaveArg<5>(&client_id_), 270 SaveArg<6>(®ister_request_))); 271 DeviceCloudPolicyManagerChromeOS::AllowedDeviceModes modes; 272 modes[DEVICE_MODE_ENTERPRISE] = true; 273 manager_.StartEnrollment( 274 "auth token", is_auto_enrollment_, modes, 275 base::Bind(&DeviceCloudPolicyManagerChromeOSEnrollmentTest::Done, 276 base::Unretained(this))); 277 Mock::VerifyAndClearExpectations(&device_management_service_); 278 279 if (done_) 280 return; 281 282 // Process registration. 283 ASSERT_TRUE(register_job); 284 MockDeviceManagementJob* policy_fetch_job = NULL; 285 EXPECT_CALL(device_management_service_, 286 CreateJob(DeviceManagementRequestJob::TYPE_POLICY_FETCH)) 287 .Times(AtMost(1)) 288 .WillOnce(device_management_service_.CreateAsyncJob(&policy_fetch_job)); 289 EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _)) 290 .Times(AtMost(1)); 291 register_job->SendResponse(register_status_, register_response_); 292 Mock::VerifyAndClearExpectations(&device_management_service_); 293 294 if (done_) 295 return; 296 297 // Process policy fetch. 298 ASSERT_TRUE(policy_fetch_job); 299 policy_fetch_job->SendResponse(policy_fetch_status_, 300 policy_fetch_response_); 301 302 if (done_) 303 return; 304 305 // Process verification. 306 MockDeviceManagementJob* robot_auth_fetch_job = NULL; 307 EXPECT_CALL(device_management_service_, 308 CreateJob(DeviceManagementRequestJob::TYPE_API_AUTH_CODE_FETCH)) 309 .Times(AtMost(1)) 310 .WillOnce(device_management_service_.CreateAsyncJob( 311 &robot_auth_fetch_job)); 312 EXPECT_CALL(device_management_service_, StartJob(_, _, _, _, _, _, _)) 313 .Times(AtMost(1)); 314 base::RunLoop().RunUntilIdle(); 315 Mock::VerifyAndClearExpectations(&device_management_service_); 316 317 if (done_) 318 return; 319 320 // Process robot auth token fetch. 321 ASSERT_TRUE(robot_auth_fetch_job); 322 robot_auth_fetch_job->SendResponse(robot_auth_fetch_status_, 323 robot_auth_fetch_response_); 324 Mock::VerifyAndClearExpectations(&device_management_service_); 325 326 if (done_) 327 return; 328 329 // Process robot refresh token fetch if the auth code fetch succeeded. 330 // DeviceCloudPolicyManagerChromeOS holds an EnrollmentHandlerChromeOS which 331 // holds a GaiaOAuthClient that fetches the refresh token during enrollment. 332 // We return a successful OAuth response via a TestURLFetcher to trigger the 333 // happy path for these classes so that enrollment can continue. 334 if (robot_auth_fetch_status_ == DM_STATUS_SUCCESS) { 335 net::TestURLFetcher* url_fetcher = url_fetcher_factory_.GetFetcherByID( 336 gaia::GaiaOAuthClient::kUrlFetcherId); 337 ASSERT_TRUE(url_fetcher); 338 url_fetcher->SetMaxRetriesOn5xx(0); 339 url_fetcher->set_status(net::URLRequestStatus()); 340 url_fetcher->set_response_code(url_fetcher_response_code_); 341 url_fetcher->SetResponseString(url_fetcher_response_string_); 342 url_fetcher->delegate()->OnURLFetchComplete(url_fetcher); 343 } 344 base::RunLoop().RunUntilIdle(); 345 346 // Process policy store. 347 device_settings_test_helper_.set_store_result(store_result_); 348 device_settings_test_helper_.FlushStore(); 349 EXPECT_EQ(device_policy_.GetBlob(), 350 device_settings_test_helper_.policy_blob()); 351 352 if (done_) 353 return; 354 355 // Key installation, policy load and refresh token save. 356 device_settings_test_helper_.set_policy_blob(loaded_blob_); 357 owner_key_util_->SetPublicKeyFromPrivateKey( 358 *device_policy_.GetNewSigningKey()); 359 ReloadDeviceSettings(); 360 361 if (done_) 362 return; 363 364 // Process robot refresh token store. 365 EXPECT_EQ( 366 "refreshToken4Test", 367 chromeos::DeviceOAuth2TokenServiceFactory::Get()->GetRefreshToken()); 368 } 369 370 bool is_auto_enrollment_; 371 372 DeviceManagementStatus register_status_; 373 em::DeviceManagementResponse register_response_; 374 375 DeviceManagementStatus policy_fetch_status_; 376 em::DeviceManagementResponse policy_fetch_response_; 377 378 DeviceManagementStatus robot_auth_fetch_status_; 379 em::DeviceManagementResponse robot_auth_fetch_response_; 380 381 bool store_result_; 382 std::string loaded_blob_; 383 384 em::DeviceManagementRequest register_request_; 385 std::string client_id_; 386 EnrollmentStatus status_; 387 388 bool done_; 389 390 private: 391 DISALLOW_COPY_AND_ASSIGN(DeviceCloudPolicyManagerChromeOSEnrollmentTest); 392 }; 393 394 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, Success) { 395 RunTest(); 396 ExpectSuccessfulEnrollment(); 397 } 398 399 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, AutoEnrollment) { 400 is_auto_enrollment_ = true; 401 RunTest(); 402 ExpectSuccessfulEnrollment(); 403 EXPECT_TRUE(register_request_.register_request().auto_enrolled()); 404 } 405 406 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, Reenrollment) { 407 base::RunLoop loop; 408 EnterpriseInstallAttributes::LockResult result; 409 install_attributes_.LockDevice(PolicyBuilder::kFakeUsername, 410 DEVICE_MODE_ENTERPRISE, 411 PolicyBuilder::kFakeDeviceId, 412 base::Bind(&CopyLockResult, &loop, &result)); 413 loop.Run(); 414 ASSERT_EQ(EnterpriseInstallAttributes::LOCK_SUCCESS, result); 415 416 RunTest(); 417 ExpectSuccessfulEnrollment(); 418 EXPECT_TRUE(register_request_.register_request().reregister()); 419 EXPECT_EQ(PolicyBuilder::kFakeDeviceId, client_id_); 420 } 421 422 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, RegistrationFailed) { 423 register_status_ = DM_STATUS_REQUEST_FAILED; 424 RunTest(); 425 ExpectFailedEnrollment(EnrollmentStatus::STATUS_REGISTRATION_FAILED); 426 EXPECT_EQ(DM_STATUS_REQUEST_FAILED, status_.client_status()); 427 } 428 429 // Policy server implementations are not required to support robot auth 430 // tokens, so the following 4 Robot* tests verify that enrollment succeeds 431 // even if the robot auth token fetch fails. 432 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, 433 RobotAuthCodeFetchFailed) { 434 robot_auth_fetch_status_ = DM_STATUS_REQUEST_FAILED; 435 RunTest(); 436 ExpectSuccessfulEnrollment(); 437 } 438 439 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, 440 RobotRefreshTokenFetchResponseCodeFailed) { 441 url_fetcher_response_code_ = 400; 442 RunTest(); 443 ExpectSuccessfulEnrollment(); 444 } 445 446 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, 447 RobotRefreshTokenFetchResponseStringFailed) { 448 url_fetcher_response_string_ = "invalid response json"; 449 RunTest(); 450 ExpectSuccessfulEnrollment(); 451 } 452 453 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, RobotRefreshSaveFailed) { 454 // Without a DeviceOAuth2TokenService, the refresh token can't be saved. 455 chromeos::DeviceOAuth2TokenServiceFactory::Shutdown(); 456 RunTest(); 457 ExpectSuccessfulEnrollment(); 458 } 459 460 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, PolicyFetchFailed) { 461 policy_fetch_status_ = DM_STATUS_REQUEST_FAILED; 462 RunTest(); 463 ExpectFailedEnrollment(EnrollmentStatus::STATUS_POLICY_FETCH_FAILED); 464 EXPECT_EQ(DM_STATUS_REQUEST_FAILED, status_.client_status()); 465 } 466 467 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, ValidationFailed) { 468 device_policy_.policy().set_policy_data_signature("bad"); 469 policy_fetch_response_.clear_policy_response(); 470 policy_fetch_response_.mutable_policy_response()->add_response()->CopyFrom( 471 device_policy_.policy()); 472 RunTest(); 473 ExpectFailedEnrollment(EnrollmentStatus::STATUS_VALIDATION_FAILED); 474 EXPECT_EQ(CloudPolicyValidatorBase::VALIDATION_BAD_INITIAL_SIGNATURE, 475 status_.validation_status()); 476 } 477 478 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, StoreError) { 479 store_result_ = false; 480 RunTest(); 481 ExpectFailedEnrollment(EnrollmentStatus::STATUS_STORE_ERROR); 482 EXPECT_EQ(CloudPolicyStore::STATUS_STORE_ERROR, 483 status_.store_status()); 484 } 485 486 TEST_F(DeviceCloudPolicyManagerChromeOSEnrollmentTest, LoadError) { 487 loaded_blob_.clear(); 488 RunTest(); 489 ExpectFailedEnrollment(EnrollmentStatus::STATUS_STORE_ERROR); 490 EXPECT_EQ(CloudPolicyStore::STATUS_LOAD_ERROR, 491 status_.store_status()); 492 } 493 494 } // namespace 495 } // namespace policy 496