Chromium Code Reviews| 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* g_whitelisted_extension_id = NULL; | |
| 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 IsWhitelistedForTest(const std::string& extension_id) { | |
| 231 if (!g_whitelisted_extension_id) { | |
|
not at google - send to devlin
2015/04/09 14:36:52
TODO(jackhou): Delete the commandline whitelisting
jackhou1
2015/04/10 01:45:31
Done.
| |
| 232 g_whitelisted_extension_id = new std::string( | |
| 233 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( | |
| 234 switches::kWhitelistedExtensionID)); | |
| 235 } | |
| 236 return !g_whitelisted_extension_id->empty() && | |
|
not at google - send to devlin
2015/04/09 14:36:52
I don't think the .empty() check here is necessary
tapted
2015/04/09 14:56:46
yeah.. I suggested this nugget of paranoia :)
IsI
not at google - send to devlin
2015/04/09 15:01:28
ok :-) seems like a CHECK (or early-ignore) situat
| |
| 237 *g_whitelisted_extension_id == extension_id; | |
| 238 } | |
| 239 | |
| 225 } // namespace | 240 } // namespace |
| 226 | 241 |
| 242 SimpleFeature::ScopedWhitelistForTest::ScopedWhitelistForTest( | |
| 243 const std::string& id) | |
| 244 : previous_id_(g_whitelisted_extension_id) { | |
| 245 g_whitelisted_extension_id = new std::string(id); | |
| 246 } | |
| 247 | |
| 248 SimpleFeature::ScopedWhitelistForTest::~ScopedWhitelistForTest() { | |
| 249 delete g_whitelisted_extension_id; | |
| 250 g_whitelisted_extension_id = previous_id_; | |
| 251 } | |
| 252 | |
| 227 struct SimpleFeature::Mappings { | 253 struct SimpleFeature::Mappings { |
| 228 Mappings() { | 254 Mappings() { |
| 229 extension_types["extension"] = Manifest::TYPE_EXTENSION; | 255 extension_types["extension"] = Manifest::TYPE_EXTENSION; |
| 230 extension_types["theme"] = Manifest::TYPE_THEME; | 256 extension_types["theme"] = Manifest::TYPE_THEME; |
| 231 extension_types["legacy_packaged_app"] = Manifest::TYPE_LEGACY_PACKAGED_APP; | 257 extension_types["legacy_packaged_app"] = Manifest::TYPE_LEGACY_PACKAGED_APP; |
| 232 extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP; | 258 extension_types["hosted_app"] = Manifest::TYPE_HOSTED_APP; |
| 233 extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP; | 259 extension_types["platform_app"] = Manifest::TYPE_PLATFORM_APP; |
| 234 extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE; | 260 extension_types["shared_module"] = Manifest::TYPE_SHARED_MODULE; |
| 235 | 261 |
| 236 contexts["blessed_extension"] = Feature::BLESSED_EXTENSION_CONTEXT; | 262 contexts["blessed_extension"] = Feature::BLESSED_EXTENSION_CONTEXT; |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 if (IsIdInBlacklist(extension_id)) | 382 if (IsIdInBlacklist(extension_id)) |
| 357 return CreateAvailability(FOUND_IN_BLACKLIST, type); | 383 return CreateAvailability(FOUND_IN_BLACKLIST, type); |
| 358 | 384 |
| 359 // TODO(benwells): don't grant all component extensions. | 385 // TODO(benwells): don't grant all component extensions. |
| 360 // See http://crbug.com/370375 for more details. | 386 // See http://crbug.com/370375 for more details. |
| 361 // Component extensions can access any feature. | 387 // Component extensions can access any feature. |
| 362 // NOTE: Deliberately does not match EXTERNAL_COMPONENT. | 388 // NOTE: Deliberately does not match EXTERNAL_COMPONENT. |
| 363 if (component_extensions_auto_granted_ && location == Manifest::COMPONENT) | 389 if (component_extensions_auto_granted_ && location == Manifest::COMPONENT) |
| 364 return CreateAvailability(IS_AVAILABLE, type); | 390 return CreateAvailability(IS_AVAILABLE, type); |
| 365 | 391 |
| 366 if (!whitelist_.empty()) { | 392 if (!whitelist_.empty() && !IsIdInWhitelist(extension_id) && |
| 367 if (!IsIdInWhitelist(extension_id)) { | 393 !IsWhitelistedForTest(extension_id)) { |
| 368 // TODO(aa): This is gross. There should be a better way to test the | 394 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 } | 395 } |
| 381 | 396 |
| 382 if (!MatchesManifestLocation(location)) | 397 if (!MatchesManifestLocation(location)) |
| 383 return CreateAvailability(INVALID_LOCATION, type); | 398 return CreateAvailability(INVALID_LOCATION, type); |
| 384 | 399 |
| 385 if (!platforms_.empty() && !ContainsValue(platforms_, platform)) | 400 if (!platforms_.empty() && !ContainsValue(platforms_, platform)) |
| 386 return CreateAvailability(INVALID_PLATFORM, type); | 401 return CreateAvailability(INVALID_PLATFORM, type); |
| 387 | 402 |
| 388 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) | 403 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) |
| 389 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); | 404 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 616 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) { | 631 bool SimpleFeature::IsValidExtensionId(const std::string& extension_id) { |
| 617 // Belt-and-suspenders philosophy here. We should be pretty confident by this | 632 // 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 | 633 // 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 | 634 // slips through, we avoid a class of attack where creative ID manipulation |
| 620 // leads to hash collisions. | 635 // leads to hash collisions. |
| 621 // 128 bits / 4 = 32 mpdecimal characters | 636 // 128 bits / 4 = 32 mpdecimal characters |
| 622 return (extension_id.length() == 32); | 637 return (extension_id.length() == 32); |
| 623 } | 638 } |
| 624 | 639 |
| 625 } // namespace extensions | 640 } // namespace extensions |
| OLD | NEW |