OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "extensions/common/features/simple_feature.h" | 5 #include "extensions/common/features/simple_feature.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/command_line.h" | 12 #include "base/command_line.h" |
13 #include "base/debug/alias.h" | 13 #include "base/debug/alias.h" |
14 #include "base/macros.h" | |
14 #include "base/sha1.h" | 15 #include "base/sha1.h" |
15 #include "base/stl_util.h" | 16 #include "base/stl_util.h" |
16 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
17 #include "base/strings/string_util.h" | 18 #include "base/strings/string_util.h" |
18 #include "base/strings/stringprintf.h" | 19 #include "base/strings/stringprintf.h" |
19 #include "extensions/common/extension_api.h" | 20 #include "extensions/common/extension_api.h" |
20 #include "extensions/common/features/feature_provider.h" | 21 #include "extensions/common/features/feature_provider.h" |
21 #include "extensions/common/switches.h" | 22 #include "extensions/common/switches.h" |
22 | 23 |
23 namespace extensions { | 24 namespace extensions { |
24 | 25 |
25 namespace { | 26 namespace { |
26 | 27 |
28 // A singleton copy of the --whitelisted-extension-id so that we don't need to | |
29 // copy it from the CommandLine each time. | |
30 std::string* whitelisted_extension_id = NULL; | |
not at google - send to devlin
2015/04/08 17:59:22
should be g_whitelisted_extension_id;
jackhou1
2015/04/09 07:23:28
Done.
| |
31 | |
27 Feature::Availability IsAvailableToManifestForBind( | 32 Feature::Availability IsAvailableToManifestForBind( |
28 const std::string& extension_id, | 33 const std::string& extension_id, |
29 Manifest::Type type, | 34 Manifest::Type type, |
30 Manifest::Location location, | 35 Manifest::Location location, |
31 int manifest_version, | 36 int manifest_version, |
32 Feature::Platform platform, | 37 Feature::Platform platform, |
33 const Feature* feature) { | 38 const Feature* feature) { |
34 return feature->IsAvailableToManifest( | 39 return feature->IsAvailableToManifest( |
35 extension_id, type, location, manifest_version, platform); | 40 extension_id, type, location, manifest_version, platform); |
36 } | 41 } |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
215 | 220 |
216 bool IsCommandLineSwitchEnabled(const std::string& switch_name) { | 221 bool IsCommandLineSwitchEnabled(const std::string& switch_name) { |
217 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 222 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
218 if (command_line->HasSwitch(switch_name + "=1")) | 223 if (command_line->HasSwitch(switch_name + "=1")) |
219 return true; | 224 return true; |
220 if (command_line->HasSwitch(std::string("enable-") + switch_name)) | 225 if (command_line->HasSwitch(std::string("enable-") + switch_name)) |
221 return true; | 226 return true; |
222 return false; | 227 return false; |
223 } | 228 } |
224 | 229 |
230 bool IsWhitelistedByCommandLine(const std::string& extension_id) { | |
231 if (!whitelisted_extension_id) | |
232 SimpleFeature::SetWhitelistedExtensionId( | |
233 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
234 switches::kWhitelistedExtensionID)); | |
235 return !whitelisted_extension_id->empty() && | |
236 *whitelisted_extension_id == extension_id; | |
237 } | |
238 | |
225 } // namespace | 239 } // namespace |
226 | 240 |
227 struct SimpleFeature::Mappings { | 241 struct SimpleFeature::Mappings { |
228 Mappings() { | 242 Mappings() { |
229 extension_types["extension"] = Manifest::TYPE_EXTENSION; | 243 extension_types["extension"] = Manifest::TYPE_EXTENSION; |
230 extension_types["theme"] = Manifest::TYPE_THEME; | 244 extension_types["theme"] = Manifest::TYPE_THEME; |
231 extension_types["legacy_packaged_app"] = Manifest::TYPE_LEGACY_PACKAGED_APP; | 245 extension_types["legacy_packaged_app"] = Manifest::TYPE_LEGACY_PACKAGED_APP; |
232 extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP; | 246 extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP; |
233 extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP; | 247 extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP; |
234 extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE; | 248 extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE; |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
356 if (IsIdInBlacklist(extension_id)) | 370 if (IsIdInBlacklist(extension_id)) |
357 return CreateAvailability(FOUND_IN_BLACKLIST, type); | 371 return CreateAvailability(FOUND_IN_BLACKLIST, type); |
358 | 372 |
359 // TODO(benwells): don't grant all component extensions. | 373 // TODO(benwells): don't grant all component extensions. |
360 // See http://crbug.com/370375 for more details. | 374 // See http://crbug.com/370375 for more details. |
361 // Component extensions can access any feature. | 375 // Component extensions can access any feature. |
362 // NOTE: Deliberately does not match EXTERNAL_COMPONENT. | 376 // NOTE: Deliberately does not match EXTERNAL_COMPONENT. |
363 if (component_extensions_auto_granted_ && location == Manifest::COMPONENT) | 377 if (component_extensions_auto_granted_ && location == Manifest::COMPONENT) |
364 return CreateAvailability(IS_AVAILABLE, type); | 378 return CreateAvailability(IS_AVAILABLE, type); |
365 | 379 |
366 if (!whitelist_.empty()) { | 380 if (!whitelist_.empty() && !IsIdInWhitelist(extension_id) && |
367 if (!IsIdInWhitelist(extension_id)) { | 381 !IsWhitelistedByCommandLine(extension_id)) { |
not at google - send to devlin
2015/04/08 17:59:22
"IsWhitelistedByCommandLine" isn't accurate anymor
jackhou1
2015/04/09 07:23:28
Done.
| |
368 // TODO(aa): This is gross. There should be a better way to test the | 382 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); |
369 // whitelist. | |
370 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | |
371 if (!command_line->HasSwitch(switches::kWhitelistedExtensionID)) | |
372 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); | |
373 | |
374 std::string whitelist_switch_value = | |
375 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
376 switches::kWhitelistedExtensionID); | |
377 if (extension_id != whitelist_switch_value) | |
378 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); | |
379 } | |
380 } | 383 } |
381 | 384 |
382 if (!MatchesManifestLocation(location)) | 385 if (!MatchesManifestLocation(location)) |
383 return CreateAvailability(INVALID_LOCATION, type); | 386 return CreateAvailability(INVALID_LOCATION, type); |
384 | 387 |
385 if (!platforms_.empty() && !ContainsValue(platforms_, platform)) | 388 if (!platforms_.empty() && !ContainsValue(platforms_, platform)) |
386 return CreateAvailability(INVALID_PLATFORM, type); | 389 return CreateAvailability(INVALID_PLATFORM, type); |
387 | 390 |
388 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) | 391 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) |
389 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); | 392 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 return false; | 568 return false; |
566 | 569 |
567 const char* const* start = array; | 570 const char* const* start = array; |
568 const char* const* end = array + array_length; | 571 const char* const* end = array + array_length; |
569 | 572 |
570 return ((std::find(start, end, extension_id) != end) || | 573 return ((std::find(start, end, extension_id) != end) || |
571 (std::find(start, end, HashExtensionId(extension_id)) != end)); | 574 (std::find(start, end, HashExtensionId(extension_id)) != end)); |
572 } | 575 } |
573 | 576 |
574 // static | 577 // static |
578 void SimpleFeature::SetWhitelistedExtensionId(const std::string& id) { | |
579 if (whitelisted_extension_id) | |
580 delete whitelisted_extension_id; | |
581 whitelisted_extension_id = new std::string(id); | |
not at google - send to devlin
2015/04/08 17:59:22
This will leak in the final unit test that calls S
jackhou1
2015/04/09 07:23:28
Done.
| |
582 } | |
583 | |
584 // static | |
575 bool SimpleFeature::IsIdInList(const std::string& extension_id, | 585 bool SimpleFeature::IsIdInList(const std::string& extension_id, |
576 const std::vector<std::string>& list) { | 586 const std::vector<std::string>& list) { |
577 if (!IsValidExtensionId(extension_id)) | 587 if (!IsValidExtensionId(extension_id)) |
578 return false; | 588 return false; |
579 | 589 |
580 return (ContainsValue(list, extension_id) || | 590 return (ContainsValue(list, extension_id) || |
581 ContainsValue(list, HashExtensionId(extension_id))); | 591 ContainsValue(list, HashExtensionId(extension_id))); |
582 } | 592 } |
583 | 593 |
584 bool SimpleFeature::MatchesManifestLocation( | 594 bool SimpleFeature::MatchesManifestLocation( |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
616 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) { | 626 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) { |
617 // Belt-and-suspenders philosophy here. We should be pretty confident by this | 627 // Belt-and-suspenders philosophy here. We should be pretty confident by this |
618 // point that we've validated the extension ID format, but in case something | 628 // point that we've validated the extension ID format, but in case something |
619 // slips through, we avoid a class of attack where creative ID manipulation | 629 // slips through, we avoid a class of attack where creative ID manipulation |
620 // leads to hash collisions. | 630 // leads to hash collisions. |
621 // 128 bits / 4 = 32 mpdecimal characters | 631 // 128 bits / 4 = 32 mpdecimal characters |
622 return (extension_id.length() == 32); | 632 return (extension_id.length() == 32); |
623 } | 633 } |
624 | 634 |
625 } // namespace extensions | 635 } // namespace extensions |
OLD | NEW |