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