diff options
author | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-28 19:42:59 +0000 |
---|---|---|
committer | ygorshenin@chromium.org <ygorshenin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-28 19:42:59 +0000 |
commit | 8522332eef21df16cac696d7725f4b5eeebc3be6 (patch) | |
tree | 8a2704f6dd82e0a8ef9ed247766cdb63a7728e1e /content | |
parent | a23bccf2686126046ec29b7cbe69b0b9c809a153 (diff) | |
download | chromium_src-8522332eef21df16cac696d7725f4b5eeebc3be6.zip chromium_src-8522332eef21df16cac696d7725f4b5eeebc3be6.tar.gz chromium_src-8522332eef21df16cac696d7725f4b5eeebc3be6.tar.bz2 |
TCPSockets are switched to the new Pepper proxy.
BUG=230784
TEST=browser_tests:*TCPSocket*, *TCPServerSocket*
Review URL: https://chromiumcodereview.appspot.com/22923014
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@220073 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
30 files changed, 1174 insertions, 976 deletions
diff --git a/content/browser/plugin_service_impl.cc b/content/browser/plugin_service_impl.cc index 6682a4d..3837223 100644 --- a/content/browser/plugin_service_impl.cc +++ b/content/browser/plugin_service_impl.cc @@ -328,8 +328,7 @@ PluginProcessHost* PluginServiceImpl::FindOrStartNpapiPluginProcess( PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess( int render_process_id, const base::FilePath& plugin_path, - const base::FilePath& profile_data_directory, - PpapiPluginProcessHost::PluginClient* client) { + const base::FilePath& profile_data_directory) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); if (filter_ && !filter_->CanLoadPlugin(render_process_id, plugin_path)) @@ -356,8 +355,7 @@ PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiPluginProcess( // This plugin isn't loaded by any plugin process, so create a new process. return PpapiPluginProcessHost::CreatePluginHost( - *info, profile_data_directory, - client->GetResourceContext()->GetHostResolver()); + *info, profile_data_directory); } PpapiPluginProcessHost* PluginServiceImpl::FindOrStartPpapiBrokerProcess( @@ -413,7 +411,7 @@ void PluginServiceImpl::OpenChannelToPpapiPlugin( const base::FilePath& profile_data_directory, PpapiPluginProcessHost::PluginClient* client) { PpapiPluginProcessHost* plugin_host = FindOrStartPpapiPluginProcess( - render_process_id, plugin_path, profile_data_directory, client); + render_process_id, plugin_path, profile_data_directory); if (plugin_host) { plugin_host->OpenChannelToPlugin(client); } else { diff --git a/content/browser/plugin_service_impl.h b/content/browser/plugin_service_impl.h index 6d358fd..11fb257 100644 --- a/content/browser/plugin_service_impl.h +++ b/content/browser/plugin_service_impl.h @@ -131,8 +131,7 @@ class CONTENT_EXPORT PluginServiceImpl PpapiPluginProcessHost* FindOrStartPpapiPluginProcess( int render_process_id, const base::FilePath& plugin_path, - const base::FilePath& profile_data_directory, - PpapiPluginProcessHost::PluginClient* client); + const base::FilePath& profile_data_directory); PpapiPluginProcessHost* FindOrStartPpapiBrokerProcess( int render_process_id, const base::FilePath& plugin_path); diff --git a/content/browser/ppapi_plugin_process_host.cc b/content/browser/ppapi_plugin_process_host.cc index c9aa699..30dd182 100644 --- a/content/browser/ppapi_plugin_process_host.cc +++ b/content/browser/ppapi_plugin_process_host.cc @@ -114,10 +114,9 @@ PpapiPluginProcessHost::~PpapiPluginProcessHost() { // static PpapiPluginProcessHost* PpapiPluginProcessHost::CreatePluginHost( const PepperPluginInfo& info, - const base::FilePath& profile_data_directory, - net::HostResolver* host_resolver) { + const base::FilePath& profile_data_directory) { PpapiPluginProcessHost* plugin_host = new PpapiPluginProcessHost( - info, profile_data_directory, host_resolver); + info, profile_data_directory); if (plugin_host->Init(info)) return plugin_host; @@ -206,8 +205,7 @@ void PpapiPluginProcessHost::OpenChannelToPlugin(Client* client) { PpapiPluginProcessHost::PpapiPluginProcessHost( const PepperPluginInfo& info, - const base::FilePath& profile_data_directory, - net::HostResolver* host_resolver) + const base::FilePath& profile_data_directory) : permissions_( ppapi::PpapiPermissions::GetForCommandLine(info.permissions)), profile_data_directory_(profile_data_directory), @@ -215,13 +213,11 @@ PpapiPluginProcessHost::PpapiPluginProcessHost( process_.reset(new BrowserChildProcessHostImpl( PROCESS_TYPE_PPAPI_PLUGIN, this)); - filter_ = new PepperMessageFilter(permissions_, host_resolver); - host_impl_.reset(new BrowserPpapiHostImpl(this, permissions_, info.name, info.path, profile_data_directory, - false, - filter_)); + false)); + filter_ = PepperMessageFilter::CreateForPpapiPluginProcess(permissions_); process_->GetHost()->AddFilter(filter_.get()); process_->GetHost()->AddFilter(host_impl_->message_filter().get()); @@ -243,8 +239,7 @@ PpapiPluginProcessHost::PpapiPluginProcessHost() host_impl_.reset(new BrowserPpapiHostImpl(this, permissions, std::string(), base::FilePath(), base::FilePath(), - false, - NULL)); + false)); } bool PpapiPluginProcessHost::Init(const PepperPluginInfo& info) { diff --git a/content/browser/ppapi_plugin_process_host.h b/content/browser/ppapi_plugin_process_host.h index 78d6bd6..87c79c3 100644 --- a/content/browser/ppapi_plugin_process_host.h +++ b/content/browser/ppapi_plugin_process_host.h @@ -21,10 +21,6 @@ #include "ipc/ipc_sender.h" #include "ppapi/shared_impl/ppapi_permissions.h" -namespace net { -class HostResolver; -} - namespace content { class BrowserChildProcessHostImpl; class ResourceContext; @@ -76,8 +72,7 @@ class PpapiPluginProcessHost : public BrowserChildProcessHostDelegate, static PpapiPluginProcessHost* CreatePluginHost( const PepperPluginInfo& info, - const base::FilePath& profile_data_directory, - net::HostResolver* host_resolver); + const base::FilePath& profile_data_directory); static PpapiPluginProcessHost* CreateBrokerHost( const PepperPluginInfo& info); @@ -122,8 +117,7 @@ class PpapiPluginProcessHost : public BrowserChildProcessHostDelegate, // Constructors for plugin and broker process hosts, respectively. // You must call Init before doing anything else. PpapiPluginProcessHost(const PepperPluginInfo& info, - const base::FilePath& profile_data_directory, - net::HostResolver* host_resolver); + const base::FilePath& profile_data_directory); PpapiPluginProcessHost(); // Actually launches the process with the given plugin info. Returns true diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc index 10eef8b..f23965f 100644 --- a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc +++ b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.cc @@ -4,6 +4,7 @@ #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" +#include "content/browser/renderer_host/pepper/pepper_message_filter.h" #include "content/browser/tracing/trace_message_filter.h" #include "content/common/pepper_renderer_instance_data.h" #include "content/public/browser/render_view_host.h" @@ -18,23 +19,17 @@ BrowserPpapiHost* BrowserPpapiHost::CreateExternalPluginProcess( ppapi::PpapiPermissions permissions, base::ProcessHandle plugin_child_process, IPC::ChannelProxy* channel, - net::HostResolver* host_resolver, int render_process_id, int render_view_id, const base::FilePath& profile_directory) { - scoped_refptr<PepperMessageFilter> pepper_message_filter( - new PepperMessageFilter(permissions, - host_resolver, - render_process_id, - render_view_id)); - // The plugin name and path shouldn't be needed for external plugins. BrowserPpapiHostImpl* browser_ppapi_host = new BrowserPpapiHostImpl(sender, permissions, std::string(), - base::FilePath(), profile_directory, true, - pepper_message_filter); + base::FilePath(), profile_directory, true); browser_ppapi_host->set_plugin_process_handle(plugin_child_process); + scoped_refptr<PepperMessageFilter> pepper_message_filter( + PepperMessageFilter::CreateForExternalPluginProcess(permissions)); channel->AddFilter(pepper_message_filter); channel->AddFilter(browser_ppapi_host->message_filter().get()); channel->AddFilter(new TraceMessageFilter()); @@ -48,17 +43,17 @@ BrowserPpapiHostImpl::BrowserPpapiHostImpl( const std::string& plugin_name, const base::FilePath& plugin_path, const base::FilePath& profile_data_directory, - bool external_plugin, - const scoped_refptr<PepperMessageFilter>& pepper_message_filter) + bool external_plugin) : ppapi_host_(new ppapi::host::PpapiHost(sender, permissions)), plugin_process_handle_(base::kNullProcessHandle), plugin_name_(plugin_name), plugin_path_(plugin_path), profile_data_directory_(profile_data_directory), - external_plugin_(external_plugin) { + external_plugin_(external_plugin), + ssl_context_helper_(new SSLContextHelper()) { message_filter_ = new HostMessageFilter(ppapi_host_.get()); ppapi_host_->AddHostFactoryFilter(scoped_ptr<ppapi::host::HostFactory>( - new ContentBrowserPepperHostFactory(this, pepper_message_filter))); + new ContentBrowserPepperHostFactory(this))); } BrowserPpapiHostImpl::~BrowserPpapiHostImpl() { diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h index 9723634..86c1b7c 100644 --- a/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h +++ b/content/browser/renderer_host/pepper/browser_ppapi_host_impl.h @@ -13,7 +13,7 @@ #include "base/files/file_path.h" #include "base/memory/ref_counted.h" #include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h" -#include "content/browser/renderer_host/pepper/pepper_message_filter.h" +#include "content/browser/renderer_host/pepper/ssl_context_helper.h" #include "content/common/content_export.h" #include "content/public/browser/browser_ppapi_host.h" #include "content/public/common/process_type.h" @@ -37,10 +37,7 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { const std::string& plugin_name, const base::FilePath& plugin_path, const base::FilePath& profile_data_directory, - bool external_plugin, - // TODO (ygorshenin@): remove this once TCP sockets are - // converted to the new design. - const scoped_refptr<PepperMessageFilter>& pepper_message_filter); + bool external_plugin); virtual ~BrowserPpapiHostImpl(); // BrowserPpapiHost. @@ -73,6 +70,10 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { return message_filter_; } + const scoped_refptr<SSLContextHelper>& ssl_context_helper() const { + return ssl_context_helper_; + } + private: friend class BrowserPpapiHostTest; @@ -104,6 +105,8 @@ class CONTENT_EXPORT BrowserPpapiHostImpl : public BrowserPpapiHost { // BrowserPpapiHost::CreateExternalPluginProcess. bool external_plugin_; + scoped_refptr<SSLContextHelper> ssl_context_helper_; + // Tracks all PP_Instances in this plugin and associated renderer-related // data. typedef std::map<PP_Instance, PepperRendererInstanceData> InstanceMap; diff --git a/content/browser/renderer_host/pepper/browser_ppapi_host_test.cc b/content/browser/renderer_host/pepper/browser_ppapi_host_test.cc index a8c257a..c338a99 100644 --- a/content/browser/renderer_host/pepper/browser_ppapi_host_test.cc +++ b/content/browser/renderer_host/pepper/browser_ppapi_host_test.cc @@ -16,8 +16,7 @@ BrowserPpapiHostTest::BrowserPpapiHostTest() std::string(), base::FilePath(), base::FilePath(), - false, - NULL)); + false)); ppapi_host_->set_plugin_process_handle(base::GetCurrentProcessHandle()); } diff --git a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc index f0cefc4..97e3173 100644 --- a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc +++ b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.cc @@ -15,8 +15,10 @@ #include "content/browser/renderer_host/pepper/pepper_print_settings_manager.h" #include "content/browser/renderer_host/pepper/pepper_printing_host.h" #include "content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h" +#include "content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h" #include "content/browser/renderer_host/pepper/pepper_truetype_font_list_host.h" #include "content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.h" +#include "net/socket/stream_socket.h" #include "ppapi/host/message_filter_host.h" #include "ppapi/host/ppapi_host.h" #include "ppapi/host/resource_host.h" @@ -36,18 +38,17 @@ const size_t kMaxSocketsAllowed = 1024; bool CanCreateSocket() { return - PepperUDPSocketMessageFilter::GetNumInstances() + - PepperTCPServerSocketMessageFilter::GetNumInstances() < + PepperTCPServerSocketMessageFilter::GetNumInstances() + + PepperTCPSocketMessageFilter::GetNumInstances() + + PepperUDPSocketMessageFilter::GetNumInstances() < kMaxSocketsAllowed; } } // namespace ContentBrowserPepperHostFactory::ContentBrowserPepperHostFactory( - BrowserPpapiHostImpl* host, - const scoped_refptr<PepperMessageFilter>& pepper_message_filter) - : host_(host), - pepper_message_filter_(pepper_message_filter) { + BrowserPpapiHostImpl* host) + : host_(host) { } ContentBrowserPepperHostFactory::~ContentBrowserPepperHostFactory() { @@ -102,6 +103,18 @@ scoped_ptr<ResourceHost> ContentBrowserPepperHostFactory::CreateResourceHost( return scoped_ptr<ResourceHost>(new PepperFileRefHost( host_, instance, params.pp_resource(), file_system, internal_path)); } + case PpapiHostMsg_TCPSocket_Create::ID: { + if (CanCreateSocket()) { + scoped_refptr<ResourceMessageFilter> tcp_socket( + new PepperTCPSocketMessageFilter(host_, + instance, + false)); + return scoped_ptr<ResourceHost>(new MessageFilterHost( + host_->GetPpapiHost(), instance, params.pp_resource(), tcp_socket)); + } else { + return scoped_ptr<ResourceHost>(); + } + } case PpapiHostMsg_UDPSocket_Create::ID: { if (CanCreateSocket()) { scoped_refptr<ResourceMessageFilter> udp_socket( @@ -155,8 +168,7 @@ scoped_ptr<ResourceHost> ContentBrowserPepperHostFactory::CreateResourceHost( if (message.type() == PpapiHostMsg_TCPServerSocket_CreatePrivate::ID) { if (CanCreateSocket()) { scoped_refptr<ResourceMessageFilter> tcp_server_socket( - new PepperTCPServerSocketMessageFilter(host_, instance, true, - pepper_message_filter_)); + new PepperTCPServerSocketMessageFilter(this, host_, instance, true)); return scoped_ptr<ResourceHost>(new MessageFilterHost( host_->GetPpapiHost(), instance, params.pp_resource(), tcp_server_socket)); @@ -164,6 +176,18 @@ scoped_ptr<ResourceHost> ContentBrowserPepperHostFactory::CreateResourceHost( return scoped_ptr<ResourceHost>(); } } + if (message.type() == PpapiHostMsg_TCPSocket_CreatePrivate::ID) { + if (CanCreateSocket()) { + scoped_refptr<ResourceMessageFilter> tcp_socket( + new PepperTCPSocketMessageFilter(host_, + instance, + true)); + return scoped_ptr<ResourceHost>(new MessageFilterHost( + host_->GetPpapiHost(), instance, params.pp_resource(), tcp_socket)); + } else { + return scoped_ptr<ResourceHost>(); + } + } if (message.type() == PpapiHostMsg_UDPSocket_CreatePrivate::ID) { if (CanCreateSocket()) { scoped_refptr<ResourceMessageFilter> udp_socket( @@ -191,6 +215,24 @@ scoped_ptr<ResourceHost> ContentBrowserPepperHostFactory::CreateResourceHost( return scoped_ptr<ResourceHost>(); } +scoped_ptr<ppapi::host::ResourceHost> +ContentBrowserPepperHostFactory::CreateAcceptedTCPSocket( + PP_Instance instance, + bool private_api, + net::StreamSocket* socket) { + scoped_ptr<net::StreamSocket> s(socket); + + if (!CanCreateSocket()) + return scoped_ptr<ResourceHost>(); + scoped_refptr<ResourceMessageFilter> tcp_socket( + new PepperTCPSocketMessageFilter(host_, + instance, + private_api, + s.release())); + return scoped_ptr<ResourceHost>(new MessageFilterHost( + host_->GetPpapiHost(), instance, 0, tcp_socket)); +} + const ppapi::PpapiPermissions& ContentBrowserPepperHostFactory::GetPermissions() const { return host_->GetPpapiHost()->permissions(); diff --git a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h index e39ec35..64c8b42 100644 --- a/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h +++ b/content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h @@ -7,9 +7,13 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" -#include "content/browser/renderer_host/pepper/pepper_message_filter.h" +#include "base/memory/scoped_ptr.h" #include "ppapi/host/host_factory.h" +namespace net { +class StreamSocket; +} + namespace ppapi { class PpapiPermissions; } @@ -21,11 +25,8 @@ class BrowserPpapiHostImpl; class ContentBrowserPepperHostFactory : public ppapi::host::HostFactory { public: // Non-owning pointer to the filter must outlive this class. - ContentBrowserPepperHostFactory( - BrowserPpapiHostImpl* host, - // TODO (ygorshenin@): remove this once TCP sockets are - // converted to the new design. - const scoped_refptr<PepperMessageFilter>& pepper_message_filter); + explicit ContentBrowserPepperHostFactory(BrowserPpapiHostImpl* host); + virtual ~ContentBrowserPepperHostFactory(); virtual scoped_ptr<ppapi::host::ResourceHost> CreateResourceHost( @@ -34,14 +35,20 @@ class ContentBrowserPepperHostFactory : public ppapi::host::HostFactory { PP_Instance instance, const IPC::Message& message) OVERRIDE; + // Creates ResourceHost for already accepted TCP |socket|. Takes + // ownership of the |socket|. In the case of failure returns wrapped + // NULL. + scoped_ptr<ppapi::host::ResourceHost> CreateAcceptedTCPSocket( + PP_Instance instance, + bool private_api, + net::StreamSocket* socket); + private: const ppapi::PpapiPermissions& GetPermissions() const; // Non-owning pointer. BrowserPpapiHostImpl* host_; - scoped_refptr<PepperMessageFilter> pepper_message_filter_; - DISALLOW_COPY_AND_ASSIGN(ContentBrowserPepperHostFactory); }; diff --git a/content/browser/renderer_host/pepper/pepper_message_filter.cc b/content/browser/renderer_host/pepper/pepper_message_filter.cc index 717de35..698decf 100644 --- a/content/browser/renderer_host/pepper/pepper_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_message_filter.cc @@ -6,110 +6,44 @@ #include "base/bind.h" #include "base/bind_helpers.h" -#include "base/callback.h" -#include "base/compiler_specific.h" -#include "base/files/file_path.h" #include "base/logging.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "base/threading/sequenced_worker_pool.h" -#include "base/threading/worker_pool.h" -#include "build/build_config.h" #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" -#include "content/browser/renderer_host/pepper/pepper_tcp_socket.h" #include "content/browser/renderer_host/render_process_host_impl.h" -#include "content/browser/renderer_host/render_view_host_impl.h" -#include "content/common/pepper_messages.h" -#include "content/public/browser/browser_context.h" #include "content/public/browser/browser_thread.h" -#include "content/public/browser/content_browser_client.h" -#include "content/public/browser/resource_context.h" #include "content/public/common/content_client.h" -#include "net/base/address_family.h" -#include "net/base/address_list.h" -#include "net/base/host_port_pair.h" -#include "net/base/sys_addrinfo.h" -#include "net/cert/cert_verifier.h" -#include "ppapi/c/pp_errors.h" -#include "ppapi/c/private/ppb_net_address_private.h" +#include "ppapi/c/private/ppb_network_list_private.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/api_id.h" #include "ppapi/shared_impl/private/net_address_private_impl.h" -#include "ppapi/shared_impl/socket_option_data.h" using ppapi::NetAddressPrivateImpl; namespace content { -namespace { -const size_t kMaxSocketsAllowed = 1024; -const uint32 kInvalidSocketID = 0; - -} // namespace - -PepperMessageFilter::PepperMessageFilter(int process_id, - BrowserContext* browser_context) - : plugin_type_(PLUGIN_TYPE_IN_PROCESS), - permissions_(), - process_id_(process_id), - external_plugin_render_view_id_(0), - resource_context_(browser_context->GetResourceContext()), - host_resolver_(NULL), - next_socket_id_(1) { - DCHECK(browser_context); - // Keep BrowserContext data in FILE-thread friendly storage. - browser_path_ = browser_context->GetPath(); - incognito_ = browser_context->IsOffTheRecord(); - DCHECK(resource_context_); +// static +PepperMessageFilter* PepperMessageFilter::CreateForRendererProcess() { + return new PepperMessageFilter(ppapi::PpapiPermissions(), + PLUGIN_TYPE_IN_PROCESS); } -PepperMessageFilter::PepperMessageFilter( - const ppapi::PpapiPermissions& permissions, - net::HostResolver* host_resolver) - : plugin_type_(PLUGIN_TYPE_OUT_OF_PROCESS), - permissions_(permissions), - process_id_(0), - external_plugin_render_view_id_(0), - resource_context_(NULL), - host_resolver_(host_resolver), - next_socket_id_(1), - incognito_(false) { - DCHECK(host_resolver); +// static +PepperMessageFilter* PepperMessageFilter::CreateForPpapiPluginProcess( + const ppapi::PpapiPermissions& permissions) { + return new PepperMessageFilter(permissions, + PLUGIN_TYPE_OUT_OF_PROCESS); } -PepperMessageFilter::PepperMessageFilter( - const ppapi::PpapiPermissions& permissions, - net::HostResolver* host_resolver, - int process_id, - int render_view_id) - : plugin_type_(PLUGIN_TYPE_EXTERNAL_PLUGIN), - permissions_(permissions), - process_id_(process_id), - external_plugin_render_view_id_(render_view_id), - resource_context_(NULL), - host_resolver_(host_resolver), - next_socket_id_(1) { - DCHECK(host_resolver); +// static +PepperMessageFilter* PepperMessageFilter::CreateForExternalPluginProcess( + const ppapi::PpapiPermissions& permissions) { + return new PepperMessageFilter(permissions, + PLUGIN_TYPE_EXTERNAL_PLUGIN); } bool PepperMessageFilter::OnMessageReceived(const IPC::Message& msg, bool* message_was_ok) { bool handled = true; IPC_BEGIN_MESSAGE_MAP_EX(PepperMessageFilter, msg, *message_was_ok) - // TCP messages. - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Create, OnTCPCreate) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_CreatePrivate, - OnTCPCreatePrivate) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Connect, OnTCPConnect) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_ConnectWithNetAddress, - OnTCPConnectWithNetAddress) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_SSLHandshake, - OnTCPSSLHandshake) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Read, OnTCPRead) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Write, OnTCPWrite) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_Disconnect, OnTCPDisconnect) - IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBTCPSocket_SetOption, OnTCPSetOption) - // NetworkMonitor messages. IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBNetworkMonitor_Start, OnNetworkMonitorStart) @@ -129,44 +63,11 @@ void PepperMessageFilter::OnIPAddressChanged() { GetAndSendNetworkList(); } -net::HostResolver* PepperMessageFilter::GetHostResolver() { - return resource_context_ ? - resource_context_->GetHostResolver() : host_resolver_; -} - -net::CertVerifier* PepperMessageFilter::GetCertVerifier() { - if (!cert_verifier_) - cert_verifier_.reset(net::CertVerifier::CreateDefault()); - - return cert_verifier_.get(); -} - -net::TransportSecurityState* PepperMessageFilter::GetTransportSecurityState() { - if (!transport_security_state_) - transport_security_state_.reset(new net::TransportSecurityState); - - return transport_security_state_.get(); -} - -uint32 PepperMessageFilter::AddAcceptedTCPSocket( - int32 routing_id, - uint32 plugin_dispatcher_id, - net::StreamSocket* socket) { - scoped_ptr<net::StreamSocket> s(socket); - - uint32 tcp_socket_id = GenerateSocketID(); - if (tcp_socket_id != kInvalidSocketID) { - // Currently all TCP sockets created this way correspond to - // PPB_TCPSocket_Private. - tcp_sockets_[tcp_socket_id] = linked_ptr<PepperTCPSocket>( - new PepperTCPSocket(this, - routing_id, - plugin_dispatcher_id, - tcp_socket_id, - s.release(), - true /* private_api */)); - } - return tcp_socket_id; +PepperMessageFilter::PepperMessageFilter( + const ppapi::PpapiPermissions& permissions, + PluginType plugin_type) + : plugin_type_(plugin_type), + permissions_(permissions) { } PepperMessageFilter::~PepperMessageFilter() { @@ -174,176 +75,6 @@ PepperMessageFilter::~PepperMessageFilter() { net::NetworkChangeNotifier::RemoveIPAddressObserver(this); } -void PepperMessageFilter::OnTCPCreate(int32 routing_id, - uint32 plugin_dispatcher_id, - uint32* socket_id) { - CreateTCPSocket(routing_id, plugin_dispatcher_id, false, socket_id); -} - -void PepperMessageFilter::OnTCPCreatePrivate(int32 routing_id, - uint32 plugin_dispatcher_id, - uint32* socket_id) { - CreateTCPSocket(routing_id, plugin_dispatcher_id, true, socket_id); -} - -void PepperMessageFilter::OnTCPConnect(int32 routing_id, - uint32 socket_id, - const std::string& host, - uint16_t port) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); - if (iter == tcp_sockets_.end()) { - NOTREACHED(); - return; - } - - // This is only supported by PPB_TCPSocket_Private. - if (!iter->second->private_api()) { - NOTREACHED(); - return; - } - - content::SocketPermissionRequest params( - content::SocketPermissionRequest::TCP_CONNECT, host, port); - BrowserThread::PostTaskAndReplyWithResult( - BrowserThread::UI, FROM_HERE, - base::Bind(&PepperMessageFilter::CanUseSocketAPIs, this, - routing_id, params, true /* private_api */), - base::Bind(&PepperMessageFilter::DoTCPConnect, this, - routing_id, socket_id, host, port)); -} - -void PepperMessageFilter::DoTCPConnect(int32 routing_id, - uint32 socket_id, - const std::string& host, - uint16_t port, - bool allowed) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); - if (iter == tcp_sockets_.end()) { - // Due to current permission check process (IO -> UI -> IO) some - // calls to the TCP socket interface can be intermixed (like - // Connect and Close). So, NOTREACHED() is not appropriate here. - return; - } - - if (routing_id == iter->second->routing_id() && allowed) - iter->second->Connect(host, port); - else - iter->second->SendConnectACKError(PP_ERROR_NOACCESS); -} - -void PepperMessageFilter::OnTCPConnectWithNetAddress( - int32 routing_id, - uint32 socket_id, - const PP_NetAddress_Private& net_addr) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); - if (iter == tcp_sockets_.end()) { - NOTREACHED(); - return; - } - - content::SocketPermissionRequest params = - pepper_socket_utils::CreateSocketPermissionRequest( - content::SocketPermissionRequest::TCP_CONNECT, net_addr); - BrowserThread::PostTaskAndReplyWithResult( - BrowserThread::UI, FROM_HERE, - base::Bind(&PepperMessageFilter::CanUseSocketAPIs, this, - routing_id, params, iter->second->private_api()), - base::Bind(&PepperMessageFilter::DoTCPConnectWithNetAddress, this, - routing_id, socket_id, net_addr)); -} - -void PepperMessageFilter::DoTCPConnectWithNetAddress( - int32 routing_id, - uint32 socket_id, - const PP_NetAddress_Private& net_addr, - bool allowed) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); - if (iter == tcp_sockets_.end()) { - // Due to current permission check process (IO -> UI -> IO) some - // calls to the TCP socket interface can be intermixed (like - // ConnectWithNetAddress and Close). So, NOTREACHED() is not - // appropriate here. - return; - } - - if (routing_id == iter->second->routing_id() && allowed) - iter->second->ConnectWithNetAddress(net_addr); - else - iter->second->SendConnectACKError(PP_ERROR_NOACCESS); -} - -void PepperMessageFilter::OnTCPSSLHandshake( - uint32 socket_id, - const std::string& server_name, - uint16_t server_port, - const std::vector<std::vector<char> >& trusted_certs, - const std::vector<std::vector<char> >& untrusted_certs) { - TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); - if (iter == tcp_sockets_.end()) { - NOTREACHED(); - return; - } - - // This is only supported by PPB_TCPSocket_Private. - if (!iter->second->private_api()) { - NOTREACHED(); - return; - } - - iter->second->SSLHandshake(server_name, server_port, trusted_certs, - untrusted_certs); -} - -void PepperMessageFilter::OnTCPRead(uint32 socket_id, int32_t bytes_to_read) { - TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); - if (iter == tcp_sockets_.end()) { - NOTREACHED(); - return; - } - - iter->second->Read(bytes_to_read); -} - -void PepperMessageFilter::OnTCPWrite(uint32 socket_id, - const std::string& data) { - TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); - if (iter == tcp_sockets_.end()) { - NOTREACHED(); - return; - } - - iter->second->Write(data); -} - -void PepperMessageFilter::OnTCPDisconnect(uint32 socket_id) { - TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); - if (iter == tcp_sockets_.end()) { - NOTREACHED(); - return; - } - - // Destroying the TCPSocket instance will cancel any pending completion - // callback. From this point on, there won't be any messages associated with - // this socket sent to the plugin side. - tcp_sockets_.erase(iter); -} - -void PepperMessageFilter::OnTCPSetOption(uint32 socket_id, - PP_TCPSocket_Option name, - const ppapi::SocketOptionData& value) { - TCPSocketMap::iterator iter = tcp_sockets_.find(socket_id); - if (iter == tcp_sockets_.end()) { - NOTREACHED(); - return; - } - - iter->second->SetOption(name, value); -} - void PepperMessageFilter::OnNetworkMonitorStart(uint32 plugin_dispatcher_id) { // Support all in-process plugins, and ones with "private" permissions. if (plugin_type_ != PLUGIN_TYPE_IN_PROCESS && @@ -376,56 +107,8 @@ void PepperMessageFilter::OnX509CertificateParseDER( ppapi::PPB_X509Certificate_Fields* result) { if (der.size() == 0) *succeeded = false; - *succeeded = PepperTCPSocket::GetCertificateFields(&der[0], der.size(), - result); -} - -uint32 PepperMessageFilter::GenerateSocketID() { - // TODO(yzshen): Change to use Pepper resource ID as socket ID. - // - // Generate a socket ID. For each process which sends us socket requests, IDs - // of living sockets must be unique, to each socket type. - // - // However, it is safe to generate IDs based on the internal state of a single - // PepperSocketMessageHandler object, because for each plugin or renderer - // process, there is at most one PepperMessageFilter (in other words, at most - // one PepperSocketMessageHandler) talking to it. - if (tcp_sockets_.size() >= kMaxSocketsAllowed) - return kInvalidSocketID; - - uint32 socket_id = kInvalidSocketID; - do { - // Although it is unlikely, make sure that we won't cause any trouble when - // the counter overflows. - socket_id = next_socket_id_++; - } while (socket_id == kInvalidSocketID || - tcp_sockets_.find(socket_id) != tcp_sockets_.end()); - - return socket_id; -} - -bool PepperMessageFilter::CanUseSocketAPIs( - int32 render_id, - const content::SocketPermissionRequest& params, - bool private_api) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - // External plugins always get their own PepperMessageFilter, initialized with - // a render view id. Use this instead of the one that came with the message, - // which is actually an API ID. - bool external_plugin = false; - if (plugin_type_ == PLUGIN_TYPE_EXTERNAL_PLUGIN) { - external_plugin = true; - render_id = external_plugin_render_view_id_; - } - - RenderViewHostImpl* render_view_host = - RenderViewHostImpl::FromID(process_id_, render_id); - - return pepper_socket_utils::CanUseSocketAPIs(external_plugin, - private_api, - params, - render_view_host); + *succeeded = + pepper_socket_utils::GetCertificateFields(&der[0], der.size(), result); } void PepperMessageFilter::GetAndSendNetworkList() { @@ -475,17 +158,4 @@ void PepperMessageFilter::SendNetworkList( } } -void PepperMessageFilter::CreateTCPSocket(int32 routing_id, - uint32 plugin_dispatcher_id, - bool private_api, - uint32* socket_id) { - *socket_id = GenerateSocketID(); - if (*socket_id == kInvalidSocketID) - return; - - tcp_sockets_[*socket_id] = linked_ptr<PepperTCPSocket>( - new PepperTCPSocket(this, routing_id, plugin_dispatcher_id, *socket_id, - private_api)); -} - } // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_message_filter.h b/content/browser/renderer_host/pepper/pepper_message_filter.h index 11c8fbd..3d17193 100644 --- a/content/browser/renderer_host/pepper/pepper_message_filter.h +++ b/content/browser/renderer_host/pepper/pepper_message_filter.h @@ -5,51 +5,23 @@ #ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_MESSAGE_FILTER_H_ #define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_MESSAGE_FILTER_H_ -#include <map> -#include <string> +#include <set> #include <vector> #include "base/basictypes.h" #include "base/compiler_specific.h" #include "base/files/file_path.h" -#include "base/memory/linked_ptr.h" #include "base/memory/scoped_ptr.h" -#include "base/process/process.h" #include "content/public/browser/browser_message_filter.h" -#include "content/public/browser/content_browser_client.h" -#include "content/public/common/process_type.h" #include "net/base/net_util.h" #include "net/base/network_change_notifier.h" -#include "net/http/transport_security_state.h" -#include "net/socket/stream_socket.h" -#include "net/ssl/ssl_config_service.h" -#include "ppapi/c/pp_resource.h" -#include "ppapi/c/pp_stdint.h" -#include "ppapi/c/ppb_tcp_socket.h" -#include "ppapi/c/private/ppb_flash.h" -#include "ppapi/host/ppapi_host.h" #include "ppapi/shared_impl/ppapi_permissions.h" -struct PP_NetAddress_Private; - -namespace base { -class ListValue; -} - -namespace net { -class CertVerifier; -class HostResolver; -} - namespace ppapi { class PPB_X509Certificate_Fields; -class SocketOptionData; } namespace content { -class BrowserContext; -class PepperTCPSocket; -class ResourceContext; // This class is used in two contexts, both supporting PPAPI plugins. The first // is on the renderer->browser channel, to handle requests from in-process @@ -60,20 +32,16 @@ class PepperMessageFilter : public BrowserMessageFilter, public net::NetworkChangeNotifier::IPAddressObserver { public: - // Constructor when used in the context of a render process. - PepperMessageFilter(int process_id, - BrowserContext* browser_context); + // Factory method used in the context of a renderer process. + static PepperMessageFilter* CreateForRendererProcess(); - // Constructor when used in the context of a PPAPI process.. - PepperMessageFilter(const ppapi::PpapiPermissions& permissions, - net::HostResolver* host_resolver); + // Factory method used in the context of a PPAPI process. + static PepperMessageFilter* CreateForPpapiPluginProcess( + const ppapi::PpapiPermissions& permissions); - // Constructor when used in the context of an external plugin, i.e. created by - // the embedder using BrowserPpapiHost::CreateExternalPluginProcess. - PepperMessageFilter(const ppapi::PpapiPermissions& permissions, - net::HostResolver* host_resolver, - int process_id, - int render_view_id); + // Factory method used in the context of an external plugin, + static PepperMessageFilter* CreateForExternalPluginProcess( + const ppapi::PpapiPermissions& permissions); // BrowserMessageFilter methods. virtual bool OnMessageReceived(const IPC::Message& message, @@ -82,105 +50,35 @@ class PepperMessageFilter // net::NetworkChangeNotifier::IPAddressObserver interface. virtual void OnIPAddressChanged() OVERRIDE; - // Returns the host resolver (it may come from the resource context or the - // host_resolver_ member). - net::HostResolver* GetHostResolver(); - - net::CertVerifier* GetCertVerifier(); - net::TransportSecurityState* GetTransportSecurityState(); - - // Adds already accepted socket to the internal TCP sockets table. Takes - // ownership over |socket|. In the case of failure (full socket table) - // returns 0 and deletes |socket|. Otherwise, returns generated ID for - // |socket|. - uint32 AddAcceptedTCPSocket(int32 routing_id, - uint32 plugin_dispatcher_id, - net::StreamSocket* socket); - - const net::SSLConfig& ssl_config() { return ssl_config_; } - protected: virtual ~PepperMessageFilter(); private: - struct OnConnectTcpBoundInfo { - int routing_id; - int request_id; - }; - - // Containers for sockets keyed by socked_id. - typedef std::map<uint32, linked_ptr<PepperTCPSocket> > TCPSocketMap; - // Set of disptachers ID's that have subscribed for NetworkMonitor // notifications. typedef std::set<uint32> NetworkMonitorIdSet; - void OnGetLocalTimeZoneOffset(base::Time t, double* result); - - void OnTCPCreate(int32 routing_id, - uint32 plugin_dispatcher_id, - uint32* socket_id); - void OnTCPCreatePrivate(int32 routing_id, - uint32 plugin_dispatcher_id, - uint32* socket_id); - void OnTCPConnect(int32 routing_id, - uint32 socket_id, - const std::string& host, - uint16_t port); - void OnTCPConnectWithNetAddress(int32 routing_id, - uint32 socket_id, - const PP_NetAddress_Private& net_addr); - void OnTCPSSLHandshake( - uint32 socket_id, - const std::string& server_name, - uint16_t server_port, - const std::vector<std::vector<char> >& trusted_certs, - const std::vector<std::vector<char> >& untrusted_certs); - void OnTCPRead(uint32 socket_id, int32_t bytes_to_read); - void OnTCPWrite(uint32 socket_id, const std::string& data); - void OnTCPDisconnect(uint32 socket_id); - void OnTCPSetOption(uint32 socket_id, - PP_TCPSocket_Option name, - const ppapi::SocketOptionData& value); + enum PluginType { + PLUGIN_TYPE_IN_PROCESS, + PLUGIN_TYPE_OUT_OF_PROCESS, + // External plugin means it was created through + // BrowserPpapiHost::CreateExternalPluginProcess. + PLUGIN_TYPE_EXTERNAL_PLUGIN, + }; + + PepperMessageFilter(const ppapi::PpapiPermissions& permissions, + PluginType plugin_type); void OnNetworkMonitorStart(uint32 plugin_dispatcher_id); void OnNetworkMonitorStop(uint32 plugin_dispatcher_id); - void DoTCPConnect(int32 routing_id, - uint32 socket_id, - const std::string& host, - uint16_t port, - bool allowed); - void DoTCPConnectWithNetAddress(int32 routing_id, - uint32 socket_id, - const PP_NetAddress_Private& net_addr, - bool allowed); void OnX509CertificateParseDER(const std::vector<char>& der, bool* succeeded, ppapi::PPB_X509Certificate_Fields* result); - void OnUpdateActivity(); - - uint32 GenerateSocketID(); - - // Return true if render with given ID can use socket APIs. - bool CanUseSocketAPIs(int32 render_id, - const content::SocketPermissionRequest& params, - bool private_api); void GetAndSendNetworkList(); void DoGetNetworkList(); void SendNetworkList(scoped_ptr<net::NetworkInterfaceList> list); - void CreateTCPSocket(int32 routing_id, - uint32 plugin_dispatcher_id, - bool private_api, - uint32* socket_id); - enum PluginType { - PLUGIN_TYPE_IN_PROCESS, - PLUGIN_TYPE_OUT_OF_PROCESS, - // External plugin means it was created through - // BrowserPpapiHost::CreateExternalPluginProcess. - PLUGIN_TYPE_EXTERNAL_PLUGIN, - }; PluginType plugin_type_; @@ -190,39 +88,8 @@ class PepperMessageFilter // be many plugins sharing this channel). ppapi::PpapiPermissions permissions_; - // Render process ID. - int process_id_; - - // External plugin RenderView id to determine private API access. Normally, we - // handle messages coming from multiple RenderViews, but external plugins - // always creates a new PepperMessageFilter for each RenderView. - int external_plugin_render_view_id_; - - // When non-NULL, this should be used instead of the host_resolver_. - ResourceContext* const resource_context_; - - // When non-NULL, this should be used instead of the resource_context_. Use - // GetHostResolver instead of accessing directly. - net::HostResolver* host_resolver_; - - // The default SSL configuration settings are used, as opposed to Chrome's SSL - // settings. - net::SSLConfig ssl_config_; - // This is lazily created. Users should use GetCertVerifier to retrieve it. - scoped_ptr<net::CertVerifier> cert_verifier_; - // This is lazily created. Users should use GetTransportSecurityState to - // retrieve it. - scoped_ptr<net::TransportSecurityState> transport_security_state_; - - uint32 next_socket_id_; - - TCPSocketMap tcp_sockets_; - NetworkMonitorIdSet network_monitor_ids_; - base::FilePath browser_path_; - bool incognito_; - DISALLOW_COPY_AND_ASSIGN(PepperMessageFilter); }; diff --git a/content/browser/renderer_host/pepper/pepper_renderer_connection.cc b/content/browser/renderer_host/pepper/pepper_renderer_connection.cc index 8b07a6f..4573acf 100644 --- a/content/browser/renderer_host/pepper/pepper_renderer_connection.cc +++ b/content/browser/renderer_host/pepper/pepper_renderer_connection.cc @@ -30,8 +30,7 @@ PepperRendererConnection::PepperRendererConnection(int render_process_id) "", base::FilePath(), base::FilePath(), - false, - NULL)); + false)); } PepperRendererConnection::~PepperRendererConnection() { diff --git a/content/browser/renderer_host/pepper/pepper_socket_utils.cc b/content/browser/renderer_host/pepper/pepper_socket_utils.cc index 9dc585e..32f2ef4 100644 --- a/content/browser/renderer_host/pepper/pepper_socket_utils.cc +++ b/content/browser/renderer_host/pepper/pepper_socket_utils.cc @@ -8,13 +8,16 @@ #include <vector> #include "base/logging.h" +#include "base/memory/ref_counted.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/content_browser_client.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/site_instance.h" #include "content/public/common/content_client.h" +#include "net/cert/x509_certificate.h" #include "ppapi/c/private/ppb_net_address_private.h" #include "ppapi/shared_impl/private/net_address_private_impl.h" +#include "ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h" namespace content { namespace pepper_socket_utils { @@ -77,5 +80,60 @@ bool CanUseSocketAPIs(bool external_plugin, return true; } +bool GetCertificateFields(const net::X509Certificate& cert, + ppapi::PPB_X509Certificate_Fields* fields) { + const net::CertPrincipal& issuer = cert.issuer(); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_COMMON_NAME, + new base::StringValue(issuer.common_name)); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_LOCALITY_NAME, + new base::StringValue(issuer.locality_name)); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_STATE_OR_PROVINCE_NAME, + new base::StringValue(issuer.state_or_province_name)); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_COUNTRY_NAME, + new base::StringValue(issuer.country_name)); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_ORGANIZATION_NAME, + new base::StringValue(JoinString(issuer.organization_names, '\n'))); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_ISSUER_ORGANIZATION_UNIT_NAME, + new base::StringValue(JoinString(issuer.organization_unit_names, '\n'))); + + const net::CertPrincipal& subject = cert.subject(); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_COMMON_NAME, + new base::StringValue(subject.common_name)); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_LOCALITY_NAME, + new base::StringValue(subject.locality_name)); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_STATE_OR_PROVINCE_NAME, + new base::StringValue(subject.state_or_province_name)); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_COUNTRY_NAME, + new base::StringValue(subject.country_name)); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_ORGANIZATION_NAME, + new base::StringValue(JoinString(subject.organization_names, '\n'))); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_SUBJECT_ORGANIZATION_UNIT_NAME, + new base::StringValue(JoinString(subject.organization_unit_names, '\n'))); + + const std::string& serial_number = cert.serial_number(); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_SERIAL_NUMBER, + base::BinaryValue::CreateWithCopiedBuffer(serial_number.data(), + serial_number.length())); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_VALIDITY_NOT_BEFORE, + new base::FundamentalValue(cert.valid_start().ToDoubleT())); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_VALIDITY_NOT_AFTER, + new base::FundamentalValue(cert.valid_expiry().ToDoubleT())); + std::string der; + net::X509Certificate::GetDEREncoded(cert.os_cert_handle(), &der); + fields->SetField(PP_X509CERTIFICATE_PRIVATE_RAW, + base::BinaryValue::CreateWithCopiedBuffer(der.data(), der.length())); + return true; +} + +bool GetCertificateFields(const char* der, + uint32_t length, + ppapi::PPB_X509Certificate_Fields* fields) { + scoped_refptr<net::X509Certificate> cert = + net::X509Certificate::CreateFromBytes(der, length); + if (!cert.get()) + return false; + return GetCertificateFields(*cert.get(), fields); +} + } // namespace pepper_socket_utils } // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_socket_utils.h b/content/browser/renderer_host/pepper/pepper_socket_utils.h index 7a0cef5..7a1e16b 100644 --- a/content/browser/renderer_host/pepper/pepper_socket_utils.h +++ b/content/browser/renderer_host/pepper/pepper_socket_utils.h @@ -6,9 +6,18 @@ #define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_SOCKET_UTILS_H_ #include "content/public/common/socket_permission_request.h" +#include "ppapi/c/pp_stdint.h" struct PP_NetAddress_Private; +namespace net { +class X509Certificate; +} + +namespace ppapi { +class PPB_X509Certificate_Fields; +} + namespace content { class RenderViewHost; @@ -31,6 +40,17 @@ bool CanUseSocketAPIs(bool external_plugin, const SocketPermissionRequest& params, RenderViewHost* render_view_host); +// Extracts the certificate field data from a net::X509Certificate into +// PPB_X509Certificate_Fields. +bool GetCertificateFields(const net::X509Certificate& cert, + ppapi::PPB_X509Certificate_Fields* fields); + +// Extracts the certificate field data from the DER representation of a +// certificate into PPB_X509Certificate_Fields. +bool GetCertificateFields(const char* der, + uint32_t length, + ppapi::PPB_X509Certificate_Fields* fields); + } // namespace pepper_socket_utils } // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc b/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc index 48c8291..af2234d 100644 --- a/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc @@ -8,6 +8,7 @@ #include "base/bind_helpers.h" #include "base/logging.h" #include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" +#include "content/browser/renderer_host/pepper/content_browser_pepper_host_factory.h" #include "content/browser/renderer_host/pepper/pepper_socket_utils.h" #include "content/public/browser/browser_thread.h" #include "content/public/common/socket_permission_request.h" @@ -20,6 +21,8 @@ #include "ppapi/c/private/ppb_net_address_private.h" #include "ppapi/host/dispatch_host_message.h" #include "ppapi/host/error_conversion.h" +#include "ppapi/host/ppapi_host.h" +#include "ppapi/host/resource_host.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/api_id.h" #include "ppapi/shared_impl/private/net_address_private_impl.h" @@ -36,18 +39,21 @@ size_t g_num_instances = 0; namespace content { PepperTCPServerSocketMessageFilter::PepperTCPServerSocketMessageFilter( + ContentBrowserPepperHostFactory* factory, BrowserPpapiHostImpl* host, PP_Instance instance, - bool private_api, - const scoped_refptr<PepperMessageFilter>& pepper_message_filter) - : state_(STATE_BEFORE_LISTENING), - pepper_message_filter_(pepper_message_filter), + bool private_api) + : ppapi_host_(host->GetPpapiHost()), + factory_(factory), + instance_(instance), + state_(STATE_BEFORE_LISTENING), external_plugin_(host->external_plugin()), private_api_(private_api), render_process_id_(0), render_view_id_(0) { ++g_num_instances; - DCHECK(host); + DCHECK(factory_); + DCHECK(ppapi_host_); if (!host->GetRenderViewIDsForInstance(instance, &render_process_id_, &render_view_id_)) { @@ -83,7 +89,7 @@ int32_t PepperTCPServerSocketMessageFilter::OnResourceMessageReceived( IPC_BEGIN_MESSAGE_MAP(PepperTCPServerSocketMessageFilter, msg) PPAPI_DISPATCH_HOST_RESOURCE_CALL( PpapiHostMsg_TCPServerSocket_Listen, OnMsgListen) - PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( PpapiHostMsg_TCPServerSocket_Accept, OnMsgAccept) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( PpapiHostMsg_TCPServerSocket_StopListening, OnMsgStopListening) @@ -117,8 +123,7 @@ int32_t PepperTCPServerSocketMessageFilter::OnMsgListen( } int32_t PepperTCPServerSocketMessageFilter::OnMsgAccept( - const ppapi::host::HostMessageContext* context, - uint32 plugin_dispatcher_id) { + const ppapi::host::HostMessageContext* context) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); DCHECK(context); @@ -131,10 +136,9 @@ int32_t PepperTCPServerSocketMessageFilter::OnMsgAccept( int net_result = socket_->Accept( &socket_buffer_, base::Bind(&PepperTCPServerSocketMessageFilter::OnAcceptCompleted, - base::Unretained(this), - reply_context, plugin_dispatcher_id)); + base::Unretained(this), reply_context)); if (net_result != net::ERR_IO_PENDING) - OnAcceptCompleted(reply_context, plugin_dispatcher_id, net_result); + OnAcceptCompleted(reply_context, net_result); return PP_OK_COMPLETIONPENDING; } @@ -211,7 +215,6 @@ void PepperTCPServerSocketMessageFilter::OnListenCompleted( void PepperTCPServerSocketMessageFilter::OnAcceptCompleted( const ppapi::host::ReplyMessageContext& context, - uint32 plugin_dispatcher_id, int net_result) { if (state_ != STATE_ACCEPT_IN_PROGRESS) { SendAcceptError(context, PP_ERROR_FAILED); @@ -260,16 +263,18 @@ void PepperTCPServerSocketMessageFilter::OnAcceptCompleted( SendAcceptError(context, PP_ERROR_FAILED); return; } - if (!pepper_message_filter_.get() || plugin_dispatcher_id == 0) { - SendAcceptError(context, PP_ERROR_FAILED); + + scoped_ptr<ppapi::host::ResourceHost> host = + factory_->CreateAcceptedTCPSocket( + instance_, true /* private_api */, socket.release()); + if (!host) { + SendAcceptError(context, PP_ERROR_NOSPACE); return; } - uint32 accepted_socket_id = pepper_message_filter_->AddAcceptedTCPSocket( - ppapi::API_ID_PPB_TCPSOCKET_PRIVATE, - plugin_dispatcher_id, - socket.release()); - if (accepted_socket_id != 0) { - SendAcceptReply(context, PP_OK, accepted_socket_id, local_addr, + int pending_resource_id = ppapi_host_->AddPendingResourceHost(host.Pass()); + if (pending_resource_id) { + SendAcceptReply(context, PP_OK, pending_resource_id, + local_addr, remote_addr); } else { SendAcceptError(context, PP_ERROR_NOSPACE); @@ -296,13 +301,13 @@ void PepperTCPServerSocketMessageFilter::SendListenError( void PepperTCPServerSocketMessageFilter::SendAcceptReply( const ppapi::host::ReplyMessageContext& context, int32_t pp_result, - uint32 accepted_socket_id, + int pending_resource_id, const PP_NetAddress_Private& local_addr, const PP_NetAddress_Private& remote_addr) { ppapi::host::ReplyMessageContext reply_context(context); reply_context.params.set_result(pp_result); SendReply(reply_context, PpapiPluginMsg_TCPServerSocket_AcceptReply( - accepted_socket_id, local_addr, remote_addr)); + pending_resource_id, local_addr, remote_addr)); } void PepperTCPServerSocketMessageFilter::SendAcceptError( diff --git a/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h b/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h index ad8cf19..d36b787 100644 --- a/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h +++ b/content/browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h @@ -9,7 +9,6 @@ #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "content/browser/renderer_host/pepper/pepper_message_filter.h" #include "content/common/content_export.h" #include "ppapi/c/pp_instance.h" #include "ppapi/host/resource_message_filter.h" @@ -21,18 +20,25 @@ class ServerSocket; class StreamSocket; } +namespace ppapi { +namespace host { +class PpapiHost; +} +} + namespace content { class BrowserPpapiHostImpl; +class ContentBrowserPepperHostFactory; class CONTENT_EXPORT PepperTCPServerSocketMessageFilter : public ppapi::host::ResourceMessageFilter { public: PepperTCPServerSocketMessageFilter( + ContentBrowserPepperHostFactory* factory, BrowserPpapiHostImpl* host, PP_Instance instance, - bool private_api, - const scoped_refptr<PepperMessageFilter>& pepper_message_filter); + bool private_api); static size_t GetNumInstances(); @@ -58,8 +64,7 @@ class CONTENT_EXPORT PepperTCPServerSocketMessageFilter int32_t OnMsgListen(const ppapi::host::HostMessageContext* context, const PP_NetAddress_Private& addr, int32_t backlog); - int32_t OnMsgAccept(const ppapi::host::HostMessageContext* context, - uint32 plugin_dispatcher_id); + int32_t OnMsgAccept(const ppapi::host::HostMessageContext* context); int32_t OnMsgStopListening(const ppapi::host::HostMessageContext* context); void DoListen(const ppapi::host::ReplyMessageContext& context, @@ -69,7 +74,6 @@ class CONTENT_EXPORT PepperTCPServerSocketMessageFilter void OnListenCompleted(const ppapi::host::ReplyMessageContext& context, int net_result); void OnAcceptCompleted(const ppapi::host::ReplyMessageContext& context, - uint32 plugin_dispatcher_id, int net_result); void SendListenReply(const ppapi::host::ReplyMessageContext& context, @@ -79,17 +83,22 @@ class CONTENT_EXPORT PepperTCPServerSocketMessageFilter int32_t pp_result); void SendAcceptReply(const ppapi::host::ReplyMessageContext& context, int32_t pp_result, - uint32 accepted_socket_id, + int pending_resource_id, const PP_NetAddress_Private& local_addr, const PP_NetAddress_Private& remote_addr); void SendAcceptError(const ppapi::host::ReplyMessageContext& context, int32_t pp_result); // Following fields are initialized and used only on the IO thread. + // Non-owning ptr. + ppapi::host::PpapiHost* ppapi_host_; + // Non-owning ptr. + ContentBrowserPepperHostFactory* factory_; + PP_Instance instance_; + State state_; scoped_ptr<net::ServerSocket> socket_; scoped_ptr<net::StreamSocket> socket_buffer_; - scoped_refptr<PepperMessageFilter> pepper_message_filter_; // Following fields are initialized on the IO thread but used only // on the UI thread. diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket.h b/content/browser/renderer_host/pepper/pepper_tcp_socket.h deleted file mode 100644 index 986afb0..0000000 --- a/content/browser/renderer_host/pepper/pepper_tcp_socket.h +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_H_ -#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_H_ - -#include <string> - -#include "base/basictypes.h" -#include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" -#include "net/base/address_list.h" -#include "net/base/completion_callback.h" -#include "ppapi/c/pp_stdint.h" -#include "ppapi/c/ppb_tcp_socket.h" - -struct PP_NetAddress_Private; - -namespace ppapi { -class PPB_X509Certificate_Fields; -class SocketOptionData; -} - -namespace net { -class DrainableIOBuffer; -class IOBuffer; -class SingleRequestHostResolver; -class StreamSocket; -class X509Certificate; -} - -namespace content { -class PepperMessageFilter; - -// PepperTCPSocket is used by PepperMessageFilter to handle requests from -// the Pepper TCP socket API (PPB_TCPSocket and PPB_TCPSocket_Private). -class PepperTCPSocket { - public: - PepperTCPSocket(PepperMessageFilter* manager, - int32 routing_id, - uint32 plugin_dispatcher_id, - uint32 socket_id, - bool private_api); - - // Used for creation already connected sockets. Takes ownership of - // |socket|. - PepperTCPSocket(PepperMessageFilter* manager, - int32 routing_id, - uint32 plugin_dispatcher_id, - uint32 socket_id, - net::StreamSocket* socket, - bool private_api); - ~PepperTCPSocket(); - - int routing_id() { return routing_id_; } - bool private_api() const { return private_api_; } - - void Connect(const std::string& host, uint16_t port); - void ConnectWithNetAddress(const PP_NetAddress_Private& net_addr); - void SSLHandshake( - const std::string& server_name, - uint16_t server_port, - const std::vector<std::vector<char> >& trusted_certs, - const std::vector<std::vector<char> >& untrusted_certs); - void Read(int32 bytes_to_read); - void Write(const std::string& data); - void SetOption(PP_TCPSocket_Option name, - const ppapi::SocketOptionData& value); - - void SendConnectACKError(int32_t error); - - // Extracts the certificate field data from a |net::X509Certificate| into - // |PPB_X509Certificate_Fields|. - static bool GetCertificateFields(const net::X509Certificate& cert, - ppapi::PPB_X509Certificate_Fields* fields); - // Extracts the certificate field data from the DER representation of a - // certificate into |PPB_X509Certificate_Fields|. - static bool GetCertificateFields(const char* der, - uint32_t length, - ppapi::PPB_X509Certificate_Fields* fields); - - private: - enum ConnectionState { - // Before a connection is successfully established (including a previous - // connect request failed). - BEFORE_CONNECT, - // There is a connect request that is pending. - CONNECT_IN_PROGRESS, - // A connection has been successfully established. - CONNECTED, - // There is an SSL handshake request that is pending. - SSL_HANDSHAKE_IN_PROGRESS, - // An SSL connection has been successfully established. - SSL_CONNECTED, - // An SSL handshake has failed. - SSL_HANDSHAKE_FAILED - }; - - void StartConnect(const net::AddressList& addresses); - - void SendReadACKError(int32_t error); - void SendWriteACKError(int32_t error); - void SendSSLHandshakeACK(bool succeeded); - void SendSetOptionACK(int32_t result); - - void OnResolveCompleted(int net_result); - void OnConnectCompleted(int net_result); - void OnSSLHandshakeCompleted(int net_result); - void OnReadCompleted(int net_result); - void OnWriteCompleted(int net_result); - - bool IsConnected() const; - bool IsSsl() const; - - // Actually does a write from |write_buffer_|; possibly called many times for - // each |Write()|. - void DoWrite(); - - PepperMessageFilter* manager_; - int32 routing_id_; - uint32 plugin_dispatcher_id_; - uint32 socket_id_; - bool private_api_; - - ConnectionState connection_state_; - bool end_of_file_reached_; - - scoped_ptr<net::SingleRequestHostResolver> resolver_; - net::AddressList address_list_; - - scoped_ptr<net::StreamSocket> socket_; - - scoped_refptr<net::IOBuffer> read_buffer_; - - // |StreamSocket::Write()| may not always write the full buffer, but we would - // rather have our |Write()| do so whenever possible. To do this, we may have - // to call the former multiple times for each of the latter. This entails - // using a |DrainableIOBuffer|, which requires an underlying base |IOBuffer|. - scoped_refptr<net::IOBuffer> write_buffer_base_; - scoped_refptr<net::DrainableIOBuffer> write_buffer_; - - DISALLOW_COPY_AND_ASSIGN(PepperTCPSocket); -}; - -} // namespace content - -#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_H_ diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc new file mode 100644 index 0000000..2ec8c54 --- /dev/null +++ b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc @@ -0,0 +1,648 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h" + +#include "base/bind.h" +#include "base/logging.h" +#include "content/browser/renderer_host/pepper/browser_ppapi_host_impl.h" +#include "content/browser/renderer_host/pepper/pepper_socket_utils.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/resource_context.h" +#include "content/public/common/socket_permission_request.h" +#include "net/base/host_port_pair.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "net/dns/single_request_host_resolver.h" +#include "net/socket/client_socket_factory.h" +#include "net/socket/client_socket_handle.h" +#include "net/socket/ssl_client_socket.h" +#include "net/socket/tcp_client_socket.h" +#include "ppapi/c/private/ppb_net_address_private.h" +#include "ppapi/host/dispatch_host_message.h" +#include "ppapi/host/error_conversion.h" +#include "ppapi/proxy/ppapi_messages.h" +#include "ppapi/proxy/tcp_socket_resource_base.h" +#include "ppapi/shared_impl/private/net_address_private_impl.h" + +using ppapi::NetAddressPrivateImpl; +using ppapi::host::NetErrorToPepperError; +using ppapi::proxy::TCPSocketResourceBase; + +namespace { + +size_t g_num_instances = 0; + +} // namespace + +namespace content { + +PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter( + BrowserPpapiHostImpl* host, + PP_Instance instance, + bool private_api) + : external_plugin_(host->external_plugin()), + private_api_(private_api), + render_process_id_(0), + render_view_id_(0), + state_(STATE_BEFORE_CONNECT), + end_of_file_reached_(false), + ssl_context_helper_(host->ssl_context_helper()) { + DCHECK(host); + ++g_num_instances; + if (!host->GetRenderViewIDsForInstance(instance, + &render_process_id_, + &render_view_id_)) { + NOTREACHED(); + } +} + +PepperTCPSocketMessageFilter::PepperTCPSocketMessageFilter( + BrowserPpapiHostImpl* host, + PP_Instance instance, + bool private_api, + net::StreamSocket* socket) + : external_plugin_(host->external_plugin()), + private_api_(private_api), + render_process_id_(0), + render_view_id_(0), + state_(STATE_CONNECTED), + end_of_file_reached_(false), + socket_(socket), + ssl_context_helper_(host->ssl_context_helper()) { + DCHECK(host); + ++g_num_instances; + if (!host->GetRenderViewIDsForInstance(instance, + &render_process_id_, + &render_view_id_)) { + NOTREACHED(); + } +} + +PepperTCPSocketMessageFilter::~PepperTCPSocketMessageFilter() { + if (socket_) + socket_->Disconnect(); + --g_num_instances; +} + +// static +size_t PepperTCPSocketMessageFilter::GetNumInstances() { + return g_num_instances; +} + +scoped_refptr<base::TaskRunner> +PepperTCPSocketMessageFilter::OverrideTaskRunnerForMessage( + const IPC::Message& message) { + switch (message.type()) { + case PpapiHostMsg_TCPSocket_Connect::ID: + case PpapiHostMsg_TCPSocket_ConnectWithNetAddress::ID: + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); + case PpapiHostMsg_TCPSocket_SSLHandshake::ID: + case PpapiHostMsg_TCPSocket_Read::ID: + case PpapiHostMsg_TCPSocket_Write::ID: + case PpapiHostMsg_TCPSocket_Disconnect::ID: + case PpapiHostMsg_TCPSocket_SetOption::ID: + return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); + } + return NULL; +} + +int32_t PepperTCPSocketMessageFilter::OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) { + IPC_BEGIN_MESSAGE_MAP(PepperTCPSocketMessageFilter, msg) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_TCPSocket_Connect, OnMsgConnect) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_TCPSocket_ConnectWithNetAddress, + OnMsgConnectWithNetAddress) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_TCPSocket_SSLHandshake, OnMsgSSLHandshake) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_TCPSocket_Read, OnMsgRead) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_TCPSocket_Write, OnMsgWrite) + PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( + PpapiHostMsg_TCPSocket_Disconnect, OnMsgDisconnect) + PPAPI_DISPATCH_HOST_RESOURCE_CALL( + PpapiHostMsg_TCPSocket_SetOption, OnMsgSetOption) + IPC_END_MESSAGE_MAP() + return PP_ERROR_FAILED; +} + +int32_t PepperTCPSocketMessageFilter::OnMsgConnect( + const ppapi::host::HostMessageContext* context, + const std::string& host, + uint16_t port) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + // This is only supported by PPB_TCPSocket_Private. + if (!private_api_) { + NOTREACHED(); + return PP_ERROR_NOACCESS; + } + + SocketPermissionRequest request(SocketPermissionRequest::TCP_CONNECT, + host, + port); + if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, private_api_, + request, render_process_id_, + render_view_id_)) { + return PP_ERROR_NOACCESS; + } + + RenderProcessHost* render_process_host = + RenderProcessHost::FromID(render_process_id_); + if (!render_process_host) + return PP_ERROR_FAILED; + BrowserContext* browser_context = render_process_host->GetBrowserContext(); + if (!browser_context || !browser_context->GetResourceContext()) + return PP_ERROR_FAILED; + + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&PepperTCPSocketMessageFilter::DoConnect, this, + context->MakeReplyMessageContext(), + host, port, browser_context->GetResourceContext())); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperTCPSocketMessageFilter::OnMsgConnectWithNetAddress( + const ppapi::host::HostMessageContext* context, + const PP_NetAddress_Private& net_addr) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + content::SocketPermissionRequest request = + pepper_socket_utils::CreateSocketPermissionRequest( + content::SocketPermissionRequest::TCP_CONNECT, net_addr); + if (!pepper_socket_utils::CanUseSocketAPIs(external_plugin_, private_api_, + request, render_process_id_, + render_view_id_)) { + return PP_ERROR_NOACCESS; + } + + BrowserThread::PostTask( + BrowserThread::IO, FROM_HERE, + base::Bind(&PepperTCPSocketMessageFilter::DoConnectWithNetAddress, this, + context->MakeReplyMessageContext(), net_addr)); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperTCPSocketMessageFilter::OnMsgSSLHandshake( + const ppapi::host::HostMessageContext* context, + const std::string& server_name, + uint16_t server_port, + const std::vector<std::vector<char> >& trusted_certs, + const std::vector<std::vector<char> >& untrusted_certs) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + // Allow to do SSL handshake only if currently the socket has been connected + // and there isn't pending read or write. + // IsConnected() includes the state that SSL handshake has been finished and + // therefore isn't suitable here. + if (state_ != STATE_CONNECTED || read_buffer_.get() || + write_buffer_base_.get() || write_buffer_.get()) { + return PP_ERROR_FAILED; + } + + SetState(STATE_SSL_HANDSHAKE_IN_PROGRESS); + // TODO(raymes,rsleevi): Use trusted/untrusted certificates when connecting. + + scoped_ptr<net::ClientSocketHandle> handle(new net::ClientSocketHandle()); + handle->SetSocket(socket_.Pass()); + net::ClientSocketFactory* factory = + net::ClientSocketFactory::GetDefaultFactory(); + net::HostPortPair host_port_pair(server_name, server_port); + net::SSLClientSocketContext ssl_context; + ssl_context.cert_verifier = ssl_context_helper_->GetCertVerifier(); + ssl_context.transport_security_state = + ssl_context_helper_->GetTransportSecurityState(); + socket_ = factory->CreateSSLClientSocket( + handle.Pass(), host_port_pair, ssl_context_helper_->ssl_config(), + ssl_context); + if (!socket_) { + LOG(WARNING) << "Failed to create an SSL client socket."; + return PP_ERROR_FAILED; + } + + const ppapi::host::ReplyMessageContext reply_context( + context->MakeReplyMessageContext()); + int net_result = socket_->Connect( + base::Bind(&PepperTCPSocketMessageFilter::OnSSLHandshakeCompleted, + base::Unretained(this), reply_context)); + if (net_result != net::ERR_IO_PENDING) + OnSSLHandshakeCompleted(reply_context, net_result); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperTCPSocketMessageFilter::OnMsgRead( + const ppapi::host::HostMessageContext* context, + int32_t bytes_to_read) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + if (!IsConnected() || end_of_file_reached_) + return PP_ERROR_FAILED; + if (read_buffer_.get()) + return PP_ERROR_INPROGRESS; + if (bytes_to_read <= 0 || + bytes_to_read > TCPSocketResourceBase::kMaxReadSize) { + return PP_ERROR_BADARGUMENT; + } + + ppapi::host::ReplyMessageContext reply_context( + context->MakeReplyMessageContext()); + read_buffer_ = new net::IOBuffer(bytes_to_read); + int net_result = socket_->Read( + read_buffer_.get(), + bytes_to_read, + base::Bind(&PepperTCPSocketMessageFilter::OnReadCompleted, + base::Unretained(this), reply_context)); + if (net_result != net::ERR_IO_PENDING) + OnReadCompleted(reply_context, net_result); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperTCPSocketMessageFilter::OnMsgWrite( + const ppapi::host::HostMessageContext* context, + const std::string& data) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + if (!IsConnected()) + return PP_ERROR_FAILED; + if (write_buffer_base_.get() || write_buffer_.get()) + return PP_ERROR_INPROGRESS; + + size_t data_size = data.size(); + if (data_size == 0 || + data_size > static_cast<size_t>(TCPSocketResourceBase::kMaxWriteSize)) { + return PP_ERROR_BADARGUMENT; + } + + write_buffer_base_ = new net::IOBuffer(data_size); + memcpy(write_buffer_base_->data(), data.data(), data_size); + write_buffer_ = + new net::DrainableIOBuffer(write_buffer_base_.get(), data_size); + DoWrite(context->MakeReplyMessageContext()); + return PP_OK_COMPLETIONPENDING; +} + +int32_t PepperTCPSocketMessageFilter::OnMsgDisconnect( + const ppapi::host::HostMessageContext* context) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + SetState(STATE_CLOSED); + return PP_OK; +} + +int32_t PepperTCPSocketMessageFilter::OnMsgSetOption( + const ppapi::host::HostMessageContext* context, + PP_TCPSocket_Option name, + const ppapi::SocketOptionData& value) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + if (!IsConnected() || IsSsl()) + return PP_ERROR_FAILED; + + net::TCPClientSocket* tcp_socket = + static_cast<net::TCPClientSocket*>(socket_.get()); + DCHECK(tcp_socket); + + switch (name) { + case PP_TCPSOCKET_OPTION_NO_DELAY: { + bool boolean_value = false; + if (!value.GetBool(&boolean_value)) + return PP_ERROR_BADARGUMENT; + return tcp_socket->SetNoDelay(boolean_value) ? PP_OK : PP_ERROR_FAILED; + } + case PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE: + case PP_TCPSOCKET_OPTION_RECV_BUFFER_SIZE: { + int32_t integer_value = 0; + if (!value.GetInt32(&integer_value) || integer_value <= 0) + return PP_ERROR_BADARGUMENT; + + bool result = false; + if (name == PP_TCPSOCKET_OPTION_SEND_BUFFER_SIZE) { + if (integer_value > TCPSocketResourceBase::kMaxSendBufferSize) + return PP_ERROR_BADARGUMENT; + result = tcp_socket->SetSendBufferSize(integer_value); + } else { + if (integer_value > TCPSocketResourceBase::kMaxReceiveBufferSize) + return PP_ERROR_BADARGUMENT; + result = tcp_socket->SetReceiveBufferSize(integer_value); + } + return result ? PP_OK : PP_ERROR_FAILED; + } + default: { + NOTREACHED(); + return PP_ERROR_BADARGUMENT; + } + } + return PP_ERROR_FAILED; +} + +void PepperTCPSocketMessageFilter::DoConnect( + const ppapi::host::ReplyMessageContext& context, + const std::string& host, + uint16_t port, + ResourceContext* resource_context) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + if (state_ != STATE_BEFORE_CONNECT) { + SendConnectError(context, PP_ERROR_FAILED); + return; + } + + SetState(STATE_CONNECT_IN_PROGRESS); + net::HostResolver::RequestInfo request_info(net::HostPortPair(host, port)); + resolver_.reset(new net::SingleRequestHostResolver( + resource_context->GetHostResolver())); + int net_result = resolver_->Resolve( + request_info, + net::DEFAULT_PRIORITY, + &address_list_, + base::Bind(&PepperTCPSocketMessageFilter::OnResolveCompleted, + base::Unretained(this), context), + net::BoundNetLog()); + if (net_result != net::ERR_IO_PENDING) + OnResolveCompleted(context, net_result); +} + +void PepperTCPSocketMessageFilter::DoConnectWithNetAddress( + const ppapi::host::ReplyMessageContext& context, + const PP_NetAddress_Private& net_addr) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + if (state_ != STATE_BEFORE_CONNECT) { + SendConnectError(context, PP_ERROR_FAILED); + return; + } + + net::IPAddressNumber address; + int port; + if (!NetAddressPrivateImpl::NetAddressToIPEndPoint(net_addr, &address, + &port)) { + SendConnectError(context, PP_ERROR_ADDRESS_INVALID); + return; + } + + // Copy the single IPEndPoint to address_list_. + address_list_.clear(); + address_list_.push_back(net::IPEndPoint(address, port)); + SetState(STATE_CONNECT_IN_PROGRESS); + StartConnect(context); +} + +void PepperTCPSocketMessageFilter::DoWrite( + const ppapi::host::ReplyMessageContext& context) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK(write_buffer_base_.get()); + DCHECK(write_buffer_.get()); + DCHECK_GT(write_buffer_->BytesRemaining(), 0); + + int net_result = socket_->Write( + write_buffer_.get(), + write_buffer_->BytesRemaining(), + base::Bind(&PepperTCPSocketMessageFilter::OnWriteCompleted, + base::Unretained(this), context)); + if (net_result != net::ERR_IO_PENDING) + OnWriteCompleted(context, net_result); +} + +void PepperTCPSocketMessageFilter::OnResolveCompleted( + const ppapi::host::ReplyMessageContext& context, + int net_result) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + if (state_ != STATE_CONNECT_IN_PROGRESS) { + SendConnectError(context, PP_ERROR_FAILED); + SetState(STATE_CLOSED); + return; + } + + if (net_result != net::OK) { + SendConnectError(context, NetErrorToPepperError(net_result)); + SetState(STATE_BEFORE_CONNECT); + return; + } + + StartConnect(context); +} + +void PepperTCPSocketMessageFilter::StartConnect( + const ppapi::host::ReplyMessageContext& context) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + if (state_ != STATE_CONNECT_IN_PROGRESS) { + SendConnectError(context, PP_ERROR_FAILED); + SetState(STATE_CLOSED); + return; + } + + socket_.reset(new net::TCPClientSocket(address_list_, NULL, + net::NetLog::Source())); + int net_result = socket_->Connect( + base::Bind(&PepperTCPSocketMessageFilter::OnConnectCompleted, + base::Unretained(this), context)); + if (net_result != net::ERR_IO_PENDING) + OnConnectCompleted(context, net_result); +} + +void PepperTCPSocketMessageFilter::OnConnectCompleted( + const ppapi::host::ReplyMessageContext& context, + int net_result) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK(socket_.get()); + + if (state_ != STATE_CONNECT_IN_PROGRESS) { + SendConnectError(context, PP_ERROR_FAILED); + SetState(STATE_CLOSED); + return; + } + + int32_t pp_result = NetErrorToPepperError(net_result); + do { + if (pp_result != PP_OK) + break; + + net::IPEndPoint ip_end_point_local; + net::IPEndPoint ip_end_point_remote; + pp_result = NetErrorToPepperError( + socket_->GetLocalAddress(&ip_end_point_local)); + if (pp_result != PP_OK) + break; + pp_result = NetErrorToPepperError( + socket_->GetPeerAddress(&ip_end_point_remote)); + if (pp_result != PP_OK) + break; + + PP_NetAddress_Private local_addr = + NetAddressPrivateImpl::kInvalidNetAddress; + PP_NetAddress_Private remote_addr = + NetAddressPrivateImpl::kInvalidNetAddress; + if (!NetAddressPrivateImpl::IPEndPointToNetAddress( + ip_end_point_local.address(), + ip_end_point_local.port(), + &local_addr) || + !NetAddressPrivateImpl::IPEndPointToNetAddress( + ip_end_point_remote.address(), + ip_end_point_remote.port(), + &remote_addr)) { + pp_result = PP_ERROR_ADDRESS_INVALID; + break; + } + + SendConnectReply(context, PP_OK, local_addr, remote_addr); + SetState(STATE_CONNECTED); + return; + } while (false); + + SendConnectError(context, pp_result); + SetState(STATE_BEFORE_CONNECT); +} + +void PepperTCPSocketMessageFilter::OnSSLHandshakeCompleted( + const ppapi::host::ReplyMessageContext& context, + int net_result) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + if (state_ != STATE_SSL_HANDSHAKE_IN_PROGRESS) { + SendSSLHandshakeReply(context, PP_ERROR_FAILED); + SetState(STATE_CLOSED); + return; + } + SendSSLHandshakeReply(context, NetErrorToPepperError(net_result)); + SetState(net_result == net::OK ? + STATE_SSL_CONNECTED : + STATE_SSL_HANDSHAKE_FAILED); +} + +void PepperTCPSocketMessageFilter::OnReadCompleted( + const ppapi::host::ReplyMessageContext& context, + int net_result) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK(read_buffer_.get()); + + if (net_result > 0) { + SendReadReply(context, + PP_OK, + std::string(read_buffer_->data(), net_result)); + } else if (net_result == 0) { + end_of_file_reached_ = true; + SendReadReply(context, PP_OK, std::string()); + } else { + SendReadError(context, NetErrorToPepperError(net_result)); + } + read_buffer_ = NULL; +} + +void PepperTCPSocketMessageFilter::OnWriteCompleted( + const ppapi::host::ReplyMessageContext& context, + int net_result) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + DCHECK(write_buffer_base_.get()); + DCHECK(write_buffer_.get()); + + // Note: For partial writes of 0 bytes, don't continue writing to avoid a + // likely infinite loop. + if (net_result > 0) { + write_buffer_->DidConsume(net_result); + if (write_buffer_->BytesRemaining() > 0) { + DoWrite(context); + return; + } + } + + if (net_result >= 0) + SendWriteReply(context, write_buffer_->BytesConsumed()); + else + SendWriteReply(context, NetErrorToPepperError(net_result)); + + write_buffer_ = NULL; + write_buffer_base_ = NULL; +} + +void PepperTCPSocketMessageFilter::SendConnectReply( + const ppapi::host::ReplyMessageContext& context, + int32_t pp_result, + const PP_NetAddress_Private& local_addr, + const PP_NetAddress_Private& remote_addr) { + ppapi::host::ReplyMessageContext reply_context(context); + reply_context.params.set_result(pp_result); + SendReply(reply_context, + PpapiPluginMsg_TCPSocket_ConnectReply(local_addr, remote_addr)); +} + +void PepperTCPSocketMessageFilter::SendConnectError( + const ppapi::host::ReplyMessageContext& context, + int32_t pp_error) { + SendConnectReply(context, + pp_error, + NetAddressPrivateImpl::kInvalidNetAddress, + NetAddressPrivateImpl::kInvalidNetAddress); +} + +void PepperTCPSocketMessageFilter::SendSSLHandshakeReply( + const ppapi::host::ReplyMessageContext& context, + int32_t pp_result) { + ppapi::host::ReplyMessageContext reply_context(context); + reply_context.params.set_result(pp_result); + ppapi::PPB_X509Certificate_Fields certificate_fields; + if (pp_result == PP_OK) { + // Our socket is guaranteed to be an SSL socket if we get here. + net::SSLClientSocket* ssl_socket = + static_cast<net::SSLClientSocket*>(socket_.get()); + net::SSLInfo ssl_info; + ssl_socket->GetSSLInfo(&ssl_info); + if (ssl_info.cert.get()) { + pepper_socket_utils::GetCertificateFields(*ssl_info.cert.get(), + &certificate_fields); + } + } + SendReply(reply_context, + PpapiPluginMsg_TCPSocket_SSLHandshakeReply(certificate_fields)); +} + +void PepperTCPSocketMessageFilter::SendReadReply( + const ppapi::host::ReplyMessageContext& context, + int32_t pp_result, + const std::string& data) { + ppapi::host::ReplyMessageContext reply_context(context); + reply_context.params.set_result(pp_result); + SendReply(reply_context, PpapiPluginMsg_TCPSocket_ReadReply(data)); +} + +void PepperTCPSocketMessageFilter::SendReadError( + const ppapi::host::ReplyMessageContext& context, + int32_t pp_error) { + SendReadReply(context, pp_error, std::string()); +} + +void PepperTCPSocketMessageFilter::SendWriteReply( + const ppapi::host::ReplyMessageContext& context, + int32_t pp_result) { + ppapi::host::ReplyMessageContext reply_context(context); + reply_context.params.set_result(pp_result); + SendReply(reply_context, PpapiPluginMsg_TCPSocket_WriteReply()); +} + +bool PepperTCPSocketMessageFilter::IsConnected() const { + return state_ == STATE_CONNECTED || state_ == STATE_SSL_CONNECTED; +} + +bool PepperTCPSocketMessageFilter::IsSsl() const { + return state_ == STATE_SSL_HANDSHAKE_IN_PROGRESS || + state_ == STATE_SSL_CONNECTED || + state_ == STATE_SSL_HANDSHAKE_FAILED; +} + +void PepperTCPSocketMessageFilter::SetState(State state) { + state_ = state; + if (state_ == STATE_CLOSED && socket_) { + // Make sure no further callbacks from socket_. + socket_->Disconnect(); + socket_.reset(); + } +} + +} // namespace content diff --git a/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h new file mode 100644 index 0000000..84e8a75 --- /dev/null +++ b/content/browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h @@ -0,0 +1,183 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_MESSAGE_FILTER_H_ +#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_MESSAGE_FILTER_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "content/browser/renderer_host/pepper/ssl_context_helper.h" +#include "content/common/content_export.h" +#include "net/base/address_list.h" +#include "ppapi/c/pp_instance.h" +#include "ppapi/c/ppb_tcp_socket.h" +#include "ppapi/host/resource_message_filter.h" + +struct PP_NetAddress_Private; + +namespace net { +class DrainableIOBuffer; +class IOBuffer; +class SingleRequestHostResolver; +class StreamSocket; +} + +namespace ppapi { +class SocketOptionData; + +namespace host { +struct ReplyMessageContext; +} +} + +namespace content { + +class BrowserPpapiHostImpl; +class ResourceContext; + +class CONTENT_EXPORT PepperTCPSocketMessageFilter + : public ppapi::host::ResourceMessageFilter { + public: + PepperTCPSocketMessageFilter( + BrowserPpapiHostImpl* host, + PP_Instance instance, + bool private_api); + + // Used for creating already connected sockets. Takes ownership of + // |socket|. + PepperTCPSocketMessageFilter( + BrowserPpapiHostImpl* host, + PP_Instance instance, + bool private_api, + net::StreamSocket* socket); + + static size_t GetNumInstances(); + + protected: + virtual ~PepperTCPSocketMessageFilter(); + + private: + enum State { + // Before a connection is successfully established (including a previous + // connect request failed). + STATE_BEFORE_CONNECT, + // There is a connect request that is pending. + STATE_CONNECT_IN_PROGRESS, + // A connection has been successfully established. + STATE_CONNECTED, + // There is an SSL handshake request that is pending. + STATE_SSL_HANDSHAKE_IN_PROGRESS, + // An SSL connection has been successfully established. + STATE_SSL_CONNECTED, + // An SSL handshake has failed. + STATE_SSL_HANDSHAKE_FAILED, + // Socket is closed. + STATE_CLOSED + }; + + // ppapi::host::ResourceMessageFilter overrides. + virtual scoped_refptr<base::TaskRunner> OverrideTaskRunnerForMessage( + const IPC::Message& message) OVERRIDE; + virtual int32_t OnResourceMessageReceived( + const IPC::Message& msg, + ppapi::host::HostMessageContext* context) OVERRIDE; + + int32_t OnMsgConnect(const ppapi::host::HostMessageContext* context, + const std::string& host, + uint16_t port); + int32_t OnMsgConnectWithNetAddress( + const ppapi::host::HostMessageContext* context, + const PP_NetAddress_Private& net_addr); + int32_t OnMsgSSLHandshake( + const ppapi::host::HostMessageContext* context, + const std::string& server_name, + uint16_t server_port, + const std::vector<std::vector<char> >& trusted_certs, + const std::vector<std::vector<char> >& untrusted_certs); + int32_t OnMsgRead(const ppapi::host::HostMessageContext* context, + int32_t bytes_to_read); + int32_t OnMsgWrite(const ppapi::host::HostMessageContext* context, + const std::string& data); + int32_t OnMsgDisconnect(const ppapi::host::HostMessageContext* context); + int32_t OnMsgSetOption(const ppapi::host::HostMessageContext* context, + PP_TCPSocket_Option name, + const ppapi::SocketOptionData& value); + + void DoConnect(const ppapi::host::ReplyMessageContext& context, + const std::string& host, + uint16_t port, + ResourceContext* resource_context); + void DoConnectWithNetAddress( + const ppapi::host::ReplyMessageContext& context, + const PP_NetAddress_Private& net_addr); + void DoWrite(const ppapi::host::ReplyMessageContext& context); + + void OnResolveCompleted(const ppapi::host::ReplyMessageContext& context, + int net_result); + void StartConnect(const ppapi::host::ReplyMessageContext& context); + + void OnConnectCompleted(const ppapi::host::ReplyMessageContext& context, + int net_result); + void OnSSLHandshakeCompleted(const ppapi::host::ReplyMessageContext& context, + int net_result); + void OnReadCompleted(const ppapi::host::ReplyMessageContext& context, + int net_result); + void OnWriteCompleted(const ppapi::host::ReplyMessageContext& context, + int net_result); + + void SendConnectReply(const ppapi::host::ReplyMessageContext& context, + int32_t pp_result, + const PP_NetAddress_Private& local_addr, + const PP_NetAddress_Private& remote_addr); + void SendConnectError(const ppapi::host::ReplyMessageContext& context, + int32_t pp_error); + void SendSSLHandshakeReply(const ppapi::host::ReplyMessageContext& context, + int32_t pp_result); + void SendReadReply(const ppapi::host::ReplyMessageContext& context, + int32_t pp_result, + const std::string& data); + void SendReadError(const ppapi::host::ReplyMessageContext& context, + int32_t pp_error); + void SendWriteReply(const ppapi::host::ReplyMessageContext& context, + int32_t pp_result); + + bool IsConnected() const; + bool IsSsl() const; + void SetState(State state); + + bool external_plugin_; + bool private_api_; + + int render_process_id_; + int render_view_id_; + + State state_; + bool end_of_file_reached_; + + scoped_ptr<net::SingleRequestHostResolver> resolver_; + net::AddressList address_list_; + + scoped_ptr<net::StreamSocket> socket_; + + scoped_refptr<net::IOBuffer> read_buffer_; + + // StreamSocket::Write() may not always write the full buffer, but we would + // rather have our DoWrite() do so whenever possible. To do this, we may have + // to call the former multiple times for each of the latter. This entails + // using a DrainableIOBuffer, which requires an underlying base IOBuffer. + scoped_refptr<net::IOBuffer> write_buffer_base_; + scoped_refptr<net::DrainableIOBuffer> write_buffer_; + scoped_refptr<SSLContextHelper> ssl_context_helper_; + + DISALLOW_COPY_AND_ASSIGN(PepperTCPSocketMessageFilter); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_PEPPER_TCP_SOCKET_MESSAGE_FILTER_H_ diff --git a/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc b/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc index 7453fd2..4a36c3d 100644 --- a/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc +++ b/content/browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc @@ -28,8 +28,8 @@ #include "ppapi/shared_impl/private/net_address_private_impl.h" #include "ppapi/shared_impl/socket_option_data.h" -using ppapi::host::NetErrorToPepperError; using ppapi::NetAddressPrivateImpl; +using ppapi::host::NetErrorToPepperError; namespace { diff --git a/content/browser/renderer_host/pepper/ssl_context_helper.cc b/content/browser/renderer_host/pepper/ssl_context_helper.cc new file mode 100644 index 0000000..3b92e6d --- /dev/null +++ b/content/browser/renderer_host/pepper/ssl_context_helper.cc @@ -0,0 +1,30 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "content/browser/renderer_host/pepper/ssl_context_helper.h" + +#include "net/cert/cert_verifier.h" +#include "net/http/transport_security_state.h" + +namespace content { + +SSLContextHelper::SSLContextHelper() { +} + +SSLContextHelper::~SSLContextHelper() { +} + +net::CertVerifier* SSLContextHelper::GetCertVerifier() { + if (!cert_verifier_) + cert_verifier_.reset(net::CertVerifier::CreateDefault()); + return cert_verifier_.get(); +} + +net::TransportSecurityState* SSLContextHelper::GetTransportSecurityState() { + if (!transport_security_state_) + transport_security_state_.reset(new net::TransportSecurityState()); + return transport_security_state_.get(); +} + +} // namespace content diff --git a/content/browser/renderer_host/pepper/ssl_context_helper.h b/content/browser/renderer_host/pepper/ssl_context_helper.h new file mode 100644 index 0000000..f1da2a6 --- /dev/null +++ b/content/browser/renderer_host/pepper/ssl_context_helper.h @@ -0,0 +1,48 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CONTENT_BROWSER_RENDERER_HOST_PEPPER_SSL_CONTEXT_HELPER_H_ +#define CONTENT_BROWSER_RENDERER_HOST_PEPPER_SSL_CONTEXT_HELPER_H_ + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "net/ssl/ssl_config_service.h" + +namespace net { +class CertVerifier; +class TransportSecurityState; +} + +namespace content { + +class SSLContextHelper : public base::RefCounted<SSLContextHelper> { + public: + SSLContextHelper(); + + net::CertVerifier* GetCertVerifier(); + net::TransportSecurityState* GetTransportSecurityState(); + const net::SSLConfig& ssl_config() { return ssl_config_; } + + private: + friend class base::RefCounted<SSLContextHelper>; + + ~SSLContextHelper(); + + // This is lazily created. Users should use GetCertVerifier to retrieve it. + scoped_ptr<net::CertVerifier> cert_verifier_; + // This is lazily created. Users should use GetTransportSecurityState to + // retrieve it. + scoped_ptr<net::TransportSecurityState> transport_security_state_; + + // The default SSL configuration settings are used, as opposed to Chrome's SSL + // settings. + net::SSLConfig ssl_config_; + + DISALLOW_COPY_AND_ASSIGN(SSLContextHelper); +}; + +} // namespace content + +#endif // CONTENT_BROWSER_RENDERER_HOST_PEPPER_SSL_CONTEXT_HELPER_H_ diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index f5e3f1c..53b2e91 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc @@ -623,7 +623,7 @@ void RenderProcessHostImpl::CreateMessageFilters() { #endif #if defined(ENABLE_PLUGINS) // TODO(raymes): PepperMessageFilter should be removed from here. - channel_->AddFilter(new PepperMessageFilter(GetID(), browser_context)); + channel_->AddFilter(PepperMessageFilter::CreateForRendererProcess()); channel_->AddFilter(new PepperRendererConnection(GetID())); #endif #if defined(ENABLE_INPUT_SPEECH) diff --git a/content/content_browser.gypi b/content/content_browser.gypi index ce8e1b0..01b33f1 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -939,8 +939,8 @@ 'browser/renderer_host/pepper/pepper_socket_utils.h', 'browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.cc', 'browser/renderer_host/pepper/pepper_tcp_server_socket_message_filter.h', - 'browser/renderer_host/pepper/pepper_tcp_socket.cc', - 'browser/renderer_host/pepper/pepper_tcp_socket.h', + 'browser/renderer_host/pepper/pepper_tcp_socket_message_filter.cc', + 'browser/renderer_host/pepper/pepper_tcp_socket_message_filter.h', 'browser/renderer_host/pepper/pepper_truetype_font_list.h', 'browser/renderer_host/pepper/pepper_truetype_font_list_android.cc', 'browser/renderer_host/pepper/pepper_truetype_font_list_host.cc', @@ -950,6 +950,8 @@ 'browser/renderer_host/pepper/pepper_truetype_font_list_win.cc', 'browser/renderer_host/pepper/pepper_udp_socket_message_filter.cc', 'browser/renderer_host/pepper/pepper_udp_socket_message_filter.h', + 'browser/renderer_host/pepper/ssl_context_helper.cc', + 'browser/renderer_host/pepper/ssl_context_helper.h', 'browser/renderer_host/popup_menu_helper_mac.h', 'browser/renderer_host/popup_menu_helper_mac.mm', 'browser/renderer_host/render_frame_host_impl.cc', diff --git a/content/content_renderer.gypi b/content/content_renderer.gypi index 3d567ce..1e9e0bb 100644 --- a/content/content_renderer.gypi +++ b/content/content_renderer.gypi @@ -365,8 +365,6 @@ 'renderer/pepper/ppb_proxy_impl.h', 'renderer/pepper/ppb_scrollbar_impl.cc', 'renderer/pepper/ppb_scrollbar_impl.h', - 'renderer/pepper/ppb_tcp_socket_private_impl.cc', - 'renderer/pepper/ppb_tcp_socket_private_impl.h', 'renderer/pepper/ppb_uma_private_impl.cc', 'renderer/pepper/ppb_uma_private_impl.h', 'renderer/pepper/ppb_var_deprecated_impl.cc', diff --git a/content/ppapi_plugin/ppapi_thread.cc b/content/ppapi_plugin/ppapi_thread.cc index 73d51ad..c2b4e04 100644 --- a/content/ppapi_plugin/ppapi_thread.cc +++ b/content/ppapi_plugin/ppapi_thread.cc @@ -101,10 +101,6 @@ PpapiThread::PpapiThread(const CommandLine& command_line, bool is_broker) // Register interfaces that expect messages from the browser process. Please // note that only those InterfaceProxy-based ones require registration. - AddRoute(ppapi::API_ID_PPB_TCPSOCKET, - &dispatcher_message_listener_); - AddRoute(ppapi::API_ID_PPB_TCPSOCKET_PRIVATE, - &dispatcher_message_listener_); AddRoute(ppapi::API_ID_PPB_HOSTRESOLVER_PRIVATE, &dispatcher_message_listener_); AddRoute(ppapi::API_ID_PPB_NETWORKMANAGER_PRIVATE, diff --git a/content/public/browser/browser_ppapi_host.h b/content/public/browser/browser_ppapi_host.h index 1ad0d17..45f997e 100644 --- a/content/public/browser/browser_ppapi_host.h +++ b/content/public/browser/browser_ppapi_host.h @@ -18,10 +18,6 @@ struct ChannelHandle; class Sender; } -namespace net { -class HostResolver; -} - namespace ppapi { class PpapiPermissions; namespace host { @@ -45,7 +41,6 @@ class CONTENT_EXPORT BrowserPpapiHost { ppapi::PpapiPermissions permissions, base::ProcessHandle plugin_child_process, IPC::ChannelProxy* channel, - net::HostResolver* host_resolver, int render_process_id, int render_view_id, const base::FilePath& profile_directory); diff --git a/content/renderer/pepper/ppb_tcp_socket_private_impl.cc b/content/renderer/pepper/ppb_tcp_socket_private_impl.cc deleted file mode 100644 index 2b47e64..0000000 --- a/content/renderer/pepper/ppb_tcp_socket_private_impl.cc +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "content/renderer/pepper/ppb_tcp_socket_private_impl.h" - -#include "content/common/pepper_messages.h" -#include "content/renderer/pepper/host_globals.h" -#include "content/renderer/pepper/pepper_plugin_instance_impl.h" -#include "content/renderer/render_thread_impl.h" -#include "ppapi/proxy/ppapi_messages.h" -#include "ppapi/shared_impl/socket_option_data.h" - -namespace content { - -PPB_TCPSocket_Private_Impl::PPB_TCPSocket_Private_Impl( - PP_Instance instance, - uint32 socket_id, - int routing_id) - : ppapi::TCPSocketPrivateImpl(instance, socket_id), - routing_id_(routing_id) { - ChildThread::current()->AddRoute(routing_id, this); -} - -PPB_TCPSocket_Private_Impl::~PPB_TCPSocket_Private_Impl() { - ChildThread::current()->RemoveRoute(routing_id_); - Disconnect(); -} - -PP_Resource PPB_TCPSocket_Private_Impl::CreateResource(PP_Instance instance) { - int routing_id = RenderThreadImpl::current()->GenerateRoutingID(); - uint32 socket_id = 0; - RenderThreadImpl::current()->Send(new PpapiHostMsg_PPBTCPSocket_CreatePrivate( - routing_id, 0, &socket_id)); - if (!socket_id) - return 0; - - return (new PPB_TCPSocket_Private_Impl( - instance, socket_id, routing_id))->GetReference(); -} - -void PPB_TCPSocket_Private_Impl::SendConnect(const std::string& host, - uint16_t port) { - RenderThreadImpl::current()->Send(new PpapiHostMsg_PPBTCPSocket_Connect( - routing_id_, socket_id_, host, port)); -} - -void PPB_TCPSocket_Private_Impl::SendConnectWithNetAddress( - const PP_NetAddress_Private& addr) { - RenderThreadImpl::current()->Send( - new PpapiHostMsg_PPBTCPSocket_ConnectWithNetAddress( - routing_id_, socket_id_, addr)); -} - -void PPB_TCPSocket_Private_Impl::SendSSLHandshake( - const std::string& server_name, - uint16_t server_port, - const std::vector<std::vector<char> >& trusted_certs, - const std::vector<std::vector<char> >& untrusted_certs) { - RenderThreadImpl::current()->Send(new PpapiHostMsg_PPBTCPSocket_SSLHandshake( - socket_id_, server_name, server_port, trusted_certs, untrusted_certs)); -} - -void PPB_TCPSocket_Private_Impl::SendRead(int32_t bytes_to_read) { - RenderThreadImpl::current()->Send(new PpapiHostMsg_PPBTCPSocket_Read( - socket_id_, bytes_to_read)); -} - - -void PPB_TCPSocket_Private_Impl::SendWrite(const std::string& buffer) { - RenderThreadImpl::current()->Send( - new PpapiHostMsg_PPBTCPSocket_Write(socket_id_, buffer)); -} - -void PPB_TCPSocket_Private_Impl::SendDisconnect() { - RenderThreadImpl::current()->Send( - new PpapiHostMsg_PPBTCPSocket_Disconnect(socket_id_)); -} - -void PPB_TCPSocket_Private_Impl::SendSetOption( - PP_TCPSocket_Option name, - const ppapi::SocketOptionData& value) { - RenderThreadImpl::current()->Send( - new PpapiHostMsg_PPBTCPSocket_SetOption(socket_id_, name, value)); -} - -bool PPB_TCPSocket_Private_Impl::OnMessageReceived( - const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(PPB_TCPSocket_Private_Impl, message) - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_ConnectACK, OnTCPSocketConnectACK) - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SSLHandshakeACK, - OnTCPSocketSSLHandshakeACK) - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_ReadACK, OnTCPSocketReadACK) - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_WriteACK, OnTCPSocketWriteACK) - IPC_MESSAGE_HANDLER(PpapiMsg_PPBTCPSocket_SetOptionACK, - OnTCPSocketSetOptionACK) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void PPB_TCPSocket_Private_Impl::OnTCPSocketConnectACK( - uint32 plugin_dispatcher_id, - uint32 socket_id, - int32_t result, - const PP_NetAddress_Private& local_addr, - const PP_NetAddress_Private& remote_addr) { - OnConnectCompleted(result, local_addr, remote_addr); -} - -void PPB_TCPSocket_Private_Impl::OnTCPSocketSSLHandshakeACK( - uint32 plugin_dispatcher_id, - uint32 socket_id, - bool succeeded, - const ppapi::PPB_X509Certificate_Fields& certificate_fields) { - OnSSLHandshakeCompleted(succeeded, certificate_fields); -} - -void PPB_TCPSocket_Private_Impl::OnTCPSocketReadACK(uint32 plugin_dispatcher_id, - uint32 socket_id, - int32_t result, - const std::string& data) { - OnReadCompleted(result, data); -} - -void PPB_TCPSocket_Private_Impl::OnTCPSocketWriteACK( - uint32 plugin_dispatcher_id, - uint32 socket_id, - int32_t result) { - OnWriteCompleted(result); -} - -void PPB_TCPSocket_Private_Impl::OnTCPSocketSetOptionACK( - uint32 plugin_dispatcher_id, - uint32 socket_id, - int32_t result) { - OnSetOptionCompleted(result); -} - -} // namespace content diff --git a/content/renderer/pepper/ppb_tcp_socket_private_impl.h b/content/renderer/pepper/ppb_tcp_socket_private_impl.h deleted file mode 100644 index 2ac6981..0000000 --- a/content/renderer/pepper/ppb_tcp_socket_private_impl.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CONTENT_RENDERER_PEPPER_PPB_TCP_SOCKET_PRIVATE_IMPL_H_ -#define CONTENT_RENDERER_PEPPER_PPB_TCP_SOCKET_PRIVATE_IMPL_H_ - -#include <vector> - -#include "base/compiler_specific.h" -#include "ipc/ipc_listener.h" -#include "ppapi/shared_impl/private/tcp_socket_private_impl.h" - -namespace content { - -class PPB_TCPSocket_Private_Impl : public ppapi::TCPSocketPrivateImpl, - public IPC::Listener { - public: - static PP_Resource CreateResource(PP_Instance instance); - - virtual void SendConnect(const std::string& host, uint16_t port) OVERRIDE; - virtual void SendConnectWithNetAddress( - const PP_NetAddress_Private& addr) OVERRIDE; - virtual void SendSSLHandshake( - const std::string& server_name, - uint16_t server_port, - const std::vector<std::vector<char> >& trusted_certs, - const std::vector<std::vector<char> >& untrusted_certs) OVERRIDE; - virtual void SendRead(int32_t bytes_to_read) OVERRIDE; - virtual void SendWrite(const std::string& buffer) OVERRIDE; - virtual void SendDisconnect() OVERRIDE; - virtual void SendSetOption(PP_TCPSocket_Option name, - const ppapi::SocketOptionData& value) OVERRIDE; - - private: - PPB_TCPSocket_Private_Impl(PP_Instance instance, - uint32 socket_id, - int routing_id); - virtual ~PPB_TCPSocket_Private_Impl(); - - // IPC::Listener implementation. - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; - - void OnTCPSocketConnectACK(uint32 plugin_dispatcher_id, - uint32 socket_id, - int32_t result, - const PP_NetAddress_Private& local_addr, - const PP_NetAddress_Private& remote_addr); - void OnTCPSocketSSLHandshakeACK( - uint32 plugin_dispatcher_id, - uint32 socket_id, - bool succeeded, - const ppapi::PPB_X509Certificate_Fields& certificate_fields); - void OnTCPSocketReadACK(uint32 plugin_dispatcher_id, - uint32 socket_id, - int32_t result, - const std::string& data); - void OnTCPSocketWriteACK(uint32 plugin_dispatcher_id, - uint32 socket_id, - int32_t result); - void OnTCPSocketSetOptionACK(uint32 plugin_dispatcher_id, - uint32 socket_id, - int32_t result); - - int routing_id_; - - DISALLOW_COPY_AND_ASSIGN(PPB_TCPSocket_Private_Impl); -}; - -} // namespace content - -#endif // CONTENT_RENDERER_PEPPER_PPB_TCP_SOCKET_PRIVATE_IMPL_H_ diff --git a/content/renderer/pepper/resource_creation_impl.cc b/content/renderer/pepper/resource_creation_impl.cc index 54c20f2..419b3270 100644 --- a/content/renderer/pepper/resource_creation_impl.cc +++ b/content/renderer/pepper/resource_creation_impl.cc @@ -13,7 +13,6 @@ #include "content/renderer/pepper/ppb_image_data_impl.h" #include "content/renderer/pepper/ppb_network_monitor_private_impl.h" #include "content/renderer/pepper/ppb_scrollbar_impl.h" -#include "content/renderer/pepper/ppb_tcp_socket_private_impl.h" #include "content/renderer/pepper/ppb_video_decoder_impl.h" #include "content/renderer/pepper/ppb_x509_certificate_private_impl.h" #include "ppapi/c/pp_size.h" @@ -238,7 +237,7 @@ PP_Resource ResourceCreationImpl::CreateTCPSocket(PP_Instance instance) { } PP_Resource ResourceCreationImpl::CreateTCPSocketPrivate(PP_Instance instance) { - return PPB_TCPSocket_Private_Impl::CreateResource(instance); + return 0; // Not supported in-process. } PP_Resource ResourceCreationImpl::CreateUDPSocket(PP_Instance instance) { |