seccomp-bpf: Remove legacy SandboxBPFPolicy class
[chromium-blink-merge.git] / chrome / browser / ssl / ssl_blocking_page.cc
blob93d94900c23ff0b75ea66cca9271678ce0959732
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/build_time.h"
8 #include "base/command_line.h"
9 #include "base/i18n/rtl.h"
10 #include "base/i18n/time_formatting.h"
11 #include "base/metrics/field_trial.h"
12 #include "base/metrics/histogram.h"
13 #include "base/process/launch.h"
14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_piece.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/time/time.h"
20 #include "base/values.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/chrome_notification_types.h"
23 #include "chrome/browser/history/history_service_factory.h"
24 #include "chrome/browser/profiles/profile.h"
25 #include "chrome/browser/renderer_preferences_util.h"
26 #include "chrome/browser/ssl/ssl_error_classification.h"
27 #include "chrome/browser/ssl/ssl_error_info.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/grit/chromium_strings.h"
30 #include "chrome/grit/generated_resources.h"
31 #include "components/google/core/browser/google_util.h"
32 #include "content/public/browser/cert_store.h"
33 #include "content/public/browser/interstitial_page.h"
34 #include "content/public/browser/navigation_controller.h"
35 #include "content/public/browser/navigation_entry.h"
36 #include "content/public/browser/notification_service.h"
37 #include "content/public/browser/notification_types.h"
38 #include "content/public/browser/render_process_host.h"
39 #include "content/public/browser/render_view_host.h"
40 #include "content/public/browser/web_contents.h"
41 #include "content/public/common/ssl_status.h"
42 #include "grit/browser_resources.h"
43 #include "net/base/hash_value.h"
44 #include "net/base/net_errors.h"
45 #include "net/base/net_util.h"
46 #include "ui/base/l10n/l10n_util.h"
47 #include "ui/base/resource/resource_bundle.h"
48 #include "ui/base/webui/jstemplate_builder.h"
49 #include "ui/base/webui/web_ui_util.h"
51 #if defined(ENABLE_EXTENSIONS)
52 #include "chrome/browser/extensions/api/experience_sampling_private/experience_sampling.h"
53 #endif
55 #if defined(OS_WIN)
56 #include "base/base_paths_win.h"
57 #include "base/path_service.h"
58 #include "base/strings/string16.h"
59 #include "base/win/windows_version.h"
60 #endif
62 #if defined(OS_CHROMEOS)
63 #include "chrome/browser/profiles/profile_manager.h"
64 #include "chrome/browser/ui/chrome_pages.h"
65 #include "chrome/common/url_constants.h"
66 #endif
68 using base::ASCIIToUTF16;
69 using base::TimeTicks;
70 using content::InterstitialPage;
71 using content::NavigationController;
72 using content::NavigationEntry;
74 #if defined(ENABLE_EXTENSIONS)
75 using extensions::ExperienceSamplingEvent;
76 #endif
78 namespace {
80 // URL for help page.
81 const char kHelpURL[] = "https://support.google.com/chrome/answer/4454607";
83 // Constants for the Experience Sampling instrumentation.
84 #if defined(ENABLE_EXTENSIONS)
85 const char kEventNameBase[] = "ssl_interstitial_";
86 const char kEventNotOverridable[] = "notoverridable_";
87 const char kEventOverridable[] = "overridable_";
88 #endif
90 // Events for UMA. Do not reorder or change!
91 enum SSLBlockingPageEvent {
92 SHOW_ALL,
93 SHOW_OVERRIDABLE,
94 PROCEED_OVERRIDABLE,
95 PROCEED_NAME,
96 PROCEED_DATE,
97 PROCEED_AUTHORITY,
98 DONT_PROCEED_OVERRIDABLE,
99 DONT_PROCEED_NAME,
100 DONT_PROCEED_DATE,
101 DONT_PROCEED_AUTHORITY,
102 MORE,
103 SHOW_UNDERSTAND, // Used by the summer 2013 Finch trial. Deprecated.
104 SHOW_INTERNAL_HOSTNAME,
105 PROCEED_INTERNAL_HOSTNAME,
106 SHOW_NEW_SITE,
107 PROCEED_NEW_SITE,
108 PROCEED_MANUAL_NONOVERRIDABLE,
109 // Captive Portal errors moved to ssl_error_classification.
110 DEPRECATED_CAPTIVE_PORTAL_DETECTION_ENABLED,
111 DEPRECATED_CAPTIVE_PORTAL_DETECTION_ENABLED_OVERRIDABLE,
112 DEPRECATED_CAPTIVE_PORTAL_PROBE_COMPLETED,
113 DEPRECATED_CAPTIVE_PORTAL_PROBE_COMPLETED_OVERRIDABLE,
114 DEPRECATED_CAPTIVE_PORTAL_NO_RESPONSE,
115 DEPRECATED_CAPTIVE_PORTAL_NO_RESPONSE_OVERRIDABLE,
116 DEPRECATED_CAPTIVE_PORTAL_DETECTED,
117 DEPRECATED_CAPTIVE_PORTAL_DETECTED_OVERRIDABLE,
118 UNUSED_BLOCKING_PAGE_EVENT,
121 // Events for UMA. Do not reorder or change!
122 enum SSLExpirationAndDecision {
123 EXPIRED_AND_PROCEED,
124 EXPIRED_AND_DO_NOT_PROCEED,
125 NOT_EXPIRED_AND_PROCEED,
126 NOT_EXPIRED_AND_DO_NOT_PROCEED,
127 END_OF_SSL_EXPIRATION_AND_DECISION,
130 void RecordSSLBlockingPageEventStats(SSLBlockingPageEvent event) {
131 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl",
132 event,
133 UNUSED_BLOCKING_PAGE_EVENT);
136 void RecordSSLExpirationPageEventState(bool expired_but_previously_allowed,
137 bool proceed,
138 bool overridable) {
139 SSLExpirationAndDecision event;
140 if (expired_but_previously_allowed && proceed)
141 event = EXPIRED_AND_PROCEED;
142 else if (expired_but_previously_allowed && !proceed)
143 event = EXPIRED_AND_DO_NOT_PROCEED;
144 else if (!expired_but_previously_allowed && proceed)
145 event = NOT_EXPIRED_AND_PROCEED;
146 else
147 event = NOT_EXPIRED_AND_DO_NOT_PROCEED;
149 if (overridable) {
150 UMA_HISTOGRAM_ENUMERATION(
151 "interstitial.ssl.expiration_and_decision.overridable",
152 event,
153 END_OF_SSL_EXPIRATION_AND_DECISION);
154 } else {
155 UMA_HISTOGRAM_ENUMERATION(
156 "interstitial.ssl.expiration_and_decision.nonoverridable",
157 event,
158 END_OF_SSL_EXPIRATION_AND_DECISION);
162 void RecordSSLBlockingPageDetailedStats(bool proceed,
163 int cert_error,
164 bool overridable,
165 bool internal,
166 int num_visits,
167 bool expired_but_previously_allowed) {
168 UMA_HISTOGRAM_ENUMERATION("interstitial.ssl_error_type",
169 SSLErrorInfo::NetErrorToErrorType(cert_error), SSLErrorInfo::END_OF_ENUM);
170 RecordSSLExpirationPageEventState(
171 expired_but_previously_allowed, proceed, overridable);
172 if (!overridable) {
173 if (proceed) {
174 RecordSSLBlockingPageEventStats(PROCEED_MANUAL_NONOVERRIDABLE);
176 // Overridable is false if the user didn't have any option except to turn
177 // back. If that's the case, don't record some of the metrics.
178 return;
180 if (num_visits == 0)
181 RecordSSLBlockingPageEventStats(SHOW_NEW_SITE);
182 if (proceed) {
183 RecordSSLBlockingPageEventStats(PROCEED_OVERRIDABLE);
184 if (internal)
185 RecordSSLBlockingPageEventStats(PROCEED_INTERNAL_HOSTNAME);
186 if (num_visits == 0)
187 RecordSSLBlockingPageEventStats(PROCEED_NEW_SITE);
188 } else if (!proceed) {
189 RecordSSLBlockingPageEventStats(DONT_PROCEED_OVERRIDABLE);
191 SSLErrorInfo::ErrorType type = SSLErrorInfo::NetErrorToErrorType(cert_error);
192 switch (type) {
193 case SSLErrorInfo::CERT_COMMON_NAME_INVALID: {
194 if (proceed)
195 RecordSSLBlockingPageEventStats(PROCEED_NAME);
196 else
197 RecordSSLBlockingPageEventStats(DONT_PROCEED_NAME);
198 break;
200 case SSLErrorInfo::CERT_DATE_INVALID: {
201 if (proceed)
202 RecordSSLBlockingPageEventStats(PROCEED_DATE);
203 else
204 RecordSSLBlockingPageEventStats(DONT_PROCEED_DATE);
205 break;
207 case SSLErrorInfo::CERT_AUTHORITY_INVALID: {
208 if (proceed)
209 RecordSSLBlockingPageEventStats(PROCEED_AUTHORITY);
210 else
211 RecordSSLBlockingPageEventStats(DONT_PROCEED_AUTHORITY);
212 break;
214 default: {
215 break;
220 void LaunchDateAndTimeSettings() {
221 #if defined(OS_CHROMEOS)
222 std::string sub_page = std::string(chrome::kSearchSubPage) + "#" +
223 l10n_util::GetStringUTF8(IDS_OPTIONS_SETTINGS_SECTION_TITLE_DATETIME);
224 chrome::ShowSettingsSubPageForProfile(
225 ProfileManager::GetActiveUserProfile(), sub_page);
226 return;
227 #elif defined(OS_ANDROID)
228 CommandLine command(base::FilePath("/system/bin/am"));
229 command.AppendArg("start");
230 command.AppendArg(
231 "'com.android.settings/.Settings$DateTimeSettingsActivity'");
232 #elif defined(OS_IOS)
233 // Apparently, iOS really does not have a way to launch the date and time
234 // settings. Weird. TODO(palmer): Do something more graceful than ignoring
235 // the user's click! crbug.com/394993
236 return;
237 #elif defined(OS_LINUX)
238 struct ClockCommand {
239 const char* pathname;
240 const char* argument;
242 static const ClockCommand kClockCommands[] = {
243 // GNOME
245 // NOTE: On old Ubuntu, naming control panels doesn't work, so it
246 // opens the overview. This will have to be good enough.
247 { "/usr/bin/gnome-control-center", "datetime" },
248 { "/usr/local/bin/gnome-control-center", "datetime" },
249 { "/opt/bin/gnome-control-center", "datetime" },
250 // KDE
251 { "/usr/bin/kcmshell4", "clock" },
252 { "/usr/local/bin/kcmshell4", "clock" },
253 { "/opt/bin/kcmshell4", "clock" },
256 CommandLine command(base::FilePath(""));
257 for (size_t i = 0; i < arraysize(kClockCommands); ++i) {
258 base::FilePath pathname(kClockCommands[i].pathname);
259 if (base::PathExists(pathname)) {
260 command.SetProgram(pathname);
261 command.AppendArg(kClockCommands[i].argument);
262 break;
265 if (command.GetProgram().empty()) {
266 // Alas, there is nothing we can do.
267 return;
269 #elif defined(OS_MACOSX)
270 CommandLine command(base::FilePath("/usr/bin/open"));
271 command.AppendArg("/System/Library/PreferencePanes/DateAndTime.prefPane");
272 #elif defined(OS_WIN)
273 base::FilePath path;
274 PathService::Get(base::DIR_SYSTEM, &path);
275 static const base::char16 kControlPanelExe[] = L"control.exe";
276 path = path.Append(base::string16(kControlPanelExe));
277 CommandLine command(path);
278 command.AppendArg(std::string("/name"));
279 command.AppendArg(std::string("Microsoft.DateAndTime"));
280 #else
281 return;
282 #endif
284 #if !defined(OS_CHROMEOS)
285 base::LaunchOptions options;
286 options.wait = false;
287 #if defined(OS_LINUX)
288 options.allow_new_privs = true;
289 #endif
290 base::LaunchProcess(command, options, NULL);
291 #endif
294 bool IsErrorDueToBadClock(const base::Time& now, int error) {
295 if (SSLErrorInfo::NetErrorToErrorType(error) !=
296 SSLErrorInfo::CERT_DATE_INVALID) {
297 return false;
299 return SSLErrorClassification::IsUserClockInThePast(now) ||
300 SSLErrorClassification::IsUserClockInTheFuture(now);
303 } // namespace
305 // Note that we always create a navigation entry with SSL errors.
306 // No error happening loading a sub-resource triggers an interstitial so far.
307 SSLBlockingPage::SSLBlockingPage(content::WebContents* web_contents,
308 int cert_error,
309 const net::SSLInfo& ssl_info,
310 const GURL& request_url,
311 int options_mask,
312 const base::Callback<void(bool)>& callback)
313 : callback_(callback),
314 web_contents_(web_contents),
315 cert_error_(cert_error),
316 ssl_info_(ssl_info),
317 request_url_(request_url),
318 overridable_(options_mask & OVERRIDABLE &&
319 !(options_mask & STRICT_ENFORCEMENT)),
320 strict_enforcement_((options_mask & STRICT_ENFORCEMENT) != 0),
321 interstitial_page_(NULL),
322 internal_(false),
323 num_visits_(-1),
324 expired_but_previously_allowed_(
325 (options_mask & EXPIRED_BUT_PREVIOUSLY_ALLOWED) != 0) {
326 Profile* profile = Profile::FromBrowserContext(
327 web_contents->GetBrowserContext());
328 // For UMA stats.
329 if (net::IsHostnameNonUnique(request_url_.HostNoBrackets()))
330 internal_ = true;
331 RecordSSLBlockingPageEventStats(SHOW_ALL);
332 if (overridable_) {
333 RecordSSLBlockingPageEventStats(SHOW_OVERRIDABLE);
334 if (internal_)
335 RecordSSLBlockingPageEventStats(SHOW_INTERNAL_HOSTNAME);
336 HistoryService* history_service = HistoryServiceFactory::GetForProfile(
337 profile, Profile::EXPLICIT_ACCESS);
338 if (history_service) {
339 history_service->GetVisibleVisitCountToHost(
340 request_url_,
341 base::Bind(&SSLBlockingPage::OnGotHistoryCount,
342 base::Unretained(this)),
343 &request_tracker_);
347 ssl_error_classification_.reset(new SSLErrorClassification(
348 web_contents_,
349 base::Time::NowFromSystemTime(),
350 request_url_,
351 cert_error_,
352 *ssl_info_.cert.get()));
353 ssl_error_classification_->RecordUMAStatistics(overridable_);
355 #if defined(ENABLE_CAPTIVE_PORTAL_DETECTION)
356 ssl_error_classification_->RecordCaptivePortalUMAStatistics(overridable_);
357 #endif
359 #if defined(ENABLE_EXTENSIONS)
360 // ExperienceSampling: Set up new sampling event for this interstitial.
361 std::string event_name(kEventNameBase);
362 if (overridable_ && !strict_enforcement_)
363 event_name.append(kEventOverridable);
364 else
365 event_name.append(kEventNotOverridable);
366 event_name.append(net::ErrorToString(cert_error_));
367 sampling_event_.reset(new ExperienceSamplingEvent(
368 event_name,
369 request_url_,
370 web_contents_->GetLastCommittedURL(),
371 web_contents_->GetBrowserContext()));
372 #endif
374 // Creating an interstitial without showing (e.g. from chrome://interstitials)
375 // it leaks memory, so don't create it here.
378 SSLBlockingPage::~SSLBlockingPage() {
379 // InvalidCommonNameSeverityScore() and InvalidDateSeverityScore() are in the
380 // destructor because they depend on knowing whether captive portal detection
381 // happened before the user made a decision.
382 SSLErrorInfo::ErrorType type =
383 SSLErrorInfo::NetErrorToErrorType(cert_error_);
384 switch (type) {
385 case SSLErrorInfo::CERT_DATE_INVALID:
386 ssl_error_classification_->InvalidDateSeverityScore();
387 break;
388 case SSLErrorInfo::CERT_COMMON_NAME_INVALID:
389 ssl_error_classification_->InvalidCommonNameSeverityScore();
390 break;
391 default:
392 break;
394 if (!callback_.is_null()) {
395 RecordSSLBlockingPageDetailedStats(false,
396 cert_error_,
397 overridable_,
398 internal_,
399 num_visits_,
400 expired_but_previously_allowed_);
401 // The page is closed without the user having chosen what to do, default to
402 // deny.
403 NotifyDenyCertificate();
407 void SSLBlockingPage::Show() {
408 DCHECK(!interstitial_page_);
409 interstitial_page_ = InterstitialPage::Create(
410 web_contents_, true, request_url_, this);
411 interstitial_page_->Show();
414 std::string SSLBlockingPage::GetHTMLContents() {
415 base::DictionaryValue load_time_data;
416 base::string16 url(ASCIIToUTF16(request_url_.host()));
417 if (base::i18n::IsRTL())
418 base::i18n::WrapStringWithLTRFormatting(&url);
419 webui::SetFontAndTextDirection(&load_time_data);
421 // Shared values for both the overridable and non-overridable versions.
422 load_time_data.SetString("type", "SSL");
423 load_time_data.SetBoolean("overridable", overridable_);
424 load_time_data.SetString(
425 "tabTitle", l10n_util::GetStringUTF16(IDS_SSL_V2_TITLE));
426 load_time_data.SetString(
427 "heading", l10n_util::GetStringUTF16(IDS_SSL_V2_HEADING));
429 base::Time now = base::Time::NowFromSystemTime();
430 bool bad_clock = IsErrorDueToBadClock(now, cert_error_);
431 if (bad_clock) {
432 load_time_data.SetString("primaryParagraph",
433 l10n_util::GetStringFUTF16(
434 IDS_SSL_CLOCK_ERROR,
435 url,
436 base::TimeFormatShortDate(now)));
437 } else {
438 load_time_data.SetString(
439 "primaryParagraph",
440 l10n_util::GetStringFUTF16(IDS_SSL_V2_PRIMARY_PARAGRAPH, url));
443 load_time_data.SetString(
444 "openDetails",
445 l10n_util::GetStringUTF16(IDS_SSL_V2_OPEN_DETAILS_BUTTON));
446 load_time_data.SetString(
447 "closeDetails",
448 l10n_util::GetStringUTF16(IDS_SSL_V2_CLOSE_DETAILS_BUTTON));
449 load_time_data.SetString("errorCode", net::ErrorToString(cert_error_));
451 if (overridable_) {
452 SSLErrorInfo error_info =
453 SSLErrorInfo::CreateError(
454 SSLErrorInfo::NetErrorToErrorType(cert_error_),
455 ssl_info_.cert.get(),
456 request_url_);
457 if (bad_clock) {
458 load_time_data.SetString("explanationParagraph",
459 l10n_util::GetStringFUTF16(
460 IDS_SSL_CLOCK_ERROR_EXPLANATION, url));
461 } else {
462 load_time_data.SetString("explanationParagraph", error_info.details());
464 load_time_data.SetString(
465 "primaryButtonText",
466 l10n_util::GetStringUTF16(IDS_SSL_OVERRIDABLE_SAFETY_BUTTON));
467 load_time_data.SetString(
468 "finalParagraph",
469 l10n_util::GetStringFUTF16(IDS_SSL_OVERRIDABLE_PROCEED_PARAGRAPH,
470 url));
471 } else {
472 SSLErrorInfo::ErrorType type =
473 SSLErrorInfo::NetErrorToErrorType(cert_error_);
474 if (type == SSLErrorInfo::CERT_INVALID && SSLErrorClassification::
475 MaybeWindowsLacksSHA256Support()) {
476 load_time_data.SetString(
477 "explanationParagraph",
478 l10n_util::GetStringFUTF16(
479 IDS_SSL_NONOVERRIDABLE_MORE_INVALID_SP3, url));
480 } else if (bad_clock) {
481 load_time_data.SetString("explanationParagraph",
482 l10n_util::GetStringFUTF16(
483 IDS_SSL_CLOCK_ERROR_EXPLANATION, url));
484 } else {
485 load_time_data.SetString("explanationParagraph",
486 l10n_util::GetStringFUTF16(
487 IDS_SSL_NONOVERRIDABLE_MORE, url));
489 load_time_data.SetString(
490 "primaryButtonText",
491 l10n_util::GetStringUTF16(IDS_SSL_NONOVERRIDABLE_RELOAD_BUTTON));
492 // Customize the help link depending on the specific error type.
493 // Only mark as HSTS if none of the more specific error types apply, and use
494 // INVALID as a fallback if no other string is appropriate.
495 load_time_data.SetInteger("errorType", type);
496 int help_string = IDS_SSL_NONOVERRIDABLE_INVALID;
497 switch (type) {
498 case SSLErrorInfo::CERT_REVOKED:
499 help_string = IDS_SSL_NONOVERRIDABLE_REVOKED;
500 break;
501 case SSLErrorInfo::CERT_PINNED_KEY_MISSING:
502 help_string = IDS_SSL_NONOVERRIDABLE_PINNED;
503 break;
504 case SSLErrorInfo::CERT_INVALID:
505 help_string = IDS_SSL_NONOVERRIDABLE_INVALID;
506 break;
507 default:
508 if (strict_enforcement_)
509 help_string = IDS_SSL_NONOVERRIDABLE_HSTS;
511 load_time_data.SetString(
512 "finalParagraph", l10n_util::GetStringFUTF16(help_string, url));
515 // Set debugging information at the bottom of the warning.
516 load_time_data.SetString(
517 "subject", ssl_info_.cert->subject().GetDisplayName());
518 load_time_data.SetString(
519 "issuer", ssl_info_.cert->issuer().GetDisplayName());
520 load_time_data.SetString(
521 "expirationDate",
522 base::TimeFormatShortDate(ssl_info_.cert->valid_expiry()));
523 load_time_data.SetString(
524 "currentDate", base::TimeFormatShortDate(now));
525 std::vector<std::string> encoded_chain;
526 ssl_info_.cert->GetPEMEncodedChain(&encoded_chain);
527 load_time_data.SetString("pem", JoinString(encoded_chain, std::string()));
529 base::StringPiece html(
530 ResourceBundle::GetSharedInstance().GetRawDataResource(
531 IDR_SECURITY_INTERSTITIAL_HTML));
532 return webui::GetI18nTemplateHtml(html, &load_time_data);
535 void SSLBlockingPage::OverrideEntry(NavigationEntry* entry) {
536 int cert_id = content::CertStore::GetInstance()->StoreCert(
537 ssl_info_.cert.get(), web_contents_->GetRenderProcessHost()->GetID());
538 DCHECK(cert_id);
540 entry->GetSSL().security_style =
541 content::SECURITY_STYLE_AUTHENTICATION_BROKEN;
542 entry->GetSSL().cert_id = cert_id;
543 entry->GetSSL().cert_status = ssl_info_.cert_status;
544 entry->GetSSL().security_bits = ssl_info_.security_bits;
547 // This handles the commands sent from the interstitial JavaScript. They are
548 // defined in chrome/browser/resources/ssl/ssl_errors_common.js.
549 // DO NOT reorder or change this logic without also changing the JavaScript!
550 void SSLBlockingPage::CommandReceived(const std::string& command) {
551 int cmd = 0;
552 bool retval = base::StringToInt(command, &cmd);
553 DCHECK(retval);
554 switch (cmd) {
555 case CMD_DONT_PROCEED: {
556 interstitial_page_->DontProceed();
557 break;
559 case CMD_PROCEED: {
560 interstitial_page_->Proceed();
561 break;
563 case CMD_MORE: {
564 RecordSSLBlockingPageEventStats(MORE);
565 #if defined(ENABLE_EXTENSIONS)
566 if (sampling_event_.get())
567 sampling_event_->set_has_viewed_details(true);
568 #endif
569 break;
571 case CMD_RELOAD: {
572 // The interstitial can't refresh itself.
573 web_contents_->GetController().Reload(true);
574 break;
576 case CMD_HELP: {
577 content::NavigationController::LoadURLParams help_page_params(
578 google_util::AppendGoogleLocaleParam(
579 GURL(kHelpURL), g_browser_process->GetApplicationLocale()));
580 #if defined(ENABLE_EXTENSIONS)
581 if (sampling_event_.get())
582 sampling_event_->set_has_viewed_learn_more(true);
583 #endif
584 web_contents_->GetController().LoadURLWithParams(help_page_params);
585 break;
587 case CMD_CLOCK: {
588 LaunchDateAndTimeSettings();
589 break;
591 default: {
592 NOTREACHED();
597 void SSLBlockingPage::OverrideRendererPrefs(
598 content::RendererPreferences* prefs) {
599 Profile* profile = Profile::FromBrowserContext(
600 web_contents_->GetBrowserContext());
601 renderer_preferences_util::UpdateFromSystemSettings(prefs, profile);
604 void SSLBlockingPage::OnProceed() {
605 RecordSSLBlockingPageDetailedStats(true,
606 cert_error_,
607 overridable_,
608 internal_,
609 num_visits_,
610 expired_but_previously_allowed_);
611 #if defined(ENABLE_EXTENSIONS)
612 // ExperienceSampling: Notify that user decided to proceed.
613 if (sampling_event_.get())
614 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kProceed);
615 #endif
617 // Accepting the certificate resumes the loading of the page.
618 NotifyAllowCertificate();
621 void SSLBlockingPage::OnDontProceed() {
622 RecordSSLBlockingPageDetailedStats(false,
623 cert_error_,
624 overridable_,
625 internal_,
626 num_visits_,
627 expired_but_previously_allowed_);
628 #if defined(ENABLE_EXTENSIONS)
629 // ExperienceSampling: Notify that user decided to not proceed.
630 // This also occurs if the user navigates away or closes the tab.
631 if (sampling_event_.get())
632 sampling_event_->CreateUserDecisionEvent(ExperienceSamplingEvent::kDeny);
633 #endif
634 NotifyDenyCertificate();
637 void SSLBlockingPage::NotifyDenyCertificate() {
638 // It's possible that callback_ may not exist if the user clicks "Proceed"
639 // followed by pressing the back button before the interstitial is hidden.
640 // In that case the certificate will still be treated as allowed.
641 if (callback_.is_null())
642 return;
644 callback_.Run(false);
645 callback_.Reset();
648 void SSLBlockingPage::NotifyAllowCertificate() {
649 DCHECK(!callback_.is_null());
651 callback_.Run(true);
652 callback_.Reset();
655 // static
656 void SSLBlockingPage::SetExtraInfo(
657 base::DictionaryValue* strings,
658 const std::vector<base::string16>& extra_info) {
659 DCHECK_LT(extra_info.size(), 5U); // We allow 5 paragraphs max.
660 const char* keys[5] = {
661 "moreInfo1", "moreInfo2", "moreInfo3", "moreInfo4", "moreInfo5"
663 int i;
664 for (i = 0; i < static_cast<int>(extra_info.size()); i++) {
665 strings->SetString(keys[i], extra_info[i]);
667 for (; i < 5; i++) {
668 strings->SetString(keys[i], std::string());
672 void SSLBlockingPage::OnGotHistoryCount(bool success,
673 int num_visits,
674 base::Time first_visit) {
675 num_visits_ = num_visits;