Home | History | Annotate | Download | only in cros
      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