diff options
-rw-r--r-- | chrome_frame/chrome_frame_activex.cc | 14 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_activex_base.h | 38 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_npapi.cc | 34 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_npapi.h | 4 | ||||
-rw-r--r-- | chrome_frame/chrome_frame_plugin.h | 22 | ||||
-rw-r--r-- | chrome_frame/navigation_constraints.cc | 17 | ||||
-rw-r--r-- | chrome_frame/navigation_constraints.h | 14 | ||||
-rw-r--r-- | chrome_frame/test/util_unittests.cc | 37 |
8 files changed, 96 insertions, 84 deletions
diff --git a/chrome_frame/chrome_frame_activex.cc b/chrome_frame/chrome_frame_activex.cc index 286f351..fe3a36a 100644 --- a/chrome_frame/chrome_frame_activex.cc +++ b/chrome_frame/chrome_frame_activex.cc @@ -210,7 +210,7 @@ void ChromeFrameActivex::OnMessageFromChromeFrame(int tab_handle, if (target.compare("*") != 0) { bool drop = true; - if (is_privileged_) { + if (is_privileged()) { // Forward messages if the control is in privileged mode. ScopedComPtr<IDispatch> message_event; if (SUCCEEDED(CreateDomEvent("message", message, origin, @@ -272,7 +272,7 @@ void ChromeFrameActivex::OnAutomationServerLaunchFailed( Base::OnAutomationServerLaunchFailed(reason, server_version); if (reason == AUTOMATION_VERSION_MISMATCH && - ShouldShowVersionMismatchDialog(is_privileged_, m_spClientSite)) { + ShouldShowVersionMismatchDialog(is_privileged(), m_spClientSite)) { THREAD_SAFE_UMA_HISTOGRAM_COUNTS( "ChromeFrame.VersionMismatchDisplayed", 1); DisplayVersionMismatchWarning(m_hWnd, server_version); @@ -427,7 +427,7 @@ HRESULT ChromeFrameActivex::IOleObject_SetClientSite( handlers[i]->clear(); // Drop privileged mode on uninitialization. - is_privileged_ = false; + set_is_privileged(false); } else { ScopedComPtr<IHTMLDocument2> document; GetContainingDocument(document.Receive()); @@ -448,13 +448,13 @@ HRESULT ChromeFrameActivex::IOleObject_SetClientSite( service_hr = service->GetWantsPrivileged(&wants_privileged); if (SUCCEEDED(service_hr) && wants_privileged) - is_privileged_ = true; + set_is_privileged(true); - url_fetcher_->set_privileged_mode(is_privileged_); + url_fetcher_->set_privileged_mode(is_privileged()); } std::wstring profile_name(GetHostProcessName(false)); - if (is_privileged_) { + if (is_privileged()) { base::win::ScopedBstr automated_functions_arg; service_hr = service->GetExtensionApisToAutomate( @@ -491,7 +491,7 @@ HRESULT ChromeFrameActivex::IOleObject_SetClientSite( chrome_extra_arguments.append( ASCIIToWide(switches::kEnableExperimentalExtensionApis)); - url_fetcher_->set_frame_busting(!is_privileged_); + url_fetcher_->set_frame_busting(!is_privileged()); automation_client_->SetUrlFetcher(url_fetcher_.get()); if (!InitializeAutomation(profile_name, chrome_extra_arguments, IsIEInPrivate(), true, GURL(utf8_url), diff --git a/chrome_frame/chrome_frame_activex_base.h b/chrome_frame/chrome_frame_activex_base.h index 7d39a7e5..dfc3da0 100644 --- a/chrome_frame/chrome_frame_activex_base.h +++ b/chrome_frame/chrome_frame_activex_base.h @@ -29,7 +29,6 @@ #include "chrome_frame/chrome_frame_plugin.h" #include "chrome_frame/com_message_event.h" #include "chrome_frame/com_type_info_holder.h" -#include "chrome_frame/navigation_constraints.h" #include "chrome_frame/simple_resource_loader.h" #include "chrome_frame/urlmon_url_request.h" #include "chrome_frame/urlmon_url_request_private.h" @@ -170,8 +169,7 @@ class ATL_NO_VTABLE ChromeFrameActivexBase : // NOLINT public IPropertyNotifySinkCP<T>, public CComCoClass<T, &class_id>, public CComControl<T>, - public ChromeFramePlugin<T>, - public NavigationConstraintsImpl { + public ChromeFramePlugin<T> { protected: typedef std::set<base::win::ScopedComPtr<IDispatch> > EventHandlers; typedef ChromeFrameActivexBase<T, class_id> BasePlugin; @@ -388,7 +386,7 @@ END_MSG_MAP() // The base implementation returns true unless we are in privileged // mode, in which case we always trust our container so we return false. bool is_frame_busting_enabled() const { - return !is_privileged_; + return !is_privileged(); } // Needed to support PostTask. @@ -494,7 +492,7 @@ END_MSG_MAP() // passing mechanism between this CF instance, and the BHO that will // be constructed in the new IE tab. if (parsed_url.SchemeIs("chrome-extension") && - is_privileged_) { + is_privileged()) { const char kScheme[] = "http"; const char kHost[] = "local_host"; @@ -573,20 +571,6 @@ END_MSG_MAP() Fire_onclose(); } - // NavigationConstraints overrides. - virtual bool IsSchemeAllowed(const GURL& url) { - bool allowed = NavigationConstraintsImpl::IsSchemeAllowed(url); - if (allowed) - return true; - - if (is_privileged_ && - (url.SchemeIs(chrome::kDataScheme) || - url.SchemeIs(chrome::kExtensionScheme))) { - return true; - } - return false; - } - // Overridden to take advantage of readystate prop changes and send those // to potential listeners. HRESULT FireOnChanged(DISPID dispid) { @@ -733,7 +717,7 @@ END_MSG_MAP() } STDMETHOD(put_useChromeNetwork)(VARIANT_BOOL use_chrome_network) { - if (!is_privileged_) { + if (!is_privileged()) { DLOG(ERROR) << "Attempt to set useChromeNetwork in non-privileged mode"; return E_ACCESSDENIED; } @@ -830,7 +814,7 @@ END_MSG_MAP() if (NULL == message) return E_INVALIDARG; - if (!is_privileged_) { + if (!is_privileged()) { DLOG(ERROR) << "Attempt to postPrivateMessage in non-privileged mode"; return E_ACCESSDENIED; } @@ -859,7 +843,7 @@ END_MSG_MAP() return E_INVALIDARG; } - if (!is_privileged_) { + if (!is_privileged()) { DLOG(ERROR) << "Attempt to installExtension in non-privileged mode"; return E_ACCESSDENIED; } @@ -879,7 +863,7 @@ END_MSG_MAP() return E_INVALIDARG; } - if (!is_privileged_) { + if (!is_privileged()) { DLOG(ERROR) << "Attempt to loadExtension in non-privileged mode"; return E_ACCESSDENIED; } @@ -894,7 +878,7 @@ END_MSG_MAP() STDMETHOD(getEnabledExtensions)() { DCHECK(automation_client_.get()); - if (!is_privileged_) { + if (!is_privileged()) { DLOG(ERROR) << "Attempt to getEnabledExtensions in non-privileged mode"; return E_ACCESSDENIED; } @@ -907,7 +891,7 @@ END_MSG_MAP() DCHECK(automation_client_.get()); DCHECK(session_id); - if (!is_privileged_) { + if (!is_privileged()) { DLOG(ERROR) << "Attempt to getSessionId in non-privileged mode"; return E_ACCESSDENIED; } @@ -941,7 +925,7 @@ END_MSG_MAP() } else if (LowerCaseEqualsASCII(event_type, event_type_end, "privatemessage")) { // This event handler is only available in privileged mode. - if (is_privileged_) { + if (is_privileged()) { *handlers = &onprivatemessage_; } else { Error("Event type 'privatemessage' is privileged"); @@ -950,7 +934,7 @@ END_MSG_MAP() } else if (LowerCaseEqualsASCII(event_type, event_type_end, "extensionready")) { // This event handler is only available in privileged mode. - if (is_privileged_) { + if (is_privileged()) { *handlers = &onextensionready_; } else { Error("Event type 'extensionready' is privileged"); diff --git a/chrome_frame/chrome_frame_npapi.cc b/chrome_frame/chrome_frame_npapi.cc index 639a40a..c36c1b7 100644 --- a/chrome_frame/chrome_frame_npapi.cc +++ b/chrome_frame/chrome_frame_npapi.cc @@ -230,15 +230,15 @@ bool ChromeFrameNPAPI::Initialize(NPMIMEType mime_type, NPP instance, // Is the privileged mode requested? if (wants_privileged) { - is_privileged_ = IsFireFoxPrivilegedInvocation(instance); - if (!is_privileged_) { + set_is_privileged(IsFireFoxPrivilegedInvocation(instance)); + if (!is_privileged()) { DLOG(WARNING) << "Privileged mode requested in non-privileged context"; } } std::wstring extra_arguments; std::wstring profile_name(GetHostProcessName(false)); - if (is_privileged_) { + if (is_privileged()) { // Process any privileged mode-only arguments we were handed. if (onprivatemessage_arg) onprivatemessage_handler_ = JavascriptToNPObject(onprivatemessage_arg); @@ -260,14 +260,14 @@ bool ChromeFrameNPAPI::Initialize(NPMIMEType mime_type, NPP instance, // Setup Url fetcher. url_fetcher_.set_NPPInstance(instance_); - url_fetcher_.set_frame_busting(!is_privileged_); + url_fetcher_.set_frame_busting(!is_privileged()); automation_client_->SetUrlFetcher(&url_fetcher_); // TODO(joshia): Initialize navigation here and send proxy config as // part of LaunchSettings /* if (!src_.empty()) - automation_client_->InitiateNavigation(src_, is_privileged_); + automation_client_->InitiateNavigation(src_, is_privileged()); std::string proxy_settings; bool has_prefs = pref_service_->Initialize(instance_, @@ -439,7 +439,7 @@ void ChromeFrameNPAPI::OnAcceleratorPressed(int tab_handle, // WM_KEYUP, etc, which will result in messages like WM_CHAR, WM_SYSCHAR, etc // being posted to the message queue. We don't post these messages here to // avoid these messages from getting handled twice. - if (!is_privileged_ && + if (!is_privileged() && accel_message.message != WM_CHAR && accel_message.message != WM_DEADCHAR && accel_message.message != WM_SYSCHAR && @@ -636,7 +636,7 @@ bool ChromeFrameNPAPI::GetProperty(NPIdentifier name, } } else if (name == plugin_property_identifiers_[PLUGIN_PROPERTY_ONPRIVATEMESSAGE]) { - if (!is_privileged_) { + if (!is_privileged()) { DLOG(WARNING) << "Attempt to read onprivatemessage property while not " "privileged"; } else { @@ -669,7 +669,7 @@ bool ChromeFrameNPAPI::GetProperty(NPIdentifier name, BOOLEAN_TO_NPVARIANT(automation_client_->use_chrome_network(), *variant); return true; } else if (name == plugin_property_identifiers_[PLUGIN_PROPERTY_SESSIONID]) { - if (!is_privileged_) { + if (!is_privileged()) { DLOG(WARNING) << "Attempt to read sessionid property while not " "privileged"; } else { @@ -711,7 +711,7 @@ bool ChromeFrameNPAPI::SetProperty(NPIdentifier name, return true; } else if (name == plugin_property_identifiers_[PLUGIN_PROPERTY_ONPRIVATEMESSAGE]) { - if (!is_privileged_) { + if (!is_privileged()) { DLOG(WARNING) << "Attempt to set onprivatemessage while not privileged"; } else { onprivatemessage_handler_.Free(); @@ -823,7 +823,7 @@ void ChromeFrameNPAPI::OnMessageFromChromeFrame(int tab_handle, const std::string& target) { bool private_message = false; if (target.compare("*") != 0) { - if (is_privileged_) { + if (is_privileged()) { private_message = true; } else { if (!HaveSameOrigin(target, document_url_)) { @@ -848,7 +848,7 @@ void ChromeFrameNPAPI::OnMessageFromChromeFrame(int tab_handle, OBJECT_TO_NPVARIANT(event, params[0]); bool invoke = false; if (private_message) { - DCHECK(is_privileged_); + DCHECK(is_privileged()); STRINGN_TO_NPVARIANT(target.c_str(), target.length(), params[1]); invoke = InvokeDefault(onprivatemessage_handler_, arraysize(params), @@ -1218,7 +1218,7 @@ bool ChromeFrameNPAPI::postPrivateMessage(NPObject* npobject, const NPVariant* args, uint32_t arg_count, NPVariant* result) { - if (!is_privileged_) { + if (!is_privileged()) { DLOG(WARNING) << "postPrivateMessage invoked in non-privileged mode"; return false; } @@ -1251,7 +1251,7 @@ bool ChromeFrameNPAPI::installExtension(NPObject* npobject, return false; } - if (!is_privileged_) { + if (!is_privileged()) { DLOG(WARNING) << "installExtension invoked in non-privileged mode"; return false; } @@ -1298,7 +1298,7 @@ bool ChromeFrameNPAPI::loadExtension(NPObject* npobject, return false; } - if (!is_privileged_) { + if (!is_privileged()) { DLOG(WARNING) << "loadExtension invoked in non-privileged mode"; return false; } @@ -1331,7 +1331,7 @@ bool ChromeFrameNPAPI::enableExtensionAutomation(NPObject* npobject, return false; } - if (!is_privileged_) { + if (!is_privileged()) { DLOG(WARNING) << "enableExtensionAutomation invoked in non-privileged mode"; return false; @@ -1379,7 +1379,7 @@ bool ChromeFrameNPAPI::getEnabledExtensions(NPObject* npobject, return false; } - if (!is_privileged_) { + if (!is_privileged()) { DLOG(WARNING) << "getEnabledExtensions invoked in non-privileged mode"; return false; } @@ -1480,7 +1480,7 @@ bool ChromeFrameNPAPI::GetBrowserIncognitoMode() { bool ChromeFrameNPAPI::PreProcessContextMenu(HMENU menu) { // TODO: Remove this overridden method once HandleContextMenuCommand // implements "About Chrome Frame" handling. - if (!is_privileged_) { + if (!is_privileged()) { // Call base class (adds 'About' item). return ChromeFramePlugin::PreProcessContextMenu(menu); } diff --git a/chrome_frame/chrome_frame_npapi.h b/chrome_frame/chrome_frame_npapi.h index 3a9e61e..f05185c 100644 --- a/chrome_frame/chrome_frame_npapi.h +++ b/chrome_frame/chrome_frame_npapi.h @@ -11,7 +11,6 @@ #include "chrome_frame/chrome_frame_automation.h" #include "chrome_frame/chrome_frame_plugin.h" -#include "chrome_frame/navigation_constraints.h" #include "chrome_frame/np_browser_functions.h" #include "chrome_frame/np_event_listener.h" #include "chrome_frame/np_proxy_service.h" @@ -28,8 +27,7 @@ class nsIURI; class ChromeFrameNPAPI : public CWindowImpl<ChromeFrameNPAPI>, public ChromeFramePlugin<ChromeFrameNPAPI>, - public NpEventDelegate, - public NavigationConstraintsImpl { + public NpEventDelegate { public: typedef ChromeFramePlugin<ChromeFrameNPAPI> Base; diff --git a/chrome_frame/chrome_frame_plugin.h b/chrome_frame/chrome_frame_plugin.h index 58a76a6..7acda3c 100644 --- a/chrome_frame/chrome_frame_plugin.h +++ b/chrome_frame/chrome_frame_plugin.h @@ -14,6 +14,7 @@ #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_paths_internal.h" #include "chrome_frame/simple_resource_loader.h" +#include "chrome_frame/navigation_constraints.h" #include "chrome_frame/utils.h" #include "grit/chromium_strings.h" @@ -22,11 +23,11 @@ // A class to implement common functionality for all types of // plugins: NPAPI. ActiveX and ActiveDoc template <typename T> -class ChromeFramePlugin : public ChromeFrameDelegateImpl { +class ChromeFramePlugin + : public ChromeFrameDelegateImpl, + public NavigationConstraintsImpl { public: - ChromeFramePlugin() - : ignore_setfocus_(false), - is_privileged_(false) { + ChromeFramePlugin() : ignore_setfocus_(false){ } ~ChromeFramePlugin() { Uninitialize(); @@ -67,7 +68,7 @@ END_MSG_MAP() DCHECK(launch_params_ == NULL); // We don't want to do incognito when privileged, since we're // running in browser chrome or some other privileged context. - bool incognito_mode = !is_privileged_ && incognito; + bool incognito_mode = !is_privileged() && incognito; FilePath profile_path; GetProfilePath(profile_name, &profile_path); // The profile name could change based on the browser version. For e.g. for @@ -99,7 +100,7 @@ END_MSG_MAP() virtual void OnAutomationServerReady() { // Issue the extension automation request if we're privileged to // allow this control to handle extension requests from Chrome. - if (is_privileged_ && IsValid()) + if (is_privileged() && IsValid()) automation_client_->SetEnableExtensionAutomation(functions_enabled_); } @@ -261,14 +262,6 @@ END_MSG_MAP() // When the flag is not set, we transfer the focus to chrome. bool ignore_setfocus_; - // The plugin is privileged if it is: - // * Invoked by a window running under the system principal in FireFox. - // * Being hosted by a custom host exposing the SID_ChromeFramePrivileged - // service. - // - // When privileged, additional interfaces are made available to the user. - bool is_privileged_; - // List of functions to enable for automation, or a single entry "*" to // enable all functions for automation. Ignored unless is_privileged_ is // true. Defaults to the empty list, meaning automation will not be @@ -277,4 +270,3 @@ END_MSG_MAP() }; #endif // CHROME_FRAME_CHROME_FRAME_PLUGIN_H_ - diff --git a/chrome_frame/navigation_constraints.cc b/chrome_frame/navigation_constraints.cc index 0845bb1..78bd8df 100644 --- a/chrome_frame/navigation_constraints.cc +++ b/chrome_frame/navigation_constraints.cc @@ -9,6 +9,9 @@ #include "chrome/common/url_constants.h" #include "chrome_frame/utils.h" +NavigationConstraintsImpl::NavigationConstraintsImpl() : is_privileged_(false) { +} + // NavigationConstraintsImpl method definitions. bool NavigationConstraintsImpl::AllowUnsafeUrls() { // No sanity checks if unsafe URLs are allowed @@ -42,6 +45,13 @@ bool NavigationConstraintsImpl::IsSchemeAllowed(const GURL& url) { return true; } } + + if (is_privileged_ && + (url.SchemeIs(chrome::kDataScheme) || + url.SchemeIs(chrome::kExtensionScheme))) { + return true; + } + return false; } @@ -67,3 +77,10 @@ bool NavigationConstraintsImpl::IsZoneAllowed(const GURL& url) { return true; } +bool NavigationConstraintsImpl::is_privileged() const { + return is_privileged_; +} + +void NavigationConstraintsImpl::set_is_privileged(bool is_privileged) { + is_privileged_ = is_privileged; +} diff --git a/chrome_frame/navigation_constraints.h b/chrome_frame/navigation_constraints.h index a66cdeb..fe24558 100644 --- a/chrome_frame/navigation_constraints.h +++ b/chrome_frame/navigation_constraints.h @@ -23,15 +23,27 @@ class NavigationConstraints { // Provides default implementation for the NavigationConstraints interface. class NavigationConstraintsImpl : public NavigationConstraints { public: + NavigationConstraintsImpl(); virtual ~NavigationConstraintsImpl() {} // NavigationConstraints method overrides. virtual bool AllowUnsafeUrls(); virtual bool IsSchemeAllowed(const GURL& url); virtual bool IsZoneAllowed(const GURL& url); + + bool is_privileged() const; + void set_is_privileged(bool is_privileged); + private: base::win::ScopedComPtr<IInternetSecurityManager> security_manager_; + + // The plugin is privileged if it is: + // * Invoked by a window running under the system principal in FireFox. + // * Being hosted by a custom host exposing the SID_ChromeFramePrivileged + // service. + // + // When privileged, additional interfaces are made available to the user. + bool is_privileged_; }; #endif // CHROME_FRAME_NAVIGATION_CONSTRAINTS_H_ - diff --git a/chrome_frame/test/util_unittests.cc b/chrome_frame/test/util_unittests.cc index 68173b9..ac4bccf 100644 --- a/chrome_frame/test/util_unittests.cc +++ b/chrome_frame/test/util_unittests.cc @@ -271,6 +271,7 @@ TEST_F(UtilTests, CanNavigateTest) { { L"about:", URLZONE_TRUSTED }, { L"view-source:", URLZONE_TRUSTED }, { L"chrome-extension:", URLZONE_TRUSTED }, + { L"data:", URLZONE_INTERNET }, { L"ftp:", URLZONE_UNTRUSTED }, { L"file:", URLZONE_LOCAL_MACHINE }, { L"sip:", URLZONE_UNTRUSTED }, @@ -286,31 +287,39 @@ TEST_F(UtilTests, CanNavigateTest) { const char* url; bool default_expected; bool unsafe_expected; + bool is_privileged; } test_cases[] = { // Invalid URL - { " ", false, false }, - { "foo bar", false, false }, + { " ", false, false, false }, + { "foo bar", false, false, false }, // non-privileged test cases { "http://blah/?attach_external_tab&10&1&0&0&100&100&iexplore", true, - true }, - { "http://untrusted/bar.html", false, true }, + true, false }, + { "http://untrusted/bar.html", false, true, false }, { "http://blah/?attach_external_tab&10&1&0&0&100&100&iexplore", true, + true, false }, + { "view-source:http://www.google.ca", true, true, false }, + { "view-source:javascript:alert('foo');", false, true, false }, + { "about:blank", true, true, false }, + { "About:Version", true, true, false }, + { "about:config", false, true, false }, + { "chrome-extension://aaaaaaaaaaaaaaaaaaa/toolstrip.html", false, true, + false }, + { "ftp://www.google.ca", false, true, false }, + { "file://www.google.ca", false, true, false }, + { "file://C:\boot.ini", false, true, false }, + { "SIP:someone@10.1.2.3", false, true, false }, + + // privileged test cases + { "chrome-extension://aaaaaaaaaaaaaaaaaaa/toolstrip.html", true, true, true }, - { "view-source:http://www.google.ca", true, true }, - { "view-source:javascript:alert('foo');", false, true }, - { "about:blank", true, true }, - { "About:Version", true, true }, - { "about:config", false, true }, - { "chrome-extension://aaaaaaaaaaaaaaaaaaa/toolstrip.html", false, true }, - { "ftp://www.google.ca", false, true }, - { "file://www.google.ca", false, true }, - { "file://C:\boot.ini", false, true }, - { "SIP:someone@10.1.2.3", false, true }, + { "data://aaaaaaaaaaaaaaaaaaa/toolstrip.html", true, true, true }, }; for (int i = 0; i < arraysize(test_cases); ++i) { const Cases& test = test_cases[i]; + mock.set_is_privileged(test.is_privileged); bool actual = CanNavigate(GURL(test.url), &mock); EXPECT_EQ(test.default_expected, actual) << "Failure url: " << test.url; } |