| 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 |