summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ssl/ssl_manager.h
diff options
context:
space:
mode:
authorben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-16 03:29:03 +0000
committerben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-01-16 03:29:03 +0000
commit3b073b258b19937b1dd9b6b2a609dee207865eba (patch)
treefb0779236d58e8a49513c1036d891c2e10c9573c /chrome/browser/ssl/ssl_manager.h
parent7fb087e0800d0faaa31e4a029ad6813f251b4848 (diff)
downloadchromium_src-3b073b258b19937b1dd9b6b2a609dee207865eba.zip
chromium_src-3b073b258b19937b1dd9b6b2a609dee207865eba.tar.gz
chromium_src-3b073b258b19937b1dd9b6b2a609dee207865eba.tar.bz2
Move all the SSL stuff into its own subdir
Review URL: http://codereview.chromium.org/18137 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@8165 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/ssl/ssl_manager.h')
-rw-r--r--chrome/browser/ssl/ssl_manager.h465
1 files changed, 465 insertions, 0 deletions
diff --git a/chrome/browser/ssl/ssl_manager.h b/chrome/browser/ssl/ssl_manager.h
new file mode 100644
index 0000000..e650b35
--- /dev/null
+++ b/chrome/browser/ssl/ssl_manager.h
@@ -0,0 +1,465 @@
+// Copyright (c) 2006-2008 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_MANAGER_H_
+#define CHROME_BROWSER_SSL_MANAGER_H_
+
+#include <string>
+#include <map>
+
+#include "base/basictypes.h"
+#include "base/observer_list.h"
+#include "base/ref_counted.h"
+#include "chrome/browser/renderer_host/resource_dispatcher_host.h"
+#include "chrome/browser/security_style.h"
+#include "chrome/browser/tab_contents/provisional_load_details.h"
+#include "chrome/common/notification_registrar.h"
+#include "chrome/common/notification_service.h"
+#include "chrome/common/render_messages.h"
+#include "googleurl/src/gurl.h"
+#include "net/base/net_errors.h"
+#include "net/base/ssl_info.h"
+#include "net/base/x509_certificate.h"
+#include "webkit/glue/console_message_level.h"
+#include "webkit/glue/resource_type.h"
+
+class AutomationProvider;
+class NavigationEntry;
+class LoadFromMemoryCacheDetails;
+class LoadNotificationDetails;
+class NavigationController;
+class PrefService;
+class ResourceRedirectDetails;
+class ResourceRequestDetails;
+class SSLErrorInfo;
+class Task;
+class URLRequest;
+class WebContents;
+
+// The SSLManager SSLManager controls the SSL UI elements in a TabContents. It
+// listens for various events that influence when these elements should or
+// should not be displayed and adjusts them accordingly.
+//
+// There is one SSLManager per tab.
+// The security state (secure/insecure) is stored in the navigation entry.
+// Along with it are stored any SSL error code and the associated cert.
+//
+
+class SSLManager : public NotificationObserver {
+ public:
+ // 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() { }
+
+ // 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_; }
+
+ // Call on the UI thread.
+ SSLManager* manager() const { return manager_; };
+
+ // Returns the WebContents this object is associated with. Should be
+ // called from the UI thread.
+ WebContents* GetWebContents();
+
+ // 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,
+ 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_;
+
+ // This read-only member can be accessed on any thread.
+ const GURL request_url_; // The URL that we requested.
+
+ // Should only be accessed on the IO thread
+ bool request_has_been_notified_; // A flag to make sure we notify the
+ // URLRequest exactly once.
+
+ DISALLOW_EVIL_CONSTRUCTORS(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:
+ // These accessors are available on either thread
+ const net::SSLInfo& ssl_info() const { return ssl_info_; }
+ int cert_error() const { return cert_error_; }
+
+ ResourceType::Type resource_type() const { return resource_type_; }
+ private:
+ // SSLManager is responsible for creating CertError objects.
+ friend class SSLManager;
+
+ // 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,
+ 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.
+
+ // What kind of resource is associated with the requested that generated
+ // that error.
+ ResourceType::Type resource_type_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(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,
+ MessageLoop* ui_loop)
+ : ErrorHandler(rdh, request, ui_loop) { }
+
+ protected:
+ virtual void OnDispatchFailed() { TakeNoAction(); }
+ virtual void OnDispatched() { manager()->OnMixedContent(this); }
+
+ private:
+ DISALLOW_EVIL_CONSTRUCTORS(MixedContentHandler);
+ };
+
+ // 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.
+ //
+ // Delegates should interact with the rest of the browser only through their
+ // parameters and through the delegate API of the SSLManager.
+ //
+ // If a delegate needs to do something tricky, consider having the SSLManager
+ // do it instead.
+ class Delegate {
+ public:
+ // An error occurred with the certificate in an SSL connection.
+ virtual void OnCertError(const GURL& main_frame_url, CertError* error) = 0;
+
+ // A request for a mixed-content resource was made. Note that the resource
+ // request was not started yet and the delegate is responsible for starting
+ // it.
+ virtual void OnMixedContent(
+ NavigationController* navigation_controller,
+ const GURL& main_frame_url,
+ MixedContentHandler* mixed_content_handler) = 0;
+
+ // We have started a resource request for the given URL.
+ virtual void OnRequestStarted(SSLManager* manager,
+ const GURL& url,
+ ResourceType::Type resource_type,
+ int ssl_cert_id,
+ int ssl_cert_status) = 0;
+
+ // Returns the default security style for a given URL.
+ virtual SecurityStyle GetDefaultStyle(const GURL& url) = 0;
+ };
+
+ static void RegisterUserPrefs(PrefService* prefs);
+
+ // Construct an SSLManager for the specified tab.
+ // If |delegate| is NULL, SSLPolicy::GetDefaultPolicy() is used.
+ SSLManager(NavigationController* controller, Delegate* delegate);
+
+ ~SSLManager();
+
+ //////////////////////////////////////////////////////////////////////////////
+ // Delegate API
+ //
+ // The SSL manager expects these methods to be called by its delegate. They
+ // exist to make Delegates easy to implement.
+
+ // Ensure that the specified message is displayed to the user. This will
+ // display an InfoBar at the top of the associated tab.
+ void ShowMessage(const std::wstring& msg);
+
+ // Same as ShowMessage but also contains a link that when clicked run the
+ // specified task. The SSL Manager becomes the owner of the task.
+ void ShowMessageWithLink(const std::wstring& msg,
+ const std::wstring& link_text,
+ Task* task);
+
+ // Sets the maximum security style for the page. If the current security
+ // style is lower than |style|, this will not have an effect on the security
+ // indicators.
+ //
+ // It will return true if the navigation entry was updated or false if
+ // nothing changed. The caller is responsible for broadcasting
+ // NOTIFY_SSY_STATE_CHANGED if it returns true.
+ bool SetMaxSecurityStyle(SecurityStyle style);
+
+ // Logs a message to the console of the page.
+ void AddMessageToConsole(const std::wstring& msg,
+ ConsoleMessageLevel level);
+
+ // Records that |cert| is permitted to be used for |host| in the future.
+ void DenyCertForHost(net::X509Certificate* cert, const std::string& host);
+
+ // Records that |cert| is not permitted to be used for |host| in the future.
+ void AllowCertForHost(net::X509Certificate* cert, const std::string& host);
+
+ // Queries whether |cert| is allowed or denied for |host|.
+ net::X509Certificate::Policy::Judgment QueryPolicy(
+ net::X509Certificate* cert, const std::string& host);
+
+ // Allow mixed/unsafe content to be visible (non filtered) for the specified
+ // URL.
+ // Note that the current implementation allows on a host name basis.
+ void AllowShowInsecureContentForURL(const GURL& url);
+
+ // Returns whether the specified URL is allowed to show insecure (mixed or
+ // unsafe) content.
+ bool CanShowInsecureContent(const GURL& url);
+
+ //
+ //////////////////////////////////////////////////////////////////////////////
+
+ // The delegate of the SSLManager. This value may be changed at any time,
+ // but it is not permissible for it to be NULL.
+ Delegate* delegate() const { return delegate_; }
+ void set_delegate(Delegate* delegate) { delegate_ = delegate; }
+
+ // Entry point for SSLCertificateErrors. This function begins the process
+ // of resolving a certificate error during an SSL connection. SSLManager
+ // will adjust the security UI and either call |Cancel| or
+ // |ContinueDespiteLastError| on the URLRequest.
+ //
+ // Called on the IO thread.
+ static void OnSSLCertificateError(ResourceDispatcherHost* resource_dispatcher,
+ URLRequest* request,
+ int cert_error,
+ net::X509Certificate* cert,
+ MessageLoop* ui_loop);
+
+ // Called when a mixed-content sub-resource request has been detected. The
+ // request is not started yet. The SSLManager will make a decision on whether
+ // to filter that request's content (with the filter_policy flag).
+ // TODO (jcampan): Implement a way to just cancel the request. This is not
+ // straight-forward as canceling a request that has not been started will
+ // not remove from the pending_requests_ of the ResourceDispatcherHost.
+ // Called on the IO thread.
+ static void OnMixedContentRequest(ResourceDispatcherHost* resource_dispatcher,
+ URLRequest* request,
+ MessageLoop* ui_loop);
+
+ // Called by CertError::Dispatch to kick off processing of the cert error by
+ // the SSL manager. The error originated from the ResourceDispatcherHost.
+ //
+ // Called on the UI thread.
+ void OnCertError(CertError* error);
+
+ // 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* mixed_content);
+
+ // Entry point for navigation. This function begins the process of updating
+ // the security UI when the main frame navigates to a new URL.
+ //
+ // Called on the UI thread.
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details);
+
+ // Entry point for navigation. This function begins the process of updating
+ // the security UI when the main frame navigates.
+ //
+ // Called on the UI thread.
+ void NavigationStateChanged();
+
+ // Called to determine if there were any processed SSL errors from request.
+ bool ProcessedSSLErrorFromRequest() const;
+
+ NavigationController* controller() { return controller_; }
+
+ // Convenience methods for serializing/deserializing the security info.
+ static std::string SerializeSecurityInfo(int cert_id,
+ int cert_status,
+ int security_bits);
+ static bool DeserializeSecurityInfo(const std::string& state,
+ int* cert_id,
+ int* cert_status,
+ int* security_bits);
+
+ // Sets |short_name| to <organization_name> [<country>] and |ca_name|
+ // to something like:
+ // "Verified by <issuer_organization_name>"
+ static bool GetEVCertNames(const net::X509Certificate& cert,
+ std::wstring* short_name,
+ std::wstring* ca_name);
+
+ private:
+ // SSLMessageInfo contains the information necessary for displaying a message
+ // in an info-bar.
+ struct SSLMessageInfo {
+ public:
+ explicit SSLMessageInfo(const std::wstring& text)
+ : message(text),
+ action(NULL) { }
+ SSLMessageInfo(const std::wstring& message,
+ const std::wstring& link_text,
+ Task* action)
+ : message(message), link_text(link_text), action(action) { }
+
+ // Overridden so that std::find works.
+ bool operator==(const std::wstring& other_message) const {
+ // We are uniquing SSLMessageInfo by their message only.
+ return message == other_message;
+ }
+
+ std::wstring message;
+ std::wstring link_text;
+ Task* action;
+ };
+
+ // Entry points for notifications to which we subscribe. Note that
+ // DidCommitProvisionalLoad uses the abstract NotificationDetails type since
+ // the type we need is in NavigationController which would create a circular
+ // header file dependency.
+ void DidLoadFromMemoryCache(LoadFromMemoryCacheDetails* details);
+ void DidCommitProvisionalLoad(const NotificationDetails& details);
+ void DidFailProvisionalLoadWithError(ProvisionalLoadDetails* details);
+ void DidStartResourceResponse(ResourceRequestDetails* details);
+ void DidReceiveResourceRedirect(ResourceRedirectDetails* details);
+
+ // Convenience method for initializing navigation entries.
+ void InitializeEntryIfNeeded(NavigationEntry* entry);
+
+ // Shows the pending messages (in info-bars) if any.
+ void ShowPendingMessages();
+
+ // Clears any pending messages.
+ void ClearPendingMessages();
+
+ // Our delegate. The delegate is responsible for making policy decisions.
+ // Must not be NULL.
+ Delegate* delegate_;
+
+ // The NavigationController that owns this SSLManager. We are responsible
+ // for the security UI of this tab.
+ NavigationController* controller_;
+
+ // Handles registering notifications with the NotificationService.
+ NotificationRegistrar registrar_;
+
+ // Certificate policies for each host.
+ std::map<std::string, net::X509Certificate::Policy> cert_policy_for_host_;
+
+ // Domains for which it is OK to show insecure content.
+ std::set<std::string> can_show_insecure_content_for_host_;
+
+ // The list of messages that should be displayed (in info bars) when the page
+ // currently loading had loaded.
+ std::vector<SSLMessageInfo> pending_messages_;
+
+ DISALLOW_COPY_AND_ASSIGN(SSLManager);
+};
+
+#endif // CHROME_BROWSER_SSL_MANAGER_H_
+