Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/chromeos/extensions/file_handler_util.h" | 5 #include "chrome/browser/chromeos/extensions/file_handler_util.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
| 9 #include "base/i18n/case_conversion.h" | 9 #include "base/i18n/case_conversion.h" |
| 10 #include "base/json/json_writer.h" | 10 #include "base/json/json_writer.h" |
| 11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
| 12 #include "base/stringprintf.h" | 12 #include "base/stringprintf.h" |
| 13 #include "base/utf_string_conversions.h" | 13 #include "base/utf_string_conversions.h" |
| 14 #include "chrome/browser/chromeos/gdata/gdata_file_system.h" | |
| 15 #include "chrome/browser/chromeos/gdata/gdata_util.h" | |
| 14 #include "chrome/browser/chromeos/extensions/file_manager_util.h" | 16 #include "chrome/browser/chromeos/extensions/file_manager_util.h" |
| 15 #include "chrome/browser/extensions/extension_event_router.h" | 17 #include "chrome/browser/extensions/extension_event_router.h" |
| 16 #include "chrome/browser/extensions/extension_service.h" | 18 #include "chrome/browser/extensions/extension_service.h" |
| 17 #include "chrome/browser/extensions/extension_tab_util.h" | 19 #include "chrome/browser/extensions/extension_tab_util.h" |
| 18 #include "chrome/browser/prefs/scoped_user_pref_update.h" | 20 #include "chrome/browser/prefs/scoped_user_pref_update.h" |
| 19 #include "chrome/browser/profiles/profile.h" | 21 #include "chrome/browser/profiles/profile.h" |
| 20 #include "chrome/browser/ui/browser.h" | 22 #include "chrome/browser/ui/browser.h" |
| 21 #include "chrome/common/extensions/file_browser_handler.h" | 23 #include "chrome/common/extensions/file_browser_handler.h" |
| 22 #include "chrome/common/pref_names.h" | 24 #include "chrome/common/pref_names.h" |
| 23 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 44 base::PLATFORM_FILE_OPEN_ALWAYS | | 46 base::PLATFORM_FILE_OPEN_ALWAYS | |
| 45 base::PLATFORM_FILE_CREATE_ALWAYS | | 47 base::PLATFORM_FILE_CREATE_ALWAYS | |
| 46 base::PLATFORM_FILE_OPEN_TRUNCATED | | 48 base::PLATFORM_FILE_OPEN_TRUNCATED | |
| 47 base::PLATFORM_FILE_READ | | 49 base::PLATFORM_FILE_READ | |
| 48 base::PLATFORM_FILE_WRITE | | 50 base::PLATFORM_FILE_WRITE | |
| 49 base::PLATFORM_FILE_EXCLUSIVE_READ | | 51 base::PLATFORM_FILE_EXCLUSIVE_READ | |
| 50 base::PLATFORM_FILE_EXCLUSIVE_WRITE | | 52 base::PLATFORM_FILE_EXCLUSIVE_WRITE | |
| 51 base::PLATFORM_FILE_ASYNC | | 53 base::PLATFORM_FILE_ASYNC | |
| 52 base::PLATFORM_FILE_WRITE_ATTRIBUTES; | 54 base::PLATFORM_FILE_WRITE_ATTRIBUTES; |
| 53 | 55 |
| 56 const int kReadOnlyFilePermissions = base::PLATFORM_FILE_OPEN | | |
| 57 base::PLATFORM_FILE_READ | | |
| 58 base::PLATFORM_FILE_EXCLUSIVE_READ | | |
| 59 base::PLATFORM_FILE_ASYNC; | |
| 54 | 60 |
| 55 // Returns process id of the process the extension is running in. | 61 // Returns process id of the process the extension is running in. |
| 56 int ExtractProcessFromExtensionId(const std::string& extension_id, | 62 int ExtractProcessFromExtensionId(const std::string& extension_id, |
| 57 Profile* profile) { | 63 Profile* profile) { |
| 58 GURL extension_url = | 64 GURL extension_url = |
| 59 Extension::GetBaseURLFromExtensionId(extension_id); | 65 Extension::GetBaseURLFromExtensionId(extension_id); |
| 60 ExtensionProcessManager* manager = profile->GetExtensionProcessManager(); | 66 ExtensionProcessManager* manager = profile->GetExtensionProcessManager(); |
| 61 | 67 |
| 62 SiteInstance* site_instance = manager->GetSiteInstanceForURL(extension_url); | 68 SiteInstance* site_instance = manager->GetSiteInstanceForURL(extension_url); |
| 63 if (!site_instance || !site_instance->HasProcess()) | 69 if (!site_instance || !site_instance->HasProcess()) |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 155 | 161 |
| 156 void SortLastUsedHandlerList(LastUsedHandlerList *list) { | 162 void SortLastUsedHandlerList(LastUsedHandlerList *list) { |
| 157 // Sort by the last used descending. | 163 // Sort by the last used descending. |
| 158 std::sort(list->begin(), list->end(), SortByLastUsedTimestampDesc); | 164 std::sort(list->begin(), list->end(), SortByLastUsedTimestampDesc); |
| 159 if (list->size() > 1) { | 165 if (list->size() > 1) { |
| 160 // Sort the rest by name. | 166 // Sort the rest by name. |
| 161 std::sort(list->begin() + 1, list->end(), SortByTaskName); | 167 std::sort(list->begin() + 1, list->end(), SortByTaskName); |
| 162 } | 168 } |
| 163 } | 169 } |
| 164 | 170 |
| 171 void SetPermissionsForGDataCacheFiles(Profile* profile, | |
| 172 int pid, | |
|
satorux1
2012/03/22 22:28:29
indentation is off
tonibarzic
2012/03/22 23:38:20
Done.
| |
| 173 const FilePath& path) { | |
| 174 gdata::GDataFileSystem* file_system = | |
| 175 gdata::GDataFileSystemFactory::GetForProfile(profile); | |
| 176 if (!file_system) | |
| 177 return; | |
| 178 | |
| 179 gdata::GDataFileProperties file_properties; | |
| 180 file_system->GetFileInfoFromPath(path, &file_properties); | |
| 181 | |
| 182 std::string resource_id = file_properties.resource_id; | |
| 183 std::string file_md5 = file_properties.file_md5; | |
| 184 | |
| 185 // We check permissions for raw cache file paths only for read-only | |
| 186 // operations (when fileEntry.file() is called), so read only permissions | |
| 187 // should be sufficient for all cache paths. For the rest of supported | |
| 188 // operations the file access check is done for gdata/ paths. | |
| 189 std::vector<std::pair<FilePath, int> > cache_paths; | |
|
zel
2012/03/22 22:21:53
please move the block that gives you all file name
tonibarzic
2012/03/22 23:38:20
Done.
| |
| 190 cache_paths.push_back(std::make_pair( | |
| 191 file_system->GetCacheFilePath(resource_id, file_md5, | |
| 192 gdata::GDataFileSystem::CACHE_TYPE_PERSISTENT, | |
| 193 gdata::GDataFileSystem::CACHED_FILE_FROM_SERVER), | |
| 194 GetReadOnlyPermissions())); | |
| 195 // TODO(tbarzic): When we start supporting openFile operation, we may have to | |
| 196 // change permission for localy modified files to match handler's permissions. | |
| 197 cache_paths.push_back(std::make_pair( | |
| 198 file_system->GetCacheFilePath(resource_id, file_md5, | |
| 199 gdata::GDataFileSystem::CACHE_TYPE_PERSISTENT, | |
| 200 gdata::GDataFileSystem::CACHED_FILE_LOCALLY_MODIFIED), | |
| 201 GetReadOnlyPermissions())); | |
| 202 cache_paths.push_back(std::make_pair( | |
| 203 file_system->GetCacheFilePath(resource_id, file_md5, | |
| 204 gdata::GDataFileSystem::CACHE_TYPE_TMP, | |
| 205 gdata::GDataFileSystem::CACHED_FILE_FROM_SERVER), | |
| 206 GetReadOnlyPermissions())); | |
| 207 | |
| 208 for (size_t i = 0; i < cache_paths.size(); i++) { | |
| 209 ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile( | |
| 210 pid, cache_paths[i].first, cache_paths[i].second); | |
| 211 } | |
| 212 } | |
| 213 | |
| 165 } // namespace | 214 } // namespace |
| 166 | 215 |
| 167 int GetReadWritePermissions() { | 216 int GetReadWritePermissions() { |
| 168 return kReadWriteFilePermissions; | 217 return kReadWriteFilePermissions; |
| 169 } | 218 } |
| 170 | 219 |
| 220 int GetReadOnlyPermissions() { | |
| 221 return kReadOnlyFilePermissions; | |
| 222 } | |
| 223 | |
| 171 std::string MakeTaskID(const std::string& extension_id, | 224 std::string MakeTaskID(const std::string& extension_id, |
| 172 const std::string& action_id) { | 225 const std::string& action_id) { |
| 173 return base::StringPrintf("%s|%s", extension_id.c_str(), action_id.c_str()); | 226 return base::StringPrintf("%s|%s", extension_id.c_str(), action_id.c_str()); |
| 174 } | 227 } |
| 175 | 228 |
| 176 // Breaks down task_id that is used between getFileTasks() and executeTask() on | 229 // Breaks down task_id that is used between getFileTasks() and executeTask() on |
| 177 // its building blocks. task_id field the following structure: | 230 // its building blocks. task_id field the following structure: |
| 178 // <extension-id>|<task-action-id> | 231 // <extension-id>|<task-action-id> |
| 179 // Currently, the only supported task-type is of 'context'. | 232 // Currently, the only supported task-type is of 'context'. |
| 180 bool CrackTaskID(const std::string& task_id, | 233 bool CrackTaskID(const std::string& task_id, |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 384 external_provider->GetFileSystemRootPathOnFileThread( | 437 external_provider->GetFileSystemRootPathOnFileThread( |
| 385 file_origin_url, | 438 file_origin_url, |
| 386 fileapi::kFileSystemTypeExternal, | 439 fileapi::kFileSystemTypeExternal, |
| 387 virtual_path, | 440 virtual_path, |
| 388 false); // create | 441 false); // create |
| 389 FilePath final_file_path = root_path.Append(virtual_path); | 442 FilePath final_file_path = root_path.Append(virtual_path); |
| 390 | 443 |
| 391 // Check if this file system entry exists first. | 444 // Check if this file system entry exists first. |
| 392 base::PlatformFileInfo file_info; | 445 base::PlatformFileInfo file_info; |
| 393 | 446 |
| 394 if (!file_util::PathExists(final_file_path) || | 447 bool is_gdata_file = gdata::util::IsUnderGDataMountPoint(final_file_path); |
| 395 file_util::IsLink(final_file_path) || | |
| 396 !file_util::GetFileInfo(final_file_path, &file_info)) | |
| 397 return false; | |
| 398 | 448 |
| 399 // TODO(zelidrag): Let's just prevent all symlinks for now. We don't want a | 449 // If the file is under gdata mount point, there is no actual file to be |
| 400 // USB drive content to point to something in the rest of the file system. | 450 // found on the final_file_path. |
| 401 // Ideally, we should permit symlinks within the boundary of the same | 451 if (!is_gdata_file) { |
| 402 // virtual mount point. | 452 if (!file_util::PathExists(final_file_path) || |
| 403 if (file_info.is_symbolic_link) | 453 file_util::IsLink(final_file_path) || |
|
satorux1
2012/03/22 22:28:29
Why are we checking IsLink()? we are checking file
tonibarzic
2012/03/22 23:38:20
I'm not sure why we check that, but removed symbol
| |
| 404 return false; | 454 !file_util::GetFileInfo(final_file_path, &file_info)) { |
| 455 return false; | |
| 456 } | |
| 457 | |
| 458 // TODO(zelidrag): Let's just prevent all symlinks for now. We don't want | |
| 459 // a USB drive content to point to something in the rest of the file | |
| 460 // system. Ideally, we should permit symlinks within the boundary of the | |
| 461 // same virtual mount point. | |
| 462 if (file_info.is_symbolic_link) | |
| 463 return false; | |
| 464 } | |
| 405 | 465 |
| 406 // TODO(tbarzic): Add explicit R/W + R/O permissions for non-component | 466 // TODO(tbarzic): Add explicit R/W + R/O permissions for non-component |
| 407 // extensions. | 467 // extensions. |
| 408 | 468 |
| 409 // Grant R/O access permission to non-component extension and R/W to | 469 // Grant R/O access permission to non-component extension and R/W to |
| 410 // component extensions. | 470 // component extensions. |
| 411 ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile( | 471 ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile( |
| 412 handler_pid_, | 472 handler_pid_, |
| 413 final_file_path, | 473 final_file_path, |
| 414 GetReadWritePermissions()); | 474 GetReadWritePermissions()); |
| 415 | 475 |
| 476 if (is_gdata_file) | |
| 477 SetPermissionsForGDataCacheFiles(profile_, handler_pid_, final_file_path); | |
| 478 | |
| 416 // Grant access to this particular file to target extension. This will | 479 // Grant access to this particular file to target extension. This will |
| 417 // ensure that the target extension can access only this FS entry and | 480 // ensure that the target extension can access only this FS entry and |
| 418 // prevent from traversing FS hierarchy upward. | 481 // prevent from traversing FS hierarchy upward. |
| 419 external_provider->GrantFileAccessToExtension(handler_extension_->id(), | 482 external_provider->GrantFileAccessToExtension(handler_extension_->id(), |
| 420 virtual_path); | 483 virtual_path); |
| 421 | 484 |
| 422 // Output values. | 485 // Output values. |
| 423 GURL target_origin_url(Extension::GetBaseURLFromExtensionId( | 486 GURL target_origin_url(Extension::GetBaseURLFromExtensionId( |
| 424 handler_extension_->id())); | 487 handler_extension_->id())); |
| 425 GURL base_url = fileapi::GetFileSystemRootURI(target_origin_url, | 488 GURL base_url = fileapi::GetFileSystemRootURI(target_origin_url, |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 560 base::JSONWriter::Write(event_args.get(), &json_args); | 623 base::JSONWriter::Write(event_args.get(), &json_args); |
| 561 event_router->DispatchEventToExtension( | 624 event_router->DispatchEventToExtension( |
| 562 extension_id_, std::string("fileBrowserHandler.onExecute"), | 625 extension_id_, std::string("fileBrowserHandler.onExecute"), |
| 563 json_args, profile_, | 626 json_args, profile_, |
| 564 GURL()); | 627 GURL()); |
| 565 Done(true); | 628 Done(true); |
| 566 } | 629 } |
| 567 | 630 |
| 568 } // namespace file_handler_util | 631 } // namespace file_handler_util |
| 569 | 632 |
| OLD | NEW |