| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_blocking_page.h" | 5 #include "chrome/browser/ssl/ssl_blocking_page.h" |
| 6 | 6 |
| 7 #include "base/build_time.h" | 7 #include "base/build_time.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/i18n/rtl.h" | 9 #include "base/i18n/rtl.h" |
| 10 #include "base/i18n/time_formatting.h" | 10 #include "base/i18n/time_formatting.h" |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 const void* SSLBlockingPage::kTypeForTesting = | 215 const void* SSLBlockingPage::kTypeForTesting = |
| 216 &SSLBlockingPage::kTypeForTesting; | 216 &SSLBlockingPage::kTypeForTesting; |
| 217 | 217 |
| 218 // Note that we always create a navigation entry with SSL errors. | 218 // Note that we always create a navigation entry with SSL errors. |
| 219 // No error happening loading a sub-resource triggers an interstitial so far. | 219 // No error happening loading a sub-resource triggers an interstitial so far. |
| 220 SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents, | 220 SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents, |
| 221 int cert_error, | 221 int cert_error, |
| 222 const net::SSLInfo& ssl_info, | 222 const net::SSLInfo& ssl_info, |
| 223 const GURL& request_url, | 223 const GURL& request_url, |
| 224 int options_mask, | 224 int options_mask, |
| 225 const base::Callback<void(bool)>& callback) | 225 const base::Callback<void(bool)>& callback, |
| 226 const base::Time& time_triggered) |
| 226 : SecurityInterstitialPage(web_contents, request_url), | 227 : SecurityInterstitialPage(web_contents, request_url), |
| 227 callback_(callback), | 228 callback_(callback), |
| 228 cert_error_(cert_error), | 229 cert_error_(cert_error), |
| 229 ssl_info_(ssl_info), | 230 ssl_info_(ssl_info), |
| 230 overridable_(IsOptionsOverridable(options_mask)), | 231 overridable_(IsOptionsOverridable(options_mask)), |
| 231 danger_overridable_(true), | 232 danger_overridable_(true), |
| 232 strict_enforcement_((options_mask & STRICT_ENFORCEMENT) != 0), | 233 strict_enforcement_((options_mask & STRICT_ENFORCEMENT) != 0), |
| 233 expired_but_previously_allowed_( | 234 expired_but_previously_allowed_( |
| 234 (options_mask & EXPIRED_BUT_PREVIOUSLY_ALLOWED) != 0) { | 235 (options_mask & EXPIRED_BUT_PREVIOUSLY_ALLOWED) != 0), |
| 235 interstitial_reason_ = | 236 time_triggered_(time_triggered) { |
| 236 IsErrorDueToBadClock(base::Time::NowFromSystemTime(), cert_error_) ? | 237 interstitial_reason_ = IsErrorDueToBadClock(time_triggered_, cert_error_) |
| 237 SSL_REASON_BAD_CLOCK : SSL_REASON_SSL; | 238 ? SSL_REASON_BAD_CLOCK |
| 239 : SSL_REASON_SSL; |
| 238 | 240 |
| 239 // We collapse the Rappor metric name to just "ssl" so we don't leak | 241 // We collapse the Rappor metric name to just "ssl" so we don't leak |
| 240 // the "overridable" bit. We skip Rappor altogether for bad clocks. | 242 // the "overridable" bit. We skip Rappor altogether for bad clocks. |
| 241 // This must be done after calculating |interstitial_reason_| above. | 243 // This must be done after calculating |interstitial_reason_| above. |
| 242 metrics_helper_.reset(new SecurityInterstitialMetricsHelper( | 244 metrics_helper_.reset(new SecurityInterstitialMetricsHelper( |
| 243 web_contents, request_url, GetUmaHistogramPrefix(), kSSLRapporPrefix, | 245 web_contents, request_url, GetUmaHistogramPrefix(), kSSLRapporPrefix, |
| 244 (interstitial_reason_ == SSL_REASON_BAD_CLOCK | 246 (interstitial_reason_ == SSL_REASON_BAD_CLOCK |
| 245 ? SecurityInterstitialMetricsHelper::SKIP_RAPPOR | 247 ? SecurityInterstitialMetricsHelper::SKIP_RAPPOR |
| 246 : SecurityInterstitialMetricsHelper::REPORT_RAPPOR), | 248 : SecurityInterstitialMetricsHelper::REPORT_RAPPOR), |
| 247 GetSamplingEventName())); | 249 GetSamplingEventName())); |
| 248 | 250 |
| 249 metrics_helper_->RecordUserDecision(SecurityInterstitialMetricsHelper::SHOW); | 251 metrics_helper_->RecordUserDecision(SecurityInterstitialMetricsHelper::SHOW); |
| 250 metrics_helper_->RecordUserInteraction( | 252 metrics_helper_->RecordUserInteraction( |
| 251 SecurityInterstitialMetricsHelper::TOTAL_VISITS); | 253 SecurityInterstitialMetricsHelper::TOTAL_VISITS); |
| 252 | 254 |
| 253 ssl_error_classification_.reset(new SSLErrorClassification( | 255 ssl_error_classification_.reset(new SSLErrorClassification( |
| 254 web_contents, | 256 web_contents, |
| 255 base::Time::NowFromSystemTime(), | 257 time_triggered_, |
| 256 request_url, | 258 request_url, |
| 257 cert_error_, | 259 cert_error_, |
| 258 *ssl_info_.cert.get())); | 260 *ssl_info_.cert.get())); |
| 259 ssl_error_classification_->RecordUMAStatistics(overridable_); | 261 ssl_error_classification_->RecordUMAStatistics(overridable_); |
| 260 | 262 |
| 261 // Creating an interstitial without showing (e.g. from chrome://interstitials) | 263 // Creating an interstitial without showing (e.g. from chrome://interstitials) |
| 262 // it leaks memory, so don't create it here. | 264 // it leaks memory, so don't create it here. |
| 263 } | 265 } |
| 264 | 266 |
| 265 bool SSLBlockingPage::ShouldCreateNewNavigation() const { | 267 bool SSLBlockingPage::ShouldCreateNewNavigation() const { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 288 } | 290 } |
| 289 | 291 |
| 290 void SSLBlockingPage::PopulateInterstitialStrings( | 292 void SSLBlockingPage::PopulateInterstitialStrings( |
| 291 base::DictionaryValue* load_time_data) { | 293 base::DictionaryValue* load_time_data) { |
| 292 CHECK(load_time_data); | 294 CHECK(load_time_data); |
| 293 base::string16 url(GetFormattedHostName()); | 295 base::string16 url(GetFormattedHostName()); |
| 294 // Shared values for both the overridable and non-overridable versions. | 296 // Shared values for both the overridable and non-overridable versions. |
| 295 load_time_data->SetString("type", "SSL"); | 297 load_time_data->SetString("type", "SSL"); |
| 296 | 298 |
| 297 // Shared UI configuration for all SSL interstitials. | 299 // Shared UI configuration for all SSL interstitials. |
| 298 base::Time now = base::Time::NowFromSystemTime(); | |
| 299 load_time_data->SetString("errorCode", net::ErrorToString(cert_error_)); | 300 load_time_data->SetString("errorCode", net::ErrorToString(cert_error_)); |
| 300 load_time_data->SetString( | 301 load_time_data->SetString( |
| 301 "openDetails", | 302 "openDetails", |
| 302 l10n_util::GetStringUTF16(IDS_SSL_V2_OPEN_DETAILS_BUTTON)); | 303 l10n_util::GetStringUTF16(IDS_SSL_V2_OPEN_DETAILS_BUTTON)); |
| 303 load_time_data->SetString( | 304 load_time_data->SetString( |
| 304 "closeDetails", | 305 "closeDetails", |
| 305 l10n_util::GetStringUTF16(IDS_SSL_V2_CLOSE_DETAILS_BUTTON)); | 306 l10n_util::GetStringUTF16(IDS_SSL_V2_CLOSE_DETAILS_BUTTON)); |
| 306 | 307 |
| 307 // Conditional UI configuration. | 308 // Conditional UI configuration. |
| 308 if (interstitial_reason_ == SSL_REASON_BAD_CLOCK) { | 309 if (interstitial_reason_ == SSL_REASON_BAD_CLOCK) { |
| 309 load_time_data->SetBoolean("bad_clock", true); | 310 load_time_data->SetBoolean("bad_clock", true); |
| 310 load_time_data->SetBoolean("overridable", false); | 311 load_time_data->SetBoolean("overridable", false); |
| 311 | 312 |
| 312 #if defined(OS_IOS) | 313 #if defined(OS_IOS) |
| 313 load_time_data->SetBoolean("hide_primary_button", true); | 314 load_time_data->SetBoolean("hide_primary_button", true); |
| 314 #else | 315 #else |
| 315 load_time_data->SetBoolean("hide_primary_button", false); | 316 load_time_data->SetBoolean("hide_primary_button", false); |
| 316 #endif | 317 #endif |
| 317 | 318 |
| 318 // We're showing the SSL clock warning to be helpful, but we haven't warned | 319 // We're showing the SSL clock warning to be helpful, but we haven't warned |
| 319 // them about the risks. (And there might still be an SSL error after they | 320 // them about the risks. (And there might still be an SSL error after they |
| 320 // fix their clock.) Thus, we don't allow the "danger" override in this | 321 // fix their clock.) Thus, we don't allow the "danger" override in this |
| 321 // case. | 322 // case. |
| 322 danger_overridable_ = false; | 323 danger_overridable_ = false; |
| 323 | 324 |
| 324 int heading_string = SSLErrorClassification::IsUserClockInTheFuture(now) ? | 325 int heading_string = |
| 325 IDS_SSL_V2_CLOCK_AHEAD_HEADING : | 326 SSLErrorClassification::IsUserClockInTheFuture(time_triggered_) |
| 326 IDS_SSL_V2_CLOCK_BEHIND_HEADING; | 327 ? IDS_SSL_V2_CLOCK_AHEAD_HEADING |
| 328 : IDS_SSL_V2_CLOCK_BEHIND_HEADING; |
| 327 | 329 |
| 328 load_time_data->SetString( | 330 load_time_data->SetString( |
| 329 "tabTitle", | 331 "tabTitle", |
| 330 l10n_util::GetStringUTF16(IDS_SSL_V2_CLOCK_TITLE)); | 332 l10n_util::GetStringUTF16(IDS_SSL_V2_CLOCK_TITLE)); |
| 331 load_time_data->SetString( | 333 load_time_data->SetString( |
| 332 "heading", | 334 "heading", |
| 333 l10n_util::GetStringUTF16(heading_string)); | 335 l10n_util::GetStringUTF16(heading_string)); |
| 334 load_time_data->SetString("primaryParagraph", | 336 load_time_data->SetString( |
| 335 l10n_util::GetStringFUTF16( | 337 "primaryParagraph", |
| 336 IDS_SSL_V2_CLOCK_PRIMARY_PARAGRAPH , | 338 l10n_util::GetStringFUTF16( |
| 337 url, | 339 IDS_SSL_V2_CLOCK_PRIMARY_PARAGRAPH, url, |
| 338 base::TimeFormatFriendlyDateAndTime(now))); | 340 base::TimeFormatFriendlyDateAndTime(time_triggered_))); |
| 339 | 341 |
| 340 load_time_data->SetString( | 342 load_time_data->SetString( |
| 341 "primaryButtonText", | 343 "primaryButtonText", |
| 342 l10n_util::GetStringUTF16(IDS_SSL_V2_CLOCK_UPDATE_DATE_AND_TIME)); | 344 l10n_util::GetStringUTF16(IDS_SSL_V2_CLOCK_UPDATE_DATE_AND_TIME)); |
| 343 load_time_data->SetString( | 345 load_time_data->SetString( |
| 344 "explanationParagraph", | 346 "explanationParagraph", |
| 345 l10n_util::GetStringUTF16(IDS_SSL_V2_CLOCK_EXPLANATION)); | 347 l10n_util::GetStringUTF16(IDS_SSL_V2_CLOCK_EXPLANATION)); |
| 346 | 348 |
| 347 // The interstitial template expects this string, but we're not using it. So | 349 // The interstitial template expects this string, but we're not using it. So |
| 348 // we send a blank string for now. | 350 // we send a blank string for now. |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 | 421 |
| 420 // Set debugging information at the bottom of the warning. | 422 // Set debugging information at the bottom of the warning. |
| 421 load_time_data->SetString( | 423 load_time_data->SetString( |
| 422 "subject", ssl_info_.cert->subject().GetDisplayName()); | 424 "subject", ssl_info_.cert->subject().GetDisplayName()); |
| 423 load_time_data->SetString( | 425 load_time_data->SetString( |
| 424 "issuer", ssl_info_.cert->issuer().GetDisplayName()); | 426 "issuer", ssl_info_.cert->issuer().GetDisplayName()); |
| 425 load_time_data->SetString( | 427 load_time_data->SetString( |
| 426 "expirationDate", | 428 "expirationDate", |
| 427 base::TimeFormatShortDate(ssl_info_.cert->valid_expiry())); | 429 base::TimeFormatShortDate(ssl_info_.cert->valid_expiry())); |
| 428 load_time_data->SetString( | 430 load_time_data->SetString( |
| 429 "currentDate", base::TimeFormatShortDate(now)); | 431 "currentDate", base::TimeFormatShortDate(time_triggered_)); |
| 430 std::vector<std::string> encoded_chain; | 432 std::vector<std::string> encoded_chain; |
| 431 ssl_info_.cert->GetPEMEncodedChain(&encoded_chain); | 433 ssl_info_.cert->GetPEMEncodedChain( |
| 432 load_time_data->SetString("pem", JoinString(encoded_chain, std::string())); | 434 &encoded_chain); |
| 435 load_time_data->SetString( |
| 436 "pem", JoinString(encoded_chain, std::string())); |
| 433 } | 437 } |
| 434 | 438 |
| 435 void SSLBlockingPage::OverrideEntry(NavigationEntry* entry) { | 439 void SSLBlockingPage::OverrideEntry(NavigationEntry* entry) { |
| 436 int cert_id = content::CertStore::GetInstance()->StoreCert( | 440 int cert_id = content::CertStore::GetInstance()->StoreCert( |
| 437 ssl_info_.cert.get(), web_contents()->GetRenderProcessHost()->GetID()); | 441 ssl_info_.cert.get(), web_contents()->GetRenderProcessHost()->GetID()); |
| 438 DCHECK(cert_id); | 442 DCHECK(cert_id); |
| 439 | 443 |
| 440 entry->GetSSL().security_style = | 444 entry->GetSSL().security_style = |
| 441 content::SECURITY_STYLE_AUTHENTICATION_BROKEN; | 445 content::SECURITY_STYLE_AUTHENTICATION_BROKEN; |
| 442 entry->GetSSL().cert_id = cert_id; | 446 entry->GetSSL().cert_id = cert_id; |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 event_name.append(kEventNotOverridable); | 564 event_name.append(kEventNotOverridable); |
| 561 event_name.append(net::ErrorToString(cert_error_)); | 565 event_name.append(net::ErrorToString(cert_error_)); |
| 562 return event_name; | 566 return event_name; |
| 563 } | 567 } |
| 564 | 568 |
| 565 // static | 569 // static |
| 566 bool SSLBlockingPage::IsOptionsOverridable(int options_mask) { | 570 bool SSLBlockingPage::IsOptionsOverridable(int options_mask) { |
| 567 return (options_mask & SSLBlockingPage::OVERRIDABLE) && | 571 return (options_mask & SSLBlockingPage::OVERRIDABLE) && |
| 568 !(options_mask & SSLBlockingPage::STRICT_ENFORCEMENT); | 572 !(options_mask & SSLBlockingPage::STRICT_ENFORCEMENT); |
| 569 } | 573 } |
| OLD | NEW |