summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ssl/ssl_error_handler.h
blob: 025eb1bdfe4f3c674388fa049d6769c85468cb61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// Copyright 2014 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/callback_forward.h"
#include "base/macros.h"
#include "base/timer/timer.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ssl/common_name_mismatch_handler.h"
#include "chrome/browser/ssl/ssl_cert_reporter.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/web_contents_observer.h"
#include "content/public/browser/web_contents_user_data.h"
#include "net/ssl/ssl_info.h"
#include "url/gurl.h"

class Profile;
class CommonNameMismatchHandler;

namespace content {
class RenderViewHost;
class WebContents;
}

// This class is responsible for deciding whether to show an SSL warning or a
// captive portal error page. It makes this decision by delaying the display of
// SSL interstitial for a few seconds (2 by default), and waiting for a captive
// portal result to arrive during this window. If a captive portal detected
// result arrives in this window, a captive portal error page is shown.
// Otherwise, an SSL interstitial is shown.
//
// An SSLErrorHandler is associated with a particular WebContents, and is
// deleted if the WebContents is destroyed, or an interstitial is displayed.
// It should only be used on the UI thread because its implementation uses
// captive_portal::CaptivePortalService which can only be accessed on the UI
// thread.
class SSLErrorHandler : public content::WebContentsUserData<SSLErrorHandler>,
                        public content::WebContentsObserver,
                        public content::NotificationObserver {
 public:
  // Type of the delay to display the SSL interstitial.
  enum InterstitialDelayType {
    NORMAL,  // Default interstitial timer delay used in production.
    NONE,    // No interstitial timer delay (i.e. zero), used in tests.
    LONG     // Very long interstitial timer delay (ie. an hour), used in tests.
  };

  static void HandleSSLError(content::WebContents* web_contents,
                             int cert_error,
                             const net::SSLInfo& ssl_info,
                             const GURL& request_url,
                             int options_mask,
                             scoped_ptr<SSLCertReporter> ssl_cert_reporter,
                             const base::Callback<void(bool)>& callback);

  static void SetInterstitialDelayTypeForTest(InterstitialDelayType delay);

  typedef base::Callback<void(content::WebContents*)> TimerStartedCallback;
  static void SetInterstitialTimerStartedCallbackForTest(
      TimerStartedCallback* callback);

  // Gets the result of whether the suggested URL is valid. Displays
  // common name mismatch interstitial or ssl interstitial accordingly.
  void CommonNameMismatchHandlerCallback(
      const CommonNameMismatchHandler::SuggestedUrlCheckResult& result,
      const GURL& suggested_url);

 protected:
  SSLErrorHandler(content::WebContents* web_contents,
                  int cert_error,
                  const net::SSLInfo& ssl_info,
                  const GURL& request_url,
                  int options_mask,
                  scoped_ptr<SSLCertReporter> ssl_cert_reporter,
                  const base::Callback<void(bool)>& callback);

  ~SSLErrorHandler() override;

  // Called when an SSL cert error is encountered. Triggers a captive portal
  // check and fires a one shot timer to wait for a "captive portal detected"
  // result to arrive.
  void StartHandlingError();
  const base::OneShotTimer<SSLErrorHandler>& get_timer() const {
    return timer_;
  }

 private:
  // Callback for the one-shot timer. When the timer expires, an SSL error is
  // immediately displayed.
  void OnTimerExpired();

  // These are virtual for tests:
  virtual void CheckForCaptivePortal();
  virtual void ShowCaptivePortalInterstitial(const GURL& landing_url);
  virtual void ShowSSLInterstitial();
  virtual bool GetSuggestedUrl(const std::vector<std::string>& dns_names,
                               GURL* suggested_url) const;
  virtual void CheckSuggestedUrl(const GURL& suggested_url);
  virtual void NavigateToSuggestedURL(const GURL& suggested_url);

  // content::NotificationObserver:
  void Observe(
      int type,
      const content::NotificationSource& source,
      const content::NotificationDetails& details) override;

  // content::WebContentsObserver:
  void DidStartNavigationToPendingEntry(
      const GURL& url,
      content::NavigationController::ReloadType reload_type) override;

  // content::WebContentsObserver:
  void NavigationStopped() override;

  // Deletes the SSLErrorHandler. This method is called when the page
  // load stops or when there is a new navigation.
  void DeleteSSLErrorHandler();

  content::WebContents* web_contents_;
  const int cert_error_;
  const net::SSLInfo ssl_info_;
  const GURL request_url_;
  const int options_mask_;
  base::Callback<void(bool)> callback_;
  Profile* const profile_;

  content::NotificationRegistrar registrar_;
  base::OneShotTimer<SSLErrorHandler> timer_;

  scoped_ptr<CommonNameMismatchHandler> common_name_mismatch_handler_;

  scoped_ptr<SSLCertReporter> ssl_cert_reporter_;

  DISALLOW_COPY_AND_ASSIGN(SSLErrorHandler);
};

#endif  // CHROME_BROWSER_SSL_SSL_ERROR_HANDLER_H_