OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/net_util.h" | 5 #include "net/base/net_util.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <string.h> | |
9 | 8 |
10 #include <algorithm> | 9 #include <algorithm> |
11 #include <iterator> | |
12 #include <limits> | 10 #include <limits> |
13 #include <set> | 11 #include <string> |
14 | 12 |
15 #include "build/build_config.h" | 13 #include "build/build_config.h" |
16 | 14 |
17 #if defined(OS_WIN) | 15 #if defined(OS_WIN) |
18 #include <windows.h> | 16 #include <windows.h> |
19 #include <iphlpapi.h> | 17 #include <iphlpapi.h> |
20 #include <winsock2.h> | 18 #include <winsock2.h> |
21 #include <ws2bth.h> | 19 #include <ws2bth.h> |
22 #pragma comment(lib, "iphlpapi.lib") | 20 #pragma comment(lib, "iphlpapi.lib") |
23 #elif defined(OS_POSIX) | 21 #elif defined(OS_POSIX) |
24 #include <fcntl.h> | 22 #include <fcntl.h> |
25 #include <netdb.h> | 23 #include <netdb.h> |
26 #include <netinet/in.h> | 24 #include <netinet/in.h> |
27 #include <unistd.h> | 25 #include <unistd.h> |
28 #if !defined(OS_NACL) | 26 #if !defined(OS_NACL) |
29 #include <net/if.h> | 27 #include <net/if.h> |
30 #if !defined(OS_ANDROID) | 28 #if !defined(OS_ANDROID) |
31 #include <ifaddrs.h> | 29 #include <ifaddrs.h> |
32 #endif // !defined(OS_NACL) | 30 #endif // !defined(OS_NACL) |
33 #endif // !defined(OS_ANDROID) | 31 #endif // !defined(OS_ANDROID) |
34 #endif // defined(OS_POSIX) | 32 #endif // defined(OS_POSIX) |
35 | 33 |
36 #include "base/basictypes.h" | 34 #include "base/basictypes.h" |
37 #include "base/json/string_escape.h" | 35 #include "base/json/string_escape.h" |
38 #include "base/lazy_instance.h" | |
39 #include "base/logging.h" | 36 #include "base/logging.h" |
40 #include "base/strings/string_number_conversions.h" | |
41 #include "base/strings/string_piece.h" | 37 #include "base/strings/string_piece.h" |
42 #include "base/strings/string_split.h" | 38 #include "base/strings/string_split.h" |
43 #include "base/strings/string_util.h" | 39 #include "base/strings/string_util.h" |
44 #include "base/strings/stringprintf.h" | 40 #include "base/strings/stringprintf.h" |
45 #include "base/strings/utf_string_conversions.h" | 41 #include "base/strings/utf_string_conversions.h" |
46 #include "base/sys_byteorder.h" | 42 #include "base/sys_byteorder.h" |
47 #include "base/values.h" | 43 #include "base/values.h" |
48 #include "net/base/address_list.h" | 44 #include "net/base/address_list.h" |
49 #include "net/base/dns_util.h" | 45 #include "net/base/dns_util.h" |
50 #include "net/base/ip_address_number.h" | 46 #include "net/base/ip_address_number.h" |
51 #include "net/base/net_module.h" | 47 #include "net/base/net_module.h" |
52 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 48 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
53 #include "net/grit/net_resources.h" | 49 #include "net/grit/net_resources.h" |
54 #include "net/http/http_content_disposition.h" | 50 #include "net/http/http_content_disposition.h" |
55 #include "url/gurl.h" | 51 #include "url/gurl.h" |
56 #include "url/third_party/mozilla/url_parse.h" | 52 #include "url/third_party/mozilla/url_parse.h" |
57 #include "url/url_canon.h" | 53 #include "url/url_canon.h" |
58 #include "url/url_canon_ip.h" | 54 #include "url/url_canon_ip.h" |
59 #include "url/url_constants.h" | |
60 | 55 |
61 #if defined(OS_ANDROID) | 56 #if defined(OS_ANDROID) |
62 #include "net/android/network_library.h" | 57 #include "net/android/network_library.h" |
63 #endif | 58 #endif |
64 #if defined(OS_WIN) | 59 #if defined(OS_WIN) |
65 #include "net/base/winsock_init.h" | 60 #include "net/base/winsock_init.h" |
66 #endif | 61 #endif |
67 | 62 |
68 namespace net { | 63 namespace net { |
69 | 64 |
70 namespace { | 65 namespace { |
71 | 66 |
72 // The general list of blocked ports. Will be blocked unless a specific | |
73 // protocol overrides it. (Ex: ftp can use ports 20 and 21) | |
74 static const int kRestrictedPorts[] = { | |
75 1, // tcpmux | |
76 7, // echo | |
77 9, // discard | |
78 11, // systat | |
79 13, // daytime | |
80 15, // netstat | |
81 17, // qotd | |
82 19, // chargen | |
83 20, // ftp data | |
84 21, // ftp access | |
85 22, // ssh | |
86 23, // telnet | |
87 25, // smtp | |
88 37, // time | |
89 42, // name | |
90 43, // nicname | |
91 53, // domain | |
92 77, // priv-rjs | |
93 79, // finger | |
94 87, // ttylink | |
95 95, // supdup | |
96 101, // hostriame | |
97 102, // iso-tsap | |
98 103, // gppitnp | |
99 104, // acr-nema | |
100 109, // pop2 | |
101 110, // pop3 | |
102 111, // sunrpc | |
103 113, // auth | |
104 115, // sftp | |
105 117, // uucp-path | |
106 119, // nntp | |
107 123, // NTP | |
108 135, // loc-srv /epmap | |
109 139, // netbios | |
110 143, // imap2 | |
111 179, // BGP | |
112 389, // ldap | |
113 465, // smtp+ssl | |
114 512, // print / exec | |
115 513, // login | |
116 514, // shell | |
117 515, // printer | |
118 526, // tempo | |
119 530, // courier | |
120 531, // chat | |
121 532, // netnews | |
122 540, // uucp | |
123 556, // remotefs | |
124 563, // nntp+ssl | |
125 587, // stmp? | |
126 601, // ?? | |
127 636, // ldap+ssl | |
128 993, // ldap+ssl | |
129 995, // pop3+ssl | |
130 2049, // nfs | |
131 3659, // apple-sasl / PasswordServer | |
132 4045, // lockd | |
133 6000, // X11 | |
134 6665, // Alternate IRC [Apple addition] | |
135 6666, // Alternate IRC [Apple addition] | |
136 6667, // Standard IRC [Apple addition] | |
137 6668, // Alternate IRC [Apple addition] | |
138 6669, // Alternate IRC [Apple addition] | |
139 0xFFFF, // Used to block all invalid port numbers (see | |
140 // third_party/WebKit/Source/platform/weborigin/KURL.cpp, | |
141 // KURL::port()) | |
142 }; | |
143 | |
144 // FTP overrides the following restricted ports. | |
145 static const int kAllowedFtpPorts[] = { | |
146 21, // ftp data | |
147 22, // ssh | |
148 }; | |
149 | |
150 std::string NormalizeHostname(const std::string& host) { | 67 std::string NormalizeHostname(const std::string& host) { |
151 std::string result = base::StringToLowerASCII(host); | 68 std::string result = base::StringToLowerASCII(host); |
152 if (!result.empty() && *result.rbegin() == '.') | 69 if (!result.empty() && *result.rbegin() == '.') |
153 result.resize(result.size() - 1); | 70 result.resize(result.size() - 1); |
154 return result; | 71 return result; |
155 } | 72 } |
156 | 73 |
157 bool IsNormalizedLocalhostTLD(const std::string& host) { | 74 bool IsNormalizedLocalhostTLD(const std::string& host) { |
158 return base::EndsWith(host, ".localhost", true); | 75 return base::EndsWith(host, ".localhost", true); |
159 } | 76 } |
160 | 77 |
161 // |host| should be normalized. | 78 // |host| should be normalized. |
162 bool IsLocalHostname(const std::string& host) { | 79 bool IsLocalHostname(const std::string& host) { |
163 return host == "localhost" || host == "localhost.localdomain" || | 80 return host == "localhost" || host == "localhost.localdomain" || |
164 IsNormalizedLocalhostTLD(host); | 81 IsNormalizedLocalhostTLD(host); |
165 } | 82 } |
166 | 83 |
167 // |host| should be normalized. | 84 // |host| should be normalized. |
168 bool IsLocal6Hostname(const std::string& host) { | 85 bool IsLocal6Hostname(const std::string& host) { |
169 return host == "localhost6" || host == "localhost6.localdomain6"; | 86 return host == "localhost6" || host == "localhost6.localdomain6"; |
170 } | 87 } |
171 | 88 |
172 } // namespace | 89 } // namespace |
173 | 90 |
174 static base::LazyInstance<std::multiset<int> >::Leaky | |
175 g_explicitly_allowed_ports = LAZY_INSTANCE_INITIALIZER; | |
176 | |
177 std::string CanonicalizeHost(const std::string& host, | 91 std::string CanonicalizeHost(const std::string& host, |
178 url::CanonHostInfo* host_info) { | 92 url::CanonHostInfo* host_info) { |
179 // Try to canonicalize the host. | 93 // Try to canonicalize the host. |
180 const url::Component raw_host_component(0, static_cast<int>(host.length())); | 94 const url::Component raw_host_component(0, static_cast<int>(host.length())); |
181 std::string canon_host; | 95 std::string canon_host; |
182 url::StdStringCanonOutput canon_host_output(&canon_host); | 96 url::StdStringCanonOutput canon_host_output(&canon_host); |
183 url::CanonicalizeHostVerbose(host.c_str(), raw_host_component, | 97 url::CanonicalizeHostVerbose(host.c_str(), raw_host_component, |
184 &canon_host_output, host_info); | 98 &canon_host_output, host_info); |
185 | 99 |
186 if (host_info->out_host.is_nonempty() && | 100 if (host_info->out_host.is_nonempty() && |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 const base::string16 www(base::ASCIIToUTF16("www.")); | 164 const base::string16 www(base::ASCIIToUTF16("www.")); |
251 return base::StartsWith(text, www, base::CompareCase::SENSITIVE) | 165 return base::StartsWith(text, www, base::CompareCase::SENSITIVE) |
252 ? text.substr(www.length()) : text; | 166 ? text.substr(www.length()) : text; |
253 } | 167 } |
254 | 168 |
255 base::string16 StripWWWFromHost(const GURL& url) { | 169 base::string16 StripWWWFromHost(const GURL& url) { |
256 DCHECK(url.is_valid()); | 170 DCHECK(url.is_valid()); |
257 return StripWWW(base::ASCIIToUTF16(url.host())); | 171 return StripWWW(base::ASCIIToUTF16(url.host())); |
258 } | 172 } |
259 | 173 |
260 bool IsPortValid(int port) { | |
261 return port >= 0 && port <= std::numeric_limits<uint16_t>::max(); | |
262 } | |
263 | |
264 bool IsWellKnownPort(int port) { | |
265 return port >= 0 && port < 1024; | |
266 } | |
267 | |
268 bool IsPortAllowedForScheme(int port, const std::string& url_scheme) { | |
269 // Reject invalid ports. | |
270 if (!IsPortValid(port)) | |
271 return false; | |
272 | |
273 // Allow explitly allowed ports for any scheme. | |
274 if (g_explicitly_allowed_ports.Get().count(port) > 0) | |
275 return true; | |
276 | |
277 // FTP requests have an extra set of whitelisted schemes. | |
278 if (base::LowerCaseEqualsASCII(url_scheme, url::kFtpScheme)) { | |
279 for (int allowed_ftp_port : kAllowedFtpPorts) { | |
280 if (allowed_ftp_port == port) | |
281 return true; | |
282 } | |
283 } | |
284 | |
285 // Finally check against the generic list of restricted ports for all | |
286 // schemes. | |
287 for (int restricted_port : kRestrictedPorts) { | |
288 if (restricted_port == port) | |
289 return false; | |
290 } | |
291 | |
292 return true; | |
293 } | |
294 | |
295 size_t GetCountOfExplicitlyAllowedPorts() { | |
296 return g_explicitly_allowed_ports.Get().size(); | |
297 } | |
298 | |
299 // Specifies a comma separated list of port numbers that should be accepted | |
300 // despite bans. If the string is invalid no allowed ports are stored. | |
301 void SetExplicitlyAllowedPorts(const std::string& allowed_ports) { | |
302 if (allowed_ports.empty()) | |
303 return; | |
304 | |
305 std::multiset<int> ports; | |
306 size_t last = 0; | |
307 size_t size = allowed_ports.size(); | |
308 // The comma delimiter. | |
309 const std::string::value_type kComma = ','; | |
310 | |
311 // Overflow is still possible for evil user inputs. | |
312 for (size_t i = 0; i <= size; ++i) { | |
313 // The string should be composed of only digits and commas. | |
314 if (i != size && !base::IsAsciiDigit(allowed_ports[i]) && | |
315 (allowed_ports[i] != kComma)) | |
316 return; | |
317 if (i == size || allowed_ports[i] == kComma) { | |
318 if (i > last) { | |
319 int port; | |
320 base::StringToInt(base::StringPiece(allowed_ports.begin() + last, | |
321 allowed_ports.begin() + i), | |
322 &port); | |
323 ports.insert(port); | |
324 } | |
325 last = i + 1; | |
326 } | |
327 } | |
328 g_explicitly_allowed_ports.Get() = ports; | |
329 } | |
330 | |
331 ScopedPortException::ScopedPortException(int port) : port_(port) { | |
332 g_explicitly_allowed_ports.Get().insert(port); | |
333 } | |
334 | |
335 ScopedPortException::~ScopedPortException() { | |
336 std::multiset<int>::iterator it = | |
337 g_explicitly_allowed_ports.Get().find(port_); | |
338 if (it != g_explicitly_allowed_ports.Get().end()) | |
339 g_explicitly_allowed_ports.Get().erase(it); | |
340 else | |
341 NOTREACHED(); | |
342 } | |
343 | |
344 int SetNonBlocking(int fd) { | 174 int SetNonBlocking(int fd) { |
345 #if defined(OS_WIN) | 175 #if defined(OS_WIN) |
346 unsigned long no_block = 1; | 176 unsigned long no_block = 1; |
347 return ioctlsocket(fd, FIONBIO, &no_block); | 177 return ioctlsocket(fd, FIONBIO, &no_block); |
348 #elif defined(OS_POSIX) | 178 #elif defined(OS_POSIX) |
349 int flags = fcntl(fd, F_GETFL, 0); | 179 int flags = fcntl(fd, F_GETFL, 0); |
350 if (-1 == flags) | 180 if (-1 == flags) |
351 return flags; | 181 return flags; |
352 return fcntl(fd, F_SETFL, flags | O_NONBLOCK); | 182 return fcntl(fd, F_SETFL, flags | O_NONBLOCK); |
353 #endif | 183 #endif |
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 }; | 631 }; |
802 const std::string& host = url.host(); | 632 const std::string& host = url.host(); |
803 for (const char* suffix : kGoogleHostSuffixes) { | 633 for (const char* suffix : kGoogleHostSuffixes) { |
804 if (base::EndsWith(host, suffix, false)) | 634 if (base::EndsWith(host, suffix, false)) |
805 return true; | 635 return true; |
806 } | 636 } |
807 return false; | 637 return false; |
808 } | 638 } |
809 | 639 |
810 } // namespace net | 640 } // namespace net |
OLD | NEW |