summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ssl/ssl_error_handler.h
blob: dd69364a44643c644b11fca9683405e5feb66498 (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
145
146
147
148
// 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 "components/ssl_errors/error_classification.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 CommonNameMismatchHandler;
class Profile;

namespace base {
class Clock;
}

namespace content {
class RenderViewHost;
class WebContents;
}

// This class is responsible for deciding what type of interstitial to show for
// an SSL validation error. The display of the interstitial might be delayed by
// a few seconds (2 by default) while trying to determine the cause of the
// error. During this window, the class will: check for a clock error, wait for
// a name-mismatch suggested URL, or wait for a captive portal result to arrive.
// If there is a name mismatch error and a corresponding suggested URL
// result arrives in this window, the user is redirected to the suggested URL.
// Failing that, if a captive portal detected result arrives in the time window,
// a captive portal error page is shown. If none of these potential error
// causes match, an SSL interstitial is shown.
//
// This class 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:
  typedef base::Callback<void(content::WebContents*)> TimerStartedCallback;

  // Entry point for the class. The parameters are the same as SSLBlockingPage
  // constructor.
  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);

  // Testing methods.
  static void SetInterstitialDelayForTest(base::TimeDelta delay);
  // The callback pointer must remain valid for the duration of error handling.
  static void SetInterstitialTimerStartedCallbackForTest(
      TimerStartedCallback* callback);
  static void SetClockForTest(base::Clock* testing_clock);

 protected:
  // The parameters are the same as SSLBlockingPage's constructor.
  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& get_timer() const { return timer_; }

  // These are virtual for tests:
  virtual void CheckForCaptivePortal();
  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);
  virtual bool IsErrorOverridable() const;
  virtual void ShowCaptivePortalInterstitial(const GURL& landing_url);
  virtual void ShowSSLInterstitial();

  void ShowBadClockInterstitial(const base::Time& now,
                                ssl_errors::ClockState clock_state);

  // 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);

 private:
  // 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 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_