summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authornick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-02 22:00:19 +0000
committernick@chromium.org <nick@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-02 22:00:19 +0000
commit4dfabfcfe11281e15bc2a37dad0a73de2ec4b5aa (patch)
tree8888d228d02d867cd84f7aeff5f5e15ba5327e43 /net
parentfae7669f438f42169f9da35406d9b4cef6b541fd (diff)
downloadchromium_src-4dfabfcfe11281e15bc2a37dad0a73de2ec4b5aa.zip
chromium_src-4dfabfcfe11281e15bc2a37dad0a73de2ec4b5aa.tar.gz
chromium_src-4dfabfcfe11281e15bc2a37dad0a73de2ec4b5aa.tar.bz2
Revert 54528 - Digest authentication uses a uri field to prevent replay attacks.
[Reason for revert: we want to revert r54505, this was a dependent change. cbentzel agrees to reland.] When authenticating to an HTTP proxy to establish a secure tunnel (via CONNECT), the uri should be the hostname of the server and the destination port, such as "www.example.com:443". When authenticating to an HTTP proxy for a non-secure content, the uri should be the path at the server, i.e. "/index.html". If the site we are trying to connect to previously advertised "Alternate-Protocol: 443:spdy-npn/1" a request to "http://www.example.com" will be attempted on a secure port. However, the URL passed into the digest authenticator was an unsecure one, and it decided to have a uri in the form "/index.html" rather than the correct "www.example.com:443". This causes persistent failure with the password and many password prompts. BUG=49865,50822 TEST=Run with --use-spdy=npn, force connection through a digest authenticating proxy, and browse a site which advertises Alternate-Protocol through http URLs. Review URL: http://codereview.chromium.org/3028021 TBR=cbentzel@chromium.org Review URL: http://codereview.chromium.org/3091001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54614 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/http/http_auth_handler_mock.cc16
-rw-r--r--net/http/http_auth_handler_mock.h15
-rw-r--r--net/http/http_network_transaction.cc39
-rw-r--r--net/http/http_network_transaction_unittest.cc142
-rw-r--r--net/socket/socket_test_util.cc1
5 files changed, 13 insertions, 200 deletions
diff --git a/net/http/http_auth_handler_mock.cc b/net/http/http_auth_handler_mock.cc
index 9f0011d..983105b 100644
--- a/net/http/http_auth_handler_mock.cc
+++ b/net/http/http_auth_handler_mock.cc
@@ -6,7 +6,6 @@
#include "base/message_loop.h"
#include "net/base/net_errors.h"
-#include "net/http/http_request_info.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace net {
@@ -83,7 +82,6 @@ int HttpAuthHandlerMock::GenerateAuthTokenImpl(const string16* username,
CompletionCallback* callback,
std::string* auth_token) {
first_round_ = false;
- request_url_ = request->url;
if (generate_async_) {
EXPECT_TRUE(user_callback_ == NULL);
EXPECT_TRUE(auth_token_ == NULL);
@@ -120,14 +118,6 @@ void HttpAuthHandlerMock::OnGenerateAuthToken() {
callback->Run(generate_rv_);
}
-HttpAuthHandlerMock::Factory::Factory()
- : do_init_from_challenge_(false) {
- // TODO(cbentzel): Default do_init_from_challenge_ to true.
-}
-
-HttpAuthHandlerMock::Factory::~Factory() {
-}
-
void HttpAuthHandlerMock::Factory::set_mock_handler(
HttpAuthHandler* handler, HttpAuth::Target target) {
EXPECT_TRUE(handlers_[target].get() == NULL);
@@ -144,11 +134,7 @@ int HttpAuthHandlerMock::Factory::CreateAuthHandler(
scoped_ptr<HttpAuthHandler>* handler) {
if (!handlers_[target].get())
return ERR_UNEXPECTED;
- scoped_ptr<HttpAuthHandler> tmp_handler(handlers_[target].release());
- if (do_init_from_challenge_ &&
- !tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
- return ERR_INVALID_RESPONSE;
- handler->swap(tmp_handler);
+ handler->swap(handlers_[target]);
return OK;
}
diff --git a/net/http/http_auth_handler_mock.h b/net/http/http_auth_handler_mock.h
index a6b0d48..f9a676c 100644
--- a/net/http/http_auth_handler_mock.h
+++ b/net/http/http_auth_handler_mock.h
@@ -10,7 +10,6 @@
#include "base/string16.h"
#include "base/task.h"
-#include "googleurl/src/gurl.h"
#include "net/http/http_auth_handler.h"
#include "net/http/http_auth_handler_factory.h"
@@ -47,23 +46,15 @@ class HttpAuthHandlerMock : public HttpAuthHandler {
connection_based_ = connection_based;
}
- const GURL& request_url() const {
- return request_url_;
- }
-
// The Factory class simply returns the same handler each time
// CreateAuthHandler is called.
class Factory : public HttpAuthHandlerFactory {
public:
- Factory();
- virtual ~Factory();
+ Factory() {}
+ virtual ~Factory() {}
void set_mock_handler(HttpAuthHandler* handler, HttpAuth::Target target);
- void set_do_init_from_challenge(bool do_init_from_challenge) {
- do_init_from_challenge_ = do_init_from_challenge;
- }
-
virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge,
HttpAuth::Target target,
const GURL& origin,
@@ -74,7 +65,6 @@ class HttpAuthHandlerMock : public HttpAuthHandler {
private:
scoped_ptr<HttpAuthHandler> handlers_[HttpAuth::AUTH_NUM_TARGETS];
- bool do_init_from_challenge_;
};
protected:
@@ -99,7 +89,6 @@ class HttpAuthHandlerMock : public HttpAuthHandler {
std::string* auth_token_;
bool first_round_;
bool connection_based_;
- GURL request_url_;
};
} // namespace net
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 966eccb..bb17bcb 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -194,17 +194,6 @@ void ProcessAlternateProtocol(const HttpResponseHeaders& headers,
alternate_protocols->SetAlternateProtocolFor(host_port, port, protocol);
}
-GURL UpgradeUrlToHttps(const GURL& original_url) {
- GURL::Replacements replacements;
- // new_sheme and new_port need to be in scope here because GURL::Replacements
- // references the memory contained by them directly.
- const std::string new_scheme = "https";
- const std::string new_port = IntToString(443);
- replacements.SetSchemeStr(new_scheme);
- replacements.SetPortStr(new_port);
- return original_url.ReplaceComponents(replacements);
-}
-
} // namespace
//-----------------------------------------------------------------------------
@@ -693,7 +682,15 @@ int HttpNetworkTransaction::DoResolveProxy() {
endpoint_.set_port(alternate.port);
alternate_protocol_ = alternate.protocol;
alternate_protocol_mode_ = kUsingAlternateProtocol;
- alternate_endpoint_url = UpgradeUrlToHttps(*curr_endpoint_url);
+
+ url_canon::Replacements<char> replacements;
+ replacements.SetScheme("https",
+ url_parse::Component(0, strlen("https")));
+ const std::string port_str = base::IntToString(endpoint_.port());
+ replacements.SetPort(port_str.c_str(),
+ url_parse::Component(0, port_str.size()));
+ alternate_endpoint_url =
+ curr_endpoint_url->ReplaceComponents(replacements);
curr_endpoint_url = &alternate_endpoint_url;
}
}
@@ -783,25 +780,9 @@ int HttpNetworkTransaction::DoInitConnection() {
request_->referrer, disable_resolver_cache);
if (proxy_info_.is_http()) {
- GURL authentication_url = request_->url;
- if (using_ssl_) {
- if (!authentication_url.SchemeIs("https")) {
- // If a proxy tunnel connection needs to be established due to
- // an Alternate-Protocol, the URL needs to be changed to indicate
- // https or digest authentication attempts will fail.
- // For example, suppose the initial request was for
- // "http://www.example.com/index.html". If this is an SSL
- // upgrade due to alternate protocol, the digest authorization
- // should have a uri="www.example.com:443" field rather than a
- // "/index.html" entry, even though the original request URL has not
- // changed.
- authentication_url = UpgradeUrlToHttps(authentication_url);
- }
- }
establishing_tunnel_ = using_ssl_;
http_proxy_params = new HttpProxySocketParams(proxy_tcp_params,
- authentication_url,
- endpoint_,
+ request_->url, endpoint_,
session_, using_ssl_);
} else {
DCHECK(proxy_info_.is_socks());
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index 4e0d354..d6e5779 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -6373,146 +6373,4 @@ TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
HttpNetworkTransaction::SetUseAlternateProtocols(false);
}
-TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
- // This test ensures that the URL passed into the proxy is upgraded
- // to https when doing an Alternate Protocol upgrade.
- HttpNetworkTransaction::SetUseAlternateProtocols(true);
- HttpNetworkTransaction::SetNextProtos(
- "\x08http/1.1\x07http1.1\x06spdy/2\x04spdy");
-
- SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
- HttpAuthHandlerMock::Factory* auth_factory =
- new HttpAuthHandlerMock::Factory();
- HttpAuthHandlerMock* auth_handler = new HttpAuthHandlerMock();
- auth_factory->set_mock_handler(auth_handler, HttpAuth::AUTH_PROXY);
- auth_factory->set_do_init_from_challenge(true);
- session_deps.http_auth_handler_factory.reset(auth_factory);
-
- HttpRequestInfo request;
- request.method = "GET";
- request.url = GURL("http://www.google.com");
- request.load_flags = 0;
-
- // First round goes unauthenticated through the proxy.
- MockWrite data_writes_1[] = {
- MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "\r\n"),
- };
- MockRead data_reads_1[] = {
- MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
- MockRead("HTTP/1.1 200 OK\r\n"
- "Alternate-Protocol: 443:npn-spdy/2\r\n"
- "Proxy-Connection: close\r\n"
- "\r\n"),
- };
- StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
- data_writes_1, arraysize(data_writes_1));
-
- // Second round tries to tunnel to www.google.com due to the
- // Alternate-Protocol announcement in the first round. It fails due
- // to a proxy authentication challenge.
- // After the failure, a tunnel is established to www.google.com using
- // Proxy-Authorization headers. There is then a SPDY request round.
- //
- // NOTE: Despite the "Proxy-Connection: Close", these are done on the
- // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
- // does a Disconnect and Connect on the same socket, rather than trying
- // to obtain a new one.
- //
- // NOTE: Originally, the proxy response to the second CONNECT request
- // simply returned another 407 so the unit test could skip the SSL connection
- // establishment and SPDY framing issues. Alas, the
- // retry-http-when-alternate-protocol fails logic kicks in, which was more
- // complicated to set up expectations for than the SPDY session.
-
- scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
- scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
- scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
-
- MockWrite data_writes_2[] = {
- // First connection attempt without Proxy-Authorization.
- MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "\r\n"),
-
- // Second connection attempt with Proxy-Authorization.
- MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
- "Host: www.google.com\r\n"
- "Proxy-Connection: keep-alive\r\n"
- "Proxy-Authorization: auth_token\r\n"
- "\r\n"),
-
- // SPDY request
- CreateMockWrite(*req),
- };
- const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
- "Proxy-Authenticate: Mock\r\n"
- "Proxy-Connection: close\r\n"
- "\r\n");
- const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
- MockRead data_reads_2[] = {
- // First connection attempt fails
- MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
- MockRead(true, kRejectConnectResponse,
- arraysize(kRejectConnectResponse) - 1, 1),
-
- // Second connection attempt passes
- MockRead(true, kAcceptConnectResponse,
- arraysize(kAcceptConnectResponse) -1, 4),
-
- // SPDY response
- CreateMockRead(*resp.get(), 6),
- CreateMockRead(*data.get(), 6),
- MockRead(true, 0, 0, 6),
- };
- scoped_refptr<OrderedSocketData> data_2(
- new OrderedSocketData(data_reads_2, arraysize(data_reads_2),
- data_writes_2, arraysize(data_writes_2)));
-
- SSLSocketDataProvider ssl(true, OK);
- ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
- ssl.next_proto = "spdy/2";
- ssl.was_npn_negotiated = true;
-
- session_deps.socket_factory.AddSocketDataProvider(&data_1);
- session_deps.socket_factory.AddSocketDataProvider(data_2.get());
- session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
- scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
-
- // First round should work and provide the Alternate-Protocol state.
- TestCompletionCallback callback_1;
- scoped_ptr<HttpTransaction> trans_1(new HttpNetworkTransaction(session));
- int rv = trans_1->Start(&request, &callback_1, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- EXPECT_EQ(OK, callback_1.WaitForResult());
-
- // Second round should attempt a tunnel connect and get an auth challenge.
- TestCompletionCallback callback_2;
- scoped_ptr<HttpTransaction> trans_2(new HttpNetworkTransaction(session));
- rv = trans_2->Start(&request, &callback_2, BoundNetLog());
- EXPECT_EQ(ERR_IO_PENDING, rv);
- EXPECT_EQ(OK, callback_2.WaitForResult());
- const HttpResponseInfo* response = trans_2->GetResponseInfo();
- ASSERT_FALSE(response == NULL);
- ASSERT_FALSE(response->auth_challenge.get() == NULL);
-
- // Restart with auth. Tunnel should work and response received.
- TestCompletionCallback callback_3;
- rv = trans_2->RestartWithAuth(kFoo, kBar, &callback_3);
- EXPECT_EQ(ERR_IO_PENDING, rv);
- EXPECT_EQ(OK, callback_3.WaitForResult());
-
- // After all that work, these two lines (or actually, just the scheme) are
- // what this test is all about. Make sure it happens correctly.
- const GURL& request_url = auth_handler->request_url();
- EXPECT_EQ("https", request_url.scheme());
- EXPECT_EQ("www.google.com", request_url.host());
-
- HttpNetworkTransaction::SetNextProtos("");
- HttpNetworkTransaction::SetUseAlternateProtocols(false);
-}
-
} // namespace net
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index 142a39e..ce7f3fc06 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -187,7 +187,6 @@ int MockTCPClientSocket::Connect(net::CompletionCallback* callback) {
if (connected_)
return net::OK;
connected_ = true;
- peer_closed_connection_ = false;
if (data_->connect_data().async) {
RunCallbackAsync(callback, data_->connect_data().result);
return net::ERR_IO_PENDING;