12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/renderer_host/pepper/pepper_flash_file_message_filter.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 8c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "base/files/file.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_enumerator.h" 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/sequenced_worker_pool.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/child_process_security_policy_impl.h" 13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "content/browser/renderer_host/pepper/pepper_security_helper.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_ppapi_host.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/common/content_constants.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_platform_file.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/c/pp_errors.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/dispatch_host_message.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/host_message_context.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/host/ppapi_host.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/file_path.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ppapi/shared_impl/file_type_conversion.h" 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace content { 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 30a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)bool CanRead(int process_id, const base::FilePath& path) { 31a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ChildProcessSecurityPolicyImpl::GetInstance()->CanReadFile(process_id, 32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch path); 33a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)bool CanCreateReadWrite(int process_id, const base::FilePath& path) { 36a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ChildProcessSecurityPolicyImpl::GetInstance()->CanCreateReadWriteFile( 37a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch process_id, path); 38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PepperFlashFileMessageFilter::PepperFlashFileMessageFilter( 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PP_Instance instance, 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserPpapiHost* host) 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : plugin_process_handle_(host->GetPluginProcessHandle()) { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int unused; 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) host->GetRenderFrameIDsForInstance(instance, &render_process_id_, &unused); 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath profile_data_directory = host->GetProfileDataDirectory(); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string plugin_name = host->GetPluginName(); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (profile_data_directory.empty() || plugin_name.empty()) { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // These are used to construct the path. If they are not set it means we 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // will construct a bad path and could provide access to the wrong files. 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In this case, |plugin_data_directory_| will remain unset and 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |ValidateAndConvertPepperFilePath| will fail. 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) plugin_data_directory_ = GetDataDirName(profile_data_directory).Append( 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath::FromUTF8Unsafe(plugin_name)); 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 63a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperFlashFileMessageFilter::~PepperFlashFileMessageFilter() {} 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath PepperFlashFileMessageFilter::GetDataDirName( 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& profile_path) { 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return profile_path.Append(kPepperDataDirname); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<base::TaskRunner> 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PepperFlashFileMessageFilter::OverrideTaskRunnerForMessage( 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const IPC::Message& msg) { 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The blocking pool provides a pool of threads to run file 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // operations, instead of a single thread which might require 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // queuing time. Since these messages are synchronous as sent from 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the plugin, the sending thread cannot send a new message until 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // this one returns, so there is no need to sequence tasks here. If 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the plugin has multiple threads, it cannot make assumptions about 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ordering of IPC message sends, so it cannot make assumptions 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // about ordering of operations caused by those IPC messages. 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scoped_refptr<base::TaskRunner>(BrowserThread::GetBlockingPool()); 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperFlashFileMessageFilter::OnResourceMessageReceived( 86a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch const IPC::Message& msg, 87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ppapi::host::HostMessageContext* context) { 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_BEGIN_MESSAGE_MAP(PepperFlashFileMessageFilter, msg) 89cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFile_OpenFile, 90cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnOpenFile) 91cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFile_RenameFile, 92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnRenameFile) 93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFile_DeleteFileOrDir, 94cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnDeleteFileOrDir) 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFile_CreateDir, 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnCreateDir) 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFile_QueryFile, 98cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnQueryFile) 99cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_FlashFile_GetDirContents, 100cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnGetDirContents) 101cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0( 102cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PpapiHostMsg_FlashFile_CreateTemporaryFile, OnCreateTemporaryFile) 103cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_END_MESSAGE_MAP() 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_ERROR_FAILED; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperFlashFileMessageFilter::OnOpenFile( 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi::host::HostMessageContext* context, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ppapi::PepperFilePath& path, 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int pp_open_flags) { 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::FilePath full_path = ValidateAndConvertPepperFilePath( 112a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch path, base::Bind(&CanOpenWithPepperFlags, pp_open_flags)); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (full_path.empty()) { 114a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ppapi::FileErrorToPepperError(base::File::FILE_ERROR_ACCESS_DENIED); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) int platform_file_flags = 0; 118a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!ppapi::PepperFileOpenFlagsToPlatformFileFlags(pp_open_flags, 119a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &platform_file_flags)) { 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return base::File::FILE_ERROR_FAILED; 121a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 123c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::File file(full_path, platform_file_flags); 124c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!file.IsValid()) { 125c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return ppapi::FileErrorToPepperError(file.error_details()); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure we didn't try to open a directory: directory fd shouldn't be 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // passed to untrusted processes because they open security holes. 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::File::Info info; 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!file.GetInfo(&info) || info.is_directory) { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // When in doubt, throw it out. 133a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ppapi::FileErrorToPepperError(base::File::FILE_ERROR_ACCESS_DENIED); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 136c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IPC::PlatformFileForTransit transit_file = 137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IPC::TakeFileHandleForProcess(file.Pass(), plugin_process_handle_); 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi::host::ReplyMessageContext reply_context = 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context->MakeReplyMessageContext(); 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reply_context.params.AppendHandle(ppapi::proxy::SerializedHandle( 141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ppapi::proxy::SerializedHandle::FILE, transit_file)); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendReply(reply_context, IPC::Message()); 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperFlashFileMessageFilter::OnRenameFile( 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi::host::HostMessageContext* context, 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ppapi::PepperFilePath& from_path, 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ppapi::PepperFilePath& to_path) { 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath from_full_path = ValidateAndConvertPepperFilePath( 1514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) from_path, base::Bind(&CanCreateReadWrite)); 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath to_full_path = ValidateAndConvertPepperFilePath( 1534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) to_path, base::Bind(&CanCreateReadWrite)); 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (from_full_path.empty() || to_full_path.empty()) { 155a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ppapi::FileErrorToPepperError(base::File::FILE_ERROR_ACCESS_DENIED); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool result = base::Move(from_full_path, to_full_path); 159a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ppapi::FileErrorToPepperError( 160a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch result ? base::File::FILE_OK : base::File::FILE_ERROR_ACCESS_DENIED); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperFlashFileMessageFilter::OnDeleteFileOrDir( 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi::host::HostMessageContext* context, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ppapi::PepperFilePath& path, 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool recursive) { 167a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::FilePath full_path = 168a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ValidateAndConvertPepperFilePath(path, base::Bind(&CanCreateReadWrite)); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (full_path.empty()) { 170a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ppapi::FileErrorToPepperError(base::File::FILE_ERROR_ACCESS_DENIED); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool result = base::DeleteFile(full_path, recursive); 174a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ppapi::FileErrorToPepperError( 175a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch result ? base::File::FILE_OK : base::File::FILE_ERROR_ACCESS_DENIED); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperFlashFileMessageFilter::OnCreateDir( 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi::host::HostMessageContext* context, 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ppapi::PepperFilePath& path) { 180a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::FilePath full_path = 181a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ValidateAndConvertPepperFilePath(path, base::Bind(&CanCreateReadWrite)); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (full_path.empty()) { 183a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ppapi::FileErrorToPepperError(base::File::FILE_ERROR_ACCESS_DENIED); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 186a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool result = base::CreateDirectory(full_path); 187a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ppapi::FileErrorToPepperError( 188a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch result ? base::File::FILE_OK : base::File::FILE_ERROR_ACCESS_DENIED); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperFlashFileMessageFilter::OnQueryFile( 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi::host::HostMessageContext* context, 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ppapi::PepperFilePath& path) { 194a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::FilePath full_path = 195a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ValidateAndConvertPepperFilePath(path, base::Bind(&CanRead)); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (full_path.empty()) { 197a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ppapi::FileErrorToPepperError(base::File::FILE_ERROR_ACCESS_DENIED); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::File::Info info; 201a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool result = base::GetFileInfo(full_path, &info); 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context->reply_msg = PpapiPluginMsg_FlashFile_QueryFileReply(info); 203a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ppapi::FileErrorToPepperError( 204a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch result ? base::File::FILE_OK : base::File::FILE_ERROR_ACCESS_DENIED); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperFlashFileMessageFilter::OnGetDirContents( 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi::host::HostMessageContext* context, 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ppapi::PepperFilePath& path) { 210a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::FilePath full_path = 211a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ValidateAndConvertPepperFilePath(path, base::Bind(&CanRead)); 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (full_path.empty()) { 213a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ppapi::FileErrorToPepperError(base::File::FILE_ERROR_ACCESS_DENIED); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi::DirContents contents; 217a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::FileEnumerator enumerator(full_path, 218a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch false, 219a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::FileEnumerator::FILES | 220a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::FileEnumerator::DIRECTORIES | 221a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::FileEnumerator::INCLUDE_DOT_DOT); 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!enumerator.Next().empty()) { 224868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::FileEnumerator::FileInfo info = enumerator.GetInfo(); 225a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ppapi::DirEntry entry = {info.GetName(), info.IsDirectory()}; 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) contents.push_back(entry); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context->reply_msg = PpapiPluginMsg_FlashFile_GetDirContentsReply(contents); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK; 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int32_t PepperFlashFileMessageFilter::OnCreateTemporaryFile( 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi::host::HostMessageContext* context) { 235a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ppapi::PepperFilePath dir_path(ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL, 236a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::FilePath()); 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath validated_dir_path = ValidateAndConvertPepperFilePath( 2384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) dir_path, base::Bind(&CanCreateReadWrite)); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (validated_dir_path.empty() || 2407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch (!base::DirectoryExists(validated_dir_path) && 241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) !base::CreateDirectory(validated_dir_path))) { 242a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ppapi::FileErrorToPepperError(base::File::FILE_ERROR_ACCESS_DENIED); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file_path; 246a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!base::CreateTemporaryFileInDir(validated_dir_path, &file_path)) { 247a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch return ppapi::FileErrorToPepperError(base::File::FILE_ERROR_FAILED); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 250c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::File file(file_path, 251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_READ | 252c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::File::FLAG_WRITE | base::File::FLAG_TEMPORARY | 253c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch base::File::FLAG_DELETE_ON_CLOSE); 254c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 255c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!file.IsValid()) 256c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return ppapi::FileErrorToPepperError(file.error_details()); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 258c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IPC::PlatformFileForTransit transit_file = 259c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch IPC::TakeFileHandleForProcess(file.Pass(), plugin_process_handle_); 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ppapi::host::ReplyMessageContext reply_context = 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) context->MakeReplyMessageContext(); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) reply_context.params.AppendHandle(ppapi::proxy::SerializedHandle( 263c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch ppapi::proxy::SerializedHandle::FILE, transit_file)); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SendReply(reply_context, IPC::Message()); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath PepperFlashFileMessageFilter::ValidateAndConvertPepperFilePath( 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ppapi::PepperFilePath& pepper_path, 270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const CheckPermissionsCallback& check_permissions_callback) const { 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file_path; // Empty path returned on error. 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (pepper_path.domain()) { 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ppapi::PepperFilePath::DOMAIN_ABSOLUTE: 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (pepper_path.path().IsAbsolute() && 275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) check_permissions_callback.Run(render_process_id_, 276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pepper_path.path())) 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_path = pepper_path.path(); 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ppapi::PepperFilePath::DOMAIN_MODULE_LOCAL: 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This filter provides the module name portion of the path to prevent 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // plugins from accessing each other's data. 282a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch if (!plugin_data_directory_.empty() && !pepper_path.path().IsAbsolute() && 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !pepper_path.path().ReferencesParent()) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_path = plugin_data_directory_.Append(pepper_path.path()); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return file_path; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace content 294