| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/common/extensions/extension.h" | 5 #include "chrome/common/extensions/extension.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 current_whitelist->push_back(*it); | 399 current_whitelist->push_back(*it); |
| 400 } | 400 } |
| 401 } | 401 } |
| 402 | 402 |
| 403 // static | 403 // static |
| 404 const Extension::ScriptingWhitelist* Extension::GetScriptingWhitelist() { | 404 const Extension::ScriptingWhitelist* Extension::GetScriptingWhitelist() { |
| 405 return ExtensionConfig::GetInstance()->whitelist(); | 405 return ExtensionConfig::GetInstance()->whitelist(); |
| 406 } | 406 } |
| 407 | 407 |
| 408 bool Extension::HasAPIPermission(APIPermission::ID permission) const { | 408 bool Extension::HasAPIPermission(APIPermission::ID permission) const { |
| 409 base::AutoLock auto_lock(runtime_data_lock_); | 409 return PermissionsData::HasAPIPermission(this, permission); |
| 410 return runtime_data_.GetActivePermissions()->HasAPIPermission(permission); | |
| 411 } | 410 } |
| 412 | 411 |
| 413 bool Extension::HasAPIPermission(const std::string& function_name) const { | 412 bool Extension::HasAPIPermission(const std::string& function_name) const { |
| 414 base::AutoLock auto_lock(runtime_data_lock_); | 413 return PermissionsData::HasAPIPermission(this, function_name); |
| 415 return runtime_data_.GetActivePermissions()-> | |
| 416 HasAccessToFunction(function_name, true); | |
| 417 } | |
| 418 | |
| 419 bool Extension::HasAPIPermissionForTab(int tab_id, | |
| 420 APIPermission::ID permission) const { | |
| 421 base::AutoLock auto_lock(runtime_data_lock_); | |
| 422 if (runtime_data_.GetActivePermissions()->HasAPIPermission(permission)) | |
| 423 return true; | |
| 424 scoped_refptr<const PermissionSet> tab_specific_permissions = | |
| 425 runtime_data_.GetTabSpecificPermissions(tab_id); | |
| 426 return tab_specific_permissions.get() && | |
| 427 tab_specific_permissions->HasAPIPermission(permission); | |
| 428 } | |
| 429 | |
| 430 bool Extension::CheckAPIPermissionWithParam(APIPermission::ID permission, | |
| 431 const APIPermission::CheckParam* param) const { | |
| 432 base::AutoLock auto_lock(runtime_data_lock_); | |
| 433 return runtime_data_.GetActivePermissions()-> | |
| 434 CheckAPIPermissionWithParam(permission, param); | |
| 435 } | |
| 436 | |
| 437 const URLPatternSet& Extension::GetEffectiveHostPermissions() const { | |
| 438 base::AutoLock auto_lock(runtime_data_lock_); | |
| 439 return runtime_data_.GetActivePermissions()->effective_hosts(); | |
| 440 } | |
| 441 | |
| 442 bool Extension::CanSilentlyIncreasePermissions() const { | |
| 443 return location() != Manifest::INTERNAL; | |
| 444 } | |
| 445 | |
| 446 bool Extension::HasHostPermission(const GURL& url) const { | |
| 447 base::AutoLock auto_lock(runtime_data_lock_); | |
| 448 return runtime_data_.GetActivePermissions()-> | |
| 449 HasExplicitAccessToOrigin(url); | |
| 450 } | |
| 451 | |
| 452 bool Extension::HasEffectiveAccessToAllHosts() const { | |
| 453 base::AutoLock auto_lock(runtime_data_lock_); | |
| 454 return runtime_data_.GetActivePermissions()->HasEffectiveAccessToAllHosts(); | |
| 455 } | |
| 456 | |
| 457 bool Extension::HasFullPermissions() const { | |
| 458 base::AutoLock auto_lock(runtime_data_lock_); | |
| 459 return runtime_data_.GetActivePermissions()->HasEffectiveFullAccess(); | |
| 460 } | |
| 461 | |
| 462 PermissionMessages Extension::GetPermissionMessages() const { | |
| 463 base::AutoLock auto_lock(runtime_data_lock_); | |
| 464 if (IsTrustedId(id())) { | |
| 465 return PermissionMessages(); | |
| 466 } else { | |
| 467 return runtime_data_.GetActivePermissions()->GetPermissionMessages( | |
| 468 GetType()); | |
| 469 } | |
| 470 } | |
| 471 | |
| 472 std::vector<string16> Extension::GetPermissionMessageStrings() const { | |
| 473 base::AutoLock auto_lock(runtime_data_lock_); | |
| 474 if (IsTrustedId(id())) | |
| 475 return std::vector<string16>(); | |
| 476 else | |
| 477 return runtime_data_.GetActivePermissions()->GetWarningMessages(GetType()); | |
| 478 } | |
| 479 | |
| 480 bool Extension::ShouldSkipPermissionWarnings() const { | |
| 481 return IsTrustedId(id()); | |
| 482 } | |
| 483 | |
| 484 void Extension::SetActivePermissions(const PermissionSet* permissions) const { | |
| 485 base::AutoLock auto_lock(runtime_data_lock_); | |
| 486 runtime_data_.SetActivePermissions(permissions); | |
| 487 } | 414 } |
| 488 | 415 |
| 489 scoped_refptr<const PermissionSet> Extension::GetActivePermissions() const { | 416 scoped_refptr<const PermissionSet> Extension::GetActivePermissions() const { |
| 490 base::AutoLock auto_lock(runtime_data_lock_); | 417 return PermissionsData::GetActivePermissions(this); |
| 491 return runtime_data_.GetActivePermissions(); | |
| 492 } | 418 } |
| 493 | 419 |
| 494 bool Extension::ShowConfigureContextMenus() const { | 420 bool Extension::ShowConfigureContextMenus() const { |
| 495 // Don't show context menu for component extensions. We might want to show | 421 // Don't show context menu for component extensions. We might want to show |
| 496 // options for component extension button but now there is no component | 422 // options for component extension button but now there is no component |
| 497 // extension with options. All other menu items like uninstall have | 423 // extension with options. All other menu items like uninstall have |
| 498 // no sense for component extensions. | 424 // no sense for component extensions. |
| 499 return location() != Manifest::COMPONENT; | 425 return location() != Manifest::COMPONENT; |
| 500 } | 426 } |
| 501 | 427 |
| 502 GURL Extension::GetFullLaunchURL() const { | 428 GURL Extension::GetFullLaunchURL() const { |
| 503 return launch_local_path().empty() ? GURL(launch_web_url()) : | 429 return launch_local_path().empty() ? GURL(launch_web_url()) : |
| 504 url().Resolve(launch_local_path()); | 430 url().Resolve(launch_local_path()); |
| 505 } | 431 } |
| 506 | 432 |
| 507 bool Extension::CanExecuteScriptOnPage(const GURL& document_url, | |
| 508 const GURL& top_frame_url, | |
| 509 int tab_id, | |
| 510 const UserScript* script, | |
| 511 std::string* error) const { | |
| 512 base::AutoLock auto_lock(runtime_data_lock_); | |
| 513 // The gallery is special-cased as a restricted URL for scripting to prevent | |
| 514 // access to special JS bindings we expose to the gallery (and avoid things | |
| 515 // like extensions removing the "report abuse" link). | |
| 516 // TODO(erikkay): This seems like the wrong test. Shouldn't we we testing | |
| 517 // against the store app extent? | |
| 518 GURL store_url(extension_urls::GetWebstoreLaunchURL()); | |
| 519 if ((document_url.host() == store_url.host()) && | |
| 520 !CanExecuteScriptEverywhere() && | |
| 521 !CommandLine::ForCurrentProcess()->HasSwitch( | |
| 522 switches::kAllowScriptingGallery)) { | |
| 523 if (error) | |
| 524 *error = errors::kCannotScriptGallery; | |
| 525 return false; | |
| 526 } | |
| 527 | |
| 528 if (!CommandLine::ForCurrentProcess()->HasSwitch( | |
| 529 switches::kExtensionsOnChromeURLs)) { | |
| 530 if (document_url.SchemeIs(chrome::kChromeUIScheme) && | |
| 531 !CanExecuteScriptEverywhere()) { | |
| 532 if (error) | |
| 533 *error = errors::kCannotAccessChromeUrl; | |
| 534 return false; | |
| 535 } | |
| 536 } | |
| 537 | |
| 538 if (top_frame_url.SchemeIs(extensions::kExtensionScheme) && | |
| 539 top_frame_url.GetOrigin() != | |
| 540 GetBaseURLFromExtensionId(id()).GetOrigin() && | |
| 541 !CanExecuteScriptEverywhere()) { | |
| 542 if (error) | |
| 543 *error = errors::kCannotAccessExtensionUrl; | |
| 544 return false; | |
| 545 } | |
| 546 | |
| 547 // If a tab ID is specified, try the tab-specific permissions. | |
| 548 if (tab_id >= 0) { | |
| 549 scoped_refptr<const PermissionSet> tab_permissions = | |
| 550 runtime_data_.GetTabSpecificPermissions(tab_id); | |
| 551 if (tab_permissions.get() && | |
| 552 tab_permissions->explicit_hosts().MatchesSecurityOrigin(document_url)) { | |
| 553 return true; | |
| 554 } | |
| 555 } | |
| 556 | |
| 557 bool can_access = false; | |
| 558 | |
| 559 if (script) { | |
| 560 // If a script is specified, use its matches. | |
| 561 can_access = script->MatchesURL(document_url); | |
| 562 } else { | |
| 563 // Otherwise, see if this extension has permission to execute script | |
| 564 // programmatically on pages. | |
| 565 can_access = runtime_data_.GetActivePermissions()-> | |
| 566 HasExplicitAccessToOrigin(document_url); | |
| 567 } | |
| 568 | |
| 569 if (!can_access && error) { | |
| 570 *error = ErrorUtils::FormatErrorMessage(errors::kCannotAccessPage, | |
| 571 document_url.spec()); | |
| 572 } | |
| 573 | |
| 574 return can_access; | |
| 575 } | |
| 576 | |
| 577 bool Extension::CanExecuteScriptEverywhere() const { | |
| 578 if (location() == Manifest::COMPONENT) | |
| 579 return true; | |
| 580 | |
| 581 ScriptingWhitelist* whitelist = ExtensionConfig::GetInstance()->whitelist(); | |
| 582 | |
| 583 for (ScriptingWhitelist::const_iterator it = whitelist->begin(); | |
| 584 it != whitelist->end(); ++it) { | |
| 585 if (id() == *it) { | |
| 586 return true; | |
| 587 } | |
| 588 } | |
| 589 | |
| 590 return false; | |
| 591 } | |
| 592 | |
| 593 bool Extension::CanCaptureVisiblePage(const GURL& page_url, | |
| 594 int tab_id, | |
| 595 std::string* error) const { | |
| 596 if (tab_id >= 0) { | |
| 597 scoped_refptr<const PermissionSet> tab_permissions = | |
| 598 GetTabSpecificPermissions(tab_id); | |
| 599 if (tab_permissions.get() && | |
| 600 tab_permissions->explicit_hosts().MatchesSecurityOrigin(page_url)) { | |
| 601 return true; | |
| 602 } | |
| 603 } | |
| 604 | |
| 605 if (HasHostPermission(page_url) || page_url.GetOrigin() == url()) | |
| 606 return true; | |
| 607 | |
| 608 if (error) { | |
| 609 *error = ErrorUtils::FormatErrorMessage(errors::kCannotAccessPage, | |
| 610 page_url.spec()); | |
| 611 } | |
| 612 return false; | |
| 613 } | |
| 614 | |
| 615 bool Extension::UpdatesFromGallery() const { | 433 bool Extension::UpdatesFromGallery() const { |
| 616 return extension_urls::IsWebstoreUpdateUrl(ManifestURL::GetUpdateURL(this)); | 434 return extension_urls::IsWebstoreUpdateUrl(ManifestURL::GetUpdateURL(this)); |
| 617 } | 435 } |
| 618 | 436 |
| 619 bool Extension::OverlapsWithOrigin(const GURL& origin) const { | 437 bool Extension::OverlapsWithOrigin(const GURL& origin) const { |
| 620 if (url() == origin) | 438 if (url() == origin) |
| 621 return true; | 439 return true; |
| 622 | 440 |
| 623 if (web_extent().is_empty()) | 441 if (web_extent().is_empty()) |
| 624 return false; | 442 return false; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 // show packaged apps and platform apps because there are some pieces of | 544 // show packaged apps and platform apps because there are some pieces of |
| 727 // functionality that are only available in chrome://extensions/ but which | 545 // functionality that are only available in chrome://extensions/ but which |
| 728 // are needed for packaged and platform apps. For example, inspecting | 546 // are needed for packaged and platform apps. For example, inspecting |
| 729 // background pages. See http://crbug.com/116134. | 547 // background pages. See http://crbug.com/116134. |
| 730 if (is_hosted_app()) | 548 if (is_hosted_app()) |
| 731 return false; | 549 return false; |
| 732 | 550 |
| 733 return true; | 551 return true; |
| 734 } | 552 } |
| 735 | 553 |
| 736 scoped_refptr<const PermissionSet> Extension::GetTabSpecificPermissions( | |
| 737 int tab_id) const { | |
| 738 base::AutoLock auto_lock(runtime_data_lock_); | |
| 739 return runtime_data_.GetTabSpecificPermissions(tab_id); | |
| 740 } | |
| 741 | |
| 742 void Extension::UpdateTabSpecificPermissions( | |
| 743 int tab_id, | |
| 744 scoped_refptr<const PermissionSet> permissions) const { | |
| 745 base::AutoLock auto_lock(runtime_data_lock_); | |
| 746 runtime_data_.UpdateTabSpecificPermissions(tab_id, permissions); | |
| 747 } | |
| 748 | |
| 749 void Extension::ClearTabSpecificPermissions(int tab_id) const { | |
| 750 base::AutoLock auto_lock(runtime_data_lock_); | |
| 751 runtime_data_.ClearTabSpecificPermissions(tab_id); | |
| 752 } | |
| 753 | |
| 754 Extension::ManifestData* Extension::GetManifestData(const std::string& key) | 554 Extension::ManifestData* Extension::GetManifestData(const std::string& key) |
| 755 const { | 555 const { |
| 756 DCHECK(finished_parsing_manifest_ || thread_checker_.CalledOnValidThread()); | 556 DCHECK(finished_parsing_manifest_ || thread_checker_.CalledOnValidThread()); |
| 757 ManifestDataMap::const_iterator iter = manifest_data_.find(key); | 557 ManifestDataMap::const_iterator iter = manifest_data_.find(key); |
| 758 if (iter != manifest_data_.end()) | 558 if (iter != manifest_data_.end()) |
| 759 return iter->second.get(); | 559 return iter->second.get(); |
| 760 return NULL; | 560 return NULL; |
| 761 } | 561 } |
| 762 | 562 |
| 763 void Extension::SetManifestData(const std::string& key, | 563 void Extension::SetManifestData(const std::string& key, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 814 } | 614 } |
| 815 | 615 |
| 816 void Extension::AddWebExtentPattern(const URLPattern& pattern) { | 616 void Extension::AddWebExtentPattern(const URLPattern& pattern) { |
| 817 extent_.AddPattern(pattern); | 617 extent_.AddPattern(pattern); |
| 818 } | 618 } |
| 819 | 619 |
| 820 bool Extension::is_theme() const { | 620 bool Extension::is_theme() const { |
| 821 return manifest()->is_theme(); | 621 return manifest()->is_theme(); |
| 822 } | 622 } |
| 823 | 623 |
| 824 Extension::RuntimeData::RuntimeData() {} | |
| 825 Extension::RuntimeData::RuntimeData(const PermissionSet* active) | |
| 826 : active_permissions_(active) {} | |
| 827 Extension::RuntimeData::~RuntimeData() {} | |
| 828 | |
| 829 void Extension::RuntimeData::SetActivePermissions( | |
| 830 const PermissionSet* active) { | |
| 831 active_permissions_ = active; | |
| 832 } | |
| 833 | |
| 834 scoped_refptr<const PermissionSet> | |
| 835 Extension::RuntimeData::GetActivePermissions() const { | |
| 836 return active_permissions_; | |
| 837 } | |
| 838 | |
| 839 scoped_refptr<const PermissionSet> | |
| 840 Extension::RuntimeData::GetTabSpecificPermissions(int tab_id) const { | |
| 841 CHECK_GE(tab_id, 0); | |
| 842 TabPermissionsMap::const_iterator it = tab_specific_permissions_.find(tab_id); | |
| 843 return (it != tab_specific_permissions_.end()) ? it->second : NULL; | |
| 844 } | |
| 845 | |
| 846 void Extension::RuntimeData::UpdateTabSpecificPermissions( | |
| 847 int tab_id, | |
| 848 scoped_refptr<const PermissionSet> permissions) { | |
| 849 CHECK_GE(tab_id, 0); | |
| 850 if (tab_specific_permissions_.count(tab_id)) { | |
| 851 tab_specific_permissions_[tab_id] = PermissionSet::CreateUnion( | |
| 852 tab_specific_permissions_[tab_id], | |
| 853 permissions.get()); | |
| 854 } else { | |
| 855 tab_specific_permissions_[tab_id] = permissions; | |
| 856 } | |
| 857 } | |
| 858 | |
| 859 void Extension::RuntimeData::ClearTabSpecificPermissions(int tab_id) { | |
| 860 CHECK_GE(tab_id, 0); | |
| 861 tab_specific_permissions_.erase(tab_id); | |
| 862 } | |
| 863 | |
| 864 // static | 624 // static |
| 865 bool Extension::InitExtensionID(extensions::Manifest* manifest, | 625 bool Extension::InitExtensionID(extensions::Manifest* manifest, |
| 866 const base::FilePath& path, | 626 const base::FilePath& path, |
| 867 const std::string& explicit_id, | 627 const std::string& explicit_id, |
| 868 int creation_flags, | 628 int creation_flags, |
| 869 string16* error) { | 629 string16* error) { |
| 870 if (!explicit_id.empty()) { | 630 if (!explicit_id.empty()) { |
| 871 manifest->set_extension_id(explicit_id); | 631 manifest->set_extension_id(explicit_id); |
| 872 return true; | 632 return true; |
| 873 } | 633 } |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 if (is_app() && !LoadAppFeatures(error)) | 717 if (is_app() && !LoadAppFeatures(error)) |
| 958 return false; | 718 return false; |
| 959 | 719 |
| 960 permissions_data_.reset(new PermissionsData); | 720 permissions_data_.reset(new PermissionsData); |
| 961 if (!permissions_data_->ParsePermissions(this, error)) | 721 if (!permissions_data_->ParsePermissions(this, error)) |
| 962 return false; | 722 return false; |
| 963 | 723 |
| 964 if (!LoadSharedFeatures(error)) | 724 if (!LoadSharedFeatures(error)) |
| 965 return false; | 725 return false; |
| 966 | 726 |
| 967 if (manifest_->HasKey(keys::kConvertedFromUserScript)) | 727 if (manifest_->HasKey(keys::kConvertedFromUserScript)) { |
| 968 manifest_->GetBoolean(keys::kConvertedFromUserScript, | 728 manifest_->GetBoolean(keys::kConvertedFromUserScript, |
| 969 &converted_from_user_script_); | 729 &converted_from_user_script_); |
| 730 } |
| 970 | 731 |
| 971 if (HasMultipleUISurfaces()) { | 732 if (HasMultipleUISurfaces()) { |
| 972 *error = ASCIIToUTF16(errors::kOneUISurfaceOnly); | 733 *error = ASCIIToUTF16(errors::kOneUISurfaceOnly); |
| 973 return false; | 734 return false; |
| 974 } | 735 } |
| 975 | 736 |
| 976 finished_parsing_manifest_ = true; | 737 finished_parsing_manifest_ = true; |
| 977 | 738 |
| 978 permissions_data_->FinalizePermissions(this); | 739 permissions_data_->FinalizePermissions(this); |
| 979 | 740 |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1485 | 1246 |
| 1486 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 1247 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
| 1487 const Extension* extension, | 1248 const Extension* extension, |
| 1488 const PermissionSet* permissions, | 1249 const PermissionSet* permissions, |
| 1489 Reason reason) | 1250 Reason reason) |
| 1490 : reason(reason), | 1251 : reason(reason), |
| 1491 extension(extension), | 1252 extension(extension), |
| 1492 permissions(permissions) {} | 1253 permissions(permissions) {} |
| 1493 | 1254 |
| 1494 } // namespace extensions | 1255 } // namespace extensions |
| OLD | NEW |