diff options
author | mirandac@chromium.org <mirandac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-31 16:20:14 +0000 |
---|---|---|
committer | mirandac@chromium.org <mirandac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-31 16:20:14 +0000 |
commit | bcb84f8b62103f881ffcb50e8aed0e9bd1a2d821 (patch) | |
tree | c6cf85e5249bdd54dc57b463e1acca0db39fd0ac /net | |
parent | b65272fdbd41b9571cb12fdb63804761e405f0ce (diff) | |
download | chromium_src-bcb84f8b62103f881ffcb50e8aed0e9bd1a2d821.zip chromium_src-bcb84f8b62103f881ffcb50e8aed0e9bd1a2d821.tar.gz chromium_src-bcb84f8b62103f881ffcb50e8aed0e9bd1a2d821.tar.bz2 |
Adding command-line option to override bans on certain port numbers through a comma-separated list of ports.
BUG= http://crbug.com/18307
TEST= url_request_unittest, use commandline flag allowed_ports=1,600. Navigate to http://www.google.com:1 or http://www.google.com:600. You should not get an ERR_UNSAFE_PORT, it will attempt to load the page.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24883 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/url_request/url_request_http_job.cc | 48 | ||||
-rw-r--r-- | net/url_request/url_request_http_job.h | 15 | ||||
-rw-r--r-- | net/url_request/url_request_unittest.cc | 17 |
3 files changed, 79 insertions, 1 deletions
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc index b0438fa..ada94c3 100644 --- a/net/url_request/url_request_http_job.cc +++ b/net/url_request/url_request_http_job.cc @@ -29,6 +29,9 @@ #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_error_job.h" +// static +std::set<int> URLRequestHttpJob::explicitly_allowed_ports_; + // TODO(darin): make sure the port blocking code is not lost // static @@ -36,7 +39,8 @@ URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, const std::string& scheme) { DCHECK(scheme == "http" || scheme == "https"); - if (!net::IsPortAllowedByDefault(request->url().IntPort())) + int port = request->url().IntPort(); + if (!net::IsPortAllowedByDefault(port) && !IsPortAllowedByOverride(port)) return new URLRequestErrorJob(request, net::ERR_UNSAFE_PORT); if (!request->context() || @@ -58,6 +62,35 @@ URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request, return new URLRequestHttpJob(request); } +// static +void URLRequestHttpJob::SetExplicitlyAllowedPorts( + const std::wstring& allowed_ports) { + if (allowed_ports.empty()) + return; + + std::set<int> ports; + size_t last = 0; + size_t size = allowed_ports.size(); + // The comma delimiter. + const std::wstring::value_type kComma = L','; + + // 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 && !IsAsciiDigit(allowed_ports[i]) && + (allowed_ports[i] != kComma)) + return; + if (i == size || allowed_ports[i] == kComma) { + size_t length = i - last; + if (length > 0) + ports.insert(StringToInt(WideToASCII( + allowed_ports.substr(last, length)))); + last = i + 1; + } + } + explicitly_allowed_ports_ = ports; +} + URLRequestHttpJob::URLRequestHttpJob(URLRequest* request) : URLRequestJob(request), context_(request->context()), @@ -345,6 +378,19 @@ void URLRequestHttpJob::RestartTransactionWithAuth( this, &URLRequestHttpJob::OnStartCompleted, rv)); } +// static +bool URLRequestHttpJob::IsPortAllowedByOverride(int port) { + if (explicitly_allowed_ports().empty()) + return false; + + std::set<int>::const_iterator it = + std::find(explicitly_allowed_ports().begin(), + explicitly_allowed_ports().end(), + port); + + return it != explicitly_allowed_ports().end(); +} + void URLRequestHttpJob::CancelAuth() { // Proxy gets set first, then WWW. if (proxy_auth_state_ == net::AUTH_STATE_NEED_AUTH) { diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h index fdb32ae..48c155d 100644 --- a/net/url_request/url_request_http_job.h +++ b/net/url_request/url_request_http_job.h @@ -5,6 +5,7 @@ #ifndef NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_H_ #define NET_URL_REQUEST_URL_REQUEST_HTTP_JOB_H_ +#include <set> #include <string> #include <vector> @@ -25,6 +26,12 @@ class URLRequestContext; class URLRequestHttpJob : public URLRequestJob { public: static URLRequestJob* Factory(URLRequest* request, const std::string& scheme); + // Specifies a comma separated list of port numbers that should be accepted + // despite bans. If the string is invalid no allowed ports are stored. + static void SetExplicitlyAllowedPorts(const std::wstring& allowed_ports); + static const std::set<int>& explicitly_allowed_ports() { + return explicitly_allowed_ports_; + } virtual ~URLRequestHttpJob(); @@ -78,6 +85,10 @@ class URLRequestHttpJob : public URLRequestJob { void RestartTransactionWithAuth(const std::wstring& username, const std::wstring& password); + // Check if banned |port| has been overriden by an entry in + // |explicitly_allowed_ports_|. + static bool IsPortAllowedByOverride(int port); + // Keep a reference to the url request context to be sure it's not deleted // before us. scoped_refptr<URLRequestContext> context_; @@ -115,6 +126,10 @@ class URLRequestHttpJob : public URLRequestJob { // For recording of stats, we need to remember if this is cached content. bool is_cached_content_; + private: + // Holds a list of ports that should be accepted despite bans. + static std::set<int> explicitly_allowed_ports_; + DISALLOW_COPY_AND_ASSIGN(URLRequestHttpJob); }; diff --git a/net/url_request/url_request_unittest.cc b/net/url_request/url_request_unittest.cc index 0dc7992..6f4338c 100644 --- a/net/url_request/url_request_unittest.cc +++ b/net/url_request/url_request_unittest.cc @@ -37,6 +37,7 @@ #include "net/socket/ssl_test_util.h" #include "net/url_request/url_request.h" #include "net/url_request/url_request_file_dir_job.h" +#include "net/url_request/url_request_http_job.h" #include "net/url_request/url_request_test_job.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -223,6 +224,22 @@ TEST_F(URLRequestTestHTTP, GetTest) { #endif } +TEST_F(URLRequestTestHTTP, SetExplicitlyAllowedPortsTest) { + std::wstring invalid[] = { L"1,2,a", L"'1','2'", L"1, 2, 3", L"1 0,11,12" }; + std::wstring valid[] = { L"", L"1", L"1,2", L"1,2,3", L"10,11,12,13" }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(invalid); ++i) { + URLRequestHttpJob::SetExplicitlyAllowedPorts(invalid[i]); + EXPECT_EQ(0, static_cast<int>( + URLRequestHttpJob::explicitly_allowed_ports().size())); + } + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(valid); ++i) { + URLRequestHttpJob::SetExplicitlyAllowedPorts(valid[i]); + EXPECT_EQ(i, URLRequestHttpJob::explicitly_allowed_ports().size()); + } +} + TEST_F(URLRequestTest, QuitTest) { // Don't use shared server here because we order it to quit. // It would impact other tests. |