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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
65 #endif | 65 #endif |
66 | 66 |
67 using base::ASCIIToUTF16; | 67 using base::ASCIIToUTF16; |
68 using base::TimeTicks; | 68 using base::TimeTicks; |
69 using content::InterstitialPage; | 69 using content::InterstitialPage; |
70 using content::NavigationController; | 70 using content::NavigationController; |
71 using content::NavigationEntry; | 71 using content::NavigationEntry; |
72 | 72 |
73 namespace { | 73 namespace { |
74 | 74 |
75 // Constants for the M37 Finch trial. | |
76 const char kInterstitialTrialName[] = "SSLInterstitialVersion"; | |
77 const char kCondV1[] = "V1"; | |
78 const char kCondV1LayoutV2Text[] = "V1LayoutV2Text"; | |
79 const char kCondV2[] = "V2"; // Also the default. | |
80 const char kCondV2Guard[] = "V2WithGuard"; | |
81 const char kCondV2Yellow[] = "V2Yellow"; | |
82 | |
83 const char* GetTrialCondition() { | |
84 CommandLine* cli = CommandLine::ForCurrentProcess(); | |
85 if (cli->HasSwitch(switches::kSSLInterstitialV1)) | |
86 return kCondV1; | |
87 if (cli->HasSwitch(switches::kSSLInterstitialV2)) | |
88 return kCondV2; | |
89 if (cli->HasSwitch(switches::kSSLInterstitialV1WithV2Text)) | |
90 return kCondV1LayoutV2Text; | |
91 if (cli->HasSwitch(switches::kSSLInterstitialV2Guard)) | |
92 return kCondV2Guard; | |
93 if (cli->HasSwitch(switches::kSSLInterstitialV2Yellow)) | |
94 return kCondV2Yellow; | |
95 | |
96 std::string name(base::FieldTrialList::FindFullName(kInterstitialTrialName)); | |
97 if (name == kCondV1) | |
98 return kCondV1; | |
99 if (name == kCondV2) | |
100 return kCondV2; | |
101 if (name == kCondV1LayoutV2Text) | |
102 return kCondV1LayoutV2Text; | |
103 if (name == kCondV2Guard) | |
104 return kCondV2Guard; | |
105 if (name == kCondV2Yellow) | |
106 return kCondV2Yellow; | |
107 return kCondV2; | |
108 } | |
109 | |
110 // Events for UMA. Do not reorder or change! | 75 // Events for UMA. Do not reorder or change! |
111 enum SSLBlockingPageEvent { | 76 enum SSLBlockingPageEvent { |
112 SHOW_ALL, | 77 SHOW_ALL, |
113 SHOW_OVERRIDABLE, | 78 SHOW_OVERRIDABLE, |
114 PROCEED_OVERRIDABLE, | 79 PROCEED_OVERRIDABLE, |
115 PROCEED_NAME, | 80 PROCEED_NAME, |
116 PROCEED_DATE, | 81 PROCEED_DATE, |
117 PROCEED_AUTHORITY, | 82 PROCEED_AUTHORITY, |
118 DONT_PROCEED_OVERRIDABLE, | 83 DONT_PROCEED_OVERRIDABLE, |
119 DONT_PROCEED_NAME, | 84 DONT_PROCEED_NAME, |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
317 cert_error_(cert_error), | 282 cert_error_(cert_error), |
318 ssl_info_(ssl_info), | 283 ssl_info_(ssl_info), |
319 request_url_(request_url), | 284 request_url_(request_url), |
320 overridable_(overridable), | 285 overridable_(overridable), |
321 strict_enforcement_(strict_enforcement), | 286 strict_enforcement_(strict_enforcement), |
322 internal_(false), | 287 internal_(false), |
323 num_visits_(-1), | 288 num_visits_(-1), |
324 captive_portal_detection_enabled_(false), | 289 captive_portal_detection_enabled_(false), |
325 captive_portal_probe_completed_(false), | 290 captive_portal_probe_completed_(false), |
326 captive_portal_no_response_(false), | 291 captive_portal_no_response_(false), |
327 captive_portal_detected_(false), | 292 captive_portal_detected_(false) { |
328 trial_condition_(GetTrialCondition()) { | |
329 Profile* profile = Profile::FromBrowserContext( | 293 Profile* profile = Profile::FromBrowserContext( |
330 web_contents->GetBrowserContext()); | 294 web_contents->GetBrowserContext()); |
331 // For UMA stats. | 295 // For UMA stats. |
332 if (net::IsHostnameNonUnique(request_url_.HostNoBrackets())) | 296 if (net::IsHostnameNonUnique(request_url_.HostNoBrackets())) |
333 internal_ = true; | 297 internal_ = true; |
334 RecordSSLBlockingPageEventStats(SHOW_ALL); | 298 RecordSSLBlockingPageEventStats(SHOW_ALL); |
335 if (overridable_ && !strict_enforcement_) { | 299 if (overridable_ && !strict_enforcement_) { |
336 RecordSSLBlockingPageEventStats(SHOW_OVERRIDABLE); | 300 RecordSSLBlockingPageEventStats(SHOW_OVERRIDABLE); |
337 if (internal_) | 301 if (internal_) |
338 RecordSSLBlockingPageEventStats(SHOW_INTERNAL_HOSTNAME); | 302 RecordSSLBlockingPageEventStats(SHOW_INTERNAL_HOSTNAME); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
378 captive_portal_probe_completed_, | 342 captive_portal_probe_completed_, |
379 captive_portal_no_response_, | 343 captive_portal_no_response_, |
380 captive_portal_detected_); | 344 captive_portal_detected_); |
381 // The page is closed without the user having chosen what to do, default to | 345 // The page is closed without the user having chosen what to do, default to |
382 // deny. | 346 // deny. |
383 NotifyDenyCertificate(); | 347 NotifyDenyCertificate(); |
384 } | 348 } |
385 } | 349 } |
386 | 350 |
387 std::string SSLBlockingPage::GetHTMLContents() { | 351 std::string SSLBlockingPage::GetHTMLContents() { |
388 if (trial_condition_ == kCondV1 || trial_condition_ == kCondV1LayoutV2Text) | |
389 return GetHTMLContentsV1(); | |
390 return GetHTMLContentsV2(); | |
391 } | |
392 | |
393 std::string SSLBlockingPage::GetHTMLContentsV1() { | |
394 base::DictionaryValue strings; | |
395 int resource_id; | |
396 if (overridable_ && !strict_enforcement_) { | |
397 // Let's build the overridable error page. | |
398 SSLErrorInfo error_info = | |
399 SSLErrorInfo::CreateError( | |
400 SSLErrorInfo::NetErrorToErrorType(cert_error_), | |
401 ssl_info_.cert.get(), | |
402 request_url_); | |
403 resource_id = IDR_SSL_ROAD_BLOCK_HTML; | |
404 strings.SetString("textdirection", base::i18n::IsRTL() ? "rtl" : "ltr"); | |
405 strings.SetString("errorType", "overridable"); | |
406 if (trial_condition_ == kCondV1LayoutV2Text) { | |
407 base::string16 url(ASCIIToUTF16(request_url_.host())); | |
408 strings.SetString( | |
409 "headLine", l10n_util::GetStringUTF16(IDS_SSL_V2_HEADING)); | |
410 strings.SetString( | |
411 "description", | |
412 l10n_util::GetStringFUTF16(IDS_SSL_V2_PRIMARY_PARAGRAPH, url)); | |
413 strings.SetString( | |
414 "moreInfoTitle", | |
415 l10n_util::GetStringUTF16(IDS_SSL_V2_OPEN_DETAILS_BUTTON)); | |
416 strings.SetString("moreInfo1", error_info.details()); | |
417 strings.SetString("moreInfo2", base::string16()); | |
418 strings.SetString("moreInfo3", base::string16()); | |
419 strings.SetString("moreInfo4", base::string16()); | |
420 strings.SetString("moreInfo5", base::string16()); | |
421 strings.SetString( | |
422 "exit", | |
423 l10n_util::GetStringUTF16(IDS_SSL_OVERRIDABLE_SAFETY_BUTTON)); | |
424 strings.SetString( | |
425 "title", l10n_util::GetStringUTF16(IDS_SSL_V2_TITLE)); | |
426 strings.SetString( | |
427 "proceed", | |
428 l10n_util::GetStringUTF16(IDS_SSL_OVERRIDABLE_PROCEED_LINK_TEXT)); | |
429 strings.SetString("reasonForNotProceeding", base::string16()); | |
430 } else { | |
431 strings.SetString("headLine", error_info.title()); | |
432 strings.SetString("description", error_info.details()); | |
433 strings.SetString("moreInfoTitle", | |
434 l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_TITLE)); | |
435 SetExtraInfo(&strings, error_info.extra_information()); | |
436 | |
437 strings.SetString( | |
438 "exit", l10n_util::GetStringUTF16(IDS_SSL_OVERRIDABLE_PAGE_EXIT)); | |
439 strings.SetString( | |
440 "title", l10n_util::GetStringUTF16(IDS_SSL_OVERRIDABLE_PAGE_TITLE)); | |
441 strings.SetString( | |
442 "proceed", | |
443 l10n_util::GetStringUTF16(IDS_SSL_OVERRIDABLE_PAGE_PROCEED)); | |
444 strings.SetString("reasonForNotProceeding", | |
445 l10n_util::GetStringUTF16( | |
446 IDS_SSL_OVERRIDABLE_PAGE_SHOULD_NOT_PROCEED)); | |
447 } | |
448 } else { | |
449 // Let's build the blocking error page. | |
450 resource_id = IDR_SSL_BLOCKING_HTML; | |
451 | |
452 // Strings that are not dependent on the URL. | |
453 strings.SetString( | |
454 "title", l10n_util::GetStringUTF16(IDS_SSL_BLOCKING_PAGE_TITLE)); | |
455 strings.SetString( | |
456 "reloadMsg", l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_RELOAD)); | |
457 strings.SetString( | |
458 "more", l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_MORE)); | |
459 strings.SetString( | |
460 "less", l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_LESS)); | |
461 strings.SetString( | |
462 "moreTitle", | |
463 l10n_util::GetStringUTF16(IDS_SSL_BLOCKING_PAGE_MORE_TITLE)); | |
464 strings.SetString( | |
465 "techTitle", | |
466 l10n_util::GetStringUTF16(IDS_SSL_BLOCKING_PAGE_TECH_TITLE)); | |
467 | |
468 // Strings that are dependent on the URL. | |
469 base::string16 url(ASCIIToUTF16(request_url_.host())); | |
470 bool rtl = base::i18n::IsRTL(); | |
471 strings.SetString("textDirection", rtl ? "rtl" : "ltr"); | |
472 if (rtl) | |
473 base::i18n::WrapStringWithLTRFormatting(&url); | |
474 strings.SetString( | |
475 "headline", l10n_util::GetStringFUTF16(IDS_SSL_BLOCKING_PAGE_HEADLINE, | |
476 url.c_str())); | |
477 strings.SetString( | |
478 "message", l10n_util::GetStringFUTF16(IDS_SSL_BLOCKING_PAGE_BODY_TEXT, | |
479 url.c_str())); | |
480 strings.SetString( | |
481 "moreMessage", | |
482 l10n_util::GetStringFUTF16(IDS_SSL_BLOCKING_PAGE_MORE_TEXT, | |
483 url.c_str())); | |
484 strings.SetString("reloadUrl", request_url_.spec()); | |
485 | |
486 // Strings that are dependent on the error type. | |
487 SSLErrorInfo::ErrorType type = | |
488 SSLErrorInfo::NetErrorToErrorType(cert_error_); | |
489 base::string16 errorType; | |
490 if (type == SSLErrorInfo::CERT_REVOKED) { | |
491 errorType = base::string16(ASCIIToUTF16("Key revocation")); | |
492 strings.SetString( | |
493 "failure", | |
494 l10n_util::GetStringUTF16(IDS_SSL_BLOCKING_PAGE_REVOKED)); | |
495 } else if (type == SSLErrorInfo::CERT_INVALID) { | |
496 errorType = base::string16(ASCIIToUTF16("Malformed certificate")); | |
497 strings.SetString( | |
498 "failure", | |
499 l10n_util::GetStringUTF16(IDS_SSL_BLOCKING_PAGE_FORMATTED)); | |
500 } else if (type == SSLErrorInfo::CERT_PINNED_KEY_MISSING) { | |
501 errorType = base::string16(ASCIIToUTF16("Certificate pinning failure")); | |
502 strings.SetString( | |
503 "failure", | |
504 l10n_util::GetStringFUTF16(IDS_SSL_BLOCKING_PAGE_PINNING, | |
505 url.c_str())); | |
506 } else if (type == SSLErrorInfo::CERT_WEAK_KEY_DH) { | |
507 errorType = base::string16(ASCIIToUTF16("Weak DH public key")); | |
508 strings.SetString( | |
509 "failure", | |
510 l10n_util::GetStringFUTF16(IDS_SSL_BLOCKING_PAGE_WEAK_DH, | |
511 url.c_str())); | |
512 } else { | |
513 // HSTS failure. | |
514 errorType = base::string16(ASCIIToUTF16("HSTS failure")); | |
515 strings.SetString( | |
516 "failure", | |
517 l10n_util::GetStringFUTF16(IDS_SSL_BLOCKING_PAGE_HSTS, url.c_str())); | |
518 } | |
519 if (rtl) | |
520 base::i18n::WrapStringWithLTRFormatting(&errorType); | |
521 strings.SetString( | |
522 "errorType", l10n_util::GetStringFUTF16(IDS_SSL_BLOCKING_PAGE_ERROR, | |
523 errorType.c_str())); | |
524 | |
525 // Strings that display the invalid cert. | |
526 base::string16 subject( | |
527 ASCIIToUTF16(ssl_info_.cert->subject().GetDisplayName())); | |
528 base::string16 issuer( | |
529 ASCIIToUTF16(ssl_info_.cert->issuer().GetDisplayName())); | |
530 std::string hashes; | |
531 for (std::vector<net::HashValue>::const_iterator it = | |
532 ssl_info_.public_key_hashes.begin(); | |
533 it != ssl_info_.public_key_hashes.end(); | |
534 ++it) { | |
535 base::StringAppendF(&hashes, "%s ", it->ToString().c_str()); | |
536 } | |
537 base::string16 fingerprint(ASCIIToUTF16(hashes)); | |
538 if (rtl) { | |
539 // These are always going to be LTR. | |
540 base::i18n::WrapStringWithLTRFormatting(&subject); | |
541 base::i18n::WrapStringWithLTRFormatting(&issuer); | |
542 base::i18n::WrapStringWithLTRFormatting(&fingerprint); | |
543 } | |
544 strings.SetString( | |
545 "subject", l10n_util::GetStringFUTF16(IDS_SSL_BLOCKING_PAGE_SUBJECT, | |
546 subject.c_str())); | |
547 strings.SetString( | |
548 "issuer", l10n_util::GetStringFUTF16(IDS_SSL_BLOCKING_PAGE_ISSUER, | |
549 issuer.c_str())); | |
550 strings.SetString( | |
551 "fingerprint", | |
552 l10n_util::GetStringFUTF16(IDS_SSL_BLOCKING_PAGE_HASHES, | |
553 fingerprint.c_str())); | |
554 } | |
555 | |
556 base::StringPiece html( | |
557 ResourceBundle::GetSharedInstance().GetRawDataResource( | |
558 resource_id)); | |
559 return webui::GetI18nTemplateHtml(html, &strings); | |
560 } | |
561 | |
562 std::string SSLBlockingPage::GetHTMLContentsV2() { | |
563 base::DictionaryValue load_time_data; | 352 base::DictionaryValue load_time_data; |
564 base::string16 url(ASCIIToUTF16(request_url_.host())); | 353 base::string16 url(ASCIIToUTF16(request_url_.host())); |
565 if (base::i18n::IsRTL()) | 354 if (base::i18n::IsRTL()) |
566 base::i18n::WrapStringWithLTRFormatting(&url); | 355 base::i18n::WrapStringWithLTRFormatting(&url); |
567 webui::SetFontAndTextDirection(&load_time_data); | 356 webui::SetFontAndTextDirection(&load_time_data); |
568 load_time_data.SetString("trialCondition", trial_condition_); | |
569 | 357 |
570 // Shared values for both the overridable and non-overridable versions. | 358 // Shared values for both the overridable and non-overridable versions. |
571 load_time_data.SetBoolean("ssl", true); | 359 load_time_data.SetBoolean("ssl", true); |
572 load_time_data.SetBoolean( | 360 load_time_data.SetBoolean( |
573 "overridable", overridable_ && !strict_enforcement_); | 361 "overridable", overridable_ && !strict_enforcement_); |
574 load_time_data.SetString( | 362 load_time_data.SetString( |
575 "tabTitle", l10n_util::GetStringUTF16(IDS_SSL_V2_TITLE)); | 363 "tabTitle", l10n_util::GetStringUTF16(IDS_SSL_V2_TITLE)); |
576 load_time_data.SetString( | 364 load_time_data.SetString( |
577 "heading", l10n_util::GetStringUTF16(IDS_SSL_V2_HEADING)); | 365 "heading", l10n_util::GetStringUTF16(IDS_SSL_V2_HEADING)); |
578 if ((SSLErrorClassification::IsUserClockInThePast( | 366 if ((SSLErrorClassification::IsUserClockInThePast( |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
811 // sure we don't clear the captive portal flag, since the interstitial was | 599 // sure we don't clear the captive portal flag, since the interstitial was |
812 // potentially caused by the captive portal. | 600 // potentially caused by the captive portal. |
813 captive_portal_detected_ = captive_portal_detected_ || | 601 captive_portal_detected_ = captive_portal_detected_ || |
814 (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL); | 602 (results->result == captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL); |
815 // Also keep track of non-HTTP portals and error cases. | 603 // Also keep track of non-HTTP portals and error cases. |
816 captive_portal_no_response_ = captive_portal_no_response_ || | 604 captive_portal_no_response_ = captive_portal_no_response_ || |
817 (results->result == captive_portal::RESULT_NO_RESPONSE); | 605 (results->result == captive_portal::RESULT_NO_RESPONSE); |
818 } | 606 } |
819 #endif | 607 #endif |
820 } | 608 } |
OLD | NEW |