Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: chrome/browser/ssl/ssl_error_handler.cc

Issue 318213002: Add custom interstitial for captive portals. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove unnecessary change Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ssl/ssl_error_handler.h"
6
7 #include "base/time/time.h"
8 #include "base/timer/timer.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/ssl/captive_portal_blocking_page.h"
11 #include "chrome/browser/ssl/ssl_blocking_page.h"
12 #include "chrome/common/chrome_version_info.h"
13 #include "content/public/browser/notification_service.h"
14 #include "content/public/browser/notification_source.h"
15 #include "content/public/browser/web_contents.h"
16
17 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
18 #include "chrome/browser/captive_portal/captive_portal_service.h"
19 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
20 #endif
21
22 namespace {
mmenke 2014/10/30 19:28:02 nit: blank line after namespace starts
meacer 2014/11/06 21:21:56 Done.
23 // Events for UMA.
24 enum SSLErrorHandlerEvent {
25 HANDLE_ALL,
26 CAPTIVE_PORTAL_CHECK,
27 CAPTIVE_PORTAL_RESULT_ALREADY_HANDLED,
28 CAPTIVE_PORTAL_RESULT_BEFORE_TIMER_TRIGGER,
29 CAPTIVE_PORTAL_RESULT_AFTER_TIMER_EXPIRE,
mmenke 2014/10/30 19:28:02 nit: TRIGGERED / EXPIRED
meacer 2014/11/06 21:21:56 Done.
30 SSL_WARNING_ALREADY_HANDLED,
31 SHOW_CAPTIVE_PORTAL_INTERSTITIAL,
32 SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE,
33 SHOW_SSL_INTERSTITIAL,
34 SHOW_SSL_INTERSTITIAL_OVERRIDABLE,
35 SHOW_SSL_INTERSTITIAL_WITHOUT_CAPTIVE_PORTAL_CHECK,
36 SHOW_SSL_INTERSTITIAL_WITHOUT_CAPTIVE_PORTAL_CHECK_OVERRIDABLE,
37 SSL_ERROR_HANDLER_EVENT_COUNT
38 };
39
40 void RecordUMA(SSLErrorHandlerEvent event) {
41 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_handler",
42 event,
43 SSL_ERROR_HANDLER_EVENT_COUNT);
44 }
45
46 bool IsCaptivePortalInterstitialEnabled() {
47 chrome::VersionInfo::Channel channel = chrome::VersionInfo::GetChannel();
48 return channel <= chrome::VersionInfo::CHANNEL_DEV;
49 }
50
51 } // namespace
52
53 SSLErrorHandler::SSLErrorHandler(content::WebContents* web_contents,
54 int cert_error,
55 const net::SSLInfo& ssl_info,
56 const GURL& request_url,
57 const int options_mask,
58 const base::TimeDelta ssl_error_delay,
59 const base::Callback<void(bool)>& callback)
60 : content::WebContentsObserver(web_contents),
61 web_contents_(web_contents),
62 cert_error_(cert_error),
63 ssl_info_(ssl_info),
64 request_url_(request_url),
65 options_mask_(options_mask),
66 callback_(callback),
67 handled_(false),
68 captive_portal_check_count_(0),
69 ssl_interstitial_show_count_(0),
70 captive_portal_interstitial_show_count_(0),
71 ssl_interstitial_display_delay_(ssl_error_delay),
72 create_interstitials_(true),
73 timer_expired_(false) {
74 }
75
76 SSLErrorHandler::~SSLErrorHandler() {
77 }
78
79 bool SSLErrorHandler::overridable() const {
mmenke 2014/10/30 19:28:02 Definition order should match declaration order
mmenke 2014/10/30 19:28:02 nit: Should either change naming style, or inline
meacer 2014/11/06 21:21:56 Moved to SSLBlockingPage.
80 return (options_mask_ & SSLBlockingPage::OVERRIDABLE) &&
81 !(options_mask_ & SSLBlockingPage::STRICT_ENFORCEMENT);
mmenke 2014/10/30 19:28:02 I have no idea what these enum values mean, and th
meacer 2014/11/06 21:21:56 Added descriptions in ssl_blocking_page.h
82 }
83
84 void SSLErrorHandler::Handle() {
85 if (handled_) {
86 RecordUMA(SSL_WARNING_ALREADY_HANDLED);
mmenke 2014/10/30 19:33:44 Also, this doesn't get anything. Should just DCHE
meacer 2014/11/06 21:21:56 OnCaptivePortalResult might get calledbefore Handl
mmenke 2014/11/06 22:12:40 That can't happen, because we don't spin the messa
meacer 2014/11/06 23:23:18 Okay, I was assuming that could happen so I had ad
mmenke 2014/11/06 23:39:07 In the test it happens because you send the notifi
87 return;
88 }
89 RecordUMA(HANDLE_ALL);
90
91 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
92 if (IsCaptivePortalInterstitialEnabled()) {
93 CheckForCaptivePortal();
94 timer_.Start(FROM_HERE, ssl_interstitial_display_delay_,
95 base::Bind(&SSLErrorHandler::OnTimerExpired,
96 base::Unretained(this)));
97 return;
98 }
99 #endif
100 // Display an SSL interstitial.
101 RecordUMA(overridable() ?
102 SHOW_SSL_INTERSTITIAL_WITHOUT_CAPTIVE_PORTAL_CHECK_OVERRIDABLE :
103 SHOW_SSL_INTERSTITIAL_WITHOUT_CAPTIVE_PORTAL_CHECK);
mmenke 2014/10/30 19:28:02 What does this get us? ENABLE_CAPTIVE_PORTAL_DETE
meacer 2014/11/06 21:21:56 Removed.
104 ShowSSLInterstitial();
105 handled_ = true;
106 }
107
108 void SSLErrorHandler::CheckForCaptivePortal() {
109 captive_portal_check_count_++;
110 // No need to do an actual captive portal check if no interstitial is shown.
111 if (!create_interstitials_)
112 return;
113
114 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
115 RecordUMA(CAPTIVE_PORTAL_CHECK);
116 Profile* profile = Profile::FromBrowserContext(
117 web_contents_->GetBrowserContext());
118 CaptivePortalService* captive_portal_service =
119 CaptivePortalServiceFactory::GetForProfile(profile);
120 captive_portal_service->DetectCaptivePortal();
121 registrar_.Add(this,
122 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
123 content::Source<Profile>(profile));
124 #endif
125 }
126
127 void SSLErrorHandler::Observe(
128 int type,
129 const content::NotificationSource& source,
130 const content::NotificationDetails& details) {
131 // TODO(meacer): Refactor this method in SSLBlockingPage.
132 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
133 if (type == chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT) {
134 CaptivePortalService::Results* results =
135 content::Details<CaptivePortalService::Results>(details).ptr();
136 if (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL)
137 OnCaptivePortalResult();
mmenke 2014/10/30 19:28:02 If we don't see a captive portal, and handled_ is
meacer 2014/11/06 21:21:56 Hmm, isn't it possible that we could see a captive
mmenke 2014/11/06 22:12:40 Yes, it's possible, theoretically, but due to expo
meacer 2014/11/06 23:23:18 Sure, will do.
138 }
139 #endif
140 }
141
142 void SSLErrorHandler::OnCaptivePortalResult() {
mmenke 2014/10/30 19:28:02 "CaptivePortalResult" is a very confusing name her
meacer 2014/11/06 21:21:56 Done.
143 if (!timer_.IsRunning()) {
144 RecordUMA(timer_expired_ ?
145 CAPTIVE_PORTAL_RESULT_AFTER_TIMER_EXPIRE :
146 CAPTIVE_PORTAL_RESULT_BEFORE_TIMER_TRIGGER);
147 }
148 if (handled_) {
mmenke 2014/10/30 19:28:02 Is there any case where handled_ != timer_.IsRunni
meacer 2014/11/06 21:21:56 That would be the general case where timer is runn
mmenke 2014/11/06 22:12:40 Sorry, I meant handled_ != !timer_.IsRunning(). i
meacer 2014/11/06 23:23:18 Good point, looks like CAPTIVE_PORTAL_DETECTED_AFT
149 RecordUMA(CAPTIVE_PORTAL_RESULT_ALREADY_HANDLED);
150 return;
151 }
152 timer_.Stop();
153 ShowCaptivePortalInterstitial();
154 handled_ = true;
155 }
156
157 void SSLErrorHandler::OnTimerExpired() {
158 timer_expired_ = true;
159 if (handled_) {
160 return;
161 }
162 ShowSSLInterstitial();
163 handled_ = true;
164 }
165
166 void SSLErrorHandler::ShowCaptivePortalInterstitial() {
167 captive_portal_interstitial_show_count_++;
mmenke 2014/10/30 19:28:02 If you want to go this route for testing, I think
meacer 2014/11/06 21:21:56 Done.
168 if (!create_interstitials_)
169 return;
170 // Show captive portal blocking page. The interstitial owns the blocking page.
171 RecordUMA(overridable() ?
172 SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE :
173 SHOW_CAPTIVE_PORTAL_INTERSTITIAL);
174 (new CaptivePortalBlockingPage(web_contents_, request_url_))->Show();
175 }
176
177 void SSLErrorHandler::ShowSSLInterstitial() {
178 ssl_interstitial_show_count_++;
179 if (!create_interstitials_)
180 return;
181 // Show SSL blocking page. The interstitial owns the blocking page.
182 RecordUMA(overridable() ?
183 SHOW_SSL_INTERSTITIAL_OVERRIDABLE :
184 SHOW_SSL_INTERSTITIAL);
185 (new SSLBlockingPage(web_contents_, cert_error_, ssl_info_, request_url_,
186 options_mask_, callback_))->Show();
187 }
188
189 void SSLErrorHandler::DidStopLoading(
190 content::RenderViewHost* render_view_host) {
191 delete this;
192 }
193
194 void SSLErrorHandler::WebContentsDestroyed() {
195 delete this;
196 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698