From 152423b7de07db4edb26a66bae4a9586e62262a8 Mon Sep 17 00:00:00 2001 From: Taylor `Riastradh' Campbell Date: Thu, 1 Feb 2018 00:00:14 +0000 Subject: [PATCH 01/11] SOCKS5 authentication support. --- chromium_src/BUILD.gn | 11 + chromium_src/net/socket/socks_auth_null.cc | 32 ++ chromium_src/net/socket/socks_auth_null.h | 34 ++ .../socket/socks_auth_username_password.cc | 135 +++++ .../net/socket/socks_auth_username_password.h | 53 ++ patches/master_patch.patch | 482 ++++++++++++++++++ 6 files changed, 747 insertions(+) create mode 100644 chromium_src/net/socket/socks_auth_null.cc create mode 100644 chromium_src/net/socket/socks_auth_null.h create mode 100644 chromium_src/net/socket/socks_auth_username_password.cc create mode 100644 chromium_src/net/socket/socks_auth_username_password.h diff --git a/chromium_src/BUILD.gn b/chromium_src/BUILD.gn index 73bde456d3..a64c55b0b5 100644 --- a/chromium_src/BUILD.gn +++ b/chromium_src/BUILD.gn @@ -144,6 +144,7 @@ source_set("browser") { ":favicon", ":history", ":metrics", + ":net", ":password_manager", ":sessions", ":web_data", @@ -1196,3 +1197,13 @@ source_set("sessions") { "//third_party/protobuf:protobuf_lite", ] } + +source_set("net") { + sources = [ + "net/socket/socks_auth_null.cc", + "net/socket/socks_auth_username_password.cc", + ] + deps = [ + "//net", + ] +} diff --git a/chromium_src/net/socket/socks_auth_null.cc b/chromium_src/net/socket/socks_auth_null.cc new file mode 100644 index 0000000000..7f0b7c1da6 --- /dev/null +++ b/chromium_src/net/socket/socks_auth_null.cc @@ -0,0 +1,32 @@ +// Copyright 2017 The Brave 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/socket/socks_auth_null.h" + +namespace net { + +// Null authentication method. + +SOCKSAuthNull::SOCKSAuthNull() = default; + +SOCKSAuthNull::~SOCKSAuthNull() = default; + +SOCKSAuthState* SOCKSAuthNull::Initialize() const { + return new SOCKSAuthNull::State; +} + +SOCKSAuthNull::State::State() = default; + +SOCKSAuthNull::State::~State() = default; + +uint8_t SOCKSAuthNull::State::method_number() { + return 0x00; +} + +int SOCKSAuthNull::State::Do(int rv, ClientSocketHandle& socket, + CompletionCallback& callback) { + return OK; +} + +} // namespace net diff --git a/chromium_src/net/socket/socks_auth_null.h b/chromium_src/net/socket/socks_auth_null.h new file mode 100644 index 0000000000..5337ed27b8 --- /dev/null +++ b/chromium_src/net/socket/socks_auth_null.h @@ -0,0 +1,34 @@ +// Copyright 2017 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_SOCKET_SOCKS_AUTH_NULL_H_ +#define NET_SOCKET_SOCKS_AUTH_NULL_H_ + +#include "net/socket/socks_client_socket_pool.h" + +namespace net { + +// Null authentication method. +class NET_EXPORT_PRIVATE SOCKSAuthNull : public SOCKSAuth { + public: + SOCKSAuthNull(); + ~SOCKSAuthNull() override; + SOCKSAuthState* Initialize() const override; + private: + class State : public SOCKSAuthState { + public: + ~State() override; + uint8_t method_number() override; + int Do(int, ClientSocketHandle&, CompletionCallback&) override; + private: + friend class SOCKSAuthNull; + State(); + DISALLOW_COPY_AND_ASSIGN(State); + }; + DISALLOW_COPY_AND_ASSIGN(SOCKSAuthNull); +}; + +} // namespace net + +#endif // NET_SOCKET_SOCKS_AUTH_NULL_H_ diff --git a/chromium_src/net/socket/socks_auth_username_password.cc b/chromium_src/net/socket/socks_auth_username_password.cc new file mode 100644 index 0000000000..c62508502c --- /dev/null +++ b/chromium_src/net/socket/socks_auth_username_password.cc @@ -0,0 +1,135 @@ +// Copyright 2017 The Brave 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/io_buffer.h" +#include "net/socket/socks_auth_username_password.h" + +namespace net { + +SOCKSAuthUsernamePassword::SOCKSAuthUsernamePassword( + const std::string& username, const std::string& password) + : username_(username), password_(password) { +} + +SOCKSAuthUsernamePassword::~SOCKSAuthUsernamePassword() = default; + +SOCKSAuthState* SOCKSAuthUsernamePassword::Initialize() const { + return new SOCKSAuthUsernamePassword::State(this); +} + +SOCKSAuthUsernamePassword::State::State(const SOCKSAuthUsernamePassword* auth) + : auth_(auth), + next_state_(STATE_INIT_WRITE) { +} + +SOCKSAuthUsernamePassword::State::~State() = default; + +uint8_t SOCKSAuthUsernamePassword::State::method_number() { + return 0x02; +} + +static const size_t kSOCKSAuthUsernamePasswordResponseLen = 2; + +int SOCKSAuthUsernamePassword::State::Do( + int rv, ClientSocketHandle& transport, CompletionCallback& callback) { + const NetLogWithSource& net_log = transport.socket()->NetLog(); + do { + switch (next_state_) { + case STATE_INIT_WRITE: { + DCHECK_EQ(OK, rv); + // Initialize the buffer with  + // 0x01, usernamelen, username, passwordlen, password + size_t usernamelen = auth_->username_.size(); + size_t passwordlen = auth_->password_.size(); + buffer_ = std::string(1 + 1 + usernamelen + 1 + passwordlen, 0); + buffer_[0] = 0x01; + buffer_[1] = usernamelen; + buffer_.replace(2, usernamelen, auth_->username_); + buffer_[2 + usernamelen] = passwordlen; + buffer_.replace(2 + usernamelen + 1, passwordlen, auth_->password_); + DCHECK_EQ(buffer_.size(), 2 + usernamelen + 1 + passwordlen); + buffer_left_ = buffer_.size(); + next_state_ = STATE_WRITE; + rv = OK; + break; + } + case STATE_WRITE: + DCHECK_EQ(OK, rv); + DCHECK_LT(0, buffer_left_); + iobuf_ = new IOBuffer(buffer_left_); + memcpy(iobuf_->data(), + &buffer_.data()[buffer_.size() - buffer_left_], + buffer_left_); + next_state_ = STATE_WRITE_COMPLETE; + net_log.BeginEvent(NetLogEventType::SOCKS5_AUTH_WRITE); + rv = transport.socket()->Write(iobuf_.get(), buffer_left_, callback); + break; + + case STATE_WRITE_COMPLETE: + // TODO(riastradh): Zero iobuf? Zero buffer? + net_log.EndEventWithNetErrorCode(NetLogEventType::SOCKS5_AUTH_WRITE, + std::max(rv, 0)); + if (rv < 0) { + next_state_ = STATE_BAD; + return rv; + } + DCHECK_LE(static_cast(rv), buffer_left_); + buffer_left_ -= rv; + next_state_ = (buffer_left_ == 0 ? STATE_INIT_READ : STATE_WRITE); + rv = OK; + break; + + case STATE_INIT_READ: + DCHECK_EQ(OK, rv); + buffer_.clear(); + buffer_left_ = kSOCKSAuthUsernamePasswordResponseLen; + iobuf_ = new IOBuffer(buffer_left_); + next_state_ = STATE_READ; + rv = OK; + break; + + case STATE_READ: + DCHECK_EQ(OK, rv); + iobuf_ = new IOBuffer(buffer_left_); + next_state_ = STATE_READ_COMPLETE; + net_log.BeginEvent(NetLogEventType::SOCKS5_AUTH_READ); + rv = transport.socket()->Read(iobuf_.get(), buffer_left_, callback); + break; + + case STATE_READ_COMPLETE: + net_log.EndEventWithNetErrorCode(NetLogEventType::SOCKS5_AUTH_READ, + std::max(rv, 0)); + if (rv < 0) { + next_state_ = STATE_BAD; + return rv; + } + DCHECK_LE(static_cast(rv), buffer_left_); + buffer_.append(iobuf_->data(), rv); + buffer_left_ -= rv; + next_state_ = (buffer_left_ == 0 ? STATE_DONE : STATE_READ); + rv = OK; + break; + + case STATE_DONE: { + DCHECK_EQ(OK, rv); + DCHECK_EQ(buffer_.size(), kSOCKSAuthUsernamePasswordResponseLen); + static_assert(kSOCKSAuthUsernamePasswordResponseLen == 2, "bad size"); + uint8_t ver = buffer_[0]; + uint8_t status = buffer_[1]; + next_state_ = STATE_BAD; // Caller had better stop here. + if (ver != 0x01 || status != 0x00) + return ERR_FAILED; + return OK; + } + + case STATE_BAD: + default: + NOTREACHED() << "bad state"; + return ERR_UNEXPECTED; + } + } while (rv != ERR_IO_PENDING); + return rv; +} + +} // namespace net diff --git a/chromium_src/net/socket/socks_auth_username_password.h b/chromium_src/net/socket/socks_auth_username_password.h new file mode 100644 index 0000000000..25aea21a7c --- /dev/null +++ b/chromium_src/net/socket/socks_auth_username_password.h @@ -0,0 +1,53 @@ +// Copyright 2017 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_SOCKET_SOCKS_AUTH_USERNAME_PASSWORD_H_ +#define NET_SOCKET_SOCKS_AUTH_USERNAME_PASSWORD_H_ + +#include "net/base/net_export.h" +#include "net/socket/socks_client_socket_pool.h" + +namespace net { + +class IOBuffer; + +class NET_EXPORT_PRIVATE SOCKSAuthUsernamePassword : public SOCKSAuth { + public: + SOCKSAuthUsernamePassword(const std::string&, const std::string&); + ~SOCKSAuthUsernamePassword() override; + SOCKSAuthState* Initialize() const override; + private: + friend class State; + std::string username_; + std::string password_; + class State : public SOCKSAuthState { + public: + ~State() override; + uint8_t method_number() override; + int Do(int, ClientSocketHandle&, CompletionCallback&) override; + private: + friend class SOCKSAuthUsernamePassword; + explicit State(const SOCKSAuthUsernamePassword*); + const SOCKSAuthUsernamePassword* auth_; + enum { + STATE_INIT_WRITE = 0, + STATE_WRITE, + STATE_WRITE_COMPLETE, + STATE_INIT_READ, + STATE_READ, + STATE_READ_COMPLETE, + STATE_DONE, + STATE_BAD, + } next_state_; + scoped_refptr iobuf_; + std::string buffer_; + size_t buffer_left_; + DISALLOW_COPY_AND_ASSIGN(State); + }; + DISALLOW_COPY_AND_ASSIGN(SOCKSAuthUsernamePassword); +}; + +} // namespace net + +#endif // NET_SOCKET_SOCKS_AUTH_USERNAME_PASSWORD_H_ diff --git a/patches/master_patch.patch b/patches/master_patch.patch index 0a34c88032..5a799e323d 100644 --- a/patches/master_patch.patch +++ b/patches/master_patch.patch @@ -2148,6 +2148,488 @@ index 6eaa321ef4b8d5d743cab4448ed695ac1a02fabf..19020dbe84515b22d061a2bb80881592 DCHECK_CALLED_ON_VALID_THREAD(thread_checker_); } +diff --git a/net/log/net_log_event_type_list.h b/net/log/net_log_event_type_list.h +index 551953165f93c8d8e4772f0e905f1c4819aaf3b5..caf6df58e858580b165e6ff689572a3d26525510 100644 +--- a/net/log/net_log_event_type_list.h ++++ b/net/log/net_log_event_type_list.h +@@ -2108,6 +2108,12 @@ EVENT_TYPE(SOCKS5_GREET_WRITE) + // The time spent waiting for the "greeting" response from the SOCKS server. + EVENT_TYPE(SOCKS5_GREET_READ) + ++// The time spent sending authentication to the SOCKS server ++EVENT_TYPE(SOCKS5_AUTH_WRITE) ++ ++// The time spent waiting for the authentication response from the SOCKS server ++EVENT_TYPE(SOCKS5_AUTH_READ) ++ + // The time spent sending the CONNECT request to the SOCKS server. + EVENT_TYPE(SOCKS5_HANDSHAKE_WRITE) + +diff --git a/net/proxy/proxy_server.cc b/net/proxy/proxy_server.cc +index ed81ebbb26b4f439d618c115b32f49249d9284a6..a0e78e5e842fe7804f860f5bd1b7a2cba9903f14 100644 +--- a/net/proxy/proxy_server.cc ++++ b/net/proxy/proxy_server.cc +@@ -65,7 +65,23 @@ ProxyServer::Scheme GetSchemeFromURIInternal(base::StringPiece type) { + } // namespace + + ProxyServer::ProxyServer(Scheme scheme, const HostPortPair& host_port_pair) +- : scheme_(scheme), host_port_pair_(host_port_pair) { ++ : scheme_(scheme), host_port_pair_(host_port_pair), auth_(false) { ++ if (scheme_ == SCHEME_DIRECT || scheme_ == SCHEME_INVALID) { ++ // |host_port_pair| isn't relevant for these special schemes, so none should ++ // have been specified. It is important for this to be consistent since we ++ // do raw field comparisons in the equality and comparison functions. ++ DCHECK(host_port_pair.Equals(HostPortPair())); ++ host_port_pair_ = HostPortPair(); ++ } ++} ++ ++ProxyServer::ProxyServer(Scheme scheme, const HostPortPair& host_port_pair, ++ const std::string& username, ++ const std::string& password) ++ : scheme_(scheme), host_port_pair_(host_port_pair), ++ auth_(true), username_(username), password_(password) { ++ // Authentication is supported only for SOCKS5 proxies. ++ DCHECK(scheme_ == SCHEME_SOCKS5); + if (scheme_ == SCHEME_DIRECT || scheme_ == SCHEME_INVALID) { + // |host_port_pair| isn't relevant for these special schemes, so none should + // have been specified. It is important for this to be consistent since we +@@ -83,6 +99,16 @@ const HostPortPair& ProxyServer::host_port_pair() const { + return host_port_pair_; + } + ++const std::string& ProxyServer::username() const { ++ DCHECK(is_auth()); ++ return username_; ++}; ++ ++const std::string& ProxyServer::password() const { ++ DCHECK(is_auth()); ++ return password_; ++}; ++ + // static + ProxyServer ProxyServer::FromURI(const std::string& uri, + Scheme default_scheme) { +@@ -123,7 +149,8 @@ std::string ProxyServer::ToURI() const { + case SCHEME_SOCKS4: + return std::string("socks4://") + host_port_pair().ToString(); + case SCHEME_SOCKS5: +- return std::string("socks5://") + host_port_pair().ToString(); ++ return std::string("socks5://") + AuthString() + ++ host_port_pair().ToString(); + case SCHEME_HTTPS: + return std::string("https://") + host_port_pair().ToString(); + case SCHEME_QUIC: +@@ -175,7 +202,8 @@ std::string ProxyServer::ToPacString() const { + // For compatibility send SOCKS instead of SOCKS4. + return std::string("SOCKS ") + host_port_pair().ToString(); + case SCHEME_SOCKS5: +- return std::string("SOCKS5 ") + host_port_pair().ToString(); ++ return std::string("SOCKS5 ") + AuthString() + ++ host_port_pair().ToString(); + case SCHEME_HTTPS: + return std::string("HTTPS ") + host_port_pair().ToString(); + case SCHEME_QUIC: +@@ -187,6 +215,16 @@ std::string ProxyServer::ToPacString() const { + } + } + ++std::string ProxyServer::AuthString() const { ++ if (!is_auth()) ++ return ""; ++ std::string auth = username(); ++ if (password().size() > 0) ++ auth += ":" + password(); ++ auth += "@"; ++ return auth; ++}; ++ + // static + int ProxyServer::GetDefaultPortForScheme(Scheme scheme) { + switch (scheme) { +@@ -227,6 +265,24 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( + return ProxyServer(); // Invalid -- DIRECT cannot have a host/port. + + HostPortPair host_port_pair; ++ bool auth = false; ++ std::string username; ++ std::string password; ++ ++ std::string::const_iterator at = std::find(begin, end, '@'); ++ if (at != end) { ++ if (scheme != SCHEME_SOCKS5) ++ return ProxyServer(); // Invalid -- only SOCKS5 has authentication. ++ auth = true; ++ std::string::const_iterator colon = std::find(begin, at, ':'); ++ if (colon != at) { ++ username = std::string(begin, colon); ++ password = std::string(colon + 1, at); ++ } else { ++ username = std::string(begin, at); ++ } ++ begin = at + 1; ++ } + + if (scheme != SCHEME_INVALID && scheme != SCHEME_DIRECT) { + std::string host; +@@ -243,7 +299,10 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( + host_port_pair = HostPortPair(host, static_cast(port)); + } + +- return ProxyServer(scheme, host_port_pair); ++ if (auth) ++ return ProxyServer(scheme, host_port_pair, username, password); ++ else ++ return ProxyServer(scheme, host_port_pair); + } + + } // namespace net +diff --git a/net/proxy/proxy_server.h b/net/proxy/proxy_server.h +index 8de93ea0aa4eff6501675b1bb8c1bbd07cff1222..8d8ca8262e2ee7134bf86d6e1e8ac3eac556d35d 100644 +--- a/net/proxy/proxy_server.h ++++ b/net/proxy/proxy_server.h +@@ -19,7 +19,7 @@ + + namespace net { + +-// ProxyServer encodes the {type, host, port} of a proxy server. ++// ProxyServer encodes the {type, user, pass, host, port} of a proxy server. + // ProxyServer is immutable. + class NET_EXPORT ProxyServer { + public: +@@ -44,6 +44,8 @@ class NET_EXPORT ProxyServer { + ProxyServer() : scheme_(SCHEME_INVALID) {} + + ProxyServer(Scheme scheme, const HostPortPair& host_port_pair); ++ ProxyServer(Scheme scheme, const HostPortPair& host_port_pair, ++ const std::string& username, const std::string& password); + + bool is_valid() const { return scheme_ != SCHEME_INVALID; } + +@@ -67,7 +69,12 @@ class NET_EXPORT ProxyServer { + // Returns true if this ProxyServer is a QUIC proxy. + bool is_quic() const { return scheme_ == SCHEME_QUIC; } + ++ // Returns true if this ProxyServer has username/password authentication ++ bool is_auth() const { return auth_; } ++ + const HostPortPair& host_port_pair() const; ++ const std::string& username() const; ++ const std::string& password() const; + + // Parses from an input with format: + // ["://"][":"] +@@ -146,15 +153,18 @@ class NET_EXPORT ProxyServer { + + bool operator==(const ProxyServer& other) const { + return scheme_ == other.scheme_ && +- host_port_pair_.Equals(other.host_port_pair_); ++ host_port_pair_.Equals(other.host_port_pair_) && ++ username_ == other.username_ && ++ password_ == other.password_; + } + + bool operator!=(const ProxyServer& other) const { return !(*this == other); } + + // Comparator function so this can be placed in a std::map. + bool operator<(const ProxyServer& other) const { +- return std::tie(scheme_, host_port_pair_) < +- std::tie(other.scheme_, other.host_port_pair_); ++ return std::tie(scheme_, host_port_pair_, auth_, username_, password_) < ++ std::tie(other.scheme_, other.host_port_pair_, ++ other.auth_, other.username_, other.password_); + } + + // Returns the estimate of dynamically allocated memory in bytes. +@@ -168,8 +178,15 @@ class NET_EXPORT ProxyServer { + std::string::const_iterator host_and_port_begin, + std::string::const_iterator host_and_port_end); + ++ // Returns the `:@' prefix, if authentication is ++ // enabled, or empty if not. ++ std::string AuthString() const; ++ + Scheme scheme_; + HostPortPair host_port_pair_; ++ bool auth_; ++ std::string username_; ++ std::string password_; + }; + + typedef std::pair HostPortProxyPair; +diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc +index ffec16ff2944915301b2af4ca34b556cbc177b5d..07dcb8111b833292cf59148514064a1356b2b70b 100644 +--- a/net/socket/client_socket_pool_manager.cc ++++ b/net/socket/client_socket_pool_manager.cc +@@ -13,6 +13,7 @@ + #include "net/proxy/proxy_info.h" + #include "net/socket/client_socket_handle.h" + #include "net/socket/client_socket_pool.h" ++#include "net/socket/socks_auth_username_password.h" + #include "net/socket/socks_client_socket_pool.h" + #include "net/socket/ssl_client_socket_pool.h" + #include "net/socket/transport_client_socket_pool.h" +@@ -189,9 +190,20 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type, + connection_group = base::StringPrintf( + "socks%c/%s", socks_version, connection_group.c_str()); + +- socks_params = new SOCKSSocketParams(proxy_tcp_params, +- socks_version == '5', +- origin_host_port); ++ scoped_refptr auth(nullptr); ++ if (proxy_server.is_auth()) { ++ DCHECK_EQ('5', socks_version); ++ const std::string& username = proxy_server.username(); ++ const std::string& password = proxy_server.password(); ++ auth = new SOCKSAuthUsernamePassword(username, password); ++ socks_params = new SOCKSSocketParams(proxy_tcp_params, ++ origin_host_port, ++ auth); ++ } else { ++ socks_params = new SOCKSSocketParams(proxy_tcp_params, ++ socks_version == '5', ++ origin_host_port); ++ } + } + } + +diff --git a/net/socket/socks5_client_socket.cc b/net/socket/socks5_client_socket.cc +index 19cdfddbe0c533b18f57bfcdd25ff9958ac724dc..c85f17315b84544b01c0969230c8f3a6f8b1be68 100644 +--- a/net/socket/socks5_client_socket.cc ++++ b/net/socket/socks5_client_socket.cc +@@ -31,10 +31,12 @@ static_assert(sizeof(struct in6_addr) == 16, "incorrect system size of IPv6"); + + SOCKS5ClientSocket::SOCKS5ClientSocket( + std::unique_ptr transport_socket, +- const HostResolver::RequestInfo& req_info) ++ const HostResolver::RequestInfo& req_info, ++ const SOCKSAuth& auth) + : io_callback_(base::Bind(&SOCKS5ClientSocket::OnIOComplete, + base::Unretained(this))), + transport_(std::move(transport_socket)), ++ auth_state_(auth.Initialize()), + next_state_(STATE_NONE), + completed_handshake_(false), + bytes_sent_(0), +@@ -245,6 +247,9 @@ int SOCKS5ClientSocket::DoLoop(int last_io_result) { + net_log_.EndEventWithNetErrorCode(NetLogEventType::SOCKS5_GREET_READ, + rv); + break; ++ case STATE_AUTH: ++ rv = DoAuth(rv); ++ break; + case STATE_HANDSHAKE_WRITE: + DCHECK_EQ(OK, rv); + net_log_.BeginEvent(NetLogEventType::SOCKS5_HANDSHAKE_WRITE); +@@ -274,8 +279,6 @@ int SOCKS5ClientSocket::DoLoop(int last_io_result) { + return rv; + } + +-const char kSOCKS5GreetWriteData[] = { 0x05, 0x01, 0x00 }; // no authentication +- + int SOCKS5ClientSocket::DoGreetWrite() { + // Since we only have 1 byte to send the hostname length in, if the + // URL has a hostname longer than 255 characters we can't send it. +@@ -285,8 +288,12 @@ int SOCKS5ClientSocket::DoGreetWrite() { + } + + if (buffer_.empty()) { +- buffer_ = std::string(kSOCKS5GreetWriteData, +- arraysize(kSOCKS5GreetWriteData)); ++ const char greeting[] = { ++ 0x05, // SOCKS version ++ 0x01, // number of authentication methods ++ auth_state_->method_number(), ++ }; ++ buffer_ = std::string(greeting, sizeof(greeting)); + bytes_sent_ = 0; + } + +@@ -345,17 +352,23 @@ int SOCKS5ClientSocket::DoGreetReadComplete(int result) { + NetLog::IntCallback("version", buffer_[0])); + return ERR_SOCKS_CONNECTION_FAILED; + } +- if (buffer_[1] != 0x00) { ++ if (buffer_[1] != auth_state_->method_number()) { + net_log_.AddEvent(NetLogEventType::SOCKS_UNEXPECTED_AUTH, + NetLog::IntCallback("method", buffer_[1])); + return ERR_SOCKS_CONNECTION_FAILED; + } + + buffer_.clear(); +- next_state_ = STATE_HANDSHAKE_WRITE; ++ next_state_ = STATE_AUTH; + return OK; + } + ++int SOCKS5ClientSocket::DoAuth(int rv) { ++ rv = auth_state_->Do(rv, *transport_, io_callback_); ++ next_state_ = (rv == OK ? STATE_HANDSHAKE_WRITE : STATE_AUTH); ++ return rv; ++} ++ + int SOCKS5ClientSocket::BuildHandshakeWriteBuffer(std::string* handshake) + const { + DCHECK(handshake->empty()); +diff --git a/net/socket/socks5_client_socket.h b/net/socket/socks5_client_socket.h +index afef312d001297ac1178b93fea92586102a54ac8..ab275b81a76973db6c49e558a89b0fcf6f633445 100644 +--- a/net/socket/socks5_client_socket.h ++++ b/net/socket/socks5_client_socket.h +@@ -19,6 +19,7 @@ + #include "net/base/net_export.h" + #include "net/dns/host_resolver.h" + #include "net/log/net_log_with_source.h" ++#include "net/socket/socks_client_socket_pool.h" + #include "net/socket/stream_socket.h" + #include "url/gurl.h" + +@@ -37,7 +38,8 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { + // always pass it a hostname. This means the DNS resolving is done + // proxy side. + SOCKS5ClientSocket(std::unique_ptr transport_socket, +- const HostResolver::RequestInfo& req_info); ++ const HostResolver::RequestInfo& req_info, ++ const SOCKSAuth& auth); + + // On destruction Disconnect() is called. + ~SOCKS5ClientSocket() override; +@@ -81,6 +83,8 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { + STATE_GREET_WRITE_COMPLETE, + STATE_GREET_READ, + STATE_GREET_READ_COMPLETE, ++ STATE_AUTH, ++ STATE_AUTH_COMPLETE, + STATE_HANDSHAKE_WRITE, + STATE_HANDSHAKE_WRITE_COMPLETE, + STATE_HANDSHAKE_READ, +@@ -115,6 +119,7 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { + int DoGreetReadComplete(int result); + int DoGreetWrite(); + int DoGreetWriteComplete(int result); ++ int DoAuth(int result); + + // Writes the SOCKS handshake buffer into |handshake| + // and return OK on success. +@@ -125,6 +130,9 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { + // Stores the underlying socket. + std::unique_ptr transport_; + ++ // Stores authentication state. ++ std::unique_ptr auth_state_; ++ + State next_state_; + + // Stores the callback to the layer above, called on completing Connect(). +diff --git a/net/socket/socks_client_socket_pool.cc b/net/socket/socks_client_socket_pool.cc +index 86b4ac0d109fca5da44501b6fdb08d97b05fc28d..af0d0e650544b0c8c0e1bdb8291994a90192f942 100644 +--- a/net/socket/socks_client_socket_pool.cc ++++ b/net/socket/socks_client_socket_pool.cc +@@ -17,6 +17,7 @@ + #include "net/socket/client_socket_handle.h" + #include "net/socket/client_socket_pool_base.h" + #include "net/socket/socks5_client_socket.h" ++#include "net/socket/socks_auth_null.h" + #include "net/socket/socks_client_socket.h" + #include "net/socket/transport_client_socket_pool.h" + +@@ -30,11 +31,26 @@ SOCKSSocketParams::SOCKSSocketParams( + const HostPortPair& host_port_pair) + : transport_params_(proxy_server), + destination_(host_port_pair), +- socks_v5_(socks_v5) { ++ socks_v5_(socks_v5), ++ auth_(new SOCKSAuthNull) { ++} ++ ++SOCKSSocketParams::SOCKSSocketParams( ++ const scoped_refptr& proxy_server, ++ const HostPortPair& host_port_pair, ++ const scoped_refptr& auth) ++ : transport_params_(proxy_server), ++ destination_(host_port_pair), ++ socks_v5_(true), ++ auth_(auth) { + } + + SOCKSSocketParams::~SOCKSSocketParams() = default; + ++SOCKSAuth::~SOCKSAuth() = default; ++ ++SOCKSAuthState::~SOCKSAuthState() = default; ++ + // SOCKSConnectJobs will time out after this many seconds. Note this is on + // top of the timeout for the transport socket. + static const int kSOCKSConnectJobTimeoutInSeconds = 30; +@@ -147,7 +163,8 @@ int SOCKSConnectJob::DoSOCKSConnect() { + // Add a SOCKS connection on top of the tcp socket. + if (socks_params_->is_socks_v5()) { + socket_.reset(new SOCKS5ClientSocket(std::move(transport_socket_handle_), +- socks_params_->destination())); ++ socks_params_->destination(), ++ *socks_params_->auth())); + } else { + socket_.reset(new SOCKSClientSocket(std::move(transport_socket_handle_), + socks_params_->destination(), +diff --git a/net/socket/socks_client_socket_pool.h b/net/socket/socks_client_socket_pool.h +index 4eb72e8e4fe5109f68620034ee2ae417ee4731fc..c15bafd8f9c556a64010ca66dcbf87cf6d5d9950 100644 +--- a/net/socket/socks_client_socket_pool.h ++++ b/net/socket/socks_client_socket_pool.h +@@ -21,6 +21,8 @@ + namespace net { + + class ConnectJobFactory; ++class SOCKSAuth; ++class SOCKSAuthState; + class SocketPerformanceWatcherFactory; + class TransportClientSocketPool; + class TransportSocketParams; +@@ -30,11 +32,15 @@ class NET_EXPORT_PRIVATE SOCKSSocketParams + public: + SOCKSSocketParams(const scoped_refptr& proxy_server, + bool socks_v5, const HostPortPair& host_port_pair); ++ SOCKSSocketParams(const scoped_refptr& proxy_server, ++ const HostPortPair& host_port_pair, ++ const scoped_refptr& auth); + + const scoped_refptr& transport_params() const { + return transport_params_; + } + const HostResolver::RequestInfo& destination() const { return destination_; } ++ const scoped_refptr& auth() const { return auth_; } + bool is_socks_v5() const { return socks_v5_; } + + private: +@@ -46,10 +52,29 @@ class NET_EXPORT_PRIVATE SOCKSSocketParams + // This is the HTTP destination. + HostResolver::RequestInfo destination_; + const bool socks_v5_; ++ const scoped_refptr auth_; + + DISALLOW_COPY_AND_ASSIGN(SOCKSSocketParams); + }; + ++// Method and parameters for authentication. ++class NET_EXPORT_PRIVATE SOCKSAuth ++ : public base::RefCounted { ++ public: ++ virtual SOCKSAuthState* Initialize() const = 0; ++ protected: ++ friend class base::RefCounted; ++ virtual ~SOCKSAuth() = 0; ++}; ++ ++// State for performing authentication. ++class NET_EXPORT_PRIVATE SOCKSAuthState { ++ public: ++ virtual ~SOCKSAuthState() = 0; ++ virtual uint8_t method_number() = 0; ++ virtual int Do(int, ClientSocketHandle&, CompletionCallback&) = 0; ++}; ++ + // SOCKSConnectJob handles the handshake to a socks server after setting up + // an underlying transport socket. + class SOCKSConnectJob : public ConnectJob { diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h index 389315a25d7da30d71b59e3803ab795bc4c18e1c..79797fe7e674f9f6d2a65de542f262a945454f16 100644 --- a/net/url_request/url_request_job.h From 132d833b916c770bca39d96fa493fcd72ed976ba Mon Sep 17 00:00:00 2001 From: Taylor `Riastradh' Campbell Date: Thu, 1 Feb 2018 18:36:56 +0000 Subject: [PATCH 02/11] Simplify ProxyServer patches a bit. Treat empty username/password as no authentication. --- patches/master_patch.patch | 73 ++++++++++++++------------------------ 1 file changed, 27 insertions(+), 46 deletions(-) diff --git a/patches/master_patch.patch b/patches/master_patch.patch index 5a799e323d..437f0dfa12 100644 --- a/patches/master_patch.patch +++ b/patches/master_patch.patch @@ -2166,52 +2166,44 @@ index 551953165f93c8d8e4772f0e905f1c4819aaf3b5..caf6df58e858580b165e6ff689572a3d EVENT_TYPE(SOCKS5_HANDSHAKE_WRITE) diff --git a/net/proxy/proxy_server.cc b/net/proxy/proxy_server.cc -index ed81ebbb26b4f439d618c115b32f49249d9284a6..a0e78e5e842fe7804f860f5bd1b7a2cba9903f14 100644 +index ed81ebbb26b4f439d618c115b32f49249d9284a6..3ad26195376d8cb017d2eaf8def61fa681c8aa79 100644 --- a/net/proxy/proxy_server.cc +++ b/net/proxy/proxy_server.cc -@@ -65,7 +65,23 @@ ProxyServer::Scheme GetSchemeFromURIInternal(base::StringPiece type) { +@@ -65,7 +65,17 @@ ProxyServer::Scheme GetSchemeFromURIInternal(base::StringPiece type) { } // namespace ProxyServer::ProxyServer(Scheme scheme, const HostPortPair& host_port_pair) - : scheme_(scheme), host_port_pair_(host_port_pair) { -+ : scheme_(scheme), host_port_pair_(host_port_pair), auth_(false) { -+ if (scheme_ == SCHEME_DIRECT || scheme_ == SCHEME_INVALID) { -+ // |host_port_pair| isn't relevant for these special schemes, so none should -+ // have been specified. It is important for this to be consistent since we -+ // do raw field comparisons in the equality and comparison functions. -+ DCHECK(host_port_pair.Equals(HostPortPair())); -+ host_port_pair_ = HostPortPair(); -+ } ++ : ProxyServer(scheme, host_port_pair, "", "") { +} + +ProxyServer::ProxyServer(Scheme scheme, const HostPortPair& host_port_pair, + const std::string& username, + const std::string& password) + : scheme_(scheme), host_port_pair_(host_port_pair), -+ auth_(true), username_(username), password_(password) { ++ username_(username), password_(password) { + // Authentication is supported only for SOCKS5 proxies. -+ DCHECK(scheme_ == SCHEME_SOCKS5); ++ DCHECK(scheme_ == SCHEME_SOCKS5 || ++ (username.size() == 0 && password.size() == 0)); if (scheme_ == SCHEME_DIRECT || scheme_ == SCHEME_INVALID) { // |host_port_pair| isn't relevant for these special schemes, so none should // have been specified. It is important for this to be consistent since we -@@ -83,6 +99,16 @@ const HostPortPair& ProxyServer::host_port_pair() const { +@@ -83,6 +93,14 @@ const HostPortPair& ProxyServer::host_port_pair() const { return host_port_pair_; } +const std::string& ProxyServer::username() const { -+ DCHECK(is_auth()); + return username_; +}; + +const std::string& ProxyServer::password() const { -+ DCHECK(is_auth()); + return password_; +}; + // static ProxyServer ProxyServer::FromURI(const std::string& uri, Scheme default_scheme) { -@@ -123,7 +149,8 @@ std::string ProxyServer::ToURI() const { +@@ -123,7 +141,8 @@ std::string ProxyServer::ToURI() const { case SCHEME_SOCKS4: return std::string("socks4://") + host_port_pair().ToString(); case SCHEME_SOCKS5: @@ -2221,7 +2213,7 @@ index ed81ebbb26b4f439d618c115b32f49249d9284a6..a0e78e5e842fe7804f860f5bd1b7a2cb case SCHEME_HTTPS: return std::string("https://") + host_port_pair().ToString(); case SCHEME_QUIC: -@@ -175,7 +202,8 @@ std::string ProxyServer::ToPacString() const { +@@ -175,7 +194,8 @@ std::string ProxyServer::ToPacString() const { // For compatibility send SOCKS instead of SOCKS4. return std::string("SOCKS ") + host_port_pair().ToString(); case SCHEME_SOCKS5: @@ -2231,12 +2223,12 @@ index ed81ebbb26b4f439d618c115b32f49249d9284a6..a0e78e5e842fe7804f860f5bd1b7a2cb case SCHEME_HTTPS: return std::string("HTTPS ") + host_port_pair().ToString(); case SCHEME_QUIC: -@@ -187,6 +215,16 @@ std::string ProxyServer::ToPacString() const { +@@ -187,6 +207,16 @@ std::string ProxyServer::ToPacString() const { } } +std::string ProxyServer::AuthString() const { -+ if (!is_auth()) ++ if (username().size() == 0 && password().size() == 0) + return ""; + std::string auth = username(); + if (password().size() > 0) @@ -2248,11 +2240,10 @@ index ed81ebbb26b4f439d618c115b32f49249d9284a6..a0e78e5e842fe7804f860f5bd1b7a2cb // static int ProxyServer::GetDefaultPortForScheme(Scheme scheme) { switch (scheme) { -@@ -227,6 +265,24 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( +@@ -227,6 +257,22 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( return ProxyServer(); // Invalid -- DIRECT cannot have a host/port. HostPortPair host_port_pair; -+ bool auth = false; + std::string username; + std::string password; + @@ -2260,7 +2251,6 @@ index ed81ebbb26b4f439d618c115b32f49249d9284a6..a0e78e5e842fe7804f860f5bd1b7a2cb + if (at != end) { + if (scheme != SCHEME_SOCKS5) + return ProxyServer(); // Invalid -- only SOCKS5 has authentication. -+ auth = true; + std::string::const_iterator colon = std::find(begin, at, ':'); + if (colon != at) { + username = std::string(begin, colon); @@ -2273,20 +2263,17 @@ index ed81ebbb26b4f439d618c115b32f49249d9284a6..a0e78e5e842fe7804f860f5bd1b7a2cb if (scheme != SCHEME_INVALID && scheme != SCHEME_DIRECT) { std::string host; -@@ -243,7 +299,10 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( +@@ -243,7 +289,7 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( host_port_pair = HostPortPair(host, static_cast(port)); } - return ProxyServer(scheme, host_port_pair); -+ if (auth) -+ return ProxyServer(scheme, host_port_pair, username, password); -+ else -+ return ProxyServer(scheme, host_port_pair); ++ return ProxyServer(scheme, host_port_pair, username, password); } } // namespace net diff --git a/net/proxy/proxy_server.h b/net/proxy/proxy_server.h -index 8de93ea0aa4eff6501675b1bb8c1bbd07cff1222..8d8ca8262e2ee7134bf86d6e1e8ac3eac556d35d 100644 +index 8de93ea0aa4eff6501675b1bb8c1bbd07cff1222..560ffb507a304c8546d8c93737c31a72eb95604d 100644 --- a/net/proxy/proxy_server.h +++ b/net/proxy/proxy_server.h @@ -19,7 +19,7 @@ @@ -2307,20 +2294,16 @@ index 8de93ea0aa4eff6501675b1bb8c1bbd07cff1222..8d8ca8262e2ee7134bf86d6e1e8ac3ea bool is_valid() const { return scheme_ != SCHEME_INVALID; } -@@ -67,7 +69,12 @@ class NET_EXPORT ProxyServer { - // Returns true if this ProxyServer is a QUIC proxy. +@@ -68,6 +70,8 @@ class NET_EXPORT ProxyServer { bool is_quic() const { return scheme_ == SCHEME_QUIC; } -+ // Returns true if this ProxyServer has username/password authentication -+ bool is_auth() const { return auth_; } -+ const HostPortPair& host_port_pair() const; + const std::string& username() const; + const std::string& password() const; // Parses from an input with format: // ["://"][":"] -@@ -146,15 +153,18 @@ class NET_EXPORT ProxyServer { +@@ -146,15 +150,18 @@ class NET_EXPORT ProxyServer { bool operator==(const ProxyServer& other) const { return scheme_ == other.scheme_ && @@ -2336,13 +2319,13 @@ index 8de93ea0aa4eff6501675b1bb8c1bbd07cff1222..8d8ca8262e2ee7134bf86d6e1e8ac3ea bool operator<(const ProxyServer& other) const { - return std::tie(scheme_, host_port_pair_) < - std::tie(other.scheme_, other.host_port_pair_); -+ return std::tie(scheme_, host_port_pair_, auth_, username_, password_) < ++ return std::tie(scheme_, host_port_pair_, username_, password_) < + std::tie(other.scheme_, other.host_port_pair_, -+ other.auth_, other.username_, other.password_); ++ other.username_, other.password_); } // Returns the estimate of dynamically allocated memory in bytes. -@@ -168,8 +178,15 @@ class NET_EXPORT ProxyServer { +@@ -168,8 +175,14 @@ class NET_EXPORT ProxyServer { std::string::const_iterator host_and_port_begin, std::string::const_iterator host_and_port_end); @@ -2352,14 +2335,13 @@ index 8de93ea0aa4eff6501675b1bb8c1bbd07cff1222..8d8ca8262e2ee7134bf86d6e1e8ac3ea + Scheme scheme_; HostPortPair host_port_pair_; -+ bool auth_; + std::string username_; + std::string password_; }; typedef std::pair HostPortProxyPair; diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc -index ffec16ff2944915301b2af4ca34b556cbc177b5d..07dcb8111b833292cf59148514064a1356b2b70b 100644 +index ffec16ff2944915301b2af4ca34b556cbc177b5d..272e99ba7ae79610cb92f606ddc9ecaf0655017b 100644 --- a/net/socket/client_socket_pool_manager.cc +++ b/net/socket/client_socket_pool_manager.cc @@ -13,6 +13,7 @@ @@ -2370,22 +2352,21 @@ index ffec16ff2944915301b2af4ca34b556cbc177b5d..07dcb8111b833292cf59148514064a13 #include "net/socket/socks_client_socket_pool.h" #include "net/socket/ssl_client_socket_pool.h" #include "net/socket/transport_client_socket_pool.h" -@@ -189,9 +190,20 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type, +@@ -189,9 +190,19 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type, connection_group = base::StringPrintf( "socks%c/%s", socks_version, connection_group.c_str()); - socks_params = new SOCKSSocketParams(proxy_tcp_params, - socks_version == '5', - origin_host_port); -+ scoped_refptr auth(nullptr); -+ if (proxy_server.is_auth()) { ++ if (proxy_server.username().size() != 0 || ++ proxy_server.password().size() != 0) { + DCHECK_EQ('5', socks_version); -+ const std::string& username = proxy_server.username(); -+ const std::string& password = proxy_server.password(); -+ auth = new SOCKSAuthUsernamePassword(username, password); + socks_params = new SOCKSSocketParams(proxy_tcp_params, + origin_host_port, -+ auth); ++ new SOCKSAuthUsernamePassword( ++ proxy_server.username(), ++ proxy_server.password())); + } else { + socks_params = new SOCKSSocketParams(proxy_tcp_params, + socks_version == '5', From 4f59bc4cf7c504c15fe35fa2b9a2035827963cf2 Mon Sep 17 00:00:00 2001 From: Taylor `Riastradh' Campbell Date: Fri, 2 Feb 2018 00:12:59 +0000 Subject: [PATCH 03/11] Work username/password into HostPortPair, not ProxyServer. Reduces diff a little bit. --- chromium_src/net/base/host_port_pair_auth.cc | 16 + chromium_src/net/base/url_auth_util.cc | 84 ++++ chromium_src/net/base/url_auth_util.h | 22 + ...ssword.cc => socks5_client_socket_auth.cc} | 49 +- .../net/socket/socks5_client_socket_auth.h | 45 ++ chromium_src/net/socket/socks_auth_null.cc | 32 -- chromium_src/net/socket/socks_auth_null.h | 34 -- .../net/socket/socks_auth_username_password.h | 53 -- patches/master_patch.patch | 470 +++++------------- 9 files changed, 325 insertions(+), 480 deletions(-) create mode 100644 chromium_src/net/base/host_port_pair_auth.cc create mode 100644 chromium_src/net/base/url_auth_util.cc create mode 100644 chromium_src/net/base/url_auth_util.h rename chromium_src/net/socket/{socks_auth_username_password.cc => socks5_client_socket_auth.cc} (74%) create mode 100644 chromium_src/net/socket/socks5_client_socket_auth.h delete mode 100644 chromium_src/net/socket/socks_auth_null.cc delete mode 100644 chromium_src/net/socket/socks_auth_null.h delete mode 100644 chromium_src/net/socket/socks_auth_username_password.h diff --git a/chromium_src/net/base/host_port_pair_auth.cc b/chromium_src/net/base/host_port_pair_auth.cc new file mode 100644 index 0000000000..ea761d35cb --- /dev/null +++ b/chromium_src/net/base/host_port_pair_auth.cc @@ -0,0 +1,16 @@ +// Copyright 2017 The Brave 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/host_port_pair.h" + +namespace net { + +HostPortPair::HostPortPair(const std::string& username, + const std::string& password, + const std::string& in_host, uint16_t in_port) + : username_(username), password_(password), + host_(in_host), port_(in_port) { +} + +} // namespace net diff --git a/chromium_src/net/base/url_auth_util.cc b/chromium_src/net/base/url_auth_util.cc new file mode 100644 index 0000000000..a8e804a615 --- /dev/null +++ b/chromium_src/net/base/url_auth_util.cc @@ -0,0 +1,84 @@ +// Copyright 2013 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 +#include + +#include "net/base/url_auth_util.h" +#include "url/third_party/mozilla/url_parse.h" +#include "url/url_canon_ip.h" + +namespace net { + +// Copypasta of ParseHostAndPort that extracts the username and +// password instead of rejecting them. +bool ParseAuthHostAndPort(std::string::const_iterator host_and_port_begin, + std::string::const_iterator host_and_port_end, + std::string *username, + std::string *password, + std::string* host, + int* port) { + if (host_and_port_begin >= host_and_port_end) + return false; + + // When using url, we use char*. + const char* auth_begin = &(*host_and_port_begin); + int auth_len = host_and_port_end - host_and_port_begin; + + url::Component auth_component(0, auth_len); + url::Component username_component; + url::Component password_component; + url::Component hostname_component; + url::Component port_component; + + url::ParseAuthority(auth_begin, auth_component, &username_component, + &password_component, &hostname_component, &port_component); + + if (!hostname_component.is_nonempty()) + return false; // Failed parsing. + + int parsed_port_number = -1; + if (port_component.is_nonempty()) { + parsed_port_number = url::ParsePort(auth_begin, port_component); + + // If parsing failed, port_number will be either PORT_INVALID or + // PORT_UNSPECIFIED, both of which are negative. + if (parsed_port_number < 0) + return false; // Failed parsing the port number. + } + + if (port_component.len == 0) + return false; // Reject inputs like "foo:" + + unsigned char tmp_ipv6_addr[16]; + + // If the hostname starts with a bracket, it is either an IPv6 literal or + // invalid. If it is an IPv6 literal then strip the brackets. + if (hostname_component.len > 0 && + auth_begin[hostname_component.begin] == '[') { + if (auth_begin[hostname_component.end() - 1] == ']' && + url::IPv6AddressToNumber( + auth_begin, hostname_component, tmp_ipv6_addr)) { + // Strip the brackets. + hostname_component.begin++; + hostname_component.len -= 2; + } else { + return false; + } + } + + // Pass results back to caller. + username->assign(auth_begin + username_component.begin, + username_component.len); + password->assign(auth_begin + password_component.begin, + password_component.len); + host->assign(auth_begin + hostname_component.begin, hostname_component.len); + *port = parsed_port_number; + + std::cerr << "username(" << username->size() << "): " << *username << "\n"; + std::cerr << "password(" << password->size() << "): " << *password << "\n"; + return true; // Success. +} + +} diff --git a/chromium_src/net/base/url_auth_util.h b/chromium_src/net/base/url_auth_util.h new file mode 100644 index 0000000000..b1645c2b02 --- /dev/null +++ b/chromium_src/net/base/url_auth_util.h @@ -0,0 +1,22 @@ +// Copyright 2013 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. + +#ifndef NET_BASE_URL_AUTH_UTIL_H_ +#define NET_BASE_URL_AUTH_UTIL_H_ + +#include "net/base/net_export.h" + +namespace net { + +NET_EXPORT bool ParseAuthHostAndPort( + std::string::const_iterator host_and_port_begin, + std::string::const_iterator host_and_port_end, + std::string* username, + std::string* password, + std::string* host, + int* port); + +} + +#endif // NET_BASE_URL_AUTH_UTIL_H_ diff --git a/chromium_src/net/socket/socks_auth_username_password.cc b/chromium_src/net/socket/socks5_client_socket_auth.cc similarity index 74% rename from chromium_src/net/socket/socks_auth_username_password.cc rename to chromium_src/net/socket/socks5_client_socket_auth.cc index c62508502c..b7fd7eda02 100644 --- a/chromium_src/net/socket/socks_auth_username_password.cc +++ b/chromium_src/net/socket/socks5_client_socket_auth.cc @@ -3,51 +3,62 @@ // found in the LICENSE file. #include "net/base/io_buffer.h" -#include "net/socket/socks_auth_username_password.h" +#include "net/socket/socks5_client_socket_auth.h" namespace net { -SOCKSAuthUsernamePassword::SOCKSAuthUsernamePassword( - const std::string& username, const std::string& password) - : username_(username), password_(password) { +SOCKS5ClientSocketAuth::SOCKS5ClientSocketAuth( + std::unique_ptr transport_socket, + const HostResolver::RequestInfo& req_info, + const HostPortPair& proxy_host_port) + : SOCKS5ClientSocket(std::move(transport_socket), req_info), + proxy_host_port_(proxy_host_port), + next_state_(STATE_INIT_WRITE) { } -SOCKSAuthUsernamePassword::~SOCKSAuthUsernamePassword() = default; +SOCKS5ClientSocketAuth::~SOCKS5ClientSocketAuth() = default; -SOCKSAuthState* SOCKSAuthUsernamePassword::Initialize() const { - return new SOCKSAuthUsernamePassword::State(this); +const std::string& SOCKS5ClientSocketAuth::username() { + return proxy_host_port_.username(); } -SOCKSAuthUsernamePassword::State::State(const SOCKSAuthUsernamePassword* auth) - : auth_(auth), - next_state_(STATE_INIT_WRITE) { +const std::string& SOCKS5ClientSocketAuth::password() { + return proxy_host_port_.password(); } -SOCKSAuthUsernamePassword::State::~State() = default; +bool SOCKS5ClientSocketAuth::do_auth() { + return username().size() != 0 || password().size() != 0; +} -uint8_t SOCKSAuthUsernamePassword::State::method_number() { +uint8_t SOCKS5ClientSocketAuth::auth_method() { + if (!do_auth()) + return 0x00; return 0x02; } static const size_t kSOCKSAuthUsernamePasswordResponseLen = 2; -int SOCKSAuthUsernamePassword::State::Do( - int rv, ClientSocketHandle& transport, CompletionCallback& callback) { - const NetLogWithSource& net_log = transport.socket()->NetLog(); +int SOCKS5ClientSocketAuth::Authenticate( + int rv, ClientSocketHandle& transport, NetLogWithSource& net_log, + CompletionCallback& callback) { + if (!do_auth()) { + DCHECK_EQ(OK, rv); + return OK; + } do { switch (next_state_) { case STATE_INIT_WRITE: { DCHECK_EQ(OK, rv); // Initialize the buffer with  // 0x01, usernamelen, username, passwordlen, password - size_t usernamelen = auth_->username_.size(); - size_t passwordlen = auth_->password_.size(); + size_t usernamelen = username().size(); + size_t passwordlen = password().size(); buffer_ = std::string(1 + 1 + usernamelen + 1 + passwordlen, 0); buffer_[0] = 0x01; buffer_[1] = usernamelen; - buffer_.replace(2, usernamelen, auth_->username_); + buffer_.replace(2, usernamelen, username()); buffer_[2 + usernamelen] = passwordlen; - buffer_.replace(2 + usernamelen + 1, passwordlen, auth_->password_); + buffer_.replace(2 + usernamelen + 1, passwordlen, password()); DCHECK_EQ(buffer_.size(), 2 + usernamelen + 1 + passwordlen); buffer_left_ = buffer_.size(); next_state_ = STATE_WRITE; diff --git a/chromium_src/net/socket/socks5_client_socket_auth.h b/chromium_src/net/socket/socks5_client_socket_auth.h new file mode 100644 index 0000000000..05878aaa32 --- /dev/null +++ b/chromium_src/net/socket/socks5_client_socket_auth.h @@ -0,0 +1,45 @@ +// Copyright 2017 The Brave Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_SOCKET_SOCKS5_CLIENT_SOCKET_AUTH_H_ +#define NET_SOCKET_SOCKS5_CLIENT_SOCKET_AUTH_H_ + +#include "net/socket/socks5_client_socket.h" + +namespace net { + +class NET_EXPORT_PRIVATE SOCKS5ClientSocketAuth : public SOCKS5ClientSocket { + public: + SOCKS5ClientSocketAuth(std::unique_ptr transport_socket, + const HostResolver::RequestInfo& req_info, + const HostPortPair& proxy_host_port); + ~SOCKS5ClientSocketAuth() override; + private: + bool do_auth(); + const std::string& username(); + const std::string& password(); + uint8_t auth_method() override; + int Authenticate(int rv, + ClientSocketHandle& transport, NetLogWithSource& net_log, + CompletionCallback& callback) override; + const HostPortPair proxy_host_port_; + enum { + STATE_INIT_WRITE = 0, + STATE_WRITE, + STATE_WRITE_COMPLETE, + STATE_INIT_READ, + STATE_READ, + STATE_READ_COMPLETE, + STATE_DONE, + STATE_BAD, + } next_state_; + scoped_refptr iobuf_; + std::string buffer_; + size_t buffer_left_; + DISALLOW_COPY_AND_ASSIGN(SOCKS5ClientSocketAuth); +}; + +} // namespace net + +#endif // NET_SOCKET_SOCKS5_CLIENT_SOCKET_AUTH_H_ diff --git a/chromium_src/net/socket/socks_auth_null.cc b/chromium_src/net/socket/socks_auth_null.cc deleted file mode 100644 index 7f0b7c1da6..0000000000 --- a/chromium_src/net/socket/socks_auth_null.cc +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2017 The Brave 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/socket/socks_auth_null.h" - -namespace net { - -// Null authentication method. - -SOCKSAuthNull::SOCKSAuthNull() = default; - -SOCKSAuthNull::~SOCKSAuthNull() = default; - -SOCKSAuthState* SOCKSAuthNull::Initialize() const { - return new SOCKSAuthNull::State; -} - -SOCKSAuthNull::State::State() = default; - -SOCKSAuthNull::State::~State() = default; - -uint8_t SOCKSAuthNull::State::method_number() { - return 0x00; -} - -int SOCKSAuthNull::State::Do(int rv, ClientSocketHandle& socket, - CompletionCallback& callback) { - return OK; -} - -} // namespace net diff --git a/chromium_src/net/socket/socks_auth_null.h b/chromium_src/net/socket/socks_auth_null.h deleted file mode 100644 index 5337ed27b8..0000000000 --- a/chromium_src/net/socket/socks_auth_null.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2017 The Brave Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_SOCKET_SOCKS_AUTH_NULL_H_ -#define NET_SOCKET_SOCKS_AUTH_NULL_H_ - -#include "net/socket/socks_client_socket_pool.h" - -namespace net { - -// Null authentication method. -class NET_EXPORT_PRIVATE SOCKSAuthNull : public SOCKSAuth { - public: - SOCKSAuthNull(); - ~SOCKSAuthNull() override; - SOCKSAuthState* Initialize() const override; - private: - class State : public SOCKSAuthState { - public: - ~State() override; - uint8_t method_number() override; - int Do(int, ClientSocketHandle&, CompletionCallback&) override; - private: - friend class SOCKSAuthNull; - State(); - DISALLOW_COPY_AND_ASSIGN(State); - }; - DISALLOW_COPY_AND_ASSIGN(SOCKSAuthNull); -}; - -} // namespace net - -#endif // NET_SOCKET_SOCKS_AUTH_NULL_H_ diff --git a/chromium_src/net/socket/socks_auth_username_password.h b/chromium_src/net/socket/socks_auth_username_password.h deleted file mode 100644 index 25aea21a7c..0000000000 --- a/chromium_src/net/socket/socks_auth_username_password.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright 2017 The Brave Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef NET_SOCKET_SOCKS_AUTH_USERNAME_PASSWORD_H_ -#define NET_SOCKET_SOCKS_AUTH_USERNAME_PASSWORD_H_ - -#include "net/base/net_export.h" -#include "net/socket/socks_client_socket_pool.h" - -namespace net { - -class IOBuffer; - -class NET_EXPORT_PRIVATE SOCKSAuthUsernamePassword : public SOCKSAuth { - public: - SOCKSAuthUsernamePassword(const std::string&, const std::string&); - ~SOCKSAuthUsernamePassword() override; - SOCKSAuthState* Initialize() const override; - private: - friend class State; - std::string username_; - std::string password_; - class State : public SOCKSAuthState { - public: - ~State() override; - uint8_t method_number() override; - int Do(int, ClientSocketHandle&, CompletionCallback&) override; - private: - friend class SOCKSAuthUsernamePassword; - explicit State(const SOCKSAuthUsernamePassword*); - const SOCKSAuthUsernamePassword* auth_; - enum { - STATE_INIT_WRITE = 0, - STATE_WRITE, - STATE_WRITE_COMPLETE, - STATE_INIT_READ, - STATE_READ, - STATE_READ_COMPLETE, - STATE_DONE, - STATE_BAD, - } next_state_; - scoped_refptr iobuf_; - std::string buffer_; - size_t buffer_left_; - DISALLOW_COPY_AND_ASSIGN(State); - }; - DISALLOW_COPY_AND_ASSIGN(SOCKSAuthUsernamePassword); -}; - -} // namespace net - -#endif // NET_SOCKET_SOCKS_AUTH_USERNAME_PASSWORD_H_ diff --git a/patches/master_patch.patch b/patches/master_patch.patch index 437f0dfa12..98b458d0c1 100644 --- a/patches/master_patch.patch +++ b/patches/master_patch.patch @@ -2105,6 +2105,54 @@ index b7fb84846acdd37de8593a1180dfaedd2fbc431c..3b4be3019ec0dd2fa0ed636bc6a56ea2 return switches::autoplay::kUserGestureRequiredPolicy; #else return switches::autoplay::kNoUserGestureRequiredPolicy; +diff --git a/net/base/host_port_pair.h b/net/base/host_port_pair.h +index a5ee6bda3ff542624b484b7a11811b708fec3e11..0d635e6dd1242382bd5845f6cb7674dc32c58b5d 100644 +--- a/net/base/host_port_pair.h ++++ b/net/base/host_port_pair.h +@@ -23,6 +23,8 @@ class NET_EXPORT HostPortPair { + HostPortPair(); + // If |in_host| represents an IPv6 address, it should not bracket the address. + HostPortPair(const std::string& in_host, uint16_t in_port); ++ HostPortPair(const std::string& username, const std::string& password, ++ const std::string& in_host, uint16_t in_port); + + // Creates a HostPortPair for the origin of |url|. + static HostPortPair FromURL(const GURL& url); +@@ -37,18 +39,23 @@ class NET_EXPORT HostPortPair { + // TODO(willchan): Define a functor instead. + // Comparator function so this can be placed in a std::map. + bool operator<(const HostPortPair& other) const { +- return std::tie(port_, host_) < std::tie(other.port_, other.host_); ++ return std::tie(port_, host_, username_, password_) < ++ std::tie(other.port_, other.host_, other.username_, other.password_); + } + + // Equality test of contents. (Probably another violation of style guide). + bool Equals(const HostPortPair& other) const { +- return host_ == other.host_ && port_ == other.port_; ++ return username_ == other.username_ && password_ == other.password_ && ++ host_ == other.host_ && port_ == other.port_; + } + + bool IsEmpty() const { + return host_.empty() && port_ == 0; + } + ++ const std::string& username() const { return username_; } ++ const std::string& password() const { return password_; } ++ + const std::string& host() const { + return host_; + } +@@ -72,6 +79,8 @@ class NET_EXPORT HostPortPair { + size_t EstimateMemoryUsage() const; + + private: ++ std::string username_; ++ std::string password_; + // If |host_| represents an IPv6 address, this string will not contain + // brackets around the address. + std::string host_; diff --git a/net/http/BUILD.gn b/net/http/BUILD.gn index d00da41da1d8bbc40d8a85d582c1966ed22eaaf1..6a3b54e91eafb8f187989c9c954be0008343aa63 100644 --- a/net/http/BUILD.gn @@ -2166,234 +2214,50 @@ index 551953165f93c8d8e4772f0e905f1c4819aaf3b5..caf6df58e858580b165e6ff689572a3d EVENT_TYPE(SOCKS5_HANDSHAKE_WRITE) diff --git a/net/proxy/proxy_server.cc b/net/proxy/proxy_server.cc -index ed81ebbb26b4f439d618c115b32f49249d9284a6..3ad26195376d8cb017d2eaf8def61fa681c8aa79 100644 +index ed81ebbb26b4f439d618c115b32f49249d9284a6..35c592babe062b5804c8d3292dd3893ea51279b2 100644 --- a/net/proxy/proxy_server.cc +++ b/net/proxy/proxy_server.cc -@@ -65,7 +65,17 @@ ProxyServer::Scheme GetSchemeFromURIInternal(base::StringPiece type) { - } // namespace - - ProxyServer::ProxyServer(Scheme scheme, const HostPortPair& host_port_pair) -- : scheme_(scheme), host_port_pair_(host_port_pair) { -+ : ProxyServer(scheme, host_port_pair, "", "") { -+} -+ -+ProxyServer::ProxyServer(Scheme scheme, const HostPortPair& host_port_pair, -+ const std::string& username, -+ const std::string& password) -+ : scheme_(scheme), host_port_pair_(host_port_pair), -+ username_(username), password_(password) { -+ // Authentication is supported only for SOCKS5 proxies. -+ DCHECK(scheme_ == SCHEME_SOCKS5 || -+ (username.size() == 0 && password.size() == 0)); - if (scheme_ == SCHEME_DIRECT || scheme_ == SCHEME_INVALID) { - // |host_port_pair| isn't relevant for these special schemes, so none should - // have been specified. It is important for this to be consistent since we -@@ -83,6 +93,14 @@ const HostPortPair& ProxyServer::host_port_pair() const { - return host_port_pair_; - } - -+const std::string& ProxyServer::username() const { -+ return username_; -+}; -+ -+const std::string& ProxyServer::password() const { -+ return password_; -+}; -+ - // static - ProxyServer ProxyServer::FromURI(const std::string& uri, - Scheme default_scheme) { -@@ -123,7 +141,8 @@ std::string ProxyServer::ToURI() const { - case SCHEME_SOCKS4: - return std::string("socks4://") + host_port_pair().ToString(); - case SCHEME_SOCKS5: -- return std::string("socks5://") + host_port_pair().ToString(); -+ return std::string("socks5://") + AuthString() + -+ host_port_pair().ToString(); - case SCHEME_HTTPS: - return std::string("https://") + host_port_pair().ToString(); - case SCHEME_QUIC: -@@ -175,7 +194,8 @@ std::string ProxyServer::ToPacString() const { - // For compatibility send SOCKS instead of SOCKS4. - return std::string("SOCKS ") + host_port_pair().ToString(); - case SCHEME_SOCKS5: -- return std::string("SOCKS5 ") + host_port_pair().ToString(); -+ return std::string("SOCKS5 ") + AuthString() + -+ host_port_pair().ToString(); - case SCHEME_HTTPS: - return std::string("HTTPS ") + host_port_pair().ToString(); - case SCHEME_QUIC: -@@ -187,6 +207,16 @@ std::string ProxyServer::ToPacString() const { - } - } +@@ -8,6 +8,7 @@ -+std::string ProxyServer::AuthString() const { -+ if (username().size() == 0 && password().size() == 0) -+ return ""; -+ std::string auth = username(); -+ if (password().size() > 0) -+ auth += ":" + password(); -+ auth += "@"; -+ return auth; -+}; -+ - // static - int ProxyServer::GetDefaultPortForScheme(Scheme scheme) { - switch (scheme) { -@@ -227,6 +257,22 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( - return ProxyServer(); // Invalid -- DIRECT cannot have a host/port. + #include "base/strings/string_util.h" + #include "base/trace_event/memory_usage_estimator.h" ++#include "net/base/url_auth_util.h" + #include "net/base/url_util.h" + #include "net/http/http_util.h" +@@ -229,10 +230,14 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( HostPortPair host_port_pair; -+ std::string username; -+ std::string password; -+ -+ std::string::const_iterator at = std::find(begin, end, '@'); -+ if (at != end) { -+ if (scheme != SCHEME_SOCKS5) -+ return ProxyServer(); // Invalid -- only SOCKS5 has authentication. -+ std::string::const_iterator colon = std::find(begin, at, ':'); -+ if (colon != at) { -+ username = std::string(begin, colon); -+ password = std::string(colon + 1, at); -+ } else { -+ username = std::string(begin, at); -+ } -+ begin = at + 1; -+ } if (scheme != SCHEME_INVALID && scheme != SCHEME_DIRECT) { ++ std::string username; ++ std::string password; std::string host; -@@ -243,7 +289,7 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( - host_port_pair = HostPortPair(host, static_cast(port)); - } - -- return ProxyServer(scheme, host_port_pair); -+ return ProxyServer(scheme, host_port_pair, username, password); - } - - } // namespace net -diff --git a/net/proxy/proxy_server.h b/net/proxy/proxy_server.h -index 8de93ea0aa4eff6501675b1bb8c1bbd07cff1222..560ffb507a304c8546d8c93737c31a72eb95604d 100644 ---- a/net/proxy/proxy_server.h -+++ b/net/proxy/proxy_server.h -@@ -19,7 +19,7 @@ - - namespace net { - --// ProxyServer encodes the {type, host, port} of a proxy server. -+// ProxyServer encodes the {type, user, pass, host, port} of a proxy server. - // ProxyServer is immutable. - class NET_EXPORT ProxyServer { - public: -@@ -44,6 +44,8 @@ class NET_EXPORT ProxyServer { - ProxyServer() : scheme_(SCHEME_INVALID) {} - - ProxyServer(Scheme scheme, const HostPortPair& host_port_pair); -+ ProxyServer(Scheme scheme, const HostPortPair& host_port_pair, -+ const std::string& username, const std::string& password); - - bool is_valid() const { return scheme_ != SCHEME_INVALID; } - -@@ -68,6 +70,8 @@ class NET_EXPORT ProxyServer { - bool is_quic() const { return scheme_ == SCHEME_QUIC; } - - const HostPortPair& host_port_pair() const; -+ const std::string& username() const; -+ const std::string& password() const; - - // Parses from an input with format: - // ["://"][":"] -@@ -146,15 +150,18 @@ class NET_EXPORT ProxyServer { - - bool operator==(const ProxyServer& other) const { - return scheme_ == other.scheme_ && -- host_port_pair_.Equals(other.host_port_pair_); -+ host_port_pair_.Equals(other.host_port_pair_) && -+ username_ == other.username_ && -+ password_ == other.password_; - } - - bool operator!=(const ProxyServer& other) const { return !(*this == other); } - - // Comparator function so this can be placed in a std::map. - bool operator<(const ProxyServer& other) const { -- return std::tie(scheme_, host_port_pair_) < -- std::tie(other.scheme_, other.host_port_pair_); -+ return std::tie(scheme_, host_port_pair_, username_, password_) < -+ std::tie(other.scheme_, other.host_port_pair_, -+ other.username_, other.password_); - } - - // Returns the estimate of dynamically allocated memory in bytes. -@@ -168,8 +175,14 @@ class NET_EXPORT ProxyServer { - std::string::const_iterator host_and_port_begin, - std::string::const_iterator host_and_port_end); - -+ // Returns the `:@' prefix, if authentication is -+ // enabled, or empty if not. -+ std::string AuthString() const; -+ - Scheme scheme_; - HostPortPair host_port_pair_; -+ std::string username_; -+ std::string password_; - }; - - typedef std::pair HostPortProxyPair; -diff --git a/net/socket/client_socket_pool_manager.cc b/net/socket/client_socket_pool_manager.cc -index ffec16ff2944915301b2af4ca34b556cbc177b5d..272e99ba7ae79610cb92f606ddc9ecaf0655017b 100644 ---- a/net/socket/client_socket_pool_manager.cc -+++ b/net/socket/client_socket_pool_manager.cc -@@ -13,6 +13,7 @@ - #include "net/proxy/proxy_info.h" - #include "net/socket/client_socket_handle.h" - #include "net/socket/client_socket_pool.h" -+#include "net/socket/socks_auth_username_password.h" - #include "net/socket/socks_client_socket_pool.h" - #include "net/socket/ssl_client_socket_pool.h" - #include "net/socket/transport_client_socket_pool.h" -@@ -189,9 +190,19 @@ int InitSocketPoolHelper(ClientSocketPoolManager::SocketGroupType group_type, - connection_group = base::StringPrintf( - "socks%c/%s", socks_version, connection_group.c_str()); - -- socks_params = new SOCKSSocketParams(proxy_tcp_params, -- socks_version == '5', -- origin_host_port); -+ if (proxy_server.username().size() != 0 || -+ proxy_server.password().size() != 0) { -+ DCHECK_EQ('5', socks_version); -+ socks_params = new SOCKSSocketParams(proxy_tcp_params, -+ origin_host_port, -+ new SOCKSAuthUsernamePassword( -+ proxy_server.username(), -+ proxy_server.password())); -+ } else { -+ socks_params = new SOCKSSocketParams(proxy_tcp_params, -+ socks_version == '5', -+ origin_host_port); -+ } - } + int port = -1; + // If the scheme has a host/port, parse it. +- bool ok = ParseHostAndPort(begin, end, &host, &port); ++ bool ok = scheme == SCHEME_SOCKS5 ++ ? ParseAuthHostAndPort(begin, end, &username, &password, &host, &port) ++ : ParseHostAndPort(begin, end, &host, &port); + if (!ok) + return ProxyServer(); // Invalid -- failed parsing [":"] + +@@ -240,7 +245,10 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( + if (port == -1) + port = GetDefaultPortForScheme(scheme); + +- host_port_pair = HostPortPair(host, static_cast(port)); ++ DCHECK(scheme == SCHEME_SOCKS5 || username.size() == 0); ++ DCHECK(scheme == SCHEME_SOCKS5 || password.size() == 0); ++ host_port_pair = HostPortPair( ++ username, password, host, static_cast(port)); } + return ProxyServer(scheme, host_port_pair); diff --git a/net/socket/socks5_client_socket.cc b/net/socket/socks5_client_socket.cc -index 19cdfddbe0c533b18f57bfcdd25ff9958ac724dc..c85f17315b84544b01c0969230c8f3a6f8b1be68 100644 +index 19cdfddbe0c533b18f57bfcdd25ff9958ac724dc..c99f6642e0204fc5c2c6e745dcce67473e2b8188 100644 --- a/net/socket/socks5_client_socket.cc +++ b/net/socket/socks5_client_socket.cc -@@ -31,10 +31,12 @@ static_assert(sizeof(struct in6_addr) == 16, "incorrect system size of IPv6"); - - SOCKS5ClientSocket::SOCKS5ClientSocket( - std::unique_ptr transport_socket, -- const HostResolver::RequestInfo& req_info) -+ const HostResolver::RequestInfo& req_info, -+ const SOCKSAuth& auth) - : io_callback_(base::Bind(&SOCKS5ClientSocket::OnIOComplete, - base::Unretained(this))), - transport_(std::move(transport_socket)), -+ auth_state_(auth.Initialize()), - next_state_(STATE_NONE), - completed_handshake_(false), - bytes_sent_(0), -@@ -245,6 +247,9 @@ int SOCKS5ClientSocket::DoLoop(int last_io_result) { +@@ -245,6 +245,9 @@ int SOCKS5ClientSocket::DoLoop(int last_io_result) { net_log_.EndEventWithNetErrorCode(NetLogEventType::SOCKS5_GREET_READ, rv); break; @@ -2403,7 +2267,7 @@ index 19cdfddbe0c533b18f57bfcdd25ff9958ac724dc..c85f17315b84544b01c0969230c8f3a6 case STATE_HANDSHAKE_WRITE: DCHECK_EQ(OK, rv); net_log_.BeginEvent(NetLogEventType::SOCKS5_HANDSHAKE_WRITE); -@@ -274,8 +279,6 @@ int SOCKS5ClientSocket::DoLoop(int last_io_result) { +@@ -274,8 +277,6 @@ int SOCKS5ClientSocket::DoLoop(int last_io_result) { return rv; } @@ -2412,7 +2276,7 @@ index 19cdfddbe0c533b18f57bfcdd25ff9958ac724dc..c85f17315b84544b01c0969230c8f3a6 int SOCKS5ClientSocket::DoGreetWrite() { // Since we only have 1 byte to send the hostname length in, if the // URL has a hostname longer than 255 characters we can't send it. -@@ -285,8 +288,12 @@ int SOCKS5ClientSocket::DoGreetWrite() { +@@ -285,8 +286,12 @@ int SOCKS5ClientSocket::DoGreetWrite() { } if (buffer_.empty()) { @@ -2421,18 +2285,18 @@ index 19cdfddbe0c533b18f57bfcdd25ff9958ac724dc..c85f17315b84544b01c0969230c8f3a6 + const char greeting[] = { + 0x05, // SOCKS version + 0x01, // number of authentication methods -+ auth_state_->method_number(), ++ auth_method(), + }; + buffer_ = std::string(greeting, sizeof(greeting)); bytes_sent_ = 0; } -@@ -345,17 +352,23 @@ int SOCKS5ClientSocket::DoGreetReadComplete(int result) { +@@ -345,14 +350,32 @@ int SOCKS5ClientSocket::DoGreetReadComplete(int result) { NetLog::IntCallback("version", buffer_[0])); return ERR_SOCKS_CONNECTION_FAILED; } - if (buffer_[1] != 0x00) { -+ if (buffer_[1] != auth_state_->method_number()) { ++ if (buffer_[1] != auth_method()) { net_log_.AddEvent(NetLogEventType::SOCKS_UNEXPECTED_AUTH, NetLog::IntCallback("method", buffer_[1])); return ERR_SOCKS_CONNECTION_FAILED; @@ -2441,20 +2305,29 @@ index 19cdfddbe0c533b18f57bfcdd25ff9958ac724dc..c85f17315b84544b01c0969230c8f3a6 buffer_.clear(); - next_state_ = STATE_HANDSHAKE_WRITE; + next_state_ = STATE_AUTH; - return OK; - } - ++ return OK; ++} ++ +int SOCKS5ClientSocket::DoAuth(int rv) { -+ rv = auth_state_->Do(rv, *transport_, io_callback_); ++ rv = Authenticate(rv, *transport_, net_log_, io_callback_); + next_state_ = (rv == OK ? STATE_HANDSHAKE_WRITE : STATE_AUTH); + return rv; +} + - int SOCKS5ClientSocket::BuildHandshakeWriteBuffer(std::string* handshake) - const { - DCHECK(handshake->empty()); ++uint8_t SOCKS5ClientSocket::auth_method() { ++ return 0x00; ++} ++ ++int SOCKS5ClientSocket::Authenticate(int rv, ++ ClientSocketHandle& socket, ++ NetLogWithSource& net_log, ++ CompletionCallback& callback) { ++ DCHECK_EQ(OK, rv); + return OK; + } + diff --git a/net/socket/socks5_client_socket.h b/net/socket/socks5_client_socket.h -index afef312d001297ac1178b93fea92586102a54ac8..ab275b81a76973db6c49e558a89b0fcf6f633445 100644 +index afef312d001297ac1178b93fea92586102a54ac8..9c37710526d38ce9a48ef4942654e9dbaae2c567 100644 --- a/net/socket/socks5_client_socket.h +++ b/net/socket/socks5_client_socket.h @@ -19,6 +19,7 @@ @@ -2465,17 +2338,16 @@ index afef312d001297ac1178b93fea92586102a54ac8..ab275b81a76973db6c49e558a89b0fcf #include "net/socket/stream_socket.h" #include "url/gurl.h" -@@ -37,7 +38,8 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { - // always pass it a hostname. This means the DNS resolving is done - // proxy side. - SOCKS5ClientSocket(std::unique_ptr transport_socket, -- const HostResolver::RequestInfo& req_info); -+ const HostResolver::RequestInfo& req_info, -+ const SOCKSAuth& auth); +@@ -40,7 +41,7 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { + const HostResolver::RequestInfo& req_info); // On destruction Disconnect() is called. - ~SOCKS5ClientSocket() override; -@@ -81,6 +83,8 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { +- ~SOCKS5ClientSocket() override; ++ virtual ~SOCKS5ClientSocket() override; + + // StreamSocket implementation. + +@@ -81,6 +82,8 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { STATE_GREET_WRITE_COMPLETE, STATE_GREET_READ, STATE_GREET_READ_COMPLETE, @@ -2484,133 +2356,47 @@ index afef312d001297ac1178b93fea92586102a54ac8..ab275b81a76973db6c49e558a89b0fcf STATE_HANDSHAKE_WRITE, STATE_HANDSHAKE_WRITE_COMPLETE, STATE_HANDSHAKE_READ, -@@ -115,6 +119,7 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { +@@ -115,6 +118,14 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { int DoGreetReadComplete(int result); int DoGreetWrite(); int DoGreetWriteComplete(int result); + int DoAuth(int result); ++ ++ // Authentication hooks. ++ virtual uint8_t auth_method(); ++ virtual int Authenticate(int result, ++ ClientSocketHandle& socket, ++ NetLogWithSource& net_log, ++ CompletionCallback& callback); // Writes the SOCKS handshake buffer into |handshake| // and return OK on success. -@@ -125,6 +130,9 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { - // Stores the underlying socket. - std::unique_ptr transport_; - -+ // Stores authentication state. -+ std::unique_ptr auth_state_; -+ - State next_state_; - - // Stores the callback to the layer above, called on completing Connect(). diff --git a/net/socket/socks_client_socket_pool.cc b/net/socket/socks_client_socket_pool.cc -index 86b4ac0d109fca5da44501b6fdb08d97b05fc28d..af0d0e650544b0c8c0e1bdb8291994a90192f942 100644 +index 86b4ac0d109fca5da44501b6fdb08d97b05fc28d..3294267b3e97cbc5c28a95473245fbc6ea5b4919 100644 --- a/net/socket/socks_client_socket_pool.cc +++ b/net/socket/socks_client_socket_pool.cc -@@ -17,6 +17,7 @@ +@@ -16,7 +16,7 @@ + #include "net/socket/client_socket_factory.h" #include "net/socket/client_socket_handle.h" #include "net/socket/client_socket_pool_base.h" - #include "net/socket/socks5_client_socket.h" -+#include "net/socket/socks_auth_null.h" +-#include "net/socket/socks5_client_socket.h" ++#include "net/socket/socks5_client_socket_auth.h" #include "net/socket/socks_client_socket.h" #include "net/socket/transport_client_socket_pool.h" -@@ -30,11 +31,26 @@ SOCKSSocketParams::SOCKSSocketParams( - const HostPortPair& host_port_pair) - : transport_params_(proxy_server), - destination_(host_port_pair), -- socks_v5_(socks_v5) { -+ socks_v5_(socks_v5), -+ auth_(new SOCKSAuthNull) { -+} -+ -+SOCKSSocketParams::SOCKSSocketParams( -+ const scoped_refptr& proxy_server, -+ const HostPortPair& host_port_pair, -+ const scoped_refptr& auth) -+ : transport_params_(proxy_server), -+ destination_(host_port_pair), -+ socks_v5_(true), -+ auth_(auth) { - } - - SOCKSSocketParams::~SOCKSSocketParams() = default; +@@ -146,8 +146,10 @@ int SOCKSConnectJob::DoSOCKSConnect() { -+SOCKSAuth::~SOCKSAuth() = default; -+ -+SOCKSAuthState::~SOCKSAuthState() = default; -+ - // SOCKSConnectJobs will time out after this many seconds. Note this is on - // top of the timeout for the transport socket. - static const int kSOCKSConnectJobTimeoutInSeconds = 30; -@@ -147,7 +163,8 @@ int SOCKSConnectJob::DoSOCKSConnect() { // Add a SOCKS connection on top of the tcp socket. if (socks_params_->is_socks_v5()) { - socket_.reset(new SOCKS5ClientSocket(std::move(transport_socket_handle_), +- socket_.reset(new SOCKS5ClientSocket(std::move(transport_socket_handle_), - socks_params_->destination())); -+ socks_params_->destination(), -+ *socks_params_->auth())); ++ socket_.reset(new SOCKS5ClientSocketAuth( ++ std::move(transport_socket_handle_), ++ socks_params_->destination(), ++ socks_params_->transport_params()->destination().host_port_pair())); } else { socket_.reset(new SOCKSClientSocket(std::move(transport_socket_handle_), socks_params_->destination(), -diff --git a/net/socket/socks_client_socket_pool.h b/net/socket/socks_client_socket_pool.h -index 4eb72e8e4fe5109f68620034ee2ae417ee4731fc..c15bafd8f9c556a64010ca66dcbf87cf6d5d9950 100644 ---- a/net/socket/socks_client_socket_pool.h -+++ b/net/socket/socks_client_socket_pool.h -@@ -21,6 +21,8 @@ - namespace net { - - class ConnectJobFactory; -+class SOCKSAuth; -+class SOCKSAuthState; - class SocketPerformanceWatcherFactory; - class TransportClientSocketPool; - class TransportSocketParams; -@@ -30,11 +32,15 @@ class NET_EXPORT_PRIVATE SOCKSSocketParams - public: - SOCKSSocketParams(const scoped_refptr& proxy_server, - bool socks_v5, const HostPortPair& host_port_pair); -+ SOCKSSocketParams(const scoped_refptr& proxy_server, -+ const HostPortPair& host_port_pair, -+ const scoped_refptr& auth); - - const scoped_refptr& transport_params() const { - return transport_params_; - } - const HostResolver::RequestInfo& destination() const { return destination_; } -+ const scoped_refptr& auth() const { return auth_; } - bool is_socks_v5() const { return socks_v5_; } - - private: -@@ -46,10 +52,29 @@ class NET_EXPORT_PRIVATE SOCKSSocketParams - // This is the HTTP destination. - HostResolver::RequestInfo destination_; - const bool socks_v5_; -+ const scoped_refptr auth_; - - DISALLOW_COPY_AND_ASSIGN(SOCKSSocketParams); - }; - -+// Method and parameters for authentication. -+class NET_EXPORT_PRIVATE SOCKSAuth -+ : public base::RefCounted { -+ public: -+ virtual SOCKSAuthState* Initialize() const = 0; -+ protected: -+ friend class base::RefCounted; -+ virtual ~SOCKSAuth() = 0; -+}; -+ -+// State for performing authentication. -+class NET_EXPORT_PRIVATE SOCKSAuthState { -+ public: -+ virtual ~SOCKSAuthState() = 0; -+ virtual uint8_t method_number() = 0; -+ virtual int Do(int, ClientSocketHandle&, CompletionCallback&) = 0; -+}; -+ - // SOCKSConnectJob handles the handshake to a socks server after setting up - // an underlying transport socket. - class SOCKSConnectJob : public ConnectJob { diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h index 389315a25d7da30d71b59e3803ab795bc4c18e1c..79797fe7e674f9f6d2a65de542f262a945454f16 100644 --- a/net/url_request/url_request_job.h From b031d34f065ea7633c95e8d259cd2ca64fc6cb30 Mon Sep 17 00:00:00 2001 From: Taylor `Riastradh' Campbell Date: Fri, 2 Feb 2018 01:07:28 +0000 Subject: [PATCH 04/11] Remove debugging vestige. --- chromium_src/net/base/url_auth_util.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/chromium_src/net/base/url_auth_util.cc b/chromium_src/net/base/url_auth_util.cc index a8e804a615..03844aeecf 100644 --- a/chromium_src/net/base/url_auth_util.cc +++ b/chromium_src/net/base/url_auth_util.cc @@ -76,8 +76,6 @@ bool ParseAuthHostAndPort(std::string::const_iterator host_and_port_begin, host->assign(auth_begin + hostname_component.begin, hostname_component.len); *port = parsed_port_number; - std::cerr << "username(" << username->size() << "): " << *username << "\n"; - std::cerr << "password(" << password->size() << "): " << *password << "\n"; return true; // Success. } From 5270979237f771004b26af04633eaf6802b8bd52 Mon Sep 17 00:00:00 2001 From: Taylor `Riastradh' Campbell Date: Fri, 2 Feb 2018 01:11:18 +0000 Subject: [PATCH 05/11] Reduce diff in proxy_server.cc even further. To do this, we (a) parse the user/pass/host/port in ParseAuthHostAndPort; (b) then reassemble user:pass@host in it; and finally (c) proceed to reparse the user/pass/host in the HostPortPair constructor. --- chromium_src/net/base/host_port_pair_auth.cc | 16 ++++++++ chromium_src/net/base/url_auth_util.cc | 28 +++++++++---- chromium_src/net/base/url_auth_util.h | 4 +- patches/master_patch.patch | 41 +++++++++----------- 4 files changed, 56 insertions(+), 33 deletions(-) diff --git a/chromium_src/net/base/host_port_pair_auth.cc b/chromium_src/net/base/host_port_pair_auth.cc index ea761d35cb..ab0fd70190 100644 --- a/chromium_src/net/base/host_port_pair_auth.cc +++ b/chromium_src/net/base/host_port_pair_auth.cc @@ -13,4 +13,20 @@ HostPortPair::HostPortPair(const std::string& username, host_(in_host), port_(in_port) { } +HostPortPair::HostPortPair(const std::string& up_host, uint16_t in_port) + : port_(in_port) { + std::string::const_iterator begin = up_host.begin(); + std::string::const_iterator end = up_host.end(); + std::string::const_iterator at = std::find(begin, end, '@'); + if (at == end) { + host_ = up_host; + } else { + std::string::const_iterator colon = std::find(begin, at, ':'); + username_ = std::string(begin, colon); + if (colon != at) + password_ = std::string(colon + 1, at); + host_ = std::string(at + 1, end); + } +} + } // namespace net diff --git a/chromium_src/net/base/url_auth_util.cc b/chromium_src/net/base/url_auth_util.cc index 03844aeecf..b0ce8b5d32 100644 --- a/chromium_src/net/base/url_auth_util.cc +++ b/chromium_src/net/base/url_auth_util.cc @@ -15,9 +15,7 @@ namespace net { // password instead of rejecting them. bool ParseAuthHostAndPort(std::string::const_iterator host_and_port_begin, std::string::const_iterator host_and_port_end, - std::string *username, - std::string *password, - std::string* host, + std::string* up_host_ret, int* port) { if (host_and_port_begin >= host_and_port_end) return false; @@ -68,12 +66,26 @@ bool ParseAuthHostAndPort(std::string::const_iterator host_and_port_begin, } } + // Reassemble user:pass@host as up_host. + std::string up_host; + std::string username(auth_begin + username_component.begin, + username_component.len); + std::string password(auth_begin + password_component.begin, + password_component.len); + std::string hostname(auth_begin + hostname_component.begin, + hostname_component.len); + if (username.size() != 0 || password.size() != 0) { + up_host += username; + if (password.size() != 0) { + up_host += ":"; + up_host += password; + } + up_host += "@"; + } + up_host += hostname; + // Pass results back to caller. - username->assign(auth_begin + username_component.begin, - username_component.len); - password->assign(auth_begin + password_component.begin, - password_component.len); - host->assign(auth_begin + hostname_component.begin, hostname_component.len); + *up_host_ret = up_host; *port = parsed_port_number; return true; // Success. diff --git a/chromium_src/net/base/url_auth_util.h b/chromium_src/net/base/url_auth_util.h index b1645c2b02..00b08eab66 100644 --- a/chromium_src/net/base/url_auth_util.h +++ b/chromium_src/net/base/url_auth_util.h @@ -12,9 +12,7 @@ namespace net { NET_EXPORT bool ParseAuthHostAndPort( std::string::const_iterator host_and_port_begin, std::string::const_iterator host_and_port_end, - std::string* username, - std::string* password, - std::string* host, + std::string* up_host_ret, int* port); } diff --git a/patches/master_patch.patch b/patches/master_patch.patch index 98b458d0c1..668a5b4519 100644 --- a/patches/master_patch.patch +++ b/patches/master_patch.patch @@ -2105,6 +2105,22 @@ index b7fb84846acdd37de8593a1180dfaedd2fbc431c..3b4be3019ec0dd2fa0ed636bc6a56ea2 return switches::autoplay::kUserGestureRequiredPolicy; #else return switches::autoplay::kNoUserGestureRequiredPolicy; +diff --git a/net/base/host_port_pair.cc b/net/base/host_port_pair.cc +index ec8248449dbcd4156e361fcc8781ce0712f26a02..8fd7daa8348a7a8e7f044b501dfeff8d4b578b35 100644 +--- a/net/base/host_port_pair.cc ++++ b/net/base/host_port_pair.cc +@@ -18,9 +18,11 @@ + namespace net { + + HostPortPair::HostPortPair() : port_(0) {} ++#if 0 // muon override + HostPortPair::HostPortPair(const std::string& in_host, uint16_t in_port) + : host_(in_host), port_(in_port) { + } ++#endif + + // static + HostPortPair HostPortPair::FromURL(const GURL& url) { diff --git a/net/base/host_port_pair.h b/net/base/host_port_pair.h index a5ee6bda3ff542624b484b7a11811b708fec3e11..0d635e6dd1242382bd5845f6cb7674dc32c58b5d 100644 --- a/net/base/host_port_pair.h @@ -2214,7 +2230,7 @@ index 551953165f93c8d8e4772f0e905f1c4819aaf3b5..caf6df58e858580b165e6ff689572a3d EVENT_TYPE(SOCKS5_HANDSHAKE_WRITE) diff --git a/net/proxy/proxy_server.cc b/net/proxy/proxy_server.cc -index ed81ebbb26b4f439d618c115b32f49249d9284a6..35c592babe062b5804c8d3292dd3893ea51279b2 100644 +index ed81ebbb26b4f439d618c115b32f49249d9284a6..ebfa79de63e40539a09d072a62c8522fef7cf0f4 100644 --- a/net/proxy/proxy_server.cc +++ b/net/proxy/proxy_server.cc @@ -8,6 +8,7 @@ @@ -2225,34 +2241,15 @@ index ed81ebbb26b4f439d618c115b32f49249d9284a6..35c592babe062b5804c8d3292dd3893e #include "net/base/url_util.h" #include "net/http/http_util.h" -@@ -229,10 +230,14 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( - HostPortPair host_port_pair; - - if (scheme != SCHEME_INVALID && scheme != SCHEME_DIRECT) { -+ std::string username; -+ std::string password; +@@ -232,7 +233,7 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( std::string host; int port = -1; // If the scheme has a host/port, parse it. - bool ok = ParseHostAndPort(begin, end, &host, &port); -+ bool ok = scheme == SCHEME_SOCKS5 -+ ? ParseAuthHostAndPort(begin, end, &username, &password, &host, &port) -+ : ParseHostAndPort(begin, end, &host, &port); ++ bool ok = ParseAuthHostAndPort(begin, end, &host, &port); if (!ok) return ProxyServer(); // Invalid -- failed parsing [":"] -@@ -240,7 +245,10 @@ ProxyServer ProxyServer::FromSchemeHostAndPort( - if (port == -1) - port = GetDefaultPortForScheme(scheme); - -- host_port_pair = HostPortPair(host, static_cast(port)); -+ DCHECK(scheme == SCHEME_SOCKS5 || username.size() == 0); -+ DCHECK(scheme == SCHEME_SOCKS5 || password.size() == 0); -+ host_port_pair = HostPortPair( -+ username, password, host, static_cast(port)); - } - - return ProxyServer(scheme, host_port_pair); diff --git a/net/socket/socks5_client_socket.cc b/net/socket/socks5_client_socket.cc index 19cdfddbe0c533b18f57bfcdd25ff9958ac724dc..c99f6642e0204fc5c2c6e745dcce67473e2b8188 100644 --- a/net/socket/socks5_client_socket.cc From 650ace6e0bd6dd71f717a331af446253545edf11 Mon Sep 17 00:00:00 2001 From: Taylor `Riastradh' Campbell Date: Fri, 2 Feb 2018 01:18:16 +0000 Subject: [PATCH 06/11] Omit needless hunk to mark already-virtual function as virtual. --- patches/master_patch.patch | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/patches/master_patch.patch b/patches/master_patch.patch index 668a5b4519..f2655b4a4f 100644 --- a/patches/master_patch.patch +++ b/patches/master_patch.patch @@ -2324,7 +2324,7 @@ index 19cdfddbe0c533b18f57bfcdd25ff9958ac724dc..c99f6642e0204fc5c2c6e745dcce6747 } diff --git a/net/socket/socks5_client_socket.h b/net/socket/socks5_client_socket.h -index afef312d001297ac1178b93fea92586102a54ac8..9c37710526d38ce9a48ef4942654e9dbaae2c567 100644 +index afef312d001297ac1178b93fea92586102a54ac8..6f04733219580abd2477bfb0deaafd2e00cd5251 100644 --- a/net/socket/socks5_client_socket.h +++ b/net/socket/socks5_client_socket.h @@ -19,6 +19,7 @@ @@ -2335,15 +2335,6 @@ index afef312d001297ac1178b93fea92586102a54ac8..9c37710526d38ce9a48ef4942654e9db #include "net/socket/stream_socket.h" #include "url/gurl.h" -@@ -40,7 +41,7 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { - const HostResolver::RequestInfo& req_info); - - // On destruction Disconnect() is called. -- ~SOCKS5ClientSocket() override; -+ virtual ~SOCKS5ClientSocket() override; - - // StreamSocket implementation. - @@ -81,6 +82,8 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { STATE_GREET_WRITE_COMPLETE, STATE_GREET_READ, From f42eb0defa5f85a3a5d450197846125eb3d6a7fc Mon Sep 17 00:00:00 2001 From: Taylor `Riastradh' Campbell Date: Wed, 7 Feb 2018 21:20:02 +0000 Subject: [PATCH 07/11] Update chromium_src/BUILD.gn for previous commits. --- chromium_src/BUILD.gn | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/chromium_src/BUILD.gn b/chromium_src/BUILD.gn index a64c55b0b5..4adfaa5eeb 100644 --- a/chromium_src/BUILD.gn +++ b/chromium_src/BUILD.gn @@ -1200,8 +1200,9 @@ source_set("sessions") { source_set("net") { sources = [ - "net/socket/socks_auth_null.cc", - "net/socket/socks_auth_username_password.cc", + "net/base/host_port_pair_auth.cc", + "net/base/url_auth_util.cc", + "net/socket/socks5_client_socket_auth.cc", ] deps = [ "//net", From 1edc0969249bfb558812acce4b78de0ec9586a07 Mon Sep 17 00:00:00 2001 From: Taylor `Riastradh' Campbell Date: Fri, 9 Feb 2018 21:40:52 +0000 Subject: [PATCH 08/11] Use username/password components from URL parse only if valid. Otherwise, we crash trying to use them. --- chromium_src/net/base/url_auth_util.cc | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/chromium_src/net/base/url_auth_util.cc b/chromium_src/net/base/url_auth_util.cc index b0ce8b5d32..99a2e3481c 100644 --- a/chromium_src/net/base/url_auth_util.cc +++ b/chromium_src/net/base/url_auth_util.cc @@ -68,20 +68,22 @@ bool ParseAuthHostAndPort(std::string::const_iterator host_and_port_begin, // Reassemble user:pass@host as up_host. std::string up_host; - std::string username(auth_begin + username_component.begin, - username_component.len); - std::string password(auth_begin + password_component.begin, - password_component.len); - std::string hostname(auth_begin + hostname_component.begin, - hostname_component.len); - if (username.size() != 0 || password.size() != 0) { - up_host += username; - if (password.size() != 0) { + if (username_component.is_valid() || password_component.is_valid()) { + if (username_component.is_valid()) { + std::string username(auth_begin + username_component.begin, + username_component.len); + up_host += username; + } + if (password_component.is_valid()) { + std::string password(auth_begin + password_component.begin, + password_component.len); up_host += ":"; up_host += password; } up_host += "@"; } + std::string hostname(auth_begin + hostname_component.begin, + hostname_component.len); up_host += hostname; // Pass results back to caller. From 25e3a6a14feaa2f090b2e501aec4dea855add5d6 Mon Sep 17 00:00:00 2001 From: Taylor `Riastradh' Campbell Date: Fri, 9 Feb 2018 21:43:59 +0000 Subject: [PATCH 09/11] Override HostPortPair::ToString too so it is possible to test this. --- chromium_src/net/base/host_port_pair_auth.cc | 18 ++++++++++++++++++ patches/master_patch.patch | 17 ++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/chromium_src/net/base/host_port_pair_auth.cc b/chromium_src/net/base/host_port_pair_auth.cc index ab0fd70190..c63e993e68 100644 --- a/chromium_src/net/base/host_port_pair_auth.cc +++ b/chromium_src/net/base/host_port_pair_auth.cc @@ -4,6 +4,8 @@ #include "net/base/host_port_pair.h" +#include "base/strings/string_number_conversions.h" + namespace net { HostPortPair::HostPortPair(const std::string& username, @@ -29,4 +31,20 @@ HostPortPair::HostPortPair(const std::string& up_host, uint16_t in_port) } } +std::string HostPortPair::ToString() const { + std::string ret; + if (username_.size() != 0 || password_.size() != 0) { + ret += username_; + if (password_.size() != 0) { + ret += ':'; + ret += password_; + } + ret += '@'; + } + ret += HostForURL(); + ret += ':'; + ret += base::UintToString(port_); + return ret; +} + } // namespace net diff --git a/patches/master_patch.patch b/patches/master_patch.patch index f2655b4a4f..abfc2bec18 100644 --- a/patches/master_patch.patch +++ b/patches/master_patch.patch @@ -2106,7 +2106,7 @@ index b7fb84846acdd37de8593a1180dfaedd2fbc431c..3b4be3019ec0dd2fa0ed636bc6a56ea2 #else return switches::autoplay::kNoUserGestureRequiredPolicy; diff --git a/net/base/host_port_pair.cc b/net/base/host_port_pair.cc -index ec8248449dbcd4156e361fcc8781ce0712f26a02..8fd7daa8348a7a8e7f044b501dfeff8d4b578b35 100644 +index ec8248449dbcd4156e361fcc8781ce0712f26a02..e9f4dce79a73c1949293c45486606377f4f11ebb 100644 --- a/net/base/host_port_pair.cc +++ b/net/base/host_port_pair.cc @@ -18,9 +18,11 @@ @@ -2121,6 +2121,21 @@ index ec8248449dbcd4156e361fcc8781ce0712f26a02..8fd7daa8348a7a8e7f044b501dfeff8d // static HostPortPair HostPortPair::FromURL(const GURL& url) { +@@ -50,12 +52,14 @@ HostPortPair HostPortPair::FromString(const std::string& str) { + return host_port_pair; + } + ++#if 0 // muon override + std::string HostPortPair::ToString() const { + std::string ret(HostForURL()); + ret += ':'; + ret += base::UintToString(port_); + return ret; + } ++#endif + + std::string HostPortPair::HostForURL() const { + // TODO(rtenneti): Add support for |host| to have '\0'. diff --git a/net/base/host_port_pair.h b/net/base/host_port_pair.h index a5ee6bda3ff542624b484b7a11811b708fec3e11..0d635e6dd1242382bd5845f6cb7674dc32c58b5d 100644 --- a/net/base/host_port_pair.h From 5f97ec7be572d9719e46aada4d2f2a62a2c7e3ec Mon Sep 17 00:00:00 2001 From: Taylor `Riastradh' Campbell Date: Tue, 20 Mar 2018 22:33:32 +0000 Subject: [PATCH 10/11] Resolve C65 merge conflicts. --- .../net/socket/socks5_client_socket_auth.cc | 4 +++- chromium_src/net/socket/socks5_client_socket_auth.h | 1 + patches/master_patch.patch | 13 ++++++++----- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/chromium_src/net/socket/socks5_client_socket_auth.cc b/chromium_src/net/socket/socks5_client_socket_auth.cc index b7fd7eda02..119034c95f 100644 --- a/chromium_src/net/socket/socks5_client_socket_auth.cc +++ b/chromium_src/net/socket/socks5_client_socket_auth.cc @@ -10,8 +10,10 @@ namespace net { SOCKS5ClientSocketAuth::SOCKS5ClientSocketAuth( std::unique_ptr transport_socket, const HostResolver::RequestInfo& req_info, + const NetworkTrafficAnnotationTag& traffic_annotation, const HostPortPair& proxy_host_port) - : SOCKS5ClientSocket(std::move(transport_socket), req_info), + : SOCKS5ClientSocket(std::move(transport_socket), req_info, + traffic_annotation), proxy_host_port_(proxy_host_port), next_state_(STATE_INIT_WRITE) { } diff --git a/chromium_src/net/socket/socks5_client_socket_auth.h b/chromium_src/net/socket/socks5_client_socket_auth.h index 05878aaa32..f1c176f7e8 100644 --- a/chromium_src/net/socket/socks5_client_socket_auth.h +++ b/chromium_src/net/socket/socks5_client_socket_auth.h @@ -13,6 +13,7 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocketAuth : public SOCKS5ClientSocket { public: SOCKS5ClientSocketAuth(std::unique_ptr transport_socket, const HostResolver::RequestInfo& req_info, + const NetworkTrafficAnnotationTag& traffic_annotation, const HostPortPair& proxy_host_port); ~SOCKS5ClientSocketAuth() override; private: diff --git a/patches/master_patch.patch b/patches/master_patch.patch index abfc2bec18..b5e1172b53 100644 --- a/patches/master_patch.patch +++ b/patches/master_patch.patch @@ -2342,12 +2342,13 @@ diff --git a/net/socket/socks5_client_socket.h b/net/socket/socks5_client_socket index afef312d001297ac1178b93fea92586102a54ac8..6f04733219580abd2477bfb0deaafd2e00cd5251 100644 --- a/net/socket/socks5_client_socket.h +++ b/net/socket/socks5_client_socket.h -@@ -19,6 +19,7 @@ +@@ -19,7 +19,8 @@ #include "net/base/net_export.h" #include "net/dns/host_resolver.h" #include "net/log/net_log_with_source.h" +#include "net/socket/socks_client_socket_pool.h" #include "net/socket/stream_socket.h" + #include "net/traffic_annotation/network_traffic_annotation.h" #include "url/gurl.h" @@ -81,6 +82,8 @@ class NET_EXPORT_PRIVATE SOCKS5ClientSocket : public StreamSocket { @@ -2387,19 +2388,21 @@ index 86b4ac0d109fca5da44501b6fdb08d97b05fc28d..3294267b3e97cbc5c28a95473245fbc6 #include "net/socket/socks_client_socket.h" #include "net/socket/transport_client_socket_pool.h" -@@ -146,8 +146,10 @@ int SOCKSConnectJob::DoSOCKSConnect() { +@@ -146,9 +146,11 @@ int SOCKSConnectJob::DoSOCKSConnect() { // Add a SOCKS connection on top of the tcp socket. if (socks_params_->is_socks_v5()) { - socket_.reset(new SOCKS5ClientSocket(std::move(transport_socket_handle_), -- socks_params_->destination())); +- socks_params_->destination(), +- socks_params_->traffic_annotation())); + socket_.reset(new SOCKS5ClientSocketAuth( + std::move(transport_socket_handle_), + socks_params_->destination(), ++ socks_params_->traffic_annotation(), + socks_params_->transport_params()->destination().host_port_pair())); } else { - socket_.reset(new SOCKSClientSocket(std::move(transport_socket_handle_), - socks_params_->destination(), + socket_.reset(new SOCKSClientSocket( + std::move(transport_socket_handle_), socks_params_->destination(), diff --git a/net/url_request/url_request_job.h b/net/url_request/url_request_job.h index 389315a25d7da30d71b59e3803ab795bc4c18e1c..79797fe7e674f9f6d2a65de542f262a945454f16 100644 --- a/net/url_request/url_request_job.h From b9e3f89dd7a2cdbd0729006d1c969298a8624f01 Mon Sep 17 00:00:00 2001 From: Taylor `Riastradh' Campbell Date: Wed, 21 Mar 2018 18:13:38 +0000 Subject: [PATCH 11/11] Add configs to net set per request from @bridiver. --- chromium_src/BUILD.gn | 3 +++ 1 file changed, 3 insertions(+) diff --git a/chromium_src/BUILD.gn b/chromium_src/BUILD.gn index 4adfaa5eeb..d912a7e153 100644 --- a/chromium_src/BUILD.gn +++ b/chromium_src/BUILD.gn @@ -1199,6 +1199,9 @@ source_set("sessions") { } source_set("net") { + configs += [ "//electron/build:electron_config" ] + configs += [ ":chromium_src_config" ] + sources = [ "net/base/host_port_pair_auth.cc", "net/base/url_auth_util.cc",