1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/ssl/ssl_blocking_page.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/i18n/rtl.h" 8731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "base/metrics/histogram.h" 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_piece.h" 103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/values.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/dom_operation_notification_details.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/ssl/ssl_cert_error_handler.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/ssl/ssl_error_info.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/jstemplate_builder.h" 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/cert_store.h" 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_process_host.h" 18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h" 19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_controller.h" 20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/navigation_entry.h" 21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h" 22ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "content/common/notification_service.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/browser_resources.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h" 2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h" 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/resource/resource_bundle.h" 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace { 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum SSLBlockingPageEvent { 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SHOW, 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch PROCEED, 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DONT_PROCEED, 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UNUSED_ENUM, 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid RecordSSLBlockingPageStats(SSLBlockingPageEvent event) { 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch UMA_HISTOGRAM_ENUMERATION("interstial.ssl", event, UNUSED_ENUM); 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Note that we always create a navigation entry with SSL errors. 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// No error happening loading a sub-resource triggers an interstitial so far. 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSSLBlockingPage::SSLBlockingPage(SSLCertErrorHandler* handler, 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Delegate* delegate, 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ErrorLevel error_level) 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : InterstitialPage(handler->GetTabContents(), true, handler->request_url()), 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch handler_(handler), 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delegate_(delegate), 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delegate_has_been_notified_(false), 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch error_level_(error_level) { 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RecordSSLBlockingPageStats(SHOW); 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochSSLBlockingPage::~SSLBlockingPage() { 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!delegate_has_been_notified_) { 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The page is closed without the user having chosen what to do, default to 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // deny. 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyDenyCertificate(); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::string SSLBlockingPage::GetHTMLContents() { 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Let's build the html error page. 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue strings; 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SSLErrorInfo error_info = delegate_->GetSSLErrorInfo(handler_); 683f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen strings.SetString("headLine", error_info.title()); 693f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen strings.SetString("description", error_info.details()); 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick strings.SetString("moreInfoTitle", 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_TITLE)); 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetExtraInfo(&strings, error_info.extra_information()); 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int resource_id; 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (error_level_ == ERROR_OVERRIDABLE) { 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch resource_id = IDR_SSL_ROAD_BLOCK_HTML; 783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick strings.SetString("title", 793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_SSL_BLOCKING_PAGE_TITLE)); 803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick strings.SetString("proceed", 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_SSL_BLOCKING_PAGE_PROCEED)); 823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick strings.SetString("exit", 833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_SSL_BLOCKING_PAGE_EXIT)); 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK_EQ(error_level_, ERROR_FATAL); 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch resource_id = IDR_SSL_ERROR_HTML; 873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick strings.SetString("title", 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_SSL_ERROR_PAGE_TITLE)); 893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick strings.SetString("back", 903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick l10n_util::GetStringUTF16(IDS_SSL_ERROR_PAGE_BACK)); 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick strings.SetString("textdirection", base::i18n::IsRTL() ? "rtl" : "ltr"); 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch base::StringPiece html( 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id)); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return jstemplate_builder::GetI18nTemplateHtml(html, &strings); 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLBlockingPage::UpdateEntry(NavigationEntry* entry) { 102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const net::SSLInfo& ssl_info = handler_->ssl_info(); 10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen int cert_id = CertStore::GetInstance()->StoreCert( 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ssl_info.cert, tab()->render_view_host()->process()->id()); 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry->ssl().set_security_style(SECURITY_STYLE_AUTHENTICATION_BROKEN); 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry->ssl().set_cert_id(cert_id); 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry->ssl().set_cert_status(ssl_info.cert_status); 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch entry->ssl().set_security_bits(ssl_info.security_bits); 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::current()->Notify( 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationType::SSL_VISIBLE_STATE_CHANGED, 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Source<NavigationController>(&tab()->controller()), 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotificationService::NoDetails()); 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLBlockingPage::CommandReceived(const std::string& command) { 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (command == "1") { 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Proceed(); 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DontProceed(); 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLBlockingPage::Proceed() { 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RecordSSLBlockingPageStats(PROCEED); 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Accepting the certificate resumes the loading of the page. 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyAllowCertificate(); 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // This call hides and deletes the interstitial. 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InterstitialPage::Proceed(); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLBlockingPage::DontProceed() { 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch RecordSSLBlockingPageStats(DONT_PROCEED); 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch NotifyDenyCertificate(); 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InterstitialPage::DontProceed(); 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLBlockingPage::NotifyDenyCertificate() { 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!delegate_has_been_notified_); 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delegate_->OnDenyCertificate(handler_); 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delegate_has_been_notified_ = true; 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLBlockingPage::NotifyAllowCertificate() { 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(!delegate_has_been_notified_); 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delegate_->OnAllowCertificate(handler_); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch delegate_has_been_notified_ = true; 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid SSLBlockingPage::SetExtraInfo( 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DictionaryValue* strings, 1583f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen const std::vector<string16>& extra_info) { 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DCHECK(extra_info.size() < 5); // We allow 5 paragraphs max. 1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const char* keys[5] = { 1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick "moreInfo1", "moreInfo2", "moreInfo3", "moreInfo4", "moreInfo5" 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch }; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int i; 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch for (i = 0; i < static_cast<int>(extra_info.size()); i++) { 1653f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen strings->SetString(keys[i], extra_info[i]); 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick for (; i < 5; i++) { 1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick strings->SetString(keys[i], ""); 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 171