proxy_config_handler.cc revision ca12bfac764ba476d6cd062bf1dde12cc64c3f40
1// Copyright (c) 2013 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/net/proxy_config_handler.h" 6 7#include "base/bind.h" 8#include "base/json/json_writer.h" 9#include "base/logging.h" 10#include "base/prefs/pref_registry_simple.h" 11#include "base/prefs/pref_service.h" 12#include "base/values.h" 13#include "chrome/browser/chromeos/net/onc_utils.h" 14#include "chrome/browser/prefs/proxy_config_dictionary.h" 15#include "chrome/common/pref_names.h" 16#include "chromeos/dbus/dbus_thread_manager.h" 17#include "chromeos/dbus/shill_service_client.h" 18#include "chromeos/network/network_handler_callbacks.h" 19#include "chromeos/network/network_profile.h" 20#include "chromeos/network/network_profile_handler.h" 21#include "chromeos/network/network_state.h" 22#include "chromeos/network/network_state_handler.h" 23#include "components/user_prefs/pref_registry_syncable.h" 24#include "dbus/object_path.h" 25#include "third_party/cros_system_api/dbus/service_constants.h" 26 27namespace chromeos { 28 29namespace { 30 31const base::DictionaryValue* GetNetworkConfigByGUID( 32 const base::ListValue& network_configs, 33 const std::string& guid) { 34 for (base::ListValue::const_iterator it = network_configs.begin(); 35 it != network_configs.end(); 36 ++it) { 37 const base::DictionaryValue* network = NULL; 38 (*it)->GetAsDictionary(&network); 39 std::string current_guid; 40 network->GetStringWithoutPathExpansion(onc::network_config::kGUID, 41 ¤t_guid); 42 if (current_guid == guid) 43 return network; 44 } 45 return NULL; 46} 47 48scoped_ptr<ProxyConfigDictionary> GetProxyPolicy( 49 const PrefService* pref_service, 50 const char* pref_name, 51 const NetworkState& network, 52 bool* network_is_managed) { 53 *network_is_managed = false; 54 55 if (!pref_service || network.guid().empty()) 56 return scoped_ptr<ProxyConfigDictionary>(); 57 58 if (!pref_service->IsManagedPreference(pref_name)) { 59 // No policy set. 60 return scoped_ptr<ProxyConfigDictionary>(); 61 } 62 63 const base::ListValue* onc_policy = pref_service->GetList(pref_name); 64 if (!onc_policy) { 65 LOG(ERROR) << "Pref " << pref_name << " is managed, but no value is set."; 66 return scoped_ptr<ProxyConfigDictionary>(); 67 } 68 69 const base::DictionaryValue* network_policy = 70 GetNetworkConfigByGUID(*onc_policy, network.guid()); 71 if (!network_policy) { 72 // This network isn't managed by this policy. 73 return scoped_ptr<ProxyConfigDictionary>(); 74 } 75 76 const base::DictionaryValue* proxy_policy = NULL; 77 network_policy->GetDictionaryWithoutPathExpansion( 78 onc::network_config::kProxySettings, &proxy_policy); 79 if (!proxy_policy) { 80 // This policy doesn't set a proxy for this network. Nonetheless, this 81 // disallows changes by the user. 82 *network_is_managed = true; 83 return scoped_ptr<ProxyConfigDictionary>(); 84 } 85 86 scoped_ptr<base::DictionaryValue> proxy_dict = 87 onc::ConvertOncProxySettingsToProxyConfig(*proxy_policy); 88 *network_is_managed = true; 89 return make_scoped_ptr(new ProxyConfigDictionary(proxy_dict.get())); 90} 91 92} // namespace 93 94namespace proxy_config { 95 96scoped_ptr<ProxyConfigDictionary> GetProxyConfigForNetwork( 97 const PrefService* profile_prefs, 98 const PrefService* local_state_prefs, 99 const NetworkState& network, 100 onc::ONCSource* onc_source) { 101 VLOG(2) << "GetProxyConfigForNetwork network: " << network.path() 102 << " , guid: " << network.guid(); 103 *onc_source = onc::ONC_SOURCE_NONE; 104 bool network_is_managed = false; 105 106 scoped_ptr<ProxyConfigDictionary> proxy_config = 107 GetProxyPolicy(profile_prefs, 108 prefs::kOpenNetworkConfiguration, 109 network, 110 &network_is_managed); 111 if (network_is_managed) { 112 VLOG(1) << "Network " << network.path() << " is managed by user policy."; 113 *onc_source = onc::ONC_SOURCE_USER_POLICY; 114 return proxy_config.Pass(); 115 } 116 proxy_config = GetProxyPolicy(local_state_prefs, 117 prefs::kDeviceOpenNetworkConfiguration, 118 network, 119 &network_is_managed); 120 if (network_is_managed) { 121 VLOG(1) << "Network " << network.path() << " is managed by device policy."; 122 *onc_source = onc::ONC_SOURCE_DEVICE_POLICY; 123 return proxy_config.Pass(); 124 } 125 126 if (network.profile_path().empty()) 127 return scoped_ptr<ProxyConfigDictionary>(); 128 129 const NetworkProfile* profile = NetworkHandler::Get() 130 ->network_profile_handler()->GetProfileForPath(network.profile_path()); 131 if (!profile) { 132 LOG(WARNING) << "Unknown profile_path '" << network.profile_path() << "'."; 133 return scoped_ptr<ProxyConfigDictionary>(); 134 } 135 if (!profile_prefs && profile->type() == NetworkProfile::TYPE_USER) { 136 // This case occurs, for example, if called from the proxy config tracker 137 // created for the system request context and the signin screen. Both don't 138 // use profile prefs and shouldn't depend on the user's not shared proxy 139 // settings. 140 VLOG(1) 141 << "Don't use unshared settings for system context or signin screen."; 142 return scoped_ptr<ProxyConfigDictionary>(); 143 } 144 145 // No policy set for this network, read instead the user's (shared or 146 // unshared) configuration. 147 const base::DictionaryValue& value = network.proxy_config(); 148 if (value.empty()) 149 return scoped_ptr<ProxyConfigDictionary>(); 150 return make_scoped_ptr(new ProxyConfigDictionary(&value)); 151} 152 153void SetProxyConfigForNetwork(const ProxyConfigDictionary& proxy_config, 154 const NetworkState& network) { 155 chromeos::ShillServiceClient* shill_service_client = 156 DBusThreadManager::Get()->GetShillServiceClient(); 157 158 ProxyPrefs::ProxyMode mode; 159 if (!proxy_config.GetMode(&mode) || mode == ProxyPrefs::MODE_DIRECT) { 160 // TODO(pneubeck): Consider removing this legacy code. Return empty string 161 // for direct mode for portal check to work correctly. 162 shill_service_client->ClearProperty( 163 dbus::ObjectPath(network.path()), 164 flimflam::kProxyConfigProperty, 165 base::Bind(&base::DoNothing), 166 base::Bind(&network_handler::ShillErrorCallbackFunction, 167 "SetProxyConfig.ClearProperty Failed", 168 network.path(), 169 network_handler::ErrorCallback())); 170 } else { 171 std::string proxy_config_str; 172 base::JSONWriter::Write(&proxy_config.GetDictionary(), &proxy_config_str); 173 shill_service_client->SetProperty( 174 dbus::ObjectPath(network.path()), 175 flimflam::kProxyConfigProperty, 176 base::StringValue(proxy_config_str), 177 base::Bind(&base::DoNothing), 178 base::Bind(&network_handler::ShillErrorCallbackFunction, 179 "SetProxyConfig.SetProperty Failed", 180 network.path(), 181 network_handler::ErrorCallback())); 182 } 183 184 if (NetworkHandler::IsInitialized()) { 185 NetworkHandler::Get()->network_state_handler() 186 ->RequestUpdateForNetwork(network.path()); 187 } 188} 189 190void RegisterPrefs(PrefRegistrySimple* registry) { 191 registry->RegisterListPref(prefs::kDeviceOpenNetworkConfiguration); 192} 193 194void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) { 195 registry->RegisterBooleanPref( 196 prefs::kUseSharedProxies, 197 false, 198 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 199 200 registry->RegisterListPref(prefs::kOpenNetworkConfiguration, 201 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 202} 203 204} // namespace proxy_config 205 206} // namespace chromeos 207