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