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

Side by Side Diff: chrome/common/extensions/extension.cc

Issue 7003098: Start refractoring extension permissions into ExtensionPermissionSet. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix a bad merge Created 9 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 <algorithm> 7 #include <algorithm>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/basictypes.h" 10 #include "base/basictypes.h"
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 91
92 bool IsBaseCrxKey(const std::string& key) { 92 bool IsBaseCrxKey(const std::string& key) {
93 for (size_t i = 0; i < arraysize(kBaseCrxKeys); ++i) { 93 for (size_t i = 0; i < arraysize(kBaseCrxKeys); ++i) {
94 if (key == kBaseCrxKeys[i]) 94 if (key == kBaseCrxKeys[i])
95 return true; 95 return true;
96 } 96 }
97 97
98 return false; 98 return false;
99 } 99 }
100 100
101 // Constant used to represent an undefined l10n message id.
102 const int kUndefinedMessageId = -1;
103
104 // Names of API modules that do not require a permission.
105 const char kBrowserActionModuleName[] = "browserAction";
106 const char kBrowserActionsModuleName[] = "browserActions";
107 const char kDevToolsModuleName[] = "devtools";
108 const char kExtensionModuleName[] = "extension";
109 const char kI18NModuleName[] = "i18n";
110 const char kOmniboxModuleName[] = "omnibox";
111 const char kPageActionModuleName[] = "pageAction";
112 const char kPageActionsModuleName[] = "pageActions";
113 const char kTestModuleName[] = "test";
114 const char kTypesModuleName[] = "types";
115
116 // Names of modules that can be used without listing it in the permissions
117 // section of the manifest.
118 const char* kNonPermissionModuleNames[] = {
119 kBrowserActionModuleName,
120 kBrowserActionsModuleName,
121 kDevToolsModuleName,
122 kExtensionModuleName,
123 kI18NModuleName,
124 kOmniboxModuleName,
125 kPageActionModuleName,
126 kPageActionsModuleName,
127 kTestModuleName,
128 kTypesModuleName
129 };
130 const size_t kNumNonPermissionModuleNames =
131 arraysize(kNonPermissionModuleNames);
132
133 // Names of functions (within modules requiring permissions) that can be used
134 // without asking for the module permission. In other words, functions you can
135 // use with no permissions specified.
136 const char* kNonPermissionFunctionNames[] = {
137 "tabs.create",
138 "tabs.onRemoved",
139 "tabs.remove",
140 "tabs.update",
141 };
142 const size_t kNumNonPermissionFunctionNames =
143 arraysize(kNonPermissionFunctionNames);
144
145 // A singleton object containing global data needed by the extension objects. 101 // A singleton object containing global data needed by the extension objects.
146 class ExtensionConfig { 102 class ExtensionConfig {
147 public: 103 public:
148 static ExtensionConfig* GetInstance() { 104 static ExtensionConfig* GetInstance() {
149 return Singleton<ExtensionConfig>::get(); 105 return Singleton<ExtensionConfig>::get();
150 } 106 }
151 107
152 Extension::PermissionMessage::MessageId GetPermissionMessageId(
153 const std::string& permission) {
154 return Extension::kPermissions[permission_map_[permission]].message_id;
155 }
156
157 Extension::ScriptingWhitelist* whitelist() { return &scripting_whitelist_; } 108 Extension::ScriptingWhitelist* whitelist() { return &scripting_whitelist_; }
158 109
159 private: 110 private:
160 friend struct DefaultSingletonTraits<ExtensionConfig>; 111 friend struct DefaultSingletonTraits<ExtensionConfig>;
161 112
162 ExtensionConfig() { 113 ExtensionConfig() { }
163 for (size_t i = 0; i < Extension::kNumPermissions; ++i)
164 permission_map_[Extension::kPermissions[i].name] = i;
165 };
166
167 ~ExtensionConfig() { } 114 ~ExtensionConfig() { }
168 115
169 std::map<const std::string, size_t> permission_map_;
170
171 // A whitelist of extensions that can script anywhere. Do not add to this 116 // A whitelist of extensions that can script anywhere. Do not add to this
172 // list (except in tests) without consulting the Extensions team first. 117 // list (except in tests) without consulting the Extensions team first.
173 // Note: Component extensions have this right implicitly and do not need to be 118 // Note: Component extensions have this right implicitly and do not need to be
174 // added to this list. 119 // added to this list.
175 Extension::ScriptingWhitelist scripting_whitelist_; 120 Extension::ScriptingWhitelist scripting_whitelist_;
176 }; 121 };
177 122
178 // Aliased to kTabPermission for purposes of API checks, but not allowed
179 // in the permissions field of the manifest.
180 static const char kWindowPermission[] = "windows";
181
182 // Rank extension locations in a way that allows 123 // Rank extension locations in a way that allows
183 // Extension::GetHigherPriorityLocation() to compare locations. 124 // Extension::GetHigherPriorityLocation() to compare locations.
184 // An extension installed from two locations will have the location 125 // An extension installed from two locations will have the location
185 // with the higher rank, as returned by this function. The actual 126 // with the higher rank, as returned by this function. The actual
186 // integer values may change, and should never be persisted. 127 // integer values may change, and should never be persisted.
187 int GetLocationRank(Extension::Location location) { 128 int GetLocationRank(Extension::Location location) {
188 const int kInvalidRank = -1; 129 const int kInvalidRank = -1;
189 int rank = kInvalidRank; // Will CHECK that rank is not kInvalidRank. 130 int rank = kInvalidRank; // Will CHECK that rank is not kInvalidRank.
190 131
191 switch (location) { 132 switch (location) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
257 EXTENSION_ICON_MEDIUM, 198 EXTENSION_ICON_MEDIUM,
258 EXTENSION_ICON_SMALL, 199 EXTENSION_ICON_SMALL,
259 EXTENSION_ICON_SMALLISH, 200 EXTENSION_ICON_SMALLISH,
260 EXTENSION_ICON_BITTY 201 EXTENSION_ICON_BITTY
261 }; 202 };
262 203
263 const int Extension::kPageActionIconMaxSize = 19; 204 const int Extension::kPageActionIconMaxSize = 19;
264 const int Extension::kBrowserActionIconMaxSize = 19; 205 const int Extension::kBrowserActionIconMaxSize = 19;
265 const int Extension::kSidebarIconMaxSize = 16; 206 const int Extension::kSidebarIconMaxSize = 16;
266 207
267 // Explicit permissions -- permission declaration required.
268 const char Extension::kBackgroundPermission[] = "background";
269 const char Extension::kBookmarkPermission[] = "bookmarks";
270 const char Extension::kClipboardReadPermission[] = "clipboardRead";
271 const char Extension::kClipboardWritePermission[] = "clipboardWrite";
272 const char Extension::kContextMenusPermission[] = "contextMenus";
273 const char Extension::kContentSettingsPermission[] = "contentSettings";
274 const char Extension::kCookiePermission[] = "cookies";
275 const char Extension::kChromePrivatePermission[] = "chromePrivate";
276 const char Extension::kChromeosInfoPrivatePermission[] = "chromeosInfoPrivate"; 208 const char Extension::kChromeosInfoPrivatePermission[] = "chromeosInfoPrivate";
277 const char Extension::kDebuggerPermission[] = "debugger";
278 const char Extension::kExperimentalPermission[] = "experimental";
279 const char Extension::kFileBrowserHandlerPermission[] = "fileBrowserHandler";
280 const char Extension::kFileBrowserPrivatePermission[] = "fileBrowserPrivate"; 209 const char Extension::kFileBrowserPrivatePermission[] = "fileBrowserPrivate";
281 const char Extension::kGeolocationPermission[] = "geolocation";
282 const char Extension::kHistoryPermission[] = "history";
283 const char Extension::kIdlePermission[] = "idle";
284 const char Extension::kManagementPermission[] = "management";
285 const char Extension::kMediaPlayerPrivatePermission[] = "mediaPlayerPrivate"; 210 const char Extension::kMediaPlayerPrivatePermission[] = "mediaPlayerPrivate";
286 const char Extension::kNotificationPermission[] = "notifications";
287 const char Extension::kProxyPermission[] = "proxy";
288 const char Extension::kTabPermission[] = "tabs";
289 const char Extension::kUnlimitedStoragePermission[] = "unlimitedStorage";
290 const char Extension::kWebstorePrivatePermission[] = "webstorePrivate"; 211 const char Extension::kWebstorePrivatePermission[] = "webstorePrivate";
291 const char Extension::kWebSocketProxyPrivatePermission[] =
292 "webSocketProxyPrivate";
293
294 // In general, all permissions should have an install message.
295 // See ExtensionsTest.PermissionMessages for an explanation of each
296 // exception.
297 const Extension::Permission Extension::kPermissions[] = {
298 { kBackgroundPermission, PermissionMessage::ID_NONE },
299 { kBookmarkPermission, PermissionMessage::ID_BOOKMARKS },
300 { kChromePrivatePermission, PermissionMessage::ID_NONE },
301 { kChromeosInfoPrivatePermission, PermissionMessage::ID_NONE },
302 { kClipboardReadPermission, PermissionMessage::ID_CLIPBOARD },
303 { kClipboardWritePermission, PermissionMessage::ID_NONE },
304 { kContentSettingsPermission, PermissionMessage::ID_NONE },
305 { kContextMenusPermission, PermissionMessage::ID_NONE },
306 { kCookiePermission, PermissionMessage::ID_NONE },
307 { kDebuggerPermission, PermissionMessage::ID_DEBUGGER },
308 { kExperimentalPermission, PermissionMessage::ID_NONE },
309 { kFileBrowserHandlerPermission, PermissionMessage::ID_NONE },
310 { kFileBrowserPrivatePermission, PermissionMessage::ID_NONE },
311 { kGeolocationPermission, PermissionMessage::ID_GEOLOCATION },
312 { kHistoryPermission, PermissionMessage::ID_BROWSING_HISTORY },
313 { kIdlePermission, PermissionMessage::ID_NONE },
314 { kManagementPermission, PermissionMessage::ID_MANAGEMENT },
315 { kMediaPlayerPrivatePermission, PermissionMessage::ID_NONE },
316 { kNotificationPermission, PermissionMessage::ID_NONE },
317 { kProxyPermission, PermissionMessage::ID_NONE },
318 { kTabPermission, PermissionMessage::ID_TABS },
319 { kUnlimitedStoragePermission, PermissionMessage::ID_NONE },
320 { kWebSocketProxyPrivatePermission, PermissionMessage::ID_NONE },
321 { kWebstorePrivatePermission, PermissionMessage::ID_NONE },
322 };
323 const size_t Extension::kNumPermissions = arraysize(Extension::kPermissions);
324
325 const char* const Extension::kHostedAppPermissionNames[] = {
326 Extension::kBackgroundPermission,
327 Extension::kChromePrivatePermission,
328 Extension::kClipboardReadPermission,
329 Extension::kClipboardWritePermission,
330 Extension::kExperimentalPermission,
331 Extension::kGeolocationPermission,
332 Extension::kNotificationPermission,
333 Extension::kUnlimitedStoragePermission,
334 Extension::kWebstorePrivatePermission,
335 };
336 const size_t Extension::kNumHostedAppPermissions =
337 arraysize(Extension::kHostedAppPermissionNames);
338 212
339 const char* const Extension::kComponentPrivatePermissionNames[] = { 213 const char* const Extension::kComponentPrivatePermissionNames[] = {
340 Extension::kFileBrowserPrivatePermission, 214 Extension::kFileBrowserPrivatePermission,
341 Extension::kWebstorePrivatePermission, 215 Extension::kWebstorePrivatePermission,
342 Extension::kMediaPlayerPrivatePermission, 216 Extension::kMediaPlayerPrivatePermission,
343 Extension::kChromeosInfoPrivatePermission, 217 Extension::kChromeosInfoPrivatePermission,
344 }; 218 };
345 const size_t Extension::kNumComponentPrivatePermissions = 219 const size_t Extension::kNumComponentPrivatePermissions =
346 arraysize(Extension::kComponentPrivatePermissionNames); 220 arraysize(Extension::kComponentPrivatePermissionNames);
347 221
348 // We purposefully don't put this into kPermissionNames. 222 // We purposefully don't put this into kPermissionNames.
349 const char Extension::kOldUnlimitedStoragePermission[] = "unlimited_storage"; 223 const char Extension::kOldUnlimitedStoragePermission[] = "unlimited_storage";
350 224
351 const int Extension::kValidWebExtentSchemes = 225 const int Extension::kValidWebExtentSchemes =
352 URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS; 226 URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS;
353 227
354 const int Extension::kValidHostPermissionSchemes = 228 const int Extension::kValidHostPermissionSchemes =
355 UserScript::kValidUserScriptSchemes | URLPattern::SCHEME_CHROMEUI; 229 UserScript::kValidUserScriptSchemes | URLPattern::SCHEME_CHROMEUI;
356 230
357 Extension::InputComponentInfo::InputComponentInfo() {} 231 Extension::InputComponentInfo::InputComponentInfo() {}
358 Extension::InputComponentInfo::~InputComponentInfo() {} 232 Extension::InputComponentInfo::~InputComponentInfo() {}
359 233
360 // 234 //
361 // PermissionMessage
362 //
363
364 // static
365 Extension::PermissionMessage Extension::PermissionMessage::CreateFromMessageId(
366 Extension::PermissionMessage::MessageId message_id) {
367 DCHECK_GT(PermissionMessage::ID_NONE, PermissionMessage::ID_UNKNOWN);
368 if (message_id <= ID_NONE)
369 return PermissionMessage(message_id, string16());
370
371 string16 message = l10n_util::GetStringUTF16(kMessageIds[message_id]);
372 return PermissionMessage(message_id, message);
373 }
374
375 // static
376 Extension::PermissionMessage Extension::PermissionMessage::CreateFromHostList(
377 const std::vector<std::string> hosts) {
378 CHECK(hosts.size() > 0);
379
380 MessageId message_id;
381 string16 message;
382 switch (hosts.size()) {
383 case 1:
384 message_id = ID_HOSTS_1;
385 message = l10n_util::GetStringFUTF16(kMessageIds[message_id],
386 UTF8ToUTF16(hosts[0]));
387 break;
388 case 2:
389 message_id = ID_HOSTS_2;
390 message = l10n_util::GetStringFUTF16(kMessageIds[message_id],
391 UTF8ToUTF16(hosts[0]),
392 UTF8ToUTF16(hosts[1]));
393 break;
394 case 3:
395 message_id = ID_HOSTS_3;
396 message = l10n_util::GetStringFUTF16(kMessageIds[message_id],
397 UTF8ToUTF16(hosts[0]),
398 UTF8ToUTF16(hosts[1]),
399 UTF8ToUTF16(hosts[2]));
400 break;
401 default:
402 message_id = ID_HOSTS_4_OR_MORE;
403 message = l10n_util::GetStringFUTF16(
404 kMessageIds[message_id],
405 UTF8ToUTF16(hosts[0]),
406 UTF8ToUTF16(hosts[1]),
407 base::IntToString16(hosts.size() - 2));
408 break;
409 }
410
411 return PermissionMessage(message_id, message);
412 }
413
414 Extension::PermissionMessage::PermissionMessage(
415 Extension::PermissionMessage::MessageId message_id, string16 message)
416 : message_id_(message_id),
417 message_(message) {
418 }
419
420 const int Extension::PermissionMessage::kMessageIds[] = {
421 kUndefinedMessageId, // "unknown"
422 kUndefinedMessageId, // "none"
423 IDS_EXTENSION_PROMPT_WARNING_BOOKMARKS,
424 IDS_EXTENSION_PROMPT_WARNING_GEOLOCATION,
425 IDS_EXTENSION_PROMPT_WARNING_BROWSING_HISTORY,
426 IDS_EXTENSION_PROMPT_WARNING_TABS,
427 IDS_EXTENSION_PROMPT_WARNING_MANAGEMENT,
428 IDS_EXTENSION_PROMPT_WARNING_DEBUGGER,
429 IDS_EXTENSION_PROMPT_WARNING_1_HOST,
430 IDS_EXTENSION_PROMPT_WARNING_2_HOSTS,
431 IDS_EXTENSION_PROMPT_WARNING_3_HOSTS,
432 IDS_EXTENSION_PROMPT_WARNING_4_OR_MORE_HOSTS,
433 IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS,
434 IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS,
435 IDS_EXTENSION_PROMPT_WARNING_CLIPBOARD
436 };
437
438 //
439 // Extension 235 // Extension
440 // 236 //
441 237
442 // static 238 // static
443 scoped_refptr<Extension> Extension::Create(const FilePath& path, 239 scoped_refptr<Extension> Extension::Create(const FilePath& path,
444 Location location, 240 Location location,
445 const DictionaryValue& value, 241 const DictionaryValue& value,
446 int flags, 242 int flags,
447 std::string* error) { 243 std::string* error) {
448 scoped_refptr<Extension> extension = new Extension(path, location); 244 scoped_refptr<Extension> extension = new Extension(path, location);
(...skipping 29 matching lines...) Expand all
478 int loc2_rank = GetLocationRank(loc2); 274 int loc2_rank = GetLocationRank(loc2);
479 275
480 // If two different locations have the same rank, then we can not 276 // If two different locations have the same rank, then we can not
481 // deterministicly choose a location. 277 // deterministicly choose a location.
482 CHECK(loc1_rank != loc2_rank); 278 CHECK(loc1_rank != loc2_rank);
483 279
484 // Lowest rank has highest priority. 280 // Lowest rank has highest priority.
485 return (loc1_rank > loc2_rank ? loc1 : loc2 ); 281 return (loc1_rank > loc2_rank ? loc1 : loc2 );
486 } 282 }
487 283
488 // static 284 ExtensionPermissionMessages Extension::GetPermissionMessages() const {
489 Extension::PermissionMessage::MessageId Extension::GetPermissionMessageId( 285 return permission_set_->GetPermissionMessages();
490 const std::string& permission) {
491 return ExtensionConfig::GetInstance()->GetPermissionMessageId(permission);
492 }
493
494 Extension::PermissionMessages Extension::GetPermissionMessages() const {
495 PermissionMessages messages;
496 if (!plugins().empty()) {
497 messages.push_back(PermissionMessage::CreateFromMessageId(
498 PermissionMessage::ID_FULL_ACCESS));
499 return messages;
500 }
501
502 if (HasEffectiveAccessToAllHosts()) {
503 messages.push_back(PermissionMessage::CreateFromMessageId(
504 PermissionMessage::ID_HOSTS_ALL));
505 } else {
506 std::vector<std::string> hosts = GetDistinctHostsForDisplay(
507 GetEffectiveHostPermissions().patterns());
508 if (!hosts.empty())
509 messages.push_back(PermissionMessage::CreateFromHostList(hosts));
510 }
511
512 std::set<PermissionMessage> simple_msgs = GetSimplePermissionMessages();
513 messages.insert(messages.end(), simple_msgs.begin(), simple_msgs.end());
514
515 return messages;
516 } 286 }
517 287
518 std::vector<string16> Extension::GetPermissionMessageStrings() const { 288 std::vector<string16> Extension::GetPermissionMessageStrings() const {
519 std::vector<string16> messages; 289 return permission_set_->GetWarningMessages();
520 PermissionMessages permissions = GetPermissionMessages();
521 for (PermissionMessages::const_iterator i = permissions.begin();
522 i != permissions.end(); ++i)
523 messages.push_back(i->message());
524 return messages;
525 }
526
527 std::set<Extension::PermissionMessage>
528 Extension::GetSimplePermissionMessages() const {
529 std::set<PermissionMessage> messages;
530 std::set<std::string>::const_iterator i;
531 for (i = api_permissions().begin(); i != api_permissions().end(); ++i) {
532 PermissionMessage::MessageId message_id = GetPermissionMessageId(*i);
533 DCHECK_GT(PermissionMessage::ID_NONE, PermissionMessage::ID_UNKNOWN);
534 if (message_id > PermissionMessage::ID_NONE)
535 messages.insert(PermissionMessage::CreateFromMessageId(message_id));
536 }
537 return messages;
538 }
539
540 // static
541 std::vector<std::string> Extension::GetDistinctHostsForDisplay(
542 const URLPatternList& list) {
543 return GetDistinctHosts(list, true);
544 }
545
546 // static
547 bool Extension::IsElevatedHostList(
548 const URLPatternList& old_list, const URLPatternList& new_list) {
549 // TODO(jstritar): This is overly conservative with respect to subdomains.
550 // For example, going from *.google.com to www.google.com will be
551 // considered an elevation, even though it is not (http://crbug.com/65337).
552
553 std::vector<std::string> new_hosts = GetDistinctHosts(new_list, false);
554 std::vector<std::string> old_hosts = GetDistinctHosts(old_list, false);
555
556 std::set<std::string> old_hosts_set(old_hosts.begin(), old_hosts.end());
557 std::set<std::string> new_hosts_set(new_hosts.begin(), new_hosts.end());
558 std::set<std::string> new_hosts_only;
559
560 std::set_difference(new_hosts_set.begin(), new_hosts_set.end(),
561 old_hosts_set.begin(), old_hosts_set.end(),
562 std::inserter(new_hosts_only, new_hosts_only.begin()));
563
564 return !new_hosts_only.empty();
565 }
566
567 // Helper for GetDistinctHosts(): com > net > org > everything else.
568 static bool RcdBetterThan(const std::string& a, const std::string& b) {
569 if (a == b)
570 return false;
571 if (a == "com")
572 return true;
573 if (a == "net")
574 return b != "com";
575 if (a == "org")
576 return b != "com" && b != "net";
577 return false;
578 }
579
580 // static
581 std::vector<std::string> Extension::GetDistinctHosts(
582 const URLPatternList& host_patterns,
583 bool include_rcd) {
584 // Use a vector to preserve order (also faster than a map on small sets).
585 // Each item is a host split into two parts: host without RCDs and
586 // current best RCD.
587 typedef std::vector<std::pair<std::string, std::string> > HostVector;
588 HostVector hosts_best_rcd;
589 for (size_t i = 0; i < host_patterns.size(); ++i) {
590 std::string host = host_patterns[i].host();
591
592 // Add the subdomain wildcard back to the host, if necessary.
593 if (host_patterns[i].match_subdomains())
594 host = "*." + host;
595
596 // If the host has an RCD, split it off so we can detect duplicates.
597 std::string rcd;
598 size_t reg_len = net::RegistryControlledDomainService::GetRegistryLength(
599 host, false);
600 if (reg_len && reg_len != std::string::npos) {
601 if (include_rcd) // else leave rcd empty
602 rcd = host.substr(host.size() - reg_len);
603 host = host.substr(0, host.size() - reg_len);
604 }
605
606 // Check if we've already seen this host.
607 HostVector::iterator it = hosts_best_rcd.begin();
608 for (; it != hosts_best_rcd.end(); ++it) {
609 if (it->first == host)
610 break;
611 }
612 // If this host was found, replace the RCD if this one is better.
613 if (it != hosts_best_rcd.end()) {
614 if (include_rcd && RcdBetterThan(rcd, it->second))
615 it->second = rcd;
616 } else { // Previously unseen host, append it.
617 hosts_best_rcd.push_back(std::make_pair(host, rcd));
618 }
619 }
620
621 // Build up the final vector by concatenating hosts and RCDs.
622 std::vector<std::string> distinct_hosts;
623 for (HostVector::iterator it = hosts_best_rcd.begin();
624 it != hosts_best_rcd.end(); ++it)
625 distinct_hosts.push_back(it->first + it->second);
626 return distinct_hosts;
627 } 290 }
628 291
629 FilePath Extension::MaybeNormalizePath(const FilePath& path) { 292 FilePath Extension::MaybeNormalizePath(const FilePath& path) {
630 #if defined(OS_WIN) 293 #if defined(OS_WIN)
631 // Normalize any drive letter to upper-case. We do this for consistency with 294 // Normalize any drive letter to upper-case. We do this for consistency with
632 // net_utils::FilePathToFileURL(), which does the same thing, to make string 295 // net_utils::FilePathToFileURL(), which does the same thing, to make string
633 // comparisons simpler. 296 // comparisons simpler.
634 std::wstring path_str = path.value(); 297 std::wstring path_str = path.value();
635 if (path_str.size() >= 2 && path_str[0] >= L'a' && path_str[0] <= L'z' && 298 if (path_str.size() >= 2 && path_str[0] >= L'a' && path_str[0] <= L'z' &&
636 path_str[1] == ':') 299 path_str[1] == ':')
637 path_str[0] += ('A' - 'a'); 300 path_str[0] += ('A' - 'a');
638 301
639 return FilePath(path_str); 302 return FilePath(path_str);
640 #else 303 #else
641 return path; 304 return path;
642 #endif 305 #endif
643 } 306 }
644 307
645 // static
646 bool Extension::IsHostedAppPermission(const std::string& str) {
647 for (size_t i = 0; i < Extension::kNumHostedAppPermissions; ++i) {
648 if (str == Extension::kHostedAppPermissionNames[i]) {
649 return true;
650 }
651 }
652 return false;
653 }
654
655 const std::string Extension::VersionString() const { 308 const std::string Extension::VersionString() const {
656 return version()->GetString(); 309 return version()->GetString();
657 } 310 }
658 311
659 // static 312 // static
660 bool Extension::IsExtension(const FilePath& file_name) { 313 bool Extension::IsExtension(const FilePath& file_name) {
661 return file_name.MatchesExtension(chrome::kExtensionFileExtension); 314 return file_name.MatchesExtension(chrome::kExtensionFileExtension);
662 } 315 }
663 316
664 // static 317 // static
(...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after
1611 output->append(" "); 1264 output->append(" ");
1612 output->append(is_public ? kPublic : kPrivate); 1265 output->append(is_public ? kPublic : kPrivate);
1613 output->append(" "); 1266 output->append(" ");
1614 output->append(kKeyInfoEndMarker); 1267 output->append(kKeyInfoEndMarker);
1615 output->append("\n"); 1268 output->append("\n");
1616 1269
1617 return true; 1270 return true;
1618 } 1271 }
1619 1272
1620 // static 1273 // static
1621 bool Extension::IsPrivilegeIncrease(const bool granted_full_access,
1622 const std::set<std::string>& granted_apis,
1623 const URLPatternSet& granted_extent,
1624 const Extension* new_extension) {
1625 // If the extension had native code access, we don't need to go any further.
1626 // Things can't get any worse.
1627 if (granted_full_access)
1628 return false;
1629
1630 // Otherwise, if the new extension has a plugin, it's a privilege increase.
1631 if (new_extension->HasFullPermissions())
1632 return true;
1633
1634 // If the extension hadn't been granted access to all hosts in the past, then
1635 // see if the extension requires more host permissions.
1636 if (!HasEffectiveAccessToAllHosts(granted_extent, granted_apis)) {
1637 if (new_extension->HasEffectiveAccessToAllHosts())
1638 return true;
1639
1640 const URLPatternSet new_extent =
1641 new_extension->GetEffectiveHostPermissions();
1642
1643 if (IsElevatedHostList(granted_extent.patterns(), new_extent.patterns()))
1644 return true;
1645 }
1646
1647 std::set<std::string> new_apis = new_extension->api_permissions();
1648 std::set<std::string> new_apis_only;
1649 std::set_difference(new_apis.begin(), new_apis.end(),
1650 granted_apis.begin(), granted_apis.end(),
1651 std::inserter(new_apis_only, new_apis_only.begin()));
1652
1653 // Ignore API permissions that don't require user approval when deciding if
1654 // an extension has increased its privileges.
1655 size_t new_api_count = 0;
1656 for (std::set<std::string>::iterator i = new_apis_only.begin();
1657 i != new_apis_only.end(); ++i) {
1658 DCHECK_GT(PermissionMessage::ID_NONE, PermissionMessage::ID_UNKNOWN);
1659 if (GetPermissionMessageId(*i) > PermissionMessage::ID_NONE)
1660 new_api_count++;
1661 }
1662
1663 if (new_api_count)
1664 return true;
1665
1666 return false;
1667 }
1668
1669 // static
1670 void Extension::DecodeIcon(const Extension* extension, 1274 void Extension::DecodeIcon(const Extension* extension,
1671 Icons icon_size, 1275 Icons icon_size,
1672 scoped_ptr<SkBitmap>* result) { 1276 scoped_ptr<SkBitmap>* result) {
1673 FilePath icon_path = extension->GetIconResource( 1277 FilePath icon_path = extension->GetIconResource(
1674 icon_size, ExtensionIconSet::MATCH_EXACTLY).GetFilePath(); 1278 icon_size, ExtensionIconSet::MATCH_EXACTLY).GetFilePath();
1675 DecodeIconFromPath(icon_path, icon_size, result); 1279 DecodeIconFromPath(icon_path, icon_size, result);
1676 } 1280 }
1677 1281
1678 // static 1282 // static
1679 void Extension::DecodeIconFromPath(const FilePath& icon_path, 1283 void Extension::DecodeIconFromPath(const FilePath& icon_path,
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1726 chrome::kStandardSchemeSeparator + extension_id + "/"); 1330 chrome::kStandardSchemeSeparator + extension_id + "/");
1727 } 1331 }
1728 1332
1729 bool Extension::InitFromValue(const DictionaryValue& source, int flags, 1333 bool Extension::InitFromValue(const DictionaryValue& source, int flags,
1730 std::string* error) { 1334 std::string* error) {
1731 // When strict error checks are enabled, make URL pattern parsing strict. 1335 // When strict error checks are enabled, make URL pattern parsing strict.
1732 URLPattern::ParseOption parse_strictness = 1336 URLPattern::ParseOption parse_strictness =
1733 (flags & STRICT_ERROR_CHECKS ? URLPattern::PARSE_STRICT 1337 (flags & STRICT_ERROR_CHECKS ? URLPattern::PARSE_STRICT
1734 : URLPattern::PARSE_LENIENT); 1338 : URLPattern::PARSE_LENIENT);
1735 1339
1340 // Initialize permissions with an empty, default permission set.
1341 permission_set_.reset(new ExtensionPermissionSet());
1342
1736 if (source.HasKey(keys::kPublicKey)) { 1343 if (source.HasKey(keys::kPublicKey)) {
1737 std::string public_key_bytes; 1344 std::string public_key_bytes;
1738 if (!source.GetString(keys::kPublicKey, 1345 if (!source.GetString(keys::kPublicKey,
1739 &public_key_) || 1346 &public_key_) ||
1740 !ParsePEMKeyBytes(public_key_, 1347 !ParsePEMKeyBytes(public_key_,
1741 &public_key_bytes) || 1348 &public_key_bytes) ||
1742 !GenerateId(public_key_bytes, &id_)) { 1349 !GenerateId(public_key_bytes, &id_)) {
1743 *error = errors::kInvalidKey; 1350 *error = errors::kInvalidKey;
1744 return false; 1351 return false;
1745 } 1352 }
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
2244 return false; 1851 return false;
2245 } 1852 }
2246 options_url_ = GetResourceURL(options_str); 1853 options_url_ = GetResourceURL(options_str);
2247 if (!options_url_.is_valid()) { 1854 if (!options_url_.is_valid()) {
2248 *error = errors::kInvalidOptionsPage; 1855 *error = errors::kInvalidOptionsPage;
2249 return false; 1856 return false;
2250 } 1857 }
2251 } 1858 }
2252 } 1859 }
2253 1860
1861 std::set<ExtensionAPIPermission> api_permissions;
1862 URLPatternList host_permissions;
1863
2254 // Initialize the permissions (optional). 1864 // Initialize the permissions (optional).
2255 if (source.HasKey(keys::kPermissions)) { 1865 if (source.HasKey(keys::kPermissions)) {
2256 ListValue* permissions = NULL; 1866 ListValue* permissions = NULL;
2257 if (!source.GetList(keys::kPermissions, &permissions)) { 1867 if (!source.GetList(keys::kPermissions, &permissions)) {
2258 *error = ExtensionErrorUtils::FormatErrorMessage( 1868 *error = ExtensionErrorUtils::FormatErrorMessage(
2259 errors::kInvalidPermissions, ""); 1869 errors::kInvalidPermissions, "");
2260 return false; 1870 return false;
2261 } 1871 }
2262 1872
2263 for (size_t i = 0; i < permissions->GetSize(); ++i) { 1873 for (size_t i = 0; i < permissions->GetSize(); ++i) {
2264 std::string permission_str; 1874 std::string permission_str;
2265 if (!permissions->GetString(i, &permission_str)) { 1875 if (!permissions->GetString(i, &permission_str)) {
2266 *error = ExtensionErrorUtils::FormatErrorMessage( 1876 *error = ExtensionErrorUtils::FormatErrorMessage(
2267 errors::kInvalidPermission, base::IntToString(i)); 1877 errors::kInvalidPermission, base::IntToString(i));
2268 return false; 1878 return false;
2269 } 1879 }
2270 1880
1881 ExtensionAPIPermission* permission =
1882 ExtensionAPIPermission::GetByName(permission_str);
1883
2271 // Only COMPONENT extensions can use private APIs. 1884 // Only COMPONENT extensions can use private APIs.
2272 // TODO(asargent) - We want a more general purpose mechanism for this, 1885 // TODO(asargent) - We want a more general purpose mechanism for this,
2273 // and better error messages. (http://crbug.com/54013) 1886 // and better error messages. (http://crbug.com/54013)
2274 if (!IsComponentOnlyPermission(permission_str) 1887 if (!IsComponentOnlyPermission(permission_str)
2275 #ifndef NDEBUG 1888 #ifndef NDEBUG
2276 && !CommandLine::ForCurrentProcess()->HasSwitch( 1889 && !CommandLine::ForCurrentProcess()->HasSwitch(
2277 switches::kExposePrivateExtensionApi) 1890 switches::kExposePrivateExtensionApi)
2278 #endif 1891 #endif
2279 ) { 1892 ) {
2280 continue; 1893 continue;
2281 } 1894 }
2282 1895
2283 // Remap the old unlimited storage permission name.
2284 if (permission_str == kOldUnlimitedStoragePermission)
2285 permission_str = kUnlimitedStoragePermission;
2286
2287 if (web_extent().is_empty() || location() == Extension::COMPONENT) { 1896 if (web_extent().is_empty() || location() == Extension::COMPONENT) {
2288 // Check if it's a module permission. If so, enable that permission. 1897 // Check if it's a module permission. If so, enable that permission.
2289 if (IsAPIPermission(permission_str)) { 1898 if (permission != NULL) {
2290 // Only allow the experimental API permission if the command line 1899 // Only allow the experimental API permission if the command line
2291 // flag is present, or if the extension is a component of Chrome. 1900 // flag is present, or if the extension is a component of Chrome.
2292 if (IsDisallowedExperimentalPermission(permission_str) && 1901 if (IsDisallowedExperimentalPermission(permission) &&
2293 location() != Extension::COMPONENT) { 1902 location() != Extension::COMPONENT) {
2294 *error = errors::kExperimentalFlagRequired; 1903 *error = errors::kExperimentalFlagRequired;
2295 return false; 1904 return false;
2296 } 1905 }
2297 api_permissions_.insert(permission_str); 1906 api_permissions.insert(*permission);
2298 continue; 1907 continue;
2299 } 1908 }
2300 } else { 1909 } else {
2301 // Hosted apps only get access to a subset of the valid permissions. 1910 // Hosted apps only get access to a subset of the valid permissions.
2302 if (IsHostedAppPermission(permission_str)) { 1911 if (permission != NULL && permission->is_hosted_app()) {
2303 if (IsDisallowedExperimentalPermission(permission_str)) { 1912 if (IsDisallowedExperimentalPermission(permission)) {
2304 *error = errors::kExperimentalFlagRequired; 1913 *error = errors::kExperimentalFlagRequired;
2305 return false; 1914 return false;
2306 } 1915 }
2307 api_permissions_.insert(permission_str); 1916 api_permissions.insert(*permission);
2308 continue; 1917 continue;
2309 } 1918 }
2310 } 1919 }
2311 1920
2312 // Check if it's a host pattern permission. 1921 // Check if it's a host pattern permission.
2313 URLPattern pattern = URLPattern(CanExecuteScriptEverywhere() ? 1922 URLPattern pattern = URLPattern(CanExecuteScriptEverywhere() ?
2314 URLPattern::SCHEME_ALL : kValidHostPermissionSchemes); 1923 URLPattern::SCHEME_ALL : kValidHostPermissionSchemes);
2315 1924
2316 URLPattern::ParseResult parse_result = pattern.Parse(permission_str, 1925 URLPattern::ParseResult parse_result = pattern.Parse(permission_str,
2317 parse_strictness); 1926 parse_strictness);
2318 if (parse_result == URLPattern::PARSE_SUCCESS) { 1927 if (parse_result == URLPattern::PARSE_SUCCESS) {
2319 if (!CanSpecifyHostPermission(pattern)) { 1928 if (!CanSpecifyHostPermission(pattern)) {
2320 *error = ExtensionErrorUtils::FormatErrorMessage( 1929 *error = ExtensionErrorUtils::FormatErrorMessage(
2321 errors::kInvalidPermissionScheme, base::IntToString(i)); 1930 errors::kInvalidPermissionScheme, base::IntToString(i));
2322 return false; 1931 return false;
2323 } 1932 }
2324 1933
2325 // The path component is not used for host permissions, so we force it 1934 // The path component is not used for host permissions, so we force it
2326 // to match all paths. 1935 // to match all paths.
2327 pattern.SetPath("/*"); 1936 pattern.SetPath("/*");
2328 1937
2329 if (pattern.MatchesScheme(chrome::kFileScheme) && 1938 if (pattern.MatchesScheme(chrome::kFileScheme) &&
2330 !CanExecuteScriptEverywhere()) { 1939 !CanExecuteScriptEverywhere()) {
2331 wants_file_access_ = true; 1940 wants_file_access_ = true;
2332 if (!(flags & ALLOW_FILE_ACCESS)) 1941 if (!(flags & ALLOW_FILE_ACCESS))
2333 pattern.set_valid_schemes( 1942 pattern.set_valid_schemes(
2334 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE); 1943 pattern.valid_schemes() & ~URLPattern::SCHEME_FILE);
2335 } 1944 }
2336 1945
1946 host_permissions.push_back(pattern);
2337 host_permissions_.push_back(pattern); 1947 host_permissions_.push_back(pattern);
2338 } 1948 }
2339 1949
2340 // If it's not a host permission, then it's probably an unknown API 1950 // If it's not a host permission, then it's probably an unknown API
2341 // permission. Do not throw an error so extensions can retain 1951 // permission. Do not throw an error so extensions can retain
2342 // backwards compatability (http://crbug.com/42742). 1952 // backwards compatability (http://crbug.com/42742).
2343 // TODO(jstritar): We can improve error messages by adding better 1953 // TODO(jstritar): We can improve error messages by adding better
2344 // validation of API permissions here. 1954 // validation of API permissions here.
2345 // TODO(skerner): Consider showing the reason |permission_str| is not 1955 // TODO(skerner): Consider showing the reason |permission_str| is not
2346 // a valid URL pattern if it is almost valid. For example, if it has 1956 // a valid URL pattern if it is almost valid. For example, if it has
2347 // a valid scheme, and failed to parse because it has a port, show an 1957 // a valid scheme, and failed to parse because it has a port, show an
2348 // error. 1958 // error.
2349 } 1959 }
2350 } 1960 }
2351 1961
2352 // Initialize background url (optional). 1962 // Initialize background url (optional).
2353 if (source.HasKey(keys::kBackground)) { 1963 if (source.HasKey(keys::kBackground)) {
2354 std::string background_str; 1964 std::string background_str;
2355 if (!source.GetString(keys::kBackground, &background_str)) { 1965 if (!source.GetString(keys::kBackground, &background_str)) {
2356 *error = errors::kInvalidBackground; 1966 *error = errors::kInvalidBackground;
2357 return false; 1967 return false;
2358 } 1968 }
2359 1969
2360 if (is_hosted_app()) { 1970 if (is_hosted_app()) {
2361 // Make sure "background" permission is set. 1971 // Make sure "background" permission is set.
2362 if (api_permissions_.find(kBackgroundPermission) == 1972 if (!api_permissions.count(ExtensionAPIPermission::Background())) {
2363 api_permissions_.end()) {
2364 *error = errors::kBackgroundPermissionNeeded; 1973 *error = errors::kBackgroundPermissionNeeded;
2365 return false; 1974 return false;
2366 } 1975 }
2367 // Hosted apps require an absolute URL. 1976 // Hosted apps require an absolute URL.
2368 GURL bg_page(background_str); 1977 GURL bg_page(background_str);
2369 if (!bg_page.is_valid()) { 1978 if (!bg_page.is_valid()) {
2370 *error = errors::kInvalidBackgroundInHostedApp; 1979 *error = errors::kInvalidBackgroundInHostedApp;
2371 return false; 1980 return false;
2372 } 1981 }
2373 1982
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
2592 content_security_policy_ = content_security_policy; 2201 content_security_policy_ = content_security_policy;
2593 } 2202 }
2594 2203
2595 // Initialize devtools page url (optional). 2204 // Initialize devtools page url (optional).
2596 if (source.HasKey(keys::kDevToolsPage)) { 2205 if (source.HasKey(keys::kDevToolsPage)) {
2597 std::string devtools_str; 2206 std::string devtools_str;
2598 if (!source.GetString(keys::kDevToolsPage, &devtools_str)) { 2207 if (!source.GetString(keys::kDevToolsPage, &devtools_str)) {
2599 *error = errors::kInvalidDevToolsPage; 2208 *error = errors::kInvalidDevToolsPage;
2600 return false; 2209 return false;
2601 } 2210 }
2602 if (!HasApiPermission(Extension::kExperimentalPermission)) { 2211 if (!api_permissions.count(ExtensionAPIPermission::Experimental())) {
2603 *error = errors::kDevToolsExperimental; 2212 *error = errors::kDevToolsExperimental;
2604 return false; 2213 return false;
2605 } 2214 }
2606 devtools_url_ = GetResourceURL(devtools_str); 2215 devtools_url_ = GetResourceURL(devtools_str);
2607 } 2216 }
2608 2217
2609 // Initialize sidebar action (optional). 2218 // Initialize sidebar action (optional).
2610 if (source.HasKey(keys::kSidebar)) { 2219 if (source.HasKey(keys::kSidebar)) {
2611 DictionaryValue* sidebar_value = NULL; 2220 DictionaryValue* sidebar_value = NULL;
2612 if (!source.GetDictionary(keys::kSidebar, &sidebar_value)) { 2221 if (!source.GetDictionary(keys::kSidebar, &sidebar_value)) {
2613 *error = errors::kInvalidSidebar; 2222 *error = errors::kInvalidSidebar;
2614 return false; 2223 return false;
2615 } 2224 }
2616 if (!HasApiPermission(Extension::kExperimentalPermission)) { 2225 if (!api_permissions.count(ExtensionAPIPermission::Experimental())) {
2617 *error = errors::kSidebarExperimental; 2226 *error = errors::kSidebarExperimental;
2618 return false; 2227 return false;
2619 } 2228 }
2620 sidebar_defaults_.reset(LoadExtensionSidebarDefaults(sidebar_value, error)); 2229 sidebar_defaults_.reset(LoadExtensionSidebarDefaults(sidebar_value, error));
2621 if (!sidebar_defaults_.get()) 2230 if (!sidebar_defaults_.get())
2622 return false; // Failed to parse sidebar definition. 2231 return false; // Failed to parse sidebar definition.
2623 } 2232 }
2624 2233
2625 // Initialize text-to-speech voices (optional). 2234 // Initialize text-to-speech voices (optional).
2626 if (source.HasKey(keys::kTts)) { 2235 if (source.HasKey(keys::kTts)) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2692 *error = errors::kInvalidIncognitoBehavior; 2301 *error = errors::kInvalidIncognitoBehavior;
2693 return false; 2302 return false;
2694 } 2303 }
2695 } 2304 }
2696 2305
2697 if (HasMultipleUISurfaces()) { 2306 if (HasMultipleUISurfaces()) {
2698 *error = errors::kOneUISurfaceOnly; 2307 *error = errors::kOneUISurfaceOnly;
2699 return false; 2308 return false;
2700 } 2309 }
2701 2310
2702 InitEffectiveHostPermissions(); 2311 permission_set_.reset(
2312 new ExtensionPermissionSet(this, api_permissions, host_permissions));
2703 2313
2704 // Although |source| is passed in as a const, it's still possible to modify 2314 // Although |source| is passed in as a const, it's still possible to modify
2705 // it. This is dangerous since the utility process re-uses |source| after 2315 // it. This is dangerous since the utility process re-uses |source| after
2706 // it calls InitFromValue, passing it up to the browser process which calls 2316 // it calls InitFromValue, passing it up to the browser process which calls
2707 // InitFromValue again. As a result, we need to make sure that nobody 2317 // InitFromValue again. As a result, we need to make sure that nobody
2708 // accidentally modifies it. 2318 // accidentally modifies it.
2709 DCHECK(source.Equals(manifest_value_.get())); 2319 DCHECK(source.Equals(manifest_value_.get()));
2710 2320
2711 return true; 2321 return true;
2712 } 2322 }
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
2883 // Only allow access to chrome://favicon to regular extensions. Component 2493 // Only allow access to chrome://favicon to regular extensions. Component
2884 // extensions can have access to all of chrome://*. 2494 // extensions can have access to all of chrome://*.
2885 return (pattern.host() == chrome::kChromeUIFaviconHost || 2495 return (pattern.host() == chrome::kChromeUIFaviconHost ||
2886 CanExecuteScriptEverywhere()); 2496 CanExecuteScriptEverywhere());
2887 } 2497 }
2888 2498
2889 // Otherwise, the valid schemes were handled by URLPattern. 2499 // Otherwise, the valid schemes were handled by URLPattern.
2890 return true; 2500 return true;
2891 } 2501 }
2892 2502
2893 // static
2894 bool Extension::HasApiPermission( 2503 bool Extension::HasApiPermission(
jstritar 2011/06/09 21:12:57 I kept many of these methods (and forward them to
2895 const std::set<std::string>& api_permissions, 2504 const ExtensionAPIPermission& api) const {
2896 const std::string& function_name) { 2505 return permission_set_->HasAPIPermission(api);
2897 std::string permission_name = function_name; 2506 }
2898 2507
2899 for (size_t i = 0; i < kNumNonPermissionFunctionNames; ++i) { 2508 bool Extension::HasApiPermission(
2900 if (permission_name == kNonPermissionFunctionNames[i]) 2509 const std::string& function_name) const {
2901 return true; 2510 return permission_set_->HasAccessToFunction(function_name);
2902 } 2511 }
2903 2512
2904 // See if this is a function or event name first and strip out the package. 2513 const URLPatternSet& Extension::GetEffectiveHostPermissions() const {
2905 // Functions will be of the form package.function 2514 return permission_set_->effective_hosts();
2906 // Events will be of the form package/id or package.optional.stuff
2907 size_t separator = function_name.find_first_of("./");
2908 if (separator != std::string::npos)
2909 permission_name = function_name.substr(0, separator);
2910
2911 // windows and tabs are the same permission.
2912 if (permission_name == kWindowPermission)
2913 permission_name = Extension::kTabPermission;
2914
2915 if (api_permissions.count(permission_name))
2916 return true;
2917
2918 for (size_t i = 0; i < kNumNonPermissionModuleNames; ++i) {
2919 if (permission_name == kNonPermissionModuleNames[i]) {
2920 return true;
2921 }
2922 }
2923
2924 return false;
2925 } 2515 }
2926 2516
2927 bool Extension::HasHostPermission(const GURL& url) const { 2517 bool Extension::HasHostPermission(const GURL& url) const {
2928 for (URLPatternList::const_iterator host = host_permissions().begin(); 2518 for (URLPatternList::const_iterator host = host_permissions().begin();
2929 host != host_permissions().end(); ++host) { 2519 host != host_permissions().end(); ++host) {
2930 // Non-component extensions can only access chrome://favicon and no other 2520 // Non-component extensions can only access chrome://favicon and no other
2931 // chrome:// scheme urls. 2521 // chrome:// scheme urls.
2932 if (url.SchemeIs(chrome::kChromeUIScheme) && 2522 if (url.SchemeIs(chrome::kChromeUIScheme) &&
2933 url.host() != chrome::kChromeUIFaviconHost && 2523 url.host() != chrome::kChromeUIFaviconHost &&
2934 location() != Extension::COMPONENT) 2524 location() != Extension::COMPONENT)
2935 return false; 2525 return false;
2936 2526
2937 if (host->MatchesURL(url)) 2527 if (host->MatchesURL(url))
2938 return true; 2528 return true;
2939 } 2529 }
2940 return false; 2530 return false;
2941 } 2531 }
2942 2532
2943 void Extension::InitEffectiveHostPermissions() {
2944 // Some APIs effectively grant access to every site. New ones should be
2945 // added here. (I'm looking at you, network API)
2946 if (HasApiPermission(api_permissions_, kProxyPermission) ||
2947 !devtools_url_.is_empty()) {
2948 URLPattern all_urls(URLPattern::SCHEME_ALL);
2949 all_urls.set_match_all_urls(true);
2950 effective_host_permissions_.AddPattern(all_urls);
2951 return;
2952 }
2953
2954 for (URLPatternList::const_iterator host = host_permissions().begin();
2955 host != host_permissions().end(); ++host)
2956 effective_host_permissions_.AddPattern(*host);
2957
2958 for (UserScriptList::const_iterator content_script =
2959 content_scripts().begin();
2960 content_script != content_scripts().end(); ++content_script) {
2961 URLPatternList::const_iterator pattern =
2962 content_script->url_patterns().begin();
2963 for (; pattern != content_script->url_patterns().end(); ++pattern)
2964 effective_host_permissions_.AddPattern(*pattern);
2965 }
2966 }
2967
2968 bool Extension::IsComponentOnlyPermission(const std::string& permission) const { 2533 bool Extension::IsComponentOnlyPermission(const std::string& permission) const {
2969 if (location() == Extension::COMPONENT) 2534 if (location() == Extension::COMPONENT)
2970 return true; 2535 return true;
2971 2536
2972 // Non-component extensions are not allowed to access private apis. 2537 // Non-component extensions are not allowed to access private apis.
2973 for (size_t i = 0; i < Extension::kNumComponentPrivatePermissions; ++i) { 2538 for (size_t i = 0; i < Extension::kNumComponentPrivatePermissions; ++i) {
2974 if (permission == Extension::kComponentPrivatePermissionNames[i]) 2539 if (permission == Extension::kComponentPrivatePermissionNames[i])
2975 return false; 2540 return false;
2976 } 2541 }
2977 return true; 2542 return true;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3025 } 2590 }
3026 2591
3027 if (error) { 2592 if (error) {
3028 *error = ExtensionErrorUtils::FormatErrorMessage(errors::kCannotAccessPage, 2593 *error = ExtensionErrorUtils::FormatErrorMessage(errors::kCannotAccessPage,
3029 page_url.spec()); 2594 page_url.spec());
3030 } 2595 }
3031 2596
3032 return false; 2597 return false;
3033 } 2598 }
3034 2599
3035 // static
3036 bool Extension::HasEffectiveAccessToAllHosts(
3037 const URLPatternSet& effective_host_permissions,
3038 const std::set<std::string>& api_permissions) {
3039 const URLPatternList patterns = effective_host_permissions.patterns();
3040 for (URLPatternList::const_iterator host = patterns.begin();
3041 host != patterns.end(); ++host) {
3042 if (host->match_all_urls() ||
3043 (host->match_subdomains() && host->host().empty()))
3044 return true;
3045 }
3046
3047 return false;
3048 }
3049
3050 bool Extension::HasEffectiveAccessToAllHosts() const { 2600 bool Extension::HasEffectiveAccessToAllHosts() const {
3051 return HasEffectiveAccessToAllHosts(GetEffectiveHostPermissions(), 2601 return permission_set_->HasEffectiveAccessToAllHosts();
3052 api_permissions());
3053 } 2602 }
3054 2603
3055 bool Extension::HasFullPermissions() const { 2604 bool Extension::HasFullPermissions() const {
3056 return !plugins().empty(); 2605 return permission_set_->native_code();
3057 } 2606 }
3058 2607
3059 bool Extension::ShowConfigureContextMenus() const { 2608 bool Extension::ShowConfigureContextMenus() const {
3060 // Don't show context menu for component extensions. We might want to show 2609 // Don't show context menu for component extensions. We might want to show
3061 // options for component extension button but now there is no component 2610 // options for component extension button but now there is no component
3062 // extension with options. All other menu items like uninstall have 2611 // extension with options. All other menu items like uninstall have
3063 // no sense for component extensions. 2612 // no sense for component extensions.
3064 return location() != Extension::COMPONENT; 2613 return location() != Extension::COMPONENT;
3065 } 2614 }
3066 2615
3067 bool Extension::IsDisallowedExperimentalPermission( 2616 bool Extension::IsDisallowedExperimentalPermission(
3068 const std::string& permission_str) const { 2617 ExtensionAPIPermission* permission) const {
3069 return permission_str == Extension::kExperimentalPermission && 2618 CHECK(permission);
2619 return *permission == ExtensionAPIPermission::Experimental() &&
3070 !CommandLine::ForCurrentProcess()->HasSwitch( 2620 !CommandLine::ForCurrentProcess()->HasSwitch(
3071 switches::kEnableExperimentalExtensionApis); 2621 switches::kEnableExperimentalExtensionApis);
3072 } 2622 }
3073 2623
3074 bool Extension::IsAPIPermission(const std::string& str) const {
3075 for (size_t i = 0; i < Extension::kNumPermissions; ++i) {
3076 if (str == Extension::kPermissions[i].name) {
3077 return true;
3078 }
3079 }
3080 return false;
3081 }
3082
3083 bool Extension::CanExecuteScriptEverywhere() const { 2624 bool Extension::CanExecuteScriptEverywhere() const {
3084 if (location() == Extension::COMPONENT 2625 if (location() == Extension::COMPONENT
3085 #ifndef NDEBUG 2626 #ifndef NDEBUG
3086 || CommandLine::ForCurrentProcess()->HasSwitch( 2627 || CommandLine::ForCurrentProcess()->HasSwitch(
3087 switches::kExposePrivateExtensionApi) 2628 switches::kExposePrivateExtensionApi)
3088 #endif 2629 #endif
3089 ) 2630 )
3090 return true; 2631 return true;
3091 2632
3092 ScriptingWhitelist* whitelist = 2633 ScriptingWhitelist* whitelist =
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
3148 extension_location(location) { 2689 extension_location(location) {
3149 if (manifest) 2690 if (manifest)
3150 extension_manifest.reset(manifest->DeepCopy()); 2691 extension_manifest.reset(manifest->DeepCopy());
3151 } 2692 }
3152 2693
3153 ExtensionInfo::~ExtensionInfo() {} 2694 ExtensionInfo::~ExtensionInfo() {}
3154 2695
3155 UninstalledExtensionInfo::UninstalledExtensionInfo( 2696 UninstalledExtensionInfo::UninstalledExtensionInfo(
3156 const Extension& extension) 2697 const Extension& extension)
3157 : extension_id(extension.id()), 2698 : extension_id(extension.id()),
3158 extension_api_permissions(extension.api_permissions()), 2699 extension_api_permissions(extension.permission_set().GetAPIsAsStrings()),
3159 extension_type(extension.GetType()), 2700 extension_type(extension.GetType()),
3160 update_url(extension.update_url()) {} 2701 update_url(extension.update_url()) {}
3161 2702
3162 UninstalledExtensionInfo::~UninstalledExtensionInfo() {} 2703 UninstalledExtensionInfo::~UninstalledExtensionInfo() {}
3163 2704
3164 2705
3165 UnloadedExtensionInfo::UnloadedExtensionInfo( 2706 UnloadedExtensionInfo::UnloadedExtensionInfo(
3166 const Extension* extension, 2707 const Extension* extension,
3167 Reason reason) 2708 Reason reason)
3168 : reason(reason), 2709 : reason(reason),
3169 already_disabled(false), 2710 already_disabled(false),
3170 extension(extension) {} 2711 extension(extension) {}
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698