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(const PermissionSet* active, |
117 const PermissionSet* permissions) const { | 118 const PermissionSet* withheld) const { |
118 base::AutoLock auto_lock(runtime_lock_); | 119 base::AutoLock auto_lock(runtime_lock_); |
119 active_permissions_unsafe_ = permissions; | 120 active_permissions_unsafe_ = active; |
| 121 withheld_permissions_unsafe_ = withheld; |
120 } | 122 } |
121 | 123 |
122 void PermissionsData::UpdateTabSpecificPermissions( | 124 void PermissionsData::UpdateTabSpecificPermissions( |
123 int tab_id, | 125 int tab_id, |
124 scoped_refptr<const PermissionSet> permissions) const { | 126 scoped_refptr<const PermissionSet> permissions) const { |
125 base::AutoLock auto_lock(runtime_lock_); | 127 base::AutoLock auto_lock(runtime_lock_); |
126 CHECK_GE(tab_id, 0); | 128 CHECK_GE(tab_id, 0); |
127 TabPermissionsMap::iterator iter = tab_specific_permissions_.find(tab_id); | 129 TabPermissionsMap::iterator iter = tab_specific_permissions_.find(tab_id); |
128 if (iter == tab_specific_permissions_.end()) | 130 if (iter == tab_specific_permissions_.end()) |
129 tab_specific_permissions_[tab_id] = permissions; | 131 tab_specific_permissions_[tab_id] = permissions; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
197 } | 199 } |
198 | 200 |
199 std::vector<base::string16> | 201 std::vector<base::string16> |
200 PermissionsData::GetPermissionMessageDetailsStrings() const { | 202 PermissionsData::GetPermissionMessageDetailsStrings() const { |
201 if (ShouldSkipPermissionWarnings(extension_id_)) | 203 if (ShouldSkipPermissionWarnings(extension_id_)) |
202 return std::vector<base::string16>(); | 204 return std::vector<base::string16>(); |
203 return PermissionMessageProvider::Get()->GetWarningMessagesDetails( | 205 return PermissionMessageProvider::Get()->GetWarningMessagesDetails( |
204 active_permissions(), manifest_type_); | 206 active_permissions(), manifest_type_); |
205 } | 207 } |
206 | 208 |
| 209 bool PermissionsData::HasWithheldAllHosts() const { |
| 210 // Since we currently only withhold all_hosts, it's sufficient to check |
| 211 // that either set is not empty. |
| 212 return !withheld_permissions()->explicit_hosts().is_empty() || |
| 213 !withheld_permissions()->scriptable_hosts().is_empty(); |
| 214 } |
| 215 |
207 bool PermissionsData::CanAccessPage(const Extension* extension, | 216 bool PermissionsData::CanAccessPage(const Extension* extension, |
208 const GURL& document_url, | 217 const GURL& document_url, |
209 const GURL& top_frame_url, | 218 const GURL& top_frame_url, |
210 int tab_id, | 219 int tab_id, |
211 int process_id, | 220 int process_id, |
212 std::string* error) const { | 221 std::string* error) const { |
| 222 AccessType result = CanRunOnPage(extension, |
| 223 document_url, |
| 224 top_frame_url, |
| 225 tab_id, |
| 226 process_id, |
| 227 active_permissions()->explicit_hosts(), |
| 228 withheld_permissions()->explicit_hosts(), |
| 229 error); |
| 230 // TODO(rdevlin.cronin) Update callers so that they only need ACCESS_ALLOWED. |
| 231 return result == ACCESS_ALLOWED || result == ACCESS_WITHHELD; |
| 232 } |
| 233 |
| 234 PermissionsData::AccessType PermissionsData::GetPageAccess( |
| 235 const Extension* extension, |
| 236 const GURL& document_url, |
| 237 const GURL& top_frame_url, |
| 238 int tab_id, |
| 239 int process_id, |
| 240 std::string* error) const { |
213 return CanRunOnPage(extension, | 241 return CanRunOnPage(extension, |
214 document_url, | 242 document_url, |
215 top_frame_url, | 243 top_frame_url, |
216 tab_id, | 244 tab_id, |
217 process_id, | 245 process_id, |
218 active_permissions()->explicit_hosts(), | 246 active_permissions()->explicit_hosts(), |
| 247 withheld_permissions()->explicit_hosts(), |
219 error); | 248 error); |
220 } | 249 } |
221 | 250 |
222 bool PermissionsData::CanRunContentScriptOnPage(const Extension* extension, | 251 bool PermissionsData::CanRunContentScriptOnPage(const Extension* extension, |
223 const GURL& document_url, | 252 const GURL& document_url, |
224 const GURL& top_frame_url, | 253 const GURL& top_frame_url, |
225 int tab_id, | 254 int tab_id, |
226 int process_id, | 255 int process_id, |
227 std::string* error) const { | 256 std::string* error) const { |
| 257 AccessType result = CanRunOnPage(extension, |
| 258 document_url, |
| 259 top_frame_url, |
| 260 tab_id, |
| 261 process_id, |
| 262 active_permissions()->scriptable_hosts(), |
| 263 withheld_permissions()->scriptable_hosts(), |
| 264 error); |
| 265 // TODO(rdevlin.cronin) Update callers so that they only need ACCESS_ALLOWED. |
| 266 return result == ACCESS_ALLOWED || result == ACCESS_WITHHELD; |
| 267 } |
| 268 |
| 269 PermissionsData::AccessType PermissionsData::GetContentScriptAccess( |
| 270 const Extension* extension, |
| 271 const GURL& document_url, |
| 272 const GURL& top_frame_url, |
| 273 int tab_id, |
| 274 int process_id, |
| 275 std::string* error) const { |
228 return CanRunOnPage(extension, | 276 return CanRunOnPage(extension, |
229 document_url, | 277 document_url, |
230 top_frame_url, | 278 top_frame_url, |
231 tab_id, | 279 tab_id, |
232 process_id, | 280 process_id, |
233 active_permissions()->scriptable_hosts(), | 281 active_permissions()->scriptable_hosts(), |
| 282 withheld_permissions()->scriptable_hosts(), |
234 error); | 283 error); |
235 } | 284 } |
236 | 285 |
237 bool PermissionsData::CanCaptureVisiblePage(int tab_id, | 286 bool PermissionsData::CanCaptureVisiblePage(int tab_id, |
238 std::string* error) const { | 287 std::string* error) const { |
239 const URLPattern all_urls(URLPattern::SCHEME_ALL, | 288 const URLPattern all_urls(URLPattern::SCHEME_ALL, |
240 URLPattern::kAllUrlsPattern); | 289 URLPattern::kAllUrlsPattern); |
241 | 290 |
242 if (active_permissions()->explicit_hosts().ContainsPattern(all_urls)) | 291 if (active_permissions()->explicit_hosts().ContainsPattern(all_urls)) |
243 return true; | 292 return true; |
244 | 293 |
245 if (tab_id >= 0) { | 294 if (tab_id >= 0) { |
246 scoped_refptr<const PermissionSet> tab_permissions = | 295 scoped_refptr<const PermissionSet> tab_permissions = |
247 GetTabSpecificPermissions(tab_id); | 296 GetTabSpecificPermissions(tab_id); |
248 if (tab_permissions && | 297 if (tab_permissions && |
249 tab_permissions->HasAPIPermission(APIPermission::kTab)) { | 298 tab_permissions->HasAPIPermission(APIPermission::kTab)) { |
250 return true; | 299 return true; |
251 } | 300 } |
252 if (error) | 301 if (error) |
253 *error = manifest_errors::kActiveTabPermissionNotGranted; | 302 *error = manifest_errors::kActiveTabPermissionNotGranted; |
254 return false; | 303 return false; |
255 } | 304 } |
256 | 305 |
257 if (error) | 306 if (error) |
258 *error = manifest_errors::kAllURLOrActiveTabNeeded; | 307 *error = manifest_errors::kAllURLOrActiveTabNeeded; |
259 return false; | 308 return false; |
260 } | 309 } |
261 | 310 |
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( | 311 scoped_refptr<const PermissionSet> PermissionsData::GetTabSpecificPermissions( |
294 int tab_id) const { | 312 int tab_id) const { |
295 base::AutoLock auto_lock(runtime_lock_); | 313 base::AutoLock auto_lock(runtime_lock_); |
296 CHECK_GE(tab_id, 0); | 314 CHECK_GE(tab_id, 0); |
297 TabPermissionsMap::const_iterator iter = | 315 TabPermissionsMap::const_iterator iter = |
298 tab_specific_permissions_.find(tab_id); | 316 tab_specific_permissions_.find(tab_id); |
299 return (iter != tab_specific_permissions_.end()) ? iter->second : NULL; | 317 return (iter != tab_specific_permissions_.end()) ? iter->second : NULL; |
300 } | 318 } |
301 | 319 |
302 bool PermissionsData::HasTabSpecificPermissionToExecuteScript( | 320 bool PermissionsData::HasTabSpecificPermissionToExecuteScript( |
303 int tab_id, | 321 int tab_id, |
304 const GURL& url) const { | 322 const GURL& url) const { |
305 if (tab_id >= 0) { | 323 if (tab_id >= 0) { |
306 scoped_refptr<const PermissionSet> tab_permissions = | 324 scoped_refptr<const PermissionSet> tab_permissions = |
307 GetTabSpecificPermissions(tab_id); | 325 GetTabSpecificPermissions(tab_id); |
308 if (tab_permissions.get() && | 326 if (tab_permissions.get() && |
309 tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) { | 327 tab_permissions->explicit_hosts().MatchesSecurityOrigin(url)) { |
310 return true; | 328 return true; |
311 } | 329 } |
312 } | 330 } |
313 return false; | 331 return false; |
314 } | 332 } |
315 | 333 |
316 bool PermissionsData::CanRunOnPage(const Extension* extension, | 334 PermissionsData::AccessType PermissionsData::CanRunOnPage( |
317 const GURL& document_url, | 335 const Extension* extension, |
318 const GURL& top_frame_url, | 336 const GURL& document_url, |
319 int tab_id, | 337 const GURL& top_frame_url, |
320 int process_id, | 338 int tab_id, |
321 const URLPatternSet& permitted_url_patterns, | 339 int process_id, |
322 std::string* error) const { | 340 const URLPatternSet& permitted_url_patterns, |
| 341 const URLPatternSet& withheld_url_patterns, |
| 342 std::string* error) const { |
323 if (g_policy_delegate && | 343 if (g_policy_delegate && |
324 !g_policy_delegate->CanExecuteScriptOnPage( | 344 !g_policy_delegate->CanExecuteScriptOnPage( |
325 extension, document_url, top_frame_url, tab_id, process_id, error)) { | 345 extension, document_url, top_frame_url, tab_id, process_id, error)) { |
326 return false; | 346 return ACCESS_DENIED; |
327 } | 347 } |
328 | 348 |
329 if (IsRestrictedUrl(document_url, top_frame_url, extension, error)) | 349 if (IsRestrictedUrl(document_url, top_frame_url, extension, error)) |
330 return false; | 350 return ACCESS_DENIED; |
331 | 351 |
332 if (HasTabSpecificPermissionToExecuteScript(tab_id, top_frame_url)) | 352 if (HasTabSpecificPermissionToExecuteScript(tab_id, top_frame_url)) |
333 return true; | 353 return ACCESS_ALLOWED; |
334 | 354 |
335 bool can_access = permitted_url_patterns.MatchesURL(document_url); | 355 if (permitted_url_patterns.MatchesURL(document_url)) |
| 356 return ACCESS_ALLOWED; |
336 | 357 |
337 if (!can_access && error) { | 358 if (withheld_url_patterns.MatchesURL(document_url)) |
| 359 return ACCESS_WITHHELD; |
| 360 |
| 361 if (error) { |
338 *error = ErrorUtils::FormatErrorMessage(manifest_errors::kCannotAccessPage, | 362 *error = ErrorUtils::FormatErrorMessage(manifest_errors::kCannotAccessPage, |
339 document_url.spec()); | 363 document_url.spec()); |
340 } | 364 } |
341 | 365 return ACCESS_DENIED; |
342 return can_access; | |
343 } | 366 } |
344 | 367 |
345 } // namespace extensions | 368 } // namespace extensions |
OLD | NEW |