diff options
Diffstat (limited to 'chrome/browser/ssl')
-rw-r--r-- | chrome/browser/ssl/ssl_blocking_page.cc | 15 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_blocking_page.h | 13 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_cert_error_handler.h | 58 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_error_handler.cc | 209 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_error_handler.h | 176 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_manager.cc | 278 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_manager.h | 281 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_mixed_content_handler.h | 38 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_policy.cc | 101 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_policy.h | 16 | ||||
-rw-r--r-- | chrome/browser/ssl/ssl_request_info.h | 65 |
11 files changed, 657 insertions, 593 deletions
diff --git a/chrome/browser/ssl/ssl_blocking_page.cc b/chrome/browser/ssl/ssl_blocking_page.cc index 24794c0..e7fe5bc 100644 --- a/chrome/browser/ssl/ssl_blocking_page.cc +++ b/chrome/browser/ssl/ssl_blocking_page.cc @@ -12,6 +12,7 @@ #include "chrome/browser/browser.h" #include "chrome/browser/cert_store.h" #include "chrome/browser/dom_operation_notification_details.h" +#include "chrome/browser/ssl/ssl_cert_error_handler.h" #include "chrome/browser/ssl/ssl_error_info.h" #include "chrome/browser/tab_contents/navigation_controller.h" #include "chrome/browser/tab_contents/navigation_entry.h" @@ -41,10 +42,10 @@ void RecordSSLBlockingPageStats(SSLBlockingPageEvent event) { // Note that we always create a navigation entry with SSL errors. // No error happening loading a sub-resource triggers an interstitial so far. -SSLBlockingPage::SSLBlockingPage(SSLManager::CertError* error, +SSLBlockingPage::SSLBlockingPage(SSLCertErrorHandler* handler, Delegate* delegate) - : InterstitialPage(error->GetTabContents(), true, error->request_url()), - error_(error), + : InterstitialPage(handler->GetTabContents(), true, handler->request_url()), + handler_(handler), delegate_(delegate), delegate_has_been_notified_(false) { RecordSSLBlockingPageStats(SHOW); @@ -61,7 +62,7 @@ SSLBlockingPage::~SSLBlockingPage() { std::string SSLBlockingPage::GetHTMLContents() { // Let's build the html error page. DictionaryValue strings; - SSLErrorInfo error_info = delegate_->GetSSLErrorInfo(error_); + SSLErrorInfo error_info = delegate_->GetSSLErrorInfo(handler_); strings.SetString(L"title", l10n_util::GetString(IDS_SSL_BLOCKING_PAGE_TITLE)); strings.SetString(L"headLine", error_info.title()); @@ -88,7 +89,7 @@ std::string SSLBlockingPage::GetHTMLContents() { } void SSLBlockingPage::UpdateEntry(NavigationEntry* entry) { - const net::SSLInfo& ssl_info = error_->ssl_info(); + const net::SSLInfo& ssl_info = handler_->ssl_info(); int cert_id = CertStore::GetSharedInstance()->StoreCert( ssl_info.cert, tab()->render_view_host()->process()->pid()); @@ -130,14 +131,14 @@ void SSLBlockingPage::DontProceed() { void SSLBlockingPage::NotifyDenyCertificate() { DCHECK(!delegate_has_been_notified_); - delegate_->OnDenyCertificate(error_); + delegate_->OnDenyCertificate(handler_); delegate_has_been_notified_ = true; } void SSLBlockingPage::NotifyAllowCertificate() { DCHECK(!delegate_has_been_notified_); - delegate_->OnAllowCertificate(error_); + delegate_->OnAllowCertificate(handler_); delegate_has_been_notified_ = true; } diff --git a/chrome/browser/ssl/ssl_blocking_page.h b/chrome/browser/ssl/ssl_blocking_page.h index e6c6971..b83e16a 100644 --- a/chrome/browser/ssl/ssl_blocking_page.h +++ b/chrome/browser/ssl/ssl_blocking_page.h @@ -7,10 +7,11 @@ #include <string> -#include "chrome/browser/ssl/ssl_manager.h" +#include "chrome/browser/ssl/ssl_error_info.h" #include "chrome/browser/tab_contents/interstitial_page.h" class DictionaryValue; +class SSLCertErrorHandler; // This class is responsible for showing/hiding the interstitial page that is // shown when a certificate error happens. @@ -23,16 +24,16 @@ class SSLBlockingPage : public InterstitialPage { public: // Should return the information about the error that causes this blocking // page. - virtual SSLErrorInfo GetSSLErrorInfo(SSLManager::CertError* error) = 0; + virtual SSLErrorInfo GetSSLErrorInfo(SSLCertErrorHandler* handler) = 0; // Notification that the user chose to reject the certificate. - virtual void OnDenyCertificate(SSLManager::CertError* error) = 0; + virtual void OnDenyCertificate(SSLCertErrorHandler* handler) = 0; // Notification that the user chose to accept the certificate. - virtual void OnAllowCertificate(SSLManager::CertError* error) = 0; + virtual void OnAllowCertificate(SSLCertErrorHandler* handler) = 0; }; - SSLBlockingPage(SSLManager::CertError* error, Delegate* delegate); + SSLBlockingPage(SSLCertErrorHandler* handler, Delegate* delegate); virtual ~SSLBlockingPage(); // A method that sets strings in the specified dictionary from the passed @@ -56,7 +57,7 @@ class SSLBlockingPage : public InterstitialPage { // The error we represent. We will either call CancelRequest() or // ContinueRequest() on this object. - scoped_refptr<SSLManager::CertError> error_; + scoped_refptr<SSLCertErrorHandler> handler_; // Our delegate. It provides useful information, like the title and details // about this error. diff --git a/chrome/browser/ssl/ssl_cert_error_handler.h b/chrome/browser/ssl/ssl_cert_error_handler.h new file mode 100644 index 0000000..632927b --- /dev/null +++ b/chrome/browser/ssl/ssl_cert_error_handler.h @@ -0,0 +1,58 @@ +// 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 CHROME_BROWSER_SSL_SSL_CERT_ERROR_HANDLER_H_ +#define CHROME_BROWSER_SSL_SSL_CERT_ERROR_HANDLER_H_ + +#include "chrome/browser/ssl/ssl_error_handler.h" +#include "chrome/browser/ssl/ssl_manager.h" +#include "net/base/ssl_info.h" +#include "net/base/x509_certificate.h" + +// A CertError represents an error that occurred with the certificate in an +// SSL session. A CertError object exists both on the IO thread and on the UI +// thread and allows us to cancel/continue a request it is associated with. +class SSLCertErrorHandler : public SSLErrorHandler { + public: + // Construct on the IO thread. + // We mark this method as private because it is tricky to correctly + // construct a CertError object. + SSLCertErrorHandler(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) + : SSLErrorHandler(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 + // we have to set the fields manually. + ssl_info_.cert = cert; + ssl_info_.SetCertError(cert_error); + } + + virtual SSLCertErrorHandler* AsSSLCertErrorHandler() { return this; } + + // These accessors are available on either thread + const net::SSLInfo& ssl_info() const { return ssl_info_; } + int cert_error() const { return cert_error_; } + + private: + // SSLErrorHandler methods + virtual void OnDispatchFailed() { CancelRequest(); } + virtual void OnDispatched() { manager_->OnCertError(this); } + + // These read-only members may be accessed on any thread. + net::SSLInfo ssl_info_; + const int cert_error_; // The error we represent. + + DISALLOW_COPY_AND_ASSIGN(SSLCertErrorHandler); +}; + +#endif // CHROME_BROWSER_SSL_SSL_CERT_ERROR_HANDLER_H_ diff --git a/chrome/browser/ssl/ssl_error_handler.cc b/chrome/browser/ssl/ssl_error_handler.cc new file mode 100644 index 0000000..b5b435b --- /dev/null +++ b/chrome/browser/ssl/ssl_error_handler.cc @@ -0,0 +1,209 @@ +// 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 "chrome/browser/ssl/ssl_error_handler.h" + +#include "base/message_loop.h" +#include "chrome/browser/ssl/ssl_cert_error_handler.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/tab_contents/tab_util.h" +#include "net/base/net_errors.h" +#include "net/url_request/url_request.h" + +SSLErrorHandler::SSLErrorHandler(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()), + manager_(NULL), + 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); + + ResourceDispatcherHost::ExtraRequestInfo* info = + ResourceDispatcherHost::ExtraInfoForRequest(request); + request_id_.process_id = info->process_id; + request_id_.request_id = info->request_id; + + if (!tab_util::GetTabContentsID(request, + &render_process_host_id_, + &tab_contents_id_)) + NOTREACHED(); + + // This makes sure we don't disappear on the IO thread until we've given an + // answer to the URLRequest. + // + // Release in CompleteCancelRequest, CompleteContinueRequest, + // CompleteStartRequest or CompleteTakeNoAction. + AddRef(); +} + +void SSLErrorHandler::Dispatch() { + DCHECK(MessageLoop::current() == ui_loop_); + + TabContents* tab_contents = + tab_util::GetTabContentsByID(render_process_host_id_, tab_contents_id_); + + if (!tab_contents) { + // We arrived on the UI thread, but the tab we're looking for is no longer + // here. + OnDispatchFailed(); + return; + } + + // Hand ourselves off to the SSLManager. + manager_ = tab_contents->controller().ssl_manager(); + OnDispatched(); +} + +TabContents* SSLErrorHandler::GetTabContents() { + return tab_util::GetTabContentsByID(render_process_host_id_, + tab_contents_id_); +} + +void SSLErrorHandler::CancelRequest() { + DCHECK(MessageLoop::current() == ui_loop_); + + // We need to complete this task on the IO thread. + io_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, &SSLErrorHandler::CompleteCancelRequest, + net::ERR_ABORTED)); +} + +void SSLErrorHandler::DenyRequest() { + DCHECK(MessageLoop::current() == ui_loop_); + + // We need to complete this task on the IO thread. + io_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, &SSLErrorHandler::CompleteCancelRequest, + net::ERR_INSECURE_RESPONSE)); +} + +void SSLErrorHandler::ContinueRequest() { + DCHECK(MessageLoop::current() == ui_loop_); + + // We need to complete this task on the IO thread. + io_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, &SSLErrorHandler::CompleteContinueRequest)); +} + +void SSLErrorHandler::StartRequest(FilterPolicy::Type filter_policy) { + DCHECK(MessageLoop::current() == ui_loop_); + + // We need to complete this task on the IO thread. + io_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, &SSLErrorHandler::CompleteStartRequest, filter_policy)); +} + +void SSLErrorHandler::TakeNoAction() { + DCHECK(MessageLoop::current() == ui_loop_); + + // We need to complete this task on the IO thread. + io_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, &SSLErrorHandler::CompleteTakeNoAction)); +} + +void SSLErrorHandler::CompleteCancelRequest(int error) { + DCHECK(MessageLoop::current() == io_loop_); + + // It is important that we notify the URLRequest only once. If we try to + // notify the request twice, it may no longer exist and |this| might have + // already have been deleted. + DCHECK(!request_has_been_notified_); + + if (!request_has_been_notified_) { + URLRequest* request = resource_dispatcher_host_->GetURLRequest(request_id_); + if (request) { + // The request can be NULL if it was cancelled by the renderer (as the + // result of the user navigating to a new page from the location bar). + DLOG(INFO) << "CompleteCancelRequest() url: " << request->url().spec(); + SSLCertErrorHandler* cert_error = AsSSLCertErrorHandler(); + if (cert_error) + request->SimulateSSLError(error, cert_error->ssl_info()); + else + request->SimulateError(error); + } + request_has_been_notified_ = true; + + // We're done with this object on the IO thread. + Release(); + } +} + +void SSLErrorHandler::CompleteContinueRequest() { + DCHECK(MessageLoop::current() == io_loop_); + + // It is important that we notify the URLRequest only once. If we try to + // notify the request twice, it may no longer exist and |this| might have + // already have been deleted. + DCHECK(!request_has_been_notified_); + + if (!request_has_been_notified_) { + URLRequest* request = resource_dispatcher_host_->GetURLRequest(request_id_); + if (request) { + // The request can be NULL if it was cancelled by the renderer (as the + // result of the user navigating to a new page from the location bar). + DLOG(INFO) << "CompleteContinueRequest() url: " << request->url().spec(); + request->ContinueDespiteLastError(); + } + request_has_been_notified_ = true; + + // We're done with this object on the IO thread. + Release(); + } +} + +void SSLErrorHandler::CompleteStartRequest(FilterPolicy::Type filter_policy) { + DCHECK(MessageLoop::current() == io_loop_); + + // It is important that we notify the URLRequest only once. If we try to + // notify the request twice, it may no longer exist and |this| might have + // already have been deleted. + DCHECK(!request_has_been_notified_); + + if (request_has_been_notified_) + return; + + URLRequest* request = resource_dispatcher_host_->GetURLRequest(request_id_); + if (request) { + // The request can be NULL if it was cancelled by the renderer (as the + // result of the user navigating to a new page from the location bar). + DLOG(INFO) << "CompleteStartRequest() url: " << request->url().spec(); + // The request should not have been started (SUCCESS is the initial state). + DCHECK(request->status().status() == URLRequestStatus::SUCCESS); + ResourceDispatcherHost::ExtraRequestInfo* info = + ResourceDispatcherHost::ExtraInfoForRequest(request); + info->filter_policy = filter_policy; + request->Start(); + } + request_has_been_notified_ = true; + + // We're done with this object on the IO thread. + Release(); +} + +void SSLErrorHandler::CompleteTakeNoAction() { + DCHECK(MessageLoop::current() == io_loop_); + + // It is important that we notify the URLRequest only once. If we try to + // notify the request twice, it may no longer exist and |this| might have + // already have been deleted. + DCHECK(!request_has_been_notified_); + + if (!request_has_been_notified_) { + request_has_been_notified_ = true; + + // We're done with this object on the IO thread. + Release(); + } +} + diff --git a/chrome/browser/ssl/ssl_error_handler.h b/chrome/browser/ssl/ssl_error_handler.h new file mode 100644 index 0000000..9ef1b04 --- /dev/null +++ b/chrome/browser/ssl/ssl_error_handler.h @@ -0,0 +1,176 @@ +// 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 CHROME_BROWSER_SSL_SSL_ERROR_HANDLER_H_ +#define CHROME_BROWSER_SSL_SSL_ERROR_HANDLER_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/ref_counted.h" +#include "chrome/browser/renderer_host/resource_dispatcher_host.h" +#include "chrome/common/filter_policy.h" +#include "googleurl/src/gurl.h" +#include "webkit/glue/resource_type.h" + +class MessageLoop; +class SSLCertErrorHandler; +class SSLManager; +class TabContents; +class URLRequest; + +// An SSLErrorHandler carries information from the IO thread to the UI thread +// and is dispatched to the appropriate SSLManager when it arrives on the +// UI thread. Subclasses should override the OnDispatched/OnDispatchFailed +// methods to implement the actions that should be taken on the UI thread. +// These methods can call the different convenience methods ContinueRequest/ +// CancelRequest/StartRequest to perform any required action on the URLRequest +// the ErrorHandler was created with. +// +// IMPORTANT NOTE: +// +// If you are not doing anything in OnDispatched/OnDispatchFailed, make sure +// you call TakeNoAction(). This is necessary for ensuring the instance is +// not leaked. +// +class SSLErrorHandler : public base::RefCountedThreadSafe<SSLErrorHandler> { + public: + virtual ~SSLErrorHandler() { } + + virtual SSLCertErrorHandler* AsSSLCertErrorHandler() { return NULL; } + + // Find the appropriate SSLManager for the URLRequest and begin handling + // this error. + // + // Call on UI thread. + void Dispatch(); + + // 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_; } + + // Returns the TabContents this object is associated with. Should be + // called from the UI thread. + TabContents* GetTabContents(); + + // Cancels the associated URLRequest. + // This method can be called from OnDispatchFailed and OnDispatched. + void CancelRequest(); + + // Continue the URLRequest ignoring any previous errors. Note that some + // errors cannot be ignored, in which case this will result in the request + // being canceled. + // This method can be called from OnDispatchFailed and OnDispatched. + void ContinueRequest(); + + // Cancels the associated URLRequest and mark it as denied. The renderer + // processes such request in a special manner, optionally replacing them + // with alternate content (typically frames content is replaced with a + // warning message). + // This method can be called from OnDispatchFailed and OnDispatched. + void DenyRequest(); + + // Starts the associated URLRequest. |filter_policy| specifies whether the + // ResourceDispatcher should attempt to filter the loaded content in order + // to make it secure (ex: images are made slightly transparent and are + // stamped). + // Should only be called when the URLRequest has not already been started. + // This method can be called from OnDispatchFailed and OnDispatched. + void StartRequest(FilterPolicy::Type filter_policy); + + // Does nothing on the URLRequest but ensures the current instance ref + // count is decremented appropriately. Subclasses that do not want to + // take any specific actions in their OnDispatched/OnDispatchFailed should + // call this. + void TakeNoAction(); + + protected: + // Construct on the IO thread. + SSLErrorHandler(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. + virtual void OnDispatchFailed() { TakeNoAction(); } + + // Can use the manager_ member. + virtual void OnDispatched() { TakeNoAction(); } + + // We cache the message loops to be able to proxy events across the thread + // boundaries. + MessageLoop* ui_loop_; + MessageLoop* io_loop_; + + // Should only be accessed on the UI thread. + SSLManager* manager_; // Our manager. + + // The id of the URLRequest associated with this object. + // Should only be accessed from the IO thread. + ResourceDispatcherHost::GlobalRequestID request_id_; + + // The ResourceDispatcherHost we are associated with. + ResourceDispatcherHost* resource_dispatcher_host_; + + private: + // Completes the CancelRequest operation on the IO thread. + // Call on the IO thread. + void CompleteCancelRequest(int error); + + // Completes the ContinueRequest operation on the IO thread. + // + // Call on the IO thread. + void CompleteContinueRequest(); + + // Completes the StartRequest operation on the IO thread. + // Call on the IO thread. + void CompleteStartRequest(FilterPolicy::Type filter_policy); + + // Derefs this instance. + // Call on the IO thread. + void CompleteTakeNoAction(); + + // We use these members to find the correct SSLManager when we arrive on + // the UI thread. + 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_; + + // 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_; + + DISALLOW_COPY_AND_ASSIGN(SSLErrorHandler); +}; + +#endif // CHROME_BROWSER_SSL_SSL_ERROR_HANDLER_H_ diff --git a/chrome/browser/ssl/ssl_manager.cc b/chrome/browser/ssl/ssl_manager.cc index 0510810..c46a20b 100644 --- a/chrome/browser/ssl/ssl_manager.cc +++ b/chrome/browser/ssl/ssl_manager.cc @@ -12,9 +12,13 @@ #include "chrome/browser/load_from_memory_cache_details.h" #include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/resource_request_details.h" +#include "chrome/browser/ssl/ssl_cert_error_handler.h" #include "chrome/browser/ssl/ssl_error_info.h" +#include "chrome/browser/ssl/ssl_error_handler.h" #include "chrome/browser/ssl/ssl_host_state.h" +#include "chrome/browser/ssl/ssl_mixed_content_handler.h" #include "chrome/browser/ssl/ssl_policy.h" +#include "chrome/browser/ssl/ssl_request_info.h" #include "chrome/browser/tab_contents/infobar_delegate.h" #include "chrome/browser/tab_contents/navigation_controller.h" #include "chrome/browser/tab_contents/navigation_entry.h" @@ -90,9 +94,6 @@ class SSLInfoBarDelegate : public ConfirmInfoBarDelegate { DISALLOW_COPY_AND_ASSIGN(SSLInfoBarDelegate); }; -//////////////////////////////////////////////////////////////////////////////// -// SSLManager - // static void SSLManager::RegisterUserPrefs(PrefService* prefs) { prefs->RegisterIntegerPref(prefs::kMixedContentFiltering, @@ -231,230 +232,6 @@ bool SSLManager::ProcessedSSLErrorFromRequest() const { return net::IsCertStatusError(entry->ssl().cert_status()); } -//////////////////////////////////////////////////////////////////////////////// -// ErrorHandler - -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()), - manager_(NULL), - 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); - - ResourceDispatcherHost::ExtraRequestInfo* info = - ResourceDispatcherHost::ExtraInfoForRequest(request); - request_id_.process_id = info->process_id; - request_id_.request_id = info->request_id; - - if (!tab_util::GetTabContentsID(request, - &render_process_host_id_, - &tab_contents_id_)) - NOTREACHED(); - - // This makes sure we don't disappear on the IO thread until we've given an - // answer to the URLRequest. - // - // Release in CompleteCancelRequest, CompleteContinueRequest, - // CompleteStartRequest or CompleteTakeNoAction. - AddRef(); -} - -void SSLManager::ErrorHandler::Dispatch() { - DCHECK(MessageLoop::current() == ui_loop_); - - TabContents* tab_contents = - tab_util::GetTabContentsByID(render_process_host_id_, tab_contents_id_); - - if (!tab_contents) { - // We arrived on the UI thread, but the tab we're looking for is no longer - // here. - OnDispatchFailed(); - return; - } - - // Hand ourselves off to the SSLManager. - manager_ = tab_contents->controller().ssl_manager(); - OnDispatched(); -} - -TabContents* SSLManager::ErrorHandler::GetTabContents() { - return tab_util::GetTabContentsByID(render_process_host_id_, - tab_contents_id_); -} - -void SSLManager::ErrorHandler::CancelRequest() { - DCHECK(MessageLoop::current() == ui_loop_); - - // We need to complete this task on the IO thread. - io_loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &SSLManager::ErrorHandler::CompleteCancelRequest, - net::ERR_ABORTED)); -} - -void SSLManager::ErrorHandler::DenyRequest() { - DCHECK(MessageLoop::current() == ui_loop_); - - // We need to complete this task on the IO thread. - io_loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &SSLManager::ErrorHandler::CompleteCancelRequest, - net::ERR_INSECURE_RESPONSE)); -} - -void SSLManager::ErrorHandler::ContinueRequest() { - DCHECK(MessageLoop::current() == ui_loop_); - - // We need to complete this task on the IO thread. - io_loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &SSLManager::ErrorHandler::CompleteContinueRequest)); -} - -void SSLManager::ErrorHandler::StartRequest(FilterPolicy::Type filter_policy) { - DCHECK(MessageLoop::current() == ui_loop_); - - // We need to complete this task on the IO thread. - io_loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &SSLManager::ErrorHandler::CompleteStartRequest, filter_policy)); -} - -void SSLManager::ErrorHandler::TakeNoAction() { - DCHECK(MessageLoop::current() == ui_loop_); - - // We need to complete this task on the IO thread. - io_loop_->PostTask(FROM_HERE, NewRunnableMethod( - this, &SSLManager::ErrorHandler::CompleteTakeNoAction)); -} - -void SSLManager::ErrorHandler::CompleteCancelRequest(int error) { - DCHECK(MessageLoop::current() == io_loop_); - - // It is important that we notify the URLRequest only once. If we try to - // notify the request twice, it may no longer exist and |this| might have - // already have been deleted. - DCHECK(!request_has_been_notified_); - - if (!request_has_been_notified_) { - URLRequest* request = resource_dispatcher_host_->GetURLRequest(request_id_); - if (request) { - // The request can be NULL if it was cancelled by the renderer (as the - // result of the user navigating to a new page from the location bar). - DLOG(INFO) << "CompleteCancelRequest() url: " << request->url().spec(); - SSLManager::CertError* cert_error = AsCertError(); - if (cert_error) - request->SimulateSSLError(error, cert_error->ssl_info()); - else - request->SimulateError(error); - } - request_has_been_notified_ = true; - - // We're done with this object on the IO thread. - Release(); - } -} - -void SSLManager::ErrorHandler::CompleteContinueRequest() { - DCHECK(MessageLoop::current() == io_loop_); - - // It is important that we notify the URLRequest only once. If we try to - // notify the request twice, it may no longer exist and |this| might have - // already have been deleted. - DCHECK(!request_has_been_notified_); - - if (!request_has_been_notified_) { - URLRequest* request = resource_dispatcher_host_->GetURLRequest(request_id_); - if (request) { - // The request can be NULL if it was cancelled by the renderer (as the - // result of the user navigating to a new page from the location bar). - DLOG(INFO) << "CompleteContinueRequest() url: " << request->url().spec(); - request->ContinueDespiteLastError(); - } - request_has_been_notified_ = true; - - // We're done with this object on the IO thread. - Release(); - } -} - -void SSLManager::ErrorHandler::CompleteStartRequest( - FilterPolicy::Type filter_policy) { - DCHECK(MessageLoop::current() == io_loop_); - - // It is important that we notify the URLRequest only once. If we try to - // notify the request twice, it may no longer exist and |this| might have - // already have been deleted. - DCHECK(!request_has_been_notified_); - - if (request_has_been_notified_) - return; - - URLRequest* request = resource_dispatcher_host_->GetURLRequest(request_id_); - if (request) { - // The request can be NULL if it was cancelled by the renderer (as the - // result of the user navigating to a new page from the location bar). - DLOG(INFO) << "CompleteStartRequest() url: " << request->url().spec(); - // The request should not have been started (SUCCESS is the initial state). - DCHECK(request->status().status() == URLRequestStatus::SUCCESS); - ResourceDispatcherHost::ExtraRequestInfo* info = - ResourceDispatcherHost::ExtraInfoForRequest(request); - info->filter_policy = filter_policy; - request->Start(); - } - request_has_been_notified_ = true; - - // We're done with this object on the IO thread. - Release(); -} - -void SSLManager::ErrorHandler::CompleteTakeNoAction() { - DCHECK(MessageLoop::current() == io_loop_); - - // It is important that we notify the URLRequest only once. If we try to - // notify the request twice, it may no longer exist and |this| might have - // already have been deleted. - DCHECK(!request_has_been_notified_); - - if (!request_has_been_notified_) { - request_has_been_notified_ = true; - - // We're done with this object on the IO thread. - Release(); - } -} - - -//////////////////////////////////////////////////////////////////////////////// -// CertError - -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, 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 - // we have to set the fields manually. - ssl_info_.cert = cert; - ssl_info_.SetCertError(cert_error); -} - // static void SSLManager::OnSSLCertificateError(ResourceDispatcherHost* rdh, URLRequest* request, @@ -468,18 +245,18 @@ void SSLManager::OnSSLCertificateError(ResourceDispatcherHost* rdh, ResourceDispatcherHost::ExtraInfoForRequest(request); DCHECK(info); - // A certificate error occurred. Construct a CertError object and hand it - // over to the UI thread for processing. + // A certificate error occurred. Construct a SSLCertErrorHandler object and + // hand it over to the UI thread for processing. ui_loop->PostTask(FROM_HERE, - NewRunnableMethod(new CertError(rdh, - request, - info->resource_type, - info->frame_origin, - info->main_frame_origin, - cert_error, - cert, - ui_loop), - &CertError::Dispatch)); + NewRunnableMethod(new SSLCertErrorHandler(rdh, + request, + info->resource_type, + info->frame_origin, + info->main_frame_origin, + cert_error, + cert, + ui_loop), + &SSLCertErrorHandler::Dispatch)); } // static @@ -500,21 +277,22 @@ bool SSLManager::ShouldStartRequest(ResourceDispatcherHost* rdh, ui_loop->PostTask(FROM_HERE, - NewRunnableMethod(new MixedContentHandler(rdh, request, - info->resource_type, - info->frame_origin, - info->main_frame_origin, - info->process_id, - ui_loop), - &MixedContentHandler::Dispatch)); + NewRunnableMethod(new SSLMixedContentHandler(rdh, + request, + info->resource_type, + info->frame_origin, + info->main_frame_origin, + info->process_id, + ui_loop), + &SSLMixedContentHandler::Dispatch)); return false; } -void SSLManager::OnCertError(CertError* error) { - delegate()->OnCertError(error); +void SSLManager::OnCertError(SSLCertErrorHandler* handler) { + delegate()->OnCertError(handler); } -void SSLManager::OnMixedContent(MixedContentHandler* handler) { +void SSLManager::OnMixedContent(SSLMixedContentHandler* handler) { delegate()->OnMixedContent(handler); } @@ -582,7 +360,7 @@ void SSLManager::DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details) { // caches sub-resources. // This resource must have been loaded with FilterPolicy::DONT_FILTER because // filtered resouces aren't cachable. - scoped_refptr<RequestInfo> info = new RequestInfo( + scoped_refptr<SSLRequestInfo> info = new SSLRequestInfo( this, details->url(), ResourceType::SUB_RESOURCE, @@ -646,7 +424,7 @@ void SSLManager::DidFailProvisionalLoadWithError( void SSLManager::DidStartResourceResponse(ResourceRequestDetails* details) { DCHECK(details); - scoped_refptr<RequestInfo> info = new RequestInfo( + scoped_refptr<SSLRequestInfo> info = new SSLRequestInfo( this, details->url(), details->resource_type(), diff --git a/chrome/browser/ssl/ssl_manager.h b/chrome/browser/ssl/ssl_manager.h index 5e6e77d..da77c05 100644 --- a/chrome/browser/ssl/ssl_manager.h +++ b/chrome/browser/ssl/ssl_manager.h @@ -32,8 +32,12 @@ class NavigationController; class PrefService; class ResourceRedirectDetails; class ResourceRequestDetails; +class SSLCertErrorHandler; +class SSLErrorHandler; class SSLErrorInfo; class SSLHostState; +class SSLMixedContentHandler; +class SSLRequestInfo; class Task; class URLRequest; class TabContents; @@ -48,273 +52,6 @@ class TabContents; class SSLManager : public NotificationObserver { public: - class CertError; - - // An ErrorHandler carries information from the IO thread to the UI thread - // and is dispatched to the appropriate SSLManager when it arrives on the - // UI thread. Subclasses should override the OnDispatched/OnDispatchFailed - // methods to implement the actions that should be taken on the UI thread. - // These methods can call the different convenience methods ContinueRequest/ - // CancelRequest/StartRequest to perform any required action on the URLRequest - // the ErrorHandler was created with. - // IMPORTANT NOTE: if you are not doing anything in - // OnDispatched/OnDispatchFailed, make sure you call TakeNoAction(). This is - // necessary for ensuring the instance is not leaked. - class ErrorHandler : public base::RefCountedThreadSafe<ErrorHandler> { - public: - virtual ~ErrorHandler() { } - - virtual CertError* AsCertError() { return NULL; } - - // Find the appropriate SSLManager for the URLRequest and begin handling - // this error. - // - // Call on UI thread. - void Dispatch(); - - // 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_; } - - // Returns the TabContents this object is associated with. Should be - // called from the UI thread. - TabContents* GetTabContents(); - - // Cancels the associated URLRequest. - // This method can be called from OnDispatchFailed and OnDispatched. - void CancelRequest(); - - // Continue the URLRequest ignoring any previous errors. Note that some - // errors cannot be ignored, in which case this will result in the request - // being canceled. - // This method can be called from OnDispatchFailed and OnDispatched. - void ContinueRequest(); - - // Cancels the associated URLRequest and mark it as denied. The renderer - // processes such request in a special manner, optionally replacing them - // with alternate content (typically frames content is replaced with a - // warning message). - // This method can be called from OnDispatchFailed and OnDispatched. - void DenyRequest(); - - // Starts the associated URLRequest. |filter_policy| specifies whether the - // ResourceDispatcher should attempt to filter the loaded content in order - // to make it secure (ex: images are made slightly transparent and are - // stamped). - // Should only be called when the URLRequest has not already been started. - // This method can be called from OnDispatchFailed and OnDispatched. - void StartRequest(FilterPolicy::Type filter_policy); - - // Does nothing on the URLRequest but ensures the current instance ref - // count is decremented appropriately. Subclasses that do not want to - // take any specific actions in their OnDispatched/OnDispatchFailed should - // call this. - void TakeNoAction(); - - protected: - // 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. - virtual void OnDispatchFailed() { TakeNoAction(); } - - // Can use the manager_ member. - virtual void OnDispatched() { TakeNoAction(); } - - // We cache the message loops to be able to proxy events across the thread - // boundaries. - MessageLoop* ui_loop_; - MessageLoop* io_loop_; - - // Should only be accessed on the UI thread. - SSLManager* manager_; // Our manager. - - // The id of the URLRequest associated with this object. - // Should only be accessed from the IO thread. - ResourceDispatcherHost::GlobalRequestID request_id_; - - // The ResourceDispatcherHost we are associated with. - ResourceDispatcherHost* resource_dispatcher_host_; - - private: - // Completes the CancelRequest operation on the IO thread. - // Call on the IO thread. - void CompleteCancelRequest(int error); - - // Completes the ContinueRequest operation on the IO thread. - // - // Call on the IO thread. - void CompleteContinueRequest(); - - // Completes the StartRequest operation on the IO thread. - // Call on the IO thread. - void CompleteStartRequest(FilterPolicy::Type filter_policy); - - // Derefs this instance. - // Call on the IO thread. - void CompleteTakeNoAction(); - - // We use these members to find the correct SSLManager when we arrive on - // the UI thread. - 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_; - - // 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_; - - DISALLOW_COPY_AND_ASSIGN(ErrorHandler); - }; - - // A CertError represents an error that occurred with the certificate in an - // SSL session. A CertError object exists both on the IO thread and on the UI - // thread and allows us to cancel/continue a request it is associated with. - class CertError : public ErrorHandler { - public: - - virtual CertError* AsCertError() { return this; } - - // These accessors are available on either thread - const net::SSLInfo& ssl_info() const { return ssl_info_; } - int cert_error() const { return cert_error_; } - - private: - // SSLManager is responsible for creating CertError objects. - friend class SSLManager; - - // Construct on the IO thread. - // We mark this method as private because it is tricky to correctly - // construct a CertError object. - 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); - - // ErrorHandler methods - virtual void OnDispatchFailed() { CancelRequest(); } - virtual void OnDispatched() { manager_->OnCertError(this); } - - // These read-only members can be accessed on any thread. - net::SSLInfo ssl_info_; - const int cert_error_; // The error we represent. - - DISALLOW_COPY_AND_ASSIGN(CertError); - }; - - // The MixedContentHandler class is used to query what to do with - // mixed content, from the IO thread to the UI thread. - class MixedContentHandler : public ErrorHandler { - public: - // 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, - int pid, - MessageLoop* ui_loop) - : ErrorHandler(rdh, request, resource_type, frame_origin, - main_frame_origin, ui_loop), - pid_(pid) {} - - int pid() const { return pid_; } - - protected: - virtual void OnDispatchFailed() { TakeNoAction(); } - virtual void OnDispatched() { manager()->OnMixedContent(this); } - - private: - int pid_; - - 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, - FilterPolicy::Type filter_policy, - int pid, - 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), - filter_policy_(filter_policy), - pid_(pid), - 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_; } - FilterPolicy::Type filter_policy() const { return filter_policy_; } - int pid() const { return pid_; } - 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_; - FilterPolicy::Type filter_policy_; - int pid_; - 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. @@ -327,15 +64,15 @@ class SSLManager : public NotificationObserver { class Delegate { public: // An error occurred with the certificate in an SSL connection. - virtual void OnCertError(CertError* error) = 0; + virtual void OnCertError(SSLCertErrorHandler* handler) = 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(MixedContentHandler* handler) = 0; + virtual void OnMixedContent(SSLMixedContentHandler* handler) = 0; // We have started a resource request with the given info. - virtual void OnRequestStarted(RequestInfo* info) = 0; + virtual void OnRequestStarted(SSLRequestInfo* info) = 0; // Update the SSL information in |entry| to match the current state. virtual void UpdateEntry(SSLManager* manager, NavigationEntry* entry) = 0; @@ -438,14 +175,14 @@ class SSLManager : public NotificationObserver { // the SSL manager. The error originated from the ResourceDispatcherHost. // // Called on the UI thread. - void OnCertError(CertError* error); + void OnCertError(SSLCertErrorHandler* handler); // Called by MixedContentHandler::Dispatch to kick off processing of the // mixed-content resource request. The info originated from the // ResourceDispatcherHost. // // Called on the UI thread. - void OnMixedContent(MixedContentHandler* handler); + void OnMixedContent(SSLMixedContentHandler* handler); // Entry point for navigation. This function begins the process of updating // the security UI when the main frame navigates to a new URL. diff --git a/chrome/browser/ssl/ssl_mixed_content_handler.h b/chrome/browser/ssl/ssl_mixed_content_handler.h new file mode 100644 index 0000000..afb7e13 --- /dev/null +++ b/chrome/browser/ssl/ssl_mixed_content_handler.h @@ -0,0 +1,38 @@ +// 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 CHROME_BROWSER_SSL_SSL_MIXED_CONTENT_HANDLER_H_ +#define CHROME_BROWSER_SSL_SSL_MIXED_CONTENT_HANDLER_H_ + +#include "chrome/browser/ssl/ssl_error_handler.h" + +// The SSLMixedContentHandler class is used to query what to do with +// mixed content, from the IO thread to the UI thread. +class SSLMixedContentHandler : public SSLErrorHandler { + public: + // Created on the IO thread. + SSLMixedContentHandler(ResourceDispatcherHost* rdh, + URLRequest* request, + ResourceType::Type resource_type, + const std::string& frame_origin, + const std::string& main_frame_origin, + int pid, + MessageLoop* ui_loop) + : SSLErrorHandler(rdh, request, resource_type, frame_origin, + main_frame_origin, ui_loop), + pid_(pid) {} + + int pid() const { return pid_; } + + protected: + virtual void OnDispatchFailed() { TakeNoAction(); } + virtual void OnDispatched() { manager()->OnMixedContent(this); } + + private: + int pid_; + + DISALLOW_COPY_AND_ASSIGN(SSLMixedContentHandler); +}; + +#endif // CHROME_BROWSER_SSL_SSL_MIXED_CONTENT_HANDLERR_H_ diff --git a/chrome/browser/ssl/ssl_policy.cc b/chrome/browser/ssl/ssl_policy.cc index 6785eec..9c37117 100644 --- a/chrome/browser/ssl/ssl_policy.cc +++ b/chrome/browser/ssl/ssl_policy.cc @@ -11,7 +11,10 @@ #include "base/string_util.h" #include "chrome/browser/cert_store.h" #include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/browser/ssl/ssl_cert_error_handler.h" #include "chrome/browser/ssl/ssl_error_info.h" +#include "chrome/browser/ssl/ssl_mixed_content_handler.h" +#include "chrome/browser/ssl/ssl_request_info.h" #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/jstemplate_builder.h" @@ -52,7 +55,7 @@ static void AllowMixedContentForOrigin(SSLManager* manager, manager->AllowMixedContentForHost(parsed_origin.host()); } -static void UpdateStateForMixedContent(SSLManager::RequestInfo* info) { +static void UpdateStateForMixedContent(SSLRequestInfo* info) { if (info->resource_type() != ResourceType::MAIN_FRAME || info->resource_type() != ResourceType::SUB_FRAME) { // The frame's origin now contains mixed content and therefore is broken. @@ -66,7 +69,7 @@ static void UpdateStateForMixedContent(SSLManager::RequestInfo* info) { } } -static void UpdateStateForUnsafeContent(SSLManager::RequestInfo* info) { +static void UpdateStateForUnsafeContent(SSLRequestInfo* info) { // This request as a broken cert, which means its host is broken. info->manager()->MarkHostAsBroken(info->url().host(), info->pid()); @@ -75,19 +78,18 @@ static void UpdateStateForUnsafeContent(SSLManager::RequestInfo* info) { class ShowMixedContentTask : public Task { public: - ShowMixedContentTask(SSLManager::MixedContentHandler* handler); + ShowMixedContentTask(SSLMixedContentHandler* handler); virtual ~ShowMixedContentTask(); virtual void Run(); private: - scoped_refptr<SSLManager::MixedContentHandler> handler_; + scoped_refptr<SSLMixedContentHandler> handler_; DISALLOW_COPY_AND_ASSIGN(ShowMixedContentTask); }; -ShowMixedContentTask::ShowMixedContentTask( - SSLManager::MixedContentHandler* handler) +ShowMixedContentTask::ShowMixedContentTask(SSLMixedContentHandler* handler) : handler_(handler) { } @@ -101,8 +103,8 @@ void ShowMixedContentTask::Run() { handler_->manager()->controller()->Reload(true); } -static void ShowErrorPage(SSLPolicy* policy, SSLManager::CertError* error) { - SSLErrorInfo error_info = policy->GetSSLErrorInfo(error); +static void ShowErrorPage(SSLPolicy* policy, SSLCertErrorHandler* handler) { + SSLErrorInfo error_info = policy->GetSSLErrorInfo(handler); // Let's build the html error page. DictionaryValue strings; @@ -126,23 +128,23 @@ static void ShowErrorPage(SSLPolicy* policy, SSLManager::CertError* error) { std::string html_text(jstemplate_builder::GetTemplateHtml(html, &strings, "template_root")); - TabContents* tab = error->GetTabContents(); + TabContents* tab = handler->GetTabContents(); int cert_id = CertStore::GetSharedInstance()->StoreCert( - error->ssl_info().cert, tab->render_view_host()->process()->pid()); + handler->ssl_info().cert, tab->render_view_host()->process()->pid()); std::string security_info = SSLManager::SerializeSecurityInfo(cert_id, - error->ssl_info().cert_status, - error->ssl_info().security_bits); + handler->ssl_info().cert_status, + handler->ssl_info().security_bits); tab->render_view_host()->LoadAlternateHTMLString(html_text, true, - error->request_url(), + handler->request_url(), security_info); tab->controller().GetActiveEntry()->set_page_type( NavigationEntry::ERROR_PAGE); } -static void ShowBlockingPage(SSLPolicy* policy, SSLManager::CertError* error) { - SSLBlockingPage* blocking_page = new SSLBlockingPage(error, policy); +static void ShowBlockingPage(SSLPolicy* policy, SSLCertErrorHandler* handler) { + SSLBlockingPage* blocking_page = new SSLBlockingPage(handler, policy); blocking_page->Show(); } @@ -154,8 +156,7 @@ static void InitializeEntryIfNeeded(NavigationEntry* entry) { SECURITY_STYLE_AUTHENTICATED : SECURITY_STYLE_UNAUTHENTICATED); } -static void AddMixedContentWarningToConsole( - SSLManager::MixedContentHandler* handler) { +static void AddMixedContentWarningToConsole(SSLMixedContentHandler* handler) { const std::wstring& text = l10n_util::GetStringF( IDS_MIXED_CONTENT_LOG_MESSAGE, UTF8ToWide(handler->frame_origin()), @@ -173,14 +174,14 @@ SSLPolicy* SSLPolicy::GetDefaultPolicy() { return Singleton<SSLPolicy>::get(); } -void SSLPolicy::OnCertError(SSLManager::CertError* error) { +void SSLPolicy::OnCertError(SSLCertErrorHandler* handler) { // First we check if we know the policy for this error. net::X509Certificate::Policy::Judgment judgment = - error->manager()->QueryPolicy(error->ssl_info().cert, - error->request_url().host()); + handler->manager()->QueryPolicy(handler->ssl_info().cert, + handler->request_url().host()); if (judgment == net::X509Certificate::Policy::ALLOWED) { - error->ContinueRequest(); + handler->ContinueRequest(); return; } @@ -188,35 +189,35 @@ void SSLPolicy::OnCertError(SSLManager::CertError* error) { // For now we handle the DENIED as the UNKNOWN, which means a blocking // page is shown to the user every time he comes back to the page. - switch(error->cert_error()) { + switch(handler->cert_error()) { case net::ERR_CERT_COMMON_NAME_INVALID: case net::ERR_CERT_DATE_INVALID: case net::ERR_CERT_AUTHORITY_INVALID: - OnOverridableCertError(error); + OnOverridableCertError(handler); break; case net::ERR_CERT_NO_REVOCATION_MECHANISM: // Ignore this error. - error->ContinueRequest(); + handler->ContinueRequest(); break; case net::ERR_CERT_UNABLE_TO_CHECK_REVOCATION: // We ignore this error and display an infobar. - error->ContinueRequest(); - error->manager()->ShowMessage(l10n_util::GetString( + handler->ContinueRequest(); + handler->manager()->ShowMessage(l10n_util::GetString( IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_INFO_BAR)); break; case net::ERR_CERT_CONTAINS_ERRORS: case net::ERR_CERT_REVOKED: case net::ERR_CERT_INVALID: - OnFatalCertError(error); + OnFatalCertError(handler); break; default: NOTREACHED(); - error->CancelRequest(); + handler->CancelRequest(); break; } } -void SSLPolicy::OnMixedContent(SSLManager::MixedContentHandler* handler) { +void SSLPolicy::OnMixedContent(SSLMixedContentHandler* handler) { // Get the user's mixed content preference. PrefService* prefs = handler->GetTabContents()->profile()->GetPrefs(); FilterPolicy::Type filter_policy = @@ -239,7 +240,7 @@ void SSLPolicy::OnMixedContent(SSLManager::MixedContentHandler* handler) { AddMixedContentWarningToConsole(handler); } -void SSLPolicy::OnRequestStarted(SSLManager::RequestInfo* info) { +void SSLPolicy::OnRequestStarted(SSLRequestInfo* info) { if (net::IsCertStatusError(info->ssl_cert_status())) UpdateStateForUnsafeContent(info); @@ -309,24 +310,24 @@ bool SSLPolicy::IsMixedContent(const GURL& url, //////////////////////////////////////////////////////////////////////////////// // SSLBlockingPage::Delegate methods -SSLErrorInfo SSLPolicy::GetSSLErrorInfo(SSLManager::CertError* error) { +SSLErrorInfo SSLPolicy::GetSSLErrorInfo(SSLCertErrorHandler* handler) { return SSLErrorInfo::CreateError( - SSLErrorInfo::NetErrorToErrorType(error->cert_error()), - error->ssl_info().cert, error->request_url()); + SSLErrorInfo::NetErrorToErrorType(handler->cert_error()), + handler->ssl_info().cert, handler->request_url()); } -void SSLPolicy::OnDenyCertificate(SSLManager::CertError* error) { +void SSLPolicy::OnDenyCertificate(SSLCertErrorHandler* handler) { // Default behavior for rejecting a certificate. // // While DenyCertForHost() executes synchronously on this thread, // CancelRequest() gets posted to a different thread. Calling // DenyCertForHost() first ensures deterministic ordering. - error->manager()->DenyCertForHost(error->ssl_info().cert, - error->request_url().host()); - error->CancelRequest(); + handler->manager()->DenyCertForHost(handler->ssl_info().cert, + handler->request_url().host()); + handler->CancelRequest(); } -void SSLPolicy::OnAllowCertificate(SSLManager::CertError* error) { +void SSLPolicy::OnAllowCertificate(SSLCertErrorHandler* handler) { // Default behavior for accepting a certificate. // Note that we should not call SetMaxSecurityStyle here, because the active // NavigationEntry has just been deleted (in HideInterstitialPage) and the @@ -337,33 +338,33 @@ void SSLPolicy::OnAllowCertificate(SSLManager::CertError* error) { // While AllowCertForHost() executes synchronously on this thread, // ContinueRequest() gets posted to a different thread. Calling // AllowCertForHost() first ensures deterministic ordering. - error->manager()->AllowCertForHost(error->ssl_info().cert, - error->request_url().host()); - error->ContinueRequest(); + handler->manager()->AllowCertForHost(handler->ssl_info().cert, + handler->request_url().host()); + handler->ContinueRequest(); } //////////////////////////////////////////////////////////////////////////////// // Certificate Error Routines -void SSLPolicy::OnOverridableCertError(SSLManager::CertError* error) { - if (error->resource_type() != ResourceType::MAIN_FRAME) { +void SSLPolicy::OnOverridableCertError(SSLCertErrorHandler* handler) { + if (handler->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 // request hard, without an info bar to allow showing the insecure // content. - error->DenyRequest(); + handler->DenyRequest(); return; } // We need to ask the user to approve this certificate. - ShowBlockingPage(this, error); + ShowBlockingPage(this, handler); } -void SSLPolicy::OnFatalCertError(SSLManager::CertError* error) { - if (error->resource_type() != ResourceType::MAIN_FRAME) { - error->DenyRequest(); +void SSLPolicy::OnFatalCertError(SSLCertErrorHandler* handler) { + if (handler->resource_type() != ResourceType::MAIN_FRAME) { + handler->DenyRequest(); return; } - error->CancelRequest(); - ShowErrorPage(this, error); + handler->CancelRequest(); + ShowErrorPage(this, handler); // No need to degrade our security indicators because we didn't continue. } diff --git a/chrome/browser/ssl/ssl_policy.h b/chrome/browser/ssl/ssl_policy.h index 51a3a3a..570783f 100644 --- a/chrome/browser/ssl/ssl_policy.h +++ b/chrome/browser/ssl/ssl_policy.h @@ -22,9 +22,9 @@ class SSLPolicy : public SSLManager::Delegate, static SSLPolicy* GetDefaultPolicy(); // SSLManager::Delegate methods. - virtual void OnCertError(SSLManager::CertError* error); - virtual void OnMixedContent(SSLManager::MixedContentHandler* handler); - virtual void OnRequestStarted(SSLManager::RequestInfo* info); + virtual void OnCertError(SSLCertErrorHandler* handler); + virtual void OnMixedContent(SSLMixedContentHandler* handler); + virtual void OnRequestStarted(SSLRequestInfo* info); virtual void UpdateEntry(SSLManager* manager, NavigationEntry* entry); // This method is static because it is called from both the UI and the IO @@ -35,9 +35,9 @@ class SSLPolicy : public SSLManager::Delegate, const std::string& frame_origin); // SSLBlockingPage::Delegate methods. - virtual SSLErrorInfo GetSSLErrorInfo(SSLManager::CertError* error); - virtual void OnDenyCertificate(SSLManager::CertError* error); - virtual void OnAllowCertificate(SSLManager::CertError* error); + virtual SSLErrorInfo GetSSLErrorInfo(SSLCertErrorHandler* handler); + virtual void OnDenyCertificate(SSLCertErrorHandler* handler); + virtual void OnAllowCertificate(SSLCertErrorHandler* handler); private: // Construct via |GetDefaultPolicy|. @@ -47,11 +47,11 @@ 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(SSLManager::CertError* error); + void OnOverridableCertError(SSLCertErrorHandler* handler); // Helper method for derived classes handling fatal certificate errors. // Cancel the request and show an error page. - void OnFatalCertError(SSLManager::CertError* error); + void OnFatalCertError(SSLCertErrorHandler* handler); DISALLOW_COPY_AND_ASSIGN(SSLPolicy); }; diff --git a/chrome/browser/ssl/ssl_request_info.h b/chrome/browser/ssl/ssl_request_info.h new file mode 100644 index 0000000..bd1544a --- /dev/null +++ b/chrome/browser/ssl/ssl_request_info.h @@ -0,0 +1,65 @@ +// 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 CHROME_BROWSER_SSL_SSL_REQUEST_INFO_H_ +#define CHROME_BROWSER_SSL_SSL_REQUEST_INFO_H_ + +#include <string> + +#include "chrome/common/filter_policy.h" +#include "googleurl/src/gurl.h" +#include "webkit/glue/resource_type.h" + +class SSLManager; + +// SSLRequestInfo wraps up the information SSLPolicy needs about a request in +// order to update our security IU. SSLRequestInfo is RefCounted in case we +// need to deal with the request asynchronously. +class SSLRequestInfo : public base::RefCounted<SSLRequestInfo> { + public: + SSLRequestInfo(SSLManager* manager, + const GURL& url, + ResourceType::Type resource_type, + const std::string& frame_origin, + const std::string& main_frame_origin, + FilterPolicy::Type filter_policy, + int pid, + 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), + filter_policy_(filter_policy), + pid_(pid), + 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_; } + FilterPolicy::Type filter_policy() const { return filter_policy_; } + int pid() const { return pid_; } + 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_; + FilterPolicy::Type filter_policy_; + int pid_; + int ssl_cert_id_; + int ssl_cert_status_; + + DISALLOW_COPY_AND_ASSIGN(SSLRequestInfo); +}; + +#endif // CHROME_BROWSER_SSL_SSL_REQUEST_INFO_H_ |