| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ssl/ssl_error_handler.h" | 5 #include "chrome/browser/ssl/ssl_error_handler.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/callback_helpers.h" | 10 #include "base/callback_helpers.h" |
| 11 #include "base/macros.h" | 11 #include "base/macros.h" |
| 12 #include "base/metrics/field_trial.h" | 12 #include "base/metrics/field_trial.h" |
| 13 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
| 14 #include "base/strings/stringprintf.h" | 14 #include "base/strings/stringprintf.h" |
| 15 #include "base/time/clock.h" | 15 #include "base/time/clock.h" |
| 16 #include "base/time/time.h" | 16 #include "base/time/time.h" |
| 17 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
| 18 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 19 #include "chrome/browser/ssl/bad_clock_blocking_page.h" | 19 #include "chrome/browser/ssl/bad_clock_blocking_page.h" |
| 20 #include "chrome/browser/ssl/ssl_blocking_page.h" | 20 #include "chrome/browser/ssl/ssl_blocking_page.h" |
| 21 #include "chrome/browser/ssl/ssl_cert_reporter.h" | 21 #include "chrome/browser/ssl/ssl_cert_reporter.h" |
| 22 #include "chrome/common/features.h" |
| 22 #include "components/ssl_errors/error_classification.h" | 23 #include "components/ssl_errors/error_classification.h" |
| 23 #include "components/ssl_errors/error_info.h" | 24 #include "components/ssl_errors/error_info.h" |
| 24 #include "content/public/browser/notification_service.h" | 25 #include "content/public/browser/notification_service.h" |
| 25 #include "content/public/browser/notification_source.h" | 26 #include "content/public/browser/notification_source.h" |
| 26 #include "content/public/browser/render_frame_host.h" | 27 #include "content/public/browser/render_frame_host.h" |
| 27 #include "content/public/browser/web_contents.h" | 28 #include "content/public/browser/web_contents.h" |
| 28 #include "net/base/net_errors.h" | 29 #include "net/base/net_errors.h" |
| 29 | 30 |
| 30 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | 31 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 31 #include "chrome/browser/captive_portal/captive_portal_service.h" | 32 #include "chrome/browser/captive_portal/captive_portal_service.h" |
| 32 #include "chrome/browser/captive_portal/captive_portal_service_factory.h" | 33 #include "chrome/browser/captive_portal/captive_portal_service_factory.h" |
| 33 #include "chrome/browser/captive_portal/captive_portal_tab_helper.h" | 34 #include "chrome/browser/captive_portal/captive_portal_tab_helper.h" |
| 34 #include "chrome/browser/ssl/captive_portal_blocking_page.h" | 35 #include "chrome/browser/ssl/captive_portal_blocking_page.h" |
| 35 #endif | 36 #endif |
| 36 | 37 |
| 37 namespace network_time { | 38 namespace network_time { |
| 38 class NetworkTimeTracker; | 39 class NetworkTimeTracker; |
| 39 } | 40 } |
| 40 | 41 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 const std::string suggested_url_hostname_; | 125 const std::string suggested_url_hostname_; |
| 125 | 126 |
| 126 DISALLOW_COPY_AND_ASSIGN(CommonNameMismatchRedirectObserver); | 127 DISALLOW_COPY_AND_ASSIGN(CommonNameMismatchRedirectObserver); |
| 127 }; | 128 }; |
| 128 | 129 |
| 129 void RecordUMA(SSLErrorHandlerEvent event) { | 130 void RecordUMA(SSLErrorHandlerEvent event) { |
| 130 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_handler", event, | 131 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_handler", event, |
| 131 SSL_ERROR_HANDLER_EVENT_COUNT); | 132 SSL_ERROR_HANDLER_EVENT_COUNT); |
| 132 } | 133 } |
| 133 | 134 |
| 134 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | 135 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 135 bool IsCaptivePortalInterstitialEnabled() { | 136 bool IsCaptivePortalInterstitialEnabled() { |
| 136 return base::FieldTrialList::FindFullName("CaptivePortalInterstitial") == | 137 return base::FieldTrialList::FindFullName("CaptivePortalInterstitial") == |
| 137 "Enabled"; | 138 "Enabled"; |
| 138 } | 139 } |
| 139 #endif | 140 #endif |
| 140 | 141 |
| 141 bool IsSSLCommonNameMismatchHandlingEnabled() { | 142 bool IsSSLCommonNameMismatchHandlingEnabled() { |
| 142 return base::FieldTrialList::FindFullName("SSLCommonNameMismatchHandling") == | 143 return base::FieldTrialList::FindFullName("SSLCommonNameMismatchHandling") == |
| 143 "Enabled"; | 144 "Enabled"; |
| 144 } | 145 } |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 this, &SSLErrorHandler::ShowSSLInterstitial); | 246 this, &SSLErrorHandler::ShowSSLInterstitial); |
| 246 if (g_timer_started_callback) | 247 if (g_timer_started_callback) |
| 247 g_timer_started_callback->Run(web_contents_); | 248 g_timer_started_callback->Run(web_contents_); |
| 248 | 249 |
| 249 // Do not check for a captive portal in this case, because a captive | 250 // Do not check for a captive portal in this case, because a captive |
| 250 // portal most likely cannot serve a valid certificate which passes the | 251 // portal most likely cannot serve a valid certificate which passes the |
| 251 // similarity check. | 252 // similarity check. |
| 252 return; | 253 return; |
| 253 } | 254 } |
| 254 | 255 |
| 255 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | 256 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 256 CaptivePortalTabHelper* captive_portal_tab_helper = | 257 CaptivePortalTabHelper* captive_portal_tab_helper = |
| 257 CaptivePortalTabHelper::FromWebContents(web_contents_); | 258 CaptivePortalTabHelper::FromWebContents(web_contents_); |
| 258 if (captive_portal_tab_helper) { | 259 if (captive_portal_tab_helper) { |
| 259 captive_portal_tab_helper->OnSSLCertError(ssl_info_); | 260 captive_portal_tab_helper->OnSSLCertError(ssl_info_); |
| 260 } | 261 } |
| 261 | 262 |
| 262 registrar_.Add(this, chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT, | 263 registrar_.Add(this, chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT, |
| 263 content::Source<Profile>(profile_)); | 264 content::Source<Profile>(profile_)); |
| 264 | 265 |
| 265 if (IsCaptivePortalInterstitialEnabled()) { | 266 if (IsCaptivePortalInterstitialEnabled()) { |
| 266 CheckForCaptivePortal(); | 267 CheckForCaptivePortal(); |
| 267 timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds( | 268 timer_.Start(FROM_HERE, base::TimeDelta::FromMilliseconds( |
| 268 g_interstitial_delay_in_milliseconds), | 269 g_interstitial_delay_in_milliseconds), |
| 269 this, &SSLErrorHandler::ShowSSLInterstitial); | 270 this, &SSLErrorHandler::ShowSSLInterstitial); |
| 270 if (g_timer_started_callback) | 271 if (g_timer_started_callback) |
| 271 g_timer_started_callback->Run(web_contents_); | 272 g_timer_started_callback->Run(web_contents_); |
| 272 return; | 273 return; |
| 273 } | 274 } |
| 274 #endif | 275 #endif |
| 275 // Display an SSL interstitial. | 276 // Display an SSL interstitial. |
| 276 ShowSSLInterstitial(); | 277 ShowSSLInterstitial(); |
| 277 } | 278 } |
| 278 | 279 |
| 279 void SSLErrorHandler::CheckForCaptivePortal() { | 280 void SSLErrorHandler::CheckForCaptivePortal() { |
| 280 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | 281 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 281 CaptivePortalService* captive_portal_service = | 282 CaptivePortalService* captive_portal_service = |
| 282 CaptivePortalServiceFactory::GetForProfile(profile_); | 283 CaptivePortalServiceFactory::GetForProfile(profile_); |
| 283 captive_portal_service->DetectCaptivePortal(); | 284 captive_portal_service->DetectCaptivePortal(); |
| 284 #else | 285 #else |
| 285 NOTREACHED(); | 286 NOTREACHED(); |
| 286 #endif | 287 #endif |
| 287 } | 288 } |
| 288 | 289 |
| 289 bool SSLErrorHandler::GetSuggestedUrl(const std::vector<std::string>& dns_names, | 290 bool SSLErrorHandler::GetSuggestedUrl(const std::vector<std::string>& dns_names, |
| 290 GURL* suggested_url) const { | 291 GURL* suggested_url) const { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 308 content::NavigationController::LoadURLParams load_params(suggested_url); | 309 content::NavigationController::LoadURLParams load_params(suggested_url); |
| 309 load_params.transition_type = ui::PAGE_TRANSITION_TYPED; | 310 load_params.transition_type = ui::PAGE_TRANSITION_TYPED; |
| 310 web_contents()->GetController().LoadURLWithParams(load_params); | 311 web_contents()->GetController().LoadURLWithParams(load_params); |
| 311 } | 312 } |
| 312 | 313 |
| 313 bool SSLErrorHandler::IsErrorOverridable() const { | 314 bool SSLErrorHandler::IsErrorOverridable() const { |
| 314 return SSLBlockingPage::IsOverridable(options_mask_, profile_); | 315 return SSLBlockingPage::IsOverridable(options_mask_, profile_); |
| 315 } | 316 } |
| 316 | 317 |
| 317 void SSLErrorHandler::ShowCaptivePortalInterstitial(const GURL& landing_url) { | 318 void SSLErrorHandler::ShowCaptivePortalInterstitial(const GURL& landing_url) { |
| 318 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | 319 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 319 // Show captive portal blocking page. The interstitial owns the blocking page. | 320 // Show captive portal blocking page. The interstitial owns the blocking page. |
| 320 RecordUMA(IsErrorOverridable() | 321 RecordUMA(IsErrorOverridable() |
| 321 ? SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE | 322 ? SHOW_CAPTIVE_PORTAL_INTERSTITIAL_OVERRIDABLE |
| 322 : SHOW_CAPTIVE_PORTAL_INTERSTITIAL_NONOVERRIDABLE); | 323 : SHOW_CAPTIVE_PORTAL_INTERSTITIAL_NONOVERRIDABLE); |
| 323 (new CaptivePortalBlockingPage(web_contents_, request_url_, landing_url, | 324 (new CaptivePortalBlockingPage(web_contents_, request_url_, landing_url, |
| 324 std::move(ssl_cert_reporter_), ssl_info_, | 325 std::move(ssl_cert_reporter_), ssl_info_, |
| 325 callback_)) | 326 callback_)) |
| 326 ->Show(); | 327 ->Show(); |
| 327 // Once an interstitial is displayed, no need to keep the handler around. | 328 // Once an interstitial is displayed, no need to keep the handler around. |
| 328 // This is the equivalent of "delete this". It also destroys the timer. | 329 // This is the equivalent of "delete this". It also destroys the timer. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 } else { | 373 } else { |
| 373 RecordUMA(WWW_MISMATCH_URL_NOT_AVAILABLE); | 374 RecordUMA(WWW_MISMATCH_URL_NOT_AVAILABLE); |
| 374 ShowSSLInterstitial(); | 375 ShowSSLInterstitial(); |
| 375 } | 376 } |
| 376 } | 377 } |
| 377 | 378 |
| 378 void SSLErrorHandler::Observe( | 379 void SSLErrorHandler::Observe( |
| 379 int type, | 380 int type, |
| 380 const content::NotificationSource& source, | 381 const content::NotificationSource& source, |
| 381 const content::NotificationDetails& details) { | 382 const content::NotificationDetails& details) { |
| 382 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION) | 383 #if BUILDFLAG(ENABLE_CAPTIVE_PORTAL_DETECTION) |
| 383 DCHECK_EQ(chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT, type); | 384 DCHECK_EQ(chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT, type); |
| 384 | 385 |
| 385 timer_.Stop(); | 386 timer_.Stop(); |
| 386 CaptivePortalService::Results* results = | 387 CaptivePortalService::Results* results = |
| 387 content::Details<CaptivePortalService::Results>(details).ptr(); | 388 content::Details<CaptivePortalService::Results>(details).ptr(); |
| 388 if (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL) | 389 if (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL) |
| 389 ShowCaptivePortalInterstitial(results->landing_url); | 390 ShowCaptivePortalInterstitial(results->landing_url); |
| 390 else | 391 else |
| 391 ShowSSLInterstitial(); | 392 ShowSSLInterstitial(); |
| 392 #endif | 393 #endif |
| (...skipping 20 matching lines...) Expand all Loading... |
| 413 base::ResetAndReturn(&callback_) | 414 base::ResetAndReturn(&callback_) |
| 414 .Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY); | 415 .Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_DENY); |
| 415 } | 416 } |
| 416 if (common_name_mismatch_handler_) { | 417 if (common_name_mismatch_handler_) { |
| 417 common_name_mismatch_handler_->Cancel(); | 418 common_name_mismatch_handler_->Cancel(); |
| 418 common_name_mismatch_handler_.reset(); | 419 common_name_mismatch_handler_.reset(); |
| 419 } | 420 } |
| 420 // Deletes |this| and also destroys the timer. | 421 // Deletes |this| and also destroys the timer. |
| 421 web_contents_->RemoveUserData(UserDataKey()); | 422 web_contents_->RemoveUserData(UserDataKey()); |
| 422 } | 423 } |
| OLD | NEW |