mirror of
https://github.com/klzgrad/naiveproxy.git
synced 2024-11-28 08:16:09 +03:00
187 lines
4.9 KiB
C++
187 lines
4.9 KiB
C++
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||
|
// 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/lazy_instance.h"
|
||
|
#include "base/logging.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 ports 20 and 21)
|
||
|
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
|
||
|
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
|
||
|
139, // netbios
|
||
|
143, // imap2
|
||
|
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)
|
||
|
556, // remotefs
|
||
|
563, // nntp+ssl
|
||
|
587, // stmp?
|
||
|
601, // ??
|
||
|
636, // ldap+ssl
|
||
|
993, // ldap+ssl
|
||
|
995, // pop3+ssl
|
||
|
2049, // nfs
|
||
|
3659, // apple-sasl / PasswordServer
|
||
|
4045, // lockd
|
||
|
6000, // X11
|
||
|
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
|
||
|
};
|
||
|
|
||
|
// FTP overrides the following restricted port.
|
||
|
const int kAllowedFtpPorts[] = {
|
||
|
21, // ftp data
|
||
|
};
|
||
|
|
||
|
base::LazyInstance<std::multiset<int>>::Leaky g_explicitly_allowed_ports =
|
||
|
LAZY_INSTANCE_INITIALIZER;
|
||
|
|
||
|
} // 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, const std::string& url_scheme) {
|
||
|
// Reject invalid ports.
|
||
|
if (!IsPortValid(port))
|
||
|
return false;
|
||
|
|
||
|
// Allow explitly allowed ports for any scheme.
|
||
|
if (g_explicitly_allowed_ports.Get().count(port) > 0)
|
||
|
return true;
|
||
|
|
||
|
// FTP requests have an extra set of whitelisted schemes.
|
||
|
if (base::LowerCaseEqualsASCII(url_scheme, url::kFtpScheme)) {
|
||
|
for (int allowed_ftp_port : kAllowedFtpPorts) {
|
||
|
if (allowed_ftp_port == port)
|
||
|
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(const std::string& allowed_ports) {
|
||
|
if (allowed_ports.empty())
|
||
|
return;
|
||
|
|
||
|
std::multiset<int> ports;
|
||
|
size_t last = 0;
|
||
|
size_t size = allowed_ports.size();
|
||
|
// The comma delimiter.
|
||
|
const std::string::value_type kComma = ',';
|
||
|
|
||
|
// Overflow is still possible for evil user inputs.
|
||
|
for (size_t i = 0; i <= size; ++i) {
|
||
|
// The string should be composed of only digits and commas.
|
||
|
if (i != size && !base::IsAsciiDigit(allowed_ports[i]) &&
|
||
|
(allowed_ports[i] != kComma))
|
||
|
return;
|
||
|
if (i == size || allowed_ports[i] == kComma) {
|
||
|
if (i > last) {
|
||
|
int port;
|
||
|
base::StringToInt(base::StringPiece(allowed_ports.begin() + last,
|
||
|
allowed_ports.begin() + i),
|
||
|
&port);
|
||
|
ports.insert(port);
|
||
|
}
|
||
|
last = i + 1;
|
||
|
}
|
||
|
}
|
||
|
g_explicitly_allowed_ports.Get() = ports;
|
||
|
}
|
||
|
|
||
|
ScopedPortException::ScopedPortException(int port) : port_(port) {
|
||
|
g_explicitly_allowed_ports.Get().insert(port);
|
||
|
}
|
||
|
|
||
|
ScopedPortException::~ScopedPortException() {
|
||
|
std::multiset<int>::iterator 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();
|
||
|
}
|
||
|
|
||
|
} // namespace net
|