| // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ssl_blocking_page.h" |
| |
| #include "base/string_piece.h" |
| #include "chrome/browser/browser.h" |
| #include "chrome/browser/browser_resources.h" |
| #include "chrome/browser/cert_store.h" |
| #include "chrome/browser/dom_operation_notification_details.h" |
| #include "chrome/browser/navigation_controller.h" |
| #include "chrome/browser/navigation_entry.h" |
| #include "chrome/browser/ssl_error_info.h" |
| #include "chrome/browser/tab_contents.h" |
| #include "chrome/browser/web_contents.h" |
| #include "chrome/common/jstemplate_builder.h" |
| #include "chrome/common/l10n_util.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/common/pref_service.h" |
| #include "chrome/common/resource_bundle.h" |
| |
| #include "generated_resources.h" |
| |
| // Note that we always create a navigation entry with SSL errors. |
| // No error happening loading a sub-resource triggers an interstitial so far. |
| SSLBlockingPage::SSLBlockingPage(SSLManager::CertError* error, |
| Delegate* delegate) |
| : InterstitialPage(error->GetTabContents(), true, error->request_url()), |
| error_(error), |
| delegate_(delegate), |
| delegate_has_been_notified_(false) { |
| } |
| |
| SSLBlockingPage::~SSLBlockingPage() { |
| if (!delegate_has_been_notified_) { |
| // The page is closed without the user having chosen what to do, default to |
| // deny. |
| NotifyDenyCertificate(); |
| } |
| } |
| |
| std::string SSLBlockingPage::GetHTMLContents() { |
| // Let's build the html error page. |
| DictionaryValue strings; |
| SSLErrorInfo error_info = delegate_->GetSSLErrorInfo(error_); |
| strings.SetString(L"title", |
| l10n_util::GetString(IDS_SSL_BLOCKING_PAGE_TITLE)); |
| strings.SetString(L"headLine", error_info.title()); |
| strings.SetString(L"description", error_info.details()); |
| |
| strings.SetString(L"moreInfoTitle", |
| l10n_util::GetString(IDS_CERT_ERROR_EXTRA_INFO_TITLE)); |
| SetExtraInfo(&strings, error_info.extra_information()); |
| |
| strings.SetString(L"proceed", |
| l10n_util::GetString(IDS_SSL_BLOCKING_PAGE_PROCEED)); |
| strings.SetString(L"exit", |
| l10n_util::GetString(IDS_SSL_BLOCKING_PAGE_EXIT)); |
| |
| strings.SetString(L"textdirection", |
| (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) ? |
| L"rtl" : L"ltr"); |
| |
| static const StringPiece html( |
| ResourceBundle::GetSharedInstance().GetRawDataResource( |
| IDR_SSL_ROAD_BLOCK_HTML)); |
| |
| return jstemplate_builder::GetTemplateHtml(html, &strings, "template_root"); |
| } |
| |
| void SSLBlockingPage::UpdateEntry(NavigationEntry* entry) { |
| DCHECK(tab()->type() == TAB_CONTENTS_WEB); |
| WebContents* web = tab()->AsWebContents(); |
| const net::SSLInfo& ssl_info = error_->ssl_info(); |
| int cert_id = CertStore::GetSharedInstance()->StoreCert( |
| ssl_info.cert, web->render_view_host()->process()->host_id()); |
| |
| entry->ssl().set_security_style(SECURITY_STYLE_AUTHENTICATION_BROKEN); |
| entry->ssl().set_cert_id(cert_id); |
| entry->ssl().set_cert_status(ssl_info.cert_status); |
| entry->ssl().set_security_bits(ssl_info.security_bits); |
| NotificationService::current()->Notify( |
| NOTIFY_SSL_STATE_CHANGED, |
| Source<NavigationController>(web->controller()), |
| NotificationService::NoDetails()); |
| } |
| |
| void SSLBlockingPage::CommandReceived(const std::string& command) { |
| if (command == "1") { |
| Proceed(); |
| } else { |
| DontProceed(); |
| } |
| } |
| |
| void SSLBlockingPage::Proceed() { |
| // We hide the interstitial page first (by calling Proceed()) as allowing the |
| // certificate will resume the request and we want the WebContents back to |
| // showing the non interstitial page (otherwise the request completion |
| // messages may confuse the WebContents if it is still showing the |
| // interstitial page). |
| InterstitialPage::Proceed(); |
| |
| // Accepting the certificate resumes the loading of the page. |
| NotifyAllowCertificate(); |
| } |
| |
| void SSLBlockingPage::DontProceed() { |
| NotifyDenyCertificate(); |
| InterstitialPage::DontProceed(); |
| } |
| |
| |
| void SSLBlockingPage::NotifyDenyCertificate() { |
| DCHECK(!delegate_has_been_notified_); |
| |
| delegate_->OnDenyCertificate(error_); |
| delegate_has_been_notified_ = true; |
| } |
| |
| void SSLBlockingPage::NotifyAllowCertificate() { |
| DCHECK(!delegate_has_been_notified_); |
| |
| delegate_->OnAllowCertificate(error_); |
| delegate_has_been_notified_ = true; |
| } |
| |
| // static |
| void SSLBlockingPage::SetExtraInfo( |
| DictionaryValue* strings, |
| const std::vector<std::wstring>& extra_info) { |
| DCHECK(extra_info.size() < 5); // We allow 5 paragraphs max. |
| const std::wstring keys[5] = { |
| L"moreInfo1", L"moreInfo2", L"moreInfo3", L"moreInfo4", L"moreInfo5" |
| }; |
| int i; |
| for (i = 0; i < static_cast<int>(extra_info.size()); i++) { |
| strings->SetString(keys[i], extra_info[i]); |
| } |
| for (;i < 5; i++) { |
| strings->SetString(keys[i], L""); |
| } |
| } |
| |