| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/chromeos/cros/network_library.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 | |
| OLD | NEW |