From 78c7977d2fc51cb7b24f1eb69e1bce64b71cb51a Mon Sep 17 00:00:00 2001 From: "tschmelcher@chromium.org" Date: Fri, 5 Mar 2010 22:01:54 +0000 Subject: Introduce two new GYP variables: 1) plugin_domain_whitelist, which sets an optional domain whitelist. If specified, websites not in the list can't use the plugin. 2) plugin_enable_fullscreen_msg, which can be optionally unset to disable the Win/Mac fullscreen message. Also fix a bug in NPPluginProxy that this uncovered. TEST=built on Windows with a whitelist and without fullscreen message and verified correct behaviour in both IE and FF. Also, the whitelist logic comes almost verbatim from another Google product where it is already well-tested BUG=none Review URL: http://codereview.chromium.org/668078 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40786 0039d316-1c4b-4281-b951-d872f2087c98 --- o3d/core/core.gyp | 9 ++ o3d/core/win/d3d9/renderer_d3d9.cc | 24 ++- o3d/core/win/d3d9/renderer_d3d9.h | 4 + o3d/plugin/cross/o3d_glue.cc | 4 + o3d/plugin/cross/o3d_glue.h | 8 +- o3d/plugin/cross/whitelist.cc | 169 +++++++++++++++++++++ o3d/plugin/cross/whitelist.h | 44 ++++++ o3d/plugin/linux/main_linux.cc | 5 + o3d/plugin/mac/main_mac.mm | 5 + o3d/plugin/mac/plugin_mac.mm | 16 ++ .../npapi_host_control/win/np_plugin_proxy.cc | 16 +- .../npapi_host_control/win/np_plugin_proxy.h | 3 + o3d/plugin/plugin.gyp | 23 +++ o3d/plugin/win/main_win.cc | 5 + 14 files changed, 327 insertions(+), 8 deletions(-) create mode 100644 o3d/plugin/cross/whitelist.cc create mode 100644 o3d/plugin/cross/whitelist.h (limited to 'o3d') diff --git a/o3d/core/core.gyp b/o3d/core/core.gyp index a3e171a..d6c70cb 100644 --- a/o3d/core/core.gyp +++ b/o3d/core/core.gyp @@ -5,6 +5,8 @@ { 'variables': { 'chromium_code': 1, + # Whether to enable the English-only, Win/Mac-only fullscreen message. + 'plugin_enable_fullscreen_msg%': '1', }, 'target_defaults': { 'include_dirs': [ @@ -20,6 +22,13 @@ 'O3D_PLUGIN_VERSION="); @@ -1037,6 +1041,7 @@ Renderer::InitStatus RendererD3D9::InitPlatformSpecific( } } +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG if (S_OK != D3DXCreateFont(d3d_device_, 27 /* font_height */, @@ -1060,6 +1065,7 @@ Renderer::InitStatus RendererD3D9::InitPlatformSpecific( DLOG(ERROR) << "Failed to initialize line for message background."; return INITIALIZATION_ERROR; } +#endif return SUCCESS; } @@ -1173,6 +1179,7 @@ bool RendererD3D9::InvalidateDeviceObjects() { } } +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG if (fullscreen_message_font_ && S_OK != fullscreen_message_font_->OnLostDevice()) { return false; @@ -1181,6 +1188,8 @@ bool RendererD3D9::InvalidateDeviceObjects() { S_OK != fullscreen_message_line_->OnLostDevice()) { return false; } +#endif + return true; } @@ -1238,6 +1247,8 @@ bool RendererD3D9::RestoreDeviceObjects() { } } } + +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG if (fullscreen_message_font_ && S_OK != fullscreen_message_font_->OnResetDevice()) { return false; @@ -1246,6 +1257,7 @@ bool RendererD3D9::RestoreDeviceObjects() { S_OK != fullscreen_message_line_->OnResetDevice()) { return false; } +#endif return true; } @@ -1412,8 +1424,10 @@ bool RendererD3D9::GoFullscreen(const DisplayWindow& display, windowed = false; } +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG showing_fullscreen_message_ = true; fullscreen_message_timer_.GetElapsedTimeAndReset(); // Reset the timer. +#endif d3d_present_parameters_.FullScreen_RefreshRateInHz = refresh_rate; d3d_present_parameters_.hDeviceWindow = window; @@ -1440,7 +1454,9 @@ bool RendererD3D9::CancelFullscreen(const DisplayWindow& display, const DisplayWindowWindows& platform_display = static_cast(display); HWND window = platform_display.hwnd(); +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG showing_fullscreen_message_ = false; +#endif d3d_present_parameters_.FullScreen_RefreshRateInHz = 0; d3d_present_parameters_.hDeviceWindow = window; d3d_present_parameters_.Windowed = true; @@ -1511,6 +1527,7 @@ void RendererD3D9::PlatformSpecificFinishRendering() { back_buffer_surface_ = NULL; back_buffer_depth_surface_ = NULL; +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG if (showing_fullscreen_message_) { // Message should display for 3 seconds after transition to fullscreen. float elapsed_time = @@ -1525,6 +1542,7 @@ void RendererD3D9::PlatformSpecificFinishRendering() { } } } +#endif } } @@ -1541,6 +1559,7 @@ void RendererD3D9::PlatformSpecificPresent() { void RendererD3D9::ApplyDirtyStates() { } +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG // TODO(gman): Why is this code in here? Shouldn't this use O3D to render this // instead of D3D? void RendererD3D9::ShowFullscreenMessage(float elapsed_time, @@ -1599,6 +1618,7 @@ void RendererD3D9::ShowFullscreenMessage(float elapsed_time, d3d_device_->SetRenderState(D3DRS_ZENABLE, z_enable); } +#endif void RendererD3D9::SetRenderSurfacesPlatformSpecific( const RenderSurface* surface, diff --git a/o3d/core/win/d3d9/renderer_d3d9.h b/o3d/core/win/d3d9/renderer_d3d9.h index cd62c5c..6fe3225 100644 --- a/o3d/core/win/d3d9/renderer_d3d9.h +++ b/o3d/core/win/d3d9/renderer_d3d9.h @@ -242,12 +242,14 @@ class RendererD3D9 : public Renderer { // Indicates we're rendering fullscreen rather than in the plugin region. bool fullscreen_; +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG // Indicates we're showing the "Press Escape..." banner. bool showing_fullscreen_message_; // We want to show the message for about 3 seconds. ElapsedTimeTimer fullscreen_message_timer_; // Draws the actual message. void ShowFullscreenMessage(float elapsedTime, float display_duration); +#endif // Invalidates all resources which are in D3DPOOL_DEFAULT. // Used before we try to reset the device, when the device is lost. @@ -269,10 +271,12 @@ class RendererD3D9 : public Renderer { // Returns true on success. bool ResetDevice(); +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG // The font to use to display the message when we go to fullscreen. CComPtr fullscreen_message_font_; // The line used to draw the background for the message. CComPtr fullscreen_message_line_; +#endif }; } // namespace o3d diff --git a/o3d/plugin/cross/o3d_glue.cc b/o3d/plugin/cross/o3d_glue.cc index b3dbf6b..6a2d53f 100644 --- a/o3d/plugin/cross/o3d_glue.cc +++ b/o3d/plugin/cross/o3d_glue.cc @@ -125,7 +125,9 @@ PluginObject::PluginObject(NPP npp) event_model_(NPEventModelCarbon), mac_window_(0), mac_fullscreen_window_(0), +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG mac_fullscreen_overlay_window_(0), +#endif mac_window_selected_tab_(0), mac_cocoa_window_(0), mac_surface_hidden_(0), @@ -133,8 +135,10 @@ PluginObject::PluginObject(NPP npp) mac_agl_context_(0), mac_cgl_context_(0), last_mac_event_time_(0), +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG time_to_hide_overlay_(0.0), #endif +#endif // OS_MACOSX #ifdef OS_LINUX display_(NULL), window_(0), diff --git a/o3d/plugin/cross/o3d_glue.h b/o3d/plugin/cross/o3d_glue.h index 7d72fee..8911804 100644 --- a/o3d/plugin/cross/o3d_glue.h +++ b/o3d/plugin/cross/o3d_glue.h @@ -226,6 +226,7 @@ class PluginObject: public NPObject { GdkEvent *configure); void SetDisplay(Display *display); #elif defined(OS_MACOSX) +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG void SetFullscreenOverlayMacWindow(WindowRef window) { mac_fullscreen_overlay_window_ = window; } @@ -233,6 +234,7 @@ class PluginObject: public NPObject { WindowRef GetFullscreenOverlayMacWindow() { return mac_fullscreen_overlay_window_; } +#endif void SetFullscreenMacWindow(WindowRef window) { mac_fullscreen_window_ = window; @@ -269,13 +271,17 @@ class PluginObject: public NPObject { // Fullscreen related stuff. +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG // FullscreenIdle gets repeatedly called while we are in fullscreen mode. // Currently its only task is to hide the fullscreen message at the right // time. void FullscreenIdle(); - double time_to_hide_overlay_; + double time_to_hide_overlay_; +#endif WindowRef mac_fullscreen_window_; // NULL if not in fullscreen modee +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG WindowRef mac_fullscreen_overlay_window_; // NULL if not in fullscreen mode +#endif Ptr mac_fullscreen_state_; #endif // OS_MACOSX diff --git a/o3d/plugin/cross/whitelist.cc b/o3d/plugin/cross/whitelist.cc new file mode 100644 index 0000000..524a57b --- /dev/null +++ b/o3d/plugin/cross/whitelist.cc @@ -0,0 +1,169 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include "plugin/cross/whitelist.h" + +#include + +#include "base/basictypes.h" +#include "base/logging.h" + +namespace o3d { + +#if !defined(O3D_PLUGIN_DOMAIN_WHITELIST) && \ + !defined(O3D_PLUGIN_ENABLE_FULLSCREEN_MSG) +#error "No whitelist and no fullscreen message is a security vulnerability" +#endif + +#ifdef O3D_PLUGIN_DOMAIN_WHITELIST + +static const char *const kDomainWhitelist[] = { + // This macro contains the comma-separated string literals for the whitelist + O3D_PLUGIN_DOMAIN_WHITELIST +}; + +static const char kHttpProtocol[] = "http://"; +static const char kHttpsProtocol[] = "https://"; + +// For testing purposes assume local files valid too. +static const char kLocalFileUrlProtocol[] = "file://"; + +static std::string GetURL(NPP instance) { + // get URL for the loading page - first approach from + // http://developer.mozilla.org/en/docs/Getting_the_page_URL_in_NPAPI_plugin + // Get the window object. + // note: on some browsers, this will increment the window ref count. + // on others, it won't. + // this is a bug in.... something, but no one agrees what. + // http://lists.apple.com/archives/webkitsdk-dev/2005/Aug/msg00044.html + NPObject *window_obj = NULL; + NPError err = NPN_GetValue(instance, NPNVWindowNPObject, + &window_obj); + if (NPERR_NO_ERROR != err) { + LOG(ERROR) << "getvalue failed (err = " << err << ")"; + return ""; + } + // Create a "location" identifier. + NPIdentifier identifier = NPN_GetStringIdentifier("location"); + // Declare a local variant value. + NPVariant variant_value; + // Get the location property from the window object + // (which is another object). + bool success = NPN_GetProperty(instance, window_obj, identifier, + &variant_value); + if (!success) { + LOG(ERROR) << "getproperty failed"; + return ""; + } + // Get a pointer to the "location" object. + NPObject *location_obj = variant_value.value.objectValue; + // Create a "href" identifier. + identifier = NPN_GetStringIdentifier("href"); + // Get the location property from the location object. + success = NPN_GetProperty(instance, location_obj, identifier, + &variant_value); + if (!success) { + LOG(ERROR) << "getproperty failed"; + return ""; + } + // let's just grab the NPUTF8 from the variant and make a std::string + // from it. + std::string url(static_cast( + variant_value.value.stringValue.UTF8Characters), + static_cast( + variant_value.value.stringValue.UTF8Length)); + + NPN_ReleaseVariantValue(&variant_value); + + return url; +} + +static std::string ParseUrlHost(const std::string &in_url) { + size_t host_start; + if (in_url.find(kHttpProtocol) == 0) { + host_start = sizeof(kHttpProtocol) - 1; + } else if (in_url.find(kHttpsProtocol) == 0) { + host_start = sizeof(kHttpsProtocol) - 1; + } else { + // Do not allow usage on non http/https pages. + return ""; + } + size_t path_start = in_url.find("/", host_start); + if (path_start == std::string::npos) { + path_start = in_url.size(); + } + const std::string host_and_port( + in_url.substr(host_start, path_start - host_start)); + size_t colon_pos = host_and_port.find(":"); + if (colon_pos == std::string::npos) { + colon_pos = host_and_port.size(); + } + return host_and_port.substr(0, colon_pos); +} + +static bool IsDomainWhitelisted(const std::string &in_url) { + if (in_url.find(kLocalFileUrlProtocol) == 0) { + // Starts with file://, so it's a local file. Allow access for testing + // purposes. + return true; + } else { + std::string host(ParseUrlHost(in_url)); + + // convert the host to a lower-cased version so we + // don't have to worry about case mismatches. + for (size_t i = 0; i < host.length(); ++i) { + host[i] = tolower(host[i]); + } + + for (int i = 0; i < arraysize(kDomainWhitelist); ++i) { + size_t pos = host.rfind(kDomainWhitelist[i]); + if (pos != std::string::npos && + ((pos + strlen(kDomainWhitelist[i]) == host.length()))) + return true; + } + + return false; + } +} + +#endif // O3D_PLUGIN_DOMAIN_WHITELIST + +bool IsDomainAuthorized(NPP instance) { +#ifdef O3D_PLUGIN_DOMAIN_WHITELIST + return IsDomainWhitelisted(GetURL(instance)); +#else + // No whitelist; allow usage on any website. (This is the default.) + return true; +#endif +} + +} // namespace o3d diff --git a/o3d/plugin/cross/whitelist.h b/o3d/plugin/cross/whitelist.h new file mode 100644 index 0000000..f6cf277 --- /dev/null +++ b/o3d/plugin/cross/whitelist.h @@ -0,0 +1,44 @@ +/* + * Copyright 2009, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef O3D_PLUGIN_CROSS_WHITELIST_H_ +#define O3D_PLUGIN_CROSS_WHITELIST_H_ + +#include "third_party/nixysa/static_glue/npapi/npn_api.h" + +namespace o3d { + +bool IsDomainAuthorized(NPP instance); + +} // namespace o3d + +#endif // O3D_PLUGIN_CROSS_WHITELIST_H_ \ No newline at end of file diff --git a/o3d/plugin/linux/main_linux.cc b/o3d/plugin/linux/main_linux.cc index e1ac5ff..80bd3d5 100644 --- a/o3d/plugin/linux/main_linux.cc +++ b/o3d/plugin/linux/main_linux.cc @@ -42,6 +42,7 @@ #include "base/scoped_ptr.h" #include "plugin/cross/main.h" #include "plugin/cross/out_of_memory.h" +#include "plugin/cross/whitelist.h" #include "plugin/linux/envvars.h" using glue::_o3d::PluginObject; @@ -703,6 +704,10 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char *argn[], char *argv[], NPSavedData *saved) { HANDLE_CRASHES; + if (!IsDomainAuthorized(instance)) { + return NPERR_INVALID_URL; + } + PluginObject* pluginObject = glue::_o3d::PluginObject::Create( instance); instance->pdata = pluginObject; diff --git a/o3d/plugin/mac/main_mac.mm b/o3d/plugin/mac/main_mac.mm index c0ce16a..0241edb 100644 --- a/o3d/plugin/mac/main_mac.mm +++ b/o3d/plugin/mac/main_mac.mm @@ -51,6 +51,7 @@ #include "plugin/cross/plugin_logging.h" #include "plugin/cross/plugin_metrics.h" #include "plugin/cross/out_of_memory.h" +#include "plugin/cross/whitelist.h" #include "plugin/mac/plugin_mac.h" #include "plugin/mac/graphics_utils_mac.h" @@ -812,6 +813,10 @@ NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, } #endif // O3D_INTERNAL_PLUGIN + if (!IsDomainAuthorized(instance)) { + return NPERR_INVALID_URL; + } + PluginObject* pluginObject = glue::_o3d::PluginObject::Create( instance); instance->pdata = pluginObject; diff --git a/o3d/plugin/mac/plugin_mac.mm b/o3d/plugin/mac/plugin_mac.mm index 517f4a5..a9b42d7 100644 --- a/o3d/plugin/mac/plugin_mac.mm +++ b/o3d/plugin/mac/plugin_mac.mm @@ -239,9 +239,11 @@ void RenderTimer::TimerCallback(CFRunLoopTimerRef timer, void* info) { bool in_fullscreen = obj->GetFullscreenMacWindow(); +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG if (in_fullscreen) { obj->FullscreenIdle(); } +#endif // We're visible if (a) we are in fullscreen mode or (b) our cliprect // height and width are both a sensible size, ie > 1 pixel. @@ -384,6 +386,8 @@ static SInt32 GetIntEventParam(EventRef inEvent, EventParamName inName) { #pragma mark ____OVERLAY_WINDOW +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG + // Returns the unicode 16 chars that we need to display as the fullscreen // message. Should be disposed with free() after use. static UniChar * GetFullscreenDisplayText(int *returned_length) { @@ -570,6 +574,8 @@ static WindowRef CreateOverlayWindow(void) { return window; } +#endif // O3D_PLUGIN_ENABLE_FULLSCREEN_MSG + // Maps the MacOS button numbers to the constants used by our // event mechanism. Not quite as obvious as you might think, as the Mac @@ -770,10 +776,14 @@ static WindowRef CreateFullscreenWindow(WindowRef window, void CleanupFullscreenWindow(PluginObject *obj) { WindowRef fs_window = obj->GetFullscreenMacWindow(); +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG WindowRef fs_o_window = obj->GetFullscreenOverlayMacWindow(); +#endif obj->SetFullscreenMacWindow(NULL); +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG obj->SetFullscreenOverlayMacWindow(NULL); +#endif if (fs_window) { HideWindow(fs_window); @@ -781,11 +791,13 @@ void CleanupFullscreenWindow(PluginObject *obj) { DisposeWindow(fs_window); } +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG if(fs_o_window) { HideWindow(fs_o_window); ReleaseWindowGroup(GetWindowGroup(fs_o_window)); DisposeWindow(fs_o_window); } +#endif } #pragma mark ____SCREEN_RESOLUTION_MANAGEMENT @@ -990,6 +1002,7 @@ bool PluginObject::RequestFullscreenDisplay() { fullscreen_ = true; client()->SendResizeEvent(renderer_->width(), renderer_->height(), true); +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG SetFullscreenOverlayMacWindow(o3d::CreateOverlayWindow()); ShowWindow(mac_fullscreen_overlay_window_); o3d::SlideWindowToRect(mac_fullscreen_overlay_window_, @@ -998,6 +1011,7 @@ bool PluginObject::RequestFullscreenDisplay() { // Hide the overlay text 4 seconds from now. time_to_hide_overlay_ = [NSDate timeIntervalSinceReferenceDate] + 4.0; +#endif return true; } @@ -1035,6 +1049,7 @@ void PluginObject::CancelFullscreenDisplay() { } } +#ifdef O3D_PLUGIN_ENABLE_FULLSCREEN_MSG void PluginObject::FullscreenIdle() { if ((mac_fullscreen_overlay_window_ != NULL) && (time_to_hide_overlay_ != 0.0) && @@ -1045,6 +1060,7 @@ void PluginObject::FullscreenIdle() { kTransitionTime); } } +#endif } // namespace glue } // namespace o3d diff --git a/o3d/plugin/npapi_host_control/win/np_plugin_proxy.cc b/o3d/plugin/npapi_host_control/win/np_plugin_proxy.cc index afc97d1..5404c5f 100644 --- a/o3d/plugin/npapi_host_control/win/np_plugin_proxy.cc +++ b/o3d/plugin/npapi_host_control/win/np_plugin_proxy.cc @@ -166,7 +166,8 @@ NPPluginProxy::NPPluginProxy() NP_Initialize_(NULL), NP_GetEntryPoints_(NULL), NP_Shutdown_(NULL), - plugin_module_(0) { + plugin_module_(0), + initialized_(false) { npp_data_.ndata = npp_data_.pdata = NULL; memset(&plugin_funcs_, NULL, sizeof(plugin_funcs_)); } @@ -228,6 +229,7 @@ bool NPPluginProxy::Init(NPBrowserProxy* browser_proxy, ATLASSERT(plugin_module_ && "Plugin module not loaded before initialization."); ATLASSERT(browser_proxy && "Browser environment required for plugin init."); + ATLASSERT(!initialized_ && "Duplicate initialization"); browser_proxy_ = browser_proxy; // Store a pointer to the browser proxy instance in the netscape data @@ -254,7 +256,6 @@ bool NPPluginProxy::Init(NPBrowserProxy* browser_proxy, reinterpret_cast(argn.get()), reinterpret_cast(argv.get()), NULL)) { - NP_Shutdown_(); ATLASSERT(false && "Unknown failure creating NPAPI plugin instance."); return false; } @@ -263,7 +264,6 @@ bool NPPluginProxy::Init(NPBrowserProxy* browser_proxy, GetNPP(), const_cast(&window))) { plugin_funcs_.destroy(GetNPP(), NULL); - NP_Shutdown_(); ATLASSERT(false && "Unknown failure binding plugin window."); return false; } @@ -276,7 +276,6 @@ bool NPPluginProxy::Init(NPBrowserProxy* browser_proxy, NPPVpluginScriptableNPObject, static_cast(&np_object))) { plugin_funcs_.destroy(GetNPP(), NULL); - NP_Shutdown_(); ATLASSERT(false && "Unable to initialize NPAPI scripting interface."); return false; } @@ -286,16 +285,21 @@ bool NPPluginProxy::Init(NPBrowserProxy* browser_proxy, NPBrowserProxy::GetBrowserFunctions()->releaseobject(np_object); + initialized_ = true; + return true; } bool NPPluginProxy::SetWindow(const NPWindow& window) { + // The ATLASSERT() upon failed NPP_New() can generate a reentrant + // SetWindow() call, which we must be prepared to ignore. + if (!initialized_) return false; + if (plugin_funcs_.setwindow != NULL && NPERR_NO_ERROR != plugin_funcs_.setwindow( GetNPP(), const_cast(&window))) { plugin_funcs_.destroy(GetNPP(), NULL); - NP_Shutdown_(); ATLASSERT(false && "Unknown failure re-setting plugin window."); return false; } @@ -359,6 +363,8 @@ void NPPluginProxy::TearDown() { scriptable_object_ = NULL; plugin_funcs_.destroy(GetNPP(), NULL); } + + initialized_ = false; } void NPPluginProxy::RegisterStreamOperation(StreamOperation* stream_op) { diff --git a/o3d/plugin/npapi_host_control/win/np_plugin_proxy.h b/o3d/plugin/npapi_host_control/win/np_plugin_proxy.h index f693bf2..58509db 100644 --- a/o3d/plugin/npapi_host_control/win/np_plugin_proxy.h +++ b/o3d/plugin/npapi_host_control/win/np_plugin_proxy.h @@ -147,6 +147,9 @@ class NPPluginProxy { // by the plugin. StreamOpArray active_stream_ops_; + // Whether this plugin instance is in an initialized state. + bool initialized_; + // Global count of the number of currently live plugin instances. Used // to ensure that NP_Initialize and NP_Shutdown are called only once // per loading of the plugin module. diff --git a/o3d/plugin/plugin.gyp b/o3d/plugin/plugin.gyp index 7caf52b..8fdb21f 100644 --- a/o3d/plugin/plugin.gyp +++ b/o3d/plugin/plugin.gyp @@ -40,6 +40,7 @@ 'cross/stream_manager.cc', 'cross/stream_manager.h', 'cross/texture_static_glue.cc', + 'cross/whitelist.cc', ], 'plugin_depends': [ '../../<(jpegdir)/libjpeg.gyp:libjpeg', @@ -55,6 +56,10 @@ '../../native_client/src/shared/imc/imc.gyp:google_nacl_imc', 'idl/idl.gyp:o3dPluginIdl', ], + # A comma-separated list of strings, each double-quoted. + 'plugin_domain_whitelist%': '', + # Whether to enable the English-only, Win/Mac-only fullscreen message. + 'plugin_enable_fullscreen_msg%': '1', }, 'includes': [ '../build/common.gypi', @@ -76,6 +81,24 @@ 'O3D_PLUGIN_VENDOR_DIRECTORY="<(plugin_vendor_directory)"', 'O3D_PLUGIN_PRODUCT_DIRECTORY="<(plugin_product_directory)"', ], + 'conditions': [ + # The funky quoting here is so that GYP doesn't shoot itself in the foot + # when expanding a quoted variable which itself contains quotes. + ["""'<(plugin_domain_whitelist)' != ''""", + { + 'defines': [ + 'O3D_PLUGIN_DOMAIN_WHITELIST=<(plugin_domain_whitelist)', + ], + }, + ], + ['<(plugin_enable_fullscreen_msg) != 0', + { + 'defines': [ + 'O3D_PLUGIN_ENABLE_FULLSCREEN_MSG=1', + ], + }, + ], + ], }, 'targets': [ { diff --git a/o3d/plugin/win/main_win.cc b/o3d/plugin/win/main_win.cc index 708e84d..3f8a465 100644 --- a/o3d/plugin/win/main_win.cc +++ b/o3d/plugin/win/main_win.cc @@ -47,6 +47,7 @@ #include "core/cross/event.h" #include "plugin/cross/plugin_logging.h" #include "plugin/cross/out_of_memory.h" +#include "plugin/cross/whitelist.h" #include "statsreport/metrics.h" #include "v8/include/v8.h" #include "breakpad/win/bluescreen_detector.h" @@ -825,6 +826,10 @@ NPError NPP_New(NPMIMEType pluginType, } #endif + if (!IsDomainAuthorized(instance)) { + return NPERR_INVALID_URL; + } + PluginObject* pluginObject = glue::_o3d::PluginObject::Create( instance); instance->pdata = pluginObject; -- cgit v1.1