OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "app/resource_bundle.h" | 7 #include "app/resource_bundle.h" |
8 #include "base/file_path.h" | 8 #include "base/file_path.h" |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/string_util.h" | 11 #include "base/string_util.h" |
12 #include "net/base/net_util.h" | 12 #include "net/base/net_util.h" |
13 #include "chrome/common/extensions/extension_error_reporter.h" | 13 #include "chrome/common/extensions/extension_error_reporter.h" |
14 #include "chrome/common/extensions/extension_error_utils.h" | 14 #include "chrome/common/extensions/extension_error_utils.h" |
15 #include "chrome/common/extensions/user_script.h" | 15 #include "chrome/common/extensions/user_script.h" |
16 #include "chrome/common/url_constants.h" | 16 #include "chrome/common/url_constants.h" |
| 17 #include "net/base/base64.h" |
17 | 18 |
18 #if defined(OS_WIN) | 19 #if defined(OS_WIN) |
19 #include "base/registry.h" | 20 #include "base/registry.h" |
20 #endif | 21 #endif |
21 | 22 |
| 23 namespace { |
| 24 const int kPEMOutputColumns = 65; |
| 25 |
| 26 // KEY MARKERS |
| 27 const char kKeyBeginHeaderMarker[] = "-----BEGIN"; |
| 28 const char kKeyBeginFooterMarker[] = "-----END"; |
| 29 const char kKeyInfoEndMarker[] = "KEY-----"; |
| 30 const char kPublic[] = "PUBLIC"; |
| 31 const char kPrivate[] = "PRIVATE"; |
| 32 |
| 33 const int kRSAKeySize = 1024; |
| 34 }; |
| 35 |
22 const char Extension::kManifestFilename[] = "manifest.json"; | 36 const char Extension::kManifestFilename[] = "manifest.json"; |
23 | 37 |
| 38 const wchar_t* Extension::kBackgroundKey = L"background_page"; |
24 const wchar_t* Extension::kContentScriptsKey = L"content_scripts"; | 39 const wchar_t* Extension::kContentScriptsKey = L"content_scripts"; |
25 const wchar_t* Extension::kCssKey = L"css"; | 40 const wchar_t* Extension::kCssKey = L"css"; |
26 const wchar_t* Extension::kDescriptionKey = L"description"; | 41 const wchar_t* Extension::kDescriptionKey = L"description"; |
27 const wchar_t* Extension::kIconPathKey = L"icon"; | 42 const wchar_t* Extension::kIconPathKey = L"icon"; |
28 const wchar_t* Extension::kIdKey = L"id"; | 43 const wchar_t* Extension::kIdKey = L"id"; |
29 const wchar_t* Extension::kJsKey = L"js"; | 44 const wchar_t* Extension::kJsKey = L"js"; |
30 const wchar_t* Extension::kMatchesKey = L"matches"; | 45 const wchar_t* Extension::kMatchesKey = L"matches"; |
31 const wchar_t* Extension::kNameKey = L"name"; | 46 const wchar_t* Extension::kNameKey = L"name"; |
32 const wchar_t* Extension::kPageActionsKey = L"page_actions"; | 47 const wchar_t* Extension::kPageActionsKey = L"page_actions"; |
33 const wchar_t* Extension::kPermissionsKey = L"permissions"; | 48 const wchar_t* Extension::kPermissionsKey = L"permissions"; |
34 const wchar_t* Extension::kPluginsKey = L"plugins"; | 49 const wchar_t* Extension::kPluginsKey = L"plugins"; |
35 const wchar_t* Extension::kPluginsPathKey = L"path"; | 50 const wchar_t* Extension::kPluginsPathKey = L"path"; |
36 const wchar_t* Extension::kPluginsPublicKey = L"public"; | 51 const wchar_t* Extension::kPluginsPublicKey = L"public"; |
37 const wchar_t* Extension::kBackgroundKey = L"background_page"; | 52 const wchar_t* Extension::kPublicKeyKey = L"key"; |
38 const wchar_t* Extension::kRunAtKey = L"run_at"; | 53 const wchar_t* Extension::kRunAtKey = L"run_at"; |
| 54 const wchar_t* Extension::kSignatureKey = L"signature"; |
39 const wchar_t* Extension::kThemeKey = L"theme"; | 55 const wchar_t* Extension::kThemeKey = L"theme"; |
40 const wchar_t* Extension::kThemeImagesKey = L"images"; | 56 const wchar_t* Extension::kThemeImagesKey = L"images"; |
41 const wchar_t* Extension::kThemeColorsKey = L"colors"; | 57 const wchar_t* Extension::kThemeColorsKey = L"colors"; |
42 const wchar_t* Extension::kThemeTintsKey = L"tints"; | 58 const wchar_t* Extension::kThemeTintsKey = L"tints"; |
43 const wchar_t* Extension::kThemeDisplayPropertiesKey = L"properties"; | 59 const wchar_t* Extension::kThemeDisplayPropertiesKey = L"properties"; |
44 const wchar_t* Extension::kToolstripsKey = L"toolstrips"; | 60 const wchar_t* Extension::kToolstripsKey = L"toolstrips"; |
45 const wchar_t* Extension::kTooltipKey = L"tooltip"; | 61 const wchar_t* Extension::kTooltipKey = L"tooltip"; |
46 const wchar_t* Extension::kTypeKey = L"type"; | 62 const wchar_t* Extension::kTypeKey = L"type"; |
47 const wchar_t* Extension::kVersionKey = L"version"; | 63 const wchar_t* Extension::kVersionKey = L"version"; |
48 const wchar_t* Extension::kZipHashKey = L"zip_hash"; | |
49 | 64 |
50 const char* Extension::kRunAtDocumentStartValue = "document_start"; | 65 const char* Extension::kRunAtDocumentStartValue = "document_start"; |
51 const char* Extension::kRunAtDocumentEndValue = "document_end"; | 66 const char* Extension::kRunAtDocumentEndValue = "document_end"; |
52 const char* Extension::kPageActionTypeTab = "tab"; | 67 const char* Extension::kPageActionTypeTab = "tab"; |
53 const char* Extension::kPageActionTypePermanent = "permanent"; | 68 const char* Extension::kPageActionTypePermanent = "permanent"; |
54 | 69 |
55 // A list of all the keys allowed by themes. | 70 // A list of all the keys allowed by themes. |
56 static const wchar_t* kValidThemeKeys[] = { | 71 static const wchar_t* kValidThemeKeys[] = { |
57 Extension::kDescriptionKey, | 72 Extension::kDescriptionKey, |
58 Extension::kIconPathKey, | 73 Extension::kIconPathKey, |
59 Extension::kIdKey, | 74 Extension::kIdKey, |
60 Extension::kNameKey, | 75 Extension::kNameKey, |
| 76 Extension::kPublicKeyKey, |
| 77 Extension::kSignatureKey, |
61 Extension::kThemeKey, | 78 Extension::kThemeKey, |
62 Extension::kVersionKey, | 79 Extension::kVersionKey |
63 Extension::kZipHashKey | |
64 }; | 80 }; |
65 | 81 |
66 // Extension-related error messages. Some of these are simple patterns, where a | 82 // Extension-related error messages. Some of these are simple patterns, where a |
67 // '*' is replaced at runtime with a specific value. This is used instead of | 83 // '*' is replaced at runtime with a specific value. This is used instead of |
68 // printf because we want to unit test them and scanf is hard to make | 84 // printf because we want to unit test them and scanf is hard to make |
69 // cross-platform. | 85 // cross-platform. |
70 const char* Extension::kInvalidContentScriptError = | 86 const char* Extension::kInvalidContentScriptError = |
71 "Invalid value for 'content_scripts[*]'."; | 87 "Invalid value for 'content_scripts[*]'."; |
72 const char* Extension::kInvalidContentScriptsListError = | 88 const char* Extension::kInvalidContentScriptsListError = |
73 "Invalid value for 'content_scripts'."; | 89 "Invalid value for 'content_scripts'."; |
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
469 if (path_str.size() >= 2 && path_str[0] >= L'a' && path_str[0] <= L'z' && | 485 if (path_str.size() >= 2 && path_str[0] >= L'a' && path_str[0] <= L'z' && |
470 path_str[1] == ':') | 486 path_str[1] == ':') |
471 path_str[0] += ('A' - 'a'); | 487 path_str[0] += ('A' - 'a'); |
472 | 488 |
473 path_ = FilePath(path_str); | 489 path_ = FilePath(path_str); |
474 #else | 490 #else |
475 path_ = path; | 491 path_ = path; |
476 #endif | 492 #endif |
477 } | 493 } |
478 | 494 |
| 495 |
| 496 // TODO(rafaelw): Move ParsePEMKeyBytes, ProducePEM & FormatPEMForOutput to a |
| 497 // util class in base: |
| 498 // http://code.google.com/p/chromium/issues/detail?id=13572 |
| 499 bool Extension::ParsePEMKeyBytes(const std::string& input, |
| 500 std::string* output) { |
| 501 CHECK(output); |
| 502 if (input.length() == 0) |
| 503 return false; |
| 504 |
| 505 std::string working = input; |
| 506 if (StartsWithASCII(working, kKeyBeginHeaderMarker, true)) { |
| 507 working = CollapseWhitespaceASCII(working, true); |
| 508 size_t header_pos = working.find(kKeyInfoEndMarker, |
| 509 sizeof(kKeyBeginHeaderMarker) - 1); |
| 510 if (header_pos == std::string::npos) |
| 511 return false; |
| 512 size_t start_pos = header_pos + sizeof(kKeyInfoEndMarker) - 1; |
| 513 size_t end_pos = working.rfind(kKeyBeginFooterMarker); |
| 514 if (end_pos == std::string::npos) |
| 515 return false; |
| 516 if (start_pos >= end_pos) |
| 517 return false; |
| 518 |
| 519 working = working.substr(start_pos, end_pos - start_pos); |
| 520 if (working.length() == 0) |
| 521 return false; |
| 522 } |
| 523 |
| 524 return net::Base64Decode(working, output); |
| 525 } |
| 526 |
| 527 bool Extension::ProducePEM(const std::string& input, |
| 528 std::string* output) { |
| 529 CHECK(output); |
| 530 if (input.length() == 0) |
| 531 return false; |
| 532 |
| 533 return net::Base64Encode(input, output); |
| 534 } |
| 535 |
| 536 bool Extension::FormatPEMForFileOutput(const std::string input, |
| 537 std::string* output, |
| 538 bool is_public) { |
| 539 CHECK(output); |
| 540 if (input.length() == 0) |
| 541 return false; |
| 542 *output = ""; |
| 543 output->append(kKeyBeginHeaderMarker); |
| 544 output->append(" "); |
| 545 output->append(is_public ? kPublic : kPrivate); |
| 546 output->append(" "); |
| 547 output->append(kKeyInfoEndMarker); |
| 548 output->append("\n"); |
| 549 for (size_t i = 0; i < input.length(); ) { |
| 550 int slice = std::min<int>(input.length() - i, kPEMOutputColumns); |
| 551 output->append(input.substr(i, slice)); |
| 552 output->append("\n"); |
| 553 i += slice; |
| 554 } |
| 555 output->append(kKeyBeginFooterMarker); |
| 556 output->append(" "); |
| 557 output->append(is_public ? kPublic : kPrivate); |
| 558 output->append(" "); |
| 559 output->append(kKeyInfoEndMarker); |
| 560 output->append("\n"); |
| 561 |
| 562 return true; |
| 563 } |
| 564 |
479 bool Extension::InitFromValue(const DictionaryValue& source, bool require_id, | 565 bool Extension::InitFromValue(const DictionaryValue& source, bool require_id, |
480 std::string* error) { | 566 std::string* error) { |
481 // Initialize id. | 567 // Initialize id. |
482 if (source.HasKey(kIdKey)) { | 568 if (source.HasKey(kIdKey)) { |
483 if (!source.GetString(kIdKey, &id_)) { | 569 if (!source.GetString(kIdKey, &id_)) { |
484 *error = kInvalidIdError; | 570 *error = kInvalidIdError; |
485 return false; | 571 return false; |
486 } | 572 } |
487 | 573 |
488 // Normalize the string to lowercase, so it can be used as an URL component | 574 // Normalize the string to lowercase, so it can be used as an URL component |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 } | 616 } |
531 | 617 |
532 // Initialize description (optional). | 618 // Initialize description (optional). |
533 if (source.HasKey(kDescriptionKey)) { | 619 if (source.HasKey(kDescriptionKey)) { |
534 if (!source.GetString(kDescriptionKey, &description_)) { | 620 if (!source.GetString(kDescriptionKey, &description_)) { |
535 *error = kInvalidDescriptionError; | 621 *error = kInvalidDescriptionError; |
536 return false; | 622 return false; |
537 } | 623 } |
538 } | 624 } |
539 | 625 |
540 // Initialize zip hash (only present in zip) | |
541 // There's no need to verify it at this point. If it's in a bogus format | |
542 // it won't pass the hash verify step. | |
543 if (source.HasKey(kZipHashKey)) { | |
544 if (!source.GetString(kZipHashKey, &zip_hash_)) { | |
545 *error = kInvalidZipHashError; | |
546 return false; | |
547 } | |
548 } | |
549 | |
550 // Initialize themes. | 626 // Initialize themes. |
551 is_theme_ = false; | 627 is_theme_ = false; |
552 if (source.HasKey(kThemeKey)) { | 628 if (source.HasKey(kThemeKey)) { |
553 // Themes cannot contain extension keys. | 629 // Themes cannot contain extension keys. |
554 if (ContainsNonThemeKeys(source)) { | 630 if (ContainsNonThemeKeys(source)) { |
555 *error = kThemesCannotContainExtensionsError; | 631 *error = kThemesCannotContainExtensionsError; |
556 return false; | 632 return false; |
557 } | 633 } |
558 | 634 |
559 DictionaryValue* theme_value; | 635 DictionaryValue* theme_value; |
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
820 } | 896 } |
821 } | 897 } |
822 | 898 |
823 for (PageActionMap::const_iterator it = page_actions().begin(); | 899 for (PageActionMap::const_iterator it = page_actions().begin(); |
824 it != page_actions().end(); ++it) { | 900 it != page_actions().end(); ++it) { |
825 image_paths.insert(it->second->icon_path()); | 901 image_paths.insert(it->second->icon_path()); |
826 } | 902 } |
827 | 903 |
828 return image_paths; | 904 return image_paths; |
829 } | 905 } |
OLD | NEW |