diff options
author | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-04 16:23:20 +0000 |
---|---|---|
committer | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-04 16:23:20 +0000 |
commit | 23ebd230311bb3c0b86e7c72ff4129688a5f4f3e (patch) | |
tree | 5bb966848ce13bfae21affd37e2cc534e3a053f8 /chrome | |
parent | e14e05c948c2ff602fcc6a1137c5c61d112cb38f (diff) | |
download | chromium_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.grd | 2 | ||||
-rw-r--r-- | chrome/browser/chromeos/login/existing_user_controller.cc | 10 | ||||
-rw-r--r-- | chrome/browser/chromeos/login/existing_user_controller.h | 4 | ||||
-rw-r--r-- | chrome/browser/dom_ui/filebrowse_ui.cc | 78 | ||||
-rw-r--r-- | chrome/browser/resources/filebrowse.html | 22 |
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'); |