blob: 2ca1b832ea6334cef0903ef48bffdd5ef4b026ca [file] [log] [blame]
// Copyright 2014 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_private/networking_private_chromeos.h"
#include <memory>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/logging.h"
#include "base/values.h"
#include "chromeos/login/login_state/login_state.h"
#include "chromeos/network/device_state.h"
#include "chromeos/network/managed_network_configuration_handler.h"
#include "chromeos/network/network_activation_handler.h"
#include "chromeos/network/network_certificate_handler.h"
#include "chromeos/network/network_connection_handler.h"
#include "chromeos/network/network_device_handler.h"
#include "chromeos/network/network_event_log.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "chromeos/network/network_util.h"
#include "chromeos/network/onc/onc_signature.h"
#include "chromeos/network/onc/onc_translator.h"
#include "chromeos/network/onc/onc_utils.h"
#include "chromeos/network/portal_detector/network_portal_detector.h"
#include "components/onc/onc_constants.h"
#include "components/proxy_config/proxy_prefs.h"
#include "content/public/browser/browser_context.h"
#include "extensions/browser/api/networking_private/networking_private_api.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/common/extension.h"
#include "extensions/common/extension_set.h"
#include "extensions/common/permissions/api_permission.h"
#include "extensions/common/permissions/permissions_data.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
using chromeos::NetworkCertificateHandler;
using chromeos::NetworkHandler;
using chromeos::NetworkStateHandler;
using chromeos::NetworkTypePattern;
using extensions::NetworkingPrivateDelegate;
namespace private_api = extensions::api::networking_private;
namespace {
chromeos::NetworkStateHandler* GetStateHandler() {
return NetworkHandler::Get()->network_state_handler();
}
chromeos::ManagedNetworkConfigurationHandler* GetManagedConfigurationHandler() {
return NetworkHandler::Get()->managed_network_configuration_handler();
}
bool GetServicePathFromGuid(const std::string& guid,
std::string* service_path,
std::string* error) {
const chromeos::NetworkState* network =
GetStateHandler()->GetNetworkStateFromGuid(guid);
if (!network) {
*error = extensions::networking_private::kErrorInvalidNetworkGuid;
return false;
}
*service_path = network->path();
return true;
}
bool IsSharedNetwork(const std::string& service_path) {
const chromeos::NetworkState* network =
GetStateHandler()->GetNetworkStateFromServicePath(
service_path, true /* configured only */);
if (!network)
return false;
return !network->IsPrivate();
}
bool GetPrimaryUserIdHash(content::BrowserContext* browser_context,
std::string* user_hash,
std::string* error) {
std::string context_user_hash =
extensions::ExtensionsBrowserClient::Get()->GetUserIdHashFromContext(
browser_context);
// Currently Chrome OS only configures networks for the primary user.
// Configuration attempts from other browser contexts should fail.
if (context_user_hash != chromeos::LoginState::Get()->primary_user_hash()) {
// Disallow class requiring a user id hash from a non-primary user context
// to avoid complexities with the policy code.
LOG(ERROR) << "networkingPrivate API call from non primary user: "
<< context_user_hash;
if (error)
*error = "Error.NonPrimaryUser";
return false;
}
if (user_hash)
*user_hash = context_user_hash;
return true;
}
void AppendDeviceState(
const std::string& type,
const chromeos::DeviceState* device,
NetworkingPrivateDelegate::DeviceStateList* device_state_list) {
DCHECK(!type.empty());
NetworkTypePattern pattern =
chromeos::onc::NetworkTypePatternFromOncType(type);
NetworkStateHandler::TechnologyState technology_state =
GetStateHandler()->GetTechnologyState(pattern);
private_api::DeviceStateType state = private_api::DEVICE_STATE_TYPE_NONE;
switch (technology_state) {
case NetworkStateHandler::TECHNOLOGY_UNAVAILABLE:
if (!device)
return;
// If we have a DeviceState entry but the technology is not available,
// assume the technology is not initialized.
state = private_api::DEVICE_STATE_TYPE_UNINITIALIZED;
break;
case NetworkStateHandler::TECHNOLOGY_AVAILABLE:
state = private_api::DEVICE_STATE_TYPE_DISABLED;
break;
case NetworkStateHandler::TECHNOLOGY_DISABLING:
state = private_api::DEVICE_STATE_TYPE_DISABLED;
break;
case NetworkStateHandler::TECHNOLOGY_UNINITIALIZED:
state = private_api::DEVICE_STATE_TYPE_UNINITIALIZED;
break;
case NetworkStateHandler::TECHNOLOGY_ENABLING:
state = private_api::DEVICE_STATE_TYPE_ENABLING;
break;
case NetworkStateHandler::TECHNOLOGY_ENABLED:
state = private_api::DEVICE_STATE_TYPE_ENABLED;
break;
case NetworkStateHandler::TECHNOLOGY_PROHIBITED:
state = private_api::DEVICE_STATE_TYPE_PROHIBITED;
break;
}
DCHECK_NE(private_api::DEVICE_STATE_TYPE_NONE, state);
std::unique_ptr<private_api::DeviceStateProperties> properties(
new private_api::DeviceStateProperties);
properties->type = private_api::ParseNetworkType(type);
properties->state = state;
if (device && state == private_api::DEVICE_STATE_TYPE_ENABLED)
properties->scanning.reset(new bool(device->scanning()));
if (device && type == ::onc::network_config::kCellular) {
bool sim_present = !device->IsSimAbsent();
properties->sim_present = std::make_unique<bool>(sim_present);
if (sim_present) {
auto sim_lock_status = std::make_unique<private_api::SIMLockStatus>();
sim_lock_status->lock_enabled = device->sim_lock_enabled();
sim_lock_status->lock_type = device->sim_lock_type();
sim_lock_status->retries_left.reset(new int(device->sim_retries_left()));
properties->sim_lock_status = std::move(sim_lock_status);
}
}
if (device && type == ::onc::network_config::kWiFi) {
properties->managed_network_available = std::make_unique<bool>(
GetStateHandler()->GetAvailableManagedWifiNetwork());
}
device_state_list->push_back(std::move(properties));
}
void NetworkHandlerFailureCallback(
const NetworkingPrivateDelegate::FailureCallback& callback,
const std::string& error_name,
std::unique_ptr<base::DictionaryValue> error_data) {
callback.Run(error_name);
}
// Returns the string corresponding to |key|. If the property is a managed
// dictionary, returns the active value. If the property does not exist or
// has no active value, returns an empty string.
std::string GetStringFromDictionary(const base::DictionaryValue& dictionary,
const std::string& key) {
std::string result;
if (!dictionary.GetStringWithoutPathExpansion(key, &result)) {
const base::DictionaryValue* managed = nullptr;
if (dictionary.GetDictionaryWithoutPathExpansion(key, &managed)) {
managed->GetStringWithoutPathExpansion(::onc::kAugmentationActiveSetting,
&result);
}
}
return result;
}
base::DictionaryValue* GetThirdPartyVPNDictionary(
base::DictionaryValue* dictionary) {
const std::string type =
GetStringFromDictionary(*dictionary, ::onc::network_config::kType);
if (type != ::onc::network_config::kVPN)
return nullptr;
base::DictionaryValue* vpn_dict = nullptr;
if (!dictionary->GetDictionary(::onc::network_config::kVPN, &vpn_dict))
return nullptr;
if (GetStringFromDictionary(*vpn_dict, ::onc::vpn::kType) !=
::onc::vpn::kThirdPartyVpn) {
return nullptr;
}
base::DictionaryValue* third_party_vpn = nullptr;
vpn_dict->GetDictionary(::onc::vpn::kThirdPartyVpn, &third_party_vpn);
return third_party_vpn;
}
const chromeos::DeviceState* GetCellularDeviceState(const std::string& guid) {
const chromeos::NetworkState* network_state = nullptr;
if (!guid.empty())
network_state = GetStateHandler()->GetNetworkStateFromGuid(guid);
const chromeos::DeviceState* device_state = nullptr;
if (network_state) {
device_state =
GetStateHandler()->GetDeviceState(network_state->device_path());
}
if (!device_state) {
device_state =
GetStateHandler()->GetDeviceStateByType(NetworkTypePattern::Cellular());
}
return device_state;
}
private_api::Certificate GetCertDictionary(
const NetworkCertificateHandler::Certificate& cert) {
private_api::Certificate api_cert;
api_cert.hash = cert.hash;
api_cert.issued_by = cert.issued_by;
api_cert.issued_to = cert.issued_to;
api_cert.hardware_backed = cert.hardware_backed;
api_cert.device_wide = cert.device_wide;
if (!cert.pem.empty())
api_cert.pem = std::make_unique<std::string>(cert.pem);
if (!cert.pkcs11_id.empty())
api_cert.pkcs11_id = std::make_unique<std::string>(cert.pkcs11_id);
return api_cert;
}
} // namespace
////////////////////////////////////////////////////////////////////////////////
namespace extensions {
NetworkingPrivateChromeOS::NetworkingPrivateChromeOS(
content::BrowserContext* browser_context)
: browser_context_(browser_context) {}
NetworkingPrivateChromeOS::~NetworkingPrivateChromeOS() {}
void NetworkingPrivateChromeOS::GetProperties(
const std::string& guid,
const DictionaryCallback& success_callback,
const FailureCallback& failure_callback) {
std::string service_path, error;
if (!GetServicePathFromGuid(guid, &service_path, &error)) {
failure_callback.Run(error);
return;
}
std::string user_id_hash;
if (!GetPrimaryUserIdHash(browser_context_, &user_id_hash, &error)) {
failure_callback.Run(error);
return;
}
GetManagedConfigurationHandler()->GetProperties(
user_id_hash, service_path,
base::BindOnce(&NetworkingPrivateChromeOS::GetPropertiesCallback,
weak_ptr_factory_.GetWeakPtr(), guid, false /* managed */,
success_callback),
base::Bind(&NetworkHandlerFailureCallback, failure_callback));
}
void NetworkingPrivateChromeOS::GetManagedProperties(
const std::string& guid,
const DictionaryCallback& success_callback,
const FailureCallback& failure_callback) {
std::string service_path, error;
if (!GetServicePathFromGuid(guid, &service_path, &error)) {
failure_callback.Run(error);
return;
}
std::string user_id_hash;
if (!GetPrimaryUserIdHash(browser_context_, &user_id_hash, &error)) {
failure_callback.Run(error);
return;
}
GetManagedConfigurationHandler()->GetManagedProperties(
user_id_hash, service_path,
base::BindOnce(&NetworkingPrivateChromeOS::GetPropertiesCallback,
weak_ptr_factory_.GetWeakPtr(), guid, true /* managed */,
success_callback),
base::Bind(&NetworkHandlerFailureCallback, failure_callback));
}
void NetworkingPrivateChromeOS::GetState(
const std::string& guid,
const DictionaryCallback& success_callback,
const FailureCallback& failure_callback) {
std::string service_path, error;
if (!GetServicePathFromGuid(guid, &service_path, &error)) {
failure_callback.Run(error);
return;
}
const chromeos::NetworkState* network_state =
GetStateHandler()->GetNetworkStateFromServicePath(
service_path, false /* configured_only */);
if (!network_state) {
failure_callback.Run(networking_private::kErrorNetworkUnavailable);
return;
}
std::unique_ptr<base::DictionaryValue> network_properties =
chromeos::network_util::TranslateNetworkStateToONC(network_state);
AppendThirdPartyProviderName(network_properties.get());
success_callback.Run(std::move(network_properties));
}
void NetworkingPrivateChromeOS::SetProperties(
const std::string& guid,
std::unique_ptr<base::DictionaryValue> properties,
bool allow_set_shared_config,
const VoidCallback& success_callback,
const FailureCallback& failure_callback) {
const chromeos::NetworkState* network =
GetStateHandler()->GetNetworkStateFromGuid(guid);
if (!network) {
failure_callback.Run(
extensions::networking_private::kErrorInvalidNetworkGuid);
return;
}
if (network->profile_path().empty()) {
failure_callback.Run(
extensions::networking_private::kErrorUnconfiguredNetwork);
return;
}
if (IsSharedNetwork(network->path())) {
if (!allow_set_shared_config) {
failure_callback.Run(networking_private::kErrorAccessToSharedConfig);
return;
}
} else {
std::string user_id_hash;
std::string error;
// Do not allow changing a non-shared network from a secondary users.
if (!GetPrimaryUserIdHash(browser_context_, &user_id_hash, &error)) {
failure_callback.Run(error);
return;
}
}
NET_LOG(USER) << "networkingPrivate.setProperties for: "
<< NetworkId(network);
GetManagedConfigurationHandler()->SetProperties(
network->path(), *properties, success_callback,
base::Bind(&NetworkHandlerFailureCallback, failure_callback));
}
void NetworkHandlerCreateCallback(
const NetworkingPrivateDelegate::StringCallback& callback,
const std::string& service_path,
const std::string& guid) {
callback.Run(guid);
}
void NetworkingPrivateChromeOS::CreateNetwork(
bool shared,
std::unique_ptr<base::DictionaryValue> properties,
const StringCallback& success_callback,
const FailureCallback& failure_callback) {
std::string user_id_hash, error;
// Do not allow configuring a non-shared network from a non-primary user.
if (!shared &&
!GetPrimaryUserIdHash(browser_context_, &user_id_hash, &error)) {
failure_callback.Run(error);
return;
}
const std::string guid =
GetStringFromDictionary(*properties, ::onc::network_config::kGUID);
NET_LOG(USER) << "networkingPrivate.CreateNetwork. GUID=" << guid;
GetManagedConfigurationHandler()->CreateConfiguration(
user_id_hash, *properties,
base::Bind(&NetworkHandlerCreateCallback, success_callback),
base::Bind(&NetworkHandlerFailureCallback, failure_callback));
}
void NetworkingPrivateChromeOS::ForgetNetwork(
const std::string& guid,
bool allow_forget_shared_config,
const VoidCallback& success_callback,
const FailureCallback& failure_callback) {
std::string service_path, error;
if (!GetServicePathFromGuid(guid, &service_path, &error)) {
failure_callback.Run(error);
return;
}
const chromeos::NetworkState* network =
GetStateHandler()->GetNetworkStateFromServicePath(
service_path, true /* configured only */);
if (!network) {
failure_callback.Run(networking_private::kErrorNetworkUnavailable);
return;
}
std::string user_id_hash;
// Don't allow non-primary user to remove private configs - the private
// configs belong to the primary user (non-primary users' network configs
// never get loaded by shill).
if (!GetPrimaryUserIdHash(browser_context_, &user_id_hash, &error) &&
network->IsPrivate()) {
failure_callback.Run(error);
return;
}
if (!allow_forget_shared_config && !network->IsPrivate()) {
failure_callback.Run(networking_private::kErrorAccessToSharedConfig);
return;
}
onc::ONCSource onc_source = onc::ONC_SOURCE_UNKNOWN;
if (GetManagedConfigurationHandler()->FindPolicyByGUID(user_id_hash, guid,
&onc_source)) {
// Prevent a policy controlled configuration removal.
if (onc_source == onc::ONC_SOURCE_DEVICE_POLICY) {
allow_forget_shared_config = false;
} else {
failure_callback.Run(networking_private::kErrorPolicyControlled);
return;
}
}
if (allow_forget_shared_config) {
GetManagedConfigurationHandler()->RemoveConfiguration(
service_path, success_callback,
base::Bind(&NetworkHandlerFailureCallback, failure_callback));
} else {
GetManagedConfigurationHandler()->RemoveConfigurationFromCurrentProfile(
service_path, success_callback,
base::Bind(&NetworkHandlerFailureCallback, failure_callback));
}
}
void NetworkingPrivateChromeOS::GetNetworks(
const std::string& network_type,
bool configured_only,
bool visible_only,
int limit,
const NetworkListCallback& success_callback,
const FailureCallback& failure_callback) {
// When requesting configured Ethernet networks, include EthernetEAP.
NetworkTypePattern pattern =
(!visible_only && network_type == ::onc::network_type::kEthernet)
? NetworkTypePattern::EthernetOrEthernetEAP()
: chromeos::onc::NetworkTypePatternFromOncType(network_type);
std::unique_ptr<base::ListValue> network_properties_list =
chromeos::network_util::TranslateNetworkListToONC(
pattern, configured_only, visible_only, limit);
for (auto& value : *network_properties_list) {
base::DictionaryValue* network_dict = nullptr;
value.GetAsDictionary(&network_dict);
DCHECK(network_dict);
if (GetThirdPartyVPNDictionary(network_dict))
AppendThirdPartyProviderName(network_dict);
}
success_callback.Run(std::move(network_properties_list));
}
void NetworkingPrivateChromeOS::StartConnect(
const std::string& guid,
const VoidCallback& success_callback,
const FailureCallback& failure_callback) {
std::string service_path, error;
if (!GetServicePathFromGuid(guid, &service_path, &error)) {
failure_callback.Run(error);
return;
}
NetworkHandler::Get()->network_connection_handler()->ConnectToNetwork(
service_path, success_callback,
base::Bind(&NetworkHandlerFailureCallback, failure_callback),
true /* check_error_state */, chromeos::ConnectCallbackMode::ON_STARTED);
}
void NetworkingPrivateChromeOS::StartDisconnect(
const std::string& guid,
const VoidCallback& success_callback,
const FailureCallback& failure_callback) {
std::string service_path, error;
if (!GetServicePathFromGuid(guid, &service_path, &error)) {
failure_callback.Run(error);
return;
}
NetworkHandler::Get()->network_connection_handler()->DisconnectNetwork(
service_path, success_callback,
base::Bind(&NetworkHandlerFailureCallback, failure_callback));
}
void NetworkingPrivateChromeOS::StartActivate(
const std::string& guid,
const std::string& specified_carrier,
const VoidCallback& success_callback,
const FailureCallback& failure_callback) {
const chromeos::NetworkState* network =
GetStateHandler()->GetNetworkStateFromGuid(guid);
if (!network) {
failure_callback.Run(
extensions::networking_private::kErrorInvalidNetworkGuid);
return;
}
if (ui_delegate())
ui_delegate()->ShowAccountDetails(guid);
success_callback.Run();
}
void NetworkingPrivateChromeOS::GetCaptivePortalStatus(
const std::string& guid,
const StringCallback& success_callback,
const FailureCallback& failure_callback) {
if (!chromeos::network_portal_detector::IsInitialized()) {
failure_callback.Run(networking_private::kErrorNotReady);
return;
}
success_callback.Run(
chromeos::NetworkPortalDetector::CaptivePortalStatusString(
chromeos::network_portal_detector::GetInstance()
->GetCaptivePortalState(guid)
.status));
}
void NetworkingPrivateChromeOS::UnlockCellularSim(
const std::string& guid,
const std::string& pin,
const std::string& puk,
const VoidCallback& success_callback,
const FailureCallback& failure_callback) {
const chromeos::DeviceState* device_state = GetCellularDeviceState(guid);
if (!device_state) {
failure_callback.Run(networking_private::kErrorNetworkUnavailable);
return;
}
std::string lock_type = device_state->sim_lock_type();
if (lock_type.empty()) {
// Sim is already unlocked.
failure_callback.Run(networking_private::kErrorInvalidNetworkOperation);
return;
}
// Unblock or unlock the SIM.
if (lock_type == shill::kSIMLockPuk) {
NetworkHandler::Get()->network_device_handler()->UnblockPin(
device_state->path(), puk, pin, success_callback,
base::Bind(&NetworkHandlerFailureCallback, failure_callback));
} else {
NetworkHandler::Get()->network_device_handler()->EnterPin(
device_state->path(), pin, success_callback,
base::Bind(&NetworkHandlerFailureCallback, failure_callback));
}
}
void NetworkingPrivateChromeOS::SetCellularSimState(
const std::string& guid,
bool require_pin,
const std::string& current_pin,
const std::string& new_pin,
const VoidCallback& success_callback,
const FailureCallback& failure_callback) {
const chromeos::DeviceState* device_state = GetCellularDeviceState(guid);
if (!device_state) {
failure_callback.Run(networking_private::kErrorNetworkUnavailable);
return;
}
if (!device_state->sim_lock_type().empty()) {
// The SIM needs to be unlocked before the state can be changed.
failure_callback.Run(networking_private::kErrorSimLocked);
return;
}
// TODO(benchan): Add more checks to validate the parameters of this method
// and the state of the SIM lock on the cellular device. Consider refactoring
// some of the code by moving the logic into shill instead.
// If |new_pin| is empty, we're trying to enable (require_pin == true) or
// disable (require_pin == false) SIM locking.
if (new_pin.empty()) {
NetworkHandler::Get()->network_device_handler()->RequirePin(
device_state->path(), require_pin, current_pin, success_callback,
base::Bind(&NetworkHandlerFailureCallback, failure_callback));
return;
}
// Otherwise, we're trying to change the PIN from |current_pin| to
// |new_pin|, which also requires SIM locking to be enabled, i.e.
// require_pin == true.
if (!require_pin) {
failure_callback.Run(networking_private::kErrorInvalidArguments);
return;
}
NetworkHandler::Get()->network_device_handler()->ChangePin(
device_state->path(), current_pin, new_pin, success_callback,
base::Bind(&NetworkHandlerFailureCallback, failure_callback));
}
void NetworkingPrivateChromeOS::SelectCellularMobileNetwork(
const std::string& guid,
const std::string& network_id,
const VoidCallback& success_callback,
const FailureCallback& failure_callback) {
const chromeos::DeviceState* device_state = GetCellularDeviceState(guid);
if (!device_state) {
failure_callback.Run(networking_private::kErrorNetworkUnavailable);
return;
}
NetworkHandler::Get()->network_device_handler()->RegisterCellularNetwork(
device_state->path(), network_id, success_callback,
base::Bind(&NetworkHandlerFailureCallback, failure_callback));
}
std::unique_ptr<base::ListValue>
NetworkingPrivateChromeOS::GetEnabledNetworkTypes() {
chromeos::NetworkStateHandler* state_handler = GetStateHandler();
std::unique_ptr<base::ListValue> network_list(new base::ListValue);
if (state_handler->IsTechnologyEnabled(NetworkTypePattern::Ethernet()))
network_list->AppendString(::onc::network_type::kEthernet);
if (state_handler->IsTechnologyEnabled(NetworkTypePattern::WiFi()))
network_list->AppendString(::onc::network_type::kWiFi);
if (state_handler->IsTechnologyEnabled(NetworkTypePattern::Cellular()))
network_list->AppendString(::onc::network_type::kCellular);
return network_list;
}
std::unique_ptr<NetworkingPrivateDelegate::DeviceStateList>
NetworkingPrivateChromeOS::GetDeviceStateList() {
std::set<std::string> technologies_found;
NetworkStateHandler::DeviceStateList devices;
NetworkHandler::Get()->network_state_handler()->GetDeviceList(&devices);
std::unique_ptr<DeviceStateList> device_state_list(new DeviceStateList);
for (const chromeos::DeviceState* device : devices) {
std::string onc_type =
chromeos::network_util::TranslateShillTypeToONC(device->type());
AppendDeviceState(onc_type, device, device_state_list.get());
technologies_found.insert(onc_type);
}
// For any technologies that we do not have a DeviceState entry for, append
// an entry if the technology is available.
const char* technology_types[] = {::onc::network_type::kEthernet,
::onc::network_type::kWiFi,
::onc::network_type::kCellular};
for (const char* technology : technology_types) {
if (base::Contains(technologies_found, technology))
continue;
AppendDeviceState(technology, nullptr /* device */,
device_state_list.get());
}
return device_state_list;
}
std::unique_ptr<base::DictionaryValue>
NetworkingPrivateChromeOS::GetGlobalPolicy() {
auto result = std::make_unique<base::DictionaryValue>();
const base::DictionaryValue* global_network_config =
GetManagedConfigurationHandler()->GetGlobalConfigFromPolicy(
std::string() /* no username hash, device policy */);
if (global_network_config)
result->MergeDictionary(global_network_config);
return result;
}
std::unique_ptr<base::DictionaryValue>
NetworkingPrivateChromeOS::GetCertificateLists() {
private_api::CertificateLists result;
const std::vector<NetworkCertificateHandler::Certificate>& server_cas =
NetworkHandler::Get()
->network_certificate_handler()
->server_ca_certificates();
for (const auto& cert : server_cas)
result.server_ca_certificates.push_back(GetCertDictionary(cert));
std::vector<private_api::Certificate> user_cert_list;
const std::vector<NetworkCertificateHandler::Certificate>& user_certs =
NetworkHandler::Get()
->network_certificate_handler()
->client_certificates();
for (const auto& cert : user_certs)
result.user_certificates.push_back(GetCertDictionary(cert));
return result.ToValue();
}
bool NetworkingPrivateChromeOS::EnableNetworkType(const std::string& type) {
NetworkTypePattern pattern =
chromeos::onc::NetworkTypePatternFromOncType(type);
GetStateHandler()->SetTechnologyEnabled(
pattern, true, chromeos::network_handler::ErrorCallback());
return true;
}
bool NetworkingPrivateChromeOS::DisableNetworkType(const std::string& type) {
NetworkTypePattern pattern =
chromeos::onc::NetworkTypePatternFromOncType(type);
GetStateHandler()->SetTechnologyEnabled(
pattern, false, chromeos::network_handler::ErrorCallback());
return true;
}
bool NetworkingPrivateChromeOS::RequestScan(const std::string& type) {
NetworkTypePattern pattern = chromeos::onc::NetworkTypePatternFromOncType(
type.empty() ? ::onc::network_type::kAllTypes : type);
GetStateHandler()->RequestScan(pattern);
return true;
}
// Private methods
void NetworkingPrivateChromeOS::GetPropertiesCallback(
const std::string& guid,
bool managed,
const DictionaryCallback& callback,
const std::string& service_path,
const base::DictionaryValue& dictionary) {
std::unique_ptr<base::DictionaryValue> dictionary_copy =
dictionary.CreateDeepCopy();
AppendThirdPartyProviderName(dictionary_copy.get());
callback.Run(std::move(dictionary_copy));
}
void NetworkingPrivateChromeOS::AppendThirdPartyProviderName(
base::DictionaryValue* dictionary) {
base::DictionaryValue* third_party_vpn =
GetThirdPartyVPNDictionary(dictionary);
if (!third_party_vpn)
return;
const std::string extension_id = GetStringFromDictionary(
*third_party_vpn, ::onc::third_party_vpn::kExtensionID);
const ExtensionSet& extensions =
ExtensionRegistry::Get(browser_context_)->enabled_extensions();
for (const auto& extension : extensions) {
if (extension->permissions_data()->HasAPIPermission(
APIPermission::kVpnProvider) &&
extension->id() == extension_id) {
third_party_vpn->SetKey(::onc::third_party_vpn::kProviderName,
base::Value(extension->name()));
break;
}
}
}
} // namespace extensions