| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chromeos/network/network_state.h" | 5 #include "chromeos/network/network_state.h" |
| 6 | 6 |
| 7 #include "base/i18n/icu_encoding_detection.h" | |
| 8 #include "base/i18n/icu_string_conversions.h" | |
| 9 #include "base/json/json_writer.h" | |
| 10 #include "base/strings/string_number_conversions.h" | |
| 11 #include "base/strings/string_util.h" | |
| 12 #include "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
| 13 #include "base/strings/utf_string_conversion_utils.h" | |
| 14 #include "chromeos/network/network_event_log.h" | 8 #include "chromeos/network/network_event_log.h" |
| 15 #include "chromeos/network/network_profile_handler.h" | 9 #include "chromeos/network/network_profile_handler.h" |
| 16 #include "chromeos/network/network_util.h" | 10 #include "chromeos/network/network_util.h" |
| 17 #include "chromeos/network/onc/onc_utils.h" | 11 #include "chromeos/network/onc/onc_utils.h" |
| 12 #include "chromeos/network/shill_property_util.h" |
| 18 #include "third_party/cros_system_api/dbus/service_constants.h" | 13 #include "third_party/cros_system_api/dbus/service_constants.h" |
| 19 | 14 |
| 20 namespace { | 15 namespace { |
| 21 | 16 |
| 22 const char kErrorUnknown[] = "Unknown"; | 17 const char kErrorUnknown[] = "Unknown"; |
| 23 | 18 |
| 24 bool ConvertListValueToStringVector(const base::ListValue& string_list, | 19 bool ConvertListValueToStringVector(const base::ListValue& string_list, |
| 25 std::vector<std::string>* result) { | 20 std::vector<std::string>* result) { |
| 26 for (size_t i = 0; i < string_list.GetSize(); ++i) { | 21 for (size_t i = 0; i < string_list.GetSize(); ++i) { |
| 27 std::string str; | 22 std::string str; |
| 28 if (!string_list.GetString(i, &str)) | 23 if (!string_list.GetString(i, &str)) |
| 29 return false; | 24 return false; |
| 30 result->push_back(str); | 25 result->push_back(str); |
| 31 } | 26 } |
| 32 return true; | 27 return true; |
| 33 } | 28 } |
| 34 | 29 |
| 35 // Replace non UTF8 characters in |str| with a replacement character. | |
| 36 std::string ValidateUTF8(const std::string& str) { | |
| 37 std::string result; | |
| 38 for (int32 index = 0; index < static_cast<int32>(str.size()); ++index) { | |
| 39 uint32 code_point_out; | |
| 40 bool is_unicode_char = base::ReadUnicodeCharacter(str.c_str(), str.size(), | |
| 41 &index, &code_point_out); | |
| 42 const uint32 kFirstNonControlChar = 0x20; | |
| 43 if (is_unicode_char && (code_point_out >= kFirstNonControlChar)) { | |
| 44 base::WriteUnicodeCharacter(code_point_out, &result); | |
| 45 } else { | |
| 46 const uint32 kReplacementChar = 0xFFFD; | |
| 47 // Puts kReplacementChar if character is a control character [0,0x20) | |
| 48 // or is not readable UTF8. | |
| 49 base::WriteUnicodeCharacter(kReplacementChar, &result); | |
| 50 } | |
| 51 } | |
| 52 return result; | |
| 53 } | |
| 54 | |
| 55 bool IsCaCertNssSet(const base::DictionaryValue& properties) { | 30 bool IsCaCertNssSet(const base::DictionaryValue& properties) { |
| 56 std::string ca_cert_nss; | 31 std::string ca_cert_nss; |
| 57 if (properties.GetStringWithoutPathExpansion(flimflam::kEapCaCertNssProperty, | 32 if (properties.GetStringWithoutPathExpansion(flimflam::kEapCaCertNssProperty, |
| 58 &ca_cert_nss) && | 33 &ca_cert_nss) && |
| 59 !ca_cert_nss.empty()) { | 34 !ca_cert_nss.empty()) { |
| 60 return true; | 35 return true; |
| 61 } | 36 } |
| 62 | 37 |
| 63 const base::DictionaryValue* provider = NULL; | 38 const base::DictionaryValue* provider = NULL; |
| 64 properties.GetDictionaryWithoutPathExpansion(flimflam::kProviderProperty, | 39 properties.GetDictionaryWithoutPathExpansion(flimflam::kProviderProperty, |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 177 // Warning: The DictionaryValue returned from | 152 // Warning: The DictionaryValue returned from |
| 178 // ReadDictionaryFromJson/JSONParser is an optimized derived class that | 153 // ReadDictionaryFromJson/JSONParser is an optimized derived class that |
| 179 // doesn't allow releasing ownership of nested values. A Swap in the wrong | 154 // doesn't allow releasing ownership of nested values. A Swap in the wrong |
| 180 // order leads to memory access errors. | 155 // order leads to memory access errors. |
| 181 proxy_config_.MergeDictionary(proxy_config_dict.get()); | 156 proxy_config_.MergeDictionary(proxy_config_dict.get()); |
| 182 } else { | 157 } else { |
| 183 NET_LOG_ERROR("Failed to parse " + key, path()); | 158 NET_LOG_ERROR("Failed to parse " + key, path()); |
| 184 } | 159 } |
| 185 return true; | 160 return true; |
| 186 } else if (key == flimflam::kUIDataProperty) { | 161 } else if (key == flimflam::kUIDataProperty) { |
| 187 if (!GetUIDataFromValue(value, &ui_data_)) { | 162 if (!shill_property_util::GetUIDataFromValue(value, &ui_data_)) { |
| 188 NET_LOG_ERROR("Failed to parse " + key, path()); | 163 NET_LOG_ERROR("Failed to parse " + key, path()); |
| 189 return false; | 164 return false; |
| 190 } | 165 } |
| 191 return true; | 166 return true; |
| 192 } else if (key == flimflam::kNetworkTechnologyProperty) { | 167 } else if (key == flimflam::kNetworkTechnologyProperty) { |
| 193 return GetStringValue(key, value, &network_technology_); | 168 return GetStringValue(key, value, &network_technology_); |
| 194 } else if (key == flimflam::kDeviceProperty) { | 169 } else if (key == flimflam::kDeviceProperty) { |
| 195 return GetStringValue(key, value, &device_path_); | 170 return GetStringValue(key, value, &device_path_); |
| 196 } else if (key == flimflam::kGuidProperty) { | 171 } else if (key == flimflam::kGuidProperty) { |
| 197 return GetStringValue(key, value, &guid_); | 172 return GetStringValue(key, value, &guid_); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 result += dns_servers_[i]; | 307 result += dns_servers_[i]; |
| 333 } | 308 } |
| 334 return result; | 309 return result; |
| 335 } | 310 } |
| 336 | 311 |
| 337 std::string NetworkState::GetNetmask() const { | 312 std::string NetworkState::GetNetmask() const { |
| 338 return network_util::PrefixLengthToNetmask(prefix_length_); | 313 return network_util::PrefixLengthToNetmask(prefix_length_); |
| 339 } | 314 } |
| 340 | 315 |
| 341 bool NetworkState::UpdateName(const base::DictionaryValue& properties) { | 316 bool NetworkState::UpdateName(const base::DictionaryValue& properties) { |
| 342 std::string updated_name = GetNameFromProperties(path(), properties); | 317 std::string updated_name = |
| 318 shill_property_util::GetNameFromProperties(path(), properties); |
| 343 if (updated_name != name()) { | 319 if (updated_name != name()) { |
| 344 set_name(updated_name); | 320 set_name(updated_name); |
| 345 return true; | 321 return true; |
| 346 } | 322 } |
| 347 return false; | 323 return false; |
| 348 } | 324 } |
| 349 | 325 |
| 350 // static | 326 // static |
| 351 std::string NetworkState::GetNameFromProperties( | |
| 352 const std::string& service_path, | |
| 353 const base::DictionaryValue& properties) { | |
| 354 std::string name, hex_ssid; | |
| 355 properties.GetStringWithoutPathExpansion(flimflam::kNameProperty, &name); | |
| 356 properties.GetStringWithoutPathExpansion(flimflam::kWifiHexSsid, &hex_ssid); | |
| 357 | |
| 358 if (hex_ssid.empty()) { | |
| 359 if (name.empty()) | |
| 360 return name; | |
| 361 // Validate name for UTF8. | |
| 362 std::string valid_ssid = ValidateUTF8(name); | |
| 363 if (valid_ssid != name) { | |
| 364 NET_LOG_DEBUG("GetNameFromProperties", base::StringPrintf( | |
| 365 "%s: UTF8: %s", service_path.c_str(), valid_ssid.c_str())); | |
| 366 } | |
| 367 return valid_ssid; | |
| 368 } | |
| 369 | |
| 370 std::string ssid; | |
| 371 std::vector<uint8> raw_ssid_bytes; | |
| 372 if (base::HexStringToBytes(hex_ssid, &raw_ssid_bytes)) { | |
| 373 ssid = std::string(raw_ssid_bytes.begin(), raw_ssid_bytes.end()); | |
| 374 NET_LOG_DEBUG("GetNameFromProperties", base::StringPrintf( | |
| 375 "%s: %s, SSID: %s", service_path.c_str(), | |
| 376 hex_ssid.c_str(), ssid.c_str())); | |
| 377 } else { | |
| 378 NET_LOG_ERROR("GetNameFromProperties", | |
| 379 base::StringPrintf("%s: Error processing: %s", | |
| 380 service_path.c_str(), hex_ssid.c_str())); | |
| 381 return name; | |
| 382 } | |
| 383 | |
| 384 if (IsStringUTF8(ssid)) { | |
| 385 if (ssid != name) { | |
| 386 NET_LOG_DEBUG("GetNameFromProperties", base::StringPrintf( | |
| 387 "%s: UTF8: %s", service_path.c_str(), ssid.c_str())); | |
| 388 } | |
| 389 return ssid; | |
| 390 } | |
| 391 | |
| 392 // Detect encoding and convert to UTF-8. | |
| 393 std::string country_code; | |
| 394 properties.GetStringWithoutPathExpansion( | |
| 395 flimflam::kCountryProperty, &country_code); | |
| 396 std::string encoding; | |
| 397 if (!base::DetectEncoding(ssid, &encoding)) { | |
| 398 // TODO(stevenjb): This is currently experimental. If we find a case where | |
| 399 // base::DetectEncoding() fails, we need to figure out whether we can use | |
| 400 // country_code with ConvertToUtf8(). crbug.com/233267. | |
| 401 encoding = country_code; | |
| 402 } | |
| 403 if (!encoding.empty()) { | |
| 404 std::string utf8_ssid; | |
| 405 if (base::ConvertToUtf8AndNormalize(ssid, encoding, &utf8_ssid)) { | |
| 406 if (utf8_ssid != name) { | |
| 407 NET_LOG_DEBUG("GetNameFromProperties", base::StringPrintf( | |
| 408 "%s: Encoding=%s: %s", service_path.c_str(), | |
| 409 encoding.c_str(), utf8_ssid.c_str())); | |
| 410 } | |
| 411 return utf8_ssid; | |
| 412 } | |
| 413 } | |
| 414 | |
| 415 // Unrecognized encoding. Only use raw bytes if name_ is empty. | |
| 416 NET_LOG_DEBUG("GetNameFromProperties", base::StringPrintf( | |
| 417 "%s: Unrecognized Encoding=%s: %s", service_path.c_str(), | |
| 418 encoding.c_str(), ssid.c_str())); | |
| 419 if (name.empty() && !ssid.empty()) | |
| 420 return ssid; | |
| 421 return name; | |
| 422 } | |
| 423 | |
| 424 // static | |
| 425 bool NetworkState::StateIsConnected(const std::string& connection_state) { | 327 bool NetworkState::StateIsConnected(const std::string& connection_state) { |
| 426 return (connection_state == flimflam::kStateReady || | 328 return (connection_state == flimflam::kStateReady || |
| 427 connection_state == flimflam::kStateOnline || | 329 connection_state == flimflam::kStateOnline || |
| 428 connection_state == flimflam::kStatePortal); | 330 connection_state == flimflam::kStatePortal); |
| 429 } | 331 } |
| 430 | 332 |
| 431 // static | 333 // static |
| 432 bool NetworkState::StateIsConnecting(const std::string& connection_state) { | 334 bool NetworkState::StateIsConnecting(const std::string& connection_state) { |
| 433 return (connection_state == flimflam::kStateAssociation || | 335 return (connection_state == flimflam::kStateAssociation || |
| 434 connection_state == flimflam::kStateConfiguration || | 336 connection_state == flimflam::kStateConfiguration || |
| 435 connection_state == flimflam::kStateCarrier); | 337 connection_state == flimflam::kStateCarrier); |
| 436 } | 338 } |
| 437 | 339 |
| 438 // static | 340 // static |
| 439 std::string NetworkState::IPConfigProperty(const char* key) { | 341 std::string NetworkState::IPConfigProperty(const char* key) { |
| 440 return base::StringPrintf("%s.%s", shill::kIPConfigProperty, key); | 342 return base::StringPrintf("%s.%s", shill::kIPConfigProperty, key); |
| 441 } | 343 } |
| 442 | 344 |
| 443 // static | |
| 444 bool NetworkState::GetUIDataFromValue(const base::Value& ui_data_value, | |
| 445 NetworkUIData* out) { | |
| 446 std::string ui_data_str; | |
| 447 if (!ui_data_value.GetAsString(&ui_data_str)) | |
| 448 return false; | |
| 449 if (ui_data_str.empty()) { | |
| 450 *out = NetworkUIData(); | |
| 451 return true; | |
| 452 } | |
| 453 scoped_ptr<base::DictionaryValue> ui_data_dict( | |
| 454 chromeos::onc::ReadDictionaryFromJson(ui_data_str)); | |
| 455 if (!ui_data_dict) | |
| 456 return false; | |
| 457 *out = NetworkUIData(*ui_data_dict); | |
| 458 return true; | |
| 459 } | |
| 460 | |
| 461 } // namespace chromeos | 345 } // namespace chromeos |
| OLD | NEW |