summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-12 18:21:48 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-12-12 18:21:48 +0000
commitb39eb5931f369c016344cb227b24d95193339099 (patch)
treeb60d80410d1080cf38f69d3a53316c8f068620d4
parent713c3e2a8c880a5f7331221c223640bf3672a4ef (diff)
downloadchromium_src-b39eb5931f369c016344cb227b24d95193339099.zip
chromium_src-b39eb5931f369c016344cb227b24d95193339099.tar.gz
chromium_src-b39eb5931f369c016344cb227b24d95193339099.tar.bz2
Move WebPermissionContent implementation to ContentSettingsObserver instead of routing the callbacks from ChromeRenderViewObserver.
BUG=304341 R=jochen@chromium.org Review URL: https://codereview.chromium.org/108873009 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@240361 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc6
-rw-r--r--chrome/renderer/chrome_render_view_observer.cc393
-rw-r--r--chrome/renderer/chrome_render_view_observer.h77
-rw-r--r--chrome/renderer/content_settings_observer.cc364
-rw-r--r--chrome/renderer/content_settings_observer.h103
-rw-r--r--chrome/renderer/content_settings_observer_browsertest.cc16
6 files changed, 434 insertions, 525 deletions
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index c41dcaf..5c02f3a 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -362,7 +362,7 @@ void ChromeContentRendererClient::RenderFrameCreated(
void ChromeContentRendererClient::RenderViewCreated(
content::RenderView* render_view) {
ContentSettingsObserver* content_settings =
- new ContentSettingsObserver(render_view);
+ new ContentSettingsObserver(render_view, extension_dispatcher_.get());
if (chrome_observer_.get()) {
content_settings->SetContentSettingRules(
chrome_observer_->content_setting_rules());
@@ -391,9 +391,7 @@ void ChromeContentRendererClient::RenderViewCreated(
if (command_line->HasSwitch(switches::kInstantProcess))
new SearchBox(render_view);
- new ChromeRenderViewObserver(
- render_view, content_settings, chrome_observer_.get(),
- extension_dispatcher_.get());
+ new ChromeRenderViewObserver(render_view, chrome_observer_.get());
new NetErrorHelper(render_view);
}
diff --git a/chrome/renderer/chrome_render_view_observer.cc b/chrome/renderer/chrome_render_view_observer.cc
index 9c604cf..e26a2c7 100644
--- a/chrome/renderer/chrome_render_view_observer.cc
+++ b/chrome/renderer/chrome_render_view_observer.cc
@@ -19,8 +19,6 @@
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "chrome/renderer/chrome_render_process_observer.h"
-#include "chrome/renderer/content_settings_observer.h"
-#include "chrome/renderer/extensions/dispatcher.h"
#include "chrome/renderer/external_host_bindings.h"
#include "chrome/renderer/prerender/prerender_helper.h"
#include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h"
@@ -57,7 +55,6 @@
#include "ui/gfx/skbitmap_operations.h"
#include "v8/include/v8-testing.h"
-using extensions::APIPermission;
using blink::WebAXObject;
using blink::WebCString;
using blink::WebDataSource;
@@ -98,74 +95,7 @@ static const int kDelayForForcedCaptureMs = 6000;
static const size_t kMaxIndexChars = 65535;
// Constants for UMA statistic collection.
-static const char kWWWDotGoogleDotCom[] = "www.google.com";
-static const char kMailDotGoogleDotCom[] = "mail.google.com";
-static const char kPlusDotGoogleDotCom[] = "plus.google.com";
-static const char kDocsDotGoogleDotCom[] = "docs.google.com";
-static const char kSitesDotGoogleDotCom[] = "sites.google.com";
-static const char kPicasawebDotGoogleDotCom[] = "picasaweb.google.com";
-static const char kCodeDotGoogleDotCom[] = "code.google.com";
-static const char kGroupsDotGoogleDotCom[] = "groups.google.com";
-static const char kMapsDotGoogleDotCom[] = "maps.google.com";
-static const char kWWWDotYoutubeDotCom[] = "www.youtube.com";
-static const char kDotGoogleUserContentDotCom[] = ".googleusercontent.com";
-static const char kGoogleReaderPathPrefix[] = "/reader/";
-static const char kGoogleSupportPathPrefix[] = "/support/";
-static const char kGoogleIntlPathPrefix[] = "/intl/";
-static const char kDotJS[] = ".js";
-static const char kDotCSS[] = ".css";
-static const char kDotSWF[] = ".swf";
-static const char kDotHTML[] = ".html";
static const char kTranslateCaptureText[] = "Translate.CaptureText";
-enum {
- INSECURE_CONTENT_DISPLAY = 0,
- INSECURE_CONTENT_DISPLAY_HOST_GOOGLE,
- INSECURE_CONTENT_DISPLAY_HOST_WWW_GOOGLE,
- INSECURE_CONTENT_DISPLAY_HTML,
- INSECURE_CONTENT_RUN,
- INSECURE_CONTENT_RUN_HOST_GOOGLE,
- INSECURE_CONTENT_RUN_HOST_WWW_GOOGLE,
- INSECURE_CONTENT_RUN_TARGET_YOUTUBE,
- INSECURE_CONTENT_RUN_JS,
- INSECURE_CONTENT_RUN_CSS,
- INSECURE_CONTENT_RUN_SWF,
- INSECURE_CONTENT_DISPLAY_HOST_YOUTUBE,
- INSECURE_CONTENT_RUN_HOST_YOUTUBE,
- INSECURE_CONTENT_RUN_HOST_GOOGLEUSERCONTENT,
- INSECURE_CONTENT_DISPLAY_HOST_MAIL_GOOGLE,
- INSECURE_CONTENT_RUN_HOST_MAIL_GOOGLE,
- INSECURE_CONTENT_DISPLAY_HOST_PLUS_GOOGLE,
- INSECURE_CONTENT_RUN_HOST_PLUS_GOOGLE,
- INSECURE_CONTENT_DISPLAY_HOST_DOCS_GOOGLE,
- INSECURE_CONTENT_RUN_HOST_DOCS_GOOGLE,
- INSECURE_CONTENT_DISPLAY_HOST_SITES_GOOGLE,
- INSECURE_CONTENT_RUN_HOST_SITES_GOOGLE,
- INSECURE_CONTENT_DISPLAY_HOST_PICASAWEB_GOOGLE,
- INSECURE_CONTENT_RUN_HOST_PICASAWEB_GOOGLE,
- INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_READER,
- INSECURE_CONTENT_RUN_HOST_GOOGLE_READER,
- INSECURE_CONTENT_DISPLAY_HOST_CODE_GOOGLE,
- INSECURE_CONTENT_RUN_HOST_CODE_GOOGLE,
- INSECURE_CONTENT_DISPLAY_HOST_GROUPS_GOOGLE,
- INSECURE_CONTENT_RUN_HOST_GROUPS_GOOGLE,
- INSECURE_CONTENT_DISPLAY_HOST_MAPS_GOOGLE,
- INSECURE_CONTENT_RUN_HOST_MAPS_GOOGLE,
- INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_SUPPORT,
- INSECURE_CONTENT_RUN_HOST_GOOGLE_SUPPORT,
- INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_INTL,
- INSECURE_CONTENT_RUN_HOST_GOOGLE_INTL,
- INSECURE_CONTENT_NUM_EVENTS
-};
-
-// Constants for mixed-content blocking.
-static const char kGoogleDotCom[] = "google.com";
-
-static bool isHostInDomain(const std::string& host, const std::string& domain) {
- return (EndsWith(host, domain, false) &&
- (host.length() == domain.length() ||
- (host.length() > domain.length() &&
- host[host.length() - domain.length() - 1] == '.')));
-}
namespace {
@@ -271,21 +201,14 @@ extensions::StackTrace GetStackTraceFromMessage(
ChromeRenderViewObserver::ChromeRenderViewObserver(
content::RenderView* render_view,
- ContentSettingsObserver* content_settings,
- ChromeRenderProcessObserver* chrome_render_process_observer,
- extensions::Dispatcher* extension_dispatcher)
+ ChromeRenderProcessObserver* chrome_render_process_observer)
: content::RenderViewObserver(render_view),
chrome_render_process_observer_(chrome_render_process_observer),
- extension_dispatcher_(extension_dispatcher),
- content_settings_(content_settings),
translate_helper_(new TranslateHelper(render_view)),
phishing_classifier_(NULL),
last_indexed_page_id_(-1),
- allow_displaying_insecure_content_(false),
- allow_running_insecure_content_(false),
capture_timer_(false, false) {
const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- render_view->GetWebView()->setPermissionClient(this);
if (!command_line.HasSwitch(switches::kDisableClientSidePhishingDetection))
OnSetClientSidePhishingDetection(true);
}
@@ -301,10 +224,6 @@ bool ChromeRenderViewObserver::OnMessageReceived(const IPC::Message& message) {
OnHandleMessageFromExternalHost)
IPC_MESSAGE_HANDLER(ChromeViewMsg_JavaScriptStressTestControl,
OnJavaScriptStressTestControl)
- IPC_MESSAGE_HANDLER(ChromeViewMsg_SetAllowDisplayingInsecureContent,
- OnSetAllowDisplayingInsecureContent)
- IPC_MESSAGE_HANDLER(ChromeViewMsg_SetAllowRunningInsecureContent,
- OnSetAllowRunningInsecureContent)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetClientSidePhishingDetection,
OnSetClientSidePhishingDetection)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetVisuallyDeemphasized,
@@ -312,7 +231,6 @@ bool ChromeRenderViewObserver::OnMessageReceived(const IPC::Message& message) {
IPC_MESSAGE_HANDLER(ChromeViewMsg_RequestThumbnailForContextNode,
OnRequestThumbnailForContextNode)
IPC_MESSAGE_HANDLER(ChromeViewMsg_GetFPS, OnGetFPS)
- IPC_MESSAGE_HANDLER(ChromeViewMsg_NPAPINotSupported, OnNPAPINotSupported)
#if defined(OS_ANDROID)
IPC_MESSAGE_HANDLER(ChromeViewMsg_UpdateTopControlsState,
OnUpdateTopControlsState)
@@ -357,26 +275,6 @@ void ChromeRenderViewObserver::OnJavaScriptStressTestControl(int cmd,
}
}
-void ChromeRenderViewObserver::OnSetAllowDisplayingInsecureContent(bool allow) {
- allow_displaying_insecure_content_ = allow;
- WebFrame* main_frame = render_view()->GetWebView()->mainFrame();
- if (main_frame)
- main_frame->reload();
-}
-
-void ChromeRenderViewObserver::OnSetAllowRunningInsecureContent(bool allow) {
- allow_running_insecure_content_ = allow;
- OnSetAllowDisplayingInsecureContent(allow);
-}
-
-void ChromeRenderViewObserver::OnNPAPINotSupported() {
-#if defined(USE_AURA) && defined(OS_WIN)
- content_settings_->BlockNPAPIPlugins();
-#else
- NOTREACHED();
-#endif
-}
-
#if defined(OS_ANDROID)
void ChromeRenderViewObserver::OnUpdateTopControlsState(
content::TopControlsState constraints,
@@ -505,283 +403,6 @@ void ChromeRenderViewObserver::OnGetFPS() {
Send(new ChromeViewHostMsg_FPS(routing_id(), fps));
}
-bool ChromeRenderViewObserver::allowDatabase(
- WebFrame* frame,
- const WebString& name,
- const WebString& display_name,
- unsigned long estimated_size) {
- return content_settings_->AllowDatabase(
- frame, name, display_name, estimated_size);
-}
-
-bool ChromeRenderViewObserver::allowFileSystem(WebFrame* frame) {
- return content_settings_->AllowFileSystem(frame);
-}
-
-bool ChromeRenderViewObserver::allowImage(WebFrame* frame,
- bool enabled_per_settings,
- const WebURL& image_url) {
- return content_settings_->AllowImage(frame, enabled_per_settings, image_url);
-}
-
-bool ChromeRenderViewObserver::allowIndexedDB(WebFrame* frame,
- const WebString& name,
- const WebSecurityOrigin& origin) {
- return content_settings_->AllowIndexedDB(frame, name, origin);
-}
-
-bool ChromeRenderViewObserver::allowPlugins(WebFrame* frame,
- bool enabled_per_settings) {
- return content_settings_->AllowPlugins(frame, enabled_per_settings);
-}
-
-bool ChromeRenderViewObserver::allowScript(WebFrame* frame,
- bool enabled_per_settings) {
- return content_settings_->AllowScript(frame, enabled_per_settings);
-}
-
-bool ChromeRenderViewObserver::allowScriptFromSource(
- WebFrame* frame,
- bool enabled_per_settings,
- const WebURL& script_url) {
- return content_settings_->AllowScriptFromSource(frame,
- enabled_per_settings,
- script_url);
-}
-
-bool ChromeRenderViewObserver::allowStorage(WebFrame* frame, bool local) {
- return content_settings_->AllowStorage(frame, local);
-}
-
-bool ChromeRenderViewObserver::allowReadFromClipboard(WebFrame* frame,
- bool default_value) {
- bool allowed = false;
- // TODO(dcheng): Should we consider a toURL() method on WebSecurityOrigin?
- Send(new ChromeViewHostMsg_CanTriggerClipboardRead(
- routing_id(), GURL(frame->document().securityOrigin().toString().utf8()),
- &allowed));
- return allowed;
-}
-
-bool ChromeRenderViewObserver::allowWriteToClipboard(WebFrame* frame,
- bool default_value) {
- bool allowed = false;
- Send(new ChromeViewHostMsg_CanTriggerClipboardWrite(
- routing_id(), GURL(frame->document().securityOrigin().toString().utf8()),
- &allowed));
- return allowed;
-}
-
-#if defined(WEBPERMISSIONCLIENT_USES_FRAME_FOR_ALL_METHODS)
-bool ChromeRenderViewObserver::allowWebComponents(WebFrame* frame,
- bool defaultValue) {
- if (defaultValue)
- return true;
-
- WebSecurityOrigin origin = frame->document().securityOrigin();
- if (EqualsASCII(origin.protocol(), chrome::kChromeUIScheme))
- return true;
-
- if (const extensions::Extension* extension = GetExtension(origin)) {
- if (extension->HasAPIPermission(APIPermission::kExperimental))
- return true;
- }
-
- return false;
-}
-
-bool ChromeRenderViewObserver::allowMutationEvents(WebFrame* frame,
- bool default_value) {
- WebSecurityOrigin origin = frame->document().securityOrigin();
- const extensions::Extension* extension = GetExtension(origin);
- if (extension && extension->is_platform_app())
- return false;
- return default_value;
-}
-
-bool ChromeRenderViewObserver::allowPushState(WebFrame* frame) {
- WebSecurityOrigin origin = frame->document().securityOrigin();
- const extensions::Extension* extension = GetExtension(origin);
- return !extension || !extension->is_platform_app();
-}
-#else
-bool ChromeRenderViewObserver::allowWebComponents(const WebDocument& document,
- bool defaultValue) {
- if (defaultValue)
- return true;
-
- WebSecurityOrigin origin = document.securityOrigin();
- if (EqualsASCII(origin.protocol(), chrome::kChromeUIScheme))
- return true;
-
- if (const extensions::Extension* extension = GetExtension(origin)) {
- if (extension->HasAPIPermission(APIPermission::kExperimental))
- return true;
- }
-
- return false;
-}
-
-bool ChromeRenderViewObserver::allowMutationEvents(const WebDocument& document,
- bool default_value) {
- WebSecurityOrigin origin = document.securityOrigin();
- const extensions::Extension* extension = GetExtension(origin);
- if (extension && extension->is_platform_app())
- return false;
- return default_value;
-}
-
-bool ChromeRenderViewObserver::allowPushState(const WebDocument& document) {
- WebSecurityOrigin origin = document.securityOrigin();
- const extensions::Extension* extension = GetExtension(origin);
- return !extension || !extension->is_platform_app();
-}
-#endif
-
-static void SendInsecureContentSignal(int signal) {
- UMA_HISTOGRAM_ENUMERATION("SSL.InsecureContent", signal,
- INSECURE_CONTENT_NUM_EVENTS);
-}
-
-bool ChromeRenderViewObserver::allowDisplayingInsecureContent(
- blink::WebFrame* frame,
- bool allowed_per_settings,
- const blink::WebSecurityOrigin& origin,
- const blink::WebURL& resource_url) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY);
-
- std::string origin_host(origin.host().utf8());
- GURL frame_gurl(frame->document().url());
- if (isHostInDomain(origin_host, kGoogleDotCom)) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE);
- if (StartsWithASCII(frame_gurl.path(), kGoogleSupportPathPrefix, false)) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_SUPPORT);
- } else if (StartsWithASCII(frame_gurl.path(),
- kGoogleIntlPathPrefix,
- false)) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_INTL);
- }
- }
-
- if (origin_host == kWWWDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_WWW_GOOGLE);
- if (StartsWithASCII(frame_gurl.path(), kGoogleReaderPathPrefix, false))
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_READER);
- } else if (origin_host == kMailDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_MAIL_GOOGLE);
- } else if (origin_host == kPlusDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_PLUS_GOOGLE);
- } else if (origin_host == kDocsDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_DOCS_GOOGLE);
- } else if (origin_host == kSitesDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_SITES_GOOGLE);
- } else if (origin_host == kPicasawebDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_PICASAWEB_GOOGLE);
- } else if (origin_host == kCodeDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_CODE_GOOGLE);
- } else if (origin_host == kGroupsDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GROUPS_GOOGLE);
- } else if (origin_host == kMapsDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_MAPS_GOOGLE);
- } else if (origin_host == kWWWDotYoutubeDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_YOUTUBE);
- }
-
- GURL resource_gurl(resource_url);
- if (EndsWith(resource_gurl.path(), kDotHTML, false))
- SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HTML);
-
- if (allowed_per_settings || allow_displaying_insecure_content_)
- return true;
-
- Send(new ChromeViewHostMsg_DidBlockDisplayingInsecureContent(routing_id()));
-
- return false;
-}
-
-bool ChromeRenderViewObserver::allowRunningInsecureContent(
- blink::WebFrame* frame,
- bool allowed_per_settings,
- const blink::WebSecurityOrigin& origin,
- const blink::WebURL& resource_url) {
- std::string origin_host(origin.host().utf8());
- GURL frame_gurl(frame->document().url());
- DCHECK_EQ(frame_gurl.host(), origin_host);
-
- bool is_google = isHostInDomain(origin_host, kGoogleDotCom);
- if (is_google) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE);
- if (StartsWithASCII(frame_gurl.path(), kGoogleSupportPathPrefix, false)) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE_SUPPORT);
- } else if (StartsWithASCII(frame_gurl.path(),
- kGoogleIntlPathPrefix,
- false)) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE_INTL);
- }
- }
-
- if (origin_host == kWWWDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_WWW_GOOGLE);
- if (StartsWithASCII(frame_gurl.path(), kGoogleReaderPathPrefix, false))
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE_READER);
- } else if (origin_host == kMailDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_MAIL_GOOGLE);
- } else if (origin_host == kPlusDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_PLUS_GOOGLE);
- } else if (origin_host == kDocsDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_DOCS_GOOGLE);
- } else if (origin_host == kSitesDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_SITES_GOOGLE);
- } else if (origin_host == kPicasawebDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_PICASAWEB_GOOGLE);
- } else if (origin_host == kCodeDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_CODE_GOOGLE);
- } else if (origin_host == kGroupsDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GROUPS_GOOGLE);
- } else if (origin_host == kMapsDotGoogleDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_MAPS_GOOGLE);
- } else if (origin_host == kWWWDotYoutubeDotCom) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_YOUTUBE);
- } else if (EndsWith(origin_host, kDotGoogleUserContentDotCom, false)) {
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLEUSERCONTENT);
- }
-
- GURL resource_gurl(resource_url);
- if (resource_gurl.host() == kWWWDotYoutubeDotCom)
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_TARGET_YOUTUBE);
-
- if (EndsWith(resource_gurl.path(), kDotJS, false))
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_JS);
- else if (EndsWith(resource_gurl.path(), kDotCSS, false))
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_CSS);
- else if (EndsWith(resource_gurl.path(), kDotSWF, false))
- SendInsecureContentSignal(INSECURE_CONTENT_RUN_SWF);
-
- if (!allow_running_insecure_content_ && !allowed_per_settings) {
- content_settings_->DidNotAllowMixedScript();
- return false;
- }
-
- return true;
-}
-
-bool ChromeRenderViewObserver::allowWebGLDebugRendererInfo(WebFrame* frame) {
- bool allowed = false;
- Send(new ChromeViewHostMsg_IsWebGLDebugRendererInfoAllowed(
- routing_id(),
- GURL(frame->top()->document().securityOrigin().toString().utf8()),
- &allowed));
- return allowed;
-}
-
-void ChromeRenderViewObserver::didNotAllowPlugins(WebFrame* frame) {
- content_settings_->DidNotAllowPlugins();
-}
-
-void ChromeRenderViewObserver::didNotAllowScript(WebFrame* frame) {
- content_settings_->DidNotAllowScript();
-}
-
void ChromeRenderViewObserver::DidStartLoading() {
if ((render_view()->GetEnabledBindings() & content::BINDINGS_POLICY_WEB_UI) &&
webui_javascript_.get()) {
@@ -985,18 +606,6 @@ ExternalHostBindings* ChromeRenderViewObserver::GetExternalHostBindings() {
return external_host_bindings_.get();
}
-const extensions::Extension* ChromeRenderViewObserver::GetExtension(
- const WebSecurityOrigin& origin) const {
- if (!EqualsASCII(origin.protocol(), extensions::kExtensionScheme))
- return NULL;
-
- const std::string extension_id = origin.host().utf8().data();
- if (!extension_dispatcher_->IsExtensionActive(extension_id))
- return NULL;
-
- return extension_dispatcher_->extensions()->GetByID(extension_id);
-}
-
bool ChromeRenderViewObserver::HasRefreshMetaTag(WebFrame* frame) {
if (!frame)
return false;
diff --git a/chrome/renderer/chrome_render_view_observer.h b/chrome/renderer/chrome_render_view_observer.h
index f615a37..03e820b 100644
--- a/chrome/renderer/chrome_render_view_observer.h
+++ b/chrome/renderer/chrome_render_view_observer.h
@@ -15,8 +15,6 @@
#include "base/timer/timer.h"
#include "content/public/common/top_controls_state.h"
#include "content/public/renderer/render_view_observer.h"
-#include "extensions/common/permissions/api_permission.h"
-#include "third_party/WebKit/public/web/WebPermissionClient.h"
#include "ui/gfx/size.h"
#include "url/gurl.h"
@@ -28,11 +26,6 @@ class TranslateHelper;
class WebViewColorOverlay;
class WebViewAnimatingOverlay;
-namespace extensions {
-class Dispatcher;
-class Extension;
-}
-
namespace blink {
class WebView;
struct WebWindowFeatures;
@@ -44,15 +37,12 @@ class PhishingClassifierDelegate;
// This class holds the Chrome specific parts of RenderView, and has the same
// lifetime.
-class ChromeRenderViewObserver : public content::RenderViewObserver,
- public blink::WebPermissionClient {
+class ChromeRenderViewObserver : public content::RenderViewObserver {
public:
// translate_helper can be NULL.
ChromeRenderViewObserver(
content::RenderView* render_view,
- ContentSettingsObserver* content_settings,
- ChromeRenderProcessObserver* chrome_render_process_observer,
- extensions::Dispatcher* extension_dispatcher);
+ ChromeRenderProcessObserver* chrome_render_process_observer);
virtual ~ChromeRenderViewObserver();
private:
@@ -77,55 +67,6 @@ class ChromeRenderViewObserver : public content::RenderViewObserver,
const base::string16& stack_trace,
int32 line_number,
int32 severity_level) OVERRIDE;
-
- // blink::WebPermissionClient implementation.
- virtual bool allowDatabase(blink::WebFrame* frame,
- const blink::WebString& name,
- const blink::WebString& display_name,
- unsigned long estimated_size);
- virtual bool allowFileSystem(blink::WebFrame* frame);
- virtual bool allowImage(blink::WebFrame* frame,
- bool enabled_per_settings,
- const blink::WebURL& image_url);
- virtual bool allowIndexedDB(blink::WebFrame* frame,
- const blink::WebString& name,
- const blink::WebSecurityOrigin& origin);
- virtual bool allowPlugins(blink::WebFrame* frame,
- bool enabled_per_settings);
- virtual bool allowScript(blink::WebFrame* frame,
- bool enabled_per_settings);
- virtual bool allowScriptFromSource(blink::WebFrame* frame,
- bool enabled_per_settings,
- const blink::WebURL& script_url);
- virtual bool allowStorage(blink::WebFrame* frame, bool local);
- virtual bool allowReadFromClipboard(blink::WebFrame* frame,
- bool default_value);
- virtual bool allowWriteToClipboard(blink::WebFrame* frame,
- bool default_value);
-#if defined(WEBPERMISSIONCLIENT_USES_FRAME_FOR_ALL_METHODS)
- virtual bool allowWebComponents(blink::WebFrame* frame, bool);
- virtual bool allowMutationEvents(blink::WebFrame* frame,
- bool default_value);
- virtual bool allowPushState(blink::WebFrame* frame);
-#else
- virtual bool allowWebComponents(const blink::WebDocument&, bool);
- virtual bool allowMutationEvents(const blink::WebDocument&,
- bool default_value);
- virtual bool allowPushState(const blink::WebDocument&);
-#endif
- virtual bool allowWebGLDebugRendererInfo(blink::WebFrame* frame);
- virtual void didNotAllowPlugins(blink::WebFrame* frame);
- virtual void didNotAllowScript(blink::WebFrame* frame);
- virtual bool allowDisplayingInsecureContent(
- blink::WebFrame* frame,
- bool allowed_per_settings,
- const blink::WebSecurityOrigin& context,
- const blink::WebURL& url);
- virtual bool allowRunningInsecureContent(
- blink::WebFrame* frame,
- bool allowed_per_settings,
- const blink::WebSecurityOrigin& context,
- const blink::WebURL& url);
virtual void Navigate(const GURL& url) OVERRIDE;
void OnWebUIJavaScript(const base::string16& frame_xpath,
@@ -136,14 +77,11 @@ class ChromeRenderViewObserver : public content::RenderViewObserver,
const std::string& origin,
const std::string& target);
void OnJavaScriptStressTestControl(int cmd, int param);
- void OnSetAllowDisplayingInsecureContent(bool allow);
- void OnSetAllowRunningInsecureContent(bool allow);
void OnSetClientSidePhishingDetection(bool enable_phishing_detection);
void OnSetVisuallyDeemphasized(bool deemphasized);
void OnRequestThumbnailForContextNode(int thumbnail_min_area_pixels,
gfx::Size thumbnail_max_size_pixels);
void OnGetFPS();
- void OnNPAPINotSupported();
#if defined(OS_ANDROID)
void OnUpdateTopControlsState(content::TopControlsState constraints,
content::TopControlsState current,
@@ -169,11 +107,6 @@ class ChromeRenderViewObserver : public content::RenderViewObserver,
// Determines if a host is in the strict security host set.
bool IsStrictSecurityHost(const std::string& host);
- // If |origin| corresponds to an installed extension, returns that extension.
- // Otherwise returns NULL.
- const extensions::Extension* GetExtension(
- const blink::WebSecurityOrigin& origin) const;
-
// Checks if a page contains <meta http-equiv="refresh" ...> tag.
bool HasRefreshMetaTag(blink::WebFrame* frame);
@@ -182,10 +115,8 @@ class ChromeRenderViewObserver : public content::RenderViewObserver,
// Owned by ChromeContentRendererClient and outlive us.
ChromeRenderProcessObserver* chrome_render_process_observer_;
- extensions::Dispatcher* extension_dispatcher_;
// Have the same lifetime as us.
- ContentSettingsObserver* content_settings_;
TranslateHelper* translate_helper_;
safe_browsing::PhishingClassifierDelegate* phishing_classifier_;
@@ -197,10 +128,6 @@ class ChromeRenderViewObserver : public content::RenderViewObserver,
// replacement.
GURL last_indexed_url_;
- // Insecure content may be permitted for the duration of this render view.
- bool allow_displaying_insecure_content_;
- bool allow_running_insecure_content_;
-
// External host exposed through automation controller.
scoped_ptr<ExternalHostBindings> external_host_bindings_;
diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc
index 0127b9b..c396153 100644
--- a/chrome/renderer/content_settings_observer.cc
+++ b/chrome/renderer/content_settings_observer.cc
@@ -5,9 +5,11 @@
#include "chrome/renderer/content_settings_observer.h"
#include "base/command_line.h"
+#include "base/metrics/histogram.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
+#include "chrome/renderer/extensions/dispatcher.h"
#include "content/public/renderer/document_state.h"
#include "content/public/renderer/navigation_state.h"
#include "content/public/renderer/render_view.h"
@@ -22,6 +24,7 @@
#include "webkit/child/weburlresponse_extradata_impl.h"
using blink::WebDataSource;
+using blink::WebDocument;
using blink::WebFrame;
using blink::WebFrameClient;
using blink::WebSecurityOrigin;
@@ -30,9 +33,80 @@ using blink::WebURL;
using blink::WebView;
using content::DocumentState;
using content::NavigationState;
+using extensions::APIPermission;
namespace {
+enum {
+ INSECURE_CONTENT_DISPLAY = 0,
+ INSECURE_CONTENT_DISPLAY_HOST_GOOGLE,
+ INSECURE_CONTENT_DISPLAY_HOST_WWW_GOOGLE,
+ INSECURE_CONTENT_DISPLAY_HTML,
+ INSECURE_CONTENT_RUN,
+ INSECURE_CONTENT_RUN_HOST_GOOGLE,
+ INSECURE_CONTENT_RUN_HOST_WWW_GOOGLE,
+ INSECURE_CONTENT_RUN_TARGET_YOUTUBE,
+ INSECURE_CONTENT_RUN_JS,
+ INSECURE_CONTENT_RUN_CSS,
+ INSECURE_CONTENT_RUN_SWF,
+ INSECURE_CONTENT_DISPLAY_HOST_YOUTUBE,
+ INSECURE_CONTENT_RUN_HOST_YOUTUBE,
+ INSECURE_CONTENT_RUN_HOST_GOOGLEUSERCONTENT,
+ INSECURE_CONTENT_DISPLAY_HOST_MAIL_GOOGLE,
+ INSECURE_CONTENT_RUN_HOST_MAIL_GOOGLE,
+ INSECURE_CONTENT_DISPLAY_HOST_PLUS_GOOGLE,
+ INSECURE_CONTENT_RUN_HOST_PLUS_GOOGLE,
+ INSECURE_CONTENT_DISPLAY_HOST_DOCS_GOOGLE,
+ INSECURE_CONTENT_RUN_HOST_DOCS_GOOGLE,
+ INSECURE_CONTENT_DISPLAY_HOST_SITES_GOOGLE,
+ INSECURE_CONTENT_RUN_HOST_SITES_GOOGLE,
+ INSECURE_CONTENT_DISPLAY_HOST_PICASAWEB_GOOGLE,
+ INSECURE_CONTENT_RUN_HOST_PICASAWEB_GOOGLE,
+ INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_READER,
+ INSECURE_CONTENT_RUN_HOST_GOOGLE_READER,
+ INSECURE_CONTENT_DISPLAY_HOST_CODE_GOOGLE,
+ INSECURE_CONTENT_RUN_HOST_CODE_GOOGLE,
+ INSECURE_CONTENT_DISPLAY_HOST_GROUPS_GOOGLE,
+ INSECURE_CONTENT_RUN_HOST_GROUPS_GOOGLE,
+ INSECURE_CONTENT_DISPLAY_HOST_MAPS_GOOGLE,
+ INSECURE_CONTENT_RUN_HOST_MAPS_GOOGLE,
+ INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_SUPPORT,
+ INSECURE_CONTENT_RUN_HOST_GOOGLE_SUPPORT,
+ INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_INTL,
+ INSECURE_CONTENT_RUN_HOST_GOOGLE_INTL,
+ INSECURE_CONTENT_NUM_EVENTS
+};
+
+// Constants for UMA statistic collection.
+static const char kWWWDotGoogleDotCom[] = "www.google.com";
+static const char kMailDotGoogleDotCom[] = "mail.google.com";
+static const char kPlusDotGoogleDotCom[] = "plus.google.com";
+static const char kDocsDotGoogleDotCom[] = "docs.google.com";
+static const char kSitesDotGoogleDotCom[] = "sites.google.com";
+static const char kPicasawebDotGoogleDotCom[] = "picasaweb.google.com";
+static const char kCodeDotGoogleDotCom[] = "code.google.com";
+static const char kGroupsDotGoogleDotCom[] = "groups.google.com";
+static const char kMapsDotGoogleDotCom[] = "maps.google.com";
+static const char kWWWDotYoutubeDotCom[] = "www.youtube.com";
+static const char kDotGoogleUserContentDotCom[] = ".googleusercontent.com";
+static const char kGoogleReaderPathPrefix[] = "/reader/";
+static const char kGoogleSupportPathPrefix[] = "/support/";
+static const char kGoogleIntlPathPrefix[] = "/intl/";
+static const char kDotJS[] = ".js";
+static const char kDotCSS[] = ".css";
+static const char kDotSWF[] = ".swf";
+static const char kDotHTML[] = ".html";
+
+// Constants for mixed-content blocking.
+static const char kGoogleDotCom[] = "google.com";
+
+static bool IsHostInDomain(const std::string& host, const std::string& domain) {
+ return (EndsWith(host, domain, false) &&
+ (host.length() == domain.length() ||
+ (host.length() > domain.length() &&
+ host[host.length() - domain.length() - 1] == '.')));
+}
+
GURL GetOriginOrURL(const WebFrame* frame) {
WebString top_origin = frame->top()->document().securityOrigin().toString();
// The the |top_origin| is unique ("null") e.g., for file:// URLs. Use the
@@ -68,13 +142,18 @@ ContentSetting GetContentSettingFromRules(
} // namespace
ContentSettingsObserver::ContentSettingsObserver(
- content::RenderView* render_view)
+ content::RenderView* render_view,
+ extensions::Dispatcher* extension_dispatcher)
: content::RenderViewObserver(render_view),
content::RenderViewObserverTracker<ContentSettingsObserver>(render_view),
+ extension_dispatcher_(extension_dispatcher),
+ allow_displaying_insecure_content_(false),
+ allow_running_insecure_content_(false),
content_setting_rules_(NULL),
is_interstitial_page_(false),
npapi_plugins_blocked_(false) {
ClearBlockedContentSettings();
+ render_view->GetWebView()->setPermissionClient(this);
}
ContentSettingsObserver::~ContentSettingsObserver() {
@@ -107,6 +186,11 @@ bool ContentSettingsObserver::OnMessageReceived(const IPC::Message& message) {
bool handled = true;
IPC_BEGIN_MESSAGE_MAP(ContentSettingsObserver, message)
IPC_MESSAGE_HANDLER(ChromeViewMsg_SetAsInterstitial, OnSetAsInterstitial)
+ IPC_MESSAGE_HANDLER(ChromeViewMsg_NPAPINotSupported, OnNPAPINotSupported)
+ IPC_MESSAGE_HANDLER(ChromeViewMsg_SetAllowDisplayingInsecureContent,
+ OnSetAllowDisplayingInsecureContent)
+ IPC_MESSAGE_HANDLER(ChromeViewMsg_SetAllowRunningInsecureContent,
+ OnSetAllowRunningInsecureContent)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
if (handled)
@@ -131,8 +215,8 @@ void ContentSettingsObserver::DidCommitProvisionalLoad(
NavigationState* navigation_state = document_state->navigation_state();
if (!navigation_state->was_within_same_page()) {
// Clear "block" flags for the new page. This needs to happen before any of
- // |AllowScript()|, |AllowScriptFromSource()|, |AllowImage()|, or
- // |AllowPlugins()| is called for the new page so that these functions can
+ // |allowScript()|, |allowScriptFromSource()|, |allowImage()|, or
+ // |allowPlugins()| is called for the new page so that these functions can
// correctly detect that a piece of content flipped from "not blocked" to
// "blocked".
ClearBlockedContentSettings();
@@ -146,7 +230,7 @@ void ContentSettingsObserver::DidCommitProvisionalLoad(
!url.SchemeIs(chrome::kDataScheme));
}
-bool ContentSettingsObserver::AllowDatabase(WebFrame* frame,
+bool ContentSettingsObserver::allowDatabase(WebFrame* frame,
const WebString& name,
const WebString& display_name,
unsigned long estimated_size) {
@@ -162,7 +246,7 @@ bool ContentSettingsObserver::AllowDatabase(WebFrame* frame,
return result;
}
-bool ContentSettingsObserver::AllowFileSystem(WebFrame* frame) {
+bool ContentSettingsObserver::allowFileSystem(WebFrame* frame) {
if (frame->document().securityOrigin().isUnique() ||
frame->top()->document().securityOrigin().isUnique())
return false;
@@ -174,7 +258,7 @@ bool ContentSettingsObserver::AllowFileSystem(WebFrame* frame) {
return result;
}
-bool ContentSettingsObserver::AllowImage(WebFrame* frame,
+bool ContentSettingsObserver::allowImage(WebFrame* frame,
bool enabled_per_settings,
const WebURL& image_url) {
bool allow = enabled_per_settings;
@@ -196,7 +280,7 @@ bool ContentSettingsObserver::AllowImage(WebFrame* frame,
return allow;
}
-bool ContentSettingsObserver::AllowIndexedDB(WebFrame* frame,
+bool ContentSettingsObserver::allowIndexedDB(WebFrame* frame,
const WebString& name,
const WebSecurityOrigin& origin) {
if (frame->document().securityOrigin().isUnique() ||
@@ -211,12 +295,12 @@ bool ContentSettingsObserver::AllowIndexedDB(WebFrame* frame,
return result;
}
-bool ContentSettingsObserver::AllowPlugins(WebFrame* frame,
+bool ContentSettingsObserver::allowPlugins(WebFrame* frame,
bool enabled_per_settings) {
return enabled_per_settings;
}
-bool ContentSettingsObserver::AllowScript(WebFrame* frame,
+bool ContentSettingsObserver::allowScript(WebFrame* frame,
bool enabled_per_settings) {
if (!enabled_per_settings)
return false;
@@ -245,7 +329,7 @@ bool ContentSettingsObserver::AllowScript(WebFrame* frame,
return allow;
}
-bool ContentSettingsObserver::AllowScriptFromSource(
+bool ContentSettingsObserver::allowScriptFromSource(
WebFrame* frame,
bool enabled_per_settings,
const blink::WebURL& script_url) {
@@ -265,7 +349,7 @@ bool ContentSettingsObserver::AllowScriptFromSource(
return allow || IsWhitelistedForContentSettings(frame);
}
-bool ContentSettingsObserver::AllowStorage(WebFrame* frame, bool local) {
+bool ContentSettingsObserver::allowStorage(WebFrame* frame, bool local) {
if (frame->document().securityOrigin().isUnique() ||
frame->top()->document().securityOrigin().isUnique())
return false;
@@ -286,20 +370,233 @@ bool ContentSettingsObserver::AllowStorage(WebFrame* frame, bool local) {
return result;
}
-void ContentSettingsObserver::DidNotAllowPlugins() {
- DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS);
+bool ContentSettingsObserver::allowReadFromClipboard(WebFrame* frame,
+ bool default_value) {
+ bool allowed = false;
+ // TODO(dcheng): Should we consider a toURL() method on WebSecurityOrigin?
+ Send(new ChromeViewHostMsg_CanTriggerClipboardRead(
+ routing_id(), GURL(frame->document().securityOrigin().toString().utf8()),
+ &allowed));
+ return allowed;
}
-void ContentSettingsObserver::DidNotAllowScript() {
- DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
+bool ContentSettingsObserver::allowWriteToClipboard(WebFrame* frame,
+ bool default_value) {
+ bool allowed = false;
+ Send(new ChromeViewHostMsg_CanTriggerClipboardWrite(
+ routing_id(), GURL(frame->document().securityOrigin().toString().utf8()),
+ &allowed));
+ return allowed;
+}
+
+#if defined(WEBPERMISSIONCLIENT_USES_FRAME_FOR_ALL_METHODS)
+bool ContentSettingsObserver::allowWebComponents(WebFrame* frame,
+ bool defaultValue) {
+ if (defaultValue)
+ return true;
+
+ WebSecurityOrigin origin = frame->document().securityOrigin();
+ if (EqualsASCII(origin.protocol(), chrome::kChromeUIScheme))
+ return true;
+
+ if (const extensions::Extension* extension = GetExtension(origin)) {
+ if (extension->HasAPIPermission(APIPermission::kExperimental))
+ return true;
+ }
+
+ return false;
}
-void ContentSettingsObserver::DidNotAllowMixedScript() {
- DidBlockContentType(CONTENT_SETTINGS_TYPE_MIXEDSCRIPT);
+bool ContentSettingsObserver::allowMutationEvents(WebFrame* frame,
+ bool default_value) {
+ WebSecurityOrigin origin = frame->document().securityOrigin();
+ const extensions::Extension* extension = GetExtension(origin);
+ if (extension && extension->is_platform_app())
+ return false;
+ return default_value;
}
-void ContentSettingsObserver::BlockNPAPIPlugins() {
- npapi_plugins_blocked_ = true;
+bool ContentSettingsObserver::allowPushState(WebFrame* frame) {
+ WebSecurityOrigin origin = frame->document().securityOrigin();
+ const extensions::Extension* extension = GetExtension(origin);
+ return !extension || !extension->is_platform_app();
+}
+#else
+bool ContentSettingsObserver::allowWebComponents(const WebDocument& document,
+ bool defaultValue) {
+ if (defaultValue)
+ return true;
+
+ WebSecurityOrigin origin = document.securityOrigin();
+ if (EqualsASCII(origin.protocol(), chrome::kChromeUIScheme))
+ return true;
+
+ if (const extensions::Extension* extension = GetExtension(origin)) {
+ if (extension->HasAPIPermission(APIPermission::kExperimental))
+ return true;
+ }
+
+ return false;
+}
+
+bool ContentSettingsObserver::allowMutationEvents(const WebDocument& document,
+ bool default_value) {
+ WebSecurityOrigin origin = document.securityOrigin();
+ const extensions::Extension* extension = GetExtension(origin);
+ if (extension && extension->is_platform_app())
+ return false;
+ return default_value;
+}
+
+bool ContentSettingsObserver::allowPushState(const WebDocument& document) {
+ WebSecurityOrigin origin = document.securityOrigin();
+ const extensions::Extension* extension = GetExtension(origin);
+ return !extension || !extension->is_platform_app();
+}
+#endif
+
+static void SendInsecureContentSignal(int signal) {
+ UMA_HISTOGRAM_ENUMERATION("SSL.InsecureContent", signal,
+ INSECURE_CONTENT_NUM_EVENTS);
+}
+
+bool ContentSettingsObserver::allowDisplayingInsecureContent(
+ blink::WebFrame* frame,
+ bool allowed_per_settings,
+ const blink::WebSecurityOrigin& origin,
+ const blink::WebURL& resource_url) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY);
+
+ std::string origin_host(origin.host().utf8());
+ GURL frame_gurl(frame->document().url());
+ if (IsHostInDomain(origin_host, kGoogleDotCom)) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE);
+ if (StartsWithASCII(frame_gurl.path(), kGoogleSupportPathPrefix, false)) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_SUPPORT);
+ } else if (StartsWithASCII(frame_gurl.path(),
+ kGoogleIntlPathPrefix,
+ false)) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_INTL);
+ }
+ }
+
+ if (origin_host == kWWWDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_WWW_GOOGLE);
+ if (StartsWithASCII(frame_gurl.path(), kGoogleReaderPathPrefix, false))
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GOOGLE_READER);
+ } else if (origin_host == kMailDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_MAIL_GOOGLE);
+ } else if (origin_host == kPlusDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_PLUS_GOOGLE);
+ } else if (origin_host == kDocsDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_DOCS_GOOGLE);
+ } else if (origin_host == kSitesDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_SITES_GOOGLE);
+ } else if (origin_host == kPicasawebDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_PICASAWEB_GOOGLE);
+ } else if (origin_host == kCodeDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_CODE_GOOGLE);
+ } else if (origin_host == kGroupsDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_GROUPS_GOOGLE);
+ } else if (origin_host == kMapsDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_MAPS_GOOGLE);
+ } else if (origin_host == kWWWDotYoutubeDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HOST_YOUTUBE);
+ }
+
+ GURL resource_gurl(resource_url);
+ if (EndsWith(resource_gurl.path(), kDotHTML, false))
+ SendInsecureContentSignal(INSECURE_CONTENT_DISPLAY_HTML);
+
+ if (allowed_per_settings || allow_displaying_insecure_content_)
+ return true;
+
+ Send(new ChromeViewHostMsg_DidBlockDisplayingInsecureContent(routing_id()));
+
+ return false;
+}
+
+bool ContentSettingsObserver::allowRunningInsecureContent(
+ blink::WebFrame* frame,
+ bool allowed_per_settings,
+ const blink::WebSecurityOrigin& origin,
+ const blink::WebURL& resource_url) {
+ std::string origin_host(origin.host().utf8());
+ GURL frame_gurl(frame->document().url());
+ DCHECK_EQ(frame_gurl.host(), origin_host);
+
+ bool is_google = IsHostInDomain(origin_host, kGoogleDotCom);
+ if (is_google) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE);
+ if (StartsWithASCII(frame_gurl.path(), kGoogleSupportPathPrefix, false)) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE_SUPPORT);
+ } else if (StartsWithASCII(frame_gurl.path(),
+ kGoogleIntlPathPrefix,
+ false)) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE_INTL);
+ }
+ }
+
+ if (origin_host == kWWWDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_WWW_GOOGLE);
+ if (StartsWithASCII(frame_gurl.path(), kGoogleReaderPathPrefix, false))
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLE_READER);
+ } else if (origin_host == kMailDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_MAIL_GOOGLE);
+ } else if (origin_host == kPlusDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_PLUS_GOOGLE);
+ } else if (origin_host == kDocsDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_DOCS_GOOGLE);
+ } else if (origin_host == kSitesDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_SITES_GOOGLE);
+ } else if (origin_host == kPicasawebDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_PICASAWEB_GOOGLE);
+ } else if (origin_host == kCodeDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_CODE_GOOGLE);
+ } else if (origin_host == kGroupsDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GROUPS_GOOGLE);
+ } else if (origin_host == kMapsDotGoogleDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_MAPS_GOOGLE);
+ } else if (origin_host == kWWWDotYoutubeDotCom) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_YOUTUBE);
+ } else if (EndsWith(origin_host, kDotGoogleUserContentDotCom, false)) {
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_HOST_GOOGLEUSERCONTENT);
+ }
+
+ GURL resource_gurl(resource_url);
+ if (resource_gurl.host() == kWWWDotYoutubeDotCom)
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_TARGET_YOUTUBE);
+
+ if (EndsWith(resource_gurl.path(), kDotJS, false))
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_JS);
+ else if (EndsWith(resource_gurl.path(), kDotCSS, false))
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_CSS);
+ else if (EndsWith(resource_gurl.path(), kDotSWF, false))
+ SendInsecureContentSignal(INSECURE_CONTENT_RUN_SWF);
+
+ if (!allow_running_insecure_content_ && !allowed_per_settings) {
+ DidBlockContentType(CONTENT_SETTINGS_TYPE_MIXEDSCRIPT);
+ return false;
+ }
+
+ return true;
+}
+
+bool ContentSettingsObserver::allowWebGLDebugRendererInfo(WebFrame* frame) {
+ bool allowed = false;
+ Send(new ChromeViewHostMsg_IsWebGLDebugRendererInfoAllowed(
+ routing_id(),
+ GURL(frame->top()->document().securityOrigin().toString().utf8()),
+ &allowed));
+ return allowed;
+}
+
+void ContentSettingsObserver::didNotAllowPlugins(WebFrame* frame) {
+ DidBlockContentType(CONTENT_SETTINGS_TYPE_PLUGINS);
+}
+
+void ContentSettingsObserver::didNotAllowScript(WebFrame* frame) {
+ DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT);
}
bool ContentSettingsObserver::AreNPAPIPluginsBlocked() const {
@@ -315,6 +612,23 @@ void ContentSettingsObserver::OnSetAsInterstitial() {
is_interstitial_page_ = true;
}
+void ContentSettingsObserver::OnNPAPINotSupported() {
+ npapi_plugins_blocked_ = true;
+}
+
+void ContentSettingsObserver::OnSetAllowDisplayingInsecureContent(bool allow) {
+ allow_displaying_insecure_content_ = allow;
+ WebFrame* main_frame = render_view()->GetWebView()->mainFrame();
+ if (main_frame)
+ main_frame->reload();
+}
+
+void ContentSettingsObserver::OnSetAllowRunningInsecureContent(bool allow) {
+ allow_running_insecure_content_ = allow;
+ OnSetAllowDisplayingInsecureContent(allow);
+}
+
+
void ContentSettingsObserver::ClearBlockedContentSettings() {
for (size_t i = 0; i < arraysize(content_blocked_); ++i)
content_blocked_[i] = false;
@@ -322,6 +636,18 @@ void ContentSettingsObserver::ClearBlockedContentSettings() {
cached_script_permissions_.clear();
}
+const extensions::Extension* ContentSettingsObserver::GetExtension(
+ const WebSecurityOrigin& origin) const {
+ if (!EqualsASCII(origin.protocol(), extensions::kExtensionScheme))
+ return NULL;
+
+ const std::string extension_id = origin.host().utf8().data();
+ if (!extension_dispatcher_->IsExtensionActive(extension_id))
+ return NULL;
+
+ return extension_dispatcher_->extensions()->GetByID(extension_id);
+}
+
bool ContentSettingsObserver::IsWhitelistedForContentSettings(WebFrame* frame) {
// Whitelist Instant processes.
if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kInstantProcess))
diff --git a/chrome/renderer/content_settings_observer.h b/chrome/renderer/content_settings_observer.h
index ed579ae..d342564 100644
--- a/chrome/renderer/content_settings_observer.h
+++ b/chrome/renderer/content_settings_observer.h
@@ -11,6 +11,8 @@
#include "chrome/common/content_settings.h"
#include "content/public/renderer/render_view_observer.h"
#include "content/public/renderer/render_view_observer_tracker.h"
+#include "extensions/common/permissions/api_permission.h"
+#include "third_party/WebKit/public/web/WebPermissionClient.h"
class GURL;
@@ -20,12 +22,19 @@ class WebSecurityOrigin;
class WebURL;
}
+namespace extensions {
+class Dispatcher;
+class Extension;
+}
+
// Handles blocking content per content settings for each RenderView.
class ContentSettingsObserver
: public content::RenderViewObserver,
- public content::RenderViewObserverTracker<ContentSettingsObserver> {
+ public content::RenderViewObserverTracker<ContentSettingsObserver>,
+ public blink::WebPermissionClient {
public:
- explicit ContentSettingsObserver(content::RenderView* render_view);
+ ContentSettingsObserver(content::RenderView* render_view,
+ extensions::Dispatcher* extension_dispatcher);
virtual ~ContentSettingsObserver();
// Sets the content setting rules which back |AllowImage()|, |AllowScript()|,
@@ -39,31 +48,56 @@ class ContentSettingsObserver
// Sends an IPC notification that the specified content type was blocked.
void DidBlockContentType(ContentSettingsType settings_type);
- // These correspond to blink::WebPermissionClient methods.
- bool AllowDatabase(blink::WebFrame* frame,
- const blink::WebString& name,
- const blink::WebString& display_name,
- unsigned long estimated_size);
- bool AllowFileSystem(blink::WebFrame* frame);
- bool AllowImage(blink::WebFrame* frame,
- bool enabled_per_settings,
- const blink::WebURL& image_url);
- bool AllowIndexedDB(blink::WebFrame* frame,
- const blink::WebString& name,
- const blink::WebSecurityOrigin& origin);
- bool AllowPlugins(blink::WebFrame* frame, bool enabled_per_settings);
- bool AllowScript(blink::WebFrame* frame, bool enabled_per_settings);
- bool AllowScriptFromSource(blink::WebFrame* frame, bool enabled_per_settings,
- const blink::WebURL& script_url);
- bool AllowStorage(blink::WebFrame* frame, bool local);
-
- void DidNotAllowPlugins();
- void DidNotAllowScript();
- void DidNotAllowMixedScript();
-
- // These two methods are not related to content settings, they are used
- // for cases when the NPAPI plugins malfunction if used.
- void BlockNPAPIPlugins();
+ // blink::WebPermissionClient implementation.
+ virtual bool allowDatabase(blink::WebFrame* frame,
+ const blink::WebString& name,
+ const blink::WebString& display_name,
+ unsigned long estimated_size);
+ virtual bool allowFileSystem(blink::WebFrame* frame);
+ virtual bool allowImage(blink::WebFrame* frame,
+ bool enabled_per_settings,
+ const blink::WebURL& image_url);
+ virtual bool allowIndexedDB(blink::WebFrame* frame,
+ const blink::WebString& name,
+ const blink::WebSecurityOrigin& origin);
+ virtual bool allowPlugins(blink::WebFrame* frame,
+ bool enabled_per_settings);
+ virtual bool allowScript(blink::WebFrame* frame,
+ bool enabled_per_settings);
+ virtual bool allowScriptFromSource(blink::WebFrame* frame,
+ bool enabled_per_settings,
+ const blink::WebURL& script_url);
+ virtual bool allowStorage(blink::WebFrame* frame, bool local);
+ virtual bool allowReadFromClipboard(blink::WebFrame* frame,
+ bool default_value);
+ virtual bool allowWriteToClipboard(blink::WebFrame* frame,
+ bool default_value);
+#if defined(WEBPERMISSIONCLIENT_USES_FRAME_FOR_ALL_METHODS)
+ virtual bool allowWebComponents(blink::WebFrame* frame, bool);
+ virtual bool allowMutationEvents(blink::WebFrame* frame,
+ bool default_value);
+ virtual bool allowPushState(blink::WebFrame* frame);
+#else
+ virtual bool allowWebComponents(const blink::WebDocument&, bool);
+ virtual bool allowMutationEvents(const blink::WebDocument&,
+ bool default_value);
+ virtual bool allowPushState(const blink::WebDocument&);
+#endif
+ virtual bool allowWebGLDebugRendererInfo(blink::WebFrame* frame);
+ virtual void didNotAllowPlugins(blink::WebFrame* frame);
+ virtual void didNotAllowScript(blink::WebFrame* frame);
+ virtual bool allowDisplayingInsecureContent(
+ blink::WebFrame* frame,
+ bool allowed_per_settings,
+ const blink::WebSecurityOrigin& context,
+ const blink::WebURL& url);
+ virtual bool allowRunningInsecureContent(
+ blink::WebFrame* frame,
+ bool allowed_per_settings,
+ const blink::WebSecurityOrigin& context,
+ const blink::WebURL& url);
+
+ // This is used for cases when the NPAPI plugins malfunction if used.
bool AreNPAPIPluginsBlocked() const;
private:
@@ -79,10 +113,18 @@ class ContentSettingsObserver
// Message handlers.
void OnLoadBlockedPlugins(const std::string& identifier);
void OnSetAsInterstitial();
+ void OnNPAPINotSupported();
+ void OnSetAllowDisplayingInsecureContent(bool allow);
+ void OnSetAllowRunningInsecureContent(bool allow);
// Resets the |content_blocked_| array.
void ClearBlockedContentSettings();
+ // If |origin| corresponds to an installed extension, returns that extension.
+ // Otherwise returns NULL.
+ const extensions::Extension* GetExtension(
+ const blink::WebSecurityOrigin& origin) const;
+
// Helpers.
// True if |frame| contains content that is white-listed for content settings.
static bool IsWhitelistedForContentSettings(blink::WebFrame* frame);
@@ -90,6 +132,13 @@ class ContentSettingsObserver
const blink::WebSecurityOrigin& origin,
const GURL& document_url);
+ // Owned by ChromeContentRendererClient and outlive us.
+ extensions::Dispatcher* extension_dispatcher_;
+
+ // Insecure content may be permitted for the duration of this render view.
+ bool allow_displaying_insecure_content_;
+ bool allow_running_insecure_content_;
+
// A pointer to content setting rules stored by the renderer. Normally, the
// |RendererContentSettingRules| object is owned by
// |ChromeRenderProcessObserver|. In the tests it is owned by the caller of
diff --git a/chrome/renderer/content_settings_observer_browsertest.cc b/chrome/renderer/content_settings_observer_browsertest.cc
index f46865f..1dd0d84 100644
--- a/chrome/renderer/content_settings_observer_browsertest.cc
+++ b/chrome/renderer/content_settings_observer_browsertest.cc
@@ -34,7 +34,7 @@ class MockContentSettingsObserver : public ContentSettingsObserver {
MockContentSettingsObserver::MockContentSettingsObserver(
content::RenderView* render_view)
- : ContentSettingsObserver(render_view),
+ : ContentSettingsObserver(render_view, NULL),
image_url_("http://www.foo.com/image.jpg"),
image_origin_("http://www.foo.com") {
}
@@ -74,11 +74,11 @@ TEST_F(ChromeRenderViewTest, DISABLED_AllowDOMStorage) {
OnAllowDOMStorage(_, _, _, _, _)).WillByDefault(DeleteArg<4>());
EXPECT_CALL(observer,
OnAllowDOMStorage(_, _, _, _, _));
- observer.AllowStorage(view_->GetWebView()->focusedFrame(), true);
+ observer.allowStorage(view_->GetWebView()->focusedFrame(), true);
// Accessing localStorage from the same origin again shouldn't result in a
// new IPC.
- observer.AllowStorage(view_->GetWebView()->focusedFrame(), true);
+ observer.allowStorage(view_->GetWebView()->focusedFrame(), true);
::testing::Mock::VerifyAndClearExpectations(&observer);
}
@@ -189,7 +189,7 @@ TEST_F(ChromeRenderViewTest, ImagesBlockedByDefault) {
observer->SetContentSettingRules(&content_setting_rules);
EXPECT_CALL(mock_observer,
OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES));
- EXPECT_FALSE(observer->AllowImage(GetMainFrame(),
+ EXPECT_FALSE(observer->allowImage(GetMainFrame(),
true, mock_observer.image_url_));
::testing::Mock::VerifyAndClearExpectations(&observer);
@@ -206,7 +206,7 @@ TEST_F(ChromeRenderViewTest, ImagesBlockedByDefault) {
EXPECT_CALL(
mock_observer,
OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES)).Times(0);
- EXPECT_TRUE(observer->AllowImage(GetMainFrame(), true,
+ EXPECT_TRUE(observer->allowImage(GetMainFrame(), true,
mock_observer.image_url_));
::testing::Mock::VerifyAndClearExpectations(&observer);
}
@@ -233,7 +233,7 @@ TEST_F(ChromeRenderViewTest, ImagesAllowedByDefault) {
EXPECT_CALL(
mock_observer,
OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES)).Times(0);
- EXPECT_TRUE(observer->AllowImage(GetMainFrame(), true,
+ EXPECT_TRUE(observer->allowImage(GetMainFrame(), true,
mock_observer.image_url_));
::testing::Mock::VerifyAndClearExpectations(&observer);
@@ -248,7 +248,7 @@ TEST_F(ChromeRenderViewTest, ImagesAllowedByDefault) {
false));
EXPECT_CALL(mock_observer,
OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES));
- EXPECT_FALSE(observer->AllowImage(GetMainFrame(),
+ EXPECT_FALSE(observer->allowImage(GetMainFrame(),
true, mock_observer.image_url_));
::testing::Mock::VerifyAndClearExpectations(&observer);
}
@@ -372,7 +372,7 @@ TEST_F(ChromeRenderViewTest, ContentSettingsInterstitialPages) {
EXPECT_CALL(
mock_observer,
OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES)).Times(0);
- EXPECT_TRUE(observer->AllowImage(GetMainFrame(), true,
+ EXPECT_TRUE(observer->allowImage(GetMainFrame(), true,
mock_observer.image_url_));
::testing::Mock::VerifyAndClearExpectations(&observer);
}