| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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/permissions/permissions_data.h" | 5 #include "extensions/common/permissions/permissions_data.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "content/public/common/url_constants.h" | 8 #include "content/public/common/url_constants.h" |
| 9 #include "extensions/common/constants.h" | 9 #include "extensions/common/constants.h" |
| 10 #include "extensions/common/error_utils.h" | 10 #include "extensions/common/error_utils.h" |
| (...skipping 25 matching lines...) Expand all Loading... |
| 36 PermissionsData::PermissionsData(const Extension* extension) | 36 PermissionsData::PermissionsData(const Extension* extension) |
| 37 : extension_id_(extension->id()), manifest_type_(extension->GetType()) { | 37 : extension_id_(extension->id()), manifest_type_(extension->GetType()) { |
| 38 base::AutoLock auto_lock(runtime_lock_); | 38 base::AutoLock auto_lock(runtime_lock_); |
| 39 scoped_refptr<const PermissionSet> required_permissions = | 39 scoped_refptr<const PermissionSet> required_permissions = |
| 40 PermissionsParser::GetRequiredPermissions(extension); | 40 PermissionsParser::GetRequiredPermissions(extension); |
| 41 active_permissions_unsafe_ = | 41 active_permissions_unsafe_ = |
| 42 new PermissionSet(required_permissions->apis(), | 42 new PermissionSet(required_permissions->apis(), |
| 43 required_permissions->manifest_permissions(), | 43 required_permissions->manifest_permissions(), |
| 44 required_permissions->explicit_hosts(), | 44 required_permissions->explicit_hosts(), |
| 45 required_permissions->scriptable_hosts()); | 45 required_permissions->scriptable_hosts()); |
| 46 withheld_permissions_unsafe_ = new PermissionSet(); |
| 46 } | 47 } |
| 47 | 48 |
| 48 PermissionsData::~PermissionsData() { | 49 PermissionsData::~PermissionsData() { |
| 49 } | 50 } |
| 50 | 51 |
| 51 // static | 52 // static |
| 52 void PermissionsData::SetPolicyDelegate(PolicyDelegate* delegate) { | 53 void PermissionsData::SetPolicyDelegate(PolicyDelegate* delegate) { |
| 53 g_policy_delegate = delegate; | 54 g_policy_delegate = delegate; |
| 54 } | 55 } |
| 55 | 56 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 top_frame_url.host() != extension->id() && | 107 top_frame_url.host() != extension->id() && |
| 107 !allow_on_chrome_urls) { | 108 !allow_on_chrome_urls) { |
| 108 if (error) | 109 if (error) |
| 109 *error = manifest_errors::kCannotAccessExtensionUrl; | 110 *error = manifest_errors::kCannotAccessExtensionUrl; |
| 110 return true; | 111 return true; |
| 111 } | 112 } |
| 112 | 113 |
| 113 return false; | 114 return false; |
| 114 } | 115 } |
| 115 | 116 |
| 116 void PermissionsData::SetActivePermissions( | 117 void PermissionsData::SetPermissions( |
| 117 const PermissionSet* permissions) const { | 118 const scoped_refptr<const PermissionSet>& active, |
| 119 const scoped_refptr<const PermissionSet>& withheld) const { |
| 118 base::AutoLock auto_lock(runtime_lock_); | 120 base::AutoLock auto_lock(runtime_lock_); |
| 119 active_permissions_unsafe_ = permissions; | 121 active_permissions_unsafe_ = active; |
| 122 withheld_permissions_unsafe_ = withheld; |
| 120 } | 123 } |
| 121 | 124 |
| 122 void PermissionsData::UpdateTabSpecificPermissions( | 125 void PermissionsData::UpdateTabSpecificPermissions( |
| 123 int tab_id, | 126 int tab_id, |
| 124 scoped_refptr<const PermissionSet> permissions) const { | 127 scoped_refptr<const PermissionSet> permissions) const { |
| 125 base::AutoLock auto_lock(runtime_lock_); | 128 base::AutoLock auto_lock(runtime_lock_); |
| 126 CHECK_GE(tab_id, 0); | 129 CHECK_GE(tab_id, 0); |
| 127 TabPermissionsMap::iterator iter = tab_specific_permissions_.find(tab_id); | 130 TabPermissionsMap::iterator iter = tab_specific_permissions_.find(tab_id); |
| 128 if (iter == tab_specific_permissions_.end()) | 131 if (iter == tab_specific_permissions_.end()) |
| 129 tab_specific_permissions_[tab_id] = permissions; | 132 tab_specific_permissions_[tab_id] = permissions; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 } | 200 } |
| 198 | 201 |
| 199 std::vector<base::string16> | 202 std::vector<base::string16> |
| 200 PermissionsData::GetPermissionMessageDetailsStrings() const { | 203 PermissionsData::GetPermissionMessageDetailsStrings() const { |
| 201 if (ShouldSkipPermissionWarnings(extension_id_)) | 204 if (ShouldSkipPermissionWarnings(extension_id_)) |
| 202 return std::vector<base::string16>(); | 205 return std::vector<base::string16>(); |
| 203 return PermissionMessageProvider::Get()->GetWarningMessagesDetails( | 206 return PermissionMessageProvider::Get()->GetWarningMessagesDetails( |
| 204 active_permissions(), manifest_type_); | 207 active_permissions(), manifest_type_); |
| 205 } | 208 } |
| 206 | 209 |
| 210 bool PermissionsData::HasWithheldImpliedAllHosts() const { |
| 211 // Since we currently only withhold all_hosts, it's sufficient to check |
| 212 // that either set is not empty. |
| 213 return !withheld_permissions()->explicit_hosts().is_empty() || |
| 214 !withheld_permissions()->scriptable_hosts().is_empty(); |
| 215 } |
| 216 |
| 207 bool PermissionsData::CanAccessPage(const Extension* extension, | 217 bool PermissionsData::CanAccessPage(const Extension* extension, |
| 208 const GURL& document_url, | 218 const GURL& document_url, |
| 209 const GURL& top_frame_url, | 219 const GURL& top_frame_url, |
| 210 int tab_id, | 220 int tab_id, |
| 211 int process_id, | 221 int process_id, |
| 212 std::string* error) const { | 222 std::string* error) const { |
| 223 AccessType result = CanRunOnPage(extension, |
| 224 document_url, |
| 225 top_frame_url, |
| 226 tab_id, |
| 227 process_id, |
| 228 active_permissions()->explicit_hosts(), |
| 229 withheld_permissions()->explicit_hosts(), |
| 230 error); |
| 231 // TODO(rdevlin.cronin) Update callers so that they only need ACCESS_ALLOWED. |
| 232 return result == ACCESS_ALLOWED || result == ACCESS_WITHHELD; |
| 233 } |
| 234 |
| 235 PermissionsData::AccessType PermissionsData::GetPageAccess( |
| 236 const Extension* extension, |
| 237 const GURL& document_url, |
| 238 const GURL& top_frame_url, |
| 239 int tab_id, |
| 240 int process_id, |
| 241 std::string* error) const { |
| 213 return CanRunOnPage(extension, | 242 return CanRunOnPage(extension, |
| 214 document_url, | 243 document_url, |
| 215 top_frame_url, | 244 top_frame_url, |
| 216 tab_id, | 245 tab_id, |
| 217 process_id, | 246 process_id, |
| 218 active_permissions()->explicit_hosts(), | 247 active_permissions()->explicit_hosts(), |
| 248 withheld_permissions()->explicit_hosts(), |
| 219 error); | 249 error); |
| 220 } | 250 } |
| 221 | 251 |
| 222 bool PermissionsData::CanRunContentScriptOnPage(const Extension* extension, | 252 bool PermissionsData::CanRunContentScriptOnPage(const Extension* extension, |
| 223 const GURL& document_url, | 253 const GURL& document_url, |
| 224 const GURL& top_frame_url, | 254 const GURL& top_frame_url, |
| 225 int tab_id, | 255 int tab_id, |
| 226 int process_id, | 256 int process_id, |
| 227 std::string* error) const { | 257 std::string* error) const { |
| 258 AccessType result = CanRunOnPage(extension, |
| 259 document_url, |
| 260 top_frame_url, |
| 261 tab_id, |
| 262 process_id, |
| 263 active_permissions()->scriptable_hosts(), |
| 264 withheld_permissions()->scriptable_hosts(), |
| 265 error); |
| 266 // TODO(rdevlin.cronin) Update callers so that they only need ACCESS_ALLOWED. |
| 267 return result == ACCESS_ALLOWED || result == ACCESS_WITHHELD; |
| 268 } |
| 269 |
| 270 PermissionsData::AccessType PermissionsData::GetContentScriptAccess( |
| 271 const Extension* extension, |
| 272 const GURL& document_url, |
| 273 const GURL& top_frame_url, |
| 274 int tab_id, |
| 275 int process_id, |
| 276 std::string* error) const { |
| 228 return CanRunOnPage(extension, | 277 return CanRunOnPage(extension, |
| 229 document_url, | 278 document_url, |
| 230 top_frame_url, | 279 top_frame_url, |
| 231 tab_id, | 280 tab_id, |
| 232 process_id, | 281 process_id, |
| 233 active_permissions()->scriptable_hosts(), | 282 active_permissions()->scriptable_hosts(), |
| 283 withheld_permissions()->scriptable_hosts(), |
| 234 error); | 284 error); |
| 235 } | 285 } |
| 236 | 286 |
| 237 bool PermissionsData::CanCaptureVisiblePage(int tab_id, | 287 bool PermissionsData::CanCaptureVisiblePage(int tab_id, |
| 238 std::string* error) const { | 288 std::string* error) const { |
| 239 const URLPattern all_urls(URLPattern::SCHEME_ALL, | 289 const URLPattern all_urls(URLPattern::SCHEME_ALL, |
| 240 URLPattern::kAllUrlsPattern); | 290 URLPattern::kAllUrlsPattern); |
| 241 | 291 |
| 242 if (active_permissions()->explicit_hosts().ContainsPattern(all_urls)) | 292 if (active_permissions()->explicit_hosts().ContainsPattern(all_urls)) |
| 243 return true; | 293 return true; |
| 244 | 294 |
| 245 if (tab_id >= 0) { | 295 if (tab_id >= 0) { |
| 246 scoped_refptr<const PermissionSet> tab_permissions = | 296 scoped_refptr<const PermissionSet> tab_permissions = |
| 247 GetTabSpecificPermissions(tab_id); | 297 GetTabSpecificPermissions(tab_id); |
| 248 if (tab_permissions && | 298 if (tab_permissions && |
| 249 tab_permissions->HasAPIPermission(APIPermission::kTab)) { | 299 tab_permissions->HasAPIPermission(APIPermission::kTab)) { |
| 250 return true; | 300 return true; |
| 251 } | 301 } |
| 252 if (error) | 302 if (error) |
| 253 *error = manifest_errors::kActiveTabPermissionNotGranted; | 303 *error = manifest_errors::kActiveTabPermissionNotGranted; |
| 254 return false; | 304 return false; |
| 255 } | 305 } |
| 256 | 306 |
| 257 if (error) | 307 if (error) |
| 258 *error = manifest_errors::kAllURLOrActiveTabNeeded; | 308 *error = manifest_errors::kAllURLOrActiveTabNeeded; |
| 259 return false; | 309 return false; |
| 260 } | 310 } |
| 261 | 311 |
| 262 // static | |
| 263 bool PermissionsData::RequiresActionForScriptExecution( | |
| 264 const Extension* extension) const { | |
| 265 return RequiresActionForScriptExecution(extension, -1, GURL()); | |
| 266 } | |
| 267 | |
| 268 // static | |
| 269 bool PermissionsData::RequiresActionForScriptExecution( | |
| 270 const Extension* extension, | |
| 271 int tab_id, | |
| 272 const GURL& url) const { | |
| 273 // For now, the user should be notified when an extension with all hosts | |
| 274 // permission tries to execute a script on a page. Exceptions for policy- | |
| 275 // enabled and component extensions, and extensions which are whitelisted to | |
| 276 // execute scripts everywhere. | |
| 277 if (!extension->ShouldDisplayInExtensionSettings() || | |
| 278 Manifest::IsPolicyLocation(extension->location()) || | |
| 279 Manifest::IsComponentLocation(extension->location()) || | |
| 280 CanExecuteScriptEverywhere(extension) || | |
| 281 !active_permissions()->ShouldWarnAllHosts()) { | |
| 282 return false; | |
| 283 } | |
| 284 | |
| 285 // If the extension has explicit permission to run on the given tab, then | |
| 286 // we don't need to alert the user. | |
| 287 if (HasTabSpecificPermissionToExecuteScript(tab_id, url)) | |
| 288 return false; | |
| 289 | |
| 290 return true; | |
| 291 } | |
| 292 | |
| 293 scoped_refptr<const PermissionSet> PermissionsData::GetTabSpecificPermissions( | 312 scoped_refptr<const PermissionSet> PermissionsData::GetTabSpecificPermissions( |
| 294 int tab_id) const { | 313 int tab_id) const { |
| 295 base::AutoLock auto_lock(runtime_lock_); | 314 base::AutoLock auto_lock(runtime_lock_); |
| 296 CHECK_GE(tab_id, 0); | 315 CHECK_GE(tab_id, 0); |
| 297 TabPermissionsMap::const_iterator iter = | 316 TabPermissionsMap::const_iterator iter = |
| 298 tab_specific_permissions_.find(tab_id); | 317 tab_specific_permissions_.find(tab_id); |
| 299 return (iter != tab_specific_permissions_.end()) ? iter->second : NULL; | 318 return (iter != tab_specific_permissions_.end()) ? iter->second : NULL; |
| 300 } | 319 } |
| 301 | 320 |
| 302 bool PermissionsData::HasTabSpecificPermissionToExecuteScript( | 321 bool PermissionsData::HasTabSpecificPermissionToExecuteScript( |
| 303 int tab_id, | 322 int tab_id, |
| 304 const GURL& url) const { | 323 const GURL& url) const { |
| 305 if (tab_id >= 0) { | 324 if (tab_id >= 0) { |
| 306 scoped_refptr<const PermissionSet> tab_permissions = | 325 scoped_refptr<const PermissionSet> tab_permissions = |
| 307 GetTabSpecificPermissions(tab_id); | 326 GetTabSpecificPermissions(tab_id); |
| 308 if (tab_permissions.get() && | 327 if (tab_permissions.get() && |
| 309 tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) { | 328 tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) { |
| 310 return true; | 329 return true; |
| 311 } | 330 } |
| 312 } | 331 } |
| 313 return false; | 332 return false; |
| 314 } | 333 } |
| 315 | 334 |
| 316 bool PermissionsData::CanRunOnPage(const Extension* extension, | 335 PermissionsData::AccessType PermissionsData::CanRunOnPage( |
| 317 const GURL& document_url, | 336 const Extension* extension, |
| 318 const GURL& top_frame_url, | 337 const GURL& document_url, |
| 319 int tab_id, | 338 const GURL& top_frame_url, |
| 320 int process_id, | 339 int tab_id, |
| 321 const URLPatternSet& permitted_url_patterns, | 340 int process_id, |
| 322 std::string* error) const { | 341 const URLPatternSet& permitted_url_patterns, |
| 342 const URLPatternSet& withheld_url_patterns, |
| 343 std::string* error) const { |
| 323 if (g_policy_delegate && | 344 if (g_policy_delegate && |
| 324 !g_policy_delegate->CanExecuteScriptOnPage( | 345 !g_policy_delegate->CanExecuteScriptOnPage( |
| 325 extension, document_url, top_frame_url, tab_id, process_id, error)) { | 346 extension, document_url, top_frame_url, tab_id, process_id, error)) { |
| 326 return false; | 347 return ACCESS_DENIED; |
| 327 } | 348 } |
| 328 | 349 |
| 329 if (IsRestrictedUrl(document_url, top_frame_url, extension, error)) | 350 if (IsRestrictedUrl(document_url, top_frame_url, extension, error)) |
| 330 return false; | 351 return ACCESS_DENIED; |
| 331 | 352 |
| 332 if (HasTabSpecificPermissionToExecuteScript(tab_id, top_frame_url)) | 353 if (HasTabSpecificPermissionToExecuteScript(tab_id, top_frame_url)) |
| 333 return true; | 354 return ACCESS_ALLOWED; |
| 334 | 355 |
| 335 bool can_access = permitted_url_patterns.MatchesURL(document_url); | 356 if (permitted_url_patterns.MatchesURL(document_url)) |
| 357 return ACCESS_ALLOWED; |
| 336 | 358 |
| 337 if (!can_access && error) { | 359 if (withheld_url_patterns.MatchesURL(document_url)) |
| 360 return ACCESS_WITHHELD; |
| 361 |
| 362 if (error) { |
| 338 *error = ErrorUtils::FormatErrorMessage(manifest_errors::kCannotAccessPage, | 363 *error = ErrorUtils::FormatErrorMessage(manifest_errors::kCannotAccessPage, |
| 339 document_url.spec()); | 364 document_url.spec()); |
| 340 } | 365 } |
| 341 | 366 return ACCESS_DENIED; |
| 342 return can_access; | |
| 343 } | 367 } |
| 344 | 368 |
| 345 } // namespace extensions | 369 } // namespace extensions |
| OLD | NEW |