summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorabarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-20 04:30:23 +0000
committerabarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-05-20 04:30:23 +0000
commita9cea754e016601a59cb07be2946559a9ad21738 (patch)
treed4c5baf30736f27de914f5091fde20707d1c9e87 /net
parenta65d1b09eb7adb31e9ac975962c19cdc15c44d97 (diff)
downloadchromium_src-a9cea754e016601a59cb07be2946559a9ad21738.zip
chromium_src-a9cea754e016601a59cb07be2946559a9ad21738.tar.gz
chromium_src-a9cea754e016601a59cb07be2946559a9ad21738.tar.bz2
More progress on ForceHTTPS.
Instead of turning on strict HTTPS error processing for every site, we now track which sites have opted in. Our implementation is still experimental and hidden behing the command line switch --force-https. R=darin TEST=No tests yet because this is just an experiment. Review URL: http://codereview.chromium.org/113503 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@16464 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/base/force_tls_state.cc34
-rw-r--r--net/base/force_tls_state.h50
-rw-r--r--net/net.gyp2
-rw-r--r--net/url_request/url_request_context.h7
-rw-r--r--net/url_request/url_request_http_job.cc57
-rw-r--r--net/url_request/url_request_http_job.h5
6 files changed, 150 insertions, 5 deletions
diff --git a/net/base/force_tls_state.cc b/net/base/force_tls_state.cc
new file mode 100644
index 0000000..4be33f5
--- /dev/null
+++ b/net/base/force_tls_state.cc
@@ -0,0 +1,34 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/base/force_tls_state.h"
+
+#include "base/logging.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/registry_controlled_domain.h"
+
+namespace net {
+
+ForceTLSState::ForceTLSState() {
+}
+
+void ForceTLSState::DidReceiveHeader(const GURL& url,
+ const std::string& value) {
+ // TODO(abarth): Actually parse |value| once the spec settles down.
+ EnableHost(url.host());
+}
+
+void ForceTLSState::EnableHost(const std::string& host) {
+ // TODO(abarth): Canonicalize host.
+ AutoLock lock(lock_);
+ enabled_hosts_.insert(host);
+}
+
+bool ForceTLSState::IsEnabledForHost(const std::string& host) {
+ // TODO(abarth): Canonicalize host.
+ AutoLock lock(lock_);
+ return enabled_hosts_.find(host) != enabled_hosts_.end();
+}
+
+} // namespace
diff --git a/net/base/force_tls_state.h b/net/base/force_tls_state.h
new file mode 100644
index 0000000..988e9c07
--- /dev/null
+++ b/net/base/force_tls_state.h
@@ -0,0 +1,50 @@
+// Copyright (c) 2009 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_FORCE_TLS_STATE_H_
+#define NET_BASE_FORCE_TLS_STATE_H_
+
+#include <set>
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/lock.h"
+
+class GURL;
+
+namespace net {
+
+// ForceTLSState
+//
+// Tracks which hosts have enabled ForceTLS. After a host enables ForceTLS,
+// then we refuse to talk to the host over HTTP, treat all certificate errors as
+// fatal, and refuses to load any mixed content.
+//
+class ForceTLSState {
+ public:
+ ForceTLSState();
+
+ // Called when we see an X-Force-TLS header that we should process. Modifies
+ // our state as instructed by the header.
+ void DidReceiveHeader(const GURL& url, const std::string& value);
+
+ // Enable ForceTLS for |host|.
+ void EnableHost(const std::string& host);
+
+ // Returns whether |host| has had ForceTLS enabled.
+ bool IsEnabledForHost(const std::string& host);
+
+ private:
+ // The set of hosts that have enabled ForceTLS.
+ std::set<std::string> enabled_hosts_;
+
+ // Protect access to our data members with this lock.
+ Lock lock_;
+
+ DISALLOW_COPY_AND_ASSIGN(ForceTLSState);
+};
+
+} // namespace net
+
+#endif // NET_BASE_FORCE_TLS_STATE_H_
diff --git a/net/net.gyp b/net/net.gyp
index 8c11266..778f2da 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -75,6 +75,8 @@
'base/file_stream_win.cc',
'base/filter.cc',
'base/filter.h',
+ 'base/force_tls_state.cc',
+ 'base/force_tls_state.h',
'base/gzip_filter.cc',
'base/gzip_filter.h',
'base/gzip_header.cc',
diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h
index 29735ac..8e32c97 100644
--- a/net/url_request/url_request_context.h
+++ b/net/url_request/url_request_context.h
@@ -17,6 +17,7 @@
namespace net {
class CookieMonster;
+class ForceTLSState;
class FtpTransactionFactory;
class HttpTransactionFactory;
class ProxyService;
@@ -30,7 +31,8 @@ class URLRequestContext :
: proxy_service_(NULL),
http_transaction_factory_(NULL),
ftp_transaction_factory_(NULL),
- cookie_store_(NULL) {
+ cookie_store_(NULL),
+ force_tls_state_(NULL) {
}
// Get the proxy service for this context.
@@ -54,6 +56,8 @@ class URLRequestContext :
// Gets the cookie policy for this context.
net::CookiePolicy* cookie_policy() { return &cookie_policy_; }
+ net::ForceTLSState* force_tls_state() { return force_tls_state_; }
+
// Gets the FTP authentication cache for this context.
net::FtpAuthCache* ftp_auth_cache() { return &ftp_auth_cache_; }
@@ -89,6 +93,7 @@ class URLRequestContext :
net::FtpTransactionFactory* ftp_transaction_factory_;
net::CookieMonster* cookie_store_;
net::CookiePolicy cookie_policy_;
+ net::ForceTLSState* force_tls_state_;;
net::FtpAuthCache ftp_auth_cache_;
std::string accept_language_;
std::string accept_charset_;
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index a86edbd..eff2344 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -12,8 +12,10 @@
#include "base/message_loop.h"
#include "base/rand_util.h"
#include "base/string_util.h"
+#include "net/base/cert_status_flags.h"
#include "net/base/cookie_monster.h"
#include "net/base/filter.h"
+#include "net/base/force_tls_state.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
@@ -47,7 +49,10 @@ URLRequestJob* URLRequestHttpJob::Factory(URLRequest* request,
// network request.
static const bool kForceHTTPS =
CommandLine::ForCurrentProcess()->HasSwitch(switches::kForceHTTPS);
- if (kForceHTTPS && scheme != "https")
+ if (kForceHTTPS && scheme == "http" &&
+ request->context()->force_tls_state() &&
+ request->context()->force_tls_state()->IsEnabledForHost(
+ request->url().host()))
return new URLRequestErrorJob(request, net::ERR_DISALLOWED_URL_SCHEME);
return new URLRequestHttpJob(request);
@@ -441,9 +446,7 @@ void URLRequestHttpJob::OnStartCompleted(int result) {
if (result == net::OK) {
NotifyHeadersComplete();
- } else if (net::IsCertificateError(result) &&
- !CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kForceHTTPS)) {
+ } else if (ShouldTreatAsCertificateError(result)) {
// We encountered an SSL certificate error. Ask our delegate to decide
// what we should do.
// TODO(wtc): also pass ssl_info.cert_status, or just pass the whole
@@ -470,6 +473,22 @@ void URLRequestHttpJob::OnReadCompleted(int result) {
NotifyReadComplete(result);
}
+bool URLRequestHttpJob::ShouldTreatAsCertificateError(int result) {
+ if (!net::IsCertificateError(result))
+ return false;
+
+ // Hide the fancy processing behind a command line switch.
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kForceHTTPS))
+ return true;
+
+ // Check whether our context is using ForceTLS.
+ if (!context_->force_tls_state())
+ return true;
+
+ return !context_->force_tls_state()->IsEnabledForHost(
+ request_info_.url.host());
+}
+
void URLRequestHttpJob::NotifyHeadersComplete() {
DCHECK(!response_info_);
@@ -494,6 +513,8 @@ void URLRequestHttpJob::NotifyHeadersComplete() {
}
}
+ ProcessForceTLSHeader();
+
if (SdchManager::Global() &&
SdchManager::Global()->IsInSupportedDomain(request_->url())) {
static const std::string name = "Get-Dictionary";
@@ -657,3 +678,31 @@ void URLRequestHttpJob::FetchResponseCookies() {
while (response_info_->headers->EnumerateHeader(&iter, name, &value))
response_cookies_.push_back(value);
}
+
+
+void URLRequestHttpJob::ProcessForceTLSHeader() {
+ DCHECK(response_info_);
+
+ // Hide processing behind a command line flag.
+ if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kForceHTTPS))
+ return;
+
+ // Only process X-Force-TLS from HTTPS responses.
+ if (request_info_.url.scheme() != "https")
+ return;
+
+ // Only process X-Force-TLS from responses with valid certificates.
+ if (response_info_->ssl_info.cert_status & net::CERT_STATUS_ALL_ERRORS)
+ return;
+
+ URLRequestContext* ctx = request_->context();
+ if (!ctx || !ctx->force_tls_state())
+ return;
+
+ std::string name = "X-Force-TLS";
+ std::string value;
+
+ void* iter = NULL;
+ while (response_info_->headers->EnumerateHeader(&iter, name, &value))
+ ctx->force_tls_state()->DidReceiveHeader(request_info_.url, value);
+}
diff --git a/net/url_request/url_request_http_job.h b/net/url_request/url_request_http_job.h
index a946f62..7853f83 100644
--- a/net/url_request/url_request_http_job.h
+++ b/net/url_request/url_request_http_job.h
@@ -67,9 +67,14 @@ class URLRequestHttpJob : public URLRequestJob {
std::string AssembleRequestCookies();
void FetchResponseCookies();
+ // Process the X-Force-TLS header, if one exists.
+ void ProcessForceTLSHeader();
+
void OnStartCompleted(int result);
void OnReadCompleted(int result);
+ bool ShouldTreatAsCertificateError(int result);
+
void RestartTransactionWithAuth(const std::wstring& username,
const std::wstring& password);