Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / net / base / port_util.cc
blob1867dc3649612393b59515c78564ac0c4afd30e8
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.
5 #include "net/base/port_util.h"
7 #include <set>
9 #include "base/lazy_instance.h"
10 #include "base/logging.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/string_util.h"
13 #include "url/url_constants.h"
15 namespace net {
17 namespace {
19 // The general list of blocked ports. Will be blocked unless a specific
20 // protocol overrides it. (Ex: ftp can use ports 20 and 21)
21 const int kRestrictedPorts[] = {
22 1, // tcpmux
23 7, // echo
24 9, // discard
25 11, // systat
26 13, // daytime
27 15, // netstat
28 17, // qotd
29 19, // chargen
30 20, // ftp data
31 21, // ftp access
32 22, // ssh
33 23, // telnet
34 25, // smtp
35 37, // time
36 42, // name
37 43, // nicname
38 53, // domain
39 77, // priv-rjs
40 79, // finger
41 87, // ttylink
42 95, // supdup
43 101, // hostriame
44 102, // iso-tsap
45 103, // gppitnp
46 104, // acr-nema
47 109, // pop2
48 110, // pop3
49 111, // sunrpc
50 113, // auth
51 115, // sftp
52 117, // uucp-path
53 119, // nntp
54 123, // NTP
55 135, // loc-srv /epmap
56 139, // netbios
57 143, // imap2
58 179, // BGP
59 389, // ldap
60 465, // smtp+ssl
61 512, // print / exec
62 513, // login
63 514, // shell
64 515, // printer
65 526, // tempo
66 530, // courier
67 531, // chat
68 532, // netnews
69 540, // uucp
70 556, // remotefs
71 563, // nntp+ssl
72 587, // stmp?
73 601, // ??
74 636, // ldap+ssl
75 993, // ldap+ssl
76 995, // pop3+ssl
77 2049, // nfs
78 3659, // apple-sasl / PasswordServer
79 4045, // lockd
80 6000, // X11
81 6665, // Alternate IRC [Apple addition]
82 6666, // Alternate IRC [Apple addition]
83 6667, // Standard IRC [Apple addition]
84 6668, // Alternate IRC [Apple addition]
85 6669, // Alternate IRC [Apple addition]
86 0xFFFF, // Used to block all invalid port numbers (see
87 // third_party/WebKit/Source/platform/weborigin/KURL.cpp,
88 // KURL::port())
91 // FTP overrides the following restricted ports.
92 const int kAllowedFtpPorts[] = {
93 21, // ftp data
94 22, // ssh
97 base::LazyInstance<std::multiset<int>>::Leaky g_explicitly_allowed_ports =
98 LAZY_INSTANCE_INITIALIZER;
100 } // namespace
102 bool IsPortValid(int port) {
103 return port >= 0 && port <= std::numeric_limits<uint16_t>::max();
106 bool IsWellKnownPort(int port) {
107 return port >= 0 && port < 1024;
110 bool IsPortAllowedForScheme(int port, const std::string& url_scheme) {
111 // Reject invalid ports.
112 if (!IsPortValid(port))
113 return false;
115 // Allow explitly allowed ports for any scheme.
116 if (g_explicitly_allowed_ports.Get().count(port) > 0)
117 return true;
119 // FTP requests have an extra set of whitelisted schemes.
120 if (base::LowerCaseEqualsASCII(url_scheme, url::kFtpScheme)) {
121 for (int allowed_ftp_port : kAllowedFtpPorts) {
122 if (allowed_ftp_port == port)
123 return true;
127 // Finally check against the generic list of restricted ports for all
128 // schemes.
129 for (int restricted_port : kRestrictedPorts) {
130 if (restricted_port == port)
131 return false;
134 return true;
137 size_t GetCountOfExplicitlyAllowedPorts() {
138 return g_explicitly_allowed_ports.Get().size();
141 // Specifies a comma separated list of port numbers that should be accepted
142 // despite bans. If the string is invalid no allowed ports are stored.
143 void SetExplicitlyAllowedPorts(const std::string& allowed_ports) {
144 if (allowed_ports.empty())
145 return;
147 std::multiset<int> ports;
148 size_t last = 0;
149 size_t size = allowed_ports.size();
150 // The comma delimiter.
151 const std::string::value_type kComma = ',';
153 // Overflow is still possible for evil user inputs.
154 for (size_t i = 0; i <= size; ++i) {
155 // The string should be composed of only digits and commas.
156 if (i != size && !base::IsAsciiDigit(allowed_ports[i]) &&
157 (allowed_ports[i] != kComma))
158 return;
159 if (i == size || allowed_ports[i] == kComma) {
160 if (i > last) {
161 int port;
162 base::StringToInt(base::StringPiece(allowed_ports.begin() + last,
163 allowed_ports.begin() + i),
164 &port);
165 ports.insert(port);
167 last = i + 1;
170 g_explicitly_allowed_ports.Get() = ports;
173 ScopedPortException::ScopedPortException(int port) : port_(port) {
174 g_explicitly_allowed_ports.Get().insert(port);
177 ScopedPortException::~ScopedPortException() {
178 std::multiset<int>::iterator it =
179 g_explicitly_allowed_ports.Get().find(port_);
180 if (it != g_explicitly_allowed_ports.Get().end())
181 g_explicitly_allowed_ports.Get().erase(it);
182 else
183 NOTREACHED();
186 } // namespace net