Revert "Reland c91b178b07b0d - Delete dead signin code (SigninGlobalError)"
[chromium-blink-merge.git] / chrome / browser / ssl / ssl_blocking_page.cc
blob55dfb486d71ca1b7ea1137494c4f5388815b69a0
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
3 // found in the LICENSE file.
5 #include "chrome/browser/ssl/ssl_blocking_page.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/build_time.h"
10 #include "base/callback_helpers.h"
11 #include "base/command_line.h"
12 #include "base/i18n/rtl.h"
13 #include "base/i18n/time_formatting.h"
14 #include "base/metrics/histogram.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/process/launch.h"
17 #include "base/rand_util.h"
18 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_piece.h"
20 #include "base/strings/string_util.h"
21 #include "base/strings/stringprintf.h"
22 #include "base/strings/utf_string_conversions.h"
23 #include "base/time/time.h"
24 #include "base/values.h"
25 #include "chrome/browser/browser_process.h"
26 #include "chrome/browser/chrome_notification_types.h"
27 #include "chrome/browser/interstitials/chrome_metrics_helper.h"
28 #include "chrome/browser/profiles/profile.h"
29 #include "chrome/browser/renderer_preferences_util.h"
30 #include "chrome/browser/ssl/cert_report_helper.h"
31 #include "chrome/browser/ssl/certificate_error_report.h"
32 #include "chrome/browser/ssl/ssl_cert_reporter.h"
33 #include "chrome/browser/ssl/ssl_error_classification.h"
34 #include "chrome/browser/ssl/ssl_error_info.h"
35 #include "chrome/common/chrome_switches.h"
36 #include "chrome/common/pref_names.h"
37 #include "chrome/grit/chromium_strings.h"
38 #include "chrome/grit/generated_resources.h"
39 #include "components/google/core/browser/google_util.h"
40 #include "content/public/browser/browser_thread.h"
41 #include "content/public/browser/cert_store.h"
42 #include "content/public/browser/interstitial_page.h"
43 #include "content/public/browser/interstitial_page_delegate.h"
44 #include "content/public/browser/navigation_controller.h"
45 #include "content/public/browser/navigation_entry.h"
46 #include "content/public/browser/notification_service.h"
47 #include "content/public/browser/notification_types.h"
48 #include "content/public/browser/render_process_host.h"
49 #include "content/public/browser/render_view_host.h"
50 #include "content/public/browser/web_contents.h"
51 #include "content/public/common/renderer_preferences.h"
52 #include "content/public/common/ssl_status.h"
53 #include "grit/browser_resources.h"
54 #include "net/base/hash_value.h"
55 #include "net/base/net_errors.h"
56 #include "net/base/net_util.h"
57 #include "ui/base/l10n/l10n_util.h"
59 #if defined(OS_WIN)
60 #include "base/base_paths_win.h"
61 #include "base/path_service.h"
62 #include "base/strings/string16.h"
63 #include "base/win/windows_version.h"
64 #endif
66 #if defined(OS_ANDROID)
67 #include "chrome/browser/android/intent_helper.h"
68 #endif
70 #if defined(OS_CHROMEOS)
71 #include "chrome/browser/profiles/profile_manager.h"
72 #include "chrome/browser/ui/chrome_pages.h"
73 #include "chrome/common/url_constants.h"
74 #endif
76 using base::ASCIIToUTF16;
77 using base::TimeTicks;
78 using content::InterstitialPage;
79 using content::InterstitialPageDelegate;
80 using content::NavigationController;
81 using content::NavigationEntry;
83 namespace {
85 // URL for help page.
86 const char kHelpURL[] = "https://support.google.com/chrome/answer/4454607";
88 // Constants for the Experience Sampling instrumentation.
89 const char kEventNameBase[] = "ssl_interstitial_";
90 const char kEventNotOverridable[] = "notoverridable_";
91 const char kEventOverridable[] = "overridable_";
93 // Events for UMA. Do not reorder or change!
94 enum SSLExpirationAndDecision {
95 EXPIRED_AND_PROCEED,
96 EXPIRED_AND_DO_NOT_PROCEED,
97 NOT_EXPIRED_AND_PROCEED,
98 NOT_EXPIRED_AND_DO_NOT_PROCEED,
99 END_OF_SSL_EXPIRATION_AND_DECISION,
102 // Rappor prefix
103 const char kSSLRapporPrefix[] = "ssl2";
105 void RecordSSLExpirationPageEventState(bool expired_but_previously_allowed,
106 bool proceed,
107 bool overridable) {
108 SSLExpirationAndDecision event;
109 if (expired_but_previously_allowed && proceed)
110 event = EXPIRED_AND_PROCEED;
111 else if (expired_but_previously_allowed && !proceed)
112 event = EXPIRED_AND_DO_NOT_PROCEED;
113 else if (!expired_but_previously_allowed && proceed)
114 event = NOT_EXPIRED_AND_PROCEED;
115 else
116 event = NOT_EXPIRED_AND_DO_NOT_PROCEED;
118 if (overridable) {
119 UMA_HISTOGRAM_ENUMERATION(
120 "interstitial.ssl.expiration_and_decision.overridable",
121 event,
122 END_OF_SSL_EXPIRATION_AND_DECISION);
123 } else {
124 UMA_HISTOGRAM_ENUMERATION(
125 "interstitial.ssl.expiration_and_decision.nonoverridable",
126 event,
127 END_OF_SSL_EXPIRATION_AND_DECISION);
131 void LaunchDateAndTimeSettings() {
132 DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
133 // The code for each OS is completely separate, in order to avoid bugs like
134 // https://crbug.com/430877 .
135 #if defined(OS_ANDROID)
136 chrome::android::OpenDateAndTimeSettings();
138 #elif defined(OS_CHROMEOS)
139 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" +
140 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME);
141 chrome::ShowSettingsSubPageForProfile(
142 ProfileManager::GetActiveUserProfile(), sub_page);
144 #elif defined(OS_IOS)
145 // iOS does not have a way to launch the date and time settings.
146 NOTREACHED();
148 #elif defined(OS_LINUX)
149 struct ClockCommand {
150 const char* pathname;
151 const char* argument;
153 static const ClockCommand kClockCommands[] = {
154 // Unity
155 { "/usr/bin/unity-control-center", "datetime" },
156 // GNOME
158 // NOTE: On old Ubuntu, naming control panels doesn't work, so it
159 // opens the overview. This will have to be good enough.
160 { "/usr/bin/gnome-control-center", "datetime" },
161 { "/usr/local/bin/gnome-control-center", "datetime" },
162 { "/opt/bin/gnome-control-center", "datetime" },
163 // KDE
164 { "/usr/bin/kcmshell4", "clock" },
165 { "/usr/local/bin/kcmshell4", "clock" },
166 { "/opt/bin/kcmshell4", "clock" },
169 base::CommandLine command(base::FilePath(""));
170 for (size_t i = 0; i < arraysize(kClockCommands); ++i) {
171 base::FilePath pathname(kClockCommands[i].pathname);
172 if (base::PathExists(pathname)) {
173 command.SetProgram(pathname);
174 command.AppendArg(kClockCommands[i].argument);
175 break;
178 if (command.GetProgram().empty()) {
179 // Alas, there is nothing we can do.
180 return;
183 base::LaunchOptions options;
184 options.wait = false;
185 options.allow_new_privs = true;
186 base::LaunchProcess(command, options);
188 #elif defined(OS_MACOSX)
189 base::CommandLine command(base::FilePath("/usr/bin/open"));
190 command.AppendArg("/System/Library/PreferencePanes/DateAndTime.prefPane");
192 base::LaunchOptions options;
193 options.wait = false;
194 base::LaunchProcess(command, options);
196 #elif defined(OS_WIN)
197 base::FilePath path;
198 PathService::Get(base::DIR_SYSTEM, &path);
199 static const base::char16 kControlPanelExe[] = L"control.exe";
200 path = path.Append(base::string16(kControlPanelExe));
201 base::CommandLine command(path);
202 command.AppendArg(std::string("/name"));
203 command.AppendArg(std::string("Microsoft.DateAndTime"));
205 base::LaunchOptions options;
206 options.wait = false;
207 base::LaunchProcess(command, options);
209 #else
210 NOTREACHED();
212 #endif
213 // Don't add code here! (See the comment at the beginning of the function.)
216 bool IsErrorDueToBadClock(const base::Time& now, int error) {
217 if (SSLErrorInfo::NetErrorToErrorType(error) !=
218 SSLErrorInfo::CERT_DATE_INVALID) {
219 return false;
221 return SSLErrorClassification::IsUserClockInThePast(now) ||
222 SSLErrorClassification::IsUserClockInTheFuture(now);
225 } // namespace
227 // static
228 InterstitialPageDelegate::TypeID SSLBlockingPage::kTypeForTesting =
229 &SSLBlockingPage::kTypeForTesting;
231 // Note that we always create a navigation entry with SSL errors.
232 // No error happening loading a sub-resource triggers an interstitial so far.
233 SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents,
234 int cert_error,
235 const net::SSLInfo& ssl_info,
236 const GURL& request_url,
237 int options_mask,
238 const base::Time& time_triggered,
239 scoped_ptr<SSLCertReporter> ssl_cert_reporter,
240 const base::Callback<void(bool)>& callback)
241 : SecurityInterstitialPage(web_contents, request_url),
242 callback_(callback),
243 cert_error_(cert_error),
244 ssl_info_(ssl_info),
245 overridable_(IsOverridable(
246 options_mask,
247 Profile::FromBrowserContext(web_contents->GetBrowserContext()))),
248 danger_overridable_(DoesPolicyAllowDangerOverride(
249 Profile::FromBrowserContext(web_contents->GetBrowserContext()))),
250 strict_enforcement_((options_mask & STRICT_ENFORCEMENT) != 0),
251 expired_but_previously_allowed_(
252 (options_mask & EXPIRED_BUT_PREVIOUSLY_ALLOWED) != 0),
253 time_triggered_(time_triggered) {
254 interstitial_reason_ =
255 IsErrorDueToBadClock(time_triggered_, cert_error_) ?
256 SSL_REASON_BAD_CLOCK : SSL_REASON_SSL;
258 // We collapse the Rappor metric name to just "ssl" so we don't leak
259 // the "overridable" bit. We skip Rappor altogether for bad clocks.
260 // This must be done after calculating |interstitial_reason_| above.
261 security_interstitials::MetricsHelper::ReportDetails reporting_info;
262 reporting_info.metric_prefix = GetUmaHistogramPrefix();
263 reporting_info.rappor_prefix = kSSLRapporPrefix;
264 if (interstitial_reason_ != SSL_REASON_BAD_CLOCK)
265 reporting_info.rappor_report_type = rappor::UMA_RAPPOR_TYPE;
266 set_metrics_helper(new ChromeMetricsHelper(
267 web_contents, request_url, reporting_info, GetSamplingEventName()));
268 metrics_helper()->RecordUserDecision(
269 security_interstitials::MetricsHelper::SHOW);
270 metrics_helper()->RecordUserInteraction(
271 security_interstitials::MetricsHelper::TOTAL_VISITS);
273 cert_report_helper_.reset(new CertReportHelper(
274 ssl_cert_reporter.Pass(), web_contents, request_url, ssl_info,
275 GetCertReportInterstitialReason(), overridable_, metrics_helper()));
277 ssl_error_classification_.reset(new SSLErrorClassification(
278 web_contents,
279 time_triggered_,
280 request_url,
281 cert_error_,
282 *ssl_info_.cert.get()));
283 ssl_error_classification_->RecordUMAStatistics(overridable_);
285 // Creating an interstitial without showing (e.g. from chrome://interstitials)
286 // it leaks memory, so don't create it here.
289 bool SSLBlockingPage::ShouldCreateNewNavigation() const {
290 return true;
293 InterstitialPageDelegate::TypeID SSLBlockingPage::GetTypeForTesting() const {
294 return SSLBlockingPage::kTypeForTesting;
297 SSLBlockingPage::~SSLBlockingPage() {
298 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
299 // Captive portal detection results can arrive anytime during the interstitial
300 // is being displayed, so record it when the interstitial is going away.
301 ssl_error_classification_->RecordCaptivePortalUMAStatistics(overridable_);
302 #endif
303 if (!callback_.is_null()) {
304 // The page is closed without the user having chosen what to do, default to
305 // deny.
306 metrics_helper()->RecordUserDecision(
307 security_interstitials::MetricsHelper::DONT_PROCEED);
308 RecordSSLExpirationPageEventState(
309 expired_but_previously_allowed_, false, overridable_);
310 NotifyDenyCertificate();
314 void SSLBlockingPage::PopulateInterstitialStrings(
315 base::DictionaryValue* load_time_data) {
316 CHECK(load_time_data);
317 base::string16 url(GetFormattedHostName());
318 // Shared values for both the overridable and non-overridable versions.
319 load_time_data->SetString("type", "SSL");
321 // Shared UI configuration for all SSL interstitials.
322 load_time_data->SetString("errorCode", net::ErrorToString(cert_error_));
323 load_time_data->SetString(
324 "openDetails",
325 l10n_util::GetStringUTF16(IDS_SSL_V2_OPEN_DETAILS_BUTTON));
326 load_time_data->SetString(
327 "closeDetails",
328 l10n_util::GetStringUTF16(IDS_SSL_V2_CLOSE_DETAILS_BUTTON));
330 // Conditional UI configuration.
331 if (interstitial_reason_ == SSL_REASON_BAD_CLOCK) {
332 load_time_data->SetBoolean("bad_clock", true);
333 load_time_data->SetBoolean("overridable", false);
335 #if defined(OS_IOS)
336 load_time_data->SetBoolean("hide_primary_button", true);
337 #else
338 load_time_data->SetBoolean("hide_primary_button", false);
339 #endif
341 // We're showing the SSL clock warning to be helpful, but we haven't warned
342 // them about the risks. (And there might still be an SSL error after they
343 // fix their clock.) Thus, we don't allow the "danger" override in this
344 // case.
345 danger_overridable_ = false;
347 int heading_string =
348 SSLErrorClassification::IsUserClockInTheFuture(time_triggered_) ?
349 IDS_SSL_V2_CLOCK_AHEAD_HEADING :
350 IDS_SSL_V2_CLOCK_BEHIND_HEADING;
352 load_time_data->SetString(
353 "tabTitle",
354 l10n_util::GetStringUTF16(IDS_SSL_V2_CLOCK_TITLE));
355 load_time_data->SetString(
356 "heading",
357 l10n_util::GetStringUTF16(heading_string));
358 load_time_data->SetString(
359 "primaryParagraph",
360 l10n_util::GetStringFUTF16(
361 IDS_SSL_V2_CLOCK_PRIMARY_PARAGRAPH,
362 url,
363 base::TimeFormatFriendlyDateAndTime(time_triggered_)));
365 load_time_data->SetString(
366 "primaryButtonText",
367 l10n_util::GetStringUTF16(IDS_SSL_V2_CLOCK_UPDATE_DATE_AND_TIME));
368 load_time_data->SetString(
369 "explanationParagraph",
370 l10n_util::GetStringUTF16(IDS_SSL_V2_CLOCK_EXPLANATION));
372 // The interstitial template expects this string, but we're not using it. So
373 // we send a blank string for now.
374 load_time_data->SetString("finalParagraph", std::string());
375 } else {
376 load_time_data->SetBoolean("bad_clock", false);
378 load_time_data->SetString(
379 "tabTitle", l10n_util::GetStringUTF16(IDS_SSL_V2_TITLE));
380 load_time_data->SetString(
381 "heading", l10n_util::GetStringUTF16(IDS_SSL_V2_HEADING));
382 load_time_data->SetString(
383 "primaryParagraph",
384 l10n_util::GetStringFUTF16(IDS_SSL_V2_PRIMARY_PARAGRAPH, url));
386 if (overridable_) {
387 load_time_data->SetBoolean("overridable", true);
389 SSLErrorInfo error_info =
390 SSLErrorInfo::CreateError(
391 SSLErrorInfo::NetErrorToErrorType(cert_error_),
392 ssl_info_.cert.get(),
393 request_url());
394 load_time_data->SetString("explanationParagraph", error_info.details());
395 load_time_data->SetString(
396 "primaryButtonText",
397 l10n_util::GetStringUTF16(IDS_SSL_OVERRIDABLE_SAFETY_BUTTON));
398 load_time_data->SetString(
399 "finalParagraph",
400 l10n_util::GetStringFUTF16(IDS_SSL_OVERRIDABLE_PROCEED_PARAGRAPH,
401 url));
402 } else {
403 load_time_data->SetBoolean("overridable", false);
405 SSLErrorInfo::ErrorType type =
406 SSLErrorInfo::NetErrorToErrorType(cert_error_);
407 if (type == SSLErrorInfo::CERT_INVALID && SSLErrorClassification::
408 MaybeWindowsLacksSHA256Support()) {
409 load_time_data->SetString(
410 "explanationParagraph",
411 l10n_util::GetStringFUTF16(
412 IDS_SSL_NONOVERRIDABLE_MORE_INVALID_SP3, url));
413 } else {
414 load_time_data->SetString("explanationParagraph",
415 l10n_util::GetStringFUTF16(
416 IDS_SSL_NONOVERRIDABLE_MORE, url));
418 load_time_data->SetString(
419 "primaryButtonText",
420 l10n_util::GetStringUTF16(IDS_SSL_RELOAD));
421 // Customize the help link depending on the specific error type.
422 // Only mark as HSTS if none of the more specific error types apply,
423 // and use INVALID as a fallback if no other string is appropriate.
424 load_time_data->SetInteger("errorType", type);
425 int help_string = IDS_SSL_NONOVERRIDABLE_INVALID;
426 switch (type) {
427 case SSLErrorInfo::CERT_REVOKED:
428 help_string = IDS_SSL_NONOVERRIDABLE_REVOKED;
429 break;
430 case SSLErrorInfo::CERT_PINNED_KEY_MISSING:
431 help_string = IDS_SSL_NONOVERRIDABLE_PINNED;
432 break;
433 case SSLErrorInfo::CERT_INVALID:
434 help_string = IDS_SSL_NONOVERRIDABLE_INVALID;
435 break;
436 default:
437 if (strict_enforcement_)
438 help_string = IDS_SSL_NONOVERRIDABLE_HSTS;
440 load_time_data->SetString(
441 "finalParagraph", l10n_util::GetStringFUTF16(help_string, url));
445 // Set debugging information at the bottom of the warning.
446 load_time_data->SetString(
447 "subject", ssl_info_.cert->subject().GetDisplayName());
448 load_time_data->SetString(
449 "issuer", ssl_info_.cert->issuer().GetDisplayName());
450 load_time_data->SetString(
451 "expirationDate",
452 base::TimeFormatShortDate(ssl_info_.cert->valid_expiry()));
453 load_time_data->SetString(
454 "currentDate", base::TimeFormatShortDate(time_triggered_));
455 std::vector<std::string> encoded_chain;
456 ssl_info_.cert->GetPEMEncodedChain(
457 &encoded_chain);
458 load_time_data->SetString(
459 "pem", base::JoinString(encoded_chain, base::StringPiece()));
461 cert_report_helper_->PopulateExtendedReportingOption(load_time_data);
464 void SSLBlockingPage::OverrideEntry(NavigationEntry* entry) {
465 int cert_id = content::CertStore::GetInstance()->StoreCert(
466 ssl_info_.cert.get(), web_contents()->GetRenderProcessHost()->GetID());
467 DCHECK(cert_id);
469 entry->GetSSL().security_style =
470 content::SECURITY_STYLE_AUTHENTICATION_BROKEN;
471 entry->GetSSL().cert_id = cert_id;
472 entry->GetSSL().cert_status = ssl_info_.cert_status;
473 entry->GetSSL().security_bits = ssl_info_.security_bits;
476 void SSLBlockingPage::SetSSLCertReporterForTesting(
477 scoped_ptr<SSLCertReporter> ssl_cert_reporter) {
478 cert_report_helper_->SetSSLCertReporterForTesting(ssl_cert_reporter.Pass());
481 // This handles the commands sent from the interstitial JavaScript.
482 // DO NOT reorder or change this logic without also changing the JavaScript!
483 void SSLBlockingPage::CommandReceived(const std::string& command) {
484 if (command == "\"pageLoadComplete\"") {
485 // content::WaitForRenderFrameReady sends this message when the page
486 // load completes. Ignore it.
487 return;
490 int cmd = 0;
491 bool retval = base::StringToInt(command, &cmd);
492 DCHECK(retval);
493 switch (cmd) {
494 case CMD_DONT_PROCEED: {
495 interstitial_page()->DontProceed();
496 break;
498 case CMD_PROCEED: {
499 if (danger_overridable_) {
500 interstitial_page()->Proceed();
502 break;
504 case CMD_DO_REPORT: {
505 SetReportingPreference(true);
506 break;
508 case CMD_DONT_REPORT: {
509 SetReportingPreference(false);
510 break;
512 case CMD_SHOW_MORE_SECTION: {
513 metrics_helper()->RecordUserInteraction(
514 security_interstitials::MetricsHelper::SHOW_ADVANCED);
515 break;
517 case CMD_OPEN_HELP_CENTER: {
518 metrics_helper()->RecordUserInteraction(
519 security_interstitials::MetricsHelper::SHOW_LEARN_MORE);
520 content::NavigationController::LoadURLParams help_page_params(
521 google_util::AppendGoogleLocaleParam(
522 GURL(kHelpURL), g_browser_process->GetApplicationLocale()));
523 web_contents()->GetController().LoadURLWithParams(help_page_params);
524 break;
526 case CMD_RELOAD: {
527 metrics_helper()->RecordUserInteraction(
528 security_interstitials::MetricsHelper::RELOAD);
529 // The interstitial can't refresh itself.
530 web_contents()->GetController().Reload(true);
531 break;
533 case CMD_OPEN_DATE_SETTINGS: {
534 metrics_helper()->RecordUserInteraction(
535 security_interstitials::MetricsHelper::OPEN_TIME_SETTINGS);
536 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
537 base::Bind(&LaunchDateAndTimeSettings));
538 break;
540 case CMD_OPEN_REPORTING_PRIVACY:
541 OpenExtendedReportingPrivacyPolicy();
542 break;
543 case CMD_OPEN_DIAGNOSTIC:
544 // Google doesn't currently have a transparency report for SSL.
545 NOTREACHED() << "Unexpected command: " << command;
549 void SSLBlockingPage::OverrideRendererPrefs(
550 content::RendererPreferences* prefs) {
551 Profile* profile = Profile::FromBrowserContext(
552 web_contents()->GetBrowserContext());
553 renderer_preferences_util::UpdateFromSystemSettings(
554 prefs, profile, web_contents());
557 void SSLBlockingPage::OnProceed() {
558 metrics_helper()->RecordUserDecision(
559 security_interstitials::MetricsHelper::PROCEED);
561 // Finish collecting information about invalid certificates, if the
562 // user opted in to.
563 cert_report_helper_->FinishCertCollection(
564 CertificateErrorReport::USER_PROCEEDED);
566 RecordSSLExpirationPageEventState(
567 expired_but_previously_allowed_, true, overridable_);
568 // Accepting the certificate resumes the loading of the page.
569 NotifyAllowCertificate();
572 void SSLBlockingPage::OnDontProceed() {
573 metrics_helper()->RecordUserDecision(
574 security_interstitials::MetricsHelper::DONT_PROCEED);
576 // Finish collecting information about invalid certificates, if the
577 // user opted in to.
578 cert_report_helper_->FinishCertCollection(
579 CertificateErrorReport::USER_DID_NOT_PROCEED);
581 RecordSSLExpirationPageEventState(
582 expired_but_previously_allowed_, false, overridable_);
583 NotifyDenyCertificate();
586 void SSLBlockingPage::NotifyDenyCertificate() {
587 // It's possible that callback_ may not exist if the user clicks "Proceed"
588 // followed by pressing the back button before the interstitial is hidden.
589 // In that case the certificate will still be treated as allowed.
590 if (callback_.is_null())
591 return;
593 callback_.Run(false);
594 callback_.Reset();
597 void SSLBlockingPage::NotifyAllowCertificate() {
598 DCHECK(!callback_.is_null());
600 callback_.Run(true);
601 callback_.Reset();
604 CertificateErrorReport::InterstitialReason
605 SSLBlockingPage::GetCertReportInterstitialReason() {
606 switch (interstitial_reason_) {
607 case SSL_REASON_SSL:
608 return CertificateErrorReport::INTERSTITIAL_SSL;
609 case SSL_REASON_BAD_CLOCK:
610 return CertificateErrorReport::INTERSTITIAL_CLOCK;
613 NOTREACHED();
614 return CertificateErrorReport::INTERSTITIAL_SSL;
617 std::string SSLBlockingPage::GetUmaHistogramPrefix() const {
618 switch (interstitial_reason_) {
619 case SSL_REASON_SSL:
620 if (overridable_)
621 return "ssl_overridable";
622 else
623 return "ssl_nonoverridable";
624 case SSL_REASON_BAD_CLOCK:
625 return "bad_clock";
627 NOTREACHED();
628 return std::string();
631 std::string SSLBlockingPage::GetSamplingEventName() const {
632 std::string event_name(kEventNameBase);
633 if (overridable_)
634 event_name.append(kEventOverridable);
635 else
636 event_name.append(kEventNotOverridable);
637 event_name.append(net::ErrorToString(cert_error_));
638 return event_name;
641 // static
642 bool SSLBlockingPage::IsOverridable(int options_mask,
643 const Profile* const profile) {
644 const bool is_overridable =
645 (options_mask & SSLBlockingPage::OVERRIDABLE) &&
646 !(options_mask & SSLBlockingPage::STRICT_ENFORCEMENT) &&
647 profile->GetPrefs()->GetBoolean(prefs::kSSLErrorOverrideAllowed);
648 return is_overridable;
651 // static
652 bool SSLBlockingPage::DoesPolicyAllowDangerOverride(
653 const Profile* const profile) {
654 return profile->GetPrefs()->GetBoolean(prefs::kSSLErrorOverrideAllowed);