summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-04 16:23:20 +0000
committerxiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-04 16:23:20 +0000
commit23ebd230311bb3c0b86e7c72ff4129688a5f4f3e (patch)
tree5bb966848ce13bfae21affd37e2cc534e3a053f8 /chrome
parente14e05c948c2ff602fcc6a1137c5c61d112cb38f (diff)
downloadchromium_src-23ebd230311bb3c0b86e7c72ff4129688a5f4f3e.zip
chromium_src-23ebd230311bb3c0b86e7c72ff4129688a5f4f3e.tar.gz
chromium_src-23ebd230311bb3c0b86e7c72ff4129688a5f4f3e.tar.bz2
[ChroemOS] Add protection for settings spoof.
- Add path validation for SaveAs dialog in FileBrowse DOMUI; - Add a UserCrosSettingsProvider instance to ExistingUserController. This triggers cached settings refresh on login screen and protect us from setting spoofing. BUG=chromium-os:7738 TEST=Verify user could not save file outside default download dir andoverify that spoofed settings will be reverted on login screen show up. Review URL: http://codereview.chromium.org/4181008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65066 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/browser_resources.grd2
-rw-r--r--chrome/browser/chromeos/login/existing_user_controller.cc10
-rw-r--r--chrome/browser/chromeos/login/existing_user_controller.h4
-rw-r--r--chrome/browser/dom_ui/filebrowse_ui.cc78
-rw-r--r--chrome/browser/resources/filebrowse.html22
5 files changed, 113 insertions, 3 deletions
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 5edff45..2f7d831 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This comment is only here because changes to resources are not picked up
-without changes to the corresponding grd file. ete -->
+without changes to the corresponding grd file. et -->
<grit latest_public_release="0" current_release="1">
<outputs>
<output filename="grit/browser_resources.h" type="rc_header">
diff --git a/chrome/browser/chromeos/login/existing_user_controller.cc b/chrome/browser/chromeos/login/existing_user_controller.cc
index 84532a9..4ee8be9 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.cc
+++ b/chrome/browser/chromeos/login/existing_user_controller.cc
@@ -104,6 +104,7 @@ void EnableTooltipsIfNeeded(const std::vector<UserController*>& controllers) {
ExistingUserController*
ExistingUserController::delete_scheduled_instance_ = NULL;
+// TODO(xiyuan): Wait for the cached settings update before using them.
ExistingUserController::ExistingUserController(
const std::vector<UserManager::User>& users,
const gfx::Rect& background_bounds)
@@ -112,7 +113,8 @@ ExistingUserController::ExistingUserController(
background_view_(NULL),
selected_view_index_(kNotSelected),
num_login_attempts_(0),
- bubble_(NULL) {
+ bubble_(NULL),
+ user_settings_(new UserCrosSettingsProvider()) {
if (delete_scheduled_instance_)
delete_scheduled_instance_->Delete();
@@ -336,6 +338,12 @@ void ExistingUserController::ActivateWizard(const std::string& screen_name) {
void ExistingUserController::RemoveUser(UserController* source) {
ClearErrors();
+ // TODO(xiyuan): Wait for the cached settings update before using them.
+ if (UserCrosSettingsProvider::cached_owner() == source->user().email()) {
+ // Owner is not allowed to be removed from the device.
+ return;
+ }
+
UserManager::Get()->RemoveUser(source->user().email());
controllers_.erase(controllers_.begin() + source->user_index());
diff --git a/chrome/browser/chromeos/login/existing_user_controller.h b/chrome/browser/chromeos/login/existing_user_controller.h
index 080ff9c..aa4d7ca 100644
--- a/chrome/browser/chromeos/login/existing_user_controller.h
+++ b/chrome/browser/chromeos/login/existing_user_controller.h
@@ -26,6 +26,7 @@ namespace chromeos {
class HelpAppLauncher;
class MessageBubble;
+class UserCrosSettingsProvider;
// ExistingUserController is used to handle login when someone has
// already logged into the machine. When Init is invoked, a
@@ -164,6 +165,9 @@ class ExistingUserController : public WmMessageListener::Observer,
// Help application used for help dialogs.
scoped_ptr<HelpAppLauncher> help_app_;
+ // A user settings provider instance to trigger settings cache update.
+ scoped_ptr<UserCrosSettingsProvider> user_settings_;
+
DISALLOW_COPY_AND_ASSIGN(ExistingUserController);
};
diff --git a/chrome/browser/dom_ui/filebrowse_ui.cc b/chrome/browser/dom_ui/filebrowse_ui.cc
index 7c34413..9ea95b3 100644
--- a/chrome/browser/dom_ui/filebrowse_ui.cc
+++ b/chrome/browser/dom_ui/filebrowse_ui.cc
@@ -7,6 +7,7 @@
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "base/callback.h"
+#include "base/file_util.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/path_service.h"
@@ -182,6 +183,16 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate,
void FireUploadComplete();
void SendPicasawebRequest();
+
+ // Callback for the "validateSavePath" message.
+ void HandleValidateSavePath(const ListValue* args);
+
+ // Validate a save path on file thread.
+ void ValidateSavePathOnFileThread(const FilePath& save_path);
+
+ // Fire save path validation result to JS onValidatedSavePath.
+ void FireOnValidatedSavePathOnUIThread(bool valid, const FilePath& save_path);
+
private:
void OpenNewWindow(const ListValue* args, bool popup);
@@ -266,6 +277,17 @@ class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> {
handler_->FireCopyComplete(src_, dest_);
}
}
+
+ void ValidateSavePathOnFileThread() {
+ if (handler_)
+ handler_->ValidateSavePathOnFileThread(src_);
+ }
+ void FireOnValidatedSavePathOnUIThread(bool valid,
+ const FilePath& save_path) {
+ if (handler_)
+ handler_->FireOnValidatedSavePathOnUIThread(valid, save_path);
+ }
+
private:
base::WeakPtr<FilebrowseHandler> handler_;
FilePath src_;
@@ -460,6 +482,8 @@ void FilebrowseHandler::RegisterMessages() {
NewCallback(this, &FilebrowseHandler::HandleRefreshDirectory));
dom_ui_->RegisterMessageCallback("isAdvancedEnabled",
NewCallback(this, &FilebrowseHandler::HandleIsAdvancedEnabled));
+ dom_ui_->RegisterMessageCallback("validateSavePath",
+ NewCallback(this, &FilebrowseHandler::HandleValidateSavePath));
}
@@ -991,6 +1015,60 @@ void FilebrowseHandler::HandleCopyFile(const ListValue* value) {
#endif
}
+void FilebrowseHandler::HandleValidateSavePath(const ListValue* args) {
+ std::string string_path;
+ if (!args || !args->GetString(0, &string_path)) {
+ FireOnValidatedSavePathOnUIThread(false, FilePath()); // Invalid save path.
+ return;
+ }
+
+ FilePath save_path(string_path);
+
+#if defined(OS_CHROMEOS)
+ scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), save_path);
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(task.get(), &TaskProxy::ValidateSavePathOnFileThread));
+#else
+ // No save path checking for non-ChromeOS platforms.
+ FireOnValidatedSavePathOnUIThread(true, save_path);
+#endif
+}
+
+void FilebrowseHandler::ValidateSavePathOnFileThread(
+ const FilePath& save_path) {
+#if defined(OS_CHROMEOS)
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
+
+ FilePath default_download_path;
+ if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS,
+ &default_download_path)) {
+ NOTREACHED();
+ }
+
+ // Get containing folder of save_path.
+ FilePath save_dir = save_path.DirName();
+
+ // Valid save path must be inside default download dir.
+ bool valid = default_download_path == save_dir ||
+ file_util::ContainsPath(default_download_path, save_dir);
+
+ scoped_refptr<TaskProxy> task = new TaskProxy(AsWeakPtr(), save_path);
+ BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
+ NewRunnableMethod(task.get(),
+ &TaskProxy::FireOnValidatedSavePathOnUIThread,
+ valid, save_path));
+#endif
+}
+
+void FilebrowseHandler::FireOnValidatedSavePathOnUIThread(bool valid,
+ const FilePath& save_path) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ FundamentalValue valid_value(valid);
+ StringValue path_value(save_path.value());
+ dom_ui_->CallJavascriptFunction(L"onValidatedSavePath",
+ valid_value, path_value);
+}
void FilebrowseHandler::OnDownloadUpdated(DownloadItem* download) {
DownloadList::iterator it = find(active_download_items_.begin(),
diff --git a/chrome/browser/resources/filebrowse.html b/chrome/browser/resources/filebrowse.html
index 3627f57..5c33205 100644
--- a/chrome/browser/resources/filebrowse.html
+++ b/chrome/browser/resources/filebrowse.html
@@ -598,6 +598,10 @@ div.fullcontainer {
background: url('../../app/theme/alert_small.png');
}
+input.error {
+ background-color: #ff6666;
+}
+
</style>
<script src="shared/js/local_strings.js"></script>
<script src="shared/js/media_common.js"></script>
@@ -998,9 +1002,25 @@ function dialogSaveClick() {
}
currentPath += '/';
currentPath += filename;
- chrome.send('DialogClose', [JSON.stringify({'path' : currentPath})]);
+ chrome.send('validateSavePath', [currentPath]);
+
+ filenameInput.disabled = true;
+ $('savebutton').disabled = true;
};
+function onValidatedSavePath(valid, savePath) {
+ var filenameInput = $('filename');
+
+ filenameInput.disabled = false;
+ $('savebutton').disabled = false;
+
+ if (valid) {
+ filenameInput.classList.remove('error');
+ chrome.send('DialogClose', [JSON.stringify({'path' : savePath})]);
+ } else {
+ filenameInput.classList.add('error');
+ }
+}
function createNewFormItem(initialName, isDirectory, id, blurcallback, keypresscallback) {
var element = document.createElement('li');