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" | |
15 #include "base/sha1.h" | 14 #include "base/sha1.h" |
16 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
17 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
18 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
19 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
20 #include "extensions/common/extension_api.h" | 19 #include "extensions/common/extension_api.h" |
21 #include "extensions/common/features/feature_provider.h" | 20 #include "extensions/common/features/feature_provider.h" |
22 #include "extensions/common/switches.h" | 21 #include "extensions/common/switches.h" |
23 | 22 |
24 namespace extensions { | 23 namespace extensions { |
25 | 24 |
26 namespace { | 25 namespace { |
27 | 26 |
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* g_whitelisted_extension_id = NULL; | |
31 | |
32 Feature::Availability IsAvailableToManifestForBind( | 27 Feature::Availability IsAvailableToManifestForBind( |
33 const std::string& extension_id, | 28 const std::string& extension_id, |
34 Manifest::Type type, | 29 Manifest::Type type, |
35 Manifest::Location location, | 30 Manifest::Location location, |
36 int manifest_version, | 31 int manifest_version, |
37 Feature::Platform platform, | 32 Feature::Platform platform, |
38 const Feature* feature) { | 33 const Feature* feature) { |
39 return feature->IsAvailableToManifest( | 34 return feature->IsAvailableToManifest( |
40 extension_id, type, location, manifest_version, platform); | 35 extension_id, type, location, manifest_version, platform); |
41 } | 36 } |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 | 215 |
221 bool IsCommandLineSwitchEnabled(const std::string& switch_name) { | 216 bool IsCommandLineSwitchEnabled(const std::string& switch_name) { |
222 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 217 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); |
223 if (command_line->HasSwitch(switch_name + "=1")) | 218 if (command_line->HasSwitch(switch_name + "=1")) |
224 return true; | 219 return true; |
225 if (command_line->HasSwitch(std::string("enable-") + switch_name)) | 220 if (command_line->HasSwitch(std::string("enable-") + switch_name)) |
226 return true; | 221 return true; |
227 return false; | 222 return false; |
228 } | 223 } |
229 | 224 |
230 bool IsWhitelistedForTest(const std::string& extension_id) { | |
231 // TODO(jackhou): Delete the commandline whitelisting mechanism. | |
232 // Since it is only used it tests, ideally it should not be set via the | |
233 // commandline. At the moment the commandline is used as a mechanism to pass | |
234 // the id to the renderer process. | |
235 if (!g_whitelisted_extension_id) { | |
236 g_whitelisted_extension_id = new std::string( | |
237 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
238 switches::kWhitelistedExtensionID)); | |
239 } | |
240 return !g_whitelisted_extension_id->empty() && | |
241 *g_whitelisted_extension_id == extension_id; | |
242 } | |
243 | |
244 } // namespace | 225 } // namespace |
245 | 226 |
246 SimpleFeature::ScopedWhitelistForTest::ScopedWhitelistForTest( | |
247 const std::string& id) | |
248 : previous_id_(g_whitelisted_extension_id) { | |
249 g_whitelisted_extension_id = new std::string(id); | |
250 } | |
251 | |
252 SimpleFeature::ScopedWhitelistForTest::~ScopedWhitelistForTest() { | |
253 delete g_whitelisted_extension_id; | |
254 g_whitelisted_extension_id = previous_id_; | |
255 } | |
256 | |
257 struct SimpleFeature::Mappings { | 227 struct SimpleFeature::Mappings { |
258 Mappings() { | 228 Mappings() { |
259 extension_types["extension"] = Manifest::TYPE_EXTENSION; | 229 extension_types["extension"] = Manifest::TYPE_EXTENSION; |
260 extension_types["theme"] = Manifest::TYPE_THEME; | 230 extension_types["theme"] = Manifest::TYPE_THEME; |
261 extension_types["legacy_packaged_app"] = Manifest::TYPE_LEGACY_PACKAGED_APP; | 231 extension_types["legacy_packaged_app"] = Manifest::TYPE_LEGACY_PACKAGED_APP; |
262 extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP; | 232 extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP; |
263 extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP; | 233 extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP; |
264 extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE; | 234 extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE; |
265 | 235 |
266 contexts["blessed_extension"] = Feature::BLESSED_EXTENSION_CONTEXT; | 236 contexts["blessed_extension"] = Feature::BLESSED_EXTENSION_CONTEXT; |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 if (IsIdInBlacklist(extension_id)) | 356 if (IsIdInBlacklist(extension_id)) |
387 return CreateAvailability(FOUND_IN_BLACKLIST, type); | 357 return CreateAvailability(FOUND_IN_BLACKLIST, type); |
388 | 358 |
389 // TODO(benwells): don't grant all component extensions. | 359 // TODO(benwells): don't grant all component extensions. |
390 // See http://crbug.com/370375 for more details. | 360 // See http://crbug.com/370375 for more details. |
391 // Component extensions can access any feature. | 361 // Component extensions can access any feature. |
392 // NOTE: Deliberately does not match EXTERNAL_COMPONENT. | 362 // NOTE: Deliberately does not match EXTERNAL_COMPONENT. |
393 if (component_extensions_auto_granted_ && location == Manifest::COMPONENT) | 363 if (component_extensions_auto_granted_ && location == Manifest::COMPONENT) |
394 return CreateAvailability(IS_AVAILABLE, type); | 364 return CreateAvailability(IS_AVAILABLE, type); |
395 | 365 |
396 if (!whitelist_.empty() && !IsIdInWhitelist(extension_id) && | 366 if (!whitelist_.empty()) { |
397 !IsWhitelistedForTest(extension_id)) { | 367 if (!IsIdInWhitelist(extension_id)) { |
398 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); | 368 // TODO(aa): This is gross. There should be a better way to test the |
| 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 } |
399 } | 380 } |
400 | 381 |
401 if (!MatchesManifestLocation(location)) | 382 if (!MatchesManifestLocation(location)) |
402 return CreateAvailability(INVALID_LOCATION, type); | 383 return CreateAvailability(INVALID_LOCATION, type); |
403 | 384 |
404 if (!platforms_.empty() && !ContainsValue(platforms_, platform)) | 385 if (!platforms_.empty() && !ContainsValue(platforms_, platform)) |
405 return CreateAvailability(INVALID_PLATFORM, type); | 386 return CreateAvailability(INVALID_PLATFORM, type); |
406 | 387 |
407 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) | 388 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) |
408 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); | 389 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) { | 616 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) { |
636 // Belt-and-suspenders philosophy here. We should be pretty confident by this | 617 // Belt-and-suspenders philosophy here. We should be pretty confident by this |
637 // point that we've validated the extension ID format, but in case something | 618 // point that we've validated the extension ID format, but in case something |
638 // slips through, we avoid a class of attack where creative ID manipulation | 619 // slips through, we avoid a class of attack where creative ID manipulation |
639 // leads to hash collisions. | 620 // leads to hash collisions. |
640 // 128 bits / 4 = 32 mpdecimal characters | 621 // 128 bits / 4 = 32 mpdecimal characters |
641 return (extension_id.length() == 32); | 622 return (extension_id.length() == 32); |
642 } | 623 } |
643 | 624 |
644 } // namespace extensions | 625 } // namespace extensions |
OLD | NEW |