summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjorlow@chromium.org <jorlow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-11 17:46:13 +0000
committerjorlow@chromium.org <jorlow@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-11 17:46:13 +0000
commita3703dd92f9779ada9486a9781b05d071e836099 (patch)
treebb9673d0a5eb14cc5953f86808d17d45e78d805f
parent18fe172980c11836c129b4cdc30e5530c77c10a0 (diff)
downloadchromium_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.cc111
-rw-r--r--chrome/browser/renderer_host/database_dispatcher_host.h20
-rw-r--r--chrome/browser/renderer_host/database_permission_request.cc38
-rw-r--r--chrome/browser/renderer_host/database_permission_request.h46
-rwxr-xr-xchrome/chrome_browser.gypi2
-rw-r--r--webkit/database/database_util.cc17
-rw-r--r--webkit/database/database_util.h4
-rw-r--r--webkit/database/vfs_backend.cc22
-rw-r--r--webkit/database/vfs_backend.h7
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);
};