1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
|
// Copyright (c) 2013 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 "chrome/browser/chromeos/net/proxy_config_handler.h"
#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/values.h"
#include "chrome/browser/chromeos/net/onc_utils.h"
#include "chrome/browser/prefs/proxy_config_dictionary.h"
#include "chrome/common/pref_names.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/shill_service_client.h"
#include "chromeos/network/network_handler_callbacks.h"
#include "chromeos/network/network_profile.h"
#include "chromeos/network/network_profile_handler.h"
#include "chromeos/network/network_state.h"
#include "chromeos/network/network_state_handler.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "dbus/object_path.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace chromeos {
namespace {
void NotifyNetworkStateHandler(const std::string& service_path) {
if (NetworkHandler::IsInitialized()) {
NetworkHandler::Get()->network_state_handler()->RequestUpdateForNetwork(
service_path);
}
}
} // namespace
namespace proxy_config {
scoped_ptr<ProxyConfigDictionary> GetProxyConfigForNetwork(
const PrefService* profile_prefs,
const PrefService* local_state_prefs,
const NetworkState& network,
::onc::ONCSource* onc_source) {
const base::DictionaryValue* network_policy =
onc::GetPolicyForNetwork(
profile_prefs, local_state_prefs, network, onc_source);
if (network_policy) {
const base::DictionaryValue* proxy_policy = NULL;
network_policy->GetDictionaryWithoutPathExpansion(
::onc::network_config::kProxySettings, &proxy_policy);
if (!proxy_policy) {
// This policy doesn't set a proxy for this network. Nonetheless, this
// disallows changes by the user.
return scoped_ptr<ProxyConfigDictionary>();
}
scoped_ptr<base::DictionaryValue> proxy_dict =
onc::ConvertOncProxySettingsToProxyConfig(*proxy_policy);
return make_scoped_ptr(new ProxyConfigDictionary(proxy_dict.get()));
}
if (network.profile_path().empty())
return scoped_ptr<ProxyConfigDictionary>();
const NetworkProfile* profile = NetworkHandler::Get()
->network_profile_handler()->GetProfileForPath(network.profile_path());
if (!profile) {
VLOG(1) << "Unknown profile_path '" << network.profile_path() << "'.";
return scoped_ptr<ProxyConfigDictionary>();
}
if (!profile_prefs && profile->type() == NetworkProfile::TYPE_USER) {
// This case occurs, for example, if called from the proxy config tracker
// created for the system request context and the signin screen. Both don't
// use profile prefs and shouldn't depend on the user's not shared proxy
// settings.
VLOG(1)
<< "Don't use unshared settings for system context or signin screen.";
return scoped_ptr<ProxyConfigDictionary>();
}
// No policy set for this network, read instead the user's (shared or
// unshared) configuration.
// The user's proxy setting is not stored in the Chrome preference yet. We
// still rely on Shill storing it.
const base::DictionaryValue& value = network.proxy_config();
if (value.empty())
return scoped_ptr<ProxyConfigDictionary>();
return make_scoped_ptr(new ProxyConfigDictionary(&value));
}
void SetProxyConfigForNetwork(const ProxyConfigDictionary& proxy_config,
const NetworkState& network) {
chromeos::ShillServiceClient* shill_service_client =
DBusThreadManager::Get()->GetShillServiceClient();
// The user's proxy setting is not stored in the Chrome preference yet. We
// still rely on Shill storing it.
ProxyPrefs::ProxyMode mode;
if (!proxy_config.GetMode(&mode) || mode == ProxyPrefs::MODE_DIRECT) {
// Return empty string for direct mode for portal check to work correctly.
// TODO(pneubeck): Consider removing this legacy code.
shill_service_client->ClearProperty(
dbus::ObjectPath(network.path()),
shill::kProxyConfigProperty,
base::Bind(&NotifyNetworkStateHandler, network.path()),
base::Bind(&network_handler::ShillErrorCallbackFunction,
"SetProxyConfig.ClearProperty Failed",
network.path(),
network_handler::ErrorCallback()));
} else {
std::string proxy_config_str;
base::JSONWriter::Write(&proxy_config.GetDictionary(), &proxy_config_str);
shill_service_client->SetProperty(
dbus::ObjectPath(network.path()),
shill::kProxyConfigProperty,
base::StringValue(proxy_config_str),
base::Bind(&NotifyNetworkStateHandler, network.path()),
base::Bind(&network_handler::ShillErrorCallbackFunction,
"SetProxyConfig.SetProperty Failed",
network.path(),
network_handler::ErrorCallback()));
}
}
void RegisterPrefs(PrefRegistrySimple* registry) {
registry->RegisterListPref(prefs::kDeviceOpenNetworkConfiguration);
}
void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterBooleanPref(
prefs::kUseSharedProxies,
false,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
registry->RegisterListPref(prefs::kOpenNetworkConfiguration,
user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
}
} // namespace proxy_config
} // namespace chromeos
|