summaryrefslogtreecommitdiff
path: root/chromium/extensions/browser/api/networking_config/networking_config_service.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/extensions/browser/api/networking_config/networking_config_service.cc')
-rw-r--r--chromium/extensions/browser/api/networking_config/networking_config_service.cc234
1 files changed, 234 insertions, 0 deletions
diff --git a/chromium/extensions/browser/api/networking_config/networking_config_service.cc b/chromium/extensions/browser/api/networking_config/networking_config_service.cc
new file mode 100644
index 00000000000..0f14345bbf9
--- /dev/null
+++ b/chromium/extensions/browser/api/networking_config/networking_config_service.cc
@@ -0,0 +1,234 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "extensions/browser/api/networking_config/networking_config_service.h"
+
+#include <stddef.h>
+#include <stdint.h>
+#include <algorithm>
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/lazy_instance.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "chromeos/network/managed_network_configuration_handler.h"
+#include "chromeos/network/network_handler.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "extensions/common/api/networking_config.h"
+
+namespace extensions {
+
+namespace {
+
+bool IsValidNonEmptyHexString(const std::string& input) {
+ size_t count = input.size();
+ if (count == 0 || (count % 2) != 0)
+ return false;
+ for (const char& c : input)
+ if (!base::IsHexDigit<char>(c))
+ return false;
+ return true;
+}
+
+} // namespace
+
+NetworkingConfigService::AuthenticationResult::AuthenticationResult()
+ : authentication_state(NetworkingConfigService::NOTRY) {
+}
+
+NetworkingConfigService::AuthenticationResult::AuthenticationResult(
+ ExtensionId extension_id,
+ std::string guid,
+ AuthenticationState authentication_state)
+ : extension_id(extension_id),
+ guid(guid),
+ authentication_state(authentication_state) {
+}
+
+NetworkingConfigService::NetworkingConfigService(
+ content::BrowserContext* browser_context,
+ scoped_ptr<EventDelegate> event_delegate,
+ ExtensionRegistry* extension_registry)
+ : browser_context_(browser_context),
+ registry_observer_(this),
+ event_delegate_(std::move(event_delegate)),
+ weak_factory_(this) {
+ registry_observer_.Add(extension_registry);
+}
+
+NetworkingConfigService::~NetworkingConfigService() {
+}
+
+void NetworkingConfigService::OnExtensionUnloaded(
+ content::BrowserContext* browser_context,
+ const Extension* extension,
+ UnloadedExtensionInfo::Reason reason) {
+ UnregisterExtension(extension->id());
+}
+
+std::string NetworkingConfigService::LookupExtensionIdForHexSsid(
+ std::string hex_ssid) const {
+ // Transform hex_ssid to uppercase.
+ transform(hex_ssid.begin(), hex_ssid.end(), hex_ssid.begin(), toupper);
+
+ const auto it = hex_ssid_to_extension_id_.find(hex_ssid);
+ if (it == hex_ssid_to_extension_id_.end())
+ return std::string();
+ return it->second;
+}
+
+bool NetworkingConfigService::IsRegisteredForCaptivePortalEvent(
+ const std::string& extension_id) const {
+ return event_delegate_->HasExtensionRegisteredForEvent(extension_id);
+}
+
+bool NetworkingConfigService::RegisterHexSsid(std::string hex_ssid,
+ const std::string& extension_id) {
+ if (!IsValidNonEmptyHexString(hex_ssid)) {
+ LOG(ERROR) << "\'" << hex_ssid << "\' is not a valid hex encoded string.";
+ return false;
+ }
+
+ // Transform hex_ssid to uppercase.
+ transform(hex_ssid.begin(), hex_ssid.end(), hex_ssid.begin(), toupper);
+
+ return hex_ssid_to_extension_id_.insert(make_pair(hex_ssid, extension_id))
+ .second;
+}
+
+void NetworkingConfigService::UnregisterExtension(
+ const std::string& extension_id) {
+ for (auto it = hex_ssid_to_extension_id_.begin();
+ it != hex_ssid_to_extension_id_.end();) {
+ if (it->second == extension_id)
+ hex_ssid_to_extension_id_.erase(it++);
+ else
+ ++it;
+ }
+}
+
+const NetworkingConfigService::AuthenticationResult&
+NetworkingConfigService::GetAuthenticationResult() const {
+ return authentication_result_;
+}
+
+void NetworkingConfigService::ResetAuthenticationResult() {
+ authentication_result_ = AuthenticationResult();
+ authentication_callback_.Reset();
+}
+
+void NetworkingConfigService::SetAuthenticationResult(
+ const AuthenticationResult& authentication_result) {
+ authentication_result_ = authentication_result;
+ if (authentication_result.authentication_state != SUCCESS) {
+ LOG(WARNING) << "Captive Portal Authentication failed.";
+ return;
+ }
+
+ if (!authentication_callback_.is_null()) {
+ authentication_callback_.Run();
+ authentication_callback_.Reset();
+ }
+}
+
+void NetworkingConfigService::OnGotProperties(
+ const std::string& extension_id,
+ const std::string& guid,
+ const base::Closure& authentication_callback,
+ const std::string& service_path,
+ const base::DictionaryValue& onc_network_config) {
+ authentication_result_ = NetworkingConfigService::AuthenticationResult(
+ std::string(), guid, NetworkingConfigService::NOTRY);
+ authentication_callback_ = authentication_callback;
+
+ // Try to extract |bssid| field.
+ const base::DictionaryValue* wifi_with_state = nullptr;
+ std::string bssid;
+ scoped_ptr<Event> event;
+ if (onc_network_config.GetDictionaryWithoutPathExpansion(
+ ::onc::network_config::kWiFi, &wifi_with_state) &&
+ wifi_with_state->GetStringWithoutPathExpansion(::onc::wifi::kBSSID,
+ &bssid)) {
+ event = CreatePortalDetectedEventAndDispatch(extension_id, guid, &bssid);
+ } else {
+ event = CreatePortalDetectedEventAndDispatch(extension_id, guid, nullptr);
+ }
+
+ EventRouter::Get(browser_context_)
+ ->DispatchEventToExtension(extension_id, std::move(event));
+}
+
+void NetworkingConfigService::OnGetPropertiesFailed(
+ const std::string& extension_id,
+ const std::string& guid,
+ const std::string& error_name,
+ scoped_ptr<base::DictionaryValue> error_data) {
+ LOG(WARNING) << "Failed to determine BSSID for network with guid " << guid
+ << ": " << error_name;
+ scoped_ptr<Event> event =
+ CreatePortalDetectedEventAndDispatch(extension_id, guid, nullptr);
+ EventRouter::Get(browser_context_)
+ ->DispatchEventToExtension(extension_id, std::move(event));
+}
+
+scoped_ptr<Event> NetworkingConfigService::CreatePortalDetectedEventAndDispatch(
+ const std::string& extension_id,
+ const std::string& guid,
+ const std::string* bssid) {
+ const chromeos::NetworkState* network = chromeos::NetworkHandler::Get()
+ ->network_state_handler()
+ ->GetNetworkStateFromGuid(guid);
+ if (!network)
+ return nullptr;
+
+ // Populate the NetworkInfo object.
+ api::networking_config::NetworkInfo network_info;
+ network_info.type = api::networking_config::NETWORK_TYPE_WIFI;
+ const std::vector<uint8_t>& raw_ssid = network->raw_ssid();
+ std::string hex_ssid = base::HexEncode(raw_ssid.data(), raw_ssid.size());
+ network_info.hex_ssid = make_scoped_ptr(new std::string(hex_ssid));
+ network_info.ssid = make_scoped_ptr(new std::string(network->name()));
+ network_info.guid = make_scoped_ptr(new std::string(network->guid()));
+ if (bssid)
+ network_info.bssid.reset(new std::string(*bssid));
+ scoped_ptr<base::ListValue> results =
+ api::networking_config::OnCaptivePortalDetected::Create(network_info);
+ scoped_ptr<Event> event(
+ new Event(events::NETWORKING_CONFIG_ON_CAPTIVE_PORTAL_DETECTED,
+ api::networking_config::OnCaptivePortalDetected::kEventName,
+ std::move(results)));
+ return event;
+}
+
+void NetworkingConfigService::DispatchPortalDetectedEvent(
+ const std::string& extension_id,
+ const std::string& guid,
+ const base::Closure& authentication_callback) {
+ // This dispatch starts a new cycle of portal detection and authentication.
+ // Ensure that any old |authentication_callback_| is dropped.
+ authentication_callback_.Reset();
+
+ // Determine |service_path| of network identified by |guid|.
+ chromeos::NetworkHandler* network_handler = chromeos::NetworkHandler::Get();
+ const chromeos::NetworkState* network =
+ network_handler->network_state_handler()->GetNetworkStateFromGuid(guid);
+ if (!network)
+ return;
+ const std::string service_path = network->path();
+
+ // We do not provide |userhash| here because we only care about properties
+ // that are not affected by policy, i.e BSSID.
+ network_handler->managed_network_configuration_handler()->GetProperties(
+ "" /* empty userhash */, service_path,
+ base::Bind(&NetworkingConfigService::OnGotProperties,
+ weak_factory_.GetWeakPtr(), extension_id, guid,
+ authentication_callback),
+ base::Bind(&NetworkingConfigService::OnGetPropertiesFailed,
+ weak_factory_.GetWeakPtr(), extension_id, guid));
+}
+
+} // namespace extensions