Home | History | Annotate | Download | only in net
      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