blob: c92ddc267b22850f46cb5edbbe96e0f5cec79ac1 [file] [log] [blame]
// 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"");
}
}