1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// found in the LICENSE file. 4868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 5868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/ui_proxy_config_service.h" 6868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 7868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/logging.h" 8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/values.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/net/proxy_config_handler.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/proxy_config_service_impl.h" 124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chromeos/network/favorite_state.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chromeos/network/network_state_handler.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "grit/generated_resources.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "net/proxy/proxy_config.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace chromeos { 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 19868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace { 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 21868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char* ModeToString(UIProxyConfig::Mode mode) { 22868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) switch (mode) { 23868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case UIProxyConfig::MODE_DIRECT: 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return "direct"; 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case UIProxyConfig::MODE_AUTO_DETECT: 26868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return "auto-detect"; 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case UIProxyConfig::MODE_PAC_SCRIPT: 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return "pacurl"; 29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case UIProxyConfig::MODE_SINGLE_PROXY: 30868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return "single-proxy"; 31868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) case UIProxyConfig::MODE_PROXY_PER_SCHEME: 32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return "proxy-per-scheme"; 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) NOTREACHED() << "Unrecognized mode type"; 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return ""; 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 38ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Writes the proxy config of |network| to |proxy_config|. Sets |onc_source| to 39ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// the source of this configuration. Returns false if no proxy was configured 40ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// for this network. 41ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool GetProxyConfig(const PrefService* profile_prefs, 42ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const PrefService* local_state_prefs, 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const FavoriteState& network, 44ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch net::ProxyConfig* proxy_config, 45ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch onc::ONCSource* onc_source) { 46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<ProxyConfigDictionary> proxy_dict = 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) proxy_config::GetProxyConfigForFavoriteNetwork( 48ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch profile_prefs, local_state_prefs, network, onc_source); 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!proxy_dict) 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return false; 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return PrefProxyConfigTrackerImpl::PrefConfigToNetConfig(*proxy_dict, 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) proxy_config); 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 55ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Returns true if proxy settings from |onc_source| are editable. 56ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochbool IsNetworkProxySettingsEditable(const onc::ONCSource onc_source) { 57ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return onc_source != onc::ONC_SOURCE_DEVICE_POLICY && 58ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch onc_source != onc::ONC_SOURCE_USER_POLICY; 59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 637dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochUIProxyConfigService::UIProxyConfigService() 64ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch : profile_prefs_(NULL), local_state_prefs_(NULL) { 65868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 67868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)UIProxyConfigService::~UIProxyConfigService() { 68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid UIProxyConfigService::SetPrefs(PrefService* profile_prefs, 71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch PrefService* local_state_prefs) { 72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch profile_prefs_ = profile_prefs; 73ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch local_state_prefs_ = local_state_prefs; 74868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void UIProxyConfigService::SetCurrentNetwork( 77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) const std::string& current_network) { 78ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch current_ui_network_ = current_network; 79ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 80ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 81ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid UIProxyConfigService::UpdateFromPrefs() { 824e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const FavoriteState* network = NULL; 83ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!current_ui_network_.empty()) { 844e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) network = NetworkHandler::Get()->network_state_handler()->GetFavoriteState( 854e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_ui_network_); 864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG_IF(ERROR, !network) << "Couldn't find FavoriteState for network " 87ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch << current_ui_network_; 88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!network) { 90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_ui_network_.clear(); 91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_ui_config_ = UIProxyConfig(); 92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DetermineEffectiveConfig(*network); 96ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch VLOG(1) << "Current ui network: " << network->name() << ", " 97ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch << ModeToString(current_ui_config_.mode) << ", " 98868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << ProxyPrefs::ConfigStateToDebugString(current_ui_config_.state) 99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << ", modifiable:" << current_ui_config_.user_modifiable; 100868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 101868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void UIProxyConfigService::GetProxyConfig(UIProxyConfig* config) const { 103868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *config = current_ui_config_; 104868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 105868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void UIProxyConfigService::SetProxyConfig(const UIProxyConfig& config) { 107868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_ui_config_ = config; 108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (current_ui_network_.empty()) 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const FavoriteState* network = 1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) NetworkHandler::Get()->network_state_handler()->GetFavoriteState( 1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) current_ui_network_); 114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!network) { 1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) LOG(ERROR) << "Couldn't find FavoriteState for network " 1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << current_ui_network_; 117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Store config for this network. 121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) scoped_ptr<base::DictionaryValue> proxy_config_value( 122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) config.ToPrefProxyConfig()); 123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProxyConfigDictionary proxy_config_dict(proxy_config_value.get()); 124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) VLOG(1) << "Set proxy for " << current_ui_network_ 126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) << " to " << *proxy_config_value; 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) proxy_config::SetProxyConfigForFavoriteNetwork(proxy_config_dict, *network); 129868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_ui_config_.state = ProxyPrefs::CONFIG_SYSTEM; 130868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 132868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void UIProxyConfigService::DetermineEffectiveConfig( 1334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) const FavoriteState& network) { 134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch DCHECK(local_state_prefs_); 135ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 136ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // The pref service to read proxy settings that apply to all networks. 137ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // Settings from the profile overrule local state. 138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch PrefService* top_pref_service = 139ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch profile_prefs_ ? profile_prefs_ : local_state_prefs_; 140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Get prefs proxy config if available. 142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::ProxyConfig pref_config; 143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProxyPrefs::ConfigState pref_state = ProxyConfigServiceImpl::ReadPrefConfig( 144ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch top_pref_service, &pref_config); 145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Get network proxy config if available. 147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::ProxyConfig network_config; 148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::ProxyConfigService::ConfigAvailability network_availability = 149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::ProxyConfigService::CONFIG_UNSET; 150ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch onc::ONCSource onc_source = onc::ONC_SOURCE_NONE; 151ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (chromeos::GetProxyConfig(profile_prefs_, 152ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch local_state_prefs_, 153ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch network, 154ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch &network_config, 155ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch &onc_source)) { 156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Network is private or shared with user using shared proxies. 157ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch VLOG(1) << this << ": using proxy of network: " << network.path(); 158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) network_availability = net::ProxyConfigService::CONFIG_VALID; 159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 160868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Determine effective proxy config, either from prefs or network. 162868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProxyPrefs::ConfigState effective_config_state; 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) net::ProxyConfig effective_config; 164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) ProxyConfigServiceImpl::GetEffectiveProxyConfig( 165868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) pref_state, pref_config, 166868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) network_availability, network_config, false, 167868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &effective_config_state, &effective_config); 168868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 169868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Store effective proxy into |current_ui_config_|. 170868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_ui_config_.FromNetProxyConfig(effective_config); 171868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_ui_config_.state = effective_config_state; 172868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (ProxyConfigServiceImpl::PrefPrecedes(effective_config_state)) { 173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_ui_config_.user_modifiable = false; 174ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } else if (!IsNetworkProxySettingsEditable(onc_source)) { 175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_ui_config_.state = ProxyPrefs::CONFIG_POLICY; 176868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) current_ui_config_.user_modifiable = false; 177868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } else { 1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch current_ui_config_.user_modifiable = !ProxyConfigServiceImpl::IgnoreProxy( 179ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch profile_prefs_, network.profile_path(), onc_source); 180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) } 181868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 183868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} // namespace chromeos 184