1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_IMPL_H_
#define CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_IMPL_H_
#pragma once
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/values.h"
#include "chrome/browser/chromeos/cros/network_library.h"
#include "chrome/browser/net/pref_proxy_config_tracker_impl.h"
#include "chrome/browser/prefs/pref_member.h"
namespace chromeos {
// Implementation of proxy config service for chromeos that:
// - extends PrefProxyConfigTrackerImpl (and so lives and runs entirely on UI
// thread) to handle proxy from prefs (via PrefProxyConfigTrackerImpl) and
// system i.e. network (via flimflam notifications)
// - exists one per profile and one per local state
// - retrieves initial system proxy configuration from cros settings persisted
// on chromeos device from chromeos revisions before migration to flimflam,
// - persists proxy setting per network in flimflim
// - provides network stack with latest effective proxy configuration for
// currently active network via PrefProxyConfigTrackerImpl's mechanism of
// pushing config to ChromeProxyConfigService
// - provides UI with methods to retrieve and modify proxy configuration for
// any remembered network (either currently active or non-active) of current
// user profile
class ProxyConfigServiceImpl
: public PrefProxyConfigTrackerImpl,
public NetworkLibrary::NetworkManagerObserver,
public NetworkLibrary::NetworkObserver {
public:
// ProxyConfigServiceImpl is created in ProxyServiceFactory::
// CreatePrefProxyConfigTrackerImpl via Profile::GetProxyConfigTracker() for
// profile or IOThread constructor for local state and is owned by the
// respective classes.
//
// From the UI, it is accessed via Profile::GetProxyConfigTracker to allow
// user to read or modify the proxy configuration via UIGetProxyConfig or
// UISetProxyConfigTo* respectively.
// The new modified proxy config, together with proxy from prefs if available,
// are used to determine the effective proxy config, which is then pushed
// through PrefProxyConfigTrackerImpl to ChromeProxyConfigService to the
// network stack.
//
// In contrary to other platforms which simply use the systems' UI to allow
// users to configure proxies, we have to implement our own UI on the chromeos
// device. This requires extra and specific UI requirements that
// net::ProxyConfig does not suffice. So we create an augmented analog to
// net:ProxyConfig here to include and handle these UI requirements, e.g.
// - state of configuration e.g. where it was picked up from - policy,
// extension, etc (refer to ProxyPrefs::ConfigState)
// - the read/write access of a proxy setting
// - may add more stuff later.
// This is then converted to the common net::ProxyConfig before being pushed
// to PrefProxyConfigTrackerImpl::OnProxyConfigChanged and then to the network
// stack.
struct ProxyConfig {
// Specifies if proxy config is direct, auto-detect, using pac script,
// single-proxy, or proxy-per-scheme.
enum Mode {
MODE_DIRECT,
MODE_AUTO_DETECT,
MODE_PAC_SCRIPT,
MODE_SINGLE_PROXY,
MODE_PROXY_PER_SCHEME,
};
// Proxy setting for mode = direct or auto-detect or using pac script.
struct AutomaticProxy {
GURL pac_url; // Set if proxy is using pac script.
};
// Proxy setting for mode = single-proxy or proxy-per-scheme.
struct ManualProxy {
net::ProxyServer server;
};
ProxyConfig();
~ProxyConfig();
// Converts net::ProxyConfig to |this|.
bool FromNetProxyConfig(const net::ProxyConfig& net_config);
// Converts |this| to Dictionary of ProxyConfigDictionary format (which
// is the same format used by prefs).
DictionaryValue* ToPrefProxyConfig();
// Map |scheme| (one of "http", "https", "ftp" or "socks") to the correct
// ManualProxy. Returns NULL if scheme is invalid.
ManualProxy* MapSchemeToProxy(const std::string& scheme);
// We've migrated device settings to flimflam, so we only need to
// deserialize previously persisted device settings.
// Deserializes from signed setting on device as std::string into a
// protobuf and then into the config.
bool DeserializeForDevice(const std::string& input);
// Serializes config into a ProxyConfigDictionary and then std::string
// persisted as string property in flimflam for a network.
bool SerializeForNetwork(std::string* output);
// Encodes the proxy server as "<url-scheme>=<proxy-scheme>://<proxy>"
static void EncodeAndAppendProxyServer(const std::string& scheme,
const net::ProxyServer& server,
std::string* spec);
Mode mode;
ProxyPrefs::ConfigState state;
// True if user can modify proxy settings via UI.
// If proxy is managed by policy or extension or other_precde or is for
// shared network but kUseSharedProxies is turned off, it can't be modified
// by user.
bool user_modifiable;
// Set if mode is MODE_DIRECT or MODE_AUTO_DETECT or MODE_PAC_SCRIPT.
AutomaticProxy automatic_proxy;
// Set if mode is MODE_SINGLE_PROXY.
ManualProxy single_proxy;
// Set if mode is MODE_PROXY_PER_SCHEME and has http proxy.
ManualProxy http_proxy;
// Set if mode is MODE_PROXY_PER_SCHEME and has https proxy.
ManualProxy https_proxy;
// Set if mode is MODE_PROXY_PER_SCHEME and has ftp proxy.
ManualProxy ftp_proxy;
// Set if mode is MODE_PROXY_PER_SCHEME and has socks proxy.
ManualProxy socks_proxy;
// Exceptions for when not to use a proxy.
net::ProxyBypassRules bypass_rules;
};
// Constructor.
explicit ProxyConfigServiceImpl(PrefService* pref_service);
virtual ~ProxyConfigServiceImpl();
// Called by UI to set service path of |network| to be displayed or edited.
// Subsequent UISet* methods will use this network, until UI calls it again
// with a different network.
void UISetCurrentNetwork(const std::string& current_network);
// Called from UI to make the currently active network the one to be displayed
// or edited. Subsequent UISet* methods will use this network until UI calls
// it again when the active network has changed.
void UIMakeActiveNetworkCurrent();
// Called from UI to get name of the current network set via
// UISetCurrentNetwork or UIMakeActiveNetworkCurrent.
void UIGetCurrentNetworkName(std::string* network_name);
// Called from UI to retrieve proxy configuration in |current_ui_config_|.
void UIGetProxyConfig(ProxyConfig* config);
// Called from UI to update proxy configuration for different modes.
// Returns true if config is set properly and persisted to flimflam for the
// current network (set via UISetCurrentNetwork/UIMakeActiveNetworkCurrent).
// If this network is also currently active, config service proceeds to start
// activating it on network stack.
// Returns false if config is not set properly, probably because information
// is incomplete or invalid; while config service won't proceed to activate or
// persist this config, the information is "cached" in the service, so that
// the next UIGetProxyConfig call will return this latest information.
bool UISetProxyConfigToDirect();
bool UISetProxyConfigToAutoDetect();
bool UISetProxyConfigToPACScript(const GURL& pac_url);
bool UISetProxyConfigToSingleProxy(const net::ProxyServer& server);
// |scheme| is one of "http", "https", "ftp" or "socks".
bool UISetProxyConfigToProxyPerScheme(const std::string& scheme,
const net::ProxyServer& server);
// Only valid for MODE_SINGLE_PROXY or MODE_PROXY_PER_SCHEME.
bool UISetProxyConfigBypassRules(const net::ProxyBypassRules& bypass_rules);
// Add/Remove callback functions for notification when network to be viewed is
// changed by the UI.
void AddNotificationCallback(base::Closure callback);
void RemoveNotificationCallback(base::Closure callback);
// PrefProxyConfigTrackerImpl implementation.
virtual void OnProxyConfigChanged(ProxyPrefs::ConfigState config_state,
const net::ProxyConfig& config) OVERRIDE;
// NetworkLibrary::NetworkManagerObserver implementation.
virtual void OnNetworkManagerChanged(NetworkLibrary* cros) OVERRIDE;
// NetworkLibrary::NetworkObserver implementation.
virtual void OnNetworkChanged(NetworkLibrary* cros,
const Network* network) OVERRIDE;
// Register UseShardProxies preference.
static void RegisterPrefs(PrefService* pref_service);
#if defined(UNIT_TEST)
void SetTesting(ProxyConfig* test_config) {
UIMakeActiveNetworkCurrent();
if (test_config) {
std::string value;
test_config->SerializeForNetwork(&value);
SetProxyConfigForNetwork(active_network_, value, false);
}
}
#endif // defined(UNIT_TEST)
private:
// content::NotificationObserver implementation.
virtual void Observe(int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) OVERRIDE;
// Called from the various UISetProxyConfigTo*.
void OnUISetProxyConfig();
// Called from OnNetworkManagerChanged and OnNetworkChanged for currently
// active network, to handle previously active network, new active network,
// and if necessary, migrates device settings to flimflam and/or activates
// proxy setting of new network.
void OnActiveNetworkChanged(NetworkLibrary* cros,
const Network* active_network);
// Sets proxy config for |network_path| into flimflam and activates setting
// if the network is currently active. If |only_set_if_empty| is true,
// proxy will be set and saved only if network has no proxy.
void SetProxyConfigForNetwork(const std::string& network_path,
const std::string& value,
bool only_set_if_empty);
// Returns value of UseSharedProxies preference if it's not default, else
// returns false if user is logged in and true otherwise.
bool GetUseSharedProxies();
// Determines effective proxy config based on prefs from config tracker,
// |network| and if user is using shared proxies.
// If |activate| is true, effective config is stored in |active_config_| and
// activated on network stack, and hence, picked up by observers.
// if |activate| is false, effective config is stored in |current_ui_config_|
// but not activated on network stack, and hence, not picked up by observers.
void DetermineEffectiveConfig(const Network* network, bool activate);
// Determines |current_ui_config_| based on |network|, called from
// UISetCurrentNetwork and UIMakeActiveNetworkActive.
void OnUISetCurrentNetwork(const Network* network);
// Returns true if proxy is to be ignored for network, which happens if
// network is shared and use-shared-proxies is turned off.
bool IgnoreProxy(const Network* network) {
return network->profile_type() == PROFILE_SHARED && !GetUseSharedProxies();
}
// Reset UI cache variables that keep track of UI activities.
void ResetUICache();
void FetchProxyPolicy();
// Data members.
// Service path of currently active network (determined via flimflam
// notifications); if effective proxy config is from system, proxy of this
// network will be the one taking effect.
std::string active_network_;
// State of |active_config_|. |active_config_| is only valid if
// |active_config_state_| is not ProxyPrefs::CONFIG_UNSET.
ProxyPrefs::ConfigState active_config_state_;
// Active proxy configuration, which could be from prefs or network.
net::ProxyConfig active_config_;
// Proxy config retreived from device, in format generated from
// SerializeForNetwork, that can be directly set into flimflam.
std::string device_config_;
// Service path of network whose proxy configuration is being displayed or
// edited via UI, separate from |active_network_| which may be same or
// different.
std::string current_ui_network_;
// Proxy configuration of |current_ui_network_|.
ProxyConfig current_ui_config_;
// Track changes in UseSharedProxies user preference.
BooleanPrefMember use_shared_proxies_;
// Callbacks for notification when network to be viewed has been changed from
// the UI.
std::vector<base::Closure> callbacks_;
base::WeakPtrFactory<ProxyConfigServiceImpl> pointer_factory_;
DISALLOW_COPY_AND_ASSIGN(ProxyConfigServiceImpl);
};
} // namespace chromeos
#endif // CHROME_BROWSER_CHROMEOS_PROXY_CONFIG_SERVICE_IMPL_H_
|