summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/automation/automation_provider.cc113
-rw-r--r--chrome/browser/automation/automation_provider.h28
-rw-r--r--chrome/browser/automation/automation_tab_tracker.h47
-rw-r--r--chrome/browser/navigation_controller.cc1
-rw-r--r--chrome/browser/navigation_controller.h4
-rw-r--r--chrome/browser/provisional_load_details.cc6
-rw-r--r--chrome/browser/provisional_load_details.h6
-rw-r--r--chrome/browser/ssl_manager.cc68
-rw-r--r--chrome/browser/ssl_manager.h32
-rw-r--r--chrome/browser/ssl_policy.cc35
-rw-r--r--chrome/browser/ssl_uitest.cc439
-rw-r--r--chrome/browser/web_contents.cc4
12 files changed, 699 insertions, 84 deletions
diff --git a/chrome/browser/automation/automation_provider.cc b/chrome/browser/automation/automation_provider.cc
index 4c1ed49..8c2da33 100644
--- a/chrome/browser/automation/automation_provider.cc
+++ b/chrome/browser/automation/automation_provider.cc
@@ -21,11 +21,13 @@
#include "chrome/browser/navigation_entry.h"
#include "chrome/browser/printing/print_job.h"
#include "chrome/browser/render_view_host.h"
+#include "chrome/browser/ssl_manager.h"
#include "chrome/browser/ssl_blocking_page.h"
#include "chrome/browser/web_contents.h"
#include "chrome/browser/views/bookmark_bar_view.h"
#include "chrome/browser/views/location_bar_view.h"
#include "chrome/common/chrome_paths.h"
+#include "chrome/common/pref_service.h"
#include "chrome/test/automation/automation_messages.h"
#include "net/base/cookie_monster.h"
#include "net/url_request/url_request_filter.h"
@@ -182,7 +184,6 @@ class NavigationControllerRestoredObserver : public NotificationObserver {
DISALLOW_COPY_AND_ASSIGN(NavigationControllerRestoredObserver);
};
-
class NavigationNotificationObserver : public NotificationObserver {
public:
NavigationNotificationObserver(NavigationController* controller,
@@ -195,6 +196,8 @@ class NavigationNotificationObserver : public NotificationObserver {
controller_(controller),
navigation_started_(false) {
NotificationService* service = NotificationService::current();
+ service->AddObserver(this, NOTIFY_NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(controller_));
service->AddObserver(this, NOTIFY_LOAD_START,
Source<NavigationController>(controller_));
service->AddObserver(this, NOTIFY_LOAD_STOP,
@@ -222,6 +225,8 @@ class NavigationNotificationObserver : public NotificationObserver {
void Unregister() {
NotificationService* service = NotificationService::current();
+ service->RemoveObserver(this, NOTIFY_NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(controller_));
service->RemoveObserver(this, NOTIFY_LOAD_START,
Source<NavigationController>(controller_));
service->RemoveObserver(this, NOTIFY_LOAD_STOP,
@@ -235,7 +240,14 @@ class NavigationNotificationObserver : public NotificationObserver {
virtual void Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
- if (type == NOTIFY_LOAD_START) {
+ // We listen for 2 events to determine when the navigation started because:
+ // - when this is used by the WaitForNavigation method, we might be invoked
+ // afer the load has started (but not after the entry was committed, as
+ // WaitForNavigation compares times of the last navigation).
+ // - when this is used with a page requiring authentication, we will not get
+ // a NOTIFY_NAV_ENTRY_COMMITTED until after we authenticate, so we need the
+ // NOTIFY_LOAD_START.
+ if (type == NOTIFY_NAV_ENTRY_COMMITTED || type == NOTIFY_LOAD_START) {
navigation_started_ = true;
} else if (type == NOTIFY_LOAD_STOP) {
if (navigation_started_) {
@@ -758,6 +770,16 @@ void AutomationProvider::OnMessageReceived(const IPC::Message& message) {
HandleFindWindowLocationRequest)
IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibilityRequest,
GetBookmarkBarVisitility)
+ IPC_MESSAGE_HANDLER(AutomationMsg_GetSSLInfoBarCountRequest,
+ GetSSLInfoBarCount)
+ IPC_MESSAGE_HANDLER(AutomationMsg_ClickSSLInfoBarLinkRequest,
+ ClickSSLInfoBarLink)
+ IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTimeRequest,
+ GetLastNavigationTime)
+ IPC_MESSAGE_HANDLER(AutomationMsg_WaitForNavigationRequest,
+ WaitForNavigation)
+ IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreferenceRequest,
+ SetIntPreference)
IPC_END_MESSAGE_MAP()
}
@@ -2294,3 +2316,90 @@ void TestingAutomationProvider::Observe(NotificationType type,
void TestingAutomationProvider::OnRemoveProvider() {
AutomationProviderList::GetInstance()->RemoveProvider(this);
}
+
+void AutomationProvider::GetSSLInfoBarCount(const IPC::Message& message,
+ int handle) {
+ int count = -1; // -1 means error.
+ if (tab_tracker_->ContainsHandle(handle)) {
+ NavigationController* nav_controller = tab_tracker_->GetResource(handle);
+ if (nav_controller) {
+ count = static_cast<int>(nav_controller->ssl_manager()->
+ visible_info_bars_.size());
+ }
+ }
+ Send(new AutomationMsg_GetSSLInfoBarCountResponse(message.routing_id(),
+ count));
+}
+
+void AutomationProvider::ClickSSLInfoBarLink(const IPC::Message& message,
+ int handle,
+ int info_bar_index,
+ bool wait_for_navigation) {
+ bool success = false;
+ if (tab_tracker_->ContainsHandle(handle)) {
+ NavigationController* nav_controller = tab_tracker_->GetResource(handle);
+ if (nav_controller) {
+ int count = static_cast<int>(nav_controller->ssl_manager()->
+ visible_info_bars_.size());
+ if (info_bar_index >= 0 && info_bar_index < count) {
+ if (wait_for_navigation) {
+ AddNavigationStatusListener(nav_controller,
+ new AutomationMsg_ClickSSLInfoBarLinkResponse(
+ message.routing_id(), true),
+ new AutomationMsg_ClickSSLInfoBarLinkResponse(
+ message.routing_id(), true));
+ }
+ SSLManager::SSLInfoBar* info_bar =
+ nav_controller->ssl_manager()->visible_info_bars_.
+ GetElementAt(info_bar_index);
+ info_bar->LinkActivated(NULL, 0); // Parameters are not used.
+ success = true;
+ }
+ }
+ }
+ if (!wait_for_navigation || !success)
+ Send(new AutomationMsg_ClickSSLInfoBarLinkResponse(message.routing_id(),
+ success));
+}
+
+void AutomationProvider::GetLastNavigationTime(const IPC::Message& message,
+ int handle) {
+ Time time = tab_tracker_->GetLastNavigationTime(handle);
+ Send(new AutomationMsg_GetLastNavigationTimeResponse(message.routing_id(),
+ time.ToInternalValue()));
+}
+
+void AutomationProvider::WaitForNavigation(const IPC::Message& message,
+ int handle,
+ int64 last_navigation_time) {
+ NavigationController* controller = NULL;
+ if (tab_tracker_->ContainsHandle(handle))
+ controller = tab_tracker_->GetResource(handle);
+
+ Time time = tab_tracker_->GetLastNavigationTime(handle);
+ if (time.ToInternalValue() > last_navigation_time || !controller) {
+ Send(new AutomationMsg_WaitForNavigationResponse(message.routing_id(),
+ controller != NULL));
+ return;
+ }
+
+ AddNavigationStatusListener(controller,
+ new AutomationMsg_WaitForNavigationResponse(message.routing_id(),
+ true),
+ new AutomationMsg_WaitForNavigationResponse(message.routing_id(),
+ true));
+}
+
+void AutomationProvider::SetIntPreference(const IPC::Message& message,
+ int handle,
+ std::wstring name,
+ int value) {
+ bool success = false;
+ if (browser_tracker_->ContainsHandle(handle)) {
+ Browser* browser = browser_tracker_->GetResource(handle);
+ browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
+ success = true;
+ }
+ Send(new AutomationMsg_SetIntPreferenceResponse(message.routing_id(),
+ success));
+}
diff --git a/chrome/browser/automation/automation_provider.h b/chrome/browser/automation/automation_provider.h
index 674565c..d67615f 100644
--- a/chrome/browser/automation/automation_provider.h
+++ b/chrome/browser/automation/automation_provider.h
@@ -294,7 +294,7 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
// Retrieves if a query to an autocomplete provider is in progress.
void AutocompleteEditIsQueryInProgress(const IPC::Message& message,
- int autocomplete_edit_handle);
+ int autocomplete_edit_handle);
// Retrieves the individual autocomplete matches displayed by the popup.
void AutocompleteEditGetMatches(const IPC::Message& message,
@@ -304,6 +304,32 @@ class AutomationProvider : public base::RefCounted<AutomationProvider>,
void OnMessageFromExternalHost(int handle, const std::string& target,
const std::string& message);
+ // Retrieves the number of SSL related info-bars currently showing in |count|.
+ void GetSSLInfoBarCount(const IPC::Message& message, int handle);
+
+ // Causes a click on the link of the info-bar at |info_bar_index|. If
+ // |wait_for_navigation| is true, it sends the reply after a navigation has
+ // occurred.
+ void ClickSSLInfoBarLink(const IPC::Message& message,
+ int handle,
+ int info_bar_index,
+ bool wait_for_navigation);
+
+ // Retrieves the last time a navigation occurred for the tab.
+ void GetLastNavigationTime(const IPC::Message& message, int handle);
+
+ // Waits for a new navigation in the tab if none has happened since
+ // |last_navigation_time|.
+ void WaitForNavigation(const IPC::Message& message,
+ int handle,
+ int64 last_navigation_time);
+
+ // Sets the int value for preference with name |name|.
+ void SetIntPreference(const IPC::Message& message,
+ int handle,
+ std::wstring name,
+ int value);
+
// Convert a tab handle into a WebContents. If |tab| is non-NULL a pointer
// to the tab is also returned. Returns NULL in case of failure or if the tab
// is not of the WebContents type.
diff --git a/chrome/browser/automation/automation_tab_tracker.h b/chrome/browser/automation/automation_tab_tracker.h
index 5cda520..bb9ac24 100644
--- a/chrome/browser/automation/automation_tab_tracker.h
+++ b/chrome/browser/automation/automation_tab_tracker.h
@@ -28,6 +28,11 @@ public:
NotificationService::current()->AddObserver(
this, NOTIFY_EXTERNAL_TAB_CLOSED,
Source<NavigationController>(resource));
+ // We also want to know about navigations so we can keep track of the last
+ // navigation time.
+ NotificationService::current()->AddObserver(
+ this, NOTIFY_NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(resource));
}
virtual void RemoveObserver(NavigationController* resource) {
@@ -36,7 +41,49 @@ public:
NotificationService::current()->RemoveObserver(
this, NOTIFY_EXTERNAL_TAB_CLOSED,
Source<NavigationController>(resource));
+ NotificationService::current()->RemoveObserver(
+ this, NOTIFY_NAV_ENTRY_COMMITTED,
+ Source<NavigationController>(resource));
+ }
+
+ virtual void Observe(NotificationType type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ switch (type) {
+ case NOTIFY_NAV_ENTRY_COMMITTED:
+ last_navigation_times_[Source<NavigationController>(source).ptr()] =
+ Time::Now();
+ return;
+ case NOTIFY_EXTERNAL_TAB_CLOSED:
+ case NOTIFY_TAB_CLOSING:
+ std::map<NavigationController*, Time>::iterator iter =
+ last_navigation_times_.find(
+ Source<NavigationController>(source).ptr());
+ if (iter != last_navigation_times_.end())
+ last_navigation_times_.erase(iter);
+ break;
+ }
+ AutomationResourceTracker::Observe(type, source, details);
+ }
+
+ Time GetLastNavigationTime(int handle) {
+ if (ContainsHandle(handle)) {
+ NavigationController* controller = GetResource(handle);
+ if (controller) {
+ std::map<NavigationController*, Time>::const_iterator iter =
+ last_navigation_times_.find(controller);
+ if (iter != last_navigation_times_.end())
+ return iter->second;
+ }
+ }
+ return Time();
}
+
+ private:
+ // Last time a navigation occurred.
+ std::map<NavigationController*, Time> last_navigation_times_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutomationTabTracker);
};
#endif // CHROME_BROWSER_AUTOMATION_AUTOMATION_TAB_TRACKER_H__
diff --git a/chrome/browser/navigation_controller.cc b/chrome/browser/navigation_controller.cc
index ae5a9b8..91c1fb4 100644
--- a/chrome/browser/navigation_controller.cc
+++ b/chrome/browser/navigation_controller.cc
@@ -561,6 +561,7 @@ bool NavigationController::RendererDidNavigate(
details->is_main_frame = PageTransition::IsMainFrame(params.transition);
details->is_interstitial = is_interstitial;
details->serialized_security_info = params.security_info;
+ details->is_content_filtered = params.is_content_filtered;
NotifyNavigationEntryCommitted(details);
// It is now a safe time to schedule collection for any tab contents of a
diff --git a/chrome/browser/navigation_controller.h b/chrome/browser/navigation_controller.h
index 0e1b5919..7d99876 100644
--- a/chrome/browser/navigation_controller.h
+++ b/chrome/browser/navigation_controller.h
@@ -79,6 +79,10 @@ class NavigationController {
// won't care about interstitial loads.
bool is_interstitial;
+ // Whether the content of this frame has been altered/blocked because it was
+ // unsafe.
+ bool is_content_filtered;
+
// When the committed load is a web page from the renderer, this string
// specifies the security state if the page is secure.
// See ViewHostMsg_FrameNavigate_Params.security_info, where it comes from.
diff --git a/chrome/browser/provisional_load_details.cc b/chrome/browser/provisional_load_details.cc
index 274ecf8..f7a9f89 100644
--- a/chrome/browser/provisional_load_details.cc
+++ b/chrome/browser/provisional_load_details.cc
@@ -11,12 +11,14 @@ ProvisionalLoadDetails::ProvisionalLoadDetails(bool is_main_frame,
bool is_interstitial_page,
bool is_in_page_navigation,
const GURL& url,
- const std::string& security_info)
+ const std::string& security_info,
+ bool is_content_filtered)
: is_main_frame_(is_main_frame),
is_interstitial_page_(is_interstitial_page),
is_in_page_navigation_(is_in_page_navigation),
url_(url),
- error_code_(net::OK) {
+ error_code_(net::OK),
+ is_content_filtered_(is_content_filtered) {
SSLManager::DeserializeSecurityInfo(security_info,
&ssl_cert_id_,
&ssl_cert_status_,
diff --git a/chrome/browser/provisional_load_details.h b/chrome/browser/provisional_load_details.h
index 2c342c1..9f63acb 100644
--- a/chrome/browser/provisional_load_details.h
+++ b/chrome/browser/provisional_load_details.h
@@ -23,7 +23,8 @@ class ProvisionalLoadDetails {
bool interstitial_page,
bool in_page_navigation,
const GURL& url,
- const std::string& security_info);
+ const std::string& security_info,
+ bool is_filtered);
virtual ~ProvisionalLoadDetails() { }
void set_error_code(int error_code) { error_code_ = error_code; };
@@ -43,6 +44,8 @@ class ProvisionalLoadDetails {
int ssl_security_bits() const { return ssl_security_bits_; }
+ bool is_content_filtered() const { return is_content_filtered_; }
+
private:
int error_code_;
GURL url_;
@@ -52,6 +55,7 @@ class ProvisionalLoadDetails {
int ssl_cert_id_;
int ssl_cert_status_;
int ssl_security_bits_;
+ bool is_content_filtered_;
DISALLOW_EVIL_CONSTRUCTORS(ProvisionalLoadDetails);
};
diff --git a/chrome/browser/ssl_manager.cc b/chrome/browser/ssl_manager.cc
index 0d03c3e..94bc42e 100644
--- a/chrome/browser/ssl_manager.cc
+++ b/chrome/browser/ssl_manager.cc
@@ -35,40 +35,10 @@
#include "webkit/glue/resource_type.h"
#include "generated_resources.h"
-////////////////////////////////////////////////////////////////////////////////
-// SSLInfoBar
-//
-// An info bar with a message and an optional link that runs a task when
-// clicked.
-
-class SSLInfoBar : public InfoBarItemView,
- public ChromeViews::LinkController {
- public:
- SSLInfoBar::SSLInfoBar(SSLManager* manager,
- const std::wstring& message,
- const std::wstring& link_text,
- Task* task);
-
- virtual SSLInfoBar::~SSLInfoBar();
-
- const std::wstring GetMessageText() const;
-
- // ChromeViews::LinkController method.
- virtual void LinkActivated(ChromeViews::Link* source, int event_flags);
-
- private:
- ChromeViews::Label* label_;
- ChromeViews::Link* link_;
- SSLManager* manager_;
- scoped_ptr<Task> task_;
-
- DISALLOW_COPY_AND_ASSIGN(SSLInfoBar);
-};
-
-SSLInfoBar::SSLInfoBar(SSLManager* manager,
- const std::wstring& message,
- const std::wstring& link_text,
- Task* task)
+SSLManager::SSLInfoBar::SSLInfoBar(SSLManager* manager,
+ const std::wstring& message,
+ const std::wstring& link_text,
+ Task* task)
: label_(NULL),
link_(NULL),
manager_(manager),
@@ -94,19 +64,20 @@ SSLInfoBar::SSLInfoBar(SSLManager* manager,
DCHECK(manager);
}
-SSLInfoBar::~SSLInfoBar() {
+SSLManager::SSLInfoBar::~SSLInfoBar() {
// Notify our manager that we no longer exist.
manager_->OnInfoBarClose(this);
}
-const std::wstring SSLInfoBar::GetMessageText() const {
+const std::wstring SSLManager::SSLInfoBar::GetMessageText() const {
if (!label_)
return std::wstring();
return label_->GetText();
}
-void SSLInfoBar::LinkActivated(ChromeViews::Link* source, int event_flags) {
+void SSLManager::SSLInfoBar::LinkActivated(ChromeViews::Link* source,
+ int event_flags) {
if (task_.get()) {
task_->Run();
task_.reset(); // Ensures we won't run the task again.
@@ -643,10 +614,27 @@ void SSLManager::DidCommitProvisionalLoad(
// An HTTPS response may not have a certificate for some reason. When that
// happens, use the unauthenticated (HTTP) rather than the authentication
// broken security style so that we can detect this error condition.
- if (net::IsCertStatusError(ssl_cert_status))
+ if (net::IsCertStatusError(ssl_cert_status)) {
changed |= SetMaxSecurityStyle(SECURITY_STYLE_AUTHENTICATION_BROKEN);
- else if (details->entry->url().SchemeIsSecure() && !ssl_cert_id)
- changed |= SetMaxSecurityStyle(SECURITY_STYLE_UNAUTHENTICATED);
+ if (!details->is_main_frame &&
+ !details->entry->ssl().has_unsafe_content()) {
+ details->entry->ssl().set_has_unsafe_content();
+ changed = true;
+ }
+ } else if (details->entry->url().SchemeIsSecure() && !ssl_cert_id) {
+ if (details->is_main_frame) {
+ changed |= SetMaxSecurityStyle(SECURITY_STYLE_UNAUTHENTICATED);
+ } else {
+ // If the frame has been blocked we keep our security style as
+ // authenticated in that case as nothing insecure is actually showing or
+ // loaded.
+ if (!details->is_content_filtered &&
+ !details->entry->ssl().has_mixed_content()) {
+ details->entry->ssl().set_has_mixed_content();
+ changed = true;
+ }
+ }
+ }
if (changed) {
// Only send the notification when something actually changed.
diff --git a/chrome/browser/ssl_manager.h b/chrome/browser/ssl_manager.h
index f0409b7..a5f466f 100644
--- a/chrome/browser/ssl_manager.h
+++ b/chrome/browser/ssl_manager.h
@@ -18,6 +18,7 @@
#include "chrome/common/notification_registrar.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/render_messages.h"
+#include "chrome/views/link.h"
#include "googleurl/src/gurl.h"
#include "net/base/net_errors.h"
#include "net/base/ssl_info.h"
@@ -25,6 +26,7 @@
#include "webkit/glue/console_message_level.h"
#include "webkit/glue/resource_type.h"
+class AutomationProvider;
class InfoBarItemView;
class NavigationEntry;
class LoadFromMemoryCacheDetails;
@@ -34,7 +36,6 @@ class PrefService;
class ResourceRedirectDetails;
class ResourceRequestDetails;
class SSLErrorInfo;
-class SSLInfoBar;
class TabContents;
class Task;
class URLRequest;
@@ -261,6 +262,32 @@ class SSLManager : public NotificationObserver {
virtual SecurityStyle GetDefaultStyle(const GURL& url) = 0;
};
+ // An info bar with a message and an optional link that runs a task when
+ // clicked.
+ class SSLInfoBar : public InfoBarItemView,
+ public ChromeViews::LinkController {
+ public:
+ SSLInfoBar(SSLManager* manager,
+ const std::wstring& message,
+ const std::wstring& link_text,
+ Task* task);
+
+ virtual ~SSLInfoBar();
+
+ const std::wstring GetMessageText() const;
+
+ // ChromeViews::LinkController method.
+ virtual void LinkActivated(ChromeViews::Link* source, int event_flags);
+
+ private:
+ ChromeViews::Label* label_;
+ ChromeViews::Link* link_;
+ SSLManager* manager_;
+ scoped_ptr<Task> task_;
+
+ DISALLOW_COPY_AND_ASSIGN(SSLInfoBar);
+ };
+
static void RegisterUserPrefs(PrefService* prefs);
// Construct an SSLManager for the specified tab.
@@ -400,6 +427,9 @@ class SSLManager : public NotificationObserver {
std::wstring* ca_name);
private:
+ // The AutomationProvider needs to access the InfoBars.
+ friend class AutomationProvider;
+
// SSLMessageInfo contains the information necessary for displaying a message
// in an info-bar.
struct SSLMessageInfo {
diff --git a/chrome/browser/ssl_policy.cc b/chrome/browser/ssl_policy.cc
index d75b895..a93b31d 100644
--- a/chrome/browser/ssl_policy.cc
+++ b/chrome/browser/ssl_policy.cc
@@ -318,7 +318,21 @@ class DefaultPolicy : public SSLPolicy {
mixed_content_handler->StartRequest(filter_policy);
NavigationEntry* entry = navigation_controller->GetActiveEntry();
- entry->ssl().set_has_mixed_content();
+ // Even though we are loading the mixed-content resource, it will not be
+ // included in the page when we set the policy to FILTER_ALL or
+ // FILTER_ALL_EXCEPT_IMAGES (only images and they are stamped with warning
+ // icons), so we don't set the mixed-content mode in these cases.
+ if (filter_policy == FilterPolicy::DONT_FILTER)
+ entry->ssl().set_has_mixed_content();
+
+ // Print a message indicating the mixed-contents resource in the console.
+ const std::wstring& msg = l10n_util::GetStringF(
+ IDS_MIXED_CONTENT_LOG_MESSAGE,
+ UTF8ToWide(entry->url().spec()),
+ UTF8ToWide(mixed_content_handler->request_url().spec()));
+ mixed_content_handler->manager()->
+ AddMessageToConsole(msg, MESSAGE_LEVEL_WARNING);
+
NotificationService::current()->Notify(
NOTIFY_SSL_STATE_CHANGED,
Source<NavigationController>(navigation_controller),
@@ -414,25 +428,6 @@ void SSLPolicy::OnRequestStarted(SSLManager* manager, const GURL& url,
}
}
- // Note that when navigating to an inner-frame, we get this notification
- // before the new navigation entry is created. For now we just copy the
- // mixed/unsafe content state from the old entry to the new one. It is OK
- // to set the state on the wrong entry, as if we navigate back to it, its
- // state will be reset.
-
- // Now check for mixed content.
- if (entry->url().SchemeIsSecure() && !url.SchemeIsSecure()) {
- if (!ssl.has_mixed_content()) {
- changed = true;
- ssl.set_has_mixed_content();
- }
- const std::wstring& msg = l10n_util::GetStringF(
- IDS_MIXED_CONTENT_LOG_MESSAGE,
- UTF8ToWide(entry->url().spec()),
- UTF8ToWide(url.spec()));
- manager->AddMessageToConsole(msg, MESSAGE_LEVEL_WARNING);
- }
-
if (changed) {
// Only send the notification when something actually changed.
NotificationService::current()->Notify(
diff --git a/chrome/browser/ssl_uitest.cc b/chrome/browser/ssl_uitest.cc
index f2bcdef..4446a02 100644
--- a/chrome/browser/ssl_uitest.cc
+++ b/chrome/browser/ssl_uitest.cc
@@ -7,6 +7,7 @@
#include <string>
+#include "chrome/common/pref_names.h"
#include "chrome/test/automation/browser_proxy.h"
#include "chrome/test/automation/tab_proxy.h"
#include "chrome/test/ui/ui_test.h"
@@ -206,6 +207,8 @@ TEST_F(SSLUITest, TestMixedContents) {
kDocRoot, GetOKCertPath());
TestServer http_server(kDocRoot);
+ // Load a page with mixed-content, the default behavior is to show the mixed
+ // content.
scoped_ptr<TabProxy> tab(GetActiveTabProxy());
NavigateTab(tab.get(),
https_server.TestServerPageW(L"files/ssl/page_with_mixed_contents.html"));
@@ -222,10 +225,54 @@ TEST_F(SSLUITest, TestMixedContents) {
EXPECT_EQ(0,
cert_status & net::CERT_STATUS_ALL_ERRORS); // No errors expected.
EXPECT_EQ(NavigationEntry::SSLStatus::MIXED_CONTENT, mixed_content_state);
-}
+ // Now select the block mixed-content pref and reload the page.
+ scoped_ptr<BrowserProxy> browser_proxy(automation()->GetBrowserWindow(0));
+ EXPECT_TRUE(browser_proxy.get());
+ EXPECT_TRUE(browser_proxy->SetIntPreference(prefs::kMixedContentFiltering,
+ FilterPolicy::FILTER_ALL));
+ EXPECT_TRUE(tab->Reload());
+
+ // The image should be filtered.
+ int img_width;
+ EXPECT_TRUE(tab->ExecuteAndExtractInt(L"",
+ L"javascript:void(window.domAutomationController)"
+ L".send(ImageWidth());",
+ &img_width));
+ // In order to check that the image was not loaded, we check its width.
+ // The actual image (Google logo) is 114 pixels wide, we assume the broken
+ // image is less than 100.
+ EXPECT_GT(100, img_width);
+
+ // The state should be OK since we are not showing the resource.
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+
+ // There should be one info-bar to show the mixed-content.
+ int info_bar_count = 0;
+ EXPECT_TRUE(tab->GetSSLInfoBarCount(&info_bar_count));
+ EXPECT_EQ(1, info_bar_count);
+
+ // Activate the link on the info-bar to show the mixed-content.
+ EXPECT_TRUE(tab->ClickSSLInfoBarLink(0, true));
-/* TODO(jcampan) bug 2004: fix this test.
+ // The image should show now.
+ EXPECT_TRUE(tab->ExecuteAndExtractInt(L"",
+ L"javascript:void(window.domAutomationController)"
+ L".send(ImageWidth());",
+ &img_width));
+ EXPECT_LT(100, img_width);
+
+ // And our status should be mixed-content.
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::MIXED_CONTENT, mixed_content_state);
+}
// Visits a page with unsafe content and make sure that:
// - frames content is replaced with warning
@@ -248,10 +295,10 @@ TEST_F(SSLUITest, TestUnsafeContents) {
int cert_status;
int mixed_content_state;
// When the bad content is filtered, the state is expected to be
- // unauthenticated.
+ // authenticated.
EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
&mixed_content_state));
- EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style);
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style);
EXPECT_EQ(0,
cert_status & net::CERT_STATUS_ALL_ERRORS); // No errors expected.
EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
@@ -271,7 +318,7 @@ TEST_F(SSLUITest, TestUnsafeContents) {
L".send(ImageWidth());",
&img_width));
// In order to check that the image was not loaded, we check its width.
- // The actual image (Google logo is 114 pixels wide), we assume the broken
+ // The actual image (Google logo) is 114 pixels wide, we assume the broken
// image is less than 100.
EXPECT_GT(100, img_width);
@@ -282,7 +329,6 @@ TEST_F(SSLUITest, TestUnsafeContents) {
&js_result));
EXPECT_FALSE(js_result);
}
-*/
// Visits a page with mixed content loaded by JS (after the initial page load).
TEST_F(SSLUITest, TestMixedContentsLoadedFromJS) {
@@ -502,32 +548,395 @@ TEST_F(SSLUITest, DISABLED_TestCloseTabWithUnsafePopup) {
tab->Close();
}
-// TODO (jcampan): more tests to do below.
-
// Visit a page over bad https that is a redirect to a page with good https.
+TEST_F(SSLUITest, TestRedirectBadToGoodHTTPS) {
+ HTTPSTestServer good_https_server(kHostName, kOKHTTPSPort,
+ kDocRoot, GetOKCertPath());
+ HTTPSTestServer bad_https_server(kHostName, kBadHTTPSPort,
+ kDocRoot, GetExpiredCertPath());
+
+ scoped_ptr<TabProxy> tab(GetActiveTabProxy());
+ GURL url1 = bad_https_server.TestServerPageW(L"server-redirect?");
+ GURL url2 = good_https_server.TestServerPageW(L"files/ssl/google.html");
+ NavigateTab(tab.get(), GURL(url1.spec() + url2.spec()));
+
+ NavigationEntry::PageType page_type;
+ EXPECT_TRUE(tab->GetPageType(&page_type));
+ EXPECT_EQ(page_type, NavigationEntry::INTERSTITIAL_PAGE);
+
+ SecurityStyle security_style;
+ int cert_status;
+ int mixed_content_state;
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style);
+ EXPECT_EQ(net::CERT_STATUS_DATE_INVALID, cert_status);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+
+ EXPECT_TRUE(tab->TakeActionOnSSLBlockingPage(true));
+ // We have been redirected to the good page.
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style);
+ EXPECT_EQ(0,
+ cert_status & net::CERT_STATUS_ALL_ERRORS); // No errors expected.
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+}
// Visit a page over good https that is a redirect to a page with bad https.
+TEST_F(SSLUITest, TestRedirectGoodToBadHTTPS) {
+ HTTPSTestServer good_https_server(kHostName, kOKHTTPSPort,
+ kDocRoot, GetOKCertPath());
+ HTTPSTestServer bad_https_server(kHostName, kBadHTTPSPort,
+ kDocRoot, GetExpiredCertPath());
+
+ scoped_ptr<TabProxy> tab(GetActiveTabProxy());
+ GURL url1 = good_https_server.TestServerPageW(L"server-redirect?");
+ GURL url2 = bad_https_server.TestServerPageW(L"files/ssl/google.html");
+ NavigateTab(tab.get(), GURL(url1.spec() + url2.spec()));
+
+ NavigationEntry::PageType page_type;
+ EXPECT_TRUE(tab->GetPageType(&page_type));
+ EXPECT_EQ(page_type, NavigationEntry::INTERSTITIAL_PAGE);
+
+ EXPECT_TRUE(tab->TakeActionOnSSLBlockingPage(true));
+
+ SecurityStyle security_style;
+ int cert_status;
+ int mixed_content_state;
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style);
+ EXPECT_EQ(net::CERT_STATUS_DATE_INVALID,
+ cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+}
// Visit a page over http that is a redirect to a page with https (good and
// bad).
+TEST_F(SSLUITest, TestRedirectHTTPToHTTPS) {
+ TestServer http_server(kDocRoot);
+ HTTPSTestServer good_https_server(kHostName, kOKHTTPSPort,
+ kDocRoot, GetOKCertPath());
+ HTTPSTestServer bad_https_server(kHostName, kBadHTTPSPort,
+ kDocRoot, GetExpiredCertPath());
-// Visit a page over https that is a redirect to a page with http.
+ // HTTP redirects to good HTTPS.
+ scoped_ptr<TabProxy> tab(GetActiveTabProxy());
+ GURL http_url = http_server.TestServerPageW(L"server-redirect?");
+ GURL good_https_url =
+ good_https_server.TestServerPageW(L"files/ssl/google.html");
+ NavigateTab(tab.get(), GURL(http_url.spec() + good_https_url.spec()));
-// Visit a page over https that contains a frame with a redirect.
+ SecurityStyle security_style;
+ int cert_status;
+ int mixed_content_state;
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+
+ // HTTP redirects to bad HTTPS.
+ GURL bad_https_url =
+ bad_https_server.TestServerPageW(L"files/ssl/google.html");
+ NavigateTab(tab.get(), GURL(http_url.spec() + bad_https_url.spec()));
+
+ NavigationEntry::PageType page_type;
+ EXPECT_TRUE(tab->GetPageType(&page_type));
+ EXPECT_EQ(page_type, NavigationEntry::INTERSTITIAL_PAGE);
+
+ // Continue on the interstitial.
+ EXPECT_TRUE(tab->TakeActionOnSSLBlockingPage(true));
+
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style);
+ EXPECT_EQ(net::CERT_STATUS_DATE_INVALID,
+ cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+}
+
+// Visit a page over https that is a redirect to a page with http (to make sure
+// we don't keep the secure state).
+TEST_F(SSLUITest, TestRedirectHTTPSToHTTP) {
+ TestServer http_server(kDocRoot);
+ HTTPSTestServer https_server(kHostName, kOKHTTPSPort,
+ kDocRoot, GetOKCertPath());
+
+ scoped_ptr<TabProxy> tab(GetActiveTabProxy());
+ GURL https_url = https_server.TestServerPageW(L"server-redirect?");
+ GURL http_url = http_server.TestServerPageW(L"files/ssl/google.html");
+ NavigateTab(tab.get(), GURL(https_url.spec() + http_url.spec()));
+
+ SecurityStyle security_style;
+ int cert_status;
+ int mixed_content_state;
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+}
// Visits a page to which we could not connect (bad port) over http and https
+// and make sure the security style is correct.
+TEST_F(SSLUITest, TestConnectToBadPort) {
+ scoped_ptr<TabProxy> tab(GetActiveTabProxy());
-// XMLHttpRequest mixed in synchronous mode.
+ GURL http_url("http://localhost:17");
+ NavigateTab(tab.get(), http_url);
-// XMLHttpRequest mixed in asynchronous mode.
+ SecurityStyle security_style;
+ int cert_status;
+ int mixed_content_state;
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
-// XMLHttpRequest over bad ssl in synchronous mode.
+ // Same thing over HTTPS.
+ GURL https_url("https://localhost:17");
+ NavigateTab(tab.get(), https_url);
-// XMLHttpRequest over OK ssl in synchronous mode.
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+}
//
// Frame navigation
//
-// Navigate to broken frame and back.
+// From a good HTTPS top frame:
+// - navigate to an OK HTTPS frame
+// - navigate to a bad HTTPS (expect unsafe content and filtered frame), then
+// back
+// - navigate to HTTP (expect mixed content), then back
+TEST_F(SSLUITest, TestGoodFrameNavigation) {
+ TestServer http_server(kDocRoot);
+ HTTPSTestServer good_https_server(kHostName, kOKHTTPSPort,
+ kDocRoot, GetOKCertPath());
+ HTTPSTestServer bad_https_server(kHostName, kBadHTTPSPort,
+ kDocRoot, GetExpiredCertPath());
+
+ scoped_ptr<TabProxy> tab(GetActiveTabProxy());
+ NavigateTab(tab.get(),
+ good_https_server.TestServerPageW(L"files/ssl/top_frame.html"));
+
+ SecurityStyle security_style;
+ int cert_status;
+ int mixed_content_state;
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+
+ bool success = false;
+ // Now navigate inside the frame.
+ int64 last_nav_time = 0;
+ EXPECT_TRUE(tab->GetLastNavigationTime(&last_nav_time));
+ EXPECT_TRUE(tab->ExecuteAndExtractBool(L"",
+ L"javascript:void(window.domAutomationController)"
+ L".send(clickLink('goodHTTPSLink'));",
+ &success));
+ EXPECT_TRUE(success);
+ EXPECT_TRUE(tab->WaitForNavigation(last_nav_time));
+
+ // We should still be fine.
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+
+ // Now let's hit a bad page.
+ EXPECT_TRUE(tab->GetLastNavigationTime(&last_nav_time));
+ EXPECT_TRUE(tab->ExecuteAndExtractBool(L"",
+ L"javascript:void(window.domAutomationController)"
+ L".send(clickLink('badHTTPSLink'));",
+ &success));
+ EXPECT_TRUE(success);
+ EXPECT_TRUE(tab->WaitForNavigation(last_nav_time));
+
+ // The security style should still be secure.
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+
+ // And the frame should be blocked.
+ bool is_content_evil = true;
+ std::wstring content_frame_xpath(L"html/frameset/frame[2]");
+ std::wstring is_frame_evil_js(
+ L"javascript:void(window.domAutomationController)"
+ L".send(document.getElementById('evilDiv') != null);");
+ EXPECT_TRUE(tab->ExecuteAndExtractBool(content_frame_xpath,
+ is_frame_evil_js,
+ &is_content_evil));
+ EXPECT_FALSE(is_content_evil);
+
+ // Now go back, our state should return to OK.
+ EXPECT_TRUE(tab->GoBack());
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+
+ // Navigate to a page served over HTTP.
+ EXPECT_TRUE(tab->GetLastNavigationTime(&last_nav_time));
+ EXPECT_TRUE(tab->ExecuteAndExtractBool(L"",
+ L"javascript:void(window.domAutomationController)"
+ L".send(clickLink('HTTPLink'));",
+ &success));
+ EXPECT_TRUE(success);
+ EXPECT_TRUE(tab->WaitForNavigation(last_nav_time));
+
+ // Our state should be mixed-content.
+ // Status should be "contains bad contents".
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::MIXED_CONTENT, mixed_content_state);
+
+ // Go back, our state should be back to OK.
+ EXPECT_TRUE(tab->GoBack());
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+}
+
+// From a bad HTTPS top frame:
+// - navigate to an OK HTTPS frame (expected to be still authentication broken).
+TEST_F(SSLUITest, TestBadFrameNavigation) {
+ HTTPSTestServer good_https_server(kHostName, kOKHTTPSPort,
+ kDocRoot, GetOKCertPath());
+ HTTPSTestServer bad_https_server(kHostName, kBadHTTPSPort,
+ kDocRoot, GetExpiredCertPath());
+
+ scoped_ptr<TabProxy> tab(GetActiveTabProxy());
+ NavigateTab(tab.get(),
+ bad_https_server.TestServerPageW(L"files/ssl/top_frame.html"));
+
+ SecurityStyle security_style;
+ int cert_status;
+ int mixed_content_state;
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style);
+ EXPECT_EQ(net::CERT_STATUS_DATE_INVALID,
+ cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+
+ // Continue on the interstitial.
+ EXPECT_TRUE(tab->TakeActionOnSSLBlockingPage(true));
+
+ // Navigate to a good frame.
+ bool success = false;
+ int64 last_nav_time = 0;
+ EXPECT_TRUE(tab->GetLastNavigationTime(&last_nav_time));
+ EXPECT_TRUE(tab->ExecuteAndExtractBool(L"",
+ L"javascript:void(window.domAutomationController)"
+ L".send(clickLink('goodHTTPSLink'));",
+ &success));
+ EXPECT_TRUE(success);
+ EXPECT_TRUE(tab->WaitForNavigation(last_nav_time));
+
+ // We should still be authentication broken.
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_AUTHENTICATION_BROKEN, security_style);
+ EXPECT_EQ(net::CERT_STATUS_DATE_INVALID,
+ cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+}
+
+// From an HTTP top frame, navigate to good and bad HTTPS (security state should
+// stay unauthenticated).
+TEST_F(SSLUITest, TestUnauthenticatedFrameNavigation) {
+ TestServer http_server(kDocRoot);
+ HTTPSTestServer good_https_server(kHostName, kOKHTTPSPort,
+ kDocRoot, GetOKCertPath());
+ HTTPSTestServer bad_https_server(kHostName, kBadHTTPSPort,
+ kDocRoot, GetExpiredCertPath());
+
+ scoped_ptr<TabProxy> tab(GetActiveTabProxy());
+ NavigateTab(tab.get(),
+ http_server.TestServerPageW(L"files/ssl/top_frame.html"));
+
+ SecurityStyle security_style;
+ int cert_status;
+ int mixed_content_state;
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+
+ // Now navigate inside the frame to a secure HTTPS frame.
+ bool success = false;
+ int64 last_nav_time = 0;
+ EXPECT_TRUE(tab->GetLastNavigationTime(&last_nav_time));
+ EXPECT_TRUE(tab->ExecuteAndExtractBool(L"",
+ L"javascript:void(window.domAutomationController)"
+ L".send(clickLink('goodHTTPSLink'));",
+ &success));
+ EXPECT_TRUE(success);
+ EXPECT_TRUE(tab->WaitForNavigation(last_nav_time));
+
+ // We should still be unauthenticated.
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+
+ // Now navigate to a bad HTTPS frame.
+ EXPECT_TRUE(tab->GetLastNavigationTime(&last_nav_time));
+ EXPECT_TRUE(tab->ExecuteAndExtractBool(L"",
+ L"javascript:void(window.domAutomationController)"
+ L".send(clickLink('badHTTPSLink'));",
+ &success));
+ EXPECT_TRUE(success);
+ EXPECT_TRUE(tab->WaitForNavigation(last_nav_time));
+
+ // State should not have changed.
+ EXPECT_TRUE(tab->GetSecurityState(&security_style, &cert_status,
+ &mixed_content_state));
+ EXPECT_EQ(SECURITY_STYLE_UNAUTHENTICATED, security_style);
+ EXPECT_EQ(0, cert_status & net::CERT_STATUS_ALL_ERRORS);
+ EXPECT_EQ(NavigationEntry::SSLStatus::NORMAL_CONTENT, mixed_content_state);
+
+ // And the frame should have been blocked (see bug #2316).
+ bool is_content_evil = true;
+ std::wstring content_frame_xpath(L"html/frameset/frame[2]");
+ std::wstring is_frame_evil_js(
+ L"javascript:void(window.domAutomationController)"
+ L".send(document.getElementById('evilDiv') != null);");
+ EXPECT_TRUE(tab->ExecuteAndExtractBool(content_frame_xpath,
+ is_frame_evil_js,
+ &is_content_evil));
+ EXPECT_FALSE(is_content_evil);
+}
+
+
+// TODO (jcampan): more tests to do below.
+// Visit a page over https that contains a frame with a redirect.
+
+// XMLHttpRequest mixed in synchronous mode.
+
+// XMLHttpRequest mixed in asynchronous mode.
+
+// XMLHttpRequest over bad ssl in synchronous mode.
+
+// XMLHttpRequest over OK ssl in synchronous mode.
diff --git a/chrome/browser/web_contents.cc b/chrome/browser/web_contents.cc
index 3ac7298..b00d63f 100644
--- a/chrome/browser/web_contents.cc
+++ b/chrome/browser/web_contents.cc
@@ -1604,7 +1604,7 @@ void WebContents::DidStartProvisionalLoadForFrame(
is_main_frame,
render_manager_.IsRenderViewInterstitial(render_view_host),
controller()->IsURLInPageNavigation(url),
- url, std::string());
+ url, std::string(), false);
NotificationService::current()->
Notify(NOTIFY_FRAME_PROVISIONAL_LOAD_START,
Source<NavigationController>(controller()),
@@ -1671,7 +1671,7 @@ void WebContents::DidFailProvisionalLoadWithError(
is_main_frame,
render_manager_.IsRenderViewInterstitial(render_view_host),
controller()->IsURLInPageNavigation(url),
- url, std::string());
+ url, std::string(), false);
details.set_error_code(error_code);
render_manager_.set_showing_repost_interstitial(showing_repost_interstitial);