Chromium Code Reviews| 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 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 583 URLPattern::SCHEME_ALL : kValidHostPermissionSchemes; | 583 URLPattern::SCHEME_ALL : kValidHostPermissionSchemes; |
| 584 | 584 |
| 585 for (std::vector<std::string>::const_iterator it = host_data.begin(); | 585 for (std::vector<std::string>::const_iterator it = host_data.begin(); |
| 586 it != host_data.end(); ++it) { | 586 it != host_data.end(); ++it) { |
| 587 const std::string& permission_str = *it; | 587 const std::string& permission_str = *it; |
| 588 | 588 |
| 589 // Check if it's a host pattern permission. | 589 // Check if it's a host pattern permission. |
| 590 URLPattern pattern = URLPattern(kAllowedSchemes); | 590 URLPattern pattern = URLPattern(kAllowedSchemes); |
| 591 URLPattern::ParseResult parse_result = pattern.Parse(permission_str); | 591 URLPattern::ParseResult parse_result = pattern.Parse(permission_str); |
| 592 if (parse_result == URLPattern::PARSE_SUCCESS) { | 592 if (parse_result == URLPattern::PARSE_SUCCESS) { |
| 593 // The path component is not used for host permissions, so we force it | |
| 594 // to match all paths. | |
| 595 pattern.SetPath("/*"); | |
| 596 int valid_schemes = pattern.valid_schemes(); | |
| 597 if (pattern.MatchesScheme(chrome::kFileScheme) && | |
| 598 !CanExecuteScriptEverywhere()) { | |
| 599 wants_file_access_ = true; | |
| 600 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) | |
| 601 valid_schemes &= ~URLPattern::SCHEME_FILE; | |
| 602 } | |
| 603 | |
| 604 if (pattern.scheme() != chrome::kChromeUIScheme && | |
| 605 !CanExecuteScriptEverywhere()) { | |
| 606 // Keep chrome:// in allowed schemes only if it's explicitly requested | |
| 607 // or CanExecuteScriptEverywhere is true. If the | |
| 608 // extensions_on_chrome_urls flag is not set, CanSpecifyHostPermission | |
| 609 // will fail, so don't check the flag here. | |
| 610 valid_schemes &= ~URLPattern::SCHEME_CHROMEUI; | |
| 611 } | |
| 612 pattern.SetValidSchemes(valid_schemes); | |
| 613 | |
| 593 if (!CanSpecifyHostPermission(pattern, *api_permissions)) { | 614 if (!CanSpecifyHostPermission(pattern, *api_permissions)) { |
| 615 // TODO(aboxhall): make a warning (see line 633) | |
| 594 *error = ErrorUtils::FormatErrorMessageUTF16( | 616 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 595 errors::kInvalidPermissionScheme, permission_str); | 617 errors::kInvalidPermissionScheme, permission_str); |
| 596 return false; | 618 return false; |
| 597 } | 619 } |
| 598 | 620 |
| 599 // The path component is not used for host permissions, so we force it | 621 host_permissions->AddPattern(pattern); |
| 600 // to match all paths. | |
| 601 pattern.SetPath("/*"); | |
| 602 | 622 |
| 603 if (pattern.MatchesScheme(chrome::kFileScheme) && | 623 // We need to make sure all_urls matches chrome://favicon and |
| 604 !CanExecuteScriptEverywhere()) { | 624 // (maybe) chrome://thumbnail, so add them back in to host_permissions |
| 605 wants_file_access_ = true; | 625 // separately. |
| 606 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { | 626 if (pattern.match_all_urls()) { |
| 607 pattern.SetValidSchemes( | 627 host_permissions->AddPattern( |
| 608 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); | 628 URLPattern(URLPattern::SCHEME_CHROMEUI, |
| 629 chrome::kChromeUIFaviconURL)); | |
| 630 if (api_permissions->find(APIPermission::kExperimental) != | |
| 631 api_permissions->end()) { | |
| 632 host_permissions->AddPattern( | |
| 633 URLPattern(URLPattern::SCHEME_CHROMEUI, | |
| 634 chrome::kChromeUIThumbnailURL)); | |
| 609 } | 635 } |
| 610 } | 636 } |
| 611 | |
| 612 host_permissions->AddPattern(pattern); | |
| 613 continue; | 637 continue; |
| 614 } | 638 } |
| 615 | 639 |
| 616 // It's probably an unknown API permission. Do not throw an error so | 640 // It's probably an unknown API permission. Do not throw an error so |
| 617 // extensions can retain backwards compatability (http://crbug.com/42742). | 641 // extensions can retain backwards compatability (http://crbug.com/42742). |
| 618 install_warnings_.push_back(InstallWarning( | 642 install_warnings_.push_back(InstallWarning( |
| 619 InstallWarning::FORMAT_TEXT, | 643 InstallWarning::FORMAT_TEXT, |
| 620 base::StringPrintf( | 644 base::StringPrintf( |
| 621 "Permission '%s' is unknown or URL pattern is malformed.", | 645 "Permission '%s' is unknown or URL pattern is malformed.", |
| 622 permission_str.c_str()))); | 646 permission_str.c_str()))); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 657 const URLPatternSet& Extension::GetEffectiveHostPermissions() const { | 681 const URLPatternSet& Extension::GetEffectiveHostPermissions() const { |
| 658 base::AutoLock auto_lock(runtime_data_lock_); | 682 base::AutoLock auto_lock(runtime_data_lock_); |
| 659 return runtime_data_.GetActivePermissions()->effective_hosts(); | 683 return runtime_data_.GetActivePermissions()->effective_hosts(); |
| 660 } | 684 } |
| 661 | 685 |
| 662 bool Extension::CanSilentlyIncreasePermissions() const { | 686 bool Extension::CanSilentlyIncreasePermissions() const { |
| 663 return location() != Manifest::INTERNAL; | 687 return location() != Manifest::INTERNAL; |
| 664 } | 688 } |
| 665 | 689 |
| 666 bool Extension::HasHostPermission(const GURL& url) const { | 690 bool Extension::HasHostPermission(const GURL& url) const { |
| 667 if (url.SchemeIs(chrome::kChromeUIScheme) && | |
| 668 url.host() != chrome::kChromeUIFaviconHost && | |
| 669 url.host() != chrome::kChromeUIThumbnailHost && | |
| 670 location() != Manifest::COMPONENT) { | |
| 671 return false; | |
| 672 } | |
| 673 | |
| 674 base::AutoLock auto_lock(runtime_data_lock_); | 691 base::AutoLock auto_lock(runtime_data_lock_); |
| 675 return runtime_data_.GetActivePermissions()-> | 692 return runtime_data_.GetActivePermissions()-> |
| 676 HasExplicitAccessToOrigin(url); | 693 HasExplicitAccessToOrigin(url); |
| 677 } | 694 } |
| 678 | 695 |
| 679 bool Extension::HasEffectiveAccessToAllHosts() const { | 696 bool Extension::HasEffectiveAccessToAllHosts() const { |
| 680 base::AutoLock auto_lock(runtime_data_lock_); | 697 base::AutoLock auto_lock(runtime_data_lock_); |
| 681 return runtime_data_.GetActivePermissions()->HasEffectiveAccessToAllHosts(); | 698 return runtime_data_.GetActivePermissions()->HasEffectiveAccessToAllHosts(); |
| 682 } | 699 } |
| 683 | 700 |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 796 GURL store_url(extension_urls::GetWebstoreLaunchURL()); | 813 GURL store_url(extension_urls::GetWebstoreLaunchURL()); |
| 797 if ((document_url.host() == store_url.host()) && | 814 if ((document_url.host() == store_url.host()) && |
| 798 !CanExecuteScriptEverywhere() && | 815 !CanExecuteScriptEverywhere() && |
| 799 !CommandLine::ForCurrentProcess()->HasSwitch( | 816 !CommandLine::ForCurrentProcess()->HasSwitch( |
| 800 switches::kAllowScriptingGallery)) { | 817 switches::kAllowScriptingGallery)) { |
| 801 if (error) | 818 if (error) |
| 802 *error = errors::kCannotScriptGallery; | 819 *error = errors::kCannotScriptGallery; |
| 803 return false; | 820 return false; |
| 804 } | 821 } |
| 805 | 822 |
| 806 if (document_url.SchemeIs(chrome::kChromeUIScheme) && | 823 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
| 807 !CanExecuteScriptEverywhere()) { | 824 switches::kExtensionsOnChromeURLs)) { |
| 808 return false; | 825 if (document_url.SchemeIs(chrome::kChromeUIScheme) && |
| 826 !CanExecuteScriptEverywhere()) { | |
| 827 return false; | |
|
dmazzoni
2013/03/19 20:48:44
Doesn't this allow any extension to run on chrome:
aboxhall
2013/03/20 22:04:59
It's caught later, specifically on either line 850
| |
| 828 } | |
| 809 } | 829 } |
| 810 | 830 |
| 811 if (top_frame_url.SchemeIs(extensions::kExtensionScheme) && | 831 if (top_frame_url.SchemeIs(extensions::kExtensionScheme) && |
| 812 top_frame_url.GetOrigin() != | 832 top_frame_url.GetOrigin() != |
| 813 GetBaseURLFromExtensionId(id()).GetOrigin() && | 833 GetBaseURLFromExtensionId(id()).GetOrigin() && |
| 814 !CanExecuteScriptEverywhere()) { | 834 !CanExecuteScriptEverywhere()) { |
| 815 return false; | 835 return false; |
| 816 } | 836 } |
| 817 | 837 |
| 818 // If a tab ID is specified, try the tab-specific permissions. | 838 // If a tab ID is specified, try the tab-specific permissions. |
| (...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2148 std::string match_str; | 2168 std::string match_str; |
| 2149 if (!matches->GetString(j, &match_str)) { | 2169 if (!matches->GetString(j, &match_str)) { |
| 2150 *error = ErrorUtils::FormatErrorMessageUTF16( | 2170 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 2151 errors::kInvalidMatch, | 2171 errors::kInvalidMatch, |
| 2152 base::IntToString(definition_index), | 2172 base::IntToString(definition_index), |
| 2153 base::IntToString(j), | 2173 base::IntToString(j), |
| 2154 errors::kExpectString); | 2174 errors::kExpectString); |
| 2155 return false; | 2175 return false; |
| 2156 } | 2176 } |
| 2157 | 2177 |
| 2158 URLPattern pattern(UserScript::kValidUserScriptSchemes); | 2178 URLPattern pattern( |
| 2159 if (CanExecuteScriptEverywhere()) | 2179 UserScript::ValidUserScriptSchemes(CanExecuteScriptEverywhere())); |
| 2160 pattern.SetValidSchemes(URLPattern::SCHEME_ALL); | |
| 2161 | 2180 |
| 2162 URLPattern::ParseResult parse_result = pattern.Parse(match_str); | 2181 URLPattern::ParseResult parse_result = pattern.Parse(match_str); |
| 2163 if (parse_result != URLPattern::PARSE_SUCCESS) { | 2182 if (parse_result != URLPattern::PARSE_SUCCESS) { |
| 2164 *error = ErrorUtils::FormatErrorMessageUTF16( | 2183 *error = ErrorUtils::FormatErrorMessageUTF16( |
| 2165 errors::kInvalidMatch, | 2184 errors::kInvalidMatch, |
| 2166 base::IntToString(definition_index), | 2185 base::IntToString(definition_index), |
| 2167 base::IntToString(j), | 2186 base::IntToString(j), |
| 2168 URLPattern::GetParseResultString(parse_result)); | 2187 URLPattern::GetParseResultString(parse_result)); |
| 2169 return false; | 2188 return false; |
| 2170 } | 2189 } |
| 2171 | 2190 |
| 2191 // TODO(aboxhall): check for webstore | |
| 2192 if (!CanExecuteScriptEverywhere() && | |
| 2193 pattern.scheme() != chrome::kChromeUIScheme) { | |
| 2194 pattern.SetValidSchemes( | |
|
Matt Perry
2013/03/19 17:49:32
Add a comment on what's happening here.
aboxhall
2013/03/20 22:04:59
Done.
aboxhall
2013/03/20 22:04:59
Done.
| |
| 2195 pattern.valid_schemes() & ~URLPattern::SCHEME_CHROMEUI); | |
| 2196 } | |
| 2197 | |
| 2172 if (pattern.MatchesScheme(chrome::kFileScheme) && | 2198 if (pattern.MatchesScheme(chrome::kFileScheme) && |
| 2173 !CanExecuteScriptEverywhere()) { | 2199 !CanExecuteScriptEverywhere()) { |
| 2174 wants_file_access_ = true; | 2200 wants_file_access_ = true; |
| 2175 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { | 2201 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { |
| 2176 pattern.SetValidSchemes( | 2202 pattern.SetValidSchemes( |
| 2177 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); | 2203 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); |
| 2178 } | 2204 } |
| 2179 } | 2205 } |
| 2180 | 2206 |
| 2181 result->add_url_pattern(pattern); | 2207 result->add_url_pattern(pattern); |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2401 // Experimental extensions are also allowed chrome://thumb. | 2427 // Experimental extensions are also allowed chrome://thumb. |
| 2402 if (pattern.host() == chrome::kChromeUIThumbnailHost) { | 2428 if (pattern.host() == chrome::kChromeUIThumbnailHost) { |
| 2403 return permissions.find(APIPermission::kExperimental) != | 2429 return permissions.find(APIPermission::kExperimental) != |
| 2404 permissions.end(); | 2430 permissions.end(); |
| 2405 } | 2431 } |
| 2406 | 2432 |
| 2407 // Component extensions can have access to all of chrome://*. | 2433 // Component extensions can have access to all of chrome://*. |
| 2408 if (CanExecuteScriptEverywhere()) | 2434 if (CanExecuteScriptEverywhere()) |
| 2409 return true; | 2435 return true; |
| 2410 | 2436 |
| 2437 if (CommandLine::ForCurrentProcess()->HasSwitch( | |
| 2438 switches::kExtensionsOnChromeURLs)) | |
| 2439 return true; | |
| 2440 | |
| 2441 // TODO(aboxhall): return from_webstore() when webstore handles blocking | |
| 2442 // extensions which request chrome:// urls | |
| 2411 return false; | 2443 return false; |
| 2412 } | 2444 } |
| 2413 | 2445 |
| 2414 // Otherwise, the valid schemes were handled by URLPattern. | 2446 // Otherwise, the valid schemes were handled by URLPattern. |
| 2415 return true; | 2447 return true; |
| 2416 } | 2448 } |
| 2417 | 2449 |
| 2418 bool Extension::CheckMinimumChromeVersion(string16* error) const { | 2450 bool Extension::CheckMinimumChromeVersion(string16* error) const { |
| 2419 if (!manifest_->HasKey(keys::kMinimumChromeVersion)) | 2451 if (!manifest_->HasKey(keys::kMinimumChromeVersion)) |
| 2420 return true; | 2452 return true; |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2502 | 2534 |
| 2503 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 2535 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
| 2504 const Extension* extension, | 2536 const Extension* extension, |
| 2505 const PermissionSet* permissions, | 2537 const PermissionSet* permissions, |
| 2506 Reason reason) | 2538 Reason reason) |
| 2507 : reason(reason), | 2539 : reason(reason), |
| 2508 extension(extension), | 2540 extension(extension), |
| 2509 permissions(permissions) {} | 2541 permissions(permissions) {} |
| 2510 | 2542 |
| 2511 } // namespace extensions | 2543 } // namespace extensions |
| OLD | NEW |