| 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/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_path.h" | 10 #include "base/file_path.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 #include "base/win/metro.h" | 54 #include "base/win/metro.h" |
| 55 #endif | 55 #endif |
| 56 | 56 |
| 57 namespace keys = extension_manifest_keys; | 57 namespace keys = extension_manifest_keys; |
| 58 namespace values = extension_manifest_values; | 58 namespace values = extension_manifest_values; |
| 59 namespace errors = extension_manifest_errors; | 59 namespace errors = extension_manifest_errors; |
| 60 namespace info_keys = extension_info_keys; | 60 namespace info_keys = extension_info_keys; |
| 61 namespace switch_utils = extensions::switch_utils; | 61 namespace switch_utils = extensions::switch_utils; |
| 62 | 62 |
| 63 using extensions::csp_validator::ContentSecurityPolicyIsLegal; | 63 using extensions::csp_validator::ContentSecurityPolicyIsLegal; |
| 64 using extensions::csp_validator::ContentSecurityPolicyIsSandboxed; |
| 64 using extensions::csp_validator::ContentSecurityPolicyIsSecure; | 65 using extensions::csp_validator::ContentSecurityPolicyIsSecure; |
| 65 | 66 |
| 66 namespace extensions { | 67 namespace extensions { |
| 67 | 68 |
| 68 namespace { | 69 namespace { |
| 69 | 70 |
| 70 const int kModernManifestVersion = 1; | 71 const int kModernManifestVersion = 1; |
| 71 const int kPEMOutputColumns = 65; | 72 const int kPEMOutputColumns = 65; |
| 72 | 73 |
| 73 const char kOverrideExtentUrlPatternFormat[] = "chrome://%s/*"; | 74 const char kOverrideExtentUrlPatternFormat[] = "chrome://%s/*"; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 95 "default-src 'self' chrome-extension-resource:;" | 96 "default-src 'self' chrome-extension-resource:;" |
| 96 // For remote resources, they can fetch them via XMLHttpRequest. | 97 // For remote resources, they can fetch them via XMLHttpRequest. |
| 97 "connect-src *;" | 98 "connect-src *;" |
| 98 // And serve them via blob:, data: or filesystem: URLs | 99 // And serve them via blob:, data: or filesystem: URLs |
| 99 "style-src " PLATFORM_APP_LOCAL_CSP_SOURCES " 'unsafe-inline';" | 100 "style-src " PLATFORM_APP_LOCAL_CSP_SOURCES " 'unsafe-inline';" |
| 100 "img-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";" | 101 "img-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";" |
| 101 "media-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";" | 102 "media-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";" |
| 102 "frame-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";" | 103 "frame-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";" |
| 103 "font-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";"; | 104 "font-src " PLATFORM_APP_LOCAL_CSP_SOURCES ";"; |
| 104 | 105 |
| 106 const char kDefaultSandboxedPageContentSecurityPolicy[] = |
| 107 "sandbox allow-scripts allow-forms"; |
| 108 |
| 105 // Converts a normal hexadecimal string into the alphabet used by extensions. | 109 // Converts a normal hexadecimal string into the alphabet used by extensions. |
| 106 // We use the characters 'a'-'p' instead of '0'-'f' to avoid ever having a | 110 // We use the characters 'a'-'p' instead of '0'-'f' to avoid ever having a |
| 107 // completely numeric host, since some software interprets that as an IP | 111 // completely numeric host, since some software interprets that as an IP |
| 108 // address. | 112 // address. |
| 109 static void ConvertHexadecimalToIDAlphabet(std::string* id) { | 113 static void ConvertHexadecimalToIDAlphabet(std::string* id) { |
| 110 for (size_t i = 0; i < id->size(); ++i) { | 114 for (size_t i = 0; i < id->size(); ++i) { |
| 111 int val; | 115 int val; |
| 112 if (base::HexStringToInt(base::StringPiece(id->begin() + i, | 116 if (base::HexStringToInt(base::StringPiece(id->begin() + i, |
| 113 id->begin() + i + 1), | 117 id->begin() + i + 1), |
| 114 &val)) { | 118 &val)) { |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 return false; | 523 return false; |
| 520 } | 524 } |
| 521 | 525 |
| 522 bool Extension::HasWebAccessibleResources() const { | 526 bool Extension::HasWebAccessibleResources() const { |
| 523 if (web_accessible_resources_.size()) | 527 if (web_accessible_resources_.size()) |
| 524 return true; | 528 return true; |
| 525 | 529 |
| 526 return false; | 530 return false; |
| 527 } | 531 } |
| 528 | 532 |
| 533 bool Extension::IsSandboxedPage(const std::string& relative_path) const { |
| 534 return sandboxed_pages_.find(relative_path) != sandboxed_pages_.end(); |
| 535 } |
| 536 |
| 537 |
| 538 std::string Extension::GetResourceContentSecurityPolicy( |
| 539 const std::string& relative_path) const { |
| 540 return IsSandboxedPage(relative_path) ? |
| 541 sandboxed_pages_content_security_policy_ : content_security_policy_; |
| 542 } |
| 543 |
| 529 bool Extension::GenerateId(const std::string& input, std::string* output) { | 544 bool Extension::GenerateId(const std::string& input, std::string* output) { |
| 530 DCHECK(output); | 545 DCHECK(output); |
| 531 uint8 hash[Extension::kIdSize]; | 546 uint8 hash[Extension::kIdSize]; |
| 532 crypto::SHA256HashString(input, hash, sizeof(hash)); | 547 crypto::SHA256HashString(input, hash, sizeof(hash)); |
| 533 *output = StringToLowerASCII(base::HexEncode(hash, sizeof(hash))); | 548 *output = StringToLowerASCII(base::HexEncode(hash, sizeof(hash))); |
| 534 ConvertHexadecimalToIDAlphabet(output); | 549 ConvertHexadecimalToIDAlphabet(output); |
| 535 | 550 |
| 536 return true; | 551 return true; |
| 537 } | 552 } |
| 538 | 553 |
| (...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1273 const ExtensionAPIPermissionSet& api_permissions, | 1288 const ExtensionAPIPermissionSet& api_permissions, |
| 1274 string16* error) { | 1289 string16* error) { |
| 1275 if (!LoadDescription(error) || | 1290 if (!LoadDescription(error) || |
| 1276 !LoadHomepageURL(error) || | 1291 !LoadHomepageURL(error) || |
| 1277 !LoadUpdateURL(error) || | 1292 !LoadUpdateURL(error) || |
| 1278 !LoadIcons(error) || | 1293 !LoadIcons(error) || |
| 1279 !LoadCommands(error) || | 1294 !LoadCommands(error) || |
| 1280 !LoadPlugins(error) || | 1295 !LoadPlugins(error) || |
| 1281 !LoadNaClModules(error) || | 1296 !LoadNaClModules(error) || |
| 1282 !LoadWebAccessibleResources(error) || | 1297 !LoadWebAccessibleResources(error) || |
| 1298 !LoadSandboxedPages(error) || |
| 1283 !CheckRequirements(error) || | 1299 !CheckRequirements(error) || |
| 1284 !LoadDefaultLocale(error) || | 1300 !LoadDefaultLocale(error) || |
| 1285 !LoadOfflineEnabled(error) || | 1301 !LoadOfflineEnabled(error) || |
| 1286 !LoadOptionsPage(error) || | 1302 !LoadOptionsPage(error) || |
| 1287 // LoadBackgroundScripts() must be called before LoadBackgroundPage(). | 1303 // LoadBackgroundScripts() must be called before LoadBackgroundPage(). |
| 1288 !LoadBackgroundScripts(error) || | 1304 !LoadBackgroundScripts(error) || |
| 1289 !LoadBackgroundPage(api_permissions, error) || | 1305 !LoadBackgroundPage(api_permissions, error) || |
| 1290 !LoadBackgroundPersistent(api_permissions, error) || | 1306 !LoadBackgroundPersistent(api_permissions, error) || |
| 1291 !LoadBackgroundAllowJSAccess(api_permissions, error) || | 1307 !LoadBackgroundAllowJSAccess(api_permissions, error) || |
| 1292 !LoadWebIntentServices(error)) | 1308 !LoadWebIntentServices(error)) |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1544 nacl_modules_.back().url = GetResourceURL(path_str); | 1560 nacl_modules_.back().url = GetResourceURL(path_str); |
| 1545 nacl_modules_.back().mime_type = mime_type; | 1561 nacl_modules_.back().mime_type = mime_type; |
| 1546 } | 1562 } |
| 1547 | 1563 |
| 1548 return true; | 1564 return true; |
| 1549 } | 1565 } |
| 1550 | 1566 |
| 1551 bool Extension::LoadWebAccessibleResources(string16* error) { | 1567 bool Extension::LoadWebAccessibleResources(string16* error) { |
| 1552 if (!manifest_->HasKey(keys::kWebAccessibleResources)) | 1568 if (!manifest_->HasKey(keys::kWebAccessibleResources)) |
| 1553 return true; | 1569 return true; |
| 1554 ListValue* list_value; | 1570 ListValue* list_value = NULL; |
| 1555 if (!manifest_->GetList(keys::kWebAccessibleResources, &list_value)) { | 1571 if (!manifest_->GetList(keys::kWebAccessibleResources, &list_value)) { |
| 1556 *error = ASCIIToUTF16(errors::kInvalidWebAccessibleResourcesList); | 1572 *error = ASCIIToUTF16(errors::kInvalidWebAccessibleResourcesList); |
| 1557 return false; | 1573 return false; |
| 1558 } | 1574 } |
| 1559 for (size_t i = 0; i < list_value->GetSize(); ++i) { | 1575 for (size_t i = 0; i < list_value->GetSize(); ++i) { |
| 1560 std::string relative_path; | 1576 std::string relative_path; |
| 1561 if (!list_value->GetString(i, &relative_path)) { | 1577 if (!list_value->GetString(i, &relative_path)) { |
| 1562 *error = ExtensionErrorUtils::FormatErrorMessageUTF16( | 1578 *error = ExtensionErrorUtils::FormatErrorMessageUTF16( |
| 1563 errors::kInvalidWebAccessibleResource, base::IntToString(i)); | 1579 errors::kInvalidWebAccessibleResource, base::IntToString(i)); |
| 1564 return false; | 1580 return false; |
| 1565 } | 1581 } |
| 1566 if (relative_path[0] != '/') | 1582 if (relative_path[0] != '/') |
| 1567 relative_path = '/' + relative_path; | 1583 relative_path = '/' + relative_path; |
| 1568 web_accessible_resources_.insert(relative_path); | 1584 web_accessible_resources_.insert(relative_path); |
| 1569 } | 1585 } |
| 1570 | 1586 |
| 1571 return true; | 1587 return true; |
| 1572 } | 1588 } |
| 1573 | 1589 |
| 1590 bool Extension::LoadSandboxedPages(string16* error) { |
| 1591 // Can't use HasKey, since it doesn't do path expansion. |
| 1592 Value* ignored = NULL; |
| 1593 if (!manifest_->Get(keys::kSandboxedPages, &ignored)) |
| 1594 return true; |
| 1595 |
| 1596 ListValue* list_value = NULL; |
| 1597 if (!manifest_->GetList(keys::kSandboxedPages, &list_value)) { |
| 1598 *error = ASCIIToUTF16(errors::kInvalidSandboxedPagesList); |
| 1599 return false; |
| 1600 } |
| 1601 for (size_t i = 0; i < list_value->GetSize(); ++i) { |
| 1602 std::string relative_path; |
| 1603 if (!list_value->GetString(i, &relative_path)) { |
| 1604 *error = ExtensionErrorUtils::FormatErrorMessageUTF16( |
| 1605 errors::kInvalidSandboxedPage, base::IntToString(i)); |
| 1606 return false; |
| 1607 } |
| 1608 if (relative_path[0] != '/') |
| 1609 relative_path = '/' + relative_path; |
| 1610 sandboxed_pages_.insert(relative_path); |
| 1611 } |
| 1612 |
| 1613 if (manifest_->Get(keys::kSandboxedPagesCSP, &ignored)) { |
| 1614 if (!manifest_->GetString( |
| 1615 keys::kSandboxedPagesCSP, &sandboxed_pages_content_security_policy_)) { |
| 1616 *error = ASCIIToUTF16(errors::kInvalidSandboxedPagesCSP); |
| 1617 return false; |
| 1618 } |
| 1619 |
| 1620 if (!ContentSecurityPolicyIsLegal( |
| 1621 sandboxed_pages_content_security_policy_) || |
| 1622 !ContentSecurityPolicyIsSandboxed( |
| 1623 sandboxed_pages_content_security_policy_, GetType())) { |
| 1624 *error = ASCIIToUTF16(errors::kInvalidSandboxedPagesCSP); |
| 1625 return false; |
| 1626 } |
| 1627 } else { |
| 1628 sandboxed_pages_content_security_policy_ = |
| 1629 kDefaultSandboxedPageContentSecurityPolicy; |
| 1630 CHECK(ContentSecurityPolicyIsSandboxed( |
| 1631 sandboxed_pages_content_security_policy_, GetType())); |
| 1632 } |
| 1633 |
| 1634 return true; |
| 1635 } |
| 1636 |
| 1574 // These are not actually persisted (they're only used by the store), but | 1637 // These are not actually persisted (they're only used by the store), but |
| 1575 // still validated. | 1638 // still validated. |
| 1576 bool Extension::CheckRequirements(string16* error) { | 1639 bool Extension::CheckRequirements(string16* error) { |
| 1577 if (!manifest_->HasKey(keys::kRequirements)) | 1640 if (!manifest_->HasKey(keys::kRequirements)) |
| 1578 return true; | 1641 return true; |
| 1579 DictionaryValue* requirements_value = NULL; | 1642 DictionaryValue* requirements_value = NULL; |
| 1580 if (!manifest_->GetDictionary(keys::kRequirements, &requirements_value)) { | 1643 if (!manifest_->GetDictionary(keys::kRequirements, &requirements_value)) { |
| 1581 *error = ASCIIToUTF16(errors::kInvalidRequirements); | 1644 *error = ASCIIToUTF16(errors::kInvalidRequirements); |
| 1582 return false; | 1645 return false; |
| 1583 } | 1646 } |
| (...skipping 2050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3634 | 3697 |
| 3635 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( | 3698 UpdatedExtensionPermissionsInfo::UpdatedExtensionPermissionsInfo( |
| 3636 const Extension* extension, | 3699 const Extension* extension, |
| 3637 const ExtensionPermissionSet* permissions, | 3700 const ExtensionPermissionSet* permissions, |
| 3638 Reason reason) | 3701 Reason reason) |
| 3639 : reason(reason), | 3702 : reason(reason), |
| 3640 extension(extension), | 3703 extension(extension), |
| 3641 permissions(permissions) {} | 3704 permissions(permissions) {} |
| 3642 | 3705 |
| 3643 } // namespace extensions | 3706 } // namespace extensions |
| OLD | NEW |