1 // Copyright (c) 2010 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/importer/firefox_proxy_settings.h"
6
7 #include "base/file_path.h"
8 #include "base/string_tokenizer.h"
9 #include "base/string_util.h"
10 #include "base/values.h"
11 #include "chrome/browser/importer/firefox_importer_utils.h"
12 #include "net/proxy/proxy_config.h"
13
14 namespace {
15
16 const char* const kNetworkProxyTypeKey = "network.proxy.type";
17 const char* const kHTTPProxyKey = "network.proxy.http";
18 const char* const kHTTPProxyPortKey = "network.proxy.http_port";
19 const char* const kSSLProxyKey = "network.proxy.ssl";
20 const char* const kSSLProxyPortKey = "network.proxy.ssl_port";
21 const char* const kFTPProxyKey = "network.proxy.ftp";
22 const char* const kFTPProxyPortKey = "network.proxy.ftp_port";
23 const char* const kGopherProxyKey = "network.proxy.gopher";
24 const char* const kGopherProxyPortKey = "network.proxy.gopher_port";
25 const char* const kSOCKSHostKey = "network.proxy.socks";
26 const char* const kSOCKSHostPortKey = "network.proxy.socks_port";
27 const char* const kSOCKSVersionKey = "network.proxy.socks_version";
28 const char* const kAutoconfigURL = "network.proxy.autoconfig_url";
29 const char* const kNoProxyListKey = "network.proxy.no_proxies_on";
30 const char* const kPrefFileName = "prefs.js";
31
IntToProxyConfig(int type)32 FirefoxProxySettings::ProxyConfig IntToProxyConfig(int type) {
33 switch (type) {
34 case 1:
35 return FirefoxProxySettings::MANUAL;
36 case 2:
37 return FirefoxProxySettings::AUTO_FROM_URL;
38 case 4:
39 return FirefoxProxySettings::AUTO_DETECT;
40 case 5:
41 return FirefoxProxySettings::SYSTEM;
42 default:
43 LOG(ERROR) << "Unknown Firefox proxy config type: " << type;
44 return FirefoxProxySettings::NO_PROXY;
45 }
46 }
47
IntToSOCKSVersion(int type)48 FirefoxProxySettings::SOCKSVersion IntToSOCKSVersion(int type) {
49 switch (type) {
50 case 4:
51 return FirefoxProxySettings::V4;
52 case 5:
53 return FirefoxProxySettings::V5;
54 default:
55 LOG(ERROR) << "Unknown Firefox proxy config type: " << type;
56 return FirefoxProxySettings::UNKNONW;
57 }
58 }
59
60 } // namespace
61
FirefoxProxySettings()62 FirefoxProxySettings::FirefoxProxySettings() {
63 Reset();
64 }
65
~FirefoxProxySettings()66 FirefoxProxySettings::~FirefoxProxySettings() {
67 }
68
Reset()69 void FirefoxProxySettings::Reset() {
70 config_type_ = NO_PROXY;
71 http_proxy_.clear();
72 http_proxy_port_ = 0;
73 ssl_proxy_.clear();
74 ssl_proxy_port_ = 0;
75 ftp_proxy_.clear();
76 ftp_proxy_port_ = 0;
77 gopher_proxy_.clear();
78 gopher_proxy_port_ = 0;
79 socks_host_.clear();
80 socks_port_ = 0;
81 socks_version_ = UNKNONW;
82 proxy_bypass_list_.clear();
83 autoconfig_url_.clear();
84 }
85
86 // static
GetSettings(FirefoxProxySettings * settings)87 bool FirefoxProxySettings::GetSettings(FirefoxProxySettings* settings) {
88 DCHECK(settings);
89 settings->Reset();
90
91 FilePath profile_path = GetFirefoxProfilePath();
92 if (profile_path.empty())
93 return false;
94 FilePath pref_file = profile_path.AppendASCII(kPrefFileName);
95 return GetSettingsFromFile(pref_file, settings);
96 }
97
ToProxyConfig(net::ProxyConfig * config)98 bool FirefoxProxySettings::ToProxyConfig(net::ProxyConfig* config) {
99 switch (config_type()) {
100 case NO_PROXY:
101 *config = net::ProxyConfig::CreateDirect();
102 return true;
103 case AUTO_DETECT:
104 *config = net::ProxyConfig::CreateAutoDetect();
105 return true;
106 case AUTO_FROM_URL:
107 *config = net::ProxyConfig::CreateFromCustomPacURL(
108 GURL(autoconfig_url()));
109 return true;
110 case SYSTEM:
111 // Can't convert this directly to a ProxyConfig.
112 return false;
113 case MANUAL:
114 // Handled outside of the switch (since it is a lot of code.)
115 break;
116 default:
117 NOTREACHED();
118 return false;
119 }
120
121 // The rest of this funciton is for handling the MANUAL case.
122 DCHECK_EQ(MANUAL, config_type());
123
124 *config = net::ProxyConfig();
125 config->proxy_rules().type =
126 net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
127
128 if (!http_proxy().empty()) {
129 config->proxy_rules().proxy_for_http = net::ProxyServer(
130 net::ProxyServer::SCHEME_HTTP,
131 net::HostPortPair(http_proxy(), http_proxy_port()));
132 }
133
134 if (!ftp_proxy().empty()) {
135 config->proxy_rules().proxy_for_ftp = net::ProxyServer(
136 net::ProxyServer::SCHEME_HTTP,
137 net::HostPortPair(ftp_proxy(), ftp_proxy_port()));
138 }
139
140 if (!ssl_proxy().empty()) {
141 config->proxy_rules().proxy_for_https = net::ProxyServer(
142 net::ProxyServer::SCHEME_HTTP,
143 net::HostPortPair(ssl_proxy(), ssl_proxy_port()));
144 }
145
146 if (!socks_host().empty()) {
147 net::ProxyServer::Scheme proxy_scheme = V5 == socks_version() ?
148 net::ProxyServer::SCHEME_SOCKS5 : net::ProxyServer::SCHEME_SOCKS4;
149
150 config->proxy_rules().fallback_proxy = net::ProxyServer(
151 proxy_scheme,
152 net::HostPortPair(socks_host(), socks_port()));
153 }
154
155 config->proxy_rules().bypass_rules.ParseFromStringUsingSuffixMatching(
156 JoinString(proxy_bypass_list_, ';'));
157
158 return true;
159 }
160
161 // static
GetSettingsFromFile(const FilePath & pref_file,FirefoxProxySettings * settings)162 bool FirefoxProxySettings::GetSettingsFromFile(const FilePath& pref_file,
163 FirefoxProxySettings* settings) {
164 DictionaryValue dictionary;
165 if (!ParsePrefFile(pref_file, &dictionary))
166 return false;
167
168 int proxy_type = 0;
169 if (!dictionary.GetInteger(kNetworkProxyTypeKey, &proxy_type))
170 return true; // No type means no proxy.
171
172 settings->config_type_ = IntToProxyConfig(proxy_type);
173 if (settings->config_type_ == AUTO_FROM_URL) {
174 if (!dictionary.GetStringASCII(kAutoconfigURL,
175 &(settings->autoconfig_url_))) {
176 LOG(ERROR) << "Failed to retrieve Firefox proxy autoconfig URL";
177 }
178 return true;
179 }
180
181 if (settings->config_type_ == MANUAL) {
182 if (!dictionary.GetStringASCII(kHTTPProxyKey, &(settings->http_proxy_)))
183 LOG(ERROR) << "Failed to retrieve Firefox proxy HTTP host";
184 if (!dictionary.GetInteger(kHTTPProxyPortKey,
185 &(settings->http_proxy_port_))) {
186 LOG(ERROR) << "Failed to retrieve Firefox proxy HTTP port";
187 }
188 if (!dictionary.GetStringASCII(kSSLProxyKey, &(settings->ssl_proxy_)))
189 LOG(ERROR) << "Failed to retrieve Firefox proxy SSL host";
190 if (!dictionary.GetInteger(kSSLProxyPortKey, &(settings->ssl_proxy_port_)))
191 LOG(ERROR) << "Failed to retrieve Firefox proxy SSL port";
192 if (!dictionary.GetStringASCII(kFTPProxyKey, &(settings->ftp_proxy_)))
193 LOG(ERROR) << "Failed to retrieve Firefox proxy FTP host";
194 if (!dictionary.GetInteger(kFTPProxyPortKey, &(settings->ftp_proxy_port_)))
195 LOG(ERROR) << "Failed to retrieve Firefox proxy SSL port";
196 if (!dictionary.GetStringASCII(kGopherProxyKey, &(settings->gopher_proxy_)))
197 LOG(ERROR) << "Failed to retrieve Firefox proxy gopher host";
198 if (!dictionary.GetInteger(kGopherProxyPortKey,
199 &(settings->gopher_proxy_port_))) {
200 LOG(ERROR) << "Failed to retrieve Firefox proxy gopher port";
201 }
202 if (!dictionary.GetStringASCII(kSOCKSHostKey, &(settings->socks_host_)))
203 LOG(ERROR) << "Failed to retrieve Firefox SOCKS host";
204 if (!dictionary.GetInteger(kSOCKSHostPortKey, &(settings->socks_port_)))
205 LOG(ERROR) << "Failed to retrieve Firefox SOCKS port";
206 int socks_version;
207 if (dictionary.GetInteger(kSOCKSVersionKey, &socks_version))
208 settings->socks_version_ = IntToSOCKSVersion(socks_version);
209
210 std::string proxy_bypass;
211 if (dictionary.GetStringASCII(kNoProxyListKey, &proxy_bypass) &&
212 !proxy_bypass.empty()) {
213 StringTokenizer string_tok(proxy_bypass, ",");
214 while (string_tok.GetNext()) {
215 std::string token = string_tok.token();
216 TrimWhitespaceASCII(token, TRIM_ALL, &token);
217 if (!token.empty())
218 settings->proxy_bypass_list_.push_back(token);
219 }
220 }
221 }
222 return true;
223 }
224