Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(437)

Side by Side Diff: chrome/browser/chromeos/cros/network_library_impl_base.cc

Issue 23618026: NOT FOR SUBMIT: Remove NetworkLibrary (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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/cros/network_library_impl_base.h"
6
7 #include "base/bind.h"
8 #include "base/json/json_writer.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/stl_util.h"
11 #include "base/strings/string_util.h"
12 #include "chrome/browser/chromeos/cros/network_constants.h"
13 #include "chrome/browser/chromeos/login/user_manager.h"
14 #include "chrome/browser/chromeos/net/onc_utils.h"
15 #include "chromeos/network/network_state_handler.h"
16 #include "chromeos/network/network_ui_data.h"
17 #include "chromeos/network/onc/onc_constants.h"
18 #include "chromeos/network/onc/onc_normalizer.h"
19 #include "chromeos/network/onc/onc_signature.h"
20 #include "chromeos/network/onc/onc_translator.h"
21 #include "chromeos/network/onc/onc_utils.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "crypto/nss_util.h" // crypto::GetTPMTokenInfo() for 802.1X and VPN.
24 #include "third_party/cros_system_api/dbus/service_constants.h"
25
26 using content::BrowserThread;
27
28 namespace chromeos {
29
30 namespace {
31
32 // Only send network change notifications to observers once every 50ms.
33 const int kNetworkNotifyDelayMs = 50;
34
35 // How long we should remember that cellular plan payment was received.
36 const int kRecentPlanPaymentHours = 6;
37
38 NetworkProfileType GetProfileTypeForSource(onc::ONCSource source) {
39 switch (source) {
40 case onc::ONC_SOURCE_DEVICE_POLICY:
41 return PROFILE_SHARED;
42 case onc::ONC_SOURCE_USER_POLICY:
43 return PROFILE_USER;
44 case onc::ONC_SOURCE_NONE:
45 case onc::ONC_SOURCE_USER_IMPORT:
46 return PROFILE_NONE;
47 }
48 NOTREACHED() << "Unknown ONC source " << source;
49 return PROFILE_NONE;
50 }
51
52 } // namespace
53
54 NetworkLibraryImplBase::NetworkLibraryImplBase()
55 : ethernet_(NULL),
56 active_wifi_(NULL),
57 active_cellular_(NULL),
58 active_wimax_(NULL),
59 active_virtual_(NULL),
60 available_devices_(0),
61 uninitialized_devices_(0),
62 enabled_devices_(0),
63 busy_devices_(0),
64 wifi_scanning_(false),
65 is_locked_(false),
66 sim_operation_(SIM_OPERATION_NONE),
67 notify_manager_weak_factory_(this) {
68 }
69
70 NetworkLibraryImplBase::~NetworkLibraryImplBase() {
71 network_profile_observers_.Clear();
72 network_manager_observers_.Clear();
73 pin_operation_observers_.Clear();
74 STLDeleteValues(&network_map_);
75 ClearNetworks();
76 DeleteRememberedNetworks();
77 STLDeleteValues(&device_map_);
78 STLDeleteValues(&network_device_observers_);
79 STLDeleteValues(&network_observers_);
80 STLDeleteValues(&network_onc_map_);
81 }
82
83 //////////////////////////////////////////////////////////////////////////////
84 // NetworkLibrary implementation.
85
86 void NetworkLibraryImplBase::AddNetworkProfileObserver(
87 NetworkProfileObserver* observer) {
88 network_profile_observers_.AddObserver(observer);
89 }
90
91 void NetworkLibraryImplBase::RemoveNetworkProfileObserver(
92 NetworkProfileObserver* observer) {
93 network_profile_observers_.RemoveObserver(observer);
94 }
95
96 void NetworkLibraryImplBase::AddNetworkManagerObserver(
97 NetworkManagerObserver* observer) {
98 if (!network_manager_observers_.HasObserver(observer))
99 network_manager_observers_.AddObserver(observer);
100 }
101
102 void NetworkLibraryImplBase::RemoveNetworkManagerObserver(
103 NetworkManagerObserver* observer) {
104 network_manager_observers_.RemoveObserver(observer);
105 }
106
107 void NetworkLibraryImplBase::AddNetworkObserver(
108 const std::string& service_path, NetworkObserver* observer) {
109 // First, add the observer to the callback map.
110 NetworkObserverMap::iterator iter = network_observers_.find(service_path);
111 NetworkObserverList* oblist;
112 if (iter != network_observers_.end()) {
113 oblist = iter->second;
114 } else {
115 oblist = new NetworkObserverList();
116 network_observers_[service_path] = oblist;
117 }
118 if (observer && !oblist->HasObserver(observer))
119 oblist->AddObserver(observer);
120 MonitorNetworkStart(service_path);
121 }
122
123 void NetworkLibraryImplBase::RemoveNetworkObserver(
124 const std::string& service_path, NetworkObserver* observer) {
125 DCHECK(service_path.size());
126 NetworkObserverMap::iterator map_iter =
127 network_observers_.find(service_path);
128 if (map_iter != network_observers_.end()) {
129 map_iter->second->RemoveObserver(observer);
130 if (!map_iter->second->might_have_observers()) {
131 MonitorNetworkStop(service_path);
132 delete map_iter->second;
133 network_observers_.erase(map_iter);
134 }
135 }
136 }
137
138 void NetworkLibraryImplBase::RemoveObserverForAllNetworks(
139 NetworkObserver* observer) {
140 DCHECK(observer);
141 NetworkObserverMap::iterator map_iter = network_observers_.begin();
142 while (map_iter != network_observers_.end()) {
143 map_iter->second->RemoveObserver(observer);
144 if (!map_iter->second->might_have_observers()) {
145 MonitorNetworkStop(map_iter->first);
146 delete map_iter->second;
147 network_observers_.erase(map_iter++);
148 } else {
149 ++map_iter;
150 }
151 }
152 }
153
154 void NetworkLibraryImplBase::AddNetworkDeviceObserver(
155 const std::string& device_path, NetworkDeviceObserver* observer) {
156 // First, add the observer to the callback map.
157 NetworkDeviceObserverMap::iterator iter =
158 network_device_observers_.find(device_path);
159 NetworkDeviceObserverList* oblist;
160 if (iter != network_device_observers_.end()) {
161 oblist = iter->second;
162 } else {
163 oblist = new NetworkDeviceObserverList();
164 network_device_observers_[device_path] = oblist;
165 }
166 if (!oblist->HasObserver(observer))
167 oblist->AddObserver(observer);
168 MonitorNetworkDeviceStart(device_path);
169 }
170
171 void NetworkLibraryImplBase::RemoveNetworkDeviceObserver(
172 const std::string& device_path, NetworkDeviceObserver* observer) {
173 DCHECK(device_path.size());
174 NetworkDeviceObserverMap::iterator map_iter =
175 network_device_observers_.find(device_path);
176 if (map_iter != network_device_observers_.end()) {
177 map_iter->second->RemoveObserver(observer);
178 }
179 }
180
181 void NetworkLibraryImplBase::DeleteDeviceFromDeviceObserversMap(
182 const std::string& device_path) {
183 // Delete all device observers associated with this device.
184 NetworkDeviceObserverMap::iterator map_iter =
185 network_device_observers_.find(device_path);
186 if (map_iter != network_device_observers_.end()) {
187 delete map_iter->second;
188 network_device_observers_.erase(map_iter);
189 }
190 }
191
192 //////////////////////////////////////////////////////////////////////////////
193
194 void NetworkLibraryImplBase::AddPinOperationObserver(
195 PinOperationObserver* observer) {
196 if (!pin_operation_observers_.HasObserver(observer))
197 pin_operation_observers_.AddObserver(observer);
198 }
199
200 void NetworkLibraryImplBase::RemovePinOperationObserver(
201 PinOperationObserver* observer) {
202 pin_operation_observers_.RemoveObserver(observer);
203 }
204
205 const EthernetNetwork* NetworkLibraryImplBase::ethernet_network() const {
206 return ethernet_;
207 }
208
209 bool NetworkLibraryImplBase::ethernet_connecting() const {
210 return ethernet_ ? ethernet_->connecting() : false;
211 }
212 bool NetworkLibraryImplBase::ethernet_connected() const {
213 return ethernet_ ? ethernet_->connected() : false;
214 }
215 const WifiNetwork* NetworkLibraryImplBase::wifi_network() const {
216 return active_wifi_;
217 }
218 bool NetworkLibraryImplBase::wifi_connecting() const {
219 return active_wifi_ ? active_wifi_->connecting() : false;
220 }
221 bool NetworkLibraryImplBase::wifi_connected() const {
222 return active_wifi_ ? active_wifi_->connected() : false;
223 }
224 const CellularNetwork* NetworkLibraryImplBase::cellular_network() const {
225 return active_cellular_;
226 }
227 bool NetworkLibraryImplBase::cellular_connecting() const {
228 return active_cellular_ ? active_cellular_->connecting() : false;
229 }
230 bool NetworkLibraryImplBase::cellular_connected() const {
231 return active_cellular_ ? active_cellular_->connected() : false;
232 }
233 const WimaxNetwork* NetworkLibraryImplBase::wimax_network() const {
234 return active_wimax_;
235 }
236 bool NetworkLibraryImplBase::wimax_connecting() const {
237 return active_wimax_ ? active_wimax_->connecting() : false;
238 }
239 bool NetworkLibraryImplBase::wimax_connected() const {
240 return active_wimax_ ? active_wimax_->connected() : false;
241 }
242 const VirtualNetwork* NetworkLibraryImplBase::virtual_network() const {
243 return active_virtual_;
244 }
245 bool NetworkLibraryImplBase::virtual_network_connecting() const {
246 return active_virtual_ ? active_virtual_->connecting() : false;
247 }
248 bool NetworkLibraryImplBase::virtual_network_connected() const {
249 return active_virtual_ ? active_virtual_->connected() : false;
250 }
251 bool NetworkLibraryImplBase::Connected() const {
252 return ethernet_connected() || wifi_connected() ||
253 cellular_connected() || wimax_connected();
254 }
255 bool NetworkLibraryImplBase::Connecting() const {
256 return ethernet_connecting() || wifi_connecting() ||
257 cellular_connecting() || wimax_connecting();
258 }
259 const WifiNetworkVector& NetworkLibraryImplBase::wifi_networks() const {
260 return wifi_networks_;
261 }
262 const WifiNetworkVector&
263 NetworkLibraryImplBase::remembered_wifi_networks() const {
264 return remembered_wifi_networks_;
265 }
266 const CellularNetworkVector& NetworkLibraryImplBase::cellular_networks() const {
267 return cellular_networks_;
268 }
269 const WimaxNetworkVector& NetworkLibraryImplBase::wimax_networks() const {
270 return wimax_networks_;
271 }
272 const VirtualNetworkVector& NetworkLibraryImplBase::virtual_networks() const {
273 return virtual_networks_;
274 }
275 const VirtualNetworkVector&
276 NetworkLibraryImplBase::remembered_virtual_networks() const {
277 return remembered_virtual_networks_;
278 }
279
280 namespace {
281
282 // Use shill's ordering of the services to determine which type of
283 // network to return (i.e. don't assume priority of network types).
284 // Note: This does not include any virtual networks.
285 const Network* highest_priority(const Network* a, const Network*b) {
286 if (!a)
287 return b;
288 if (!b)
289 return a;
290 if (b->priority_order() < a->priority_order())
291 return b;
292 return a;
293 }
294
295 } // namespace
296
297 const Network* NetworkLibraryImplBase::active_network() const {
298 const Network* result = active_nonvirtual_network();
299 if (active_virtual_ && active_virtual_->is_active())
300 result = highest_priority(result, active_virtual_);
301 return result;
302 }
303
304 const Network* NetworkLibraryImplBase::active_nonvirtual_network() const {
305 const Network* result = NULL;
306 if (ethernet_ && ethernet_->is_active())
307 result = ethernet_;
308 if (active_wifi_ && active_wifi_->is_active())
309 result = highest_priority(result, active_wifi_);
310 if (active_cellular_ && active_cellular_->is_active())
311 result = highest_priority(result, active_cellular_);
312 if (active_wimax_ && active_wimax_->is_active())
313 result = highest_priority(result, active_wimax_);
314 return result;
315 }
316
317 const Network* NetworkLibraryImplBase::connected_network() const {
318 const Network* result = NULL;
319 if (ethernet_ && ethernet_->connected())
320 result = ethernet_;
321 if (active_wifi_ && active_wifi_->connected())
322 result = highest_priority(result, active_wifi_);
323 if (active_cellular_ && active_cellular_->connected())
324 result = highest_priority(result, active_cellular_);
325 if (active_wimax_ && active_wimax_->connected())
326 result = highest_priority(result, active_wimax_);
327 return result;
328 }
329
330 // Connecting order in logical preference.
331 const Network* NetworkLibraryImplBase::connecting_network() const {
332 if (ethernet_connecting())
333 return ethernet_network();
334 else if (wifi_connecting())
335 return wifi_network();
336 else if (cellular_connecting())
337 return cellular_network();
338 else if (wimax_connecting())
339 return wimax_network();
340 return NULL;
341 }
342
343 bool NetworkLibraryImplBase::ethernet_available() const {
344 return available_devices_ & (1 << TYPE_ETHERNET);
345 }
346
347 bool NetworkLibraryImplBase::wifi_available() const {
348 return available_devices_ & (1 << TYPE_WIFI);
349 }
350
351 bool NetworkLibraryImplBase::wimax_available() const {
352 return available_devices_ & (1 << TYPE_WIMAX);
353 }
354
355 bool NetworkLibraryImplBase::cellular_available() const {
356 return available_devices_ & (1 << TYPE_CELLULAR);
357 }
358
359 bool NetworkLibraryImplBase::ethernet_enabled() const {
360 return enabled_devices_ & (1 << TYPE_ETHERNET);
361 }
362
363 bool NetworkLibraryImplBase::wifi_enabled() const {
364 return enabled_devices_ & (1 << TYPE_WIFI);
365 }
366
367 bool NetworkLibraryImplBase::wimax_enabled() const {
368 return enabled_devices_ & (1 << TYPE_WIMAX);
369 }
370
371 bool NetworkLibraryImplBase::cellular_enabled() const {
372 return enabled_devices_ & (1 << TYPE_CELLULAR);
373 }
374
375 bool NetworkLibraryImplBase::wifi_scanning() const {
376 return wifi_scanning_;
377 }
378
379 bool NetworkLibraryImplBase::cellular_initializing() const {
380 if (uninitialized_devices_ & (1 << TYPE_CELLULAR))
381 return true;
382 const NetworkDevice* device = FindDeviceByType(TYPE_CELLULAR);
383 if (device && device->scanning())
384 return true;
385 return false;
386 }
387
388 /////////////////////////////////////////////////////////////////////////////
389
390 const NetworkDevice* NetworkLibraryImplBase::FindNetworkDeviceByPath(
391 const std::string& path) const {
392 NetworkDeviceMap::const_iterator iter = device_map_.find(path);
393 if (iter != device_map_.end())
394 return iter->second;
395 LOG(WARNING) << "Device path not found: " << path;
396 return NULL;
397 }
398
399 NetworkDevice* NetworkLibraryImplBase::FindNetworkDeviceByPath(
400 const std::string& path) {
401 NetworkDeviceMap::iterator iter = device_map_.find(path);
402 if (iter != device_map_.end())
403 return iter->second;
404 LOG(WARNING) << "Device path not found: " << path;
405 return NULL;
406 }
407
408 const NetworkDevice* NetworkLibraryImplBase::FindCellularDevice() const {
409 return FindDeviceByType(TYPE_CELLULAR);
410 }
411
412 const NetworkDevice* NetworkLibraryImplBase::FindMobileDevice() const {
413 const NetworkDevice* device = FindDeviceByType(TYPE_CELLULAR);
414 if (device)
415 return device;
416
417 return FindDeviceByType(TYPE_WIMAX);
418 }
419
420 Network* NetworkLibraryImplBase::FindNetworkByPath(
421 const std::string& path) const {
422 NetworkMap::const_iterator iter = network_map_.find(path);
423 if (iter != network_map_.end())
424 return iter->second;
425 return NULL;
426 }
427
428 Network* NetworkLibraryImplBase::FindNetworkByUniqueId(
429 const std::string& unique_id) const {
430 NetworkMap::const_iterator found = network_unique_id_map_.find(unique_id);
431 if (found != network_unique_id_map_.end())
432 return found->second;
433 return NULL;
434 }
435
436 WirelessNetwork* NetworkLibraryImplBase::FindWirelessNetworkByPath(
437 const std::string& path) const {
438 Network* network = FindNetworkByPath(path);
439 if (network &&
440 (network->type() == TYPE_WIFI || network->type() == TYPE_WIMAX ||
441 network->type() == TYPE_CELLULAR))
442 return static_cast<WirelessNetwork*>(network);
443 return NULL;
444 }
445
446 WifiNetwork* NetworkLibraryImplBase::FindWifiNetworkByPath(
447 const std::string& path) const {
448 Network* network = FindNetworkByPath(path);
449 if (network && network->type() == TYPE_WIFI)
450 return static_cast<WifiNetwork*>(network);
451 return NULL;
452 }
453
454 WimaxNetwork* NetworkLibraryImplBase::FindWimaxNetworkByPath(
455 const std::string& path) const {
456 Network* network = FindNetworkByPath(path);
457 if (network && (network->type() == TYPE_WIMAX))
458 return static_cast<WimaxNetwork*>(network);
459 return NULL;
460 }
461
462 CellularNetwork* NetworkLibraryImplBase::FindCellularNetworkByPath(
463 const std::string& path) const {
464 Network* network = FindNetworkByPath(path);
465 if (network && network->type() == TYPE_CELLULAR)
466 return static_cast<CellularNetwork*>(network);
467 return NULL;
468 }
469
470 VirtualNetwork* NetworkLibraryImplBase::FindVirtualNetworkByPath(
471 const std::string& path) const {
472 Network* network = FindNetworkByPath(path);
473 if (network && network->type() == TYPE_VPN)
474 return static_cast<VirtualNetwork*>(network);
475 return NULL;
476 }
477
478 Network* NetworkLibraryImplBase::FindRememberedFromNetwork(
479 const Network* network) const {
480 for (NetworkMap::const_iterator iter = remembered_network_map_.begin();
481 iter != remembered_network_map_.end(); ++iter) {
482 if (iter->second->unique_id() == network->unique_id())
483 return iter->second;
484 }
485 return NULL;
486 }
487
488 Network* NetworkLibraryImplBase::FindRememberedNetworkByPath(
489 const std::string& path) const {
490 NetworkMap::const_iterator iter = remembered_network_map_.find(path);
491 if (iter != remembered_network_map_.end())
492 return iter->second;
493 return NULL;
494 }
495
496 const base::DictionaryValue* NetworkLibraryImplBase::FindOncForNetwork(
497 const std::string& unique_id) const {
498 NetworkOncMap::const_iterator iter = network_onc_map_.find(unique_id);
499 return iter != network_onc_map_.end() ? iter->second : NULL;
500 }
501
502 void NetworkLibraryImplBase::SignalCellularPlanPayment() {
503 DCHECK(!HasRecentCellularPlanPayment());
504 cellular_plan_payment_time_ = base::Time::Now();
505 }
506
507 bool NetworkLibraryImplBase::HasRecentCellularPlanPayment() {
508 return (base::Time::Now() -
509 cellular_plan_payment_time_).InHours() < kRecentPlanPaymentHours;
510 }
511
512 const std::string& NetworkLibraryImplBase::GetCellularHomeCarrierId() const {
513 const NetworkDevice* cellular = FindCellularDevice();
514 if (cellular)
515 return cellular->home_provider_id();
516 return EmptyString();
517 }
518
519 bool NetworkLibraryImplBase::CellularDeviceUsesDirectActivation() const {
520 const NetworkDevice* cellular = FindCellularDevice();
521 return cellular && (cellular->carrier() == shill::kCarrierSprint);
522 }
523
524 /////////////////////////////////////////////////////////////////////////////
525 // Profiles.
526
527 bool NetworkLibraryImplBase::HasProfileType(NetworkProfileType type) const {
528 for (NetworkProfileList::const_iterator iter = profile_list_.begin();
529 iter != profile_list_.end(); ++iter) {
530 if ((*iter).type == type)
531 return true;
532 }
533 return false;
534 }
535
536 NetworkLibraryImplBase::NetworkProfile::NetworkProfile(const std::string& p,
537 NetworkProfileType t)
538 : path(p),
539 type(t) {
540 }
541
542 NetworkLibraryImplBase::NetworkProfile::~NetworkProfile() {}
543
544 NetworkLibraryImplBase::ConnectData::ConnectData()
545 : security(SECURITY_NONE),
546 eap_method(EAP_METHOD_UNKNOWN),
547 eap_auth(EAP_PHASE_2_AUTH_AUTO),
548 eap_use_system_cas(false),
549 save_credentials(false),
550 profile_type(PROFILE_NONE) {
551 }
552
553 NetworkLibraryImplBase::ConnectData::~ConnectData() {}
554
555 const NetworkDevice* NetworkLibraryImplBase::FindDeviceByType(
556 ConnectionType type) const {
557 for (NetworkDeviceMap::const_iterator iter = device_map_.begin();
558 iter != device_map_.end(); ++iter) {
559 if (iter->second && iter->second->type() == type)
560 return iter->second;
561 }
562 return NULL;
563 }
564
565 /////////////////////////////////////////////////////////////////////////////
566 // Connect to an existing network.
567
568 bool NetworkLibraryImplBase::CanConnectToNetwork(const Network* network) const {
569 if (!HasProfileType(PROFILE_USER) && network->RequiresUserProfile())
570 return false;
571 return true;
572 }
573
574 // 1. Request a connection to an existing wifi network.
575 // Use |shared| to pass along the desired profile type.
576 void NetworkLibraryImplBase::ConnectToWifiNetwork(
577 WifiNetwork* wifi, bool shared) {
578 NetworkConnectStartWifi(wifi, shared ? PROFILE_SHARED : PROFILE_USER);
579 }
580
581 // 1. Request a connection to an existing wifi network.
582 void NetworkLibraryImplBase::ConnectToWifiNetwork(WifiNetwork* wifi) {
583 NetworkConnectStartWifi(wifi, PROFILE_NONE);
584 }
585
586 // 1. Request a connection to an existing wimax network.
587 // Use |shared| to pass along the desired profile type.
588 void NetworkLibraryImplBase::ConnectToWimaxNetwork(
589 WimaxNetwork* wimax, bool shared) {
590 NetworkConnectStart(wimax, shared ? PROFILE_SHARED : PROFILE_USER);
591 }
592
593 // 1. Request a connection to an existing wimax network.
594 void NetworkLibraryImplBase::ConnectToWimaxNetwork(WimaxNetwork* wimax) {
595 NetworkConnectStart(wimax, PROFILE_NONE);
596 }
597
598 // 1. Connect to a cellular network.
599 void NetworkLibraryImplBase::ConnectToCellularNetwork(
600 CellularNetwork* cellular) {
601 NetworkConnectStart(cellular, PROFILE_NONE);
602 }
603
604 // 1. Connect to an existing virtual network.
605 void NetworkLibraryImplBase::ConnectToVirtualNetwork(VirtualNetwork* vpn) {
606 NetworkConnectStartVPN(vpn);
607 }
608
609 // 2. Start the connection.
610 void NetworkLibraryImplBase::NetworkConnectStartWifi(
611 WifiNetwork* wifi, NetworkProfileType profile_type) {
612 DCHECK(!wifi->connection_started());
613 // This will happen if a network resets, gets out of range or is forgotten.
614 if (wifi->user_passphrase_ != wifi->passphrase_ ||
615 wifi->passphrase_required())
616 wifi->SetPassphrase(wifi->user_passphrase_);
617 // For enterprise 802.1X networks, always provide TPM PIN when available.
618 // shill uses the PIN if it needs to access certificates in the TPM and
619 // ignores it otherwise.
620 if (wifi->encryption() == SECURITY_8021X) {
621 // If the TPM initialization has not completed, GetTpmPin() will return
622 // an empty value, in which case we do not want to clear the PIN since
623 // that will cause shill to flag the network as unconfigured.
624 // TODO(stevenjb): We may want to delay attempting to connect, or fail
625 // immediately, rather than let the network layer attempt a connection.
626 std::string tpm_pin = GetTpmPin();
627 if (!tpm_pin.empty())
628 wifi->SetCertificatePin(tpm_pin);
629 }
630 NetworkConnectStart(wifi, profile_type);
631 }
632
633 void NetworkLibraryImplBase::NetworkConnectStartVPN(VirtualNetwork* vpn) {
634 // shill needs the TPM PIN for some VPN networks to access client
635 // certificates, and ignores the PIN if it doesn't need them. Only set this
636 // if the TPM is ready (see comment in NetworkConnectStartWifi).
637 std::string tpm_pin = GetTpmPin();
638 if (!tpm_pin.empty()) {
639 std::string tpm_slot = GetTpmSlot();
640 vpn->SetCertificateSlotAndPin(tpm_slot, tpm_pin);
641 }
642 NetworkConnectStart(vpn, PROFILE_NONE);
643 }
644
645 void NetworkLibraryImplBase::NetworkConnectStart(
646 Network* network, NetworkProfileType profile_type) {
647 DCHECK(network);
648 DCHECK(!network->connection_started());
649 // In order to be certain to trigger any notifications, set the connecting
650 // state locally and notify observers. Otherwise there might be a state
651 // change without a forced notify.
652 network->set_connecting();
653 // Distinguish between user-initiated connection attempts
654 // and auto-connect.
655 network->set_user_connect_state(USER_CONNECT_STARTED);
656 NotifyNetworkManagerChanged(true); // Forced update.
657 VLOG(1) << "Requesting connect to network: " << network->name()
658 << " profile type: " << profile_type;
659 // Specify the correct profile for wifi networks (if specified or unset).
660 if ((network->type() == TYPE_WIFI || network->type() == TYPE_WIMAX) &&
661 (profile_type != PROFILE_NONE ||
662 network->profile_type() == PROFILE_NONE)) {
663 if (network->RequiresUserProfile())
664 profile_type = PROFILE_USER; // Networks with certs can not be shared.
665 else if (profile_type == PROFILE_NONE)
666 profile_type = PROFILE_SHARED; // Other networks are shared by default.
667 std::string profile_path = GetProfilePath(profile_type);
668 if (!profile_path.empty()) {
669 if (profile_path != network->profile_path())
670 SetProfileType(network, profile_type);
671 } else if (profile_type == PROFILE_USER) {
672 // The user profile was specified but is not available (i.e. pre-login).
673 // Add this network to the list of networks to move to the user profile
674 // when it becomes available.
675 VLOG(1) << "Queuing: " << network->name() << " to user_networks list.";
676 user_networks_.push_back(network->service_path());
677 }
678 }
679 CallConnectToNetwork(network);
680 }
681
682 // 3. Start the connection attempt for Network.
683 // Must Call NetworkConnectCompleted when the connection attempt completes.
684 // virtual void CallConnectToNetwork(Network* network) = 0;
685
686 // 4. Complete the connection.
687 void NetworkLibraryImplBase::NetworkConnectCompleted(
688 Network* network, NetworkConnectStatus status) {
689 DCHECK(network);
690 if (status != CONNECT_SUCCESS) {
691 // This will trigger the connection failed notification.
692 // TODO(stevenjb): Remove if chromium-os:13203 gets fixed.
693 network->SetState(STATE_FAILURE);
694 if (status == CONNECT_BAD_PASSPHRASE) {
695 network->SetError(ERROR_BAD_PASSPHRASE);
696 } else {
697 network->SetError(ERROR_CONNECT_FAILED);
698 }
699 NotifyNetworkManagerChanged(true); // Forced update.
700 NotifyNetworkChanged(network);
701 VLOG(1) << "Error connecting to network: " << network->name()
702 << " Status: " << status;
703 return;
704 }
705
706 VLOG(1) << "Connected to network: " << network->name()
707 << " State: " << network->state()
708 << " Status: " << status;
709
710 // If the user asked not to save credentials, shill will have
711 // forgotten them. Wipe our cache as well.
712 if (!network->save_credentials())
713 network->EraseCredentials();
714
715 ClearActiveNetwork(network->type());
716 UpdateActiveNetwork(network);
717
718 // Notify observers.
719 NotifyNetworkManagerChanged(true); // Forced update.
720 NotifyNetworkChanged(network);
721 }
722
723 /////////////////////////////////////////////////////////////////////////////
724 // Request a network and connect to it.
725
726 // 1. Connect to an unconfigured or unlisted wifi network.
727 // This needs to request information about the named service.
728 // The connection attempt will occur in the callback.
729 void NetworkLibraryImplBase::ConnectToUnconfiguredWifiNetwork(
730 const std::string& ssid,
731 ConnectionSecurity security,
732 const std::string& passphrase,
733 const EAPConfigData* eap_config,
734 bool save_credentials,
735 bool shared) {
736 // Store the connection data to be used by the callback.
737 connect_data_.security = security;
738 connect_data_.service_name = ssid;
739 connect_data_.passphrase = passphrase;
740 connect_data_.save_credentials = save_credentials;
741 connect_data_.profile_type = shared ? PROFILE_SHARED : PROFILE_USER;
742 if (security == SECURITY_8021X) {
743 DCHECK(eap_config);
744 connect_data_.service_name = ssid;
745 connect_data_.eap_method = eap_config->method;
746 connect_data_.eap_auth = eap_config->auth;
747 connect_data_.server_ca_cert_pem = eap_config->server_ca_cert_pem;
748 connect_data_.eap_use_system_cas = eap_config->use_system_cas;
749 connect_data_.client_cert_pkcs11_id =
750 eap_config->client_cert_pkcs11_id;
751 connect_data_.eap_identity = eap_config->identity;
752 connect_data_.eap_anonymous_identity = eap_config->anonymous_identity;
753 }
754
755 CallRequestWifiNetworkAndConnect(ssid, security);
756 }
757
758 // 1. Connect to a virtual network with a PSK.
759 void NetworkLibraryImplBase::ConnectToUnconfiguredVirtualNetwork(
760 const std::string& service_name,
761 const std::string& server_hostname,
762 ProviderType provider_type,
763 const VPNConfigData& config) {
764 // Store the connection data to be used by the callback.
765 connect_data_.service_name = service_name;
766 connect_data_.server_hostname = server_hostname;
767 connect_data_.psk_key = config.psk;
768 connect_data_.server_ca_cert_pem = config.server_ca_cert_pem;
769 connect_data_.client_cert_pkcs11_id = config.client_cert_pkcs11_id;
770 connect_data_.username = config.username;
771 connect_data_.passphrase = config.user_passphrase;
772 connect_data_.otp = config.otp;
773 connect_data_.group_name = config.group_name;
774 connect_data_.save_credentials = config.save_credentials;
775 CallRequestVirtualNetworkAndConnect(
776 service_name, server_hostname, provider_type);
777 }
778
779 // 2. Requests a WiFi Network by SSID and security.
780 // Calls ConnectToWifiNetworkUsingConnectData if network request succeeds.
781 // virtual void CallRequestWifiNetworkAndConnect(
782 // const std::string& ssid, ConnectionSecurity security) = 0;
783
784 // 2. Requests a Virtual Network by service name, etc.
785 // Calls ConnectToVirtualNetworkUsingConnectData if network request succeeds.
786 // virtual void CallRequestVirtualNetworkAndConnect(
787 // const std::string& service_name,
788 // const std::string& server_hostname,
789 // ProviderType provider_type) = 0;
790
791 // 3. Sets network properties stored in ConnectData and calls
792 // NetworkConnectStart.
793 void NetworkLibraryImplBase::ConnectToWifiNetworkUsingConnectData(
794 WifiNetwork* wifi) {
795 ConnectData& data = connect_data_;
796 if (wifi->name() != data.service_name) {
797 LOG(WARNING) << "WiFi network name does not match ConnectData: "
798 << wifi->name() << " != " << data.service_name;
799 return;
800 }
801 wifi->set_added(true);
802 if (data.security == SECURITY_8021X) {
803 // Enterprise 802.1X EAP network.
804 wifi->SetEAPMethod(data.eap_method);
805 wifi->SetEAPPhase2Auth(data.eap_auth);
806 wifi->SetEAPServerCaCertPEM(data.server_ca_cert_pem);
807 wifi->SetEAPUseSystemCAs(data.eap_use_system_cas);
808 wifi->SetEAPClientCertPkcs11Id(data.client_cert_pkcs11_id);
809 wifi->SetEAPIdentity(data.eap_identity);
810 wifi->SetEAPAnonymousIdentity(data.eap_anonymous_identity);
811 wifi->SetEAPPassphrase(data.passphrase);
812 wifi->SetSaveCredentials(data.save_credentials);
813 } else {
814 // Ordinary, non-802.1X network.
815 wifi->SetPassphrase(data.passphrase);
816 }
817
818 NetworkConnectStartWifi(wifi, data.profile_type);
819 }
820
821 // 3. Sets network properties stored in ConnectData and calls
822 // ConnectToVirtualNetwork.
823 void NetworkLibraryImplBase::ConnectToVirtualNetworkUsingConnectData(
824 VirtualNetwork* vpn) {
825 ConnectData& data = connect_data_;
826 if (vpn->name() != data.service_name) {
827 LOG(WARNING) << "Virtual network name does not match ConnectData: "
828 << vpn->name() << " != " << data.service_name;
829 return;
830 }
831
832 // When a L2TP/IPsec certificate-based VPN is created, the VirtualNetwork
833 // instance is created by NativeNetworkParser::CreateNetworkFromInfo().
834 // At that point, the provider type is deduced based on the value of
835 // client_cert_id_ of the VirtualNetwork instance, which hasn't been
836 // updated to the value of connect_data_.client_cert_pkcs11_id. Thus,
837 // the provider type is always incorrectly set to L2TP_IPSEC_PSK when
838 // L2TP_IPSEC_USER_CERT is expected. Here we fix the provider type based
839 // on connect_data_.client_cert_pkcs11_id.
840 //
841 // TODO(benchan): This is a quick and dirty workaround, we should refactor
842 // the code to make the flow more straightforward. See crosbug.com/24636
843 if (vpn->provider_type() == PROVIDER_TYPE_L2TP_IPSEC_PSK &&
844 !connect_data_.client_cert_pkcs11_id.empty()) {
845 vpn->set_provider_type(PROVIDER_TYPE_L2TP_IPSEC_USER_CERT);
846 }
847
848 vpn->set_added(true);
849 if (!data.server_hostname.empty())
850 vpn->set_server_hostname(data.server_hostname);
851
852 vpn->SetCACertPEM(data.server_ca_cert_pem);
853 switch (vpn->provider_type()) {
854 case PROVIDER_TYPE_L2TP_IPSEC_PSK:
855 vpn->SetL2TPIPsecPSKCredentials(
856 data.psk_key, data.username, data.passphrase, data.group_name);
857 break;
858 case PROVIDER_TYPE_L2TP_IPSEC_USER_CERT: {
859 vpn->SetL2TPIPsecCertCredentials(
860 data.client_cert_pkcs11_id,
861 data.username, data.passphrase, data.group_name);
862 break;
863 }
864 case PROVIDER_TYPE_OPEN_VPN: {
865 vpn->SetOpenVPNCredentials(
866 data.client_cert_pkcs11_id,
867 data.username, data.passphrase, data.otp);
868 break;
869 }
870 case PROVIDER_TYPE_MAX:
871 NOTREACHED();
872 break;
873 }
874 vpn->SetSaveCredentials(data.save_credentials);
875
876 NetworkConnectStartVPN(vpn);
877 }
878
879 /////////////////////////////////////////////////////////////////////////////
880
881 void NetworkLibraryImplBase::ForgetNetwork(const std::string& service_path) {
882 // Remove network from remembered list and notify observers.
883 DeleteRememberedNetwork(service_path);
884 NotifyNetworkManagerChanged(true); // Forced update.
885 }
886
887 /////////////////////////////////////////////////////////////////////////////
888
889 void NetworkLibraryImplBase::EnableEthernetNetworkDevice(bool enable) {
890 if (is_locked_)
891 return;
892 CallEnableNetworkDeviceType(TYPE_ETHERNET, enable);
893 }
894
895 void NetworkLibraryImplBase::EnableWifiNetworkDevice(bool enable) {
896 if (is_locked_)
897 return;
898 CallEnableNetworkDeviceType(TYPE_WIFI, enable);
899 }
900
901 void NetworkLibraryImplBase::EnableWimaxNetworkDevice(bool enable) {
902 if (is_locked_)
903 return;
904 CallEnableNetworkDeviceType(TYPE_WIMAX, enable);
905 }
906
907 void NetworkLibraryImplBase::EnableCellularNetworkDevice(bool enable) {
908 if (is_locked_)
909 return;
910 CallEnableNetworkDeviceType(TYPE_CELLULAR, enable);
911 }
912
913 void NetworkLibraryImplBase::SwitchToPreferredNetwork() {
914 // If current network (if any) is not preferred, check network service list to
915 // see if the first not connected network is preferred and set to autoconnect.
916 // If so, connect to it.
917 if (!wifi_enabled() || (active_wifi_ && active_wifi_->preferred()))
918 return;
919 for (WifiNetworkVector::const_iterator it = wifi_networks_.begin();
920 it != wifi_networks_.end(); ++it) {
921 WifiNetwork* wifi = *it;
922 if (wifi->connected() || wifi->connecting()) // Skip connected/connecting.
923 continue;
924 if (!wifi->preferred()) // All preferred networks are sorted in front.
925 break;
926 if (wifi->auto_connect()) {
927 ConnectToWifiNetwork(wifi);
928 break;
929 }
930 }
931 }
932
933 namespace {
934
935 class UserStringSubstitution : public onc::StringSubstitution {
936 public:
937 UserStringSubstitution() {}
938 virtual bool GetSubstitute(const std::string& placeholder,
939 std::string* substitute) const OVERRIDE {
940 if (!UserManager::Get()->IsUserLoggedIn())
941 return false;
942 const User* logged_in_user = UserManager::Get()->GetLoggedInUser();
943 if (placeholder == onc::substitutes::kLoginIDField)
944 *substitute = logged_in_user->GetAccountName(false);
945 else if (placeholder == onc::substitutes::kEmailField)
946 *substitute = logged_in_user->email();
947 else
948 return false;
949 return true;
950 }
951 };
952
953 } // namespace
954
955 void NetworkLibraryImplBase::LoadOncNetworks(
956 const base::ListValue& network_configs,
957 onc::ONCSource source) {
958 VLOG(2) << __func__ << ": called on " << network_configs;
959 NetworkProfile* profile = NULL;
960 bool from_policy = (source == onc::ONC_SOURCE_USER_POLICY ||
961 source == onc::ONC_SOURCE_DEVICE_POLICY);
962
963 // Policies are applied to a specific Shill profile. User ONC import however
964 // is applied to whatever profile Shill chooses. This should be the profile
965 // that is already associated with a network and if no profile is associated
966 // yet, it should be the user profile.
967 if (from_policy) {
968 profile = GetProfileForType(GetProfileTypeForSource(source));
969 if (profile == NULL) {
970 VLOG(2) << "Profile for ONC source " << onc::GetSourceAsString(source)
971 << " doesn't exist.";
972 return;
973 }
974 }
975
976 std::set<std::string> removal_ids;
977 std::set<std::string>& network_ids(network_source_map_[source]);
978 network_ids.clear();
979 VLOG(2) << "ONC file has " << network_configs.GetSize() << " networks";
980 for (base::ListValue::const_iterator it(network_configs.begin());
981 it != network_configs.end(); ++it) {
982 const base::DictionaryValue* network;
983 (*it)->GetAsDictionary(&network);
984
985 bool marked_for_removal = false;
986 network->GetBooleanWithoutPathExpansion(onc::kRemove,
987 &marked_for_removal);
988
989 std::string type;
990 network->GetStringWithoutPathExpansion(onc::network_config::kType, &type);
991
992 std::string guid;
993 network->GetStringWithoutPathExpansion(onc::network_config::kGUID, &guid);
994
995 if (source == onc::ONC_SOURCE_USER_IMPORT && marked_for_removal) {
996 // User import supports the removal of networks by ID.
997 removal_ids.insert(guid);
998 continue;
999 }
1000
1001 // Don't configure a network that is supposed to be removed. For
1002 // policy-managed networks, the "remove" functionality of ONC is
1003 // irrelevant. Instead, in general, all previously configured networks
1004 // that are no longer configured are removed.
1005 if (marked_for_removal)
1006 continue;
1007
1008 // Store the network's identifier. The identifiers are later used to clean
1009 // out any previously-existing networks that had been configured through
1010 // policy but are no longer specified in the updated ONC blob.
1011 network_ids.insert(guid);
1012
1013 // Expand strings like LoginID
1014 base::DictionaryValue* expanded_network = network->DeepCopy();
1015 UserStringSubstitution substitution;
1016 onc::ExpandStringsInOncObject(onc::kNetworkConfigurationSignature,
1017 substitution,
1018 expanded_network);
1019
1020 // Update the ONC map.
1021 const base::DictionaryValue*& entry = network_onc_map_[guid];
1022 if (entry && entry->Equals(expanded_network))
1023 continue;
1024
1025 delete entry;
1026 entry = expanded_network;
1027
1028 // Normalize the ONC: Remove irrelevant fields.
1029 onc::Normalizer normalizer(true /* remove recommended fields */);
1030 scoped_ptr<base::DictionaryValue> normalized_network =
1031 normalizer.NormalizeObject(&onc::kNetworkConfigurationSignature,
1032 *expanded_network);
1033
1034 // Configure the network.
1035 scoped_ptr<base::DictionaryValue> shill_dict =
1036 onc::TranslateONCObjectToShill(&onc::kNetworkConfigurationSignature,
1037 *normalized_network);
1038
1039 // Set the UIData.
1040 scoped_ptr<NetworkUIData> ui_data =
1041 NetworkUIData::CreateFromONC(source, *normalized_network);
1042 base::DictionaryValue ui_data_dict;
1043 ui_data->FillDictionary(&ui_data_dict);
1044 std::string ui_data_json;
1045 base::JSONWriter::Write(&ui_data_dict, &ui_data_json);
1046 shill_dict->SetStringWithoutPathExpansion(flimflam::kUIDataProperty,
1047 ui_data_json);
1048
1049 // Set the appropriate profile for |source|.
1050 if (profile != NULL) {
1051 shill_dict->SetStringWithoutPathExpansion(flimflam::kProfileProperty,
1052 profile->path);
1053 }
1054
1055 // For Ethernet networks, apply them to the current Ethernet service.
1056 if (type == onc::network_type::kEthernet) {
1057 const EthernetNetwork* ethernet = ethernet_network();
1058 if (ethernet) {
1059 CallConfigureService(ethernet->unique_id(), shill_dict.get());
1060 } else {
1061 LOG(WARNING) << "Tried to import ONC with an Ethernet network when "
1062 << "there is no active Ethernet connection.";
1063 }
1064 } else {
1065 CallConfigureService(guid, shill_dict.get());
1066 }
1067 }
1068
1069 if (from_policy) {
1070 // For policy-managed networks, go through the list of existing remembered
1071 // networks and clean out the ones that no longer have a definition in the
1072 // ONC blob. We first collect the networks and do the actual deletion later
1073 // because ForgetNetwork() changes the remembered network vectors.
1074 ForgetNetworksById(source, network_ids, false);
1075 } else if (source == onc::ONC_SOURCE_USER_IMPORT && !removal_ids.empty()) {
1076 ForgetNetworksById(source, removal_ids, true);
1077 }
1078 // Ensure NetworkStateHandler properties are up-to-date.
1079 if (NetworkHandler::IsInitialized()) {
1080 NetworkHandler::Get()->network_state_handler()->
1081 RequestUpdateForAllNetworks();
1082 }
1083 }
1084
1085 ////////////////////////////////////////////////////////////////////////////
1086 // Testing functions.
1087
1088 bool NetworkLibraryImplBase::SetActiveNetwork(
1089 ConnectionType type, const std::string& service_path) {
1090 Network* network = NULL;
1091 if (!service_path.empty())
1092 network = FindNetworkByPath(service_path);
1093 if (network && network->type() != type) {
1094 LOG(WARNING) << "SetActiveNetwork type mismatch for: " << network->name();
1095 return false;
1096 }
1097
1098 ClearActiveNetwork(type);
1099
1100 if (!network)
1101 return true;
1102
1103 // Set |network| to active.
1104 UpdateActiveNetwork(network);
1105 return true;
1106 }
1107
1108 ////////////////////////////////////////////////////////////////////////////
1109 // Network list management functions.
1110
1111 // Note: sometimes shill still returns networks when the device type is
1112 // disabled. Always check the appropriate enabled() state before adding
1113 // networks to a list or setting an active network so that we do not show them
1114 // in the UI.
1115
1116 // This relies on services being requested from shill in priority order,
1117 // and the updates getting processed and received in order.
1118 void NetworkLibraryImplBase::UpdateActiveNetwork(Network* network) {
1119 network->set_is_active(true);
1120 ConnectionType type(network->type());
1121 if (type == TYPE_ETHERNET) {
1122 if (ethernet_enabled()) {
1123 // Set ethernet_ to the first connected ethernet service, or the first
1124 // disconnected ethernet service if none are connected.
1125 if (ethernet_ == NULL || !ethernet_->connected()) {
1126 ethernet_ = static_cast<EthernetNetwork*>(network);
1127 VLOG(2) << "Active ethernet -> " << ethernet_->name();
1128 }
1129 }
1130 } else if (type == TYPE_WIFI) {
1131 if (wifi_enabled()) {
1132 // Set active_wifi_ to the first connected or connecting wifi service.
1133 if (active_wifi_ == NULL && network->connecting_or_connected()) {
1134 active_wifi_ = static_cast<WifiNetwork*>(network);
1135 VLOG(2) << "Active wifi -> " << active_wifi_->name();
1136 }
1137 }
1138 } else if (type == TYPE_CELLULAR) {
1139 if (cellular_enabled()) {
1140 // Set active_cellular_ to first connected/connecting celluar service.
1141 if (active_cellular_ == NULL && network->connecting_or_connected()) {
1142 active_cellular_ = static_cast<CellularNetwork*>(network);
1143 VLOG(2) << "Active cellular -> " << active_cellular_->name();
1144 }
1145 }
1146 } else if (type == TYPE_WIMAX) {
1147 if (wimax_enabled()) {
1148 // Set active_wimax_ to first connected/connecting wimax service.
1149 if (active_wimax_ == NULL && network->connecting_or_connected()) {
1150 active_wimax_ = static_cast<WimaxNetwork*>(network);
1151 VLOG(2) << "Active wimax -> " << active_wimax_->name();
1152 }
1153 }
1154 } else if (type == TYPE_VPN) {
1155 // Set active_virtual_ to the first connected or connecting vpn service. {
1156 if (active_virtual_ == NULL && network->connecting_or_connected()) {
1157 active_virtual_ = static_cast<VirtualNetwork*>(network);
1158 VLOG(2) << "Active virtual -> " << active_virtual_->name();
1159 }
1160 }
1161 }
1162
1163 void NetworkLibraryImplBase::ClearActiveNetwork(ConnectionType type) {
1164 // Clear any existing active network matching |type|.
1165 for (NetworkMap::iterator iter = network_map_.begin();
1166 iter != network_map_.end(); ++iter) {
1167 Network* other = iter->second;
1168 if (other->type() == type)
1169 other->set_is_active(false);
1170 }
1171 switch (type) {
1172 case TYPE_ETHERNET:
1173 ethernet_ = NULL;
1174 break;
1175 case TYPE_WIFI:
1176 active_wifi_ = NULL;
1177 break;
1178 case TYPE_CELLULAR:
1179 active_cellular_ = NULL;
1180 break;
1181 case TYPE_WIMAX:
1182 active_wimax_ = NULL;
1183 break;
1184 case TYPE_VPN:
1185 active_virtual_ = NULL;
1186 break;
1187 default:
1188 break;
1189 }
1190 }
1191
1192 void NetworkLibraryImplBase::AddNetwork(Network* network) {
1193 std::pair<NetworkMap::iterator, bool> result =
1194 network_map_.insert(std::make_pair(network->service_path(), network));
1195 DCHECK(result.second); // Should only get called with new network.
1196 VLOG(2) << "Adding Network: " << network->service_path()
1197 << " (" << network->name() << ")";
1198 ConnectionType type(network->type());
1199 if (type == TYPE_WIFI) {
1200 if (wifi_enabled())
1201 wifi_networks_.push_back(static_cast<WifiNetwork*>(network));
1202 } else if (type == TYPE_CELLULAR) {
1203 if (cellular_enabled())
1204 cellular_networks_.push_back(static_cast<CellularNetwork*>(network));
1205 } else if (type == TYPE_WIMAX) {
1206 if (wimax_enabled())
1207 wimax_networks_.push_back(static_cast<WimaxNetwork*>(network));
1208 } else if (type == TYPE_VPN) {
1209 virtual_networks_.push_back(static_cast<VirtualNetwork*>(network));
1210 }
1211 // Do not set the active network here. Wait until we parse the network.
1212 }
1213
1214 // Deletes a network. It must already be removed from any lists.
1215 void NetworkLibraryImplBase::DeleteNetwork(Network* network) {
1216 CHECK(network_map_.find(network->service_path()) == network_map_.end());
1217 delete network;
1218 }
1219
1220 void NetworkLibraryImplBase::ForgetNetworksById(
1221 onc::ONCSource source,
1222 std::set<std::string> ids,
1223 bool if_found) {
1224 std::vector<std::string> to_be_forgotten;
1225 for (WifiNetworkVector::iterator i = remembered_wifi_networks_.begin();
1226 i != remembered_wifi_networks_.end(); ++i) {
1227 WifiNetwork* wifi_network = *i;
1228 if (wifi_network->ui_data().onc_source() == source &&
1229 if_found == (ids.find(wifi_network->unique_id()) != ids.end()))
1230 to_be_forgotten.push_back(wifi_network->service_path());
1231 }
1232
1233 for (VirtualNetworkVector::iterator i = remembered_virtual_networks_.begin();
1234 i != remembered_virtual_networks_.end(); ++i) {
1235 VirtualNetwork* virtual_network = *i;
1236 if (virtual_network->ui_data().onc_source() == source &&
1237 if_found == (ids.find(virtual_network->unique_id()) != ids.end()))
1238 to_be_forgotten.push_back(virtual_network->service_path());
1239 }
1240
1241 for (std::vector<std::string>::const_iterator i = to_be_forgotten.begin();
1242 i != to_be_forgotten.end(); ++i) {
1243 ForgetNetwork(*i);
1244 }
1245 }
1246
1247 bool NetworkLibraryImplBase::ValidateRememberedNetwork(Network* network) {
1248 std::pair<NetworkMap::iterator, bool> result =
1249 remembered_network_map_.insert(
1250 std::make_pair(network->service_path(), network));
1251 DCHECK(result.second); // Should only get called with new network.
1252
1253 // See if this is a policy-configured network that has meanwhile been removed.
1254 // This situation may arise when the full list of remembered networks is not
1255 // available to LoadOncNetworks(), which can happen due to the asynchronous
1256 // communication between shill and NetworkLibrary. Just tell shill to
1257 // delete the network now.
1258 const onc::ONCSource source = network->ui_data().onc_source();
1259 if (source == onc::ONC_SOURCE_USER_POLICY ||
1260 source == onc::ONC_SOURCE_DEVICE_POLICY) {
1261 NetworkSourceMap::const_iterator network_id_set(
1262 network_source_map_.find(source));
1263 if (network_id_set != network_source_map_.end() &&
1264 network_id_set->second.find(network->unique_id()) ==
1265 network_id_set->second.end()) {
1266 DeleteRememberedNetwork(network->service_path());
1267 return false;
1268 }
1269 }
1270
1271 return true;
1272 }
1273
1274 bool NetworkLibraryImplBase::ValidateAndAddRememberedNetwork(Network* network) {
1275 if (!ValidateRememberedNetwork(network))
1276 return false;
1277
1278 if (network->type() == TYPE_WIFI) {
1279 remembered_wifi_networks_.push_back(
1280 static_cast<WifiNetwork*>(network));
1281 } else if (network->type() == TYPE_VPN) {
1282 remembered_virtual_networks_.push_back(
1283 static_cast<VirtualNetwork*>(network));
1284 } else {
1285 NOTREACHED();
1286 }
1287
1288 VLOG(1) << "ValidateAndAddRememberedNetwork: " << network->service_path();
1289 return true;
1290 }
1291
1292 void NetworkLibraryImplBase::DeleteRememberedNetwork(
1293 const std::string& service_path) {
1294 NetworkMap::iterator found = remembered_network_map_.find(service_path);
1295 if (found == remembered_network_map_.end()) {
1296 LOG(WARNING) << "Attempt to delete non-existent remembered network: "
1297 << service_path;
1298 return;
1299 }
1300 Network* remembered_network = found->second;
1301 VLOG(1) << "Deleting remembered network: "
1302 << remembered_network->service_path();
1303
1304 // Update any associated network service before removing from profile
1305 // so that shill doesn't recreate the service (e.g. when we disconenct it).
1306 Network* network = FindNetworkByUniqueId(remembered_network->unique_id());
1307 if (network) {
1308 // Clear the stored credentials for any forgotten networks.
1309 network->EraseCredentials();
1310 network->ClearUIData();
1311 SetProfileType(network, PROFILE_NONE);
1312 // Remove VPN from list of networks.
1313 if (network->type() == TYPE_VPN)
1314 CallRemoveNetwork(network);
1315 } else {
1316 // Network is not in service list.
1317 VLOG(2) << "Remembered Network not in service list: "
1318 << remembered_network->unique_id();
1319 }
1320
1321 // Delete remembered network from lists.
1322 remembered_network_map_.erase(found);
1323
1324 if (remembered_network->type() == TYPE_WIFI) {
1325 WifiNetworkVector::iterator iter = std::find(
1326 remembered_wifi_networks_.begin(),
1327 remembered_wifi_networks_.end(),
1328 remembered_network);
1329 if (iter != remembered_wifi_networks_.end())
1330 remembered_wifi_networks_.erase(iter);
1331 } else if (remembered_network->type() == TYPE_VPN) {
1332 VirtualNetworkVector::iterator iter = std::find(
1333 remembered_virtual_networks_.begin(),
1334 remembered_virtual_networks_.end(),
1335 remembered_network);
1336 if (iter != remembered_virtual_networks_.end())
1337 remembered_virtual_networks_.erase(iter);
1338 }
1339
1340 // Delete remembered network from all profiles it is in.
1341 for (NetworkProfileList::iterator iter = profile_list_.begin();
1342 iter != profile_list_.end(); ++iter) {
1343 NetworkProfile& profile = *iter;
1344 NetworkProfile::ServiceList::iterator found =
1345 profile.services.find(remembered_network->service_path());
1346 if (found != profile.services.end()) {
1347 VLOG(1) << "Deleting: " << remembered_network->service_path()
1348 << " From: " << profile.path;
1349 CallDeleteRememberedNetwork(profile.path,
1350 remembered_network->service_path());
1351 profile.services.erase(found);
1352 }
1353 }
1354
1355 // Remove the ONC blob for the network, if present.
1356 NetworkOncMap::iterator onc_map_entry =
1357 network_onc_map_.find(remembered_network->unique_id());
1358 if (onc_map_entry != network_onc_map_.end()) {
1359 delete onc_map_entry->second;
1360 network_onc_map_.erase(onc_map_entry);
1361 }
1362
1363 delete remembered_network;
1364 }
1365
1366 ////////////////////////////////////////////////////////////////////////////
1367
1368 void NetworkLibraryImplBase::ClearNetworks() {
1369 network_map_.clear();
1370 network_unique_id_map_.clear();
1371 ethernet_ = NULL;
1372 active_wifi_ = NULL;
1373 active_cellular_ = NULL;
1374 active_wimax_ = NULL;
1375 active_virtual_ = NULL;
1376 wifi_networks_.clear();
1377 cellular_networks_.clear();
1378 wimax_networks_.clear();
1379 virtual_networks_.clear();
1380 }
1381
1382 void NetworkLibraryImplBase::DeleteRememberedNetworks() {
1383 STLDeleteValues(&remembered_network_map_);
1384 remembered_network_map_.clear();
1385 remembered_wifi_networks_.clear();
1386 remembered_virtual_networks_.clear();
1387 }
1388
1389 void NetworkLibraryImplBase::DeleteDevice(const std::string& device_path) {
1390 NetworkDeviceMap::iterator found = device_map_.find(device_path);
1391 if (found == device_map_.end()) {
1392 LOG(WARNING) << "Attempt to delete non-existent device: "
1393 << device_path;
1394 return;
1395 }
1396 VLOG(2) << " Deleting device: " << device_path;
1397 NetworkDevice* device = found->second;
1398 device_map_.erase(found);
1399 delete device;
1400 DeleteDeviceFromDeviceObserversMap(device_path);
1401 }
1402
1403 ////////////////////////////////////////////////////////////////////////////
1404
1405 void NetworkLibraryImplBase::AddProfile(const std::string& profile_path,
1406 NetworkProfileType profile_type) {
1407 VLOG(1) << "Adding profile " << profile_path;
1408 profile_list_.push_back(NetworkProfile(profile_path, profile_type));
1409 // Check to see if we connected to any networks before a user profile was
1410 // available (i.e. before login), but unchecked the "Share" option (i.e.
1411 // the desired pofile is the user profile). Move these networks to the
1412 // user profile when it becomes available.
1413 if (profile_type == PROFILE_USER && !user_networks_.empty()) {
1414 for (std::list<std::string>::iterator iter2 = user_networks_.begin();
1415 iter2 != user_networks_.end(); ++iter2) {
1416 Network* network = FindNetworkByPath(*iter2);
1417 if (network && network->profile_path() != profile_path)
1418 network->SetProfilePath(profile_path);
1419 }
1420 user_networks_.clear();
1421 }
1422 }
1423
1424 NetworkLibraryImplBase::NetworkProfile*
1425 NetworkLibraryImplBase::GetProfileForType(NetworkProfileType type) {
1426 for (NetworkProfileList::iterator iter = profile_list_.begin();
1427 iter != profile_list_.end(); ++iter) {
1428 NetworkProfile& profile = *iter;
1429 if (profile.type == type)
1430 return &profile;
1431 }
1432 return NULL;
1433 }
1434
1435 void NetworkLibraryImplBase::SetProfileType(
1436 Network* network, NetworkProfileType type) {
1437 if (type == PROFILE_NONE) {
1438 network->SetProfilePath(std::string());
1439 network->set_profile_type(PROFILE_NONE);
1440 } else {
1441 std::string profile_path = GetProfilePath(type);
1442 if (!profile_path.empty()) {
1443 network->SetProfilePath(profile_path);
1444 network->set_profile_type(type);
1445 } else {
1446 LOG(WARNING) << "Profile type not found: " << type;
1447 network->set_profile_type(PROFILE_NONE);
1448 }
1449 }
1450 }
1451
1452 void NetworkLibraryImplBase::SetProfileTypeFromPath(Network* network) {
1453 if (network->profile_path().empty()) {
1454 network->set_profile_type(PROFILE_NONE);
1455 return;
1456 }
1457 for (NetworkProfileList::iterator iter = profile_list_.begin();
1458 iter != profile_list_.end(); ++iter) {
1459 NetworkProfile& profile = *iter;
1460 if (profile.path == network->profile_path()) {
1461 network->set_profile_type(profile.type);
1462 return;
1463 }
1464 }
1465 LOG(WARNING) << "Profile path not found: " << network->profile_path();
1466 network->set_profile_type(PROFILE_NONE);
1467 }
1468
1469 std::string NetworkLibraryImplBase::GetProfilePath(NetworkProfileType type) {
1470 std::string profile_path;
1471 NetworkProfile* profile = GetProfileForType(type);
1472 if (profile)
1473 profile_path = profile->path;
1474 return profile_path;
1475 }
1476
1477 ////////////////////////////////////////////////////////////////////////////
1478 // Notifications.
1479
1480 void NetworkLibraryImplBase::NotifyNetworkProfileObservers() {
1481 FOR_EACH_OBSERVER(NetworkProfileObserver,
1482 network_profile_observers_,
1483 OnProfileListChanged());
1484 }
1485
1486 // We call this any time something in NetworkLibrary changes.
1487 // TODO(stevenjb): We should consider breaking this into multiple
1488 // notifications, e.g. connection state, devices, services, etc.
1489 void NetworkLibraryImplBase::NotifyNetworkManagerChanged(bool force_update) {
1490 // Cancel any pending signals.
1491 notify_manager_weak_factory_.InvalidateWeakPtrs();
1492 if (force_update) {
1493 // Signal observers now.
1494 SignalNetworkManagerObservers();
1495 } else {
1496 // Schedule a delayed signal to limit the frequency of notifications.
1497 BrowserThread::PostDelayedTask(
1498 BrowserThread::UI,
1499 FROM_HERE,
1500 base::Bind(&NetworkLibraryImplBase::SignalNetworkManagerObservers,
1501 notify_manager_weak_factory_.GetWeakPtr()),
1502 base::TimeDelta::FromMilliseconds(kNetworkNotifyDelayMs));
1503 }
1504 }
1505
1506 void NetworkLibraryImplBase::SignalNetworkManagerObservers() {
1507 FOR_EACH_OBSERVER(NetworkManagerObserver,
1508 network_manager_observers_,
1509 OnNetworkManagerChanged(this));
1510 // Clear notification flags.
1511 for (NetworkMap::iterator iter = network_map_.begin();
1512 iter != network_map_.end(); ++iter) {
1513 iter->second->set_notify_failure(false);
1514 }
1515 }
1516
1517 void NetworkLibraryImplBase::NotifyNetworkChanged(const Network* network) {
1518 DCHECK(network);
1519 VLOG(2) << "Network changed: " << network->name();
1520 NetworkObserverMap::const_iterator iter = network_observers_.find(
1521 network->service_path());
1522 if (iter != network_observers_.end()) {
1523 FOR_EACH_OBSERVER(NetworkObserver,
1524 *(iter->second),
1525 OnNetworkChanged(this, network));
1526 } else if (IsCros()) {
1527 LOG(ERROR) << "Unexpected signal for unobserved network: "
1528 << network->name();
1529 }
1530 }
1531
1532 void NetworkLibraryImplBase::NotifyNetworkDeviceChanged(
1533 NetworkDevice* device, PropertyIndex index) {
1534 DCHECK(device);
1535 VLOG(2) << "Network device changed: " << device->name();
1536 NetworkDeviceObserverMap::const_iterator iter =
1537 network_device_observers_.find(device->device_path());
1538 if (iter != network_device_observers_.end()) {
1539 NetworkDeviceObserverList* device_observer_list = iter->second;
1540 if (index == PROPERTY_INDEX_FOUND_NETWORKS) {
1541 FOR_EACH_OBSERVER(NetworkDeviceObserver,
1542 *device_observer_list,
1543 OnNetworkDeviceFoundNetworks(this, device));
1544 } else if (index == PROPERTY_INDEX_SIM_LOCK) {
1545 FOR_EACH_OBSERVER(NetworkDeviceObserver,
1546 *device_observer_list,
1547 OnNetworkDeviceSimLockChanged(this, device));
1548 }
1549 } else {
1550 LOG(ERROR) << "Unexpected signal for unobserved device: "
1551 << device->name();
1552 }
1553 }
1554
1555 void NetworkLibraryImplBase::NotifyPinOperationCompleted(
1556 PinOperationError error) {
1557 FOR_EACH_OBSERVER(PinOperationObserver,
1558 pin_operation_observers_,
1559 OnPinOperationCompleted(this, error));
1560 sim_operation_ = SIM_OPERATION_NONE;
1561 }
1562
1563 //////////////////////////////////////////////////////////////////////////////
1564 // Pin related functions.
1565
1566 void NetworkLibraryImplBase::GetTpmInfo() {
1567 // Avoid making multiple synchronous D-Bus calls to cryptohome by caching
1568 // the TPM PIN, which does not change during a session.
1569 if (tpm_pin_.empty()) {
1570 if (crypto::IsTPMTokenReady()) {
1571 std::string tpm_label;
1572 crypto::GetTPMTokenInfo(&tpm_label, &tpm_pin_);
1573 // VLOG(1) << "TPM Label: " << tpm_label << ", PIN: " << tpm_pin_;
1574 // TODO(stevenjb): GetTPMTokenInfo returns a label, but the network
1575 // code expects a slot ID. See chromium-os:17998.
1576 // For now, use a hard coded, well known slot instead.
1577 const char kHardcodedTpmSlot[] = "0";
1578 tpm_slot_ = kHardcodedTpmSlot;
1579 } else if (IsCros()) {
1580 LOG(WARNING) << "TPM token not ready";
1581 }
1582 }
1583 }
1584
1585 const std::string& NetworkLibraryImplBase::GetTpmSlot() {
1586 GetTpmInfo();
1587 return tpm_slot_;
1588 }
1589
1590 const std::string& NetworkLibraryImplBase::GetTpmPin() {
1591 GetTpmInfo();
1592 return tpm_pin_;
1593 }
1594
1595 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/cros/network_library_impl_base.h ('k') | chrome/browser/chromeos/cros/network_library_impl_cros.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698