OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <cert.h> | |
6 #include <pk11pub.h> | 5 #include <pk11pub.h> |
7 | 6 |
8 #include <map> | 7 #include <map> |
9 #include <string> | 8 #include <string> |
10 #include <vector> | 9 #include <vector> |
11 | 10 |
12 #include "base/at_exit.h" | 11 #include "base/at_exit.h" |
13 #include "base/callback.h" | 12 #include "base/callback.h" |
14 #include "base/file_util.h" | 13 #include "base/file_util.h" |
15 #include "base/files/scoped_temp_dir.h" | 14 #include "base/files/scoped_temp_dir.h" |
16 #include "base/json/json_reader.h" | 15 #include "base/json/json_reader.h" |
17 #include "base/lazy_instance.h" | 16 #include "base/lazy_instance.h" |
18 #include "base/path_service.h" | 17 #include "base/path_service.h" |
19 #include "chrome/browser/chromeos/cros/cros_library.h" | 18 #include "chrome/browser/chromeos/cros/cros_library.h" |
20 #include "chrome/browser/chromeos/cros/network_library.h" | 19 #include "chrome/browser/chromeos/cros/network_library.h" |
21 #include "chrome/browser/chromeos/cros/network_library_impl_stub.h" | 20 #include "chrome/browser/chromeos/cros/network_library_impl_stub.h" |
22 #include "chrome/browser/chromeos/login/mock_user_manager.h" | 21 #include "chrome/browser/chromeos/login/mock_user_manager.h" |
23 #include "chrome/browser/google_apis/test_util.h" | 22 #include "chrome/browser/google_apis/test_util.h" |
24 #include "chrome/common/chrome_paths.h" | 23 #include "chrome/common/chrome_paths.h" |
25 #include "chromeos/network/onc/onc_certificate_importer.h" | 24 #include "chromeos/network/onc/onc_certificate_importer.h" |
26 #include "chromeos/network/onc/onc_constants.h" | 25 #include "chromeos/network/onc/onc_constants.h" |
27 #include "chromeos/network/onc/onc_test_utils.h" | 26 #include "chromeos/network/onc/onc_test_utils.h" |
28 #include "chromeos/network/onc/onc_utils.h" | 27 #include "chromeos/network/onc/onc_utils.h" |
29 #include "crypto/nss_util.h" | 28 #include "crypto/nss_util.h" |
30 #include "net/base/crypto_module.h" | 29 #include "net/base/crypto_module.h" |
31 #include "net/cert/nss_cert_database.h" | |
32 #include "net/cert/x509_certificate.h" | |
33 #include "testing/gmock/include/gmock/gmock.h" | 30 #include "testing/gmock/include/gmock/gmock.h" |
34 #include "testing/gtest/include/gtest/gtest.h" | 31 #include "testing/gtest/include/gtest/gtest.h" |
35 | 32 |
36 using ::testing::AnyNumber; | 33 using ::testing::AnyNumber; |
37 using ::testing::Return; | 34 using ::testing::Return; |
38 | 35 |
39 namespace chromeos { | 36 namespace chromeos { |
40 | 37 |
41 namespace { | 38 namespace { |
42 | 39 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 // predefined values, e.g. ethernet_available(). However, many other functions | 132 // predefined values, e.g. ethernet_available(). However, many other functions |
136 // such as connected_network() return values which are set indirectly and thus | 133 // such as connected_network() return values which are set indirectly and thus |
137 // we can test the logic of those setters. | 134 // we can test the logic of those setters. |
138 | 135 |
139 class NetworkLibraryStubTest : public ::testing::Test { | 136 class NetworkLibraryStubTest : public ::testing::Test { |
140 public: | 137 public: |
141 NetworkLibraryStubTest() : cros_(NULL) {} | 138 NetworkLibraryStubTest() : cros_(NULL) {} |
142 | 139 |
143 protected: | 140 protected: |
144 virtual void SetUp() { | 141 virtual void SetUp() { |
145 ASSERT_TRUE(test_nssdb_.is_open()); | |
146 | |
147 slot_ = net::NSSCertDatabase::GetInstance()->GetPublicModule(); | |
148 cros_ = static_cast<NetworkLibraryImplStub*>( | 142 cros_ = static_cast<NetworkLibraryImplStub*>( |
149 CrosLibrary::Get()->GetNetworkLibrary()); | 143 CrosLibrary::Get()->GetNetworkLibrary()); |
150 ASSERT_TRUE(cros_) << "GetNetworkLibrary() Failed!"; | 144 ASSERT_TRUE(cros_) << "GetNetworkLibrary() Failed!"; |
151 | |
152 // Test db should be empty at start of test. | |
153 EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size()); | |
154 } | 145 } |
155 | 146 |
156 virtual void TearDown() { | 147 virtual void TearDown() { |
157 cros_ = NULL; | 148 cros_ = NULL; |
158 EXPECT_TRUE(CleanupSlotContents(slot_->os_module_handle())); | |
159 EXPECT_EQ(0U, ListCertsInSlot(slot_->os_module_handle()).size()); | |
160 } | 149 } |
161 | 150 |
162 // Load the ONC from |onc_file| using NetworkLibrary::LoadOncNetworks. Check | 151 // Load the ONC from |onc_file| using NetworkLibrary::LoadOncNetworks. Check |
163 // that return value matches |expect_successful_import| and the configuration | 152 // that return value matches |expect_successful_import| and the configuration |
164 // that would be sent to Shill matches |shill_json|. | 153 // that would be sent to Shill matches |shill_json|. |
165 void LoadOncAndVerifyNetworks(std::string onc_file, | 154 void LoadOncAndVerifyNetworks(std::string onc_file, |
166 std::string shill_json, | 155 std::string shill_json, |
167 onc::ONCSource source, | 156 onc::ONCSource source, |
168 bool expect_successful_import) { | 157 bool expect_successful_import) { |
169 ScopedMockUserManagerEnabler mock_user_manager; | 158 ScopedMockUserManagerEnabler mock_user_manager; |
170 mock_user_manager.user_manager()->SetActiveUser("madmax@my.domain.com"); | 159 mock_user_manager.user_manager()->SetActiveUser("madmax@my.domain.com"); |
171 EXPECT_CALL(*mock_user_manager.user_manager(), IsUserLoggedIn()) | 160 EXPECT_CALL(*mock_user_manager.user_manager(), IsUserLoggedIn()) |
172 .Times(AnyNumber()) | 161 .Times(AnyNumber()) |
173 .WillRepeatedly(Return(true)); | 162 .WillRepeatedly(Return(true)); |
174 | 163 |
175 std::string onc_blob = onc::test_utils::ReadTestData(onc_file); | 164 scoped_ptr<base::DictionaryValue> onc_blob = |
| 165 onc::test_utils::ReadTestDictionary(onc_file); |
| 166 base::ListValue* onc_network_configs; |
| 167 onc_blob->GetListWithoutPathExpansion( |
| 168 onc::toplevel_config::kNetworkConfigurations, |
| 169 &onc_network_configs); |
| 170 ASSERT_TRUE(onc_network_configs); |
176 | 171 |
177 scoped_ptr<base::Value> expected_value = | 172 scoped_ptr<base::Value> expected_value = |
178 google_apis::test_util::LoadJSONFile(shill_json); | 173 google_apis::test_util::LoadJSONFile(shill_json); |
179 base::DictionaryValue* expected_configs; | 174 base::DictionaryValue* expected_configs; |
180 expected_value->GetAsDictionary(&expected_configs); | 175 expected_value->GetAsDictionary(&expected_configs); |
181 | 176 |
182 net::CertificateList cert_list; | 177 cros_->LoadOncNetworks(*onc_network_configs, source); |
183 EXPECT_EQ(expect_successful_import, | |
184 cros_->LoadOncNetworks(onc_blob, "", source, &cert_list)); | |
185 | 178 |
186 const std::map<std::string, base::DictionaryValue*>& configs = | 179 const std::map<std::string, base::DictionaryValue*>& configs = |
187 cros_->GetConfigurations(); | 180 cros_->GetConfigurations(); |
188 | 181 |
189 EXPECT_EQ(expected_configs->size(), configs.size()); | 182 EXPECT_EQ(expected_configs->size(), configs.size()); |
190 | 183 |
191 for (base::DictionaryValue::Iterator it(*expected_configs); !it.IsAtEnd(); | 184 for (base::DictionaryValue::Iterator it(*expected_configs); !it.IsAtEnd(); |
192 it.Advance()) { | 185 it.Advance()) { |
193 const base::DictionaryValue* expected_config; | 186 const base::DictionaryValue* expected_config; |
194 it.value().GetAsDictionary(&expected_config); | 187 it.value().GetAsDictionary(&expected_config); |
195 | 188 |
196 std::map<std::string, base::DictionaryValue*>::const_iterator entry = | 189 std::map<std::string, base::DictionaryValue*>::const_iterator entry = |
197 configs.find(it.key()); | 190 configs.find(it.key()); |
198 EXPECT_NE(entry, configs.end()); | 191 EXPECT_NE(entry, configs.end()); |
199 base::DictionaryValue* actual_config = entry->second; | 192 base::DictionaryValue* actual_config = entry->second; |
200 EXPECT_TRUE(onc::test_utils::Equals(expected_config, actual_config)); | 193 EXPECT_TRUE(onc::test_utils::Equals(expected_config, actual_config)); |
201 } | 194 } |
202 } | 195 } |
203 | 196 |
204 ScopedStubCrosEnabler cros_stub_; | 197 ScopedStubCrosEnabler cros_stub_; |
205 NetworkLibraryImplStub* cros_; | 198 NetworkLibraryImplStub* cros_; |
206 protected: | 199 protected: |
207 net::CertificateList ListCertsInSlot(PK11SlotInfo* slot) { | |
208 net::CertificateList result; | |
209 CERTCertList* cert_list = PK11_ListCertsInSlot(slot); | |
210 for (CERTCertListNode* node = CERT_LIST_HEAD(cert_list); | |
211 !CERT_LIST_END(node, cert_list); | |
212 node = CERT_LIST_NEXT(node)) { | |
213 result.push_back(net::X509Certificate::CreateFromHandle( | |
214 node->cert, net::X509Certificate::OSCertHandles())); | |
215 } | |
216 CERT_DestroyCertList(cert_list); | |
217 | |
218 // Sort the result so that test comparisons can be deterministic. | |
219 std::sort(result.begin(), result.end(), net::X509Certificate::LessThan()); | |
220 return result; | |
221 } | |
222 | |
223 bool CleanupSlotContents(PK11SlotInfo* slot) { | |
224 bool ok = true; | |
225 net::CertificateList certs = ListCertsInSlot(slot); | |
226 for (size_t i = 0; i < certs.size(); ++i) { | |
227 if (!net::NSSCertDatabase::GetInstance()->DeleteCertAndKey(certs[i])) | |
228 ok = false; | |
229 } | |
230 return ok; | |
231 } | |
232 | |
233 scoped_refptr<net::CryptoModule> slot_; | 200 scoped_refptr<net::CryptoModule> slot_; |
234 crypto::ScopedTestNSSDB test_nssdb_; | 201 crypto::ScopedTestNSSDB test_nssdb_; |
235 }; | 202 }; |
236 | 203 |
237 // Default stub state: | 204 // Default stub state: |
238 // vpn1: disconnected, L2TP/IPsec + PSK | 205 // vpn1: disconnected, L2TP/IPsec + PSK |
239 // vpn2: disconnected, L2TP/IPsec + user cert | 206 // vpn2: disconnected, L2TP/IPsec + user cert |
240 // vpn3: disconnected, OpenVpn | 207 // vpn3: disconnected, OpenVpn |
241 // eth1: connected (active network) | 208 // eth1: connected (active network) |
242 // wifi1: connected | 209 // wifi1: connected |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 } | 286 } |
320 | 287 |
321 TEST_F(NetworkLibraryStubTest, NetworkConnectWifiWithCertPattern) { | 288 TEST_F(NetworkLibraryStubTest, NetworkConnectWifiWithCertPattern) { |
322 scoped_ptr<base::DictionaryValue> onc_root = | 289 scoped_ptr<base::DictionaryValue> onc_root = |
323 onc::test_utils::ReadTestDictionary("toplevel_wifi_eap_clientcert.onc"); | 290 onc::test_utils::ReadTestDictionary("toplevel_wifi_eap_clientcert.onc"); |
324 base::ListValue* certificates; | 291 base::ListValue* certificates; |
325 onc_root->GetListWithoutPathExpansion(onc::toplevel_config::kCertificates, | 292 onc_root->GetListWithoutPathExpansion(onc::toplevel_config::kCertificates, |
326 &certificates); | 293 &certificates); |
327 | 294 |
328 onc::CertificateImporter importer(true /* allow trust imports */); | 295 onc::CertificateImporter importer(true /* allow trust imports */); |
329 net::CertificateList cert_list; | |
330 ASSERT_EQ(onc::CertificateImporter::IMPORT_OK, | 296 ASSERT_EQ(onc::CertificateImporter::IMPORT_OK, |
331 importer.ParseAndStoreCertificates(*certificates, &cert_list)); | 297 importer.ParseAndStoreCertificates(*certificates, NULL)); |
332 | 298 |
333 WifiNetwork* wifi = cros_->FindWifiNetworkByPath("wifi_cert_pattern"); | 299 WifiNetwork* wifi = cros_->FindWifiNetworkByPath("wifi_cert_pattern"); |
334 | 300 |
335 StubEnrollmentDelegate* enrollment_delegate = new StubEnrollmentDelegate(); | 301 StubEnrollmentDelegate* enrollment_delegate = new StubEnrollmentDelegate(); |
336 wifi->SetEnrollmentDelegate(enrollment_delegate); | 302 wifi->SetEnrollmentDelegate(enrollment_delegate); |
337 EXPECT_FALSE(enrollment_delegate->did_enroll); | 303 EXPECT_FALSE(enrollment_delegate->did_enroll); |
338 EXPECT_FALSE(enrollment_delegate->correct_args); | 304 EXPECT_FALSE(enrollment_delegate->correct_args); |
339 | 305 |
340 ASSERT_NE(static_cast<const WifiNetwork*>(NULL), wifi); | 306 ASSERT_NE(static_cast<const WifiNetwork*>(NULL), wifi); |
341 EXPECT_FALSE(wifi->connected()); | 307 EXPECT_FALSE(wifi->connected()); |
342 EXPECT_TRUE(cros_->CanConnectToNetwork(wifi)); | 308 EXPECT_TRUE(cros_->CanConnectToNetwork(wifi)); |
343 EXPECT_FALSE(wifi->connected()); | 309 EXPECT_FALSE(wifi->connected()); |
344 wifi->AttemptConnection( | 310 wifi->AttemptConnection( |
345 base::Bind(&WifiNetworkConnectCallback, cros_, wifi)); | 311 base::Bind(&WifiNetworkConnectCallback, cros_, wifi)); |
346 EXPECT_TRUE(wifi->connected()); | 312 EXPECT_TRUE(wifi->connected()); |
347 EXPECT_TRUE(enrollment_delegate->did_enroll); | 313 EXPECT_TRUE(enrollment_delegate->did_enroll); |
348 EXPECT_TRUE(enrollment_delegate->correct_args); | 314 EXPECT_TRUE(enrollment_delegate->correct_args); |
349 } | 315 } |
350 | 316 |
351 TEST_F(NetworkLibraryStubTest, NetworkConnectVPNWithCertPattern) { | 317 TEST_F(NetworkLibraryStubTest, NetworkConnectVPNWithCertPattern) { |
352 scoped_ptr<base::DictionaryValue> onc_root = | 318 scoped_ptr<base::DictionaryValue> onc_root = |
353 onc::test_utils::ReadTestDictionary("toplevel_openvpn_clientcert.onc"); | 319 onc::test_utils::ReadTestDictionary("toplevel_openvpn_clientcert.onc"); |
354 base::ListValue* certificates; | 320 base::ListValue* certificates; |
355 onc_root->GetListWithoutPathExpansion(onc::toplevel_config::kCertificates, | 321 onc_root->GetListWithoutPathExpansion(onc::toplevel_config::kCertificates, |
356 &certificates); | 322 &certificates); |
357 | 323 |
358 onc::CertificateImporter importer(true /* allow trust imports */); | 324 onc::CertificateImporter importer(true /* allow trust imports */); |
359 net::CertificateList cert_list; | |
360 ASSERT_EQ(onc::CertificateImporter::IMPORT_OK, | 325 ASSERT_EQ(onc::CertificateImporter::IMPORT_OK, |
361 importer.ParseAndStoreCertificates(*certificates, &cert_list)); | 326 importer.ParseAndStoreCertificates(*certificates, NULL)); |
362 | 327 |
363 VirtualNetwork* vpn = cros_->FindVirtualNetworkByPath("vpn_cert_pattern"); | 328 VirtualNetwork* vpn = cros_->FindVirtualNetworkByPath("vpn_cert_pattern"); |
364 | 329 |
365 StubEnrollmentDelegate* enrollment_delegate = new StubEnrollmentDelegate(); | 330 StubEnrollmentDelegate* enrollment_delegate = new StubEnrollmentDelegate(); |
366 vpn->SetEnrollmentDelegate(enrollment_delegate); | 331 vpn->SetEnrollmentDelegate(enrollment_delegate); |
367 EXPECT_FALSE(enrollment_delegate->did_enroll); | 332 EXPECT_FALSE(enrollment_delegate->did_enroll); |
368 EXPECT_FALSE(enrollment_delegate->correct_args); | 333 EXPECT_FALSE(enrollment_delegate->correct_args); |
369 | 334 |
370 ASSERT_NE(static_cast<const VirtualNetwork*>(NULL), vpn); | 335 ASSERT_NE(static_cast<const VirtualNetwork*>(NULL), vpn); |
371 EXPECT_FALSE(vpn->connected()); | 336 EXPECT_FALSE(vpn->connected()); |
(...skipping 10 matching lines...) Expand all Loading... |
382 VirtualNetwork* vpn1 = cros_->FindVirtualNetworkByPath("vpn1"); | 347 VirtualNetwork* vpn1 = cros_->FindVirtualNetworkByPath("vpn1"); |
383 EXPECT_NE(static_cast<const VirtualNetwork*>(NULL), vpn1); | 348 EXPECT_NE(static_cast<const VirtualNetwork*>(NULL), vpn1); |
384 EXPECT_FALSE(vpn1->connected()); | 349 EXPECT_FALSE(vpn1->connected()); |
385 EXPECT_TRUE(cros_->CanConnectToNetwork(vpn1)); | 350 EXPECT_TRUE(cros_->CanConnectToNetwork(vpn1)); |
386 cros_->ConnectToVirtualNetwork(vpn1); | 351 cros_->ConnectToVirtualNetwork(vpn1); |
387 EXPECT_TRUE(vpn1->connected()); | 352 EXPECT_TRUE(vpn1->connected()); |
388 ASSERT_NE(static_cast<const VirtualNetwork*>(NULL), cros_->virtual_network()); | 353 ASSERT_NE(static_cast<const VirtualNetwork*>(NULL), cros_->virtual_network()); |
389 EXPECT_EQ("vpn1", cros_->virtual_network()->service_path()); | 354 EXPECT_EQ("vpn1", cros_->virtual_network()->service_path()); |
390 } | 355 } |
391 | 356 |
392 TEST_F(NetworkLibraryStubTest, LoadOncNetworksWithInvalidConfig) { | |
393 LoadOncAndVerifyNetworks( | |
394 "toplevel_partially_invalid.onc", | |
395 "chromeos/net/shill_for_toplevel_partially_invalid.json", | |
396 onc::ONC_SOURCE_USER_POLICY, | |
397 false /* expect import to fail */); | |
398 | |
399 EXPECT_EQ(ListCertsInSlot(slot_->os_module_handle()).size(), 1U); | |
400 } | |
401 | |
402 namespace { | 357 namespace { |
403 | 358 |
404 struct ImportParams { | 359 struct ImportParams { |
405 // |onc_file|: Filename of source ONC, relative to | 360 // |onc_file|: Filename of source ONC, relative to |
406 // chromeos/test/data/network. | 361 // chromeos/test/data/network. |
407 // |shill_file|: Filename of expected Shill config, relative to | 362 // |shill_file|: Filename of expected Shill config, relative to |
408 // chrome/test/data). | 363 // chrome/test/data). |
409 // |onc_source|: The source of the ONC. | 364 // |onc_source|: The source of the ONC. |
410 // |expect_import_result|: The expected return value of LoadOncNetworks. | 365 // |expect_import_result|: The expected return value of LoadOncNetworks. |
411 ImportParams(const std::string& onc_file, | 366 ImportParams(const std::string& onc_file, |
(...skipping 22 matching lines...) Expand all Loading... |
434 class LoadOncNetworksTest | 389 class LoadOncNetworksTest |
435 : public NetworkLibraryStubTest, | 390 : public NetworkLibraryStubTest, |
436 public ::testing::WithParamInterface<ImportParams> { | 391 public ::testing::WithParamInterface<ImportParams> { |
437 }; | 392 }; |
438 | 393 |
439 TEST_P(LoadOncNetworksTest, VerifyNetworksAndCertificates) { | 394 TEST_P(LoadOncNetworksTest, VerifyNetworksAndCertificates) { |
440 LoadOncAndVerifyNetworks(GetParam().onc_file, | 395 LoadOncAndVerifyNetworks(GetParam().onc_file, |
441 GetParam().shill_file, | 396 GetParam().shill_file, |
442 GetParam().onc_source, | 397 GetParam().onc_source, |
443 GetParam().expect_import_result); | 398 GetParam().expect_import_result); |
444 | |
445 scoped_ptr<base::DictionaryValue> onc_dict = | |
446 onc::test_utils::ReadTestDictionary(GetParam().onc_file); | |
447 base::ListValue* onc_certs; | |
448 onc_dict->GetListWithoutPathExpansion(onc::toplevel_config::kCertificates, | |
449 &onc_certs); | |
450 | |
451 EXPECT_EQ(onc_certs->GetSize(), | |
452 ListCertsInSlot(slot_->os_module_handle()).size()); | |
453 } | 399 } |
454 | 400 |
455 INSTANTIATE_TEST_CASE_P( | 401 INSTANTIATE_TEST_CASE_P( |
456 LoadOncNetworksTest, | 402 LoadOncNetworksTest, |
457 LoadOncNetworksTest, | 403 LoadOncNetworksTest, |
458 ::testing::Values( | 404 ::testing::Values( |
459 ImportParams("managed_toplevel1.onc", | 405 ImportParams("managed_toplevel1.onc", |
460 "chromeos/net/shill_for_managed_toplevel1.json", | 406 "chromeos/net/shill_for_managed_toplevel1.json", |
461 onc::ONC_SOURCE_USER_POLICY), | 407 onc::ONC_SOURCE_USER_POLICY), |
462 ImportParams("managed_toplevel2.onc", | 408 ImportParams("managed_toplevel2.onc", |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 | 446 |
501 // TODO(stevenjb): Test network profiles. | 447 // TODO(stevenjb): Test network profiles. |
502 | 448 |
503 // TODO(stevenjb): Test network devices. | 449 // TODO(stevenjb): Test network devices. |
504 | 450 |
505 // TODO(stevenjb): Test data plans. | 451 // TODO(stevenjb): Test data plans. |
506 | 452 |
507 // TODO(stevenjb): Test monitor network / device. | 453 // TODO(stevenjb): Test monitor network / device. |
508 | 454 |
509 } // namespace chromeos | 455 } // namespace chromeos |
OLD | NEW |