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.h"
      6 
      7 #include "base/chromeos/chromeos_version.h"
      8 #include "base/i18n/icu_encoding_detection.h"
      9 #include "base/i18n/icu_string_conversions.h"
     10 #include "base/i18n/time_formatting.h"
     11 #include "base/json/json_writer.h"  // for debug output only.
     12 #include "base/strings/string_number_conversions.h"
     13 #include "base/strings/utf_string_conversion_utils.h"
     14 #include "chrome/browser/chromeos/cros/native_network_constants.h"
     15 #include "chrome/browser/chromeos/cros/native_network_parser.h"
     16 #include "chrome/browser/chromeos/cros/network_library_impl_cros.h"
     17 #include "chrome/browser/chromeos/cros/network_library_impl_stub.h"
     18 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
     19 #include "chrome/common/net/x509_certificate_model.h"
     20 #include "chromeos/network/certificate_pattern.h"
     21 #include "chromeos/network/client_cert_util.h"
     22 #include "chromeos/network/cros_network_functions.h"
     23 #include "chromeos/network/network_state_handler.h"
     24 #include "chromeos/network/onc/onc_utils.h"
     25 #include "content/public/browser/browser_thread.h"
     26 #include "grit/ash_strings.h"
     27 #include "grit/generated_resources.h"
     28 #include "net/base/url_util.h"
     29 #include "third_party/cros_system_api/dbus/service_constants.h"
     30 #include "ui/base/l10n/l10n_util.h"
     31 
     32 using content::BrowserThread;
     33 
     34 ////////////////////////////////////////////////////////////////////////////////
     35 // Implementation notes.
     36 // NetworkLibraryImpl manages a series of classes that describe network devices
     37 // and services:
     38 //
     39 // NetworkDevice: e.g. ethernet, wifi modem, cellular modem
     40 //  device_map_: canonical map<path, NetworkDevice*> for devices
     41 //
     42 // Network: a network service ("network").
     43 //  network_map_: canonical map<path, Network*> for all visible networks.
     44 //  EthernetNetwork
     45 //   ethernet_: EthernetNetwork* to the active ethernet network in network_map_.
     46 //  WirelessNetwork: a WiFi or Cellular Network.
     47 //  WifiNetwork
     48 //   active_wifi_: WifiNetwork* to the active wifi network in network_map_.
     49 //   wifi_networks_: ordered vector of WifiNetwork* entries in network_map_,
     50 //       in descending order of importance.
     51 //  CellularNetwork
     52 //   active_cellular_: Cellular version of wifi_.
     53 //   cellular_networks_: Cellular version of wifi_.
     54 // network_unique_id_map_: map<unique_id, Network*> for all visible networks.
     55 // remembered_network_map_: a canonical map<path, Network*> for all networks
     56 //     remembered in the active Profile ("favorites").
     57 // remembered_network_unique_id_map_: map<unique_id, Network*> for all
     58 //     remembered networks.
     59 // remembered_wifi_networks_: ordered vector of WifiNetwork* entries in
     60 //     remembered_network_map_, in descending order of preference.
     61 // remembered_virtual_networks_: ordered vector of VirtualNetwork* entries in
     62 //     remembered_network_map_, in descending order of preference.
     63 //
     64 // network_manager_monitor_: a handle to the libcros network Manager handler.
     65 // NetworkManagerStatusChanged: This handles all messages from the Manager.
     66 //   Messages are parsed here and the appropriate updates are then requested.
     67 //
     68 // UpdateNetworkServiceList: This is the primary Manager handler. It handles
     69 //  the "Services" message which list all visible networks. The handler
     70 //  rebuilds the network lists without destroying existing Network structures,
     71 //  then requests neccessary updates to be fetched asynchronously from
     72 //  libcros (RequestNetworkServiceProperties).
     73 //
     74 // TODO(stevenjb): Document cellular data plan handlers.
     75 //
     76 // AddNetworkObserver: Adds an observer for a specific network.
     77 // UpdateNetworkStatus: This handles changes to a monitored service, typically
     78 //     changes to transient states like Strength. (Note: also updates State).
     79 //
     80 // AddNetworkDeviceObserver: Adds an observer for a specific device.
     81 //                           Will be called on any device property change.
     82 // UpdateNetworkDeviceStatus: Handles changes to a monitored device, like
     83 //     SIM lock state and updates device state.
     84 //
     85 // All *Pin(...) methods use internal callback that would update cellular
     86 //    device state once async call is completed and notify all device observers.
     87 //
     88 ////////////////////////////////////////////////////////////////////////////////
     89 
     90 namespace chromeos {
     91 
     92 namespace {
     93 
     94 static NetworkLibrary* g_network_library = NULL;
     95 
     96 // Default value of the SIM unlock retries count. It is updated to the real
     97 // retries count once cellular device with SIM card is initialized.
     98 // If cellular device doesn't have SIM card, then retries are never used.
     99 const int kDefaultSimUnlockRetriesCount = 999;
    100 
    101 ////////////////////////////////////////////////////////////////////////////////
    102 // Misc.
    103 
    104 // Erase the memory used by a string, then clear it.
    105 void WipeString(std::string* str) {
    106   str->assign(str->size(), '\0');
    107   str->clear();
    108 }
    109 
    110 bool EnsureRunningOnChromeOS() {
    111   if (!base::chromeos::IsRunningOnChromeOS()) {
    112     return false;
    113   } else {
    114     CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI))
    115         << "chromeos_network calls made from non UI thread!";
    116     return true;
    117   }
    118 }
    119 
    120 void ValidateUTF8(const std::string& str, std::string* output) {
    121   output->clear();
    122 
    123   for (int32 index = 0; index < static_cast<int32>(str.size()); ++index) {
    124     uint32 code_point_out;
    125     bool is_unicode_char = base::ReadUnicodeCharacter(str.c_str(), str.size(),
    126                                                       &index, &code_point_out);
    127     if (is_unicode_char && (code_point_out >= 0x20))
    128       base::WriteUnicodeCharacter(code_point_out, output);
    129     else
    130       // Puts REPLACEMENT CHARACTER (U+FFFD) if character is not readable UTF-8
    131       base::WriteUnicodeCharacter(0xFFFD, output);
    132   }
    133 }
    134 
    135 std::string ConnectionStateString(ConnectionState state) {
    136   switch (state) {
    137     case STATE_UNKNOWN:
    138       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_UNKNOWN);
    139     case STATE_IDLE:
    140       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_IDLE);
    141     case STATE_CARRIER:
    142       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_CARRIER);
    143     case STATE_ASSOCIATION:
    144       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_ASSOCIATION);
    145     case STATE_CONFIGURATION:
    146       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_CONFIGURATION);
    147     case STATE_READY:
    148       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_READY);
    149     case STATE_DISCONNECT:
    150       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_DISCONNECT);
    151     case STATE_FAILURE:
    152       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_FAILURE);
    153     case STATE_ACTIVATION_FAILURE:
    154       return l10n_util::GetStringUTF8(
    155           IDS_CHROMEOS_NETWORK_STATE_ACTIVATION_FAILURE);
    156     case STATE_PORTAL:
    157       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_PORTAL);
    158     case STATE_ONLINE:
    159       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_ONLINE);
    160     case STATE_CONNECT_REQUESTED:
    161       return l10n_util::GetStringUTF8(
    162           IDS_CHROMEOS_NETWORK_STATE_CONNECT_REQUESTED);
    163   }
    164   return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_UNRECOGNIZED);
    165 }
    166 
    167 }  // namespace
    168 
    169 ////////////////////////////////////////////////////////////////////////////////
    170 // FoundCellularNetwork
    171 
    172 FoundCellularNetwork::FoundCellularNetwork() {}
    173 
    174 FoundCellularNetwork::~FoundCellularNetwork() {}
    175 
    176 ////////////////////////////////////////////////////////////////////////////////
    177 // NetworkDevice
    178 
    179 NetworkDevice::NetworkDevice(const std::string& device_path)
    180     : device_path_(device_path),
    181       type_(TYPE_UNKNOWN),
    182       scanning_(false),
    183       sim_lock_state_(SIM_UNKNOWN),
    184       sim_retries_left_(kDefaultSimUnlockRetriesCount),
    185       sim_pin_required_(SIM_PIN_REQUIRE_UNKNOWN),
    186       sim_present_(false),
    187       powered_(false),
    188       prl_version_(0),
    189       data_roaming_allowed_(false),
    190       support_network_scan_(false),
    191       device_parser_(new NativeNetworkDeviceParser) {
    192 }
    193 
    194 NetworkDevice::~NetworkDevice() {}
    195 
    196 void NetworkDevice::SetNetworkDeviceParser(NetworkDeviceParser* parser) {
    197   device_parser_.reset(parser);
    198 }
    199 
    200 void NetworkDevice::ParseInfo(const DictionaryValue& info) {
    201   if (device_parser_.get())
    202     device_parser_->UpdateDeviceFromInfo(info, this);
    203 }
    204 
    205 bool NetworkDevice::UpdateStatus(const std::string& key,
    206                                  const base::Value& value,
    207                                  PropertyIndex* index) {
    208   if (device_parser_.get())
    209     return device_parser_->UpdateStatus(key, value, this, index);
    210   return false;
    211 }
    212 
    213 ////////////////////////////////////////////////////////////////////////////////
    214 // Network
    215 
    216 Network::Network(const std::string& service_path,
    217                  ConnectionType type)
    218     : state_(STATE_UNKNOWN),
    219       error_(ERROR_NO_ERROR),
    220       connectable_(true),
    221       user_connect_state_(USER_CONNECT_NONE),
    222       is_active_(false),
    223       priority_(kPriorityNotSet),
    224       auto_connect_(false),
    225       save_credentials_(false),
    226       priority_order_(0),
    227       added_(false),
    228       notify_failure_(false),
    229       profile_type_(PROFILE_NONE),
    230       service_path_(service_path),
    231       type_(type) {
    232 }
    233 
    234 Network::~Network() {
    235 }
    236 
    237 void Network::SetNetworkParser(NetworkParser* parser) {
    238   network_parser_.reset(parser);
    239 }
    240 
    241 // static
    242 Network* Network::CreateForTesting(ConnectionType type) {
    243   return new Network("fake_service_path", type);
    244 }
    245 
    246 void Network::SetState(ConnectionState new_state) {
    247   if (new_state == state_)
    248     return;
    249   if (state_ == STATE_CONNECT_REQUESTED && new_state == STATE_IDLE) {
    250     // CONNECT_REQUESTED is set internally. Shill does not update the
    251     // state immediately, so ignore any Idle state updates sent while a
    252     // connection attempt is in progress.
    253     VLOG(2) << "Ignoring idle state change after connection request.";
    254     return;
    255   }
    256   ConnectionState old_state = state_;
    257   VLOG(2) << "Entering new state: " << ConnectionStateString(new_state);
    258   state_ = new_state;
    259   if (new_state == STATE_FAILURE) {
    260     VLOG(1) << service_path() << ": Detected Failure state.";
    261     if (old_state != STATE_UNKNOWN && old_state != STATE_IDLE &&
    262         (type() != TYPE_CELLULAR ||
    263          user_connect_state() == USER_CONNECT_STARTED)) {
    264       // New failure, the user needs to be notified.
    265       // Transition STATE_IDLE -> STATE_FAILURE sometimes happens on resume
    266       // but is not an actual failure as network device is not ready yet.
    267       // For Cellular we only show failure notifications if user initiated.
    268       notify_failure_ = true;
    269       // Normally error_ should be set, but if it is not we need to set it to
    270       // something here so that the retry logic will be triggered.
    271       if (error_ == ERROR_NO_ERROR) {
    272         VLOG(2) << "Detected NO_ERROR error state.  Setting to UNKNOWN.";
    273         error_ = ERROR_UNKNOWN;
    274       }
    275     }
    276     if (user_connect_state() == USER_CONNECT_STARTED)
    277       set_user_connect_state(USER_CONNECT_FAILED);
    278   } else if (new_state == STATE_IDLE && IsConnectingState(old_state) &&
    279              user_connect_state() == USER_CONNECT_STARTED) {
    280     // If we requested a connect and never went through a connected state,
    281     // treat it as a failure.
    282     VLOG(1) << service_path() << ": Inferring Failure state.";
    283     notify_failure_ = true;
    284     error_ = ERROR_UNKNOWN;
    285     if (user_connect_state() == USER_CONNECT_STARTED)
    286       set_user_connect_state(USER_CONNECT_FAILED);
    287   } else if (new_state != STATE_UNKNOWN) {
    288     notify_failure_ = false;
    289     // State changed, so refresh IP address.
    290     InitIPAddress();
    291     if (user_connect_state() == USER_CONNECT_STARTED) {
    292       if (IsConnectedState(new_state)) {
    293         set_user_connect_state(USER_CONNECT_CONNECTED);
    294       } else if (!IsConnectingState(new_state)) {
    295         LOG(WARNING) << "Connection started and State -> " << GetStateString();
    296         set_user_connect_state(USER_CONNECT_FAILED);
    297       }
    298     }
    299   }
    300   VLOG(1) << name() << ".State [" << service_path() << "]: " << GetStateString()
    301           << " (was: " << ConnectionStateString(old_state) << ")";
    302 }
    303 
    304 void Network::SetError(ConnectionError error) {
    305   error_ = error;
    306   if (error == ERROR_NO_ERROR)
    307     notify_failure_ = false;
    308 }
    309 
    310 void Network::SetName(const std::string& name) {
    311   std::string name_utf8;
    312   ValidateUTF8(name, &name_utf8);
    313   set_name(name_utf8);
    314 }
    315 
    316 void Network::ParseInfo(const DictionaryValue& info) {
    317   if (network_parser_.get())
    318     network_parser_->UpdateNetworkFromInfo(info, this);
    319 }
    320 
    321 void Network::EraseCredentials() {
    322 }
    323 
    324 void Network::CalculateUniqueId() {
    325   unique_id_ = name_;
    326 }
    327 
    328 bool Network::RequiresUserProfile() const {
    329   return false;
    330 }
    331 
    332 void Network::CopyCredentialsFromRemembered(Network* remembered) {
    333 }
    334 
    335 void Network::SetEnrollmentDelegate(EnrollmentDelegate* delegate) {
    336   enrollment_delegate_.reset(delegate);
    337 }
    338 
    339 void Network::SetValueProperty(const char* prop, const base::Value& value) {
    340   DCHECK(prop);
    341   if (!EnsureRunningOnChromeOS())
    342     return;
    343   CrosSetNetworkServiceProperty(service_path_, prop, value);
    344   // Ensure NetworkStateHandler properties are up-to-date.
    345   if (NetworkHandler::IsInitialized()) {
    346     NetworkHandler::Get()->network_state_handler()->RequestUpdateForNetwork(
    347         service_path());
    348   }
    349 }
    350 
    351 void Network::ClearProperty(const char* prop) {
    352   DCHECK(prop);
    353   if (!EnsureRunningOnChromeOS())
    354     return;
    355   CrosClearNetworkServiceProperty(service_path_, prop);
    356   // Ensure NetworkStateHandler properties are up-to-date.
    357   if (NetworkHandler::IsInitialized()) {
    358     NetworkHandler::Get()->network_state_handler()->RequestUpdateForNetwork(
    359         service_path());
    360   }
    361 }
    362 
    363 void Network::SetStringProperty(
    364     const char* prop, const std::string& str, std::string* dest) {
    365   if (dest)
    366     *dest = str;
    367   SetValueProperty(prop, base::StringValue(str));
    368 }
    369 
    370 void Network::SetOrClearStringProperty(const char* prop,
    371                                        const std::string& str,
    372                                        std::string* dest) {
    373   if (str.empty()) {
    374     ClearProperty(prop);
    375     if (dest)
    376       dest->clear();
    377   } else {
    378     SetStringProperty(prop, str, dest);
    379   }
    380 }
    381 
    382 void Network::SetBooleanProperty(const char* prop, bool b, bool* dest) {
    383   if (dest)
    384     *dest = b;
    385   SetValueProperty(prop, base::FundamentalValue(b));
    386 }
    387 
    388 void Network::SetIntegerProperty(const char* prop, int i, int* dest) {
    389   if (dest)
    390     *dest = i;
    391   SetValueProperty(prop, base::FundamentalValue(i));
    392 }
    393 
    394 void Network::SetPreferred(bool preferred) {
    395   if (preferred) {
    396     SetIntegerProperty(
    397         flimflam::kPriorityProperty, kPriorityPreferred, &priority_);
    398   } else {
    399     ClearProperty(flimflam::kPriorityProperty);
    400     priority_ = kPriorityNotSet;
    401   }
    402 }
    403 
    404 void Network::SetAutoConnect(bool auto_connect) {
    405   SetBooleanProperty(
    406       flimflam::kAutoConnectProperty, auto_connect, &auto_connect_);
    407 }
    408 
    409 void Network::SetSaveCredentials(bool save_credentials) {
    410   SetBooleanProperty(
    411       flimflam::kSaveCredentialsProperty, save_credentials, &save_credentials_);
    412 }
    413 
    414 void Network::ClearUIData() {
    415   ui_data_ = NetworkUIData();
    416   ClearProperty(flimflam::kUIDataProperty);
    417 }
    418 
    419 void Network::AttemptConnection(const base::Closure& closure) {
    420   // By default, just invoke the closure right away.  Some subclasses
    421   // (Wifi, VPN, etc.) override to do more work.
    422   closure.Run();
    423 }
    424 
    425 void Network::set_connecting() {
    426   state_ = STATE_CONNECT_REQUESTED;
    427 }
    428 
    429 void Network::SetProfilePath(const std::string& profile_path) {
    430   VLOG(1) << "Setting profile for: " << name_ << " to: " << profile_path;
    431   SetOrClearStringProperty(
    432       flimflam::kProfileProperty, profile_path, &profile_path_);
    433 }
    434 
    435 std::string Network::GetStateString() const {
    436   return ConnectionStateString(state_);
    437 }
    438 
    439 std::string Network::GetErrorString() const {
    440   switch (error_) {
    441     case ERROR_NO_ERROR:
    442       // TODO(nkostylev): Introduce new error message "None" instead.
    443       return std::string();
    444     case ERROR_OUT_OF_RANGE:
    445       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_OUT_OF_RANGE);
    446     case ERROR_PIN_MISSING:
    447       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_PIN_MISSING);
    448     case ERROR_DHCP_FAILED:
    449       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_DHCP_FAILED);
    450     case ERROR_CONNECT_FAILED:
    451       return l10n_util::GetStringUTF8(
    452           IDS_CHROMEOS_NETWORK_ERROR_CONNECT_FAILED);
    453     case ERROR_BAD_PASSPHRASE:
    454       return l10n_util::GetStringUTF8(
    455           IDS_CHROMEOS_NETWORK_ERROR_BAD_PASSPHRASE);
    456     case ERROR_BAD_WEPKEY:
    457       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_BAD_WEPKEY);
    458     case ERROR_ACTIVATION_FAILED:
    459       return l10n_util::GetStringUTF8(
    460           IDS_CHROMEOS_NETWORK_ERROR_ACTIVATION_FAILED);
    461     case ERROR_NEED_EVDO:
    462       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_NEED_EVDO);
    463     case ERROR_NEED_HOME_NETWORK:
    464       return l10n_util::GetStringUTF8(
    465           IDS_CHROMEOS_NETWORK_ERROR_NEED_HOME_NETWORK);
    466     case ERROR_OTASP_FAILED:
    467       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_OTASP_FAILED);
    468     case ERROR_AAA_FAILED:
    469       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_AAA_FAILED);
    470     case ERROR_INTERNAL:
    471       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_INTERNAL);
    472     case ERROR_DNS_LOOKUP_FAILED:
    473       return l10n_util::GetStringUTF8(
    474           IDS_CHROMEOS_NETWORK_ERROR_DNS_LOOKUP_FAILED);
    475     case ERROR_HTTP_GET_FAILED:
    476       return l10n_util::GetStringUTF8(
    477           IDS_CHROMEOS_NETWORK_ERROR_HTTP_GET_FAILED);
    478     case ERROR_IPSEC_PSK_AUTH_FAILED:
    479       return l10n_util::GetStringUTF8(
    480           IDS_CHROMEOS_NETWORK_ERROR_IPSEC_PSK_AUTH_FAILED);
    481     case ERROR_IPSEC_CERT_AUTH_FAILED:
    482       return l10n_util::GetStringUTF8(
    483           IDS_CHROMEOS_NETWORK_ERROR_CERT_AUTH_FAILED);
    484     case ERROR_PPP_AUTH_FAILED:
    485     case ERROR_EAP_AUTHENTICATION_FAILED:
    486     case ERROR_EAP_LOCAL_TLS_FAILED:
    487     case ERROR_EAP_REMOTE_TLS_FAILED:
    488       return l10n_util::GetStringUTF8(
    489           IDS_CHROMEOS_NETWORK_ERROR_PPP_AUTH_FAILED);
    490     case ERROR_UNKNOWN:
    491       return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_ERROR_UNKNOWN);
    492   }
    493   return l10n_util::GetStringUTF8(IDS_CHROMEOS_NETWORK_STATE_UNRECOGNIZED);
    494 }
    495 
    496 void Network::InitIPAddress() {
    497   ip_address_.clear();
    498   if (!EnsureRunningOnChromeOS())
    499     return;
    500   // If connected, get IPConfig.
    501   if (connected() && !device_path_.empty()) {
    502     CrosListIPConfigs(device_path_,
    503                       base::Bind(&Network::InitIPAddressCallback,
    504                                  service_path_));
    505   }
    506 }
    507 
    508 // static
    509 void Network::InitIPAddressCallback(
    510     const std::string& service_path,
    511     const NetworkIPConfigVector& ip_configs,
    512     const std::string& hardware_address) {
    513   Network* network =
    514       NetworkLibrary::Get()->FindNetworkByPath(service_path);
    515   if (!network)
    516     return;
    517   for (size_t i = 0; i < ip_configs.size(); ++i) {
    518     const NetworkIPConfig& ipconfig = ip_configs[i];
    519     if (ipconfig.address.size() > 0) {
    520       network->ip_address_ = ipconfig.address;
    521       break;
    522     }
    523   }
    524 }
    525 
    526 bool Network::UpdateStatus(const std::string& key,
    527                            const Value& value,
    528                            PropertyIndex* index) {
    529   if (network_parser_.get())
    530     return network_parser_->UpdateStatus(key, value, this, index);
    531   return false;
    532 }
    533 
    534 ////////////////////////////////////////////////////////////////////////////////
    535 // EthernetNetwork
    536 
    537 EthernetNetwork::EthernetNetwork(const std::string& service_path)
    538     : Network(service_path, TYPE_ETHERNET) {
    539 }
    540 
    541 ////////////////////////////////////////////////////////////////////////////////
    542 // VirtualNetwork
    543 
    544 VirtualNetwork::VirtualNetwork(const std::string& service_path)
    545     : Network(service_path, TYPE_VPN),
    546       provider_type_(PROVIDER_TYPE_L2TP_IPSEC_PSK),
    547       // Assume PSK and user passphrase are not available initially
    548       psk_passphrase_required_(true),
    549       user_passphrase_required_(true),
    550       weak_pointer_factory_(this) {
    551 }
    552 
    553 VirtualNetwork::~VirtualNetwork() {}
    554 
    555 void VirtualNetwork::EraseCredentials() {
    556   WipeString(&ca_cert_pem_);
    557   WipeString(&psk_passphrase_);
    558   WipeString(&client_cert_id_);
    559   WipeString(&user_passphrase_);
    560 }
    561 
    562 void VirtualNetwork::CalculateUniqueId() {
    563   std::string provider_type(ProviderTypeToString(provider_type_));
    564   set_unique_id(provider_type + "|" + server_hostname_);
    565 }
    566 
    567 bool VirtualNetwork::RequiresUserProfile() const {
    568   return true;
    569 }
    570 
    571 void VirtualNetwork::AttemptConnection(const base::Closure& connect) {
    572   if (client_cert_type() == CLIENT_CERT_TYPE_PATTERN) {
    573     MatchCertificatePattern(true, connect);
    574   } else {
    575     connect.Run();
    576   }
    577 }
    578 
    579 void VirtualNetwork::CopyCredentialsFromRemembered(Network* remembered) {
    580   CHECK_EQ(remembered->type(), TYPE_VPN);
    581   VirtualNetwork* remembered_vpn = static_cast<VirtualNetwork*>(remembered);
    582   VLOG(1) << "Copy VPN credentials: " << name()
    583           << " username: " << remembered_vpn->username();
    584   if (ca_cert_pem_.empty())
    585     ca_cert_pem_ = remembered_vpn->ca_cert_pem();
    586   if (psk_passphrase_.empty())
    587     psk_passphrase_ = remembered_vpn->psk_passphrase();
    588   if (client_cert_id_.empty())
    589     client_cert_id_ = remembered_vpn->client_cert_id();
    590   if (username_.empty())
    591     username_ = remembered_vpn->username();
    592   if (user_passphrase_.empty())
    593     user_passphrase_ = remembered_vpn->user_passphrase();
    594 }
    595 
    596 bool VirtualNetwork::NeedMoreInfoToConnect() const {
    597   if (server_hostname_.empty()) {
    598     VLOG(1) << "server_hostname_.empty()";
    599     return true;
    600   }
    601   if (username_.empty()) {
    602     VLOG(1) << "username_.empty()";
    603     return true;
    604   }
    605   if (IsUserPassphraseRequired()) {
    606     VLOG(1) << "User Passphrase Required";
    607     return true;
    608   }
    609   if (error() != ERROR_NO_ERROR) {
    610     VLOG(1) << "Error: " << error();
    611     return true;
    612   }
    613   switch (provider_type_) {
    614     case PROVIDER_TYPE_L2TP_IPSEC_PSK:
    615       if (IsPSKPassphraseRequired()) {
    616         VLOG(1) << "PSK Passphrase Required";
    617         return true;
    618       }
    619       break;
    620     case PROVIDER_TYPE_L2TP_IPSEC_USER_CERT:
    621       if (client_cert_id_.empty() &&
    622           client_cert_type() != CLIENT_CERT_TYPE_PATTERN) {
    623         VLOG(1) << "Certificate Required";
    624         return true;
    625       }
    626       break;
    627     case PROVIDER_TYPE_OPEN_VPN:
    628       if (client_cert_id_.empty()) {
    629         VLOG(1) << "client_cert_id_.empty()";
    630         return true;
    631       }
    632       // For now we always need additional info for OpenVPN.
    633       // TODO(stevenjb): Check connectable() once shill sets that state
    634       // properly, or define another mechanism to determine when additional
    635       // credentials are required.
    636       VLOG(1) << "OpenVPN requires credentials, connectable: "
    637               << connectable();
    638       return true;
    639       break;
    640     case PROVIDER_TYPE_MAX:
    641       NOTREACHED();
    642       break;
    643   }
    644   return false;
    645 }
    646 
    647 std::string VirtualNetwork::GetProviderTypeString() const {
    648   switch (provider_type_) {
    649     case PROVIDER_TYPE_L2TP_IPSEC_PSK:
    650       return l10n_util::GetStringUTF8(
    651           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_PSK);
    652       break;
    653     case PROVIDER_TYPE_L2TP_IPSEC_USER_CERT:
    654       return l10n_util::GetStringUTF8(
    655           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_L2TP_IPSEC_USER_CERT);
    656       break;
    657     case PROVIDER_TYPE_OPEN_VPN:
    658       return l10n_util::GetStringUTF8(
    659           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_OPEN_VPN);
    660       break;
    661     default:
    662       return l10n_util::GetStringUTF8(
    663           IDS_CHROMEOS_NETWORK_ERROR_UNKNOWN);
    664       break;
    665   }
    666 }
    667 
    668 bool VirtualNetwork::IsPSKPassphraseRequired() const {
    669   return psk_passphrase_required_ && psk_passphrase_.empty();
    670 }
    671 
    672 bool VirtualNetwork::IsUserPassphraseRequired() const {
    673   return user_passphrase_required_ && user_passphrase_.empty();
    674 }
    675 
    676 void VirtualNetwork::SetCACertPEM(const std::string& ca_cert_pem) {
    677   VLOG(1) << "SetCACertPEM " << ca_cert_pem;
    678   if (provider_type_ == PROVIDER_TYPE_OPEN_VPN) {
    679     ca_cert_pem_ = ca_cert_pem;
    680     base::ListValue pem_list;
    681     pem_list.AppendString(ca_cert_pem_);
    682     SetValueProperty(shill::kOpenVPNCaCertPemProperty, pem_list);
    683   } else {
    684     SetStringProperty(
    685         shill::kL2tpIpsecCaCertPemProperty, ca_cert_pem, &ca_cert_pem_);
    686   }
    687 }
    688 
    689 void VirtualNetwork::SetL2TPIPsecPSKCredentials(
    690     const std::string& psk_passphrase,
    691     const std::string& username,
    692     const std::string& user_passphrase,
    693     const std::string& group_name) {
    694   if (!psk_passphrase.empty()) {
    695     SetStringProperty(flimflam::kL2tpIpsecPskProperty,
    696                       psk_passphrase, &psk_passphrase_);
    697   }
    698   SetStringProperty(flimflam::kL2tpIpsecUserProperty, username, &username_);
    699   if (!user_passphrase.empty()) {
    700     SetStringProperty(flimflam::kL2tpIpsecPasswordProperty,
    701                       user_passphrase, &user_passphrase_);
    702   }
    703   SetStringProperty(shill::kL2tpIpsecTunnelGroupProperty,
    704                     group_name, &group_name_);
    705 }
    706 
    707 void VirtualNetwork::SetL2TPIPsecCertCredentials(
    708     const std::string& client_cert_id,
    709     const std::string& username,
    710     const std::string& user_passphrase,
    711     const std::string& group_name) {
    712   SetStringProperty(flimflam::kL2tpIpsecClientCertIdProperty,
    713                     client_cert_id, &client_cert_id_);
    714   SetStringProperty(flimflam::kL2tpIpsecUserProperty, username, &username_);
    715   if (!user_passphrase.empty()) {
    716     SetStringProperty(flimflam::kL2tpIpsecPasswordProperty,
    717                       user_passphrase, &user_passphrase_);
    718   }
    719   SetStringProperty(shill::kL2tpIpsecTunnelGroupProperty,
    720                     group_name, &group_name_);
    721 }
    722 
    723 void VirtualNetwork::SetOpenVPNCredentials(
    724     const std::string& client_cert_id,
    725     const std::string& username,
    726     const std::string& user_passphrase,
    727     const std::string& otp) {
    728   SetStringProperty(flimflam::kOpenVPNClientCertIdProperty,
    729                     client_cert_id, &client_cert_id_);
    730   SetStringProperty(flimflam::kOpenVPNUserProperty, username, &username_);
    731   if (!user_passphrase.empty()) {
    732     SetStringProperty(flimflam::kOpenVPNPasswordProperty,
    733                       user_passphrase, &user_passphrase_);
    734   }
    735   SetStringProperty(flimflam::kOpenVPNOTPProperty, otp, NULL);
    736 }
    737 
    738 void VirtualNetwork::SetServerHostname(const std::string& server_hostname) {
    739   SetStringProperty(flimflam::kProviderHostProperty,
    740                     server_hostname, &server_hostname_);
    741 }
    742 
    743 void VirtualNetwork::SetCertificateSlotAndPin(
    744     const std::string& slot, const std::string& pin) {
    745   if (provider_type() == PROVIDER_TYPE_OPEN_VPN) {
    746     SetOrClearStringProperty(flimflam::kOpenVPNClientCertSlotProperty,
    747                              slot, NULL);
    748     SetOrClearStringProperty(flimflam::kOpenVPNPinProperty, pin, NULL);
    749   } else {
    750     SetOrClearStringProperty(flimflam::kL2tpIpsecClientCertSlotProperty,
    751                              slot, NULL);
    752     SetOrClearStringProperty(flimflam::kL2tpIpsecPinProperty, pin, NULL);
    753   }
    754 }
    755 
    756 void VirtualNetwork::MatchCertificatePattern(bool allow_enroll,
    757                                              const base::Closure& connect) {
    758   DCHECK(client_cert_type() == CLIENT_CERT_TYPE_PATTERN);
    759   DCHECK(!client_cert_pattern().Empty());
    760 
    761   // We skip certificate patterns for device policy ONC so that an unmanaged
    762   // user can't get to the place where a cert is presented for them
    763   // involuntarily.
    764   if (client_cert_pattern().Empty() ||
    765       ui_data().onc_source() == onc::ONC_SOURCE_DEVICE_POLICY) {
    766     connect.Run();
    767     return;
    768   }
    769 
    770   scoped_refptr<net::X509Certificate> matching_cert =
    771       client_cert::GetCertificateMatch(client_cert_pattern());
    772   if (matching_cert.get()) {
    773     std::string client_cert_id =
    774         x509_certificate_model::GetPkcs11Id(matching_cert->os_cert_handle());
    775     if (provider_type() == PROVIDER_TYPE_OPEN_VPN) {
    776       SetStringProperty(flimflam::kOpenVPNClientCertIdProperty,
    777                         client_cert_id, &client_cert_id_);
    778     } else {
    779       SetStringProperty(flimflam::kL2tpIpsecClientCertIdProperty,
    780                         client_cert_id, &client_cert_id_);
    781     }
    782   } else {
    783     if (allow_enroll && enrollment_delegate()) {
    784       // Wrap the closure in another callback so that we can retry the
    785       // certificate match again before actually connecting.
    786       base::Closure wrapped_connect =
    787           base::Bind(&VirtualNetwork::MatchCertificatePattern,
    788                      weak_pointer_factory_.GetWeakPtr(),
    789                      false,
    790                      connect);
    791 
    792       enrollment_delegate()->Enroll(client_cert_pattern().enrollment_uri_list(),
    793                                     wrapped_connect);
    794       // Enrollment delegate will take care of running the closure at the
    795       // appropriate time, if the user doesn't cancel.
    796       return;
    797     }
    798   }
    799   connect.Run();
    800 }
    801 
    802 ////////////////////////////////////////////////////////////////////////////////
    803 // WirelessNetwork
    804 
    805 ////////////////////////////////////////////////////////////////////////////////
    806 // CellTower
    807 
    808 CellTower::CellTower() {}
    809 
    810 ////////////////////////////////////////////////////////////////////////////////
    811 // CellularApn
    812 
    813 CellularApn::CellularApn() {}
    814 
    815 CellularApn::CellularApn(
    816     const std::string& apn, const std::string& network_id,
    817     const std::string& username, const std::string& password)
    818     : apn(apn), network_id(network_id),
    819       username(username), password(password) {
    820 }
    821 
    822 CellularApn::~CellularApn() {}
    823 
    824 void CellularApn::Set(const DictionaryValue& dict) {
    825   if (!dict.GetStringWithoutPathExpansion(flimflam::kApnProperty, &apn))
    826     apn.clear();
    827   if (!dict.GetStringWithoutPathExpansion(flimflam::kApnNetworkIdProperty,
    828                                           &network_id))
    829     network_id.clear();
    830   if (!dict.GetStringWithoutPathExpansion(flimflam::kApnUsernameProperty,
    831                                           &username))
    832     username.clear();
    833   if (!dict.GetStringWithoutPathExpansion(flimflam::kApnPasswordProperty,
    834                                           &password))
    835     password.clear();
    836   if (!dict.GetStringWithoutPathExpansion(flimflam::kApnNameProperty, &name))
    837     name.clear();
    838   if (!dict.GetStringWithoutPathExpansion(flimflam::kApnLocalizedNameProperty,
    839                                           &localized_name))
    840     localized_name.clear();
    841   if (!dict.GetStringWithoutPathExpansion(flimflam::kApnLanguageProperty,
    842                                           &language))
    843     language.clear();
    844 }
    845 
    846 ////////////////////////////////////////////////////////////////////////////////
    847 // CellularNetwork
    848 
    849 CellularNetwork::CellularNetwork(const std::string& service_path)
    850     : WirelessNetwork(service_path, TYPE_CELLULAR),
    851       activate_over_non_cellular_network_(false),
    852       out_of_credits_(false),
    853       activation_state_(ACTIVATION_STATE_UNKNOWN),
    854       network_technology_(NETWORK_TECHNOLOGY_UNKNOWN),
    855       roaming_state_(ROAMING_STATE_UNKNOWN),
    856       using_post_(false) {
    857 }
    858 
    859 CellularNetwork::~CellularNetwork() {
    860 }
    861 
    862 bool CellularNetwork::StartActivation() {
    863   if (!EnsureRunningOnChromeOS())
    864     return false;
    865   if (!CrosActivateCellularModem(service_path(), ""))
    866     return false;
    867   // Don't wait for shill to tell us that we are really activating since
    868   // other notifications in the message loop might cause us to think that
    869   // the process hasn't started yet.
    870   activation_state_ = ACTIVATION_STATE_ACTIVATING;
    871   return true;
    872 }
    873 
    874 void CellularNetwork::CompleteActivation() {
    875   if (!EnsureRunningOnChromeOS())
    876     return;
    877   CrosCompleteCellularActivation(service_path());
    878 }
    879 
    880 void CellularNetwork::SetApn(const CellularApn& apn) {
    881   if (!apn.apn.empty()) {
    882     DictionaryValue value;
    883     // Only use the fields that are needed for establishing
    884     // connections, and ignore the rest.
    885     value.SetString(flimflam::kApnProperty, apn.apn);
    886     value.SetString(flimflam::kApnNetworkIdProperty, apn.network_id);
    887     value.SetString(flimflam::kApnUsernameProperty, apn.username);
    888     value.SetString(flimflam::kApnPasswordProperty, apn.password);
    889     SetValueProperty(flimflam::kCellularApnProperty, value);
    890   } else {
    891     ClearProperty(flimflam::kCellularApnProperty);
    892   }
    893 }
    894 
    895 bool CellularNetwork::SupportsActivation() const {
    896   return !usage_url().empty() || !payment_url().empty();
    897 }
    898 
    899 bool CellularNetwork::NeedsActivation() const {
    900   return (activation_state() == ACTIVATION_STATE_NOT_ACTIVATED ||
    901           activation_state() == ACTIVATION_STATE_PARTIALLY_ACTIVATED);
    902 }
    903 
    904 std::string CellularNetwork::GetNetworkTechnologyString() const {
    905   // No need to localize these cellular technology abbreviations.
    906   switch (network_technology_) {
    907     case NETWORK_TECHNOLOGY_1XRTT:
    908       return "1xRTT";
    909       break;
    910     case NETWORK_TECHNOLOGY_EVDO:
    911       return "EVDO";
    912       break;
    913     case NETWORK_TECHNOLOGY_GPRS:
    914       return "GPRS";
    915       break;
    916     case NETWORK_TECHNOLOGY_EDGE:
    917       return "EDGE";
    918       break;
    919     case NETWORK_TECHNOLOGY_UMTS:
    920       return "UMTS";
    921       break;
    922     case NETWORK_TECHNOLOGY_HSPA:
    923       return "HSPA";
    924       break;
    925     case NETWORK_TECHNOLOGY_HSPA_PLUS:
    926       return "HSPA Plus";
    927       break;
    928     case NETWORK_TECHNOLOGY_LTE:
    929       return "LTE";
    930       break;
    931     case NETWORK_TECHNOLOGY_LTE_ADVANCED:
    932       return "LTE Advanced";
    933       break;
    934     case NETWORK_TECHNOLOGY_GSM:
    935       return "GSM";
    936       break;
    937     default:
    938       return l10n_util::GetStringUTF8(
    939           IDS_CHROMEOS_NETWORK_CELLULAR_TECHNOLOGY_UNKNOWN);
    940       break;
    941   }
    942 }
    943 
    944 std::string CellularNetwork::ActivationStateToString(
    945     ActivationState activation_state) {
    946   switch (activation_state) {
    947     case ACTIVATION_STATE_ACTIVATED:
    948       return l10n_util::GetStringUTF8(
    949           IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATED);
    950       break;
    951     case ACTIVATION_STATE_ACTIVATING:
    952       return l10n_util::GetStringUTF8(
    953           IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_ACTIVATING);
    954       break;
    955     case ACTIVATION_STATE_NOT_ACTIVATED:
    956       return l10n_util::GetStringUTF8(
    957           IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_NOT_ACTIVATED);
    958       break;
    959     case ACTIVATION_STATE_PARTIALLY_ACTIVATED:
    960       return l10n_util::GetStringUTF8(
    961           IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_PARTIALLY_ACTIVATED);
    962       break;
    963     default:
    964       return l10n_util::GetStringUTF8(
    965           IDS_CHROMEOS_NETWORK_ACTIVATION_STATE_UNKNOWN);
    966       break;
    967   }
    968 }
    969 
    970 std::string CellularNetwork::GetActivationStateString() const {
    971   return ActivationStateToString(this->activation_state_);
    972 }
    973 
    974 std::string CellularNetwork::GetRoamingStateString() const {
    975   switch (this->roaming_state_) {
    976     case ROAMING_STATE_HOME:
    977       return l10n_util::GetStringUTF8(
    978           IDS_CHROMEOS_NETWORK_ROAMING_STATE_HOME);
    979       break;
    980     case ROAMING_STATE_ROAMING:
    981       return l10n_util::GetStringUTF8(
    982           IDS_CHROMEOS_NETWORK_ROAMING_STATE_ROAMING);
    983       break;
    984     default:
    985       return l10n_util::GetStringUTF8(
    986           IDS_CHROMEOS_NETWORK_ROAMING_STATE_UNKNOWN);
    987       break;
    988   }
    989 }
    990 
    991 ////////////////////////////////////////////////////////////////////////////////
    992 // WifiNetwork
    993 
    994 WifiNetwork::WifiNetwork(const std::string& service_path)
    995     : WirelessNetwork(service_path, TYPE_WIFI),
    996       encryption_(SECURITY_NONE),
    997       passphrase_required_(false),
    998       hidden_ssid_(false),
    999       frequency_(0),
   1000       eap_method_(EAP_METHOD_UNKNOWN),
   1001       eap_phase_2_auth_(EAP_PHASE_2_AUTH_AUTO),
   1002       eap_use_system_cas_(true),
   1003       eap_save_credentials_(false),
   1004       weak_pointer_factory_(this) {
   1005 }
   1006 
   1007 WifiNetwork::~WifiNetwork() {}
   1008 
   1009 void WifiNetwork::CalculateUniqueId() {
   1010   ConnectionSecurity encryption = encryption_;
   1011   // Shill treats wpa and rsn as psk internally, so convert those types
   1012   // to psk for unique naming.
   1013   if (encryption == SECURITY_WPA || encryption == SECURITY_RSN)
   1014     encryption = SECURITY_PSK;
   1015   std::string security = std::string(SecurityToString(encryption));
   1016   set_unique_id(security + "|" + name());
   1017 }
   1018 
   1019 bool WifiNetwork::SetSsid(const std::string& ssid) {
   1020   // Detects encoding and convert to UTF-8.
   1021   std::string ssid_utf8;
   1022   if (!IsStringUTF8(ssid)) {
   1023     std::string encoding;
   1024     if (base::DetectEncoding(ssid, &encoding)) {
   1025       if (!base::ConvertToUtf8AndNormalize(ssid, encoding, &ssid_utf8)) {
   1026         ssid_utf8.clear();
   1027       }
   1028     }
   1029   }
   1030 
   1031   if (ssid_utf8.empty())
   1032     SetName(ssid);
   1033   else
   1034     SetName(ssid_utf8);
   1035 
   1036   return true;
   1037 }
   1038 
   1039 bool WifiNetwork::SetHexSsid(const std::string& ssid_hex) {
   1040   // Converts ascii hex dump (eg. "49656c6c6f") to string (eg. "Hello").
   1041   std::vector<uint8> ssid_raw;
   1042   if (!base::HexStringToBytes(ssid_hex, &ssid_raw)) {
   1043     LOG(ERROR) << "Illegal hex char is found in WiFi.HexSSID.";
   1044     ssid_raw.clear();
   1045     return false;
   1046   }
   1047 
   1048   return SetSsid(std::string(ssid_raw.begin(), ssid_raw.end()));
   1049 }
   1050 
   1051 const std::string& WifiNetwork::GetPassphrase() const {
   1052   if (!user_passphrase_.empty())
   1053     return user_passphrase_;
   1054   return passphrase_;
   1055 }
   1056 
   1057 void WifiNetwork::SetPassphrase(const std::string& passphrase) {
   1058   // Set the user_passphrase_ only; passphrase_ stores the shill value.
   1059   // If the user sets an empty passphrase, restore it to the passphrase
   1060   // remembered by shill.
   1061   if (!passphrase.empty()) {
   1062     user_passphrase_ = passphrase;
   1063     passphrase_ = passphrase;
   1064   } else {
   1065     user_passphrase_ = passphrase_;
   1066   }
   1067   // Send the change to shill. If the format is valid, it will propagate to
   1068   // passphrase_ with a service update.
   1069   SetOrClearStringProperty(flimflam::kPassphraseProperty, passphrase, NULL);
   1070 }
   1071 
   1072 // See src/third_party/shill/doc/service-api.txt for properties that
   1073 // shill will forget when SaveCredentials is false.
   1074 void WifiNetwork::EraseCredentials() {
   1075   WipeString(&passphrase_);
   1076   WipeString(&user_passphrase_);
   1077   WipeString(&eap_server_ca_cert_pem_);
   1078   WipeString(&eap_client_cert_pkcs11_id_);
   1079   WipeString(&eap_identity_);
   1080   WipeString(&eap_anonymous_identity_);
   1081   WipeString(&eap_passphrase_);
   1082 }
   1083 
   1084 void WifiNetwork::SetEAPMethod(EAPMethod method) {
   1085   eap_method_ = method;
   1086   switch (method) {
   1087     case EAP_METHOD_PEAP:
   1088       SetStringProperty(
   1089           flimflam::kEapMethodProperty, flimflam::kEapMethodPEAP, NULL);
   1090       break;
   1091     case EAP_METHOD_TLS:
   1092       SetStringProperty(
   1093           flimflam::kEapMethodProperty, flimflam::kEapMethodTLS, NULL);
   1094       break;
   1095     case EAP_METHOD_TTLS:
   1096       SetStringProperty(
   1097           flimflam::kEapMethodProperty, flimflam::kEapMethodTTLS, NULL);
   1098       break;
   1099     case EAP_METHOD_LEAP:
   1100       SetStringProperty(
   1101           flimflam::kEapMethodProperty, flimflam::kEapMethodLEAP, NULL);
   1102       break;
   1103     default:
   1104       ClearProperty(flimflam::kEapMethodProperty);
   1105       break;
   1106   }
   1107 }
   1108 
   1109 void WifiNetwork::SetEAPPhase2Auth(EAPPhase2Auth auth) {
   1110   eap_phase_2_auth_ = auth;
   1111   bool is_peap = (eap_method_ == EAP_METHOD_PEAP);
   1112   switch (auth) {
   1113     case EAP_PHASE_2_AUTH_AUTO:
   1114       ClearProperty(flimflam::kEapPhase2AuthProperty);
   1115       break;
   1116     case EAP_PHASE_2_AUTH_MD5:
   1117       SetStringProperty(flimflam::kEapPhase2AuthProperty,
   1118                         is_peap ? flimflam::kEapPhase2AuthPEAPMD5
   1119                                 : flimflam::kEapPhase2AuthTTLSMD5,
   1120                         NULL);
   1121       break;
   1122     case EAP_PHASE_2_AUTH_MSCHAPV2:
   1123       SetStringProperty(flimflam::kEapPhase2AuthProperty,
   1124                         is_peap ? flimflam::kEapPhase2AuthPEAPMSCHAPV2
   1125                                 : flimflam::kEapPhase2AuthTTLSMSCHAPV2,
   1126                         NULL);
   1127       break;
   1128     case EAP_PHASE_2_AUTH_MSCHAP:
   1129       SetStringProperty(flimflam::kEapPhase2AuthProperty,
   1130                         flimflam::kEapPhase2AuthTTLSMSCHAP, NULL);
   1131       break;
   1132     case EAP_PHASE_2_AUTH_PAP:
   1133       SetStringProperty(flimflam::kEapPhase2AuthProperty,
   1134                         flimflam::kEapPhase2AuthTTLSPAP, NULL);
   1135       break;
   1136     case EAP_PHASE_2_AUTH_CHAP:
   1137       SetStringProperty(flimflam::kEapPhase2AuthProperty,
   1138                         flimflam::kEapPhase2AuthTTLSCHAP, NULL);
   1139       break;
   1140   }
   1141 }
   1142 
   1143 void WifiNetwork::SetEAPServerCaCertPEM(
   1144     const std::string& ca_cert_pem) {
   1145   VLOG(1) << "SetEAPServerCaCertPEM " << ca_cert_pem;
   1146   eap_server_ca_cert_pem_ = ca_cert_pem;
   1147   base::ListValue pem_list;
   1148   pem_list.AppendString(ca_cert_pem);
   1149   SetValueProperty(shill::kEapCaCertPemProperty, pem_list);
   1150 }
   1151 
   1152 void WifiNetwork::SetEAPClientCertPkcs11Id(const std::string& pkcs11_id) {
   1153   VLOG(1) << "SetEAPClientCertPkcs11Id " << pkcs11_id;
   1154   SetOrClearStringProperty(
   1155       flimflam::kEapCertIdProperty, pkcs11_id, &eap_client_cert_pkcs11_id_);
   1156   // shill requires both CertID and KeyID for TLS connections, despite
   1157   // the fact that by convention they are the same ID.
   1158   SetOrClearStringProperty(flimflam::kEapKeyIdProperty, pkcs11_id, NULL);
   1159 }
   1160 
   1161 void WifiNetwork::SetEAPUseSystemCAs(bool use_system_cas) {
   1162   SetBooleanProperty(flimflam::kEapUseSystemCasProperty, use_system_cas,
   1163                      &eap_use_system_cas_);
   1164 }
   1165 
   1166 void WifiNetwork::SetEAPIdentity(const std::string& identity) {
   1167   SetOrClearStringProperty(
   1168       flimflam::kEapIdentityProperty, identity, &eap_identity_);
   1169 }
   1170 
   1171 void WifiNetwork::SetEAPAnonymousIdentity(const std::string& identity) {
   1172   SetOrClearStringProperty(flimflam::kEapAnonymousIdentityProperty, identity,
   1173                            &eap_anonymous_identity_);
   1174 }
   1175 
   1176 void WifiNetwork::SetEAPPassphrase(const std::string& passphrase) {
   1177   SetOrClearStringProperty(
   1178       flimflam::kEapPasswordProperty, passphrase, &eap_passphrase_);
   1179 }
   1180 
   1181 std::string WifiNetwork::GetEncryptionString() const {
   1182   switch (encryption_) {
   1183     case SECURITY_UNKNOWN:
   1184       break;
   1185     case SECURITY_NONE:
   1186       return "";
   1187     case SECURITY_WEP:
   1188       return "WEP";
   1189     case SECURITY_WPA:
   1190       return "WPA";
   1191     case SECURITY_RSN:
   1192       return "RSN";
   1193     case SECURITY_8021X: {
   1194       std::string result("8021X");
   1195       switch (eap_method_) {
   1196         case EAP_METHOD_PEAP:
   1197           result += "+PEAP";
   1198           break;
   1199         case EAP_METHOD_TLS:
   1200           result += "+TLS";
   1201           break;
   1202         case EAP_METHOD_TTLS:
   1203           result += "+TTLS";
   1204           break;
   1205         case EAP_METHOD_LEAP:
   1206           result += "+LEAP";
   1207           break;
   1208         default:
   1209           break;
   1210       }
   1211       return result;
   1212     }
   1213     case SECURITY_PSK:
   1214       return "PSK";
   1215   }
   1216   return "Unknown";
   1217 }
   1218 
   1219 bool WifiNetwork::IsPassphraseRequired() const {
   1220   if (encryption_ == SECURITY_NONE)
   1221     return false;
   1222   // A connection failure might be due to a bad passphrase.
   1223   if (error() == ERROR_BAD_PASSPHRASE ||
   1224       error() == ERROR_BAD_WEPKEY ||
   1225       error() == ERROR_PPP_AUTH_FAILED ||
   1226       error() == ERROR_EAP_LOCAL_TLS_FAILED ||
   1227       error() == ERROR_EAP_REMOTE_TLS_FAILED ||
   1228       error() == ERROR_EAP_AUTHENTICATION_FAILED ||
   1229       error() == ERROR_CONNECT_FAILED ||
   1230       error() == ERROR_UNKNOWN) {
   1231     VLOG(1) << "Authentication Error: " << GetErrorString();
   1232     return true;
   1233   }
   1234   // If the user initiated a connection and it failed, request credentials in
   1235   // case it is a credentials error and Shill was unable to detect it.
   1236   if (user_connect_state() == USER_CONNECT_FAILED)
   1237     return true;
   1238   // WEP/WPA/RSN and PSK networks rely on the PassphraseRequired property.
   1239   if (encryption_ != SECURITY_8021X)
   1240     return passphrase_required_;
   1241   // For 802.1x networks, if we are using a certificate pattern we do not
   1242   // need any credentials.
   1243   if (eap_method_ == EAP_METHOD_TLS &&
   1244       client_cert_type() == CLIENT_CERT_TYPE_PATTERN) {
   1245     return false;
   1246   }
   1247   // Connectable will be false if 802.1x credentials are not set
   1248   return !connectable();
   1249 }
   1250 
   1251 bool WifiNetwork::RequiresUserProfile() const {
   1252   // 8021X requires certificates which are only stored for individual users.
   1253   if (encryption_ != SECURITY_8021X)
   1254     return false;
   1255 
   1256   if (eap_method_ != EAP_METHOD_TLS)
   1257     return false;
   1258 
   1259   if (eap_client_cert_pkcs11_id().empty() &&
   1260       client_cert_type() != CLIENT_CERT_TYPE_PATTERN)
   1261         return false;
   1262 
   1263   return true;
   1264 }
   1265 
   1266 void WifiNetwork::AttemptConnection(const base::Closure& connect) {
   1267   if (client_cert_type() == CLIENT_CERT_TYPE_PATTERN) {
   1268     MatchCertificatePattern(true, connect);
   1269   } else {
   1270     connect.Run();
   1271   }
   1272 }
   1273 
   1274 void WifiNetwork::SetCertificatePin(const std::string& pin) {
   1275   SetOrClearStringProperty(flimflam::kEapPinProperty, pin, NULL);
   1276 }
   1277 
   1278 void WifiNetwork::MatchCertificatePattern(bool allow_enroll,
   1279                                           const base::Closure& connect) {
   1280   DCHECK(client_cert_type() == CLIENT_CERT_TYPE_PATTERN);
   1281   DCHECK(!client_cert_pattern().Empty());
   1282   if (client_cert_pattern().Empty()) {
   1283     connect.Run();
   1284     return;
   1285   }
   1286 
   1287   scoped_refptr<net::X509Certificate> matching_cert =
   1288       client_cert::GetCertificateMatch(client_cert_pattern());
   1289   if (matching_cert.get()) {
   1290     SetEAPClientCertPkcs11Id(
   1291         x509_certificate_model::GetPkcs11Id(matching_cert->os_cert_handle()));
   1292   } else {
   1293     if (allow_enroll && enrollment_delegate()) {
   1294       // Wrap the closure in another callback so that we can retry the
   1295       // certificate match again before actually connecting.
   1296       base::Closure wrapped_connect =
   1297           base::Bind(&WifiNetwork::MatchCertificatePattern,
   1298                      weak_pointer_factory_.GetWeakPtr(),
   1299                      false,
   1300                      connect);
   1301 
   1302       enrollment_delegate()->Enroll(client_cert_pattern().enrollment_uri_list(),
   1303                                     wrapped_connect);
   1304       // Enrollment delegate should take care of running the closure at the
   1305       // appropriate time, if the user doesn't cancel.
   1306       return;
   1307     }
   1308   }
   1309   connect.Run();
   1310 }
   1311 
   1312 ////////////////////////////////////////////////////////////////////////////////
   1313 // WimaxNetwork
   1314 
   1315 WimaxNetwork::WimaxNetwork(const std::string& service_path)
   1316     : WirelessNetwork(service_path, TYPE_WIMAX),
   1317       passphrase_required_(false) {
   1318 }
   1319 
   1320 WimaxNetwork::~WimaxNetwork() {
   1321 }
   1322 
   1323 void WimaxNetwork::EraseCredentials() {
   1324   WipeString(&eap_passphrase_);
   1325   WipeString(&eap_identity_);
   1326 }
   1327 
   1328 void WimaxNetwork::SetEAPPassphrase(const std::string& passphrase) {
   1329   SetOrClearStringProperty(
   1330       flimflam::kEapPasswordProperty, passphrase, &eap_passphrase_);
   1331 }
   1332 
   1333 void WimaxNetwork::SetEAPIdentity(const std::string& identity) {
   1334   SetOrClearStringProperty(
   1335       flimflam::kEapIdentityProperty, identity, &eap_identity_);
   1336 }
   1337 
   1338 void WimaxNetwork::CalculateUniqueId() {
   1339   set_unique_id(name() + "|" + eap_identity());
   1340 }
   1341 
   1342 NetworkLibrary::EAPConfigData::EAPConfigData()
   1343     : method(EAP_METHOD_UNKNOWN),
   1344       auth(EAP_PHASE_2_AUTH_AUTO),
   1345       use_system_cas(true) {
   1346 }
   1347 
   1348 NetworkLibrary::EAPConfigData::~EAPConfigData() {}
   1349 
   1350 NetworkLibrary::VPNConfigData::VPNConfigData()
   1351     : save_credentials(false) {
   1352 }
   1353 
   1354 NetworkLibrary::VPNConfigData::~VPNConfigData() {}
   1355 
   1356 // static
   1357 NetworkLibrary* NetworkLibrary::GetImpl(bool stub) {
   1358   NetworkLibrary* impl;
   1359   if (stub)
   1360     impl = new NetworkLibraryImplStub();
   1361   else
   1362     impl = new NetworkLibraryImplCros();
   1363   impl->Init();
   1364   return impl;
   1365 }
   1366 
   1367 // static
   1368 void NetworkLibrary::Initialize(bool use_stub) {
   1369   CHECK(!g_network_library)
   1370       << "NetworkLibrary: Multiple calls to Initialize().";
   1371   g_network_library = NetworkLibrary::GetImpl(use_stub);
   1372   VLOG_IF(1, use_stub) << "NetworkLibrary Initialized with Stub Impl.";
   1373 }
   1374 
   1375 // static
   1376 void NetworkLibrary::Shutdown() {
   1377   VLOG(1) << "NetworkLibrary Shutting down...";
   1378   delete g_network_library;
   1379   g_network_library = NULL;
   1380   VLOG(1) << "  NetworkLibrary Shutdown completed.";
   1381 }
   1382 
   1383 // static
   1384 NetworkLibrary* NetworkLibrary::Get() {
   1385   return g_network_library;
   1386 }
   1387 
   1388 // static
   1389 void NetworkLibrary::SetForTesting(NetworkLibrary* library) {
   1390   if (g_network_library)
   1391     delete g_network_library;
   1392   g_network_library = library;
   1393 }
   1394 
   1395 }  // namespace chromeos
   1396