diff options
author | abarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-18 01:07:07 +0000 |
---|---|---|
committer | abarth@chromium.org <abarth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-18 01:07:07 +0000 |
commit | 9281268866081d21cc5b3a7fb2b98e146cc98d7b (patch) | |
tree | 2b9247e9da43413d0600fec255a67b24bc070b1a | |
parent | 44b2c885548d647611d908309dfdf6306eac7ed8 (diff) | |
download | chromium_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.cc | 137 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_manager.h | 132 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_policy.cc | 119 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_policy.h | 23 |
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); }; |