Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: extensions/common/features/simple_feature.cc

Issue 265503003: Enable file_handlers and chrome.app.runtime for QuickOffice. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Hacky approach to get around component apps being auto whitelisted to everything Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <map> 7 #include <map>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
220 DCHECK(id_hash.length() == base::kSHA1Length); 220 DCHECK(id_hash.length() == base::kSHA1Length);
221 return base::HexEncode(id_hash.c_str(), id_hash.length()); 221 return base::HexEncode(id_hash.c_str(), id_hash.length());
222 } 222 }
223 223
224 } // namespace 224 } // namespace
225 225
226 SimpleFeature::SimpleFeature() 226 SimpleFeature::SimpleFeature()
227 : location_(UNSPECIFIED_LOCATION), 227 : location_(UNSPECIFIED_LOCATION),
228 min_manifest_version_(0), 228 min_manifest_version_(0),
229 max_manifest_version_(0), 229 max_manifest_version_(0),
230 has_parent_(false) {} 230 has_parent_(false),
231 component_extensions_auto_whitelisted_(true) {}
231 232
232 SimpleFeature::~SimpleFeature() {} 233 SimpleFeature::~SimpleFeature() {}
233 234
234 void SimpleFeature::AddFilter(scoped_ptr<SimpleFeatureFilter> filter) { 235 void SimpleFeature::AddFilter(scoped_ptr<SimpleFeatureFilter> filter) {
235 filters_.push_back(make_linked_ptr(filter.release())); 236 filters_.push_back(make_linked_ptr(filter.release()));
236 } 237 }
237 238
238 std::string SimpleFeature::Parse(const base::DictionaryValue* value) { 239 std::string SimpleFeature::Parse(const base::DictionaryValue* value) {
239 ParseURLPatterns(value, "matches", &matches_); 240 ParseURLPatterns(value, "matches", &matches_);
241 ParseSet(value, "blacklist", &blacklist_);
240 ParseSet(value, "whitelist", &whitelist_); 242 ParseSet(value, "whitelist", &whitelist_);
241 ParseSet(value, "dependencies", &dependencies_); 243 ParseSet(value, "dependencies", &dependencies_);
242 ParseEnumSet<Manifest::Type>(value, "extension_types", &extension_types_, 244 ParseEnumSet<Manifest::Type>(value, "extension_types", &extension_types_,
243 g_mappings.Get().extension_types); 245 g_mappings.Get().extension_types);
244 ParseEnumSet<Context>(value, "contexts", &contexts_, 246 ParseEnumSet<Context>(value, "contexts", &contexts_,
245 g_mappings.Get().contexts); 247 g_mappings.Get().contexts);
246 ParseEnum<Location>(value, "location", &location_, 248 ParseEnum<Location>(value, "location", &location_,
247 g_mappings.Get().locations); 249 g_mappings.Get().locations);
248 ParseEnumSet<Platform>(value, "platforms", &platforms_, 250 ParseEnumSet<Platform>(value, "platforms", &platforms_,
249 g_mappings.Get().platforms); 251 g_mappings.Get().platforms);
250 value->GetInteger("min_manifest_version", &min_manifest_version_); 252 value->GetInteger("min_manifest_version", &min_manifest_version_);
251 value->GetInteger("max_manifest_version", &max_manifest_version_); 253 value->GetInteger("max_manifest_version", &max_manifest_version_);
252 254
253 no_parent_ = false; 255 no_parent_ = false;
254 value->GetBoolean("noparent", &no_parent_); 256 value->GetBoolean("noparent", &no_parent_);
255 257
258 component_extensions_auto_whitelisted_ = true;
259 value->GetBoolean("component_extensions_auto_whitelisted",
260 &component_extensions_auto_whitelisted_);
261
256 if (matches_.is_empty() && contexts_.count(WEB_PAGE_CONTEXT) != 0) { 262 if (matches_.is_empty() && contexts_.count(WEB_PAGE_CONTEXT) != 0) {
257 return name() + ": Allowing web_page contexts requires supplying a value " + 263 return name() + ": Allowing web_page contexts requires supplying a value " +
258 "for matches."; 264 "for matches.";
259 } 265 }
260 266
261 for (FilterList::iterator filter_iter = filters_.begin(); 267 for (FilterList::iterator filter_iter = filters_.begin();
262 filter_iter != filters_.end(); 268 filter_iter != filters_.end();
263 ++filter_iter) { 269 ++filter_iter) {
264 std::string result = (*filter_iter)->Parse(value); 270 std::string result = (*filter_iter)->Parse(value);
265 if (!result.empty()) { 271 if (!result.empty()) {
(...skipping 14 matching lines...) Expand all
280 // to component extensions. 286 // to component extensions.
281 // HACK(kalman): user script -> extension. Solve this in a more generic way 287 // HACK(kalman): user script -> extension. Solve this in a more generic way
282 // when we compile feature files. 288 // when we compile feature files.
283 Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ? 289 Manifest::Type type_to_check = (type == Manifest::TYPE_USER_SCRIPT) ?
284 Manifest::TYPE_EXTENSION : type; 290 Manifest::TYPE_EXTENSION : type;
285 if (!extension_types_.empty() && 291 if (!extension_types_.empty() &&
286 extension_types_.find(type_to_check) == extension_types_.end()) { 292 extension_types_.find(type_to_check) == extension_types_.end()) {
287 return CreateAvailability(INVALID_TYPE, type); 293 return CreateAvailability(INVALID_TYPE, type);
288 } 294 }
289 295
290 // Component extensions can access any feature. 296 if (IsIdInBlacklist(extension_id))
291 // TODO(kalman/asargent): Should this match EXTERNAL_COMPONENT too? 297 return CreateAvailability(FOUND_IN_BLACKLIST, type);
292 if (location == Manifest::COMPONENT) 298
299 // TODO(benwells): don't auto whitelist all component extensions.
300 // See http://crbug.com/370375 for more details.
not at google - send to devlin 2014/05/06 23:04:03 this is pretty hacky. I've been working on trying
301 if (component_extensions_auto_whitelisted_ && location == Manifest::COMPONENT)
293 return CreateAvailability(IS_AVAILABLE, type); 302 return CreateAvailability(IS_AVAILABLE, type);
294 303
295 if (!whitelist_.empty()) { 304 if (!whitelist_.empty()) {
296 if (!IsIdInWhitelist(extension_id)) { 305 if (!IsIdInWhitelist(extension_id)) {
297 // TODO(aa): This is gross. There should be a better way to test the 306 // TODO(aa): This is gross. There should be a better way to test the
298 // whitelist. 307 // whitelist.
299 CommandLine* command_line = CommandLine::ForCurrentProcess(); 308 CommandLine* command_line = CommandLine::ForCurrentProcess();
300 if (!command_line->HasSwitch(switches::kWhitelistedExtensionID)) 309 if (!command_line->HasSwitch(switches::kWhitelistedExtensionID))
301 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); 310 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type);
302 311
303 std::string whitelist_switch_value = 312 std::string whitelist_switch_value =
304 CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 313 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
305 switches::kWhitelistedExtensionID); 314 switches::kWhitelistedExtensionID);
306 if (extension_id != whitelist_switch_value) 315 if (extension_id != whitelist_switch_value)
307 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type); 316 return CreateAvailability(NOT_FOUND_IN_WHITELIST, type);
308 } 317 }
309 } 318 }
310 319
320 // Component extensions can access any feature.
321 // TODO(kalman/asargent): Should this match EXTERNAL_COMPONENT too?
not at google - send to devlin 2014/05/06 23:04:03 hey could you change this TODO to be instead: NOT
322 if (location == Manifest::COMPONENT)
323 return CreateAvailability(IS_AVAILABLE, type);
324
311 if (!MatchesManifestLocation(location)) 325 if (!MatchesManifestLocation(location))
312 return CreateAvailability(INVALID_LOCATION, type); 326 return CreateAvailability(INVALID_LOCATION, type);
313 327
314 if (!platforms_.empty() && 328 if (!platforms_.empty() &&
315 platforms_.find(platform) == platforms_.end()) 329 platforms_.find(platform) == platforms_.end())
316 return CreateAvailability(INVALID_PLATFORM, type); 330 return CreateAvailability(INVALID_PLATFORM, type);
317 331
318 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_) 332 if (min_manifest_version_ != 0 && manifest_version < min_manifest_version_)
319 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type); 333 return CreateAvailability(INVALID_MIN_MANIFEST_VERSION, type);
320 334
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 382
369 std::string SimpleFeature::GetAvailabilityMessage( 383 std::string SimpleFeature::GetAvailabilityMessage(
370 AvailabilityResult result, 384 AvailabilityResult result,
371 Manifest::Type type, 385 Manifest::Type type,
372 const GURL& url, 386 const GURL& url,
373 Context context) const { 387 Context context) const {
374 switch (result) { 388 switch (result) {
375 case IS_AVAILABLE: 389 case IS_AVAILABLE:
376 return std::string(); 390 return std::string();
377 case NOT_FOUND_IN_WHITELIST: 391 case NOT_FOUND_IN_WHITELIST:
392 case FOUND_IN_BLACKLIST:
378 return base::StringPrintf( 393 return base::StringPrintf(
379 "'%s' is not allowed for specified extension ID.", 394 "'%s' is not allowed for specified extension ID.",
380 name().c_str()); 395 name().c_str());
381 case INVALID_URL: 396 case INVALID_URL:
382 return base::StringPrintf("'%s' is not allowed on %s.", 397 return base::StringPrintf("'%s' is not allowed on %s.",
383 name().c_str(), url.spec().c_str()); 398 name().c_str(), url.spec().c_str());
384 case INVALID_TYPE: 399 case INVALID_TYPE:
385 return base::StringPrintf( 400 return base::StringPrintf(
386 "'%s' is only allowed for %s, but this is a %s.", 401 "'%s' is only allowed for %s, but this is a %s.",
387 name().c_str(), 402 name().c_str(),
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
459 std::set<Feature::Context>* SimpleFeature::GetContexts() { 474 std::set<Feature::Context>* SimpleFeature::GetContexts() {
460 return &contexts_; 475 return &contexts_;
461 } 476 }
462 477
463 bool SimpleFeature::IsInternal() const { 478 bool SimpleFeature::IsInternal() const {
464 return false; 479 return false;
465 } 480 }
466 481
467 bool SimpleFeature::IsBlockedInServiceWorker() const { return false; } 482 bool SimpleFeature::IsBlockedInServiceWorker() const { return false; }
468 483
484 bool SimpleFeature::IsIdInBlacklist(const std::string& extension_id) const {
485 return IsIdInList(extension_id, blacklist_);
486 }
487
469 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id) const { 488 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id) const {
470 return IsIdInWhitelist(extension_id, whitelist_); 489 return IsIdInList(extension_id, whitelist_);
471 } 490 }
472 491
473 // static 492 // static
474 bool SimpleFeature::IsIdInWhitelist(const std::string& extension_id, 493 bool SimpleFeature::IsIdInList(const std::string& extension_id,
475 const std::set<std::string>& whitelist) { 494 const std::set<std::string>& list) {
476 // Belt-and-suspenders philosophy here. We should be pretty confident by this 495 // Belt-and-suspenders philosophy here. We should be pretty confident by this
477 // point that we've validated the extension ID format, but in case something 496 // point that we've validated the extension ID format, but in case something
478 // slips through, we avoid a class of attack where creative ID manipulation 497 // slips through, we avoid a class of attack where creative ID manipulation
479 // leads to hash collisions. 498 // leads to hash collisions.
480 if (extension_id.length() != 32) // 128 bits / 4 = 32 mpdecimal characters 499 if (extension_id.length() != 32) // 128 bits / 4 = 32 mpdecimal characters
481 return false; 500 return false;
482 501
483 if (whitelist.find(extension_id) != whitelist.end() || 502 if (list.find(extension_id) != list.end() ||
484 whitelist.find(HashExtensionId(extension_id)) != whitelist.end()) { 503 list.find(HashExtensionId(extension_id)) != list.end()) {
485 return true; 504 return true;
486 } 505 }
487 506
488 return false; 507 return false;
489 } 508 }
490 509
491 bool SimpleFeature::MatchesManifestLocation( 510 bool SimpleFeature::MatchesManifestLocation(
492 Manifest::Location manifest_location) const { 511 Manifest::Location manifest_location) const {
493 switch (location_) { 512 switch (location_) {
494 case SimpleFeature::UNSPECIFIED_LOCATION: 513 case SimpleFeature::UNSPECIFIED_LOCATION:
495 return true; 514 return true;
496 case SimpleFeature::COMPONENT_LOCATION: 515 case SimpleFeature::COMPONENT_LOCATION:
497 // TODO(kalman/asargent): Should this include EXTERNAL_COMPONENT too? 516 // TODO(kalman/asargent): Should this include EXTERNAL_COMPONENT too?
498 return manifest_location == Manifest::COMPONENT; 517 return manifest_location == Manifest::COMPONENT;
499 case SimpleFeature::POLICY_LOCATION: 518 case SimpleFeature::POLICY_LOCATION:
500 return manifest_location == Manifest::EXTERNAL_POLICY || 519 return manifest_location == Manifest::EXTERNAL_POLICY ||
501 manifest_location == Manifest::EXTERNAL_POLICY_DOWNLOAD; 520 manifest_location == Manifest::EXTERNAL_POLICY_DOWNLOAD;
502 } 521 }
503 NOTREACHED(); 522 NOTREACHED();
504 return false; 523 return false;
505 } 524 }
506 525
507 } // namespace extensions 526 } // namespace extensions
OLDNEW
« no previous file with comments | « extensions/common/features/simple_feature.h ('k') | extensions/common/features/simple_feature_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698