1a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "chrome/browser/net/firefox_proxy_settings.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
9a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/strings/string_number_conversions.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_tokenizer.h"
11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/common/importer/firefox_importer_utils.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/proxy/proxy_config.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kNetworkProxyTypeKey = "network.proxy.type";
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kHTTPProxyKey = "network.proxy.http";
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kHTTPProxyPortKey = "network.proxy.http_port";
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kSSLProxyKey = "network.proxy.ssl";
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kSSLProxyPortKey = "network.proxy.ssl_port";
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kFTPProxyKey = "network.proxy.ftp";
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kFTPProxyPortKey = "network.proxy.ftp_port";
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kGopherProxyKey = "network.proxy.gopher";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kGopherProxyPortKey = "network.proxy.gopher_port";
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kSOCKSHostKey = "network.proxy.socks";
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kSOCKSHostPortKey = "network.proxy.socks_port";
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kSOCKSVersionKey = "network.proxy.socks_version";
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kAutoconfigURL = "network.proxy.autoconfig_url";
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kNoProxyListKey = "network.proxy.no_proxies_on";
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* const kPrefFileName = "prefs.js";
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FirefoxProxySettings::ProxyConfig IntToProxyConfig(int type) {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 1:
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FirefoxProxySettings::MANUAL;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 2:
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FirefoxProxySettings::AUTO_FROM_URL;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 4:
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FirefoxProxySettings::AUTO_DETECT;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 5:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FirefoxProxySettings::SYSTEM;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Unknown Firefox proxy config type: " << type;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FirefoxProxySettings::NO_PROXY;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FirefoxProxySettings::SOCKSVersion IntToSOCKSVersion(int type) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 4:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FirefoxProxySettings::V4;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case 5:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FirefoxProxySettings::V5;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Unknown Firefox proxy config type: " << type;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return FirefoxProxySettings::UNKNONW;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
62a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// Parses the prefs found in the file |pref_file| and puts the key/value pairs
63a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// in |prefs|. Keys are strings, and values can be strings, booleans or
64a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// integers.  Returns true if it succeeded, false otherwise (in which case
65a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// |prefs| is not filled).
66a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// Note: for strings, only valid UTF-8 string values are supported. If a
67a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch// key/pair is not valid UTF-8, it is ignored and will not appear in |prefs|.
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool ParsePrefFile(const base::FilePath& pref_file,
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                   base::DictionaryValue* prefs) {
70a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  // The string that is before a pref key.
71a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  const std::string kUserPrefString = "user_pref(\"";
72a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  std::string contents;
7358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (!base::ReadFileToString(pref_file, &contents))
74a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    return false;
75a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
76a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  std::vector<std::string> lines;
77a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  Tokenize(contents, "\n", &lines);
78a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
79a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  for (std::vector<std::string>::const_iterator iter = lines.begin();
80a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch       iter != lines.end(); ++iter) {
81a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    const std::string& line = *iter;
82a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    size_t start_key = line.find(kUserPrefString);
83a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if (start_key == std::string::npos)
84a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      continue;  // Could be a comment or a blank line.
85a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    start_key += kUserPrefString.length();
86a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    size_t stop_key = line.find('"', start_key);
87a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if (stop_key == std::string::npos) {
88a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      LOG(ERROR) << "Invalid key found in Firefox pref file '" <<
89a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          pref_file.value() << "' line is '" << line << "'.";
90a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      continue;
91a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
92a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    std::string key = line.substr(start_key, stop_key - start_key);
93a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    size_t start_value = line.find(',', stop_key + 1);
94a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if (start_value == std::string::npos) {
95a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      LOG(ERROR) << "Invalid value found in Firefox pref file '" <<
96a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          pref_file.value() << "' line is '" << line << "'.";
97a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      continue;
98a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
99a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    size_t stop_value = line.find(");", start_value + 1);
100a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if (stop_value == std::string::npos) {
101a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      LOG(ERROR) << "Invalid value found in Firefox pref file '" <<
102a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          pref_file.value() << "' line is '" << line << "'.";
103a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      continue;
104a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
105a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    std::string value = line.substr(start_value + 1,
106a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch                                    stop_value - start_value - 1);
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    base::TrimWhitespace(value, base::TRIM_ALL, &value);
108a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    // Value could be a boolean.
109a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    bool is_value_true = LowerCaseEqualsASCII(value, "true");
110a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if (is_value_true || LowerCaseEqualsASCII(value, "false")) {
111a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      prefs->SetBoolean(key, is_value_true);
112a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      continue;
113a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
114a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
115a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    // Value could be a string.
116a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if (value.size() >= 2U &&
117a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        value[0] == '"' && value[value.size() - 1] == '"') {
118a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      value = value.substr(1, value.size() - 2);
119a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      // ValueString only accept valid UTF-8.  Simply ignore that entry if it is
120a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      // not UTF-8.
121010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      if (base::IsStringUTF8(value))
122a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        prefs->SetString(key, value);
123a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      else
124a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch        VLOG(1) << "Non UTF8 value for key " << key << ", ignored.";
125a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      continue;
126a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
127a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
128a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    // Or value could be an integer.
129a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    int int_value = 0;
130a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    if (base::StringToInt(value, &int_value)) {
131a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      prefs->SetInteger(key, int_value);
132a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      continue;
133a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    }
134a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
135a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch    LOG(ERROR) << "Invalid value found in Firefox pref file '"
136a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch               << pref_file.value() << "' value is '" << value << "'.";
137a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  }
138a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  return true;
139a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
140a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FirefoxProxySettings::FirefoxProxySettings() {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Reset();
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FirefoxProxySettings::~FirefoxProxySettings() {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FirefoxProxySettings::Reset() {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config_type_ = NO_PROXY;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_proxy_.clear();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http_proxy_port_ = 0;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_proxy_.clear();
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ssl_proxy_port_ = 0;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ftp_proxy_.clear();
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ftp_proxy_port_ = 0;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gopher_proxy_.clear();
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gopher_proxy_port_ = 0;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socks_host_.clear();
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socks_port_ = 0;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  socks_version_ = UNKNONW;
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  proxy_bypass_list_.clear();
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  autoconfig_url_.clear();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FirefoxProxySettings::GetSettings(FirefoxProxySettings* settings) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(settings);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  settings->Reset();
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath profile_path = GetFirefoxProfilePath();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (profile_path.empty())
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath pref_file = profile_path.AppendASCII(kPrefFileName);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetSettingsFromFile(pref_file, settings);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool FirefoxProxySettings::ToProxyConfig(net::ProxyConfig* config) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (config_type()) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case NO_PROXY:
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *config = net::ProxyConfig::CreateDirect();
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AUTO_DETECT:
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *config = net::ProxyConfig::CreateAutoDetect();
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case AUTO_FROM_URL:
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *config = net::ProxyConfig::CreateFromCustomPacURL(
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          GURL(autoconfig_url()));
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SYSTEM:
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Can't convert this directly to a ProxyConfig.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case MANUAL:
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Handled outside of the switch (since it is a lot of code.)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The rest of this funciton is for handling the MANUAL case.
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_EQ(MANUAL, config_type());
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *config = net::ProxyConfig();
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config->proxy_rules().type =
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!http_proxy().empty()) {
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    config->proxy_rules().proxies_for_http.SetSingleProxyServer(
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        net::ProxyServer(
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            net::ProxyServer::SCHEME_HTTP,
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            net::HostPortPair(http_proxy(), http_proxy_port())));
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ftp_proxy().empty()) {
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    config->proxy_rules().proxies_for_ftp.SetSingleProxyServer(
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        net::ProxyServer(
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            net::ProxyServer::SCHEME_HTTP,
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            net::HostPortPair(ftp_proxy(), ftp_proxy_port())));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ssl_proxy().empty()) {
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    config->proxy_rules().proxies_for_https.SetSingleProxyServer(
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        net::ProxyServer(
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            net::ProxyServer::SCHEME_HTTP,
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            net::HostPortPair(ssl_proxy(), ssl_proxy_port())));
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!socks_host().empty()) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    net::ProxyServer::Scheme proxy_scheme = V5 == socks_version() ?
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        net::ProxyServer::SCHEME_SOCKS5 : net::ProxyServer::SCHEME_SOCKS4;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    config->proxy_rules().fallback_proxies.SetSingleProxyServer(
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        net::ProxyServer(
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            proxy_scheme,
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            net::HostPortPair(socks_host(), socks_port())));
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  config->proxy_rules().bypass_rules.ParseFromStringUsingSuffixMatching(
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      JoinString(proxy_bypass_list_, ';'));
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool FirefoxProxySettings::GetSettingsFromFile(const base::FilePath& pref_file,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               FirefoxProxySettings* settings) {
2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::DictionaryValue dictionary;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ParsePrefFile(pref_file, &dictionary))
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int proxy_type = 0;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dictionary.GetInteger(kNetworkProxyTypeKey, &proxy_type))
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;  // No type means no proxy.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  settings->config_type_ = IntToProxyConfig(proxy_type);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (settings->config_type_ == AUTO_FROM_URL) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!dictionary.GetStringASCII(kAutoconfigURL,
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   &(settings->autoconfig_url_))) {
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve Firefox proxy autoconfig URL";
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (settings->config_type_ == MANUAL) {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!dictionary.GetStringASCII(kHTTPProxyKey, &(settings->http_proxy_)))
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve Firefox proxy HTTP host";
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!dictionary.GetInteger(kHTTPProxyPortKey,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &(settings->http_proxy_port_))) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve Firefox proxy HTTP port";
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!dictionary.GetStringASCII(kSSLProxyKey, &(settings->ssl_proxy_)))
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve Firefox proxy SSL host";
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!dictionary.GetInteger(kSSLProxyPortKey, &(settings->ssl_proxy_port_)))
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve Firefox proxy SSL port";
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!dictionary.GetStringASCII(kFTPProxyKey, &(settings->ftp_proxy_)))
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve Firefox proxy FTP host";
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!dictionary.GetInteger(kFTPProxyPortKey, &(settings->ftp_proxy_port_)))
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve Firefox proxy SSL port";
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!dictionary.GetStringASCII(kGopherProxyKey, &(settings->gopher_proxy_)))
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve Firefox proxy gopher host";
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!dictionary.GetInteger(kGopherProxyPortKey,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               &(settings->gopher_proxy_port_))) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve Firefox proxy gopher port";
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!dictionary.GetStringASCII(kSOCKSHostKey, &(settings->socks_host_)))
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve Firefox SOCKS host";
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!dictionary.GetInteger(kSOCKSHostPortKey, &(settings->socks_port_)))
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      LOG(ERROR) << "Failed to retrieve Firefox SOCKS port";
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int socks_version;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dictionary.GetInteger(kSOCKSVersionKey, &socks_version))
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      settings->socks_version_ = IntToSOCKSVersion(socks_version);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string proxy_bypass;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (dictionary.GetStringASCII(kNoProxyListKey, &proxy_bypass) &&
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !proxy_bypass.empty()) {
2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::StringTokenizer string_tok(proxy_bypass, ",");
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      while (string_tok.GetNext()) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        std::string token = string_tok.token();
301a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        base::TrimWhitespaceASCII(token, base::TRIM_ALL, &token);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (!token.empty())
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          settings->proxy_bypass_list_.push_back(token);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
309