1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "net/base/port_util.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <limits>
8*6777b538SAndroid Build Coastguard Worker #include <set>
9*6777b538SAndroid Build Coastguard Worker
10*6777b538SAndroid Build Coastguard Worker #include "base/containers/fixed_flat_map.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/lazy_instance.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_functions.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/notreached.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
17*6777b538SAndroid Build Coastguard Worker #include "url/url_constants.h"
18*6777b538SAndroid Build Coastguard Worker
19*6777b538SAndroid Build Coastguard Worker namespace net {
20*6777b538SAndroid Build Coastguard Worker
21*6777b538SAndroid Build Coastguard Worker namespace {
22*6777b538SAndroid Build Coastguard Worker
23*6777b538SAndroid Build Coastguard Worker // The general list of blocked ports. Will be blocked unless a specific
24*6777b538SAndroid Build Coastguard Worker // protocol overrides it. (Ex: ftp can use port 21)
25*6777b538SAndroid Build Coastguard Worker // When adding a port to the list, consider also adding it to kAllowablePorts,
26*6777b538SAndroid Build Coastguard Worker // below. See <https://fetch.spec.whatwg.org/#port-blocking>.
27*6777b538SAndroid Build Coastguard Worker const int kRestrictedPorts[] = {
28*6777b538SAndroid Build Coastguard Worker 1, // tcpmux
29*6777b538SAndroid Build Coastguard Worker 7, // echo
30*6777b538SAndroid Build Coastguard Worker 9, // discard
31*6777b538SAndroid Build Coastguard Worker 11, // systat
32*6777b538SAndroid Build Coastguard Worker 13, // daytime
33*6777b538SAndroid Build Coastguard Worker 15, // netstat
34*6777b538SAndroid Build Coastguard Worker 17, // qotd
35*6777b538SAndroid Build Coastguard Worker 19, // chargen
36*6777b538SAndroid Build Coastguard Worker 20, // ftp data
37*6777b538SAndroid Build Coastguard Worker 21, // ftp access
38*6777b538SAndroid Build Coastguard Worker 22, // ssh
39*6777b538SAndroid Build Coastguard Worker 23, // telnet
40*6777b538SAndroid Build Coastguard Worker 25, // smtp
41*6777b538SAndroid Build Coastguard Worker 37, // time
42*6777b538SAndroid Build Coastguard Worker 42, // name
43*6777b538SAndroid Build Coastguard Worker 43, // nicname
44*6777b538SAndroid Build Coastguard Worker 53, // domain
45*6777b538SAndroid Build Coastguard Worker 69, // tftp
46*6777b538SAndroid Build Coastguard Worker 77, // priv-rjs
47*6777b538SAndroid Build Coastguard Worker 79, // finger
48*6777b538SAndroid Build Coastguard Worker 87, // ttylink
49*6777b538SAndroid Build Coastguard Worker 95, // supdup
50*6777b538SAndroid Build Coastguard Worker 101, // hostriame
51*6777b538SAndroid Build Coastguard Worker 102, // iso-tsap
52*6777b538SAndroid Build Coastguard Worker 103, // gppitnp
53*6777b538SAndroid Build Coastguard Worker 104, // acr-nema
54*6777b538SAndroid Build Coastguard Worker 109, // pop2
55*6777b538SAndroid Build Coastguard Worker 110, // pop3
56*6777b538SAndroid Build Coastguard Worker 111, // sunrpc
57*6777b538SAndroid Build Coastguard Worker 113, // auth
58*6777b538SAndroid Build Coastguard Worker 115, // sftp
59*6777b538SAndroid Build Coastguard Worker 117, // uucp-path
60*6777b538SAndroid Build Coastguard Worker 119, // nntp
61*6777b538SAndroid Build Coastguard Worker 123, // NTP
62*6777b538SAndroid Build Coastguard Worker 135, // loc-srv /epmap
63*6777b538SAndroid Build Coastguard Worker 137, // netbios
64*6777b538SAndroid Build Coastguard Worker 139, // netbios
65*6777b538SAndroid Build Coastguard Worker 143, // imap2
66*6777b538SAndroid Build Coastguard Worker 161, // snmp
67*6777b538SAndroid Build Coastguard Worker 179, // BGP
68*6777b538SAndroid Build Coastguard Worker 389, // ldap
69*6777b538SAndroid Build Coastguard Worker 427, // SLP (Also used by Apple Filing Protocol)
70*6777b538SAndroid Build Coastguard Worker 465, // smtp+ssl
71*6777b538SAndroid Build Coastguard Worker 512, // print / exec
72*6777b538SAndroid Build Coastguard Worker 513, // login
73*6777b538SAndroid Build Coastguard Worker 514, // shell
74*6777b538SAndroid Build Coastguard Worker 515, // printer
75*6777b538SAndroid Build Coastguard Worker 526, // tempo
76*6777b538SAndroid Build Coastguard Worker 530, // courier
77*6777b538SAndroid Build Coastguard Worker 531, // chat
78*6777b538SAndroid Build Coastguard Worker 532, // netnews
79*6777b538SAndroid Build Coastguard Worker 540, // uucp
80*6777b538SAndroid Build Coastguard Worker 548, // AFP (Apple Filing Protocol)
81*6777b538SAndroid Build Coastguard Worker 554, // rtsp
82*6777b538SAndroid Build Coastguard Worker 556, // remotefs
83*6777b538SAndroid Build Coastguard Worker 563, // nntp+ssl
84*6777b538SAndroid Build Coastguard Worker 587, // smtp (rfc6409)
85*6777b538SAndroid Build Coastguard Worker 601, // syslog-conn (rfc3195)
86*6777b538SAndroid Build Coastguard Worker 636, // ldap+ssl
87*6777b538SAndroid Build Coastguard Worker 989, // ftps-data
88*6777b538SAndroid Build Coastguard Worker 990, // ftps
89*6777b538SAndroid Build Coastguard Worker 993, // ldap+ssl
90*6777b538SAndroid Build Coastguard Worker 995, // pop3+ssl
91*6777b538SAndroid Build Coastguard Worker 1719, // h323gatestat
92*6777b538SAndroid Build Coastguard Worker 1720, // h323hostcall
93*6777b538SAndroid Build Coastguard Worker 1723, // pptp
94*6777b538SAndroid Build Coastguard Worker 2049, // nfs
95*6777b538SAndroid Build Coastguard Worker 3659, // apple-sasl / PasswordServer
96*6777b538SAndroid Build Coastguard Worker 4045, // lockd
97*6777b538SAndroid Build Coastguard Worker 5060, // sip
98*6777b538SAndroid Build Coastguard Worker 5061, // sips
99*6777b538SAndroid Build Coastguard Worker 6000, // X11
100*6777b538SAndroid Build Coastguard Worker 6566, // sane-port
101*6777b538SAndroid Build Coastguard Worker 6665, // Alternate IRC [Apple addition]
102*6777b538SAndroid Build Coastguard Worker 6666, // Alternate IRC [Apple addition]
103*6777b538SAndroid Build Coastguard Worker 6667, // Standard IRC [Apple addition]
104*6777b538SAndroid Build Coastguard Worker 6668, // Alternate IRC [Apple addition]
105*6777b538SAndroid Build Coastguard Worker 6669, // Alternate IRC [Apple addition]
106*6777b538SAndroid Build Coastguard Worker 6697, // IRC + TLS
107*6777b538SAndroid Build Coastguard Worker 10080, // Amanda
108*6777b538SAndroid Build Coastguard Worker };
109*6777b538SAndroid Build Coastguard Worker
110*6777b538SAndroid Build Coastguard Worker base::LazyInstance<std::multiset<int>>::Leaky g_explicitly_allowed_ports =
111*6777b538SAndroid Build Coastguard Worker LAZY_INSTANCE_INITIALIZER;
112*6777b538SAndroid Build Coastguard Worker
113*6777b538SAndroid Build Coastguard Worker // List of ports which are permitted to be reenabled despite being in
114*6777b538SAndroid Build Coastguard Worker // kRestrictedList. When adding an port to this list you should also update the
115*6777b538SAndroid Build Coastguard Worker // enterprise policy to document the fact that the value can be set. Ports
116*6777b538SAndroid Build Coastguard Worker // should only remain in this list for about a year to give time for users to
117*6777b538SAndroid Build Coastguard Worker // migrate off while stopping them from becoming permanent parts of the web
118*6777b538SAndroid Build Coastguard Worker // platform.
119*6777b538SAndroid Build Coastguard Worker constexpr int kAllowablePorts[] = {};
120*6777b538SAndroid Build Coastguard Worker
121*6777b538SAndroid Build Coastguard Worker int g_scoped_allowable_port = 0;
122*6777b538SAndroid Build Coastguard Worker
123*6777b538SAndroid Build Coastguard Worker } // namespace
124*6777b538SAndroid Build Coastguard Worker
IsPortValid(int port)125*6777b538SAndroid Build Coastguard Worker bool IsPortValid(int port) {
126*6777b538SAndroid Build Coastguard Worker return port >= 0 && port <= std::numeric_limits<uint16_t>::max();
127*6777b538SAndroid Build Coastguard Worker }
128*6777b538SAndroid Build Coastguard Worker
IsWellKnownPort(int port)129*6777b538SAndroid Build Coastguard Worker bool IsWellKnownPort(int port) {
130*6777b538SAndroid Build Coastguard Worker return port >= 0 && port < 1024;
131*6777b538SAndroid Build Coastguard Worker }
132*6777b538SAndroid Build Coastguard Worker
IsPortAllowedForScheme(int port,std::string_view url_scheme)133*6777b538SAndroid Build Coastguard Worker bool IsPortAllowedForScheme(int port, std::string_view url_scheme) {
134*6777b538SAndroid Build Coastguard Worker // Reject invalid ports.
135*6777b538SAndroid Build Coastguard Worker if (!IsPortValid(port))
136*6777b538SAndroid Build Coastguard Worker return false;
137*6777b538SAndroid Build Coastguard Worker
138*6777b538SAndroid Build Coastguard Worker // Allow explicitly allowed ports for any scheme.
139*6777b538SAndroid Build Coastguard Worker if (g_explicitly_allowed_ports.Get().count(port) > 0)
140*6777b538SAndroid Build Coastguard Worker return true;
141*6777b538SAndroid Build Coastguard Worker
142*6777b538SAndroid Build Coastguard Worker // Finally check against the generic list of restricted ports for all
143*6777b538SAndroid Build Coastguard Worker // schemes.
144*6777b538SAndroid Build Coastguard Worker for (int restricted_port : kRestrictedPorts) {
145*6777b538SAndroid Build Coastguard Worker if (restricted_port == port)
146*6777b538SAndroid Build Coastguard Worker return false;
147*6777b538SAndroid Build Coastguard Worker }
148*6777b538SAndroid Build Coastguard Worker
149*6777b538SAndroid Build Coastguard Worker return true;
150*6777b538SAndroid Build Coastguard Worker }
151*6777b538SAndroid Build Coastguard Worker
GetCountOfExplicitlyAllowedPorts()152*6777b538SAndroid Build Coastguard Worker size_t GetCountOfExplicitlyAllowedPorts() {
153*6777b538SAndroid Build Coastguard Worker return g_explicitly_allowed_ports.Get().size();
154*6777b538SAndroid Build Coastguard Worker }
155*6777b538SAndroid Build Coastguard Worker
156*6777b538SAndroid Build Coastguard Worker // Specifies a comma separated list of port numbers that should be accepted
157*6777b538SAndroid Build Coastguard Worker // despite bans. If the string is invalid no allowed ports are stored.
SetExplicitlyAllowedPorts(base::span<const uint16_t> allowed_ports)158*6777b538SAndroid Build Coastguard Worker void SetExplicitlyAllowedPorts(base::span<const uint16_t> allowed_ports) {
159*6777b538SAndroid Build Coastguard Worker std::multiset<int> ports(allowed_ports.begin(), allowed_ports.end());
160*6777b538SAndroid Build Coastguard Worker g_explicitly_allowed_ports.Get() = std::move(ports);
161*6777b538SAndroid Build Coastguard Worker }
162*6777b538SAndroid Build Coastguard Worker
ScopedPortException(int port)163*6777b538SAndroid Build Coastguard Worker ScopedPortException::ScopedPortException(int port) : port_(port) {
164*6777b538SAndroid Build Coastguard Worker g_explicitly_allowed_ports.Get().insert(port);
165*6777b538SAndroid Build Coastguard Worker }
166*6777b538SAndroid Build Coastguard Worker
~ScopedPortException()167*6777b538SAndroid Build Coastguard Worker ScopedPortException::~ScopedPortException() {
168*6777b538SAndroid Build Coastguard Worker auto it = g_explicitly_allowed_ports.Get().find(port_);
169*6777b538SAndroid Build Coastguard Worker if (it != g_explicitly_allowed_ports.Get().end())
170*6777b538SAndroid Build Coastguard Worker g_explicitly_allowed_ports.Get().erase(it);
171*6777b538SAndroid Build Coastguard Worker else
172*6777b538SAndroid Build Coastguard Worker NOTREACHED();
173*6777b538SAndroid Build Coastguard Worker }
174*6777b538SAndroid Build Coastguard Worker
IsAllowablePort(int port)175*6777b538SAndroid Build Coastguard Worker NET_EXPORT bool IsAllowablePort(int port) {
176*6777b538SAndroid Build Coastguard Worker for (auto allowable_port : kAllowablePorts) {
177*6777b538SAndroid Build Coastguard Worker if (port == allowable_port) {
178*6777b538SAndroid Build Coastguard Worker return true;
179*6777b538SAndroid Build Coastguard Worker }
180*6777b538SAndroid Build Coastguard Worker }
181*6777b538SAndroid Build Coastguard Worker
182*6777b538SAndroid Build Coastguard Worker if (port == g_scoped_allowable_port)
183*6777b538SAndroid Build Coastguard Worker return true;
184*6777b538SAndroid Build Coastguard Worker
185*6777b538SAndroid Build Coastguard Worker return false;
186*6777b538SAndroid Build Coastguard Worker }
187*6777b538SAndroid Build Coastguard Worker
ScopedAllowablePortForTesting(int port)188*6777b538SAndroid Build Coastguard Worker ScopedAllowablePortForTesting::ScopedAllowablePortForTesting(int port) {
189*6777b538SAndroid Build Coastguard Worker DCHECK_EQ(g_scoped_allowable_port, 0);
190*6777b538SAndroid Build Coastguard Worker g_scoped_allowable_port = port;
191*6777b538SAndroid Build Coastguard Worker }
192*6777b538SAndroid Build Coastguard Worker
~ScopedAllowablePortForTesting()193*6777b538SAndroid Build Coastguard Worker ScopedAllowablePortForTesting::~ScopedAllowablePortForTesting() {
194*6777b538SAndroid Build Coastguard Worker g_scoped_allowable_port = 0;
195*6777b538SAndroid Build Coastguard Worker }
196*6777b538SAndroid Build Coastguard Worker
197*6777b538SAndroid Build Coastguard Worker } // namespace net
198