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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 #endif | 210 #endif |
211 | 211 |
212 // first 16 bytes of SHA256 hashed public key. | 212 // first 16 bytes of SHA256 hashed public key. |
213 const size_t Extension::kIdSize = 16; | 213 const size_t Extension::kIdSize = 16; |
214 | 214 |
215 const char Extension::kMimeType[] = "application/x-chrome-extension"; | 215 const char Extension::kMimeType[] = "application/x-chrome-extension"; |
216 | 216 |
217 const int Extension::kValidWebExtentSchemes = | 217 const int Extension::kValidWebExtentSchemes = |
218 URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS; | 218 URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS; |
219 | 219 |
220 const int Extension::kValidHostPermissionSchemes = | 220 const int Extension::kValidHostPermissionSchemes = URLPattern::SCHEME_CHROMEUI | |
221 UserScript::kValidUserScriptSchemes | URLPattern::SCHEME_CHROMEUI; | 221 URLPattern::SCHEME_HTTP | |
| 222 URLPattern::SCHEME_HTTPS | |
| 223 URLPattern::SCHEME_FILE | |
| 224 URLPattern::SCHEME_FTP; |
222 | 225 |
223 Extension::Requirements::Requirements() | 226 Extension::Requirements::Requirements() |
224 : webgl(false), | 227 : webgl(false), |
225 css3d(false), | 228 css3d(false), |
226 npapi(false) { | 229 npapi(false) { |
227 } | 230 } |
228 | 231 |
229 Extension::Requirements::~Requirements() {} | 232 Extension::Requirements::~Requirements() {} |
230 | 233 |
231 // | 234 // |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 URLPattern::SCHEME_ALL : kValidHostPermissionSchemes; | 586 URLPattern::SCHEME_ALL : kValidHostPermissionSchemes; |
584 | 587 |
585 for (std::vector<std::string>::const_iterator it = host_data.begin(); | 588 for (std::vector<std::string>::const_iterator it = host_data.begin(); |
586 it != host_data.end(); ++it) { | 589 it != host_data.end(); ++it) { |
587 const std::string& permission_str = *it; | 590 const std::string& permission_str = *it; |
588 | 591 |
589 // Check if it's a host pattern permission. | 592 // Check if it's a host pattern permission. |
590 URLPattern pattern = URLPattern(kAllowedSchemes); | 593 URLPattern pattern = URLPattern(kAllowedSchemes); |
591 URLPattern::ParseResult parse_result = pattern.Parse(permission_str); | 594 URLPattern::ParseResult parse_result = pattern.Parse(permission_str); |
592 if (parse_result == URLPattern::PARSE_SUCCESS) { | 595 if (parse_result == URLPattern::PARSE_SUCCESS) { |
| 596 // The path component is not used for host permissions, so we force it |
| 597 // to match all paths. |
| 598 pattern.SetPath("/*"); |
| 599 int valid_schemes = pattern.valid_schemes(); |
| 600 if (pattern.MatchesScheme(chrome::kFileScheme) && |
| 601 !CanExecuteScriptEverywhere()) { |
| 602 wants_file_access_ = true; |
| 603 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) |
| 604 valid_schemes &= ~URLPattern::SCHEME_FILE; |
| 605 } |
| 606 |
| 607 if (pattern.scheme() != chrome::kChromeUIScheme && |
| 608 !CanExecuteScriptEverywhere()) { |
| 609 // Keep chrome:// in allowed schemes only if it's explicitly requested |
| 610 // or CanExecuteScriptEverywhere is true. If the |
| 611 // extensions_on_chrome_urls flag is not set, CanSpecifyHostPermission |
| 612 // will fail, so don't check the flag here. |
| 613 valid_schemes &= ~URLPattern::SCHEME_CHROMEUI; |
| 614 } |
| 615 pattern.SetValidSchemes(valid_schemes); |
| 616 |
593 if (!CanSpecifyHostPermission(pattern, *api_permissions)) { | 617 if (!CanSpecifyHostPermission(pattern, *api_permissions)) { |
| 618 // TODO(aboxhall): make a warning (see line 633) |
594 *error = ErrorUtils::FormatErrorMessageUTF16( | 619 *error = ErrorUtils::FormatErrorMessageUTF16( |
595 errors::kInvalidPermissionScheme, permission_str); | 620 errors::kInvalidPermissionScheme, permission_str); |
596 return false; | 621 return false; |
597 } | 622 } |
598 | 623 |
599 // The path component is not used for host permissions, so we force it | 624 host_permissions->AddPattern(pattern); |
600 // to match all paths. | |
601 pattern.SetPath("/*"); | |
602 | 625 |
603 if (pattern.MatchesScheme(chrome::kFileScheme) && | 626 // We need to make sure all_urls matches chrome://favicon and |
604 !CanExecuteScriptEverywhere()) { | 627 // (maybe) chrome://thumbnail, so add them back in to host_permissions |
605 wants_file_access_ = true; | 628 // separately. |
606 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { | 629 if (pattern.match_all_urls()) { |
607 pattern.SetValidSchemes( | 630 host_permissions->AddPattern( |
608 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); | 631 URLPattern(URLPattern::SCHEME_CHROMEUI, |
| 632 chrome::kChromeUIFaviconURL)); |
| 633 if (api_permissions->find(APIPermission::kExperimental) != |
| 634 api_permissions->end()) { |
| 635 host_permissions->AddPattern( |
| 636 URLPattern(URLPattern::SCHEME_CHROMEUI, |
| 637 chrome::kChromeUIThumbnailURL)); |
609 } | 638 } |
610 } | 639 } |
611 | |
612 host_permissions->AddPattern(pattern); | |
613 continue; | 640 continue; |
614 } | 641 } |
615 | 642 |
616 // It's probably an unknown API permission. Do not throw an error so | 643 // It's probably an unknown API permission. Do not throw an error so |
617 // extensions can retain backwards compatability (http://crbug.com/42742). | 644 // extensions can retain backwards compatability (http://crbug.com/42742). |
618 install_warnings_.push_back(InstallWarning( | 645 install_warnings_.push_back(InstallWarning( |
619 InstallWarning::FORMAT_TEXT, | 646 InstallWarning::FORMAT_TEXT, |
620 base::StringPrintf( | 647 base::StringPrintf( |
621 "Permission '%s' is unknown or URL pattern is malformed.", | 648 "Permission '%s' is unknown or URL pattern is malformed.", |
622 permission_str.c_str()))); | 649 permission_str.c_str()))); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
657 const URLPatternSet& Extension::GetEffectiveHostPermissions() const { | 684 const URLPatternSet& Extension::GetEffectiveHostPermissions() const { |
658 base::AutoLock auto_lock(runtime_data_lock_); | 685 base::AutoLock auto_lock(runtime_data_lock_); |
659 return runtime_data_.GetActivePermissions()->effective_hosts(); | 686 return runtime_data_.GetActivePermissions()->effective_hosts(); |
660 } | 687 } |
661 | 688 |
662 bool Extension::CanSilentlyIncreasePermissions() const { | 689 bool Extension::CanSilentlyIncreasePermissions() const { |
663 return location() != Manifest::INTERNAL; | 690 return location() != Manifest::INTERNAL; |
664 } | 691 } |
665 | 692 |
666 bool Extension::HasHostPermission(const GURL& url) const { | 693 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_); | 694 base::AutoLock auto_lock(runtime_data_lock_); |
675 return runtime_data_.GetActivePermissions()-> | 695 return runtime_data_.GetActivePermissions()-> |
676 HasExplicitAccessToOrigin(url); | 696 HasExplicitAccessToOrigin(url); |
677 } | 697 } |
678 | 698 |
679 bool Extension::HasEffectiveAccessToAllHosts() const { | 699 bool Extension::HasEffectiveAccessToAllHosts() const { |
680 base::AutoLock auto_lock(runtime_data_lock_); | 700 base::AutoLock auto_lock(runtime_data_lock_); |
681 return runtime_data_.GetActivePermissions()->HasEffectiveAccessToAllHosts(); | 701 return runtime_data_.GetActivePermissions()->HasEffectiveAccessToAllHosts(); |
682 } | 702 } |
683 | 703 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
796 GURL store_url(extension_urls::GetWebstoreLaunchURL()); | 816 GURL store_url(extension_urls::GetWebstoreLaunchURL()); |
797 if ((document_url.host() == store_url.host()) && | 817 if ((document_url.host() == store_url.host()) && |
798 !CanExecuteScriptEverywhere() && | 818 !CanExecuteScriptEverywhere() && |
799 !CommandLine::ForCurrentProcess()->HasSwitch( | 819 !CommandLine::ForCurrentProcess()->HasSwitch( |
800 switches::kAllowScriptingGallery)) { | 820 switches::kAllowScriptingGallery)) { |
801 if (error) | 821 if (error) |
802 *error = errors::kCannotScriptGallery; | 822 *error = errors::kCannotScriptGallery; |
803 return false; | 823 return false; |
804 } | 824 } |
805 | 825 |
806 if (document_url.SchemeIs(chrome::kChromeUIScheme) && | 826 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
807 !CanExecuteScriptEverywhere()) { | 827 switches::kExtensionsOnChromeURLs)) { |
808 return false; | 828 if (document_url.SchemeIs(chrome::kChromeUIScheme) && |
| 829 !CanExecuteScriptEverywhere()) { |
| 830 return false; |
| 831 } |
809 } | 832 } |
810 | 833 |
811 if (top_frame_url.SchemeIs(extensions::kExtensionScheme) && | 834 if (top_frame_url.SchemeIs(extensions::kExtensionScheme) && |
812 top_frame_url.GetOrigin() != | 835 top_frame_url.GetOrigin() != |
813 GetBaseURLFromExtensionId(id()).GetOrigin() && | 836 GetBaseURLFromExtensionId(id()).GetOrigin() && |
814 !CanExecuteScriptEverywhere()) { | 837 !CanExecuteScriptEverywhere()) { |
815 return false; | 838 return false; |
816 } | 839 } |
817 | 840 |
818 // If a tab ID is specified, try the tab-specific permissions. | 841 // If a tab ID is specified, try the tab-specific permissions. |
(...skipping 1136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1955 !LoadSystemIndicator(error) || | 1978 !LoadSystemIndicator(error) || |
1956 !LoadIncognitoMode(error)) | 1979 !LoadIncognitoMode(error)) |
1957 return false; | 1980 return false; |
1958 | 1981 |
1959 return true; | 1982 return true; |
1960 } | 1983 } |
1961 | 1984 |
1962 bool Extension::LoadContentScripts(string16* error) { | 1985 bool Extension::LoadContentScripts(string16* error) { |
1963 if (!manifest_->HasKey(keys::kContentScripts)) | 1986 if (!manifest_->HasKey(keys::kContentScripts)) |
1964 return true; | 1987 return true; |
| 1988 |
1965 const ListValue* list_value; | 1989 const ListValue* list_value; |
1966 if (!manifest_->GetList(keys::kContentScripts, &list_value)) { | 1990 if (!manifest_->GetList(keys::kContentScripts, &list_value)) { |
1967 *error = ASCIIToUTF16(errors::kInvalidContentScriptsList); | 1991 *error = ASCIIToUTF16(errors::kInvalidContentScriptsList); |
1968 return false; | 1992 return false; |
1969 } | 1993 } |
1970 | 1994 |
1971 for (size_t i = 0; i < list_value->GetSize(); ++i) { | 1995 for (size_t i = 0; i < list_value->GetSize(); ++i) { |
1972 const DictionaryValue* content_script = NULL; | 1996 const DictionaryValue* content_script = NULL; |
1973 if (!list_value->GetDictionary(i, &content_script)) { | 1997 if (!list_value->GetDictionary(i, &content_script)) { |
1974 *error = ErrorUtils::FormatErrorMessageUTF16( | 1998 *error = ErrorUtils::FormatErrorMessageUTF16( |
1975 errors::kInvalidContentScript, base::IntToString(i)); | 1999 errors::kInvalidContentScript, base::IntToString(i)); |
1976 return false; | 2000 return false; |
1977 } | 2001 } |
1978 | 2002 |
1979 UserScript script; | 2003 UserScript script; |
1980 if (!LoadUserScriptHelper(content_script, i, error, &script)) | 2004 if (!LoadUserScriptHelper(content_script, i, error, &script)) |
1981 return false; // Failed to parse script context definition. | 2005 return false; // Failed to parse script context definition. |
| 2006 |
1982 script.set_extension_id(id()); | 2007 script.set_extension_id(id()); |
1983 if (converted_from_user_script_) { | 2008 if (converted_from_user_script_) { |
1984 script.set_emulate_greasemonkey(true); | 2009 script.set_emulate_greasemonkey(true); |
1985 script.set_match_all_frames(true); // Greasemonkey matches all frames. | 2010 script.set_match_all_frames(true); // Greasemonkey matches all frames. |
1986 } | 2011 } |
1987 content_scripts_.push_back(script); | 2012 content_scripts_.push_back(script); |
1988 } | 2013 } |
1989 return true; | 2014 return true; |
1990 } | 2015 } |
1991 | 2016 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2097 std::string match_str; | 2122 std::string match_str; |
2098 if (!matches->GetString(j, &match_str)) { | 2123 if (!matches->GetString(j, &match_str)) { |
2099 *error = ErrorUtils::FormatErrorMessageUTF16( | 2124 *error = ErrorUtils::FormatErrorMessageUTF16( |
2100 errors::kInvalidMatch, | 2125 errors::kInvalidMatch, |
2101 base::IntToString(definition_index), | 2126 base::IntToString(definition_index), |
2102 base::IntToString(j), | 2127 base::IntToString(j), |
2103 errors::kExpectString); | 2128 errors::kExpectString); |
2104 return false; | 2129 return false; |
2105 } | 2130 } |
2106 | 2131 |
2107 URLPattern pattern(UserScript::kValidUserScriptSchemes); | 2132 URLPattern pattern( |
2108 if (CanExecuteScriptEverywhere()) | 2133 UserScript::ValidUserScriptSchemes(CanExecuteScriptEverywhere())); |
2109 pattern.SetValidSchemes(URLPattern::SCHEME_ALL); | |
2110 | 2134 |
2111 URLPattern::ParseResult parse_result = pattern.Parse(match_str); | 2135 URLPattern::ParseResult parse_result = pattern.Parse(match_str); |
2112 if (parse_result != URLPattern::PARSE_SUCCESS) { | 2136 if (parse_result != URLPattern::PARSE_SUCCESS) { |
2113 *error = ErrorUtils::FormatErrorMessageUTF16( | 2137 *error = ErrorUtils::FormatErrorMessageUTF16( |
2114 errors::kInvalidMatch, | 2138 errors::kInvalidMatch, |
2115 base::IntToString(definition_index), | 2139 base::IntToString(definition_index), |
2116 base::IntToString(j), | 2140 base::IntToString(j), |
2117 URLPattern::GetParseResultString(parse_result)); | 2141 URLPattern::GetParseResultString(parse_result)); |
2118 return false; | 2142 return false; |
2119 } | 2143 } |
2120 | 2144 |
| 2145 // TODO(aboxhall): check for webstore |
| 2146 if (!CanExecuteScriptEverywhere() && |
| 2147 pattern.scheme() != chrome::kChromeUIScheme) { |
| 2148 // Exclude SCHEME_CHROMEUI unless it's been explicitly requested. |
| 2149 // If the --extensions-on-chrome-urls flag has not been passed, requesting |
| 2150 // a chrome:// url will cause a parse failure above, so there's no need to |
| 2151 // check the flag here. |
| 2152 pattern.SetValidSchemes( |
| 2153 pattern.valid_schemes() & ~URLPattern::SCHEME_CHROMEUI); |
| 2154 } |
| 2155 |
2121 if (pattern.MatchesScheme(chrome::kFileScheme) && | 2156 if (pattern.MatchesScheme(chrome::kFileScheme) && |
2122 !CanExecuteScriptEverywhere()) { | 2157 !CanExecuteScriptEverywhere()) { |
2123 wants_file_access_ = true; | 2158 wants_file_access_ = true; |
2124 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { | 2159 if (!(creation_flags_ & ALLOW_FILE_ACCESS)) { |
2125 pattern.SetValidSchemes( | 2160 pattern.SetValidSchemes( |
2126 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); | 2161 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); |
2127 } | 2162 } |
2128 } | 2163 } |
2129 | 2164 |
2130 result->add_url_pattern(pattern); | 2165 result->add_url_pattern(pattern); |
(...skipping 13 matching lines...) Expand all Loading... |
2144 std::string match_str; | 2179 std::string match_str; |
2145 if (!exclude_matches->GetString(j, &match_str)) { | 2180 if (!exclude_matches->GetString(j, &match_str)) { |
2146 *error = ErrorUtils::FormatErrorMessageUTF16( | 2181 *error = ErrorUtils::FormatErrorMessageUTF16( |
2147 errors::kInvalidExcludeMatch, | 2182 errors::kInvalidExcludeMatch, |
2148 base::IntToString(definition_index), | 2183 base::IntToString(definition_index), |
2149 base::IntToString(j), | 2184 base::IntToString(j), |
2150 errors::kExpectString); | 2185 errors::kExpectString); |
2151 return false; | 2186 return false; |
2152 } | 2187 } |
2153 | 2188 |
2154 URLPattern pattern(UserScript::kValidUserScriptSchemes); | 2189 int valid_schemes = |
2155 if (CanExecuteScriptEverywhere()) | 2190 UserScript::ValidUserScriptSchemes(CanExecuteScriptEverywhere()); |
2156 pattern.SetValidSchemes(URLPattern::SCHEME_ALL); | 2191 URLPattern pattern(valid_schemes); |
2157 URLPattern::ParseResult parse_result = pattern.Parse(match_str); | 2192 URLPattern::ParseResult parse_result = pattern.Parse(match_str); |
2158 if (parse_result != URLPattern::PARSE_SUCCESS) { | 2193 if (parse_result != URLPattern::PARSE_SUCCESS) { |
2159 *error = ErrorUtils::FormatErrorMessageUTF16( | 2194 *error = ErrorUtils::FormatErrorMessageUTF16( |
2160 errors::kInvalidExcludeMatch, | 2195 errors::kInvalidExcludeMatch, |
2161 base::IntToString(definition_index), base::IntToString(j), | 2196 base::IntToString(definition_index), base::IntToString(j), |
2162 URLPattern::GetParseResultString(parse_result)); | 2197 URLPattern::GetParseResultString(parse_result)); |
2163 return false; | 2198 return false; |
2164 } | 2199 } |
2165 | 2200 |
2166 result->add_exclude_url_pattern(pattern); | 2201 result->add_exclude_url_pattern(pattern); |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2350 // Experimental extensions are also allowed chrome://thumb. | 2385 // Experimental extensions are also allowed chrome://thumb. |
2351 if (pattern.host() == chrome::kChromeUIThumbnailHost) { | 2386 if (pattern.host() == chrome::kChromeUIThumbnailHost) { |
2352 return permissions.find(APIPermission::kExperimental) != | 2387 return permissions.find(APIPermission::kExperimental) != |
2353 permissions.end(); | 2388 permissions.end(); |
2354 } | 2389 } |
2355 | 2390 |
2356 // Component extensions can have access to all of chrome://*. | 2391 // Component extensions can have access to all of chrome://*. |
2357 if (CanExecuteScriptEverywhere()) | 2392 if (CanExecuteScriptEverywhere()) |
2358 return true; | 2393 return true; |
2359 | 2394 |
| 2395 if (CommandLine::ForCurrentProcess()->HasSwitch( |
| 2396 switches::kExtensionsOnChromeURLs)) |
| 2397 return true; |
| 2398 |
| 2399 // TODO(aboxhall): return from_webstore() when webstore handles blocking |
| 2400 // extensions which request chrome:// urls |
2360 return false; | 2401 return false; |
2361 } | 2402 } |
2362 | 2403 |
2363 // Otherwise, the valid schemes were handled by URLPattern. | 2404 // Otherwise, the valid schemes were handled by URLPattern. |
2364 return true; | 2405 return true; |
2365 } | 2406 } |
2366 | 2407 |
2367 bool Extension::CheckMinimumChromeVersion(string16* error) const { | 2408 bool Extension::CheckMinimumChromeVersion(string16* error) const { |
2368 if (!manifest_->HasKey(keys::kMinimumChromeVersion)) | 2409 if (!manifest_->HasKey(keys::kMinimumChromeVersion)) |
2369 return true; | 2410 return true; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2451 | 2492 |
2452 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 2493 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
2453 const Extension* extension, | 2494 const Extension* extension, |
2454 const PermissionSet* permissions, | 2495 const PermissionSet* permissions, |
2455 Reason reason) | 2496 Reason reason) |
2456 : reason(reason), | 2497 : reason(reason), |
2457 extension(extension), | 2498 extension(extension), |
2458 permissions(permissions) {} | 2499 permissions(permissions) {} |
2459 | 2500 |
2460 } // namespace extensions | 2501 } // namespace extensions |
OLD | NEW |