summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorabarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-18 01:07:07 +0000
committerabarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-18 01:07:07 +0000
commit9281268866081d21cc5b3a7fb2b98e146cc98d7b (patch)
tree2b9247e9da43413d0600fec255a67b24bc070b1a
parent44b2c885548d647611d908309dfdf6306eac7ed8 (diff)
downloadchromium_src-9281268866081d21cc5b3a7fb2b98e146cc98d7b.zip
chromium_src-9281268866081d21cc5b3a7fb2b98e146cc98d7b.tar.gz
chromium_src-9281268866081d21cc5b3a7fb2b98e146cc98d7b.tar.bz2
SSLPolicy Fix: Step 8.
Cleanup the SSLPolicy API. This should be the last reorganization patch. The next step should be the substantive changes. R=jcampan BUG=8706 Review URL: http://codereview.chromium.org/48091 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@11937 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/ssl/ssl_manager.cc137
-rw-r--r--chrome/browser/ssl/ssl_manager.h132
-rw-r--r--chrome/browser/ssl/ssl_policy.cc119
-rw-r--r--chrome/browser/ssl/ssl_policy.h23
4 files changed, 267 insertions, 144 deletions
diff --git a/chrome/browser/ssl/ssl_manager.cc b/chrome/browser/ssl/ssl_manager.cc
index 095e07d..d384415 100644
--- a/chrome/browser/ssl/ssl_manager.cc
+++ b/chrome/browser/ssl/ssl_manager.cc
@@ -12,12 +12,12 @@
#include "chrome/browser/renderer_host/resource_request_details.h"
#include "chrome/browser/ssl/ssl_error_info.h"
#include "chrome/browser/ssl/ssl_host_state.h"
+#include "chrome/browser/ssl/ssl_policy.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
#include "chrome/browser/tab_contents/provisional_load_details.h"
#include "chrome/browser/tab_contents/tab_util.h"
#include "chrome/browser/tab_contents/web_contents.h"
-#include "chrome/browser/ssl/ssl_policy.h"
#include "chrome/common/l10n_util.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/pref_names.h"
@@ -120,6 +120,8 @@ SSLManager::SSLManager(NavigationController* controller, Delegate* delegate)
Source<NavigationController>(controller_));
registrar_.Add(this, NotificationType::LOAD_FROM_MEMORY_CACHE,
Source<NavigationController>(controller_));
+ registrar_.Add(this, NotificationType::SSL_INTERNAL_STATE_CHANGED,
+ NotificationService::AllSources());
}
SSLManager::~SSLManager() {
@@ -189,16 +191,29 @@ void SSLManager::AddMessageToConsole(const std::wstring& msg,
}
// Delegate API method.
+void SSLManager::MarkHostAsBroken(const std::string& host) {
+ ssl_host_state_->MarkHostAsBroken(host);
+ DispatchSSLInternalStateChanged();
+}
+
+// Delegate API method.
+bool SSLManager::DidMarkHostAsBroken(const std::string& host) const {
+ return ssl_host_state_->DidMarkHostAsBroken(host);
+}
+
+// Delegate API method.
void SSLManager::DenyCertForHost(net::X509Certificate* cert,
const std::string& host) {
// Remember that we don't like this cert for this host.
ssl_host_state_->DenyCertForHost(cert, host);
+ DispatchSSLInternalStateChanged();
}
// Delegate API method.
void SSLManager::AllowCertForHost(net::X509Certificate* cert,
const std::string& host) {
ssl_host_state_->AllowCertForHost(cert, host);
+ DispatchSSLInternalStateChanged();
}
// Delegate API method.
@@ -207,12 +222,15 @@ net::X509Certificate::Policy::Judgment SSLManager::QueryPolicy(
return ssl_host_state_->QueryPolicy(cert, host);
}
-bool SSLManager::CanShowInsecureContent(const GURL& url) {
- return ssl_host_state_->DidAllowMixedContentForHost(url.host());
+// Delegate API method.
+void SSLManager::AllowMixedContentForHost(const std::string& host) {
+ ssl_host_state_->AllowMixedContentForHost(host);
+ DispatchSSLInternalStateChanged();
}
-void SSLManager::AllowShowInsecureContentForURL(const GURL& url) {
- ssl_host_state_->AllowMixedContentForHost(url.host());
+// Delegate API method.
+bool SSLManager::DidAllowMixedContentForHost(const std::string& host) const {
+ return ssl_host_state_->DidAllowMixedContentForHost(host);
}
bool SSLManager::ProcessedSSLErrorFromRequest() const {
@@ -230,6 +248,9 @@ bool SSLManager::ProcessedSSLErrorFromRequest() const {
SSLManager::ErrorHandler::ErrorHandler(ResourceDispatcherHost* rdh,
URLRequest* request,
+ ResourceType::Type resource_type,
+ const std::string& frame_origin,
+ const std::string& main_frame_origin,
MessageLoop* ui_loop)
: ui_loop_(ui_loop),
io_loop_(MessageLoop::current()),
@@ -237,6 +258,9 @@ SSLManager::ErrorHandler::ErrorHandler(ResourceDispatcherHost* rdh,
request_id_(0, 0),
resource_dispatcher_host_(rdh),
request_url_(request->url()),
+ resource_type_(resource_type),
+ frame_origin_(frame_origin),
+ main_frame_origin_(main_frame_origin),
request_has_been_notified_(false) {
DCHECK(MessageLoop::current() != ui_loop);
@@ -427,12 +451,14 @@ SSLManager::CertError::CertError(
ResourceDispatcherHost* rdh,
URLRequest* request,
ResourceType::Type resource_type,
+ const std::string& frame_origin,
+ const std::string& main_frame_origin,
int cert_error,
net::X509Certificate* cert,
MessageLoop* ui_loop)
- : ErrorHandler(rdh, request, ui_loop),
- cert_error_(cert_error),
- resource_type_(resource_type) {
+ : ErrorHandler(rdh, request, resource_type, frame_origin,
+ main_frame_origin, ui_loop),
+ cert_error_(cert_error) {
DCHECK(request == resource_dispatcher_host_->GetURLRequest(request_id_));
// We cannot use the request->ssl_info(), it's not been initialized yet, so
@@ -457,8 +483,14 @@ void SSLManager::OnSSLCertificateError(ResourceDispatcherHost* rdh,
// A certificate error occurred. Construct a CertError object and hand it
// over to the UI thread for processing.
ui_loop->PostTask(FROM_HERE,
- NewRunnableMethod(new CertError(rdh, request, info->resource_type,
- cert_error, cert, ui_loop),
+ NewRunnableMethod(new CertError(rdh,
+ request,
+ info->resource_type,
+ info->frame_origin,
+ info->main_frame_origin,
+ cert_error,
+ cert,
+ ui_loop),
&CertError::Dispatch));
}
@@ -479,33 +511,21 @@ bool SSLManager::ShouldStartRequest(ResourceDispatcherHost* rdh,
ui_loop->PostTask(FROM_HERE,
- NewRunnableMethod(new MixedContentHandler(rdh, request, ui_loop),
+ NewRunnableMethod(new MixedContentHandler(rdh, request,
+ info->resource_type,
+ info->frame_origin,
+ info->main_frame_origin,
+ ui_loop),
&MixedContentHandler::Dispatch));
return false;
}
void SSLManager::OnCertError(CertError* error) {
- // Ask our delegate to deal with the error.
- NavigationEntry* entry = controller_->GetActiveEntry();
- // We might not have a navigation entry in some cases (e.g. when a
- // HTTPS page opens a popup with no URL and then populate it with
- // document.write()). See bug http://crbug.com/3845.
- if (!entry)
- return;
-
- delegate()->OnCertError(entry->url(), error);
+ delegate()->OnCertError(error);
}
-void SSLManager::OnMixedContent(MixedContentHandler* mixed_content) {
- // Ask our delegate to deal with the mixed content.
- NavigationEntry* entry = controller_->GetActiveEntry();
- // We might not have a navigation entry in some cases (e.g. when a
- // HTTPS page opens a popup with no URL and then populate it with
- // document.write()). See bug http://crbug.com/3845.
- if (!entry)
- return;
-
- delegate()->OnMixedContent(controller_, entry->url(), mixed_content);
+void SSLManager::OnMixedContent(MixedContentHandler* handler) {
+ delegate()->OnMixedContent(handler);
}
void SSLManager::Observe(NotificationType type,
@@ -534,11 +554,28 @@ void SSLManager::Observe(NotificationType type,
DidLoadFromMemoryCache(
Details<LoadFromMemoryCacheDetails>(details).ptr());
break;
+ case NotificationType::SSL_INTERNAL_STATE_CHANGED:
+ DidChangeSSLInternalState();
+ break;
default:
NOTREACHED() << "The SSLManager received an unexpected notification.";
}
}
+void SSLManager::DispatchSSLInternalStateChanged() {
+ NotificationService::current()->Notify(
+ NotificationType::SSL_INTERNAL_STATE_CHANGED,
+ Source<NavigationController>(controller_),
+ NotificationService::NoDetails());
+}
+
+void SSLManager::DispatchSSLVisibleStateChanged() {
+ NotificationService::current()->Notify(
+ NotificationType::SSL_VISIBLE_STATE_CHANGED,
+ Source<NavigationController>(controller_),
+ NotificationService::NoDetails());
+}
+
void SSLManager::InitializeEntryIfNeeded(NavigationEntry* entry) {
DCHECK(entry);
@@ -565,10 +602,17 @@ void SSLManager::DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details) {
// Simulate loading this resource through the usual path.
// Note that we specify SUB_RESOURCE as the resource type as WebCore only
// caches sub-resources.
- delegate()->OnRequestStarted(this, details->url(),
- ResourceType::SUB_RESOURCE,
- details->ssl_cert_id(),
- details->ssl_cert_status());
+ scoped_refptr<RequestInfo> info = new RequestInfo(
+ this,
+ details->url(),
+ ResourceType::SUB_RESOURCE,
+ details->frame_origin(),
+ details->main_frame_origin(),
+ details->ssl_cert_id(),
+ details->ssl_cert_status());
+
+ // Simulate loading this resource through the usual path.
+ delegate()->OnRequestStarted(info.get());
}
void SSLManager::DidCommitProvisionalLoad(
@@ -654,18 +698,27 @@ void SSLManager::DidFailProvisionalLoadWithError(
void SSLManager::DidStartResourceResponse(ResourceRequestDetails* details) {
DCHECK(details);
+ scoped_refptr<RequestInfo> info = new RequestInfo(
+ this,
+ details->url(),
+ details->resource_type(),
+ details->frame_origin(),
+ details->main_frame_origin(),
+ details->ssl_cert_id(),
+ details->ssl_cert_status());
+
// Notify our delegate that we started a resource request. Ideally, the
// delegate should have the ability to cancel the request, but we can't do
// that yet.
- delegate()->OnRequestStarted(this, details->url(),
- details->resource_type(),
- details->ssl_cert_id() ,
- details->ssl_cert_status());
+ delegate()->OnRequestStarted(info.get());
}
void SSLManager::DidReceiveResourceRedirect(ResourceRedirectDetails* details) {
- // TODO(jcampan): when we receive a redirect for a sub-resource, we may want
- // to clear any mixed/unsafe content error that it may have triggered.
+ // TODO(abarth): Make sure our redirect behavior is correct. If we ever see
+ // a non-HTTPS resource in the redirect chain, we want to
+ // trigger mixed content, even if the redirect chain goes back
+ // to HTTPS. This is because the network attacker can redirect
+ // the HTTP request to https://attacker.com/payload.js.
}
void SSLManager::ShowPendingMessages() {
@@ -677,6 +730,10 @@ void SSLManager::ShowPendingMessages() {
ClearPendingMessages();
}
+void SSLManager::DidChangeSSLInternalState() {
+ // TODO(abarth): We'll need to do something here in the next step.
+}
+
void SSLManager::ClearPendingMessages() {
pending_messages_.clear();
}
diff --git a/chrome/browser/ssl/ssl_manager.h b/chrome/browser/ssl/ssl_manager.h
index 28ebbaa..b15f7e8 100644
--- a/chrome/browser/ssl/ssl_manager.h
+++ b/chrome/browser/ssl/ssl_manager.h
@@ -45,7 +45,6 @@ class WebContents;
// There is one SSLManager per tab.
// The security state (secure/insecure) is stored in the navigation entry.
// Along with it are stored any SSL error code and the associated cert.
-//
class SSLManager : public NotificationObserver {
public:
@@ -76,6 +75,15 @@ class SSLManager : public NotificationObserver {
// Available on either thread.
const GURL& request_url() const { return request_url_; }
+ // Available on either thread.
+ ResourceType::Type resource_type() const { return resource_type_; }
+
+ // Available on either thread.
+ const std::string& frame_origin() const { return frame_origin_; }
+
+ // Available on either thread.
+ const std::string& main_frame_origin() const { return main_frame_origin_; }
+
// Call on the UI thread.
SSLManager* manager() const { return manager_; }
@@ -118,6 +126,9 @@ class SSLManager : public NotificationObserver {
// Construct on the IO thread.
ErrorHandler(ResourceDispatcherHost* resource_dispatcher_host,
URLRequest* request,
+ ResourceType::Type resource_type,
+ const std::string& frame_origin,
+ const std::string& main_frame_origin,
MessageLoop* ui_loop);
// The following 2 methods are the methods subclasses should implement.
@@ -164,12 +175,26 @@ class SSLManager : public NotificationObserver {
int render_process_host_id_;
int tab_contents_id_;
+ // The URL that we requested.
// This read-only member can be accessed on any thread.
- const GURL request_url_; // The URL that we requested.
+ const GURL request_url_;
+ // What kind of resource is associated with the requested that generated
+ // that error.
+ // This read-only member can be accessed on any thread.
+ const ResourceType::Type resource_type_;
+
+ // The origin of the frame associated with this request.
+ // This read-only member can be accessed on any thread.
+ const std::string frame_origin_;
+
+ // The origin of the main frame associated with this request.
+ // This read-only member can be accessed on any thread.
+ const std::string main_frame_origin_;
+
+ // A flag to make sure we notify the URLRequest exactly once.
// Should only be accessed on the IO thread
- bool request_has_been_notified_; // A flag to make sure we notify the
- // URLRequest exactly once.
+ bool request_has_been_notified_;
DISALLOW_COPY_AND_ASSIGN(ErrorHandler);
};
@@ -186,7 +211,6 @@ class SSLManager : public NotificationObserver {
const net::SSLInfo& ssl_info() const { return ssl_info_; }
int cert_error() const { return cert_error_; }
- ResourceType::Type resource_type() const { return resource_type_; }
private:
// SSLManager is responsible for creating CertError objects.
friend class SSLManager;
@@ -197,6 +221,8 @@ class SSLManager : public NotificationObserver {
CertError(ResourceDispatcherHost* resource_dispatcher_host,
URLRequest* request,
ResourceType::Type resource_type,
+ const std::string& frame_origin,
+ const std::string& main_frame_origin,
int cert_error,
net::X509Certificate* cert,
MessageLoop* ui_loop);
@@ -209,10 +235,6 @@ class SSLManager : public NotificationObserver {
net::SSLInfo ssl_info_;
const int cert_error_; // The error we represent.
- // What kind of resource is associated with the requested that generated
- // that error.
- ResourceType::Type resource_type_;
-
DISALLOW_COPY_AND_ASSIGN(CertError);
};
@@ -223,8 +245,12 @@ class SSLManager : public NotificationObserver {
// Created on the IO thread.
MixedContentHandler(ResourceDispatcherHost* rdh,
URLRequest* request,
+ ResourceType::Type resource_type,
+ const std::string& frame_origin,
+ const std::string& main_frame_origin,
MessageLoop* ui_loop)
- : ErrorHandler(rdh, request, ui_loop) { }
+ : ErrorHandler(rdh, request, resource_type, frame_origin,
+ main_frame_origin, ui_loop) { }
protected:
virtual void OnDispatchFailed() { TakeNoAction(); }
@@ -234,6 +260,47 @@ class SSLManager : public NotificationObserver {
DISALLOW_COPY_AND_ASSIGN(MixedContentHandler);
};
+ // RequestInfo wraps up the information SSLPolicy needs about a request in
+ // order to update our security IU. RequestInfo is RefCounted in case we need
+ // to deal with the request asynchronously.
+ class RequestInfo : public base::RefCounted<RequestInfo> {
+ public:
+ RequestInfo(SSLManager* manager,
+ const GURL& url,
+ ResourceType::Type resource_type,
+ const std::string& frame_origin,
+ const std::string& main_frame_origin,
+ int ssl_cert_id,
+ int ssl_cert_status)
+ : manager_(manager),
+ url_(url),
+ resource_type_(resource_type),
+ frame_origin_(frame_origin),
+ main_frame_origin_(main_frame_origin),
+ ssl_cert_id_(ssl_cert_id),
+ ssl_cert_status_(ssl_cert_status) {
+ }
+
+ SSLManager* manager() const { return manager_; }
+ const GURL& url() const { return url_; }
+ ResourceType::Type resource_type() const { return resource_type_; }
+ const std::string& frame_origin() const { return frame_origin_; }
+ const std::string& main_frame_origin() const { return main_frame_origin_; }
+ int ssl_cert_id() const { return ssl_cert_id_; }
+ int ssl_cert_status() const { return ssl_cert_status_; }
+
+ private:
+ SSLManager* manager_;
+ GURL url_;
+ ResourceType::Type resource_type_;
+ std::string frame_origin_;
+ std::string main_frame_origin_;
+ int ssl_cert_id_;
+ int ssl_cert_status_;
+
+ DISALLOW_COPY_AND_ASSIGN(RequestInfo);
+ };
+
// The SSLManager will ask its delegate to decide how to handle events
// relevant to SSL. Delegates are expected to be stateless and intended to be
// easily implementable.
@@ -246,22 +313,15 @@ class SSLManager : public NotificationObserver {
class Delegate {
public:
// An error occurred with the certificate in an SSL connection.
- virtual void OnCertError(const GURL& main_frame_url, CertError* error) = 0;
+ virtual void OnCertError(CertError* error) = 0;
// A request for a mixed-content resource was made. Note that the resource
// request was not started yet and the delegate is responsible for starting
// it.
- virtual void OnMixedContent(
- NavigationController* navigation_controller,
- const GURL& main_frame_url,
- MixedContentHandler* mixed_content_handler) = 0;
-
- // We have started a resource request for the given URL.
- virtual void OnRequestStarted(SSLManager* manager,
- const GURL& url,
- ResourceType::Type resource_type,
- int ssl_cert_id,
- int ssl_cert_status) = 0;
+ virtual void OnMixedContent(MixedContentHandler* handler) = 0;
+
+ // We have started a resource request with the given info.
+ virtual void OnRequestStarted(RequestInfo* info) = 0;
// Returns the default security style for a given URL.
virtual SecurityStyle GetDefaultStyle(const GURL& url) = 0;
@@ -291,6 +351,14 @@ class SSLManager : public NotificationObserver {
const std::wstring& link_text,
Task* task);
+ // Records that a host is "broken," that is, the origin for that host has been
+ // contaminated with insecure content, either via HTTP or via HTTPS with a
+ // bad certificate.
+ void MarkHostAsBroken(const std::string& host);
+
+ // Returns whether the specified host was marked as broken.
+ bool DidMarkHostAsBroken(const std::string& host) const;
+
// Sets the maximum security style for the page. If the current security
// style is lower than |style|, this will not have an effect on the security
// indicators.
@@ -314,14 +382,11 @@ class SSLManager : public NotificationObserver {
net::X509Certificate::Policy::Judgment QueryPolicy(
net::X509Certificate* cert, const std::string& host);
- // Allow mixed/unsafe content to be visible (non filtered) for the specified
- // URL.
- // Note that the current implementation allows on a host name basis.
- void AllowShowInsecureContentForURL(const GURL& url);
+ // Allow mixed content to be visible (non filtered).
+ void AllowMixedContentForHost(const std::string& host);
- // Returns whether the specified URL is allowed to show insecure (mixed or
- // unsafe) content.
- bool CanShowInsecureContent(const GURL& url);
+ // Returns whether the specified host is allowed to show mixed content.
+ bool DidAllowMixedContentForHost(const std::string& host) const;
//
//////////////////////////////////////////////////////////////////////////////
@@ -366,7 +431,7 @@ class SSLManager : public NotificationObserver {
// ResourceDispatcherHost.
//
// Called on the UI thread.
- void OnMixedContent(MixedContentHandler* mixed_content);
+ void OnMixedContent(MixedContentHandler* handler);
// Entry point for navigation. This function begins the process of updating
// the security UI when the main frame navigates to a new URL.
@@ -437,6 +502,13 @@ class SSLManager : public NotificationObserver {
void DidFailProvisionalLoadWithError(ProvisionalLoadDetails* details);
void DidStartResourceResponse(ResourceRequestDetails* details);
void DidReceiveResourceRedirect(ResourceRedirectDetails* details);
+ void DidChangeSSLInternalState();
+
+ // Dispatch NotificationType::SSL_INTERNAL_STATE_CHANGED notification.
+ void DispatchSSLInternalStateChanged();
+
+ // Dispatch NotificationType::SSL_VISIBLE_STATE_CHANGED notification.
+ void DispatchSSLVisibleStateChanged();
// Convenience method for initializing navigation entries.
void InitializeEntryIfNeeded(NavigationEntry* entry);
diff --git a/chrome/browser/ssl/ssl_policy.cc b/chrome/browser/ssl/ssl_policy.cc
index 66e0ba2..ed9678b 100644
--- a/chrome/browser/ssl/ssl_policy.cc
+++ b/chrome/browser/ssl/ssl_policy.cc
@@ -38,35 +38,33 @@
// Wrap all these helper classes in an anonymous namespace.
namespace {
-class ShowUnsafeContentTask : public Task {
+class ShowMixedContentTask : public Task {
public:
- ShowUnsafeContentTask(const GURL& main_frame_url,
- SSLManager::ErrorHandler* error_handler);
- virtual ~ShowUnsafeContentTask();
+ ShowMixedContentTask(SSLManager::MixedContentHandler* handler);
+ virtual ~ShowMixedContentTask();
virtual void Run();
private:
- scoped_refptr<SSLManager::ErrorHandler> error_handler_;
- GURL main_frame_url_;
+ scoped_refptr<SSLManager::MixedContentHandler> handler_;
- DISALLOW_EVIL_CONSTRUCTORS(ShowUnsafeContentTask);
+ DISALLOW_COPY_AND_ASSIGN(ShowMixedContentTask);
};
-ShowUnsafeContentTask::ShowUnsafeContentTask(
- const GURL& main_frame_url,
- SSLManager::ErrorHandler* error_handler)
- : error_handler_(error_handler),
- main_frame_url_(main_frame_url) {
+ShowMixedContentTask::ShowMixedContentTask(
+ SSLManager::MixedContentHandler* handler)
+ : handler_(handler) {
}
-ShowUnsafeContentTask::~ShowUnsafeContentTask() {
+ShowMixedContentTask::~ShowMixedContentTask() {
}
-void ShowUnsafeContentTask::Run() {
- error_handler_->manager()->AllowShowInsecureContentForURL(main_frame_url_);
+void ShowMixedContentTask::Run() {
+ handler_->manager()->AllowMixedContentForHost(
+ GURL(handler_->main_frame_origin()).host());
+
// Reload the page.
- error_handler_->GetWebContents()->controller()->Reload(true);
+ handler_->manager()->controller()->Reload(true);
}
static void ShowErrorPage(SSLPolicy* policy, SSLManager::CertError* error) {
@@ -123,8 +121,7 @@ SSLPolicy* SSLPolicy::GetDefaultPolicy() {
return Singleton<SSLPolicy>::get();
}
-void SSLPolicy::OnCertError(const GURL& main_frame_url,
- SSLManager::CertError* error) {
+void SSLPolicy::OnCertError(SSLManager::CertError* error) {
// First we check if we know the policy for this error.
net::X509Certificate::Policy::Judgment judgment =
error->manager()->QueryPolicy(error->ssl_info().cert,
@@ -152,7 +149,7 @@ void SSLPolicy::OnCertError(const GURL& main_frame_url,
case net::ERR_CERT_COMMON_NAME_INVALID:
case net::ERR_CERT_DATE_INVALID:
case net::ERR_CERT_AUTHORITY_INVALID:
- OnOverridableCertError(main_frame_url, error);
+ OnOverridableCertError(error);
break;
case net::ERR_CERT_NO_REVOCATION_MECHANISM:
// Ignore this error.
@@ -167,7 +164,7 @@ void SSLPolicy::OnCertError(const GURL& main_frame_url,
case net::ERR_CERT_CONTAINS_ERRORS:
case net::ERR_CERT_REVOKED:
case net::ERR_CERT_INVALID:
- OnFatalCertError(main_frame_url, error);
+ OnFatalCertError(error);
break;
default:
NOTREACHED();
@@ -176,27 +173,33 @@ void SSLPolicy::OnCertError(const GURL& main_frame_url,
}
}
-void SSLPolicy::OnMixedContent(
- NavigationController* navigation_controller,
- const GURL& main_frame_url,
- SSLManager::MixedContentHandler* mixed_content_handler) {
- PrefService* prefs = navigation_controller->profile()->GetPrefs();
- FilterPolicy::Type filter_policy = FilterPolicy::DONT_FILTER;
- if (!mixed_content_handler->manager()->
- CanShowInsecureContent(main_frame_url)) {
- filter_policy = FilterPolicy::FromInt(
- prefs->GetInteger(prefs::kMixedContentFiltering));
- }
+void SSLPolicy::OnMixedContent(SSLManager::MixedContentHandler* handler) {
+ // Get the user's mixed content preference.
+ PrefService* prefs = handler->GetWebContents()->profile()->GetPrefs();
+ FilterPolicy::Type filter_policy =
+ FilterPolicy::FromInt(prefs->GetInteger(prefs::kMixedContentFiltering));
+
+ // If the user have added an exception, doctor the |filter_policy|.
+ if (handler->manager()->DidAllowMixedContentForHost(
+ GURL(handler->main_frame_origin()).host()))
+ filter_policy = FilterPolicy::DONT_FILTER;
+
if (filter_policy != FilterPolicy::DONT_FILTER) {
- mixed_content_handler->manager()->ShowMessageWithLink(
+ handler->manager()->ShowMessageWithLink(
l10n_util::GetString(IDS_SSL_INFO_BAR_FILTERED_CONTENT),
l10n_util::GetString(IDS_SSL_INFO_BAR_SHOW_CONTENT),
- new ShowUnsafeContentTask(main_frame_url, mixed_content_handler));
+ new ShowMixedContentTask(handler));
}
- mixed_content_handler->StartRequest(filter_policy);
+ handler->StartRequest(filter_policy);
+
+ NavigationEntry* entry =
+ handler->manager()->controller()->GetLastCommittedEntry();
+ // We might not have a navigation entry in some cases (e.g. when a
+ // HTTPS page opens a popup with no URL and then populate it with
+ // document.write()). See bug http://crbug.com/3845.
+ if (!entry)
+ return;
- NavigationEntry* entry = navigation_controller->GetLastCommittedEntry();
- DCHECK(entry);
// Even though we are loading the mixed-content resource, it will not be
// included in the page when we set the policy to FILTER_ALL or
// FILTER_ALL_EXCEPT_IMAGES (only images and they are stamped with warning
@@ -208,26 +211,23 @@ void SSLPolicy::OnMixedContent(
const std::wstring& msg = l10n_util::GetStringF(
IDS_MIXED_CONTENT_LOG_MESSAGE,
UTF8ToWide(entry->url().spec()),
- UTF8ToWide(mixed_content_handler->request_url().spec()));
- mixed_content_handler->manager()->
- AddMessageToConsole(msg, MESSAGE_LEVEL_WARNING);
+ UTF8ToWide(handler->request_url().spec()));
+ handler->manager()->AddMessageToConsole(msg, MESSAGE_LEVEL_WARNING);
NotificationService::current()->Notify(
NotificationType::SSL_VISIBLE_STATE_CHANGED,
- Source<NavigationController>(navigation_controller),
+ Source<NavigationController>(handler->manager()->controller()),
Details<NavigationEntry>(entry));
}
-void SSLPolicy::OnRequestStarted(SSLManager* manager, const GURL& url,
- ResourceType::Type resource_type,
- int ssl_cert_id, int ssl_cert_status) {
+void SSLPolicy::OnRequestStarted(SSLManager::RequestInfo* info) {
// These schemes never leave the browser and don't require a warning.
- if (url.SchemeIs(chrome::kDataScheme) ||
- url.SchemeIs(chrome::kJavaScriptScheme) ||
- url.SchemeIs(chrome::kAboutScheme))
+ if (info->url().SchemeIs(chrome::kDataScheme) ||
+ info->url().SchemeIs(chrome::kJavaScriptScheme) ||
+ info->url().SchemeIs(chrome::kAboutScheme))
return;
- NavigationEntry* entry = manager->controller()->GetActiveEntry();
+ NavigationEntry* entry = info->manager()->controller()->GetActiveEntry();
if (!entry) {
// We may not have an entry for cases such as the inspector.
return;
@@ -236,7 +236,7 @@ void SSLPolicy::OnRequestStarted(SSLManager* manager, const GURL& url,
NavigationEntry::SSLStatus& ssl = entry->ssl();
bool changed = false;
if (!entry->url().SchemeIsSecure() || // Current page is not secure.
- resource_type == ResourceType::MAIN_FRAME || // Main frame load.
+ info->resource_type() == ResourceType::MAIN_FRAME || // Main frame load.
net::IsCertStatusError(ssl.cert_status())) { // There is already
// an error for the main page, don't report sub-resources as unsafe
// content.
@@ -244,20 +244,21 @@ void SSLPolicy::OnRequestStarted(SSLManager* manager, const GURL& url,
return;
}
- if (url.SchemeIsSecure()) {
+ if (info->url().SchemeIsSecure()) {
// Check for insecure content (anything served over intranet is considered
// insecure).
// TODO(jcampan): bug #1178228 Disabling the broken style for intranet
// hosts for beta as it is missing error strings (and cert status).
// if (IsIntranetHost(url.host()) ||
- // net::IsCertStatusError(ssl_cert_status)) {
- if (net::IsCertStatusError(ssl_cert_status)) {
+ // net::IsCertStatusError(info->ssl_cert_status())) {
+ if (net::IsCertStatusError(info->ssl_cert_status())) {
// The resource is unsafe.
if (!ssl.has_unsafe_content()) {
changed = true;
ssl.set_has_unsafe_content();
- manager->SetMaxSecurityStyle(SECURITY_STYLE_AUTHENTICATION_BROKEN);
+ info->manager()->SetMaxSecurityStyle(
+ SECURITY_STYLE_AUTHENTICATION_BROKEN);
}
}
}
@@ -266,7 +267,7 @@ void SSLPolicy::OnRequestStarted(SSLManager* manager, const GURL& url,
// Only send the notification when something actually changed.
NotificationService::current()->Notify(
NotificationType::SSL_VISIBLE_STATE_CHANGED,
- Source<NavigationController>(manager->controller()),
+ Source<NavigationController>(info->manager()->controller()),
NotificationService::NoDetails());
}
}
@@ -305,6 +306,9 @@ bool SSLPolicy::IsMixedContent(const GURL& url,
return GURL(main_frame_origin).SchemeIsSecure() && !url.SchemeIsSecure();
}
+////////////////////////////////////////////////////////////////////////////////
+// SSLBlockingPage::Delegate methods
+
SSLErrorInfo SSLPolicy::GetSSLErrorInfo(SSLManager::CertError* error) {
return SSLErrorInfo::CreateError(
SSLErrorInfo::NetErrorToErrorType(error->cert_error()),
@@ -330,8 +334,10 @@ void SSLPolicy::OnAllowCertificate(SSLManager::CertError* error) {
error->request_url().host());
}
-void SSLPolicy::OnOverridableCertError(const GURL& main_frame_url,
- SSLManager::CertError* error) {
+////////////////////////////////////////////////////////////////////////////////
+// Certificate Error Routines
+
+void SSLPolicy::OnOverridableCertError(SSLManager::CertError* error) {
if (error->resource_type() != ResourceType::MAIN_FRAME) {
// A sub-resource has a certificate error. The user doesn't really
// have a context for making the right decision, so block the
@@ -344,8 +350,7 @@ void SSLPolicy::OnOverridableCertError(const GURL& main_frame_url,
ShowBlockingPage(this, error);
}
-void SSLPolicy::OnFatalCertError(const GURL& main_frame_url,
- SSLManager::CertError* error) {
+void SSLPolicy::OnFatalCertError(SSLManager::CertError* error) {
if (error->resource_type() != ResourceType::MAIN_FRAME) {
error->DenyRequest();
return;
diff --git a/chrome/browser/ssl/ssl_policy.h b/chrome/browser/ssl/ssl_policy.h
index b7edea5..0a017eb 100644
--- a/chrome/browser/ssl/ssl_policy.h
+++ b/chrome/browser/ssl/ssl_policy.h
@@ -22,17 +22,9 @@ class SSLPolicy : public SSLManager::Delegate,
static SSLPolicy* GetDefaultPolicy();
// SSLManager::Delegate methods.
- virtual void OnCertError(const GURL& main_frame_url,
- SSLManager::CertError* error);
- virtual void OnMixedContent(
- NavigationController* navigation_controller,
- const GURL& main_frame_url,
- SSLManager::MixedContentHandler* mixed_content_handler);
- virtual void OnRequestStarted(SSLManager* manager,
- const GURL& url,
- ResourceType::Type resource_type,
- int ssl_cert_id,
- int ssl_cert_status);
+ virtual void OnCertError(SSLManager::CertError* error);
+ virtual void OnMixedContent(SSLManager::MixedContentHandler* handler);
+ virtual void OnRequestStarted(SSLManager::RequestInfo* info);
virtual SecurityStyle GetDefaultStyle(const GURL& url);
// This method is static because it is called from both the UI and the IO
@@ -46,7 +38,7 @@ class SSLPolicy : public SSLManager::Delegate,
virtual void OnDenyCertificate(SSLManager::CertError* error);
virtual void OnAllowCertificate(SSLManager::CertError* error);
- protected:
+ private:
// Construct via |GetDefaultPolicy|.
SSLPolicy();
friend struct DefaultSingletonTraits<SSLPolicy>;
@@ -54,15 +46,12 @@ class SSLPolicy : public SSLManager::Delegate,
// Helper method for derived classes handling certificate errors that can be
// overridden by the user.
// Show a blocking page and let the user continue or cancel the request.
- void OnOverridableCertError(const GURL& main_frame_url,
- SSLManager::CertError* error);
+ void OnOverridableCertError(SSLManager::CertError* error);
// Helper method for derived classes handling fatal certificate errors.
// Cancel the request and show an error page.
- void OnFatalCertError(const GURL& main_frame_url,
- SSLManager::CertError* error);
+ void OnFatalCertError(SSLManager::CertError* error);
- private:
DISALLOW_COPY_AND_ASSIGN(SSLPolicy);
};