| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/permissions/permission_context_base.h" | 5 #include "chrome/browser/permissions/permission_context_base.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <set> | |
| 10 #include <string> | 9 #include <string> |
| 11 #include <utility> | 10 #include <utility> |
| 12 | 11 |
| 13 #include "base/callback.h" | 12 #include "base/callback.h" |
| 14 #include "base/logging.h" | 13 #include "base/logging.h" |
| 15 #include "base/memory/ptr_util.h" | 14 #include "base/memory/ptr_util.h" |
| 16 #include "base/strings/stringprintf.h" | 15 #include "base/strings/stringprintf.h" |
| 17 #include "base/timer/timer.h" | |
| 18 #include "build/build_config.h" | 16 #include "build/build_config.h" |
| 19 #include "chrome/browser/browser_process.h" | 17 #include "chrome/browser/browser_process.h" |
| 20 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 18 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| 19 #include "chrome/browser/permissions/permission_blacklist_client.h" |
| 21 #include "chrome/browser/permissions/permission_decision_auto_blocker.h" | 20 #include "chrome/browser/permissions/permission_decision_auto_blocker.h" |
| 22 #include "chrome/browser/permissions/permission_request.h" | 21 #include "chrome/browser/permissions/permission_request.h" |
| 23 #include "chrome/browser/permissions/permission_request_id.h" | 22 #include "chrome/browser/permissions/permission_request_id.h" |
| 24 #include "chrome/browser/permissions/permission_request_impl.h" | 23 #include "chrome/browser/permissions/permission_request_impl.h" |
| 25 #include "chrome/browser/permissions/permission_request_manager.h" | 24 #include "chrome/browser/permissions/permission_request_manager.h" |
| 26 #include "chrome/browser/permissions/permission_uma_util.h" | 25 #include "chrome/browser/permissions/permission_uma_util.h" |
| 27 #include "chrome/browser/permissions/permission_util.h" | 26 #include "chrome/browser/permissions/permission_util.h" |
| 28 #include "chrome/browser/profiles/profile.h" | 27 #include "chrome/browser/profiles/profile.h" |
| 29 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 28 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |
| 30 #include "chrome/common/chrome_features.h" | 29 #include "chrome/common/chrome_features.h" |
| 31 #include "chrome/common/pref_names.h" | 30 #include "chrome/common/pref_names.h" |
| 32 #include "components/content_settings/core/browser/host_content_settings_map.h" | 31 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 33 #include "components/content_settings/core/browser/website_settings_registry.h" | 32 #include "components/content_settings/core/browser/website_settings_registry.h" |
| 34 #include "components/prefs/pref_service.h" | 33 #include "components/prefs/pref_service.h" |
| 35 #include "components/safe_browsing_db/database_manager.h" | |
| 36 #include "components/variations/variations_associated_data.h" | 34 #include "components/variations/variations_associated_data.h" |
| 37 #include "content/public/browser/browser_thread.h" | 35 #include "content/public/browser/browser_thread.h" |
| 38 #include "content/public/browser/render_frame_host.h" | 36 #include "content/public/browser/render_frame_host.h" |
| 39 #include "content/public/browser/web_contents.h" | 37 #include "content/public/browser/web_contents.h" |
| 40 #include "content/public/browser/web_contents_observer.h" | |
| 41 #include "content/public/common/origin_util.h" | 38 #include "content/public/common/origin_util.h" |
| 42 #include "url/gurl.h" | 39 #include "url/gurl.h" |
| 43 | 40 |
| 44 #if defined(OS_ANDROID) | 41 #if defined(OS_ANDROID) |
| 45 #include "chrome/browser/permissions/permission_queue_controller.h" | 42 #include "chrome/browser/permissions/permission_queue_controller.h" |
| 46 #endif | 43 #endif |
| 47 | 44 |
| 48 // static | 45 // static |
| 49 const char PermissionContextBase::kPermissionsKillSwitchFieldStudy[] = | 46 const char PermissionContextBase::kPermissionsKillSwitchFieldStudy[] = |
| 50 "PermissionsKillSwitch"; | 47 "PermissionsKillSwitch"; |
| 51 // static | 48 // static |
| 52 const char PermissionContextBase::kPermissionsKillSwitchBlockedValue[] = | 49 const char PermissionContextBase::kPermissionsKillSwitchBlockedValue[] = |
| 53 "blocked"; | 50 "blocked"; |
| 54 // Maximum time in milliseconds to wait for safe browsing service to check a | 51 // Maximum time in milliseconds to wait for safe browsing service to check a |
| 55 // url for blacklisting. After this amount of time, the check will be aborted | 52 // url for blacklisting. After this amount of time, the check will be aborted |
| 56 // and the url will be treated as not blacklisted. | 53 // and the url will be treated as not blacklisted. |
| 57 // TODO(meredithl): Revisit this once UMA metrics have data about request time. | 54 // TODO(meredithl): Revisit this once UMA metrics have data about request time. |
| 58 const int kCheckUrlTimeoutMs = 2000; | 55 const int kCheckUrlTimeoutMs = 2000; |
| 59 | 56 |
| 60 // The client used when checking whether a permission has been blacklisted by | |
| 61 // Safe Browsing. The check is done asynchronously as no state can be stored in | |
| 62 // PermissionContextBase (since additional permission requests may be made). | |
| 63 // This class must be created and destroyed on the UI thread. | |
| 64 class PermissionsBlacklistingClient | |
| 65 : public safe_browsing::SafeBrowsingDatabaseManager::Client, | |
| 66 public base::RefCountedThreadSafe<PermissionsBlacklistingClient>, | |
| 67 public content::WebContentsObserver { | |
| 68 public: | |
| 69 static void CheckSafeBrowsingBlacklist( | |
| 70 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager, | |
| 71 content::PermissionType permission_type, | |
| 72 const GURL& request_origin, | |
| 73 content::WebContents* web_contents, | |
| 74 int timeout, | |
| 75 base::Callback<void(bool)> callback) { | |
| 76 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 77 | |
| 78 new PermissionsBlacklistingClient(db_manager, permission_type, | |
| 79 request_origin, web_contents, timeout, | |
| 80 callback); | |
| 81 } | |
| 82 | |
| 83 private: | |
| 84 friend class base::RefCountedThreadSafe<PermissionsBlacklistingClient>; | |
| 85 | |
| 86 PermissionsBlacklistingClient( | |
| 87 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager, | |
| 88 content::PermissionType permission_type, | |
| 89 const GURL& request_origin, | |
| 90 content::WebContents* web_contents, | |
| 91 int timeout, | |
| 92 base::Callback<void(bool)> callback) | |
| 93 : content::WebContentsObserver(web_contents), | |
| 94 db_manager_(db_manager), | |
| 95 permission_type_(permission_type), | |
| 96 callback_(callback), | |
| 97 timeout_(timeout), | |
| 98 is_active_(true) { | |
| 99 // Balanced by a call to Release() in OnCheckApiBlacklistUrlResult(). | |
| 100 AddRef(); | |
| 101 content::BrowserThread::PostTask( | |
| 102 content::BrowserThread::IO, FROM_HERE, | |
| 103 base::Bind(&PermissionsBlacklistingClient::StartCheck, this, | |
| 104 request_origin)); | |
| 105 } | |
| 106 | |
| 107 ~PermissionsBlacklistingClient() override {} | |
| 108 | |
| 109 void StartCheck(const GURL& request_origin) { | |
| 110 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 111 | |
| 112 // Start the timer to interrupt into the client callback method with an | |
| 113 // empty response if Safe Browsing times out. | |
| 114 safe_browsing::ThreatMetadata empty_metadata; | |
| 115 timer_ = base::MakeUnique<base::OneShotTimer>(); | |
| 116 timer_->Start( | |
| 117 FROM_HERE, base::TimeDelta::FromMilliseconds(timeout_), | |
| 118 base::Bind(&PermissionsBlacklistingClient::OnCheckApiBlacklistUrlResult, | |
| 119 this, request_origin, empty_metadata)); | |
| 120 db_manager_->CheckApiBlacklistUrl(request_origin, this); | |
| 121 } | |
| 122 | |
| 123 // SafeBrowsingDatabaseManager::Client implementation. | |
| 124 void OnCheckApiBlacklistUrlResult( | |
| 125 const GURL& url, | |
| 126 const safe_browsing::ThreatMetadata& metadata) override { | |
| 127 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | |
| 128 | |
| 129 if (timer_->IsRunning()) | |
| 130 timer_->Stop(); | |
| 131 else | |
| 132 db_manager_->CancelApiCheck(this); | |
| 133 timer_.reset(nullptr); | |
| 134 | |
| 135 // TODO(meredithl): Convert the strings returned from Safe Browsing to the | |
| 136 // ones used by PermissionUtil for comparison. | |
| 137 bool permission_blocked = | |
| 138 metadata.api_permissions.find(PermissionUtil::GetPermissionString( | |
| 139 permission_type_)) != metadata.api_permissions.end(); | |
| 140 | |
| 141 content::BrowserThread::PostTask( | |
| 142 content::BrowserThread::UI, FROM_HERE, | |
| 143 base::Bind( | |
| 144 &PermissionsBlacklistingClient::EvaluateBlacklistResultOnUiThread, | |
| 145 this, permission_blocked)); | |
| 146 } | |
| 147 | |
| 148 void EvaluateBlacklistResultOnUiThread(bool permission_blocked) { | |
| 149 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | |
| 150 | |
| 151 if (is_active_) | |
| 152 callback_.Run(permission_blocked); | |
| 153 Release(); | |
| 154 } | |
| 155 | |
| 156 // WebContentsObserver implementation. Sets the flag so that when the database | |
| 157 // manager returns with a result, it won't attempt to run the callback with a | |
| 158 // deleted WebContents. | |
| 159 void WebContentsDestroyed() override { | |
| 160 is_active_ = false; | |
| 161 Observe(nullptr); | |
| 162 } | |
| 163 | |
| 164 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager_; | |
| 165 content::PermissionType permission_type_; | |
| 166 | |
| 167 // PermissionContextBase callback to run on the UI thread. | |
| 168 base::Callback<void(bool)> callback_; | |
| 169 | |
| 170 // Timer to abort the Safe Browsing check if it takes too long. Created and | |
| 171 // used on the IO Thread. | |
| 172 std::unique_ptr<base::OneShotTimer> timer_; | |
| 173 int timeout_; | |
| 174 | |
| 175 // True if |callback_| should be invoked, if web_contents() is destroyed, this | |
| 176 // is set to false. | |
| 177 bool is_active_; | |
| 178 | |
| 179 DISALLOW_COPY_AND_ASSIGN(PermissionsBlacklistingClient); | |
| 180 }; | |
| 181 | |
| 182 PermissionContextBase::PermissionContextBase( | 57 PermissionContextBase::PermissionContextBase( |
| 183 Profile* profile, | 58 Profile* profile, |
| 184 const content::PermissionType permission_type, | 59 const content::PermissionType permission_type, |
| 185 const ContentSettingsType content_settings_type) | 60 const ContentSettingsType content_settings_type) |
| 186 : profile_(profile), | 61 : profile_(profile), |
| 187 permission_type_(permission_type), | 62 permission_type_(permission_type), |
| 188 content_settings_type_(content_settings_type), | 63 content_settings_type_(content_settings_type), |
| 189 safe_browsing_timeout_(kCheckUrlTimeoutMs), | 64 safe_browsing_timeout_(kCheckUrlTimeoutMs), |
| 190 weak_factory_(this) { | 65 weak_factory_(this) { |
| 191 #if defined(OS_ANDROID) | 66 #if defined(OS_ANDROID) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 | 115 |
| 241 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist)) { | 116 if (base::FeatureList::IsEnabled(features::kPermissionsBlacklist)) { |
| 242 if (!db_manager_) { | 117 if (!db_manager_) { |
| 243 safe_browsing::SafeBrowsingService* sb_service = | 118 safe_browsing::SafeBrowsingService* sb_service = |
| 244 g_browser_process->safe_browsing_service(); | 119 g_browser_process->safe_browsing_service(); |
| 245 if (sb_service) | 120 if (sb_service) |
| 246 db_manager_ = sb_service->database_manager(); | 121 db_manager_ = sb_service->database_manager(); |
| 247 } | 122 } |
| 248 | 123 |
| 249 // The client contacts Safe Browsing, and runs the callback with the result. | 124 // The client contacts Safe Browsing, and runs the callback with the result. |
| 250 PermissionsBlacklistingClient::CheckSafeBrowsingBlacklist( | 125 PermissionBlacklistClient::CheckSafeBrowsingBlacklist( |
| 251 db_manager_, permission_type_, requesting_origin, web_contents, | 126 db_manager_, permission_type_, requesting_origin, web_contents, |
| 252 safe_browsing_timeout_, | 127 safe_browsing_timeout_, |
| 253 base::Bind(&PermissionContextBase::ContinueRequestPermission, | 128 base::Bind(&PermissionContextBase::ContinueRequestPermission, |
| 254 weak_factory_.GetWeakPtr(), web_contents, id, | 129 weak_factory_.GetWeakPtr(), web_contents, id, |
| 255 requesting_origin, embedding_origin, user_gesture, | 130 requesting_origin, embedding_origin, user_gesture, |
| 256 callback)); | 131 callback)); |
| 257 } else { | 132 } else { |
| 258 // TODO(meredithl): Add UMA metrics here. | 133 // TODO(meredithl): Add UMA metrics here. |
| 259 ContinueRequestPermission(web_contents, id, requesting_origin, | 134 ContinueRequestPermission(web_contents, id, requesting_origin, |
| 260 embedding_origin, user_gesture, callback, | 135 embedding_origin, user_gesture, callback, |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 content_settings_type_, std::string(), | 385 content_settings_type_, std::string(), |
| 511 content_setting); | 386 content_setting); |
| 512 } | 387 } |
| 513 | 388 |
| 514 void PermissionContextBase::SetSafeBrowsingDatabaseManagerAndTimeoutForTest( | 389 void PermissionContextBase::SetSafeBrowsingDatabaseManagerAndTimeoutForTest( |
| 515 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager, | 390 scoped_refptr<safe_browsing::SafeBrowsingDatabaseManager> db_manager, |
| 516 int timeout) { | 391 int timeout) { |
| 517 db_manager_ = db_manager; | 392 db_manager_ = db_manager; |
| 518 safe_browsing_timeout_ = timeout; | 393 safe_browsing_timeout_ = timeout; |
| 519 } | 394 } |
| OLD | NEW |