• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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/proxy_cros_settings_parser.h"
6 
7 #include "base/strings/string_util.h"
8 #include "base/values.h"
9 #include "chrome/browser/chromeos/ui_proxy_config.h"
10 #include "chrome/browser/chromeos/ui_proxy_config_service.h"
11 
12 namespace chromeos {
13 
14 // Common prefix of all proxy prefs.
15 const char kProxyPrefsPrefix[] = "cros.session.proxy";
16 
17 // Names of proxy preferences.
18 const char kProxyPacUrl[]         = "cros.session.proxy.pacurl";
19 const char kProxySingleHttp[]     = "cros.session.proxy.singlehttp";
20 const char kProxySingleHttpPort[] = "cros.session.proxy.singlehttpport";
21 const char kProxyHttpUrl[]        = "cros.session.proxy.httpurl";
22 const char kProxyHttpPort[]       = "cros.session.proxy.httpport";
23 const char kProxyHttpsUrl[]       = "cros.session.proxy.httpsurl";
24 const char kProxyHttpsPort[]      = "cros.session.proxy.httpsport";
25 const char kProxyType[]           = "cros.session.proxy.type";
26 const char kProxySingle[]         = "cros.session.proxy.single";
27 const char kProxyFtpUrl[]         = "cros.session.proxy.ftpurl";
28 const char kProxyFtpPort[]        = "cros.session.proxy.ftpport";
29 const char kProxySocks[]          = "cros.session.proxy.socks";
30 const char kProxySocksPort[]      = "cros.session.proxy.socksport";
31 const char kProxyIgnoreList[]     = "cros.session.proxy.ignorelist";
32 const char kProxyUsePacUrl[]      = "cros.session.proxy.usepacurl";
33 
34 const char* const kProxySettings[] = {
35   kProxyPacUrl,
36   kProxySingleHttp,
37   kProxySingleHttpPort,
38   kProxyHttpUrl,
39   kProxyHttpPort,
40   kProxyHttpsUrl,
41   kProxyHttpsPort,
42   kProxyType,
43   kProxySingle,
44   kProxyFtpUrl,
45   kProxyFtpPort,
46   kProxySocks,
47   kProxySocksPort,
48   kProxyIgnoreList,
49   kProxyUsePacUrl,
50 };
51 
52 // We have to explicitly export this because the arraysize macro doesn't like
53 // extern arrays as their size is not known on compile time.
54 const size_t kProxySettingsCount = arraysize(kProxySettings);
55 
56 namespace {
57 
CreateServerHostValue(const UIProxyConfig::ManualProxy & proxy)58 base::Value* CreateServerHostValue(const UIProxyConfig::ManualProxy& proxy) {
59   return proxy.server.is_valid() ?
60          new base::StringValue(proxy.server.host_port_pair().host()) :
61          NULL;
62 }
63 
CreateServerPortValue(const UIProxyConfig::ManualProxy & proxy)64 base::Value* CreateServerPortValue(const UIProxyConfig::ManualProxy& proxy) {
65   return proxy.server.is_valid() ?
66          base::Value::CreateIntegerValue(proxy.server.host_port_pair().port()) :
67          NULL;
68 }
69 
CreateProxyServer(std::string host,uint16 port,net::ProxyServer::Scheme scheme)70 net::ProxyServer CreateProxyServer(std::string host,
71                                    uint16 port,
72                                    net::ProxyServer::Scheme scheme) {
73   if (host.empty() && port == 0)
74     return net::ProxyServer();
75   uint16 default_port = net::ProxyServer::GetDefaultPortForScheme(scheme);
76   net::HostPortPair host_port_pair;
77   // Check if host is a valid URL or a string of valid format <server>::<port>.
78   GURL url(host);
79   if (url.is_valid())  // See if host is URL.
80     host_port_pair = net::HostPortPair::FromURL(url);
81   if (host_port_pair.host().empty())  // See if host is <server>::<port>.
82     host_port_pair = net::HostPortPair::FromString(host);
83   if (host_port_pair.host().empty())  // Host is not URL or <server>::<port>.
84     host_port_pair = net::HostPortPair(host, port);
85   if (host_port_pair.port() == 0)  // No port in host, use default.
86     host_port_pair.set_port(default_port);
87   return net::ProxyServer(scheme, host_port_pair);
88 }
89 
CreateProxyServerFromHost(const std::string & host,const UIProxyConfig::ManualProxy & proxy,net::ProxyServer::Scheme scheme)90 net::ProxyServer CreateProxyServerFromHost(
91     const std::string& host,
92     const UIProxyConfig::ManualProxy& proxy,
93     net::ProxyServer::Scheme scheme) {
94   uint16 port = 0;
95   if (proxy.server.is_valid())
96     port = proxy.server.host_port_pair().port();
97   return CreateProxyServer(host, port, scheme);
98 }
99 
CreateProxyServerFromPort(uint16 port,const UIProxyConfig::ManualProxy & proxy,net::ProxyServer::Scheme scheme)100 net::ProxyServer CreateProxyServerFromPort(
101     uint16 port,
102     const UIProxyConfig::ManualProxy& proxy,
103     net::ProxyServer::Scheme scheme) {
104   std::string host;
105   if (proxy.server.is_valid())
106     host = proxy.server.host_port_pair().host();
107   return CreateProxyServer(host, port, scheme);
108 }
109 
110 }  // namespace
111 
112 namespace proxy_cros_settings_parser {
113 
IsProxyPref(const std::string & path)114 bool IsProxyPref(const std::string& path) {
115   return StartsWithASCII(path, kProxyPrefsPrefix, true);
116 }
117 
SetProxyPrefValue(const std::string & path,const base::Value * in_value,UIProxyConfigService * config_service)118 void SetProxyPrefValue(const std::string& path,
119                        const base::Value* in_value,
120                        UIProxyConfigService* config_service) {
121   if (!in_value) {
122     NOTREACHED();
123     return;
124   }
125 
126   // Retrieve proxy config.
127   UIProxyConfig config;
128   config_service->GetProxyConfig(&config);
129 
130   if (path == kProxyPacUrl) {
131     std::string val;
132     if (in_value->GetAsString(&val)) {
133       GURL url(val);
134       if (url.is_valid())
135         config.SetPacUrl(url);
136       else
137         config.mode = UIProxyConfig::MODE_AUTO_DETECT;
138     }
139   } else if (path == kProxySingleHttp) {
140     std::string val;
141     if (in_value->GetAsString(&val)) {
142       config.SetSingleProxy(CreateProxyServerFromHost(
143           val, config.single_proxy, net::ProxyServer::SCHEME_HTTP));
144     }
145   } else if (path == kProxySingleHttpPort) {
146     int val;
147     if (in_value->GetAsInteger(&val)) {
148       config.SetSingleProxy(CreateProxyServerFromPort(
149           val, config.single_proxy, net::ProxyServer::SCHEME_HTTP));
150     }
151   } else if (path == kProxyHttpUrl) {
152     std::string val;
153     if (in_value->GetAsString(&val)) {
154       config.SetProxyForScheme(
155           "http", CreateProxyServerFromHost(
156               val, config.http_proxy, net::ProxyServer::SCHEME_HTTP));
157     }
158   } else if (path == kProxyHttpPort) {
159     int val;
160     if (in_value->GetAsInteger(&val)) {
161       config.SetProxyForScheme(
162           "http", CreateProxyServerFromPort(
163               val, config.http_proxy, net::ProxyServer::SCHEME_HTTP));
164     }
165   } else if (path == kProxyHttpsUrl) {
166     std::string val;
167     if (in_value->GetAsString(&val)) {
168       config.SetProxyForScheme(
169           "https", CreateProxyServerFromHost(
170               val, config.https_proxy, net::ProxyServer::SCHEME_HTTP));
171     }
172   } else if (path == kProxyHttpsPort) {
173     int val;
174     if (in_value->GetAsInteger(&val)) {
175       config.SetProxyForScheme(
176           "https", CreateProxyServerFromPort(
177               val, config.https_proxy, net::ProxyServer::SCHEME_HTTP));
178     }
179   } else if (path == kProxyType) {
180     int val;
181     if (in_value->GetAsInteger(&val)) {
182       if (val == 3) {
183         if (config.automatic_proxy.pac_url.is_valid())
184           config.SetPacUrl(config.automatic_proxy.pac_url);
185         else
186           config.mode = UIProxyConfig::MODE_AUTO_DETECT;
187       } else if (val == 2) {
188         if (config.single_proxy.server.is_valid()) {
189           config.SetSingleProxy(config.single_proxy.server);
190         } else {
191           bool set_config = false;
192           if (config.http_proxy.server.is_valid()) {
193             config.SetProxyForScheme("http", config.http_proxy.server);
194             set_config = true;
195           }
196           if (config.https_proxy.server.is_valid()) {
197             config.SetProxyForScheme("https", config.https_proxy.server);
198             set_config = true;
199           }
200           if (config.ftp_proxy.server.is_valid()) {
201             config.SetProxyForScheme("ftp", config.ftp_proxy.server);
202             set_config = true;
203           }
204           if (config.socks_proxy.server.is_valid()) {
205             config.SetProxyForScheme("socks", config.socks_proxy.server);
206             set_config = true;
207           }
208           if (!set_config)
209             config.SetProxyForScheme("http", net::ProxyServer());
210         }
211       } else {
212         config.mode = UIProxyConfig::MODE_DIRECT;
213       }
214     }
215   } else if (path == kProxySingle) {
216     bool val;
217     if (in_value->GetAsBoolean(&val)) {
218       if (val)
219         config.SetSingleProxy(config.single_proxy.server);
220       else
221         config.SetProxyForScheme("http", config.http_proxy.server);
222     }
223   } else if (path == kProxyUsePacUrl) {
224     bool use_pac_url;
225     if (in_value->GetAsBoolean(&use_pac_url)) {
226       if (use_pac_url && config.automatic_proxy.pac_url.is_valid())
227         config.SetPacUrl(config.automatic_proxy.pac_url);
228       else
229         config.mode = UIProxyConfig::MODE_AUTO_DETECT;
230     }
231   } else if (path == kProxyFtpUrl) {
232     std::string val;
233     if (in_value->GetAsString(&val)) {
234       config.SetProxyForScheme(
235           "ftp", CreateProxyServerFromHost(
236               val, config.ftp_proxy, net::ProxyServer::SCHEME_HTTP));
237     }
238   } else if (path == kProxyFtpPort) {
239     int val;
240     if (in_value->GetAsInteger(&val)) {
241       config.SetProxyForScheme(
242           "ftp", CreateProxyServerFromPort(
243               val, config.ftp_proxy, net::ProxyServer::SCHEME_HTTP));
244     }
245   } else if (path == kProxySocks) {
246     std::string val;
247     if (in_value->GetAsString(&val)) {
248       config.SetProxyForScheme(
249           "socks", CreateProxyServerFromHost(
250               val,
251               config.socks_proxy,
252               StartsWithASCII(val, "socks5://", false) ?
253               net::ProxyServer::SCHEME_SOCKS5 :
254               net::ProxyServer::SCHEME_SOCKS4));
255     }
256   } else if (path == kProxySocksPort) {
257     int val;
258     if (in_value->GetAsInteger(&val)) {
259       std::string host = config.socks_proxy.server.host_port_pair().host();
260       config.SetProxyForScheme(
261           "socks", CreateProxyServerFromPort(
262               val,
263               config.socks_proxy,
264               StartsWithASCII(host, "socks5://", false) ?
265               net::ProxyServer::SCHEME_SOCKS5 :
266               net::ProxyServer::SCHEME_SOCKS4));
267     }
268   } else if (path == kProxyIgnoreList) {
269     net::ProxyBypassRules bypass_rules;
270     if (in_value->GetType() == base::Value::TYPE_LIST) {
271       const ListValue* list_value = static_cast<const ListValue*>(in_value);
272       for (size_t x = 0; x < list_value->GetSize(); x++) {
273         std::string val;
274         if (list_value->GetString(x, &val))
275           bypass_rules.AddRuleFromString(val);
276       }
277       config.SetBypassRules(bypass_rules);
278     }
279   } else {
280     LOG(WARNING) << "Unknown proxy settings path " << path;
281     return;
282   }
283 
284   config_service->SetProxyConfig(config);
285 }
286 
GetProxyPrefValue(const UIProxyConfigService & config_service,const std::string & path,base::Value ** out_value)287 bool GetProxyPrefValue(const UIProxyConfigService& config_service,
288                        const std::string& path,
289                        base::Value** out_value) {
290   std::string controlled_by;
291   base::Value* data = NULL;
292   UIProxyConfig config;
293   config_service.GetProxyConfig(&config);
294 
295   if (path == kProxyPacUrl) {
296     // Only show pacurl for pac-script mode.
297     if (config.mode == UIProxyConfig::MODE_PAC_SCRIPT &&
298         config.automatic_proxy.pac_url.is_valid()) {
299       data = new base::StringValue(config.automatic_proxy.pac_url.spec());
300     }
301   } else if (path == kProxySingleHttp) {
302     data = CreateServerHostValue(config.single_proxy);
303   } else if (path == kProxySingleHttpPort) {
304     data = CreateServerPortValue(config.single_proxy);
305   } else if (path == kProxyHttpUrl) {
306     data = CreateServerHostValue(config.http_proxy);
307   } else if (path == kProxyHttpsUrl) {
308     data = CreateServerHostValue(config.https_proxy);
309   } else if (path == kProxyType) {
310     if (config.mode == UIProxyConfig::MODE_AUTO_DETECT ||
311         config.mode == UIProxyConfig::MODE_PAC_SCRIPT) {
312       data = base::Value::CreateIntegerValue(3);
313     } else if (config.mode == UIProxyConfig::MODE_SINGLE_PROXY ||
314                config.mode == UIProxyConfig::MODE_PROXY_PER_SCHEME) {
315       data = base::Value::CreateIntegerValue(2);
316     } else {
317       data = base::Value::CreateIntegerValue(1);
318     }
319     switch (config.state) {
320       case ProxyPrefs::CONFIG_POLICY:
321         controlled_by = "policy";
322         break;
323       case ProxyPrefs::CONFIG_EXTENSION:
324         controlled_by = "extension";
325         break;
326       case ProxyPrefs::CONFIG_OTHER_PRECEDE:
327         controlled_by = "other";
328         break;
329       default:
330         if (!config.user_modifiable)
331           controlled_by = "shared";
332         break;
333     }
334   } else if (path == kProxySingle) {
335     data = base::Value::CreateBooleanValue(
336         config.mode == UIProxyConfig::MODE_SINGLE_PROXY);
337   } else if (path == kProxyUsePacUrl) {
338     data = base::Value::CreateBooleanValue(
339         config.mode == UIProxyConfig::MODE_PAC_SCRIPT);
340   } else if (path == kProxyFtpUrl) {
341     data = CreateServerHostValue(config.ftp_proxy);
342   } else if (path == kProxySocks) {
343     data = CreateServerHostValue(config.socks_proxy);
344   } else if (path == kProxyHttpPort) {
345     data = CreateServerPortValue(config.http_proxy);
346   } else if (path == kProxyHttpsPort) {
347     data = CreateServerPortValue(config.https_proxy);
348   } else if (path == kProxyFtpPort) {
349     data = CreateServerPortValue(config.ftp_proxy);
350   } else if (path == kProxySocksPort) {
351     data = CreateServerPortValue(config.socks_proxy);
352   } else if (path == kProxyIgnoreList) {
353     ListValue* list =  new ListValue();
354     net::ProxyBypassRules::RuleList bypass_rules = config.bypass_rules.rules();
355     for (size_t x = 0; x < bypass_rules.size(); x++)
356       list->Append(new base::StringValue(bypass_rules[x]->ToString()));
357     data = list;
358   } else {
359     *out_value = NULL;
360     return false;
361   }
362 
363   // Decorate pref value as CoreOptionsHandler::CreateValueForPref() does.
364   DictionaryValue* dict = new DictionaryValue;
365   if (!data)
366     data = new base::StringValue("");
367   dict->Set("value", data);
368   if (path == kProxyType) {
369     if (!controlled_by.empty())
370       dict->SetString("controlledBy", controlled_by);
371     dict->SetBoolean("disabled", !config.user_modifiable);
372   } else {
373     dict->SetBoolean("disabled", false);
374   }
375   *out_value = dict;
376   return true;
377 }
378 
379 }  // namespace proxy_cros_settings_parser
380 
381 }  // namespace chromeos
382