proxy_config_handler.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/browser/chromeos/net/proxy_config_handler.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/bind.h"
868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/json/json_writer.h"
97dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/logging.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/prefs/pref_registry_simple.h"
117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/values.h"
127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chromeos/net/onc_utils.h"
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/prefs/proxy_config_dictionary.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/pref_names.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/dbus/dbus_thread_manager.h"
167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chromeos/dbus/shill_service_client.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/network/favorite_state.h"
187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chromeos/network/network_handler_callbacks.h"
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chromeos/network/network_profile.h"
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chromeos/network/network_profile_handler.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chromeos/network/network_state_handler.h"
227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "components/pref_registry/pref_registry_syncable.h"
237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "dbus/object_path.h"
247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "third_party/cros_system_api/dbus/service_constants.h"
257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace chromeos {
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace {
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid NotifyNetworkStateHandler(const std::string& service_path) {
317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (NetworkHandler::IsInitialized()) {
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    NetworkHandler::Get()->network_state_handler()->RequestUpdateForNetwork(
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        service_path);
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace
387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)namespace proxy_config {
403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ProxyConfigDictionary> GetProxyConfigForFavoriteNetwork(
423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const PrefService* profile_prefs,
433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const PrefService* local_state_prefs,
443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const FavoriteState& network,
453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ::onc::ONCSource* onc_source) {
463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const base::DictionaryValue* network_policy =
473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      onc::GetPolicyForFavoriteNetwork(
483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          profile_prefs, local_state_prefs, network, onc_source);
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (network_policy) {
51ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    const base::DictionaryValue* proxy_policy = NULL;
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    network_policy->GetDictionaryWithoutPathExpansion(
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ::onc::network_config::kProxySettings, &proxy_policy);
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!proxy_policy) {
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // This policy doesn't set a proxy for this network. Nonetheless, this
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // disallows changes by the user.
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return scoped_ptr<ProxyConfigDictionary>();
5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    }
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    scoped_ptr<base::DictionaryValue> proxy_dict =
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        onc::ConvertOncProxySettingsToProxyConfig(*proxy_policy);
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return make_scoped_ptr(new ProxyConfigDictionary(proxy_dict.get()));
6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (network.profile_path().empty())
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return scoped_ptr<ProxyConfigDictionary>();
677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const NetworkProfile* profile = NetworkHandler::Get()
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      ->network_profile_handler()->GetProfileForPath(network.profile_path());
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!profile) {
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    VLOG(1) << "Unknown profile_path '" << network.profile_path() << "'.";
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return scoped_ptr<ProxyConfigDictionary>();
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!profile_prefs && profile->type() == NetworkProfile::TYPE_USER) {
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // This case occurs, for example, if called from the proxy config tracker
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // created for the system request context and the signin screen. Both don't
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // use profile prefs and shouldn't depend on the user's not shared proxy
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // settings.
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    VLOG(1)
807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        << "Don't use unshared settings for system context or signin screen.";
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return scoped_ptr<ProxyConfigDictionary>();
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // No policy set for this network, read instead the user's (shared or
853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // unshared) configuration.
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The user's proxy setting is not stored in the Chrome preference yet. We
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // still rely on Shill storing it.
883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const base::DictionaryValue& value = network.proxy_config();
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (value.empty())
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return scoped_ptr<ProxyConfigDictionary>();
913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return make_scoped_ptr(new ProxyConfigDictionary(&value));
927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid SetProxyConfigForFavoriteNetwork(const ProxyConfigDictionary& proxy_config,
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                      const FavoriteState& network) {
967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  chromeos::ShillServiceClient* shill_service_client =
977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      DBusThreadManager::Get()->GetShillServiceClient();
987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // The user's proxy setting is not stored in the Chrome preference yet. We
1007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // still rely on Shill storing it.
1017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ProxyPrefs::ProxyMode mode;
1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!proxy_config.GetMode(&mode) || mode == ProxyPrefs::MODE_DIRECT) {
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // Return empty string for direct mode for portal check to work correctly.
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    // TODO(pneubeck): Consider removing this legacy code.
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    shill_service_client->ClearProperty(
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        dbus::ObjectPath(network.path()),
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        shill::kProxyConfigProperty,
1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        base::Bind(&NotifyNetworkStateHandler, network.path()),
1097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch        base::Bind(&network_handler::ShillErrorCallbackFunction,
1107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   "SetProxyConfig.ClearProperty Failed",
1117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   network.path(),
1127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch                   network_handler::ErrorCallback()));
1137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  } else {
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    std::string proxy_config_str;
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    base::JSONWriter::Write(&proxy_config.GetDictionary(), &proxy_config_str);
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    shill_service_client->SetProperty(
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        dbus::ObjectPath(network.path()),
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        shill::kProxyConfigProperty,
11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        base::StringValue(proxy_config_str),
12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        base::Bind(&NotifyNetworkStateHandler, network.path()),
12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)        base::Bind(&network_handler::ShillErrorCallbackFunction,
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                   "SetProxyConfig.SetProperty Failed",
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                   network.path(),
12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                   network_handler::ErrorCallback()));
12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void RegisterPrefs(PrefRegistrySimple* registry) {
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  registry->RegisterListPref(prefs::kDeviceOpenNetworkConfiguration);
13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
1337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  registry->RegisterBooleanPref(
1347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      prefs::kUseSharedProxies,
1357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      false,
1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  registry->RegisterListPref(prefs::kOpenNetworkConfiguration,
1393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                             user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
1403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace proxy_config
1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace chromeos
1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch