1 // Copyright 2013 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.
6 #include "base/bind_helpers.h"
7 #include "base/callback.h"
8 #include "base/files/file_path.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/run_loop.h"
11 #include "base/values.h"
12 #include "chrome/browser/chromeos/login/user.h"
13 #include "chrome/browser/chromeos/policy/device_network_configuration_updater.h"
14 #include "chrome/browser/chromeos/policy/user_network_configuration_updater.h"
15 #include "chrome/browser/chromeos/settings/cros_settings.h"
16 #include "chrome/browser/chromeos/settings/device_settings_service.h"
17 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
18 #include "chromeos/network/fake_network_device_handler.h"
19 #include "chromeos/network/mock_managed_network_configuration_handler.h"
20 #include "chromeos/network/onc/mock_certificate_importer.h"
21 #include "chromeos/network/onc/onc_test_utils.h"
22 #include "chromeos/network/onc/onc_utils.h"
23 #include "components/onc/onc_constants.h"
24 #include "components/policy/core/common/external_data_fetcher.h"
25 #include "components/policy/core/common/mock_configuration_policy_provider.h"
26 #include "components/policy/core/common/policy_map.h"
27 #include "components/policy/core/common/policy_service_impl.h"
28 #include "content/public/test/test_browser_thread_bundle.h"
29 #include "content/public/test/test_utils.h"
30 #include "net/base/test_data_directory.h"
31 #include "net/cert/x509_certificate.h"
32 #include "net/test/cert_test_util.h"
33 #include "policy/policy_constants.h"
34 #include "testing/gmock/include/gmock/gmock.h"
35 #include "testing/gtest/include/gtest/gtest.h"
37 using testing::AnyNumber
;
38 using testing::AtLeast
;
41 using testing::Return
;
42 using testing::StrictMock
;
49 const char kFakeUserEmail
[] = "fake email";
50 const char kFakeUsernameHash
[] = "fake hash";
52 class FakeUser
: public chromeos::User
{
54 FakeUser() : User(kFakeUserEmail
) {
55 set_display_email(kFakeUserEmail
);
56 set_username_hash(kFakeUsernameHash
);
58 virtual ~FakeUser() {}
61 virtual UserType
GetType() const OVERRIDE
{
62 return USER_TYPE_REGULAR
;
66 DISALLOW_COPY_AND_ASSIGN(FakeUser
);
69 class FakeWebTrustedCertsObserver
70 : public UserNetworkConfigurationUpdater::WebTrustedCertsObserver
{
72 virtual void OnTrustAnchorsChanged(
73 const net::CertificateList
& trust_anchors
) OVERRIDE
{
74 trust_anchors_
= trust_anchors
;
76 net::CertificateList trust_anchors_
;
79 class FakeNetworkDeviceHandler
: public chromeos::FakeNetworkDeviceHandler
{
81 FakeNetworkDeviceHandler() : allow_roaming_(false) {}
83 virtual void SetCellularAllowRoaming(bool allow_roaming
) OVERRIDE
{
84 allow_roaming_
= allow_roaming
;
90 const char kFakeONC
[] =
91 "{ \"NetworkConfigurations\": ["
92 " { \"GUID\": \"{485d6076-dd44-6b6d-69787465725f5040}\","
93 " \"Type\": \"WiFi\","
94 " \"Name\": \"My WiFi Network\","
96 " \"SSID\": \"ssid-none\","
97 " \"Security\": \"None\" }"
100 " \"GlobalNetworkConfiguration\": {"
101 " \"AllowOnlyPolicyNetworksToAutoconnect\": true,"
103 " \"Certificates\": ["
104 " { \"GUID\": \"{f998f760-272b-6939-4c2beffe428697ac}\","
105 " \"PKCS12\": \"abc\","
106 " \"Type\": \"Client\" }"
108 " \"Type\": \"UnencryptedConfiguration\""
111 std::string
ValueToString(const base::Value
& value
) {
112 std::stringstream str
;
117 void AppendAll(const base::ListValue
& from
, base::ListValue
* to
) {
118 for (base::ListValue::const_iterator it
= from
.begin(); it
!= from
.end();
120 to
->Append((*it
)->DeepCopy());
124 // Matcher to match base::Value.
127 std::string(negation
? "isn't" : "is") + " equal to " +
128 ValueToString(*value
)) {
129 return value
->Equals(&arg
);
132 MATCHER(IsEmpty
, std::string(negation
? "isn't" : "is") + " empty.") {
136 ACTION_P(SetCertificateList
, list
) {
144 class NetworkConfigurationUpdaterTest
: public testing::Test
{
146 NetworkConfigurationUpdaterTest() {
149 virtual void SetUp() OVERRIDE
{
150 EXPECT_CALL(provider_
, IsInitializationComplete(_
))
151 .WillRepeatedly(Return(true));
153 PolicyServiceImpl::Providers providers
;
154 providers
.push_back(&provider_
);
155 policy_service_
.reset(new PolicyServiceImpl(providers
));
157 scoped_ptr
<base::DictionaryValue
> fake_toplevel_onc
=
158 chromeos::onc::ReadDictionaryFromJson(kFakeONC
);
160 base::ListValue
* network_configs
= NULL
;
161 fake_toplevel_onc
->GetListWithoutPathExpansion(
162 onc::toplevel_config::kNetworkConfigurations
, &network_configs
);
163 AppendAll(*network_configs
, &fake_network_configs_
);
165 base::DictionaryValue
* global_config
= NULL
;
166 fake_toplevel_onc
->GetDictionaryWithoutPathExpansion(
167 onc::toplevel_config::kGlobalNetworkConfiguration
, &global_config
);
168 fake_global_network_config_
.MergeDictionary(global_config
);
170 base::ListValue
* certs
= NULL
;
171 fake_toplevel_onc
->GetListWithoutPathExpansion(
172 onc::toplevel_config::kCertificates
, &certs
);
173 AppendAll(*certs
, &fake_certificates_
);
175 certificate_importer_
=
176 new StrictMock
<chromeos::onc::MockCertificateImporter
>();
177 certificate_importer_owned_
.reset(certificate_importer_
);
180 virtual void TearDown() OVERRIDE
{
181 network_configuration_updater_
.reset();
182 provider_
.Shutdown();
183 base::RunLoop().RunUntilIdle();
186 void UpdateProviderPolicy(const PolicyMap
& policy
) {
187 provider_
.UpdateChromePolicy(policy
);
188 base::RunLoop().RunUntilIdle();
191 UserNetworkConfigurationUpdater
*
192 CreateNetworkConfigurationUpdaterForUserPolicy(
193 bool allow_trusted_certs_from_policy
) {
194 UserNetworkConfigurationUpdater
* updater
=
195 UserNetworkConfigurationUpdater::CreateForUserPolicy(
196 allow_trusted_certs_from_policy
,
198 certificate_importer_owned_
.Pass(),
199 policy_service_
.get(),
200 &network_config_handler_
).release();
201 network_configuration_updater_
.reset(updater
);
205 void CreateNetworkConfigurationUpdaterForDevicePolicy() {
206 network_configuration_updater_
=
207 DeviceNetworkConfigurationUpdater::CreateForDevicePolicy(
208 certificate_importer_owned_
.Pass(),
209 policy_service_
.get(),
210 &network_config_handler_
,
211 &network_device_handler_
,
212 chromeos::CrosSettings::Get());
215 base::ListValue fake_network_configs_
;
216 base::DictionaryValue fake_global_network_config_
;
217 base::ListValue fake_certificates_
;
218 StrictMock
<chromeos::MockManagedNetworkConfigurationHandler
>
219 network_config_handler_
;
220 FakeNetworkDeviceHandler network_device_handler_
;
222 // Not used directly. Required for CrosSettings.
223 chromeos::ScopedTestDeviceSettingsService scoped_device_settings_service_
;
224 chromeos::ScopedTestCrosSettings scoped_cros_settings_
;
226 // Ownership of certificate_importer_owned_ is passed to the
227 // NetworkConfigurationUpdater. When that happens, |certificate_importer_|
228 // continues to point to that instance but |certificate_importer_owned_| is
230 StrictMock
<chromeos::onc::MockCertificateImporter
>* certificate_importer_
;
231 scoped_ptr
<chromeos::onc::CertificateImporter
> certificate_importer_owned_
;
233 StrictMock
<MockConfigurationPolicyProvider
> provider_
;
234 scoped_ptr
<PolicyServiceImpl
> policy_service_
;
237 scoped_ptr
<NetworkConfigurationUpdater
> network_configuration_updater_
;
238 content::TestBrowserThreadBundle thread_bundle_
;
241 TEST_F(NetworkConfigurationUpdaterTest
, CellularAllowRoaming
) {
242 // Ignore networ config updates.
243 EXPECT_CALL(network_config_handler_
, SetPolicy(_
, _
, _
, _
)).Times(AtLeast(1));
244 EXPECT_CALL(*certificate_importer_
, ImportCertificates(_
, _
, _
))
247 // Setup the DataRoaming device setting.
248 chromeos::CrosSettings
* cros_settings
= chromeos::CrosSettings::Get();
249 chromeos::CrosSettingsProvider
* device_settings_provider
=
250 cros_settings
->GetProvider(chromeos::kSignedDataRoamingEnabled
);
251 cros_settings
->RemoveSettingsProvider(device_settings_provider
);
252 delete device_settings_provider
;
253 chromeos::StubCrosSettingsProvider
* stub_settings_provider
=
254 new chromeos::StubCrosSettingsProvider
;
255 cros_settings
->AddSettingsProvider(stub_settings_provider
);
257 chromeos::CrosSettings::Get()->Set(chromeos::kSignedDataRoamingEnabled
,
258 base::FundamentalValue(false));
259 EXPECT_FALSE(network_device_handler_
.allow_roaming_
);
261 CreateNetworkConfigurationUpdaterForDevicePolicy();
262 chromeos::CrosSettings::Get()->Set(chromeos::kSignedDataRoamingEnabled
,
263 base::FundamentalValue(true));
264 EXPECT_TRUE(network_device_handler_
.allow_roaming_
);
266 chromeos::CrosSettings::Get()->Set(chromeos::kSignedDataRoamingEnabled
,
267 base::FundamentalValue(false));
268 EXPECT_FALSE(network_device_handler_
.allow_roaming_
);
271 TEST_F(NetworkConfigurationUpdaterTest
, PolicyIsValidatedAndRepaired
) {
272 scoped_ptr
<base::DictionaryValue
> onc_repaired
=
273 chromeos::onc::test_utils::ReadTestDictionary(
274 "repaired_toplevel_partially_invalid.onc");
276 base::ListValue
* network_configs_repaired
= NULL
;
277 onc_repaired
->GetListWithoutPathExpansion(
278 onc::toplevel_config::kNetworkConfigurations
, &network_configs_repaired
);
279 ASSERT_TRUE(network_configs_repaired
);
281 base::DictionaryValue
* global_config_repaired
= NULL
;
282 onc_repaired
->GetDictionaryWithoutPathExpansion(
283 onc::toplevel_config::kGlobalNetworkConfiguration
,
284 &global_config_repaired
);
285 ASSERT_TRUE(global_config_repaired
);
287 std::string onc_policy
=
288 chromeos::onc::test_utils::ReadTestData("toplevel_partially_invalid.onc");
290 policy
.Set(key::kOpenNetworkConfiguration
,
291 POLICY_LEVEL_MANDATORY
,
293 new base::StringValue(onc_policy
),
295 UpdateProviderPolicy(policy
);
297 EXPECT_CALL(network_config_handler_
,
298 SetPolicy(onc::ONC_SOURCE_USER_POLICY
,
300 IsEqualTo(network_configs_repaired
),
301 IsEqualTo(global_config_repaired
)));
302 EXPECT_CALL(*certificate_importer_
,
303 ImportCertificates(_
, onc::ONC_SOURCE_USER_POLICY
, _
));
305 CreateNetworkConfigurationUpdaterForUserPolicy(
306 false /* do not allow trusted certs from policy */ );
309 TEST_F(NetworkConfigurationUpdaterTest
,
310 DoNotAllowTrustedCertificatesFromPolicy
) {
311 net::CertificateList cert_list
;
313 net::CreateCertificateListFromFile(net::GetTestCertsDirectory(),
315 net::X509Certificate::FORMAT_AUTO
);
316 ASSERT_EQ(1u, cert_list
.size());
318 EXPECT_CALL(network_config_handler_
,
319 SetPolicy(onc::ONC_SOURCE_USER_POLICY
, _
, _
, _
));
320 EXPECT_CALL(*certificate_importer_
, ImportCertificates(_
, _
, _
))
321 .WillRepeatedly(SetCertificateList(cert_list
));
323 UserNetworkConfigurationUpdater
* updater
=
324 CreateNetworkConfigurationUpdaterForUserPolicy(
325 false /* do not allow trusted certs from policy */);
327 // Certificates with the "Web" trust flag set should not be forwarded to
329 FakeWebTrustedCertsObserver observer
;
330 updater
->AddTrustedCertsObserver(&observer
);
332 base::RunLoop().RunUntilIdle();
334 net::CertificateList trust_anchors
;
335 updater
->GetWebTrustedCertificates(&trust_anchors
);
336 EXPECT_TRUE(trust_anchors
.empty());
338 EXPECT_TRUE(observer
.trust_anchors_
.empty());
339 updater
->RemoveTrustedCertsObserver(&observer
);
342 TEST_F(NetworkConfigurationUpdaterTest
,
343 AllowTrustedCertificatesFromPolicyInitially
) {
344 // Ignore network configuration changes.
345 EXPECT_CALL(network_config_handler_
, SetPolicy(_
, _
, _
, _
))
348 net::CertificateList cert_list
;
350 net::CreateCertificateListFromFile(net::GetTestCertsDirectory(),
352 net::X509Certificate::FORMAT_AUTO
);
353 ASSERT_EQ(1u, cert_list
.size());
355 EXPECT_CALL(*certificate_importer_
,
356 ImportCertificates(_
, onc::ONC_SOURCE_USER_POLICY
, _
))
357 .WillRepeatedly(SetCertificateList(cert_list
));
359 UserNetworkConfigurationUpdater
* updater
=
360 CreateNetworkConfigurationUpdaterForUserPolicy(
361 true /* allow trusted certs from policy */);
363 base::RunLoop().RunUntilIdle();
365 // Certificates with the "Web" trust flag set will be returned.
366 net::CertificateList trust_anchors
;
367 updater
->GetWebTrustedCertificates(&trust_anchors
);
368 EXPECT_EQ(1u, trust_anchors
.size());
371 TEST_F(NetworkConfigurationUpdaterTest
,
372 AllowTrustedCertificatesFromPolicyOnUpdate
) {
373 // Ignore network configuration changes.
374 EXPECT_CALL(network_config_handler_
, SetPolicy(_
, _
, _
, _
))
377 // Start with an empty certificate list.
378 EXPECT_CALL(*certificate_importer_
,
379 ImportCertificates(_
, onc::ONC_SOURCE_USER_POLICY
, _
))
380 .WillRepeatedly(SetCertificateList(net::CertificateList()));
382 UserNetworkConfigurationUpdater
* updater
=
383 CreateNetworkConfigurationUpdaterForUserPolicy(
384 true /* allow trusted certs from policy */);
386 FakeWebTrustedCertsObserver observer
;
387 updater
->AddTrustedCertsObserver(&observer
);
389 base::RunLoop().RunUntilIdle();
391 // Verify that the returned certificate list is empty.
392 Mock::VerifyAndClearExpectations(certificate_importer_
);
394 net::CertificateList trust_anchors
;
395 updater
->GetWebTrustedCertificates(&trust_anchors
);
396 EXPECT_TRUE(trust_anchors
.empty());
398 EXPECT_TRUE(observer
.trust_anchors_
.empty());
400 // Now use a non-empty certificate list to test the observer notification.
401 net::CertificateList cert_list
;
403 net::CreateCertificateListFromFile(net::GetTestCertsDirectory(),
405 net::X509Certificate::FORMAT_AUTO
);
406 ASSERT_EQ(1u, cert_list
.size());
408 EXPECT_CALL(*certificate_importer_
,
409 ImportCertificates(_
, onc::ONC_SOURCE_USER_POLICY
, _
))
410 .WillOnce(SetCertificateList(cert_list
));
412 // Change to any non-empty policy, so that updates are triggered. The actual
413 // content of the policy is irrelevant.
415 policy
.Set(key::kOpenNetworkConfiguration
,
416 POLICY_LEVEL_MANDATORY
,
418 new base::StringValue(kFakeONC
),
420 UpdateProviderPolicy(policy
);
421 base::RunLoop().RunUntilIdle();
423 // Certificates with the "Web" trust flag set will be returned and forwarded
426 net::CertificateList trust_anchors
;
427 updater
->GetWebTrustedCertificates(&trust_anchors
);
428 EXPECT_EQ(1u, trust_anchors
.size());
430 EXPECT_EQ(1u, observer
.trust_anchors_
.size());
432 updater
->RemoveTrustedCertsObserver(&observer
);
435 class NetworkConfigurationUpdaterTestWithParam
436 : public NetworkConfigurationUpdaterTest
,
437 public testing::WithParamInterface
<const char*> {
439 // Returns the currently tested ONC source.
440 onc::ONCSource
CurrentONCSource() {
441 if (GetParam() == key::kOpenNetworkConfiguration
)
442 return onc::ONC_SOURCE_USER_POLICY
;
443 DCHECK(GetParam() == key::kDeviceOpenNetworkConfiguration
);
444 return onc::ONC_SOURCE_DEVICE_POLICY
;
447 // Returns the expected username hash to push policies to
448 // ManagedNetworkConfigurationHandler.
449 std::string
ExpectedUsernameHash() {
450 if (GetParam() == key::kOpenNetworkConfiguration
)
451 return kFakeUsernameHash
;
452 return std::string();
455 void CreateNetworkConfigurationUpdater() {
456 if (GetParam() == key::kOpenNetworkConfiguration
) {
457 CreateNetworkConfigurationUpdaterForUserPolicy(
458 false /* do not allow trusted certs from policy */);
460 CreateNetworkConfigurationUpdaterForDevicePolicy();
465 TEST_P(NetworkConfigurationUpdaterTestWithParam
, InitialUpdates
) {
467 policy
.Set(GetParam(), POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_USER
,
468 new base::StringValue(kFakeONC
), NULL
);
469 UpdateProviderPolicy(policy
);
471 EXPECT_CALL(network_config_handler_
,
472 SetPolicy(CurrentONCSource(),
473 ExpectedUsernameHash(),
474 IsEqualTo(&fake_network_configs_
),
475 IsEqualTo(&fake_global_network_config_
)));
476 EXPECT_CALL(*certificate_importer_
,
478 IsEqualTo(&fake_certificates_
), CurrentONCSource(), _
));
480 CreateNetworkConfigurationUpdater();
484 TEST_P(NetworkConfigurationUpdaterTestWithParam
, PolicyChange
) {
485 // Ignore the initial updates.
486 EXPECT_CALL(network_config_handler_
, SetPolicy(_
, _
, _
, _
)).Times(AtLeast(1));
487 EXPECT_CALL(*certificate_importer_
, ImportCertificates(_
, _
, _
))
489 CreateNetworkConfigurationUpdater();
490 Mock::VerifyAndClearExpectations(&network_config_handler_
);
491 Mock::VerifyAndClearExpectations(certificate_importer_
);
493 // The Updater should update if policy changes.
494 EXPECT_CALL(network_config_handler_
,
495 SetPolicy(CurrentONCSource(),
497 IsEqualTo(&fake_network_configs_
),
498 IsEqualTo(&fake_global_network_config_
)));
499 EXPECT_CALL(*certificate_importer_
,
501 IsEqualTo(&fake_certificates_
), CurrentONCSource(), _
));
504 policy
.Set(GetParam(), POLICY_LEVEL_MANDATORY
, POLICY_SCOPE_USER
,
505 new base::StringValue(kFakeONC
), NULL
);
506 UpdateProviderPolicy(policy
);
507 Mock::VerifyAndClearExpectations(&network_config_handler_
);
508 Mock::VerifyAndClearExpectations(certificate_importer_
);
510 // Another update is expected if the policy goes away.
511 EXPECT_CALL(network_config_handler_
,
512 SetPolicy(CurrentONCSource(), _
, IsEmpty(), IsEmpty()));
513 EXPECT_CALL(*certificate_importer_
,
514 ImportCertificates(IsEmpty(), CurrentONCSource(), _
));
516 policy
.Erase(GetParam());
517 UpdateProviderPolicy(policy
);
520 INSTANTIATE_TEST_CASE_P(NetworkConfigurationUpdaterTestWithParamInstance
,
521 NetworkConfigurationUpdaterTestWithParam
,
522 testing::Values(key::kDeviceOpenNetworkConfiguration
,
523 key::kOpenNetworkConfiguration
));
525 } // namespace policy