[email protected] | ebbbb9f | 2011-03-09 13:16:14 | [diff] [blame] | 1 | // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 4 | |
[email protected] | 3b073b2 | 2009-01-16 03:29:03 | [diff] [blame] | 5 | #include "chrome/browser/ssl/ssl_blocking_page.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 6 | |
[email protected] | 7cf1b6ce | 2010-03-20 06:37:01 | [diff] [blame] | 7 | #include "base/i18n/rtl.h" |
[email protected] | 835d7c8 | 2010-10-14 04:38:38 | [diff] [blame] | 8 | #include "base/metrics/histogram.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 9 | #include "base/string_piece.h" |
[email protected] | 9992266 | 2010-08-17 16:24:25 | [diff] [blame] | 10 | #include "base/utf_string_conversions.h" |
[email protected] | bfd04a6 | 2009-02-01 18:16:56 | [diff] [blame] | 11 | #include "base/values.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 12 | #include "chrome/browser/dom_operation_notification_details.h" |
[email protected] | 3b073b2 | 2009-01-16 03:29:03 | [diff] [blame] | 13 | #include "chrome/browser/ssl/ssl_error_info.h" |
[email protected] | 8ec2647 | 2011-06-06 16:52:45 | [diff] [blame] | 14 | #include "chrome/browser/tab_contents/tab_util.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 15 | #include "chrome/common/jstemplate_builder.h" |
[email protected] | a01efd2 | 2011-03-01 00:38:32 | [diff] [blame] | 16 | #include "content/browser/cert_store.h" |
| 17 | #include "content/browser/renderer_host/render_process_host.h" |
| 18 | #include "content/browser/renderer_host/render_view_host.h" |
[email protected] | 74b962a | 2011-06-03 21:22:54 | [diff] [blame] | 19 | #include "content/browser/ssl/ssl_cert_error_handler.h" |
[email protected] | a01efd2 | 2011-03-01 00:38:32 | [diff] [blame] | 20 | #include "content/browser/tab_contents/navigation_controller.h" |
| 21 | #include "content/browser/tab_contents/navigation_entry.h" |
| 22 | #include "content/browser/tab_contents/tab_contents.h" |
[email protected] | ebbbb9f | 2011-03-09 13:16:14 | [diff] [blame] | 23 | #include "content/common/notification_service.h" |
[email protected] | 0d6e9bd | 2011-10-18 04:29:16 | [diff] [blame^] | 24 | #include "content/public/browser/notification_types.h" |
[email protected] | 34ac8f3 | 2009-02-22 23:03:27 | [diff] [blame] | 25 | #include "grit/browser_resources.h" |
| 26 | #include "grit/generated_resources.h" |
[email protected] | c051a1b | 2011-01-21 23:30:17 | [diff] [blame] | 27 | #include "ui/base/l10n/l10n_util.h" |
[email protected] | 42ce29d | 2011-01-20 23:19:46 | [diff] [blame] | 28 | #include "ui/base/resource/resource_bundle.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 29 | |
[email protected] | 49f3d55 | 2009-05-01 00:03:49 | [diff] [blame] | 30 | namespace { |
| 31 | |
| 32 | enum SSLBlockingPageEvent { |
| 33 | SHOW, |
| 34 | PROCEED, |
| 35 | DONT_PROCEED, |
[email protected] | 2753b39 | 2009-12-28 06:59:52 | [diff] [blame] | 36 | UNUSED_ENUM, |
[email protected] | 49f3d55 | 2009-05-01 00:03:49 | [diff] [blame] | 37 | }; |
| 38 | |
| 39 | void RecordSSLBlockingPageStats(SSLBlockingPageEvent event) { |
[email protected] | 2753b39 | 2009-12-28 06:59:52 | [diff] [blame] | 40 | UMA_HISTOGRAM_ENUMERATION("interstial.ssl", event, UNUSED_ENUM); |
[email protected] | 49f3d55 | 2009-05-01 00:03:49 | [diff] [blame] | 41 | } |
| 42 | |
| 43 | } // namespace |
| 44 | |
[email protected] | cbab76d | 2008-10-13 22:42:47 | [diff] [blame] | 45 | // Note that we always create a navigation entry with SSL errors. |
| 46 | // No error happening loading a sub-resource triggers an interstitial so far. |
[email protected] | 848dd04 | 2011-06-04 18:24:03 | [diff] [blame] | 47 | SSLBlockingPage::SSLBlockingPage( |
| 48 | SSLCertErrorHandler* handler, |
| 49 | bool overridable, |
[email protected] | 8a27abf | 2011-09-30 21:59:58 | [diff] [blame] | 50 | const base::Callback<void(SSLCertErrorHandler*, bool)>& callback) |
[email protected] | 8ec2647 | 2011-06-06 16:52:45 | [diff] [blame] | 51 | : ChromeInterstitialPage( |
| 52 | tab_util::GetTabContentsByID( |
| 53 | handler->render_process_host_id(), handler->tab_contents_id()), |
| 54 | true, |
| 55 | handler->request_url()), |
[email protected] | 1d89a82f | 2009-05-14 05:46:24 | [diff] [blame] | 56 | handler_(handler), |
[email protected] | 848dd04 | 2011-06-04 18:24:03 | [diff] [blame] | 57 | callback_(callback), |
| 58 | overridable_(overridable) { |
[email protected] | 49f3d55 | 2009-05-01 00:03:49 | [diff] [blame] | 59 | RecordSSLBlockingPageStats(SHOW); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 60 | } |
| 61 | |
| 62 | SSLBlockingPage::~SSLBlockingPage() { |
[email protected] | 8a27abf | 2011-09-30 21:59:58 | [diff] [blame] | 63 | if (!callback_.is_null()) { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 64 | // The page is closed without the user having chosen what to do, default to |
| 65 | // deny. |
| 66 | NotifyDenyCertificate(); |
| 67 | } |
| 68 | } |
| 69 | |
[email protected] | cbab76d | 2008-10-13 22:42:47 | [diff] [blame] | 70 | std::string SSLBlockingPage::GetHTMLContents() { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 71 | // Let's build the html error page. |
| 72 | DictionaryValue strings; |
[email protected] | 848dd04 | 2011-06-04 18:24:03 | [diff] [blame] | 73 | SSLErrorInfo error_info = SSLErrorInfo::CreateError( |
| 74 | SSLErrorInfo::NetErrorToErrorType(handler_->cert_error()), |
| 75 | handler_->ssl_info().cert, handler_->request_url()); |
| 76 | |
[email protected] | 42197a2 | 2010-12-28 23:29:42 | [diff] [blame] | 77 | strings.SetString("headLine", error_info.title()); |
| 78 | strings.SetString("description", error_info.details()); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 79 | |
[email protected] | 9992266 | 2010-08-17 16:24:25 | [diff] [blame] | 80 | strings.SetString("moreInfoTitle", |
| 81 | l10n_util::GetStringUTF16(IDS_CERT_ERROR_EXTRA_INFO_TITLE)); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 82 | SetExtraInfo(&strings, error_info.extra_information()); |
| 83 | |
[email protected] | faf9cd6 | 2010-04-20 19:17:58 | [diff] [blame] | 84 | int resource_id; |
[email protected] | 848dd04 | 2011-06-04 18:24:03 | [diff] [blame] | 85 | if (overridable_) { |
[email protected] | faf9cd6 | 2010-04-20 19:17:58 | [diff] [blame] | 86 | resource_id = IDR_SSL_ROAD_BLOCK_HTML; |
[email protected] | 9992266 | 2010-08-17 16:24:25 | [diff] [blame] | 87 | strings.SetString("title", |
| 88 | l10n_util::GetStringUTF16(IDS_SSL_BLOCKING_PAGE_TITLE)); |
| 89 | strings.SetString("proceed", |
| 90 | l10n_util::GetStringUTF16(IDS_SSL_BLOCKING_PAGE_PROCEED)); |
| 91 | strings.SetString("exit", |
| 92 | l10n_util::GetStringUTF16(IDS_SSL_BLOCKING_PAGE_EXIT)); |
[email protected] | faf9cd6 | 2010-04-20 19:17:58 | [diff] [blame] | 93 | } else { |
[email protected] | faf9cd6 | 2010-04-20 19:17:58 | [diff] [blame] | 94 | resource_id = IDR_SSL_ERROR_HTML; |
[email protected] | 9992266 | 2010-08-17 16:24:25 | [diff] [blame] | 95 | strings.SetString("title", |
| 96 | l10n_util::GetStringUTF16(IDS_SSL_ERROR_PAGE_TITLE)); |
| 97 | strings.SetString("back", |
| 98 | l10n_util::GetStringUTF16(IDS_SSL_ERROR_PAGE_BACK)); |
[email protected] | faf9cd6 | 2010-04-20 19:17:58 | [diff] [blame] | 99 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 100 | |
[email protected] | 9992266 | 2010-08-17 16:24:25 | [diff] [blame] | 101 | strings.SetString("textdirection", base::i18n::IsRTL() ? "rtl" : "ltr"); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 102 | |
[email protected] | faf9cd6 | 2010-04-20 19:17:58 | [diff] [blame] | 103 | base::StringPiece html( |
| 104 | ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id)); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 105 | |
[email protected] | 7cd22a5 | 2009-07-14 00:40:25 | [diff] [blame] | 106 | return jstemplate_builder::GetI18nTemplateHtml(html, &strings); |
[email protected] | cbab76d | 2008-10-13 22:42:47 | [diff] [blame] | 107 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 108 | |
[email protected] | cbab76d | 2008-10-13 22:42:47 | [diff] [blame] | 109 | void SSLBlockingPage::UpdateEntry(NavigationEntry* entry) { |
[email protected] | 1d89a82f | 2009-05-14 05:46:24 | [diff] [blame] | 110 | const net::SSLInfo& ssl_info = handler_->ssl_info(); |
[email protected] | 8e8bb6d | 2010-12-13 08:18:55 | [diff] [blame] | 111 | int cert_id = CertStore::GetInstance()->StoreCert( |
[email protected] | 76543b9 | 2009-08-31 17:27:45 | [diff] [blame] | 112 | ssl_info.cert, tab()->render_view_host()->process()->id()); |
[email protected] | ecd9d870 | 2008-08-28 22:10:17 | [diff] [blame] | 113 | |
[email protected] | e9ba447 | 2008-09-14 15:42:43 | [diff] [blame] | 114 | entry->ssl().set_security_style(SECURITY_STYLE_AUTHENTICATION_BROKEN); |
| 115 | entry->ssl().set_cert_id(cert_id); |
| 116 | entry->ssl().set_cert_status(ssl_info.cert_status); |
| 117 | entry->ssl().set_security_bits(ssl_info.security_bits); |
| 118 | NotificationService::current()->Notify( |
[email protected] | 43211582 | 2011-07-10 15:52:27 | [diff] [blame] | 119 | content::NOTIFICATION_SSL_VISIBLE_STATE_CHANGED, |
[email protected] | 57c6a65 | 2009-05-04 07:58:34 | [diff] [blame] | 120 | Source<NavigationController>(&tab()->controller()), |
[email protected] | e9ba447 | 2008-09-14 15:42:43 | [diff] [blame] | 121 | NotificationService::NoDetails()); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 122 | } |
| 123 | |
[email protected] | cbab76d | 2008-10-13 22:42:47 | [diff] [blame] | 124 | void SSLBlockingPage::CommandReceived(const std::string& command) { |
| 125 | if (command == "1") { |
| 126 | Proceed(); |
| 127 | } else { |
| 128 | DontProceed(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 129 | } |
| 130 | } |
| 131 | |
| 132 | void SSLBlockingPage::Proceed() { |
[email protected] | 49f3d55 | 2009-05-01 00:03:49 | [diff] [blame] | 133 | RecordSSLBlockingPageStats(PROCEED); |
| 134 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 135 | // Accepting the certificate resumes the loading of the page. |
| 136 | NotifyAllowCertificate(); |
[email protected] | a3a1d14 | 2008-12-19 00:42:30 | [diff] [blame] | 137 | |
| 138 | // This call hides and deletes the interstitial. |
| 139 | InterstitialPage::Proceed(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 140 | } |
| 141 | |
| 142 | void SSLBlockingPage::DontProceed() { |
[email protected] | 49f3d55 | 2009-05-01 00:03:49 | [diff] [blame] | 143 | RecordSSLBlockingPageStats(DONT_PROCEED); |
| 144 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 145 | NotifyDenyCertificate(); |
[email protected] | cbab76d | 2008-10-13 22:42:47 | [diff] [blame] | 146 | InterstitialPage::DontProceed(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 147 | } |
| 148 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 149 | void SSLBlockingPage::NotifyDenyCertificate() { |
[email protected] | 0d5f3307 | 2011-09-03 05:03:23 | [diff] [blame] | 150 | // It's possible that callback_ may not exist if the user clicks "Proceed" |
| 151 | // followed by pressing the back button before the interstitial is hidden. |
| 152 | // In that case the certificate will still be treated as allowed. |
[email protected] | 8a27abf | 2011-09-30 21:59:58 | [diff] [blame] | 153 | if (callback_.is_null()) |
[email protected] | 0d5f3307 | 2011-09-03 05:03:23 | [diff] [blame] | 154 | return; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 155 | |
[email protected] | 8a27abf | 2011-09-30 21:59:58 | [diff] [blame] | 156 | callback_.Run(handler_, false); |
| 157 | callback_.Reset(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 158 | } |
| 159 | |
| 160 | void SSLBlockingPage::NotifyAllowCertificate() { |
[email protected] | 8a27abf | 2011-09-30 21:59:58 | [diff] [blame] | 161 | DCHECK(!callback_.is_null()); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 162 | |
[email protected] | 8a27abf | 2011-09-30 21:59:58 | [diff] [blame] | 163 | callback_.Run(handler_, true); |
| 164 | callback_.Reset(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 165 | } |
| 166 | |
| 167 | // static |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 168 | void SSLBlockingPage::SetExtraInfo( |
| 169 | DictionaryValue* strings, |
[email protected] | 42197a2 | 2010-12-28 23:29:42 | [diff] [blame] | 170 | const std::vector<string16>& extra_info) { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 171 | DCHECK(extra_info.size() < 5); // We allow 5 paragraphs max. |
[email protected] | 9992266 | 2010-08-17 16:24:25 | [diff] [blame] | 172 | const char* keys[5] = { |
| 173 | "moreInfo1", "moreInfo2", "moreInfo3", "moreInfo4", "moreInfo5" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 174 | }; |
| 175 | int i; |
| 176 | for (i = 0; i < static_cast<int>(extra_info.size()); i++) { |
[email protected] | 42197a2 | 2010-12-28 23:29:42 | [diff] [blame] | 177 | strings->SetString(keys[i], extra_info[i]); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 178 | } |
[email protected] | 9992266 | 2010-08-17 16:24:25 | [diff] [blame] | 179 | for (; i < 5; i++) { |
| 180 | strings->SetString(keys[i], ""); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 181 | } |
| 182 | } |