summaryrefslogtreecommitdiffstats
path: root/net/http/http_network_transaction.cc
diff options
context:
space:
mode:
authorcbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-02 11:27:02 +0000
committercbentzel@chromium.org <cbentzel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-02 11:27:02 +0000
commit6cc4218f3320d1ed11553c4a89a360a8db143ca7 (patch)
tree49bd71667097cbfae482321451df754afd643a18 /net/http/http_network_transaction.cc
parentb05938fdfa5c1d830be859d4339d3992c6d12410 (diff)
downloadchromium_src-6cc4218f3320d1ed11553c4a89a360a8db143ca7.zip
chromium_src-6cc4218f3320d1ed11553c4a89a360a8db143ca7.tar.gz
chromium_src-6cc4218f3320d1ed11553c4a89a360a8db143ca7.tar.bz2
Digest authentication uses a uri field to prevent replay attacks.
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 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 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@54528 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http/http_network_transaction.cc')
-rw-r--r--net/http/http_network_transaction.cc39
1 files changed, 29 insertions, 10 deletions
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index aa557db..a3624f3 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -194,6 +194,17 @@ 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
//-----------------------------------------------------------------------------
@@ -682,15 +693,7 @@ int HttpNetworkTransaction::DoResolveProxy() {
endpoint_.set_port(alternate.port);
alternate_protocol_ = alternate.protocol;
alternate_protocol_mode_ = kUsingAlternateProtocol;
-
- 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);
+ alternate_endpoint_url = UpgradeUrlToHttps(*curr_endpoint_url);
curr_endpoint_url = &alternate_endpoint_url;
}
}
@@ -779,9 +782,25 @@ 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,
- request_->url, endpoint_,
+ authentication_url,
+ endpoint_,
session_, using_ssl_);
} else {
DCHECK(proxy_info_.is_socks());