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->size()) { 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->size()) { 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 1596