diff options
author | yzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-15 01:26:39 +0000 |
---|---|---|
committer | yzshen@chromium.org <yzshen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-15 01:26:39 +0000 |
commit | dda548290e9f9a48c2fcd8ecc4a2c9cdb4b2fc0b (patch) | |
tree | b9acb7bcd9208535f63844ab171e124f4aca2996 | |
parent | 21c9dee7008633174272cf5b61d547916ad31ad8 (diff) | |
download | chromium_src-dda548290e9f9a48c2fcd8ecc4a2c9cdb4b2fc0b.zip chromium_src-dda548290e9f9a48c2fcd8ecc4a2c9cdb4b2fc0b.tar.gz chromium_src-dda548290e9f9a48c2fcd8ecc4a2c9cdb4b2fc0b.tar.bz2 |
Change the permission check for Pepper socket API to support both the public and private APIs.
BUG=247225
TEST=None
Review URL: https://chromiumcodereview.appspot.com/17029002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@206533 0039d316-1c4b-4281-b951-d872f2087c98
15 files changed, 90 insertions, 32 deletions
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index d58b8d7..4547ff9 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc @@ -372,6 +372,7 @@ void AwContentBrowserClient::DidCreatePpapiPlugin( bool AwContentBrowserClient::AllowPepperSocketAPI( content::BrowserContext* browser_context, const GURL& url, + bool private_api, const content::SocketPermissionRequest& params) { NOTREACHED() << "Android WebView does not support plugins"; return false; diff --git a/android_webview/browser/aw_content_browser_client.h b/android_webview/browser/aw_content_browser_client.h index 1ecd2f5..ae0267b 100644 --- a/android_webview/browser/aw_content_browser_client.h +++ b/android_webview/browser/aw_content_browser_client.h @@ -140,6 +140,7 @@ class AwContentBrowserClient : public content::ContentBrowserClient { virtual bool AllowPepperSocketAPI( content::BrowserContext* browser_context, const GURL& url, + bool private_api, const content::SocketPermissionRequest& params) OVERRIDE; private: diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 5581e8b..b1802c1 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -95,6 +95,7 @@ #include "chrome/common/extensions/extension_set.h" #include "chrome/common/extensions/manifest_handlers/app_isolation_info.h" #include "chrome/common/extensions/manifest_handlers/shared_module_info.h" +#include "chrome/common/extensions/permissions/permissions_data.h" #include "chrome/common/extensions/permissions/socket_permission.h" #include "chrome/common/logging_chrome.h" #include "chrome/common/pepper_permission_util.h" @@ -2169,6 +2170,7 @@ bool ChromeContentBrowserClient::SupportsBrowserPlugin( bool ChromeContentBrowserClient::AllowPepperSocketAPI( content::BrowserContext* browser_context, const GURL& url, + bool private_api, const content::SocketPermissionRequest& params) { #if defined(ENABLE_PLUGINS) Profile* profile = Profile::FromBrowserContext(browser_context); @@ -2177,10 +2179,32 @@ bool ChromeContentBrowserClient::AllowPepperSocketAPI( extension_set = extensions::ExtensionSystem::Get(profile)-> extension_service()->extensions(); } - return IsExtensionOrSharedModuleWhitelisted(url, - extension_set, - allowed_socket_origins_, - switches::kAllowNaClSocketAPI); + + if (private_api) { + // Access to private socket APIs is controlled by the whitelist. + if (IsExtensionOrSharedModuleWhitelisted(url, extension_set, + allowed_socket_origins_)) { + return true; + } + } else { + // Access to public socket APIs is controlled by extension permissions. + if (url.is_valid() && url.SchemeIs(extensions::kExtensionScheme) && + extension_set) { + const Extension* extension = extension_set->GetByID(url.host()); + if (extension) { + extensions::SocketPermission::CheckParam check_params( + params.type, params.host, params.port); + if (extensions::PermissionsData::CheckAPIPermissionWithParam( + extension, extensions::APIPermission::kSocket, &check_params)) { + return true; + } + } + } + } + + // Allow both public and private APIs if the command line says so. + return IsHostAllowedByCommandLine(url, extension_set, + switches::kAllowNaClSocketAPI); #else return false; #endif diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index db7b5b8..9d2a5e7 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h @@ -228,6 +228,7 @@ class ChromeContentBrowserClient : public content::ContentBrowserClient { virtual bool AllowPepperSocketAPI( content::BrowserContext* browser_context, const GURL& url, + bool private_api, const content::SocketPermissionRequest& params) OVERRIDE; virtual base::FilePath GetHyphenDictionaryDirectory() OVERRIDE; virtual ui::SelectFilePolicy* CreateSelectFilePolicy( diff --git a/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.cc b/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.cc index 96f02f6..6853ee5 100644 --- a/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.cc +++ b/chrome/browser/renderer_host/pepper/pepper_crx_file_system_message_filter.cc @@ -120,10 +120,10 @@ int32_t PepperCrxFileSystemMessageFilter::OnOpenFileSystem( extension_set = extensions::ExtensionSystem::Get(profile)-> extension_service()->extensions(); } - if (!IsExtensionOrSharedModuleWhitelisted(document_url_, - extension_set, - allowed_crxfs_origins_, - switches::kAllowNaClCrxFsAPI)) { + if (!IsExtensionOrSharedModuleWhitelisted( + document_url_, extension_set, allowed_crxfs_origins_) && + !IsHostAllowedByCommandLine( + document_url_, extension_set, switches::kAllowNaClCrxFsAPI)) { LOG(ERROR) << "Host " << document_url_.host() << " cannot use CrxFs API."; return PP_ERROR_NOACCESS; } diff --git a/chrome/common/pepper_permission_util.cc b/chrome/common/pepper_permission_util.cc index 84992d4..b34e457 100644 --- a/chrome/common/pepper_permission_util.cc +++ b/chrome/common/pepper_permission_util.cc @@ -37,16 +37,13 @@ bool HostIsInSet(const std::string& host, const std::set<std::string>& set) { bool IsExtensionOrSharedModuleWhitelisted( const GURL& url, const ExtensionSet* extension_set, - const std::set<std::string>& whitelist, - const char* command_line_switch) { - const std::string host = url.host(); - if (!url.is_valid()) + const std::set<std::string>& whitelist) { + if (!url.is_valid() || !url.SchemeIs(extensions::kExtensionScheme)) return false; - if (url.SchemeIs(extensions::kExtensionScheme) && - HostIsInSet(host, whitelist)) { + const std::string host = url.host(); + if (HostIsInSet(host, whitelist)) return true; - } // Check the modules that are imported by this extension to see if any of them // is whitelisted. @@ -69,22 +66,37 @@ bool IsExtensionOrSharedModuleWhitelisted( } } + return false; +} + +bool IsHostAllowedByCommandLine(const GURL& url, + const ExtensionSet* extension_set, + const char* command_line_switch) { + if (!url.is_valid()) + return false; + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); const std::string allowed_list = command_line.GetSwitchValueASCII(command_line_switch); + if (allowed_list.empty()) + return false; + + const std::string host = url.host(); if (allowed_list == "*") { // For now, we only allow packaged and platform apps in this wildcard. + if (!extension_set || !url.SchemeIs(extensions::kExtensionScheme)) + return false; + + const Extension* extension = extension_set->GetByID(host); return extension && (extension->GetType() == Manifest::TYPE_LEGACY_PACKAGED_APP || extension->GetType() == Manifest::TYPE_PLATFORM_APP); } - if (!allowed_list.empty()) { - base::StringTokenizer t(allowed_list, ","); - while (t.GetNext()) { - if (t.token() == host) - return true; - } + base::StringTokenizer t(allowed_list, ","); + while (t.GetNext()) { + if (t.token() == host) + return true; } return false; diff --git a/chrome/common/pepper_permission_util.h b/chrome/common/pepper_permission_util.h index 8ff9e84..81e48ba 100644 --- a/chrome/common/pepper_permission_util.h +++ b/chrome/common/pepper_permission_util.h @@ -13,14 +13,21 @@ class GURL; namespace chrome { -// Returns true if the extension (or an imported module if any) is whitelisted, -// or appears in command_line_switch. +// Returns true if the extension (or an imported module if any) is whitelisted. bool IsExtensionOrSharedModuleWhitelisted( const GURL& url, const ExtensionSet* extension_set, - const std::set<std::string>& whitelist, - const char* command_line_switch); + const std::set<std::string>& whitelist); +// Checks whether the host of |url| is allowed by |command_line_switch|. +// +// If the value of |command_line_switch| is: +// (1) '*': returns true for any packaged or platform apps; +// (2) a list of host names separated by ',': returns true if |host| is in the +// list. (NOTE: In this case, |url| doesn't have to belong to an extension.) +bool IsHostAllowedByCommandLine(const GURL& url, + const ExtensionSet* extension_set, + const char* command_line_switch); } // namespace chrome #endif // CHROME_COMMON_PEPPER_PERMISSION_UTIL_H_ diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index fb2d42c..f7377f1 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -1216,11 +1216,13 @@ bool ChromeContentRendererClient::IsPluginAllowedToCallRequestOSFileHandle( #if defined(ENABLE_PLUGINS) if (!container) return false; - return IsExtensionOrSharedModuleWhitelisted( - container->element().document().baseURL(), - extension_dispatcher_->extensions(), - allowed_file_handle_origins_, - switches::kAllowNaClFileHandleAPI); + GURL url = container->element().document().baseURL(); + const ExtensionSet* extension_set = extension_dispatcher_->extensions(); + + return IsExtensionOrSharedModuleWhitelisted(url, extension_set, + allowed_file_handle_origins_) || + IsHostAllowedByCommandLine(url, extension_set, + switches::kAllowNaClFileHandleAPI); #else return false; #endif diff --git a/content/browser/renderer_host/pepper/pepper_host_resolver_private_message_filter.cc b/content/browser/renderer_host/pepper/pepper_host_resolver_private_message_filter.cc index ba27bf4..416da3e 100644 --- a/content/browser/renderer_host/pepper/pepper_host_resolver_private_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_host_resolver_private_message_filter.cc @@ -127,6 +127,7 @@ int32_t PepperHostResolverPrivateMessageFilter::OnMsgResolve( RenderViewHost::FromID(render_process_id_, render_view_id_); if (!render_view_host || !pepper_socket_utils::CanUseSocketAPIs(external_plugin_, + true, request, render_view_host)) { return PP_ERROR_FAILED; diff --git a/content/browser/renderer_host/pepper/pepper_message_filter.cc b/content/browser/renderer_host/pepper/pepper_message_filter.cc index d423a89..8db9bc4 100644 --- a/content/browser/renderer_host/pepper/pepper_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_message_filter.cc @@ -487,6 +487,7 @@ bool PepperMessageFilter::CanUseSocketAPIs(int32 render_id, RenderViewHostImpl::FromID(process_id_, render_id); return pepper_socket_utils::CanUseSocketAPIs(external_plugin, + true, params, render_view_host); } diff --git a/content/browser/renderer_host/pepper/pepper_socket_utils.cc b/content/browser/renderer_host/pepper/pepper_socket_utils.cc index 69e6ddc..60a07e7 100644 --- a/content/browser/renderer_host/pepper/pepper_socket_utils.cc +++ b/content/browser/renderer_host/pepper/pepper_socket_utils.cc @@ -33,6 +33,7 @@ SocketPermissionRequest CreateSocketPermissionRequest( } bool CanUseSocketAPIs(bool external_plugin, + bool private_api, const SocketPermissionRequest& params, RenderViewHost* render_view_host) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -52,6 +53,7 @@ bool CanUseSocketAPIs(bool external_plugin, if (!GetContentClient()->browser()->AllowPepperSocketAPI( site_instance->GetBrowserContext(), site_instance->GetSiteURL(), + private_api, params)) { LOG(ERROR) << "Host " << site_instance->GetSiteURL().host() << " cannot use socket API or destination is not allowed"; diff --git a/content/browser/renderer_host/pepper/pepper_socket_utils.h b/content/browser/renderer_host/pepper/pepper_socket_utils.h index 4630ee2..560744a 100644 --- a/content/browser/renderer_host/pepper/pepper_socket_utils.h +++ b/content/browser/renderer_host/pepper/pepper_socket_utils.h @@ -20,6 +20,7 @@ SocketPermissionRequest CreateSocketPermissionRequest( const PP_NetAddress_Private& net_addr); bool CanUseSocketAPIs(bool external_plugin, + bool private_api, const SocketPermissionRequest& params, RenderViewHost* render_view_host); diff --git a/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc b/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc index 9095710..c88c5d0 100644 --- a/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_udp_socket_private_message_filter.cc @@ -42,6 +42,7 @@ bool CanUseSocketAPIs(const SocketPermissionRequest& request, render_view_id); return render_view_host && pepper_socket_utils::CanUseSocketAPIs(external_plugin, + true, request, render_view_host); } diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index 8feb86b..ff431bc 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc @@ -263,6 +263,7 @@ bool ContentBrowserClient::SupportsBrowserPlugin( bool ContentBrowserClient::AllowPepperSocketAPI( BrowserContext* browser_context, const GURL& url, + bool private_api, const SocketPermissionRequest& params) { return false; } diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index 100909b..eb9fc41 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h @@ -509,10 +509,13 @@ class CONTENT_EXPORT ContentBrowserClient { virtual bool SupportsBrowserPlugin(BrowserContext* browser_context, const GURL& site_url); - // Returns true if renderer processes can use Pepper TCP/UDP sockets from - // the given origin and connection type. + // Returns true if the socket operation specified by |params| is allowed + // from the given |browser_context| and |url|. |private_api| indicates whether + // this permission check is for the private Pepper socket API or the public + // one. virtual bool AllowPepperSocketAPI(BrowserContext* browser_context, const GURL& url, + bool private_api, const SocketPermissionRequest& params); // Returns the directory containing hyphenation dictionaries. |