summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ssl
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/ssl')
-rw-r--r--chrome/browser/ssl/ssl_blocking_page.cc15
-rw-r--r--chrome/browser/ssl/ssl_blocking_page.h13
-rw-r--r--chrome/browser/ssl/ssl_cert_error_handler.h58
-rw-r--r--chrome/browser/ssl/ssl_error_handler.cc209
-rw-r--r--chrome/browser/ssl/ssl_error_handler.h176
-rw-r--r--chrome/browser/ssl/ssl_manager.cc278
-rw-r--r--chrome/browser/ssl/ssl_manager.h281
-rw-r--r--chrome/browser/ssl/ssl_mixed_content_handler.h38
-rw-r--r--chrome/browser/ssl/ssl_policy.cc101
-rw-r--r--chrome/browser/ssl/ssl_policy.h16
-rw-r--r--chrome/browser/ssl/ssl_request_info.h65
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_