diff options
author | jorlow@chromium.org <jorlow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-11 17:46:13 +0000 |
---|---|---|
committer | jorlow@chromium.org <jorlow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-11 17:46:13 +0000 |
commit | a3703dd92f9779ada9486a9781b05d071e836099 (patch) | |
tree | bb9673d0a5eb14cc5953f86808d17d45e78d805f | |
parent | 18fe172980c11836c129b4cdc30e5530c77c10a0 (diff) | |
download | chromium_src-a3703dd92f9779ada9486a9781b05d071e836099.zip chromium_src-a3703dd92f9779ada9486a9781b05d071e836099.tar.gz chromium_src-a3703dd92f9779ada9486a9781b05d071e836099.tar.bz2 |
Add support for CONTENT_SETTING_ASK to database.
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/572001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38783 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/renderer_host/database_dispatcher_host.cc | 111 | ||||
-rw-r--r-- | chrome/browser/renderer_host/database_dispatcher_host.h | 20 | ||||
-rw-r--r-- | chrome/browser/renderer_host/database_permission_request.cc | 38 | ||||
-rw-r--r-- | chrome/browser/renderer_host/database_permission_request.h | 46 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | webkit/database/database_util.cc | 17 | ||||
-rw-r--r-- | webkit/database/database_util.h | 4 | ||||
-rw-r--r-- | webkit/database/vfs_backend.cc | 22 | ||||
-rw-r--r-- | webkit/database/vfs_backend.h | 7 |
9 files changed, 240 insertions, 27 deletions
diff --git a/chrome/browser/renderer_host/database_dispatcher_host.cc b/chrome/browser/renderer_host/database_dispatcher_host.cc index c79796a..d72ca06 100644 --- a/chrome/browser/renderer_host/database_dispatcher_host.cc +++ b/chrome/browser/renderer_host/database_dispatcher_host.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -18,11 +18,17 @@ #include "base/thread.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_thread.h" +#include "chrome/browser/net/chrome_url_request_context.h" #include "chrome/browser/renderer_host/browser_render_process_host.h" +#include "chrome/browser/renderer_host/database_permission_request.h" +#include "chrome/browser/renderer_host/resource_message_filter.h" #include "chrome/common/render_messages.h" +#include "googleurl/src/gurl.h" +#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h" #include "webkit/database/database_util.h" #include "webkit/database/vfs_backend.h" +using WebKit::WebSecurityOrigin; using webkit_database::DatabaseTracker; using webkit_database::DatabaseUtil; using webkit_database::VfsBackend; @@ -32,14 +38,14 @@ const int kDelayDeleteRetryMs = 100; DatabaseDispatcherHost::DatabaseDispatcherHost( DatabaseTracker* db_tracker, - IPC::Message::Sender* message_sender) + ResourceMessageFilter* resource_message_filter) : db_tracker_(db_tracker), - message_sender_(message_sender), + resource_message_filter_(resource_message_filter), process_handle_(0), observer_added_(false), shutdown_(false) { DCHECK(db_tracker_); - DCHECK(message_sender_); + DCHECK(resource_message_filter_); } void DatabaseDispatcherHost::Init(base::ProcessHandle process_handle) { @@ -52,7 +58,7 @@ void DatabaseDispatcherHost::Init(base::ProcessHandle process_handle) { void DatabaseDispatcherHost::Shutdown() { shutdown_ = true; - message_sender_ = NULL; + resource_message_filter_ = NULL; if (observer_added_) { ChromeThread::PostTask( ChromeThread::FILE, FROM_HERE, @@ -106,7 +112,7 @@ void DatabaseDispatcherHost::ReceivedBadMessage(uint32 msg_type) { void DatabaseDispatcherHost::SendMessage(IPC::Message* message) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); if (!shutdown_) - message_sender_->Send(message); + resource_message_filter_->Send(message); else delete message; } @@ -121,13 +127,51 @@ void DatabaseDispatcherHost::OnDatabaseOpenFile(const string16& vfs_file_name, NewRunnableMethod(this, &DatabaseDispatcherHost::AddObserver)); } - ChromeThread::PostTask( - ChromeThread::FILE, FROM_HERE, - NewRunnableMethod(this, - &DatabaseDispatcherHost::DatabaseOpenFile, - vfs_file_name, - desired_flags, - message_id)); + // Only ask permission on the main database file in read/write mode. + if (!VfsBackend::FileTypeIsMainDB(desired_flags) || + !VfsBackend::OpenTypeIsReadWrite(desired_flags)) { + OnDatabaseOpenFileAllowed(vfs_file_name, desired_flags, message_id); + return; + } + + string16 origin_identifier; + string16 database_name; + bool ok = DatabaseUtil::CrackVfsFileName(vfs_file_name, + &origin_identifier, + &database_name, + NULL); + DCHECK(ok); // Should we assume this is an attack and kill the renderer? + if (!ok) { + OnDatabaseOpenFileBlocked(message_id); + return; + } + + // TODO(jorlow): createFromDatabaseIdentifier should not return a pointer. + scoped_ptr<WebSecurityOrigin> security_origin( + WebSecurityOrigin::createFromDatabaseIdentifier(origin_identifier)); + string16 origin(security_origin->toString()); + + ContentSetting content_setting = GetContentSetting(origin); + if (content_setting == CONTENT_SETTING_ASK) { + // Create a task for each possible outcome. + scoped_ptr<Task> on_allow(NewRunnableMethod( + this, &DatabaseDispatcherHost::OnDatabaseOpenFileAllowed, + vfs_file_name, desired_flags, message_id)); + scoped_ptr<Task> on_block(NewRunnableMethod( + this, &DatabaseDispatcherHost::OnDatabaseOpenFileBlocked, message_id)); + // And then let the permission request object do the rest. + scoped_refptr<DatabasePermissionRequest> request( + new DatabasePermissionRequest(origin, + database_name, + on_allow.release(), + on_block.release())); + request->RequestPermission(); + } else if (content_setting == CONTENT_SETTING_ALLOW) { + OnDatabaseOpenFileAllowed(vfs_file_name, desired_flags, message_id); + } else { + DCHECK(content_setting == CONTENT_SETTING_BLOCK); + OnDatabaseOpenFileBlocked(message_id); + } } static void SetOpenFileResponseParams( @@ -385,3 +429,44 @@ void DatabaseDispatcherHost::OnDatabaseSizeChanged( database_size, space_available))); } } + +void DatabaseDispatcherHost::OnDatabaseOpenFileAllowed( + const string16& vfs_file_name, int desired_flags, int32 message_id) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + if (shutdown_) + return; + + ChromeThread::PostTask( + ChromeThread::FILE, FROM_HERE, + NewRunnableMethod(this, + &DatabaseDispatcherHost::DatabaseOpenFile, + vfs_file_name, + desired_flags, + message_id)); +} + +void DatabaseDispatcherHost::OnDatabaseOpenFileBlocked(int32 message_id) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + if (shutdown_) + return; + + // This will result in failed transactions NOT a failed window.openDatabase + // call. + ViewMsg_DatabaseOpenFileResponse_Params response_params; + SetOpenFileResponseParams(&response_params, + base::kInvalidPlatformFileValue, + base::kInvalidPlatformFileValue); + SendMessage(new ViewMsg_DatabaseOpenFileResponse(message_id, + response_params)); +} + +ContentSetting DatabaseDispatcherHost::GetContentSetting( + const string16& origin) { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + GURL url = GURL(origin); + std::string host = url.host(); + ChromeURLRequestContext* url_request_context = + resource_message_filter_->GetRequestContextForURL(url); + return url_request_context->host_content_settings_map()->GetContentSetting( + host, CONTENT_SETTINGS_TYPE_COOKIES); +} diff --git a/chrome/browser/renderer_host/database_dispatcher_host.h b/chrome/browser/renderer_host/database_dispatcher_host.h index 301c261..95f8d86 100644 --- a/chrome/browser/renderer_host/database_dispatcher_host.h +++ b/chrome/browser/renderer_host/database_dispatcher_host.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -9,16 +9,19 @@ #include "base/process.h" #include "base/ref_counted.h" #include "base/string16.h" +#include "chrome/common/content_settings.h" #include "ipc/ipc_message.h" #include "webkit/database/database_connections.h" #include "webkit/database/database_tracker.h" +class ResourceMessageFilter; + class DatabaseDispatcherHost : public base::RefCountedThreadSafe<DatabaseDispatcherHost>, public webkit_database::DatabaseTracker::Observer { public: DatabaseDispatcherHost(webkit_database::DatabaseTracker* db_tracker, - IPC::Message::Sender* message_sender); + ResourceMessageFilter* resource_message_filter); void Init(base::ProcessHandle process_handle); void Shutdown(); @@ -82,11 +85,20 @@ class DatabaseDispatcherHost void DatabaseClosed(const string16& origin_identifier, const string16& database_name); + // Called once we decide whether to allow or block an open file request. + void OnDatabaseOpenFileAllowed(const string16& vfs_file_name, + int desired_flags, + int32 message_id); + void OnDatabaseOpenFileBlocked(int32 message_id); + + // Get the content setting based on an origin. IO thread only. + ContentSetting GetContentSetting(const string16& origin); + // The database tracker for the current profile. scoped_refptr<webkit_database::DatabaseTracker> db_tracker_; - // The sender to be used for sending out IPC messages. - IPC::Message::Sender* message_sender_; + // The resource message filter that owns us. + ResourceMessageFilter* resource_message_filter_; // The handle of this process. base::ProcessHandle process_handle_; diff --git a/chrome/browser/renderer_host/database_permission_request.cc b/chrome/browser/renderer_host/database_permission_request.cc new file mode 100644 index 0000000..73a9977 --- /dev/null +++ b/chrome/browser/renderer_host/database_permission_request.cc @@ -0,0 +1,38 @@ +// Copyright (c) 2010 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 "chrome/browser/renderer_host/database_permission_request.h" + +#include "chrome/browser/chrome_thread.h" + +DatabasePermissionRequest::DatabasePermissionRequest( + const string16& origin, + const string16& database_name, + Task* on_allow, + Task* on_block) + : origin_(origin), + database_name_(database_name), + on_allow_(on_allow), + on_block_(on_block) { + DCHECK(on_allow_.get()); + DCHECK(on_block_.get()); +} + +DatabasePermissionRequest::~DatabasePermissionRequest() { +} + +void DatabasePermissionRequest::RequestPermission() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO)); + ChromeThread::PostTask( + ChromeThread::UI, FROM_HERE, NewRunnableMethod( + this, &DatabasePermissionRequest::RequestPermissionUI)); +} + +void DatabasePermissionRequest::RequestPermissionUI() { + DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); + bool allow = false; // TODO(jorlow/darin): Allow user to choose. + + Task* task = allow ? on_allow_.release() : on_block_.release(); + ChromeThread::PostTask(ChromeThread::IO, FROM_HERE, task); +} diff --git a/chrome/browser/renderer_host/database_permission_request.h b/chrome/browser/renderer_host/database_permission_request.h new file mode 100644 index 0000000..7760dcd --- /dev/null +++ b/chrome/browser/renderer_host/database_permission_request.h @@ -0,0 +1,46 @@ +// Copyright (c) 2010 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 CHROME_BROWSER_RENDERER_HOST_DATABASE_PERMISSION_REQUEST_H_ +#define CHROME_BROWSER_RENDERER_HOST_DATABASE_PERMISSION_REQUEST_H_ + +#include "base/ref_counted.h" +#include "base/scoped_ptr.h" +#include "base/string16.h" + +class Task; + +// This class is fully threadsafe. +class DatabasePermissionRequest + : public base::RefCountedThreadSafe<DatabasePermissionRequest> { + public: + DatabasePermissionRequest(const string16& origin, + const string16& database_name, + Task* on_allow, + Task* on_block); + ~DatabasePermissionRequest(); + + const string16& origin() const { return origin_; } + const string16& database_name() const { return database_name_; } + + // Start the permission request process. + void RequestPermission(); + + private: + // Called on the UI thread to pop up UI to request permission to open the + // database. + void RequestPermissionUI(); + + // Info to provide the user while asking for permission. + const string16 origin_; + const string16 database_name_; + + // Set on IO, possibly release()ed on UI, destroyed on IO or UI. + scoped_ptr<Task> on_allow_; + scoped_ptr<Task> on_block_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(DatabasePermissionRequest); +}; + +#endif // CHROME_BROWSER_RENDERER_HOST_DATABASE_PERMISSION_REQUEST_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 11fcd60..d16a4d8 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1497,6 +1497,8 @@ 'browser/renderer_host/cross_site_resource_handler.h', 'browser/renderer_host/database_dispatcher_host.cc', 'browser/renderer_host/database_dispatcher_host.h', + 'browser/renderer_host/database_permission_request.cc', + 'browser/renderer_host/database_permission_request.h', 'browser/renderer_host/download_resource_handler.cc', 'browser/renderer_host/download_resource_handler.h', 'browser/renderer_host/download_throttling_resource_handler.cc', diff --git a/webkit/database/database_util.cc b/webkit/database/database_util.cc index ae52a5a..4866b30 100644 --- a/webkit/database/database_util.cc +++ b/webkit/database/database_util.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -28,11 +28,16 @@ bool DatabaseUtil::CrackVfsFileName(const string16& vfs_file_name, return false; } - *origin_identifier = vfs_file_name.substr(0, first_slash_index); - *database_name = vfs_file_name.substr( - first_slash_index + 1, last_pound_index - first_slash_index - 1); - *sqlite_suffix = vfs_file_name.substr( - last_pound_index + 1, vfs_file_name.length() - last_pound_index - 1); + if (origin_identifier) + *origin_identifier = vfs_file_name.substr(0, first_slash_index); + if (database_name) { + *database_name = vfs_file_name.substr( + first_slash_index + 1, last_pound_index - first_slash_index - 1); + } + if (sqlite_suffix) { + *sqlite_suffix = vfs_file_name.substr( + last_pound_index + 1, vfs_file_name.length() - last_pound_index - 1); + } return true; } diff --git a/webkit/database/database_util.h b/webkit/database/database_util.h index c18e5f4..2aa35b3 100644 --- a/webkit/database/database_util.h +++ b/webkit/database/database_util.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -14,6 +14,8 @@ class DatabaseTracker; class DatabaseUtil { public: + // Extract various information from a database vfs_file_name. All return + // parameters are optional. static bool CrackVfsFileName(const string16& vfs_file_name, string16* origin_identifier, string16* database_name, diff --git a/webkit/database/vfs_backend.cc b/webkit/database/vfs_backend.cc index 2c5467f..8c1b50b 100644 --- a/webkit/database/vfs_backend.cc +++ b/webkit/database/vfs_backend.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -16,8 +16,21 @@ namespace webkit_database { +static const int kFileTypeMask = 0x00007F00; + +// static +bool VfsBackend::FileTypeIsMainDB(int desired_flags) { + return (desired_flags & kFileTypeMask) == SQLITE_OPEN_MAIN_DB; +} + +// static +bool VfsBackend::OpenTypeIsReadWrite(int desired_flags) { + return desired_flags & SQLITE_OPEN_READWRITE; +} + +// static bool VfsBackend::OpenFileFlagsAreConsistent(int desired_flags) { - const int file_type = desired_flags & 0x00007F00; + const int file_type = desired_flags & kFileTypeMask; const bool is_exclusive = (desired_flags & SQLITE_OPEN_EXCLUSIVE) != 0; const bool is_delete = (desired_flags & SQLITE_OPEN_DELETEONCLOSE) != 0; const bool is_create = (desired_flags & SQLITE_OPEN_CREATE) != 0; @@ -54,6 +67,7 @@ bool VfsBackend::OpenFileFlagsAreConsistent(int desired_flags) { (file_type == SQLITE_OPEN_TRANSIENT_DB); } +// static void VfsBackend::OpenFile(const FilePath& file_path, int desired_flags, base::ProcessHandle handle, @@ -124,6 +138,7 @@ void VfsBackend::OpenFile(const FilePath& file_path, } } +// static void VfsBackend::OpenTempFileInDirectory( const FilePath& dir_path, int desired_flags, @@ -146,6 +161,7 @@ void VfsBackend::OpenTempFileInDirectory( target_handle, target_dir_handle); } +// static int VfsBackend::DeleteFile(const FilePath& file_path, bool sync_dir) { if (!file_util::PathExists(file_path)) return SQLITE_OK; @@ -169,6 +185,7 @@ int VfsBackend::DeleteFile(const FilePath& file_path, bool sync_dir) { return error_code; } +// static uint32 VfsBackend::GetFileAttributes(const FilePath& file_path) { #if defined(OS_WIN) uint32 attributes = ::GetFileAttributes(file_path.value().c_str()); @@ -184,6 +201,7 @@ uint32 VfsBackend::GetFileAttributes(const FilePath& file_path) { return attributes; } +// static int64 VfsBackend::GetFileSize(const FilePath& file_path) { int64 size = 0; return (file_util::GetFileSize(file_path, &size) ? size : 0); diff --git a/webkit/database/vfs_backend.h b/webkit/database/vfs_backend.h index 44de808..97ce7e0 100644 --- a/webkit/database/vfs_backend.h +++ b/webkit/database/vfs_backend.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 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. @@ -20,6 +20,7 @@ class VfsBackend { base::ProcessHandle handle, base::PlatformFile* target_handle, base::PlatformFile* target_dir_handle); + static void OpenTempFileInDirectory(const FilePath& dir_path, int desired_flags, base::ProcessHandle handle, @@ -32,6 +33,10 @@ class VfsBackend { static int64 GetFileSize(const FilePath& file_path); + // Used to make decisions in the DatabaseDispatcherHost. + static bool FileTypeIsMainDB(int desired_flags); + static bool OpenTypeIsReadWrite(int desired_flags); + private: static bool OpenFileFlagsAreConsistent(int desired_flags); }; |