safe_browsing_service.h revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4// 5// The Safe Browsing service is responsible for downloading anti-phishing and 6// anti-malware tables and checking urls against them. 7 8#ifndef CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_SERVICE_H_ 9#define CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_SERVICE_H_ 10#pragma once 11 12#include <deque> 13#include <set> 14#include <string> 15#include <vector> 16 17#include "base/hash_tables.h" 18#include "base/lock.h" 19#include "base/ref_counted.h" 20#include "base/scoped_ptr.h" 21#include "base/time.h" 22#include "chrome/browser/safe_browsing/safe_browsing_util.h" 23#include "googleurl/src/gurl.h" 24#include "webkit/glue/resource_type.h" 25 26class PrefService; 27class SafeBrowsingDatabase; 28class SafeBrowsingProtocolManager; 29class URLRequestContextGetter; 30 31namespace base { 32class Thread; 33} 34 35// Construction needs to happen on the main thread. 36class SafeBrowsingService 37 : public base::RefCountedThreadSafe<SafeBrowsingService> { 38 public: 39 // Users of this service implement this interface to be notified 40 // asynchronously of the result. 41 enum UrlCheckResult { 42 URL_SAFE, 43 URL_PHISHING, 44 URL_MALWARE, 45 }; 46 47 class Client { 48 public: 49 virtual ~Client() {} 50 51 // Called when the result of checking a URL is known. 52 virtual void OnUrlCheckResult(const GURL& url, UrlCheckResult result) = 0; 53 54 // Called when the user has made a decision about how to handle the 55 // SafeBrowsing interstitial page. 56 virtual void OnBlockingPageComplete(bool proceed) = 0; 57 }; 58 59 // Structure used to pass parameters between the IO and UI thread when 60 // interacting with the blocking page. 61 struct UnsafeResource { 62 GURL url; 63 GURL original_url; 64 ResourceType::Type resource_type; 65 UrlCheckResult threat_type; 66 Client* client; 67 int render_process_host_id; 68 int render_view_id; 69 }; 70 71 // Bundle of SafeBrowsing state for one URL check. 72 struct SafeBrowsingCheck { 73 GURL url; 74 Client* client; 75 bool need_get_hash; 76 base::Time start; // Time that check was sent to SB service. 77 UrlCheckResult result; 78 std::vector<SBPrefix> prefix_hits; 79 std::vector<SBFullHashResult> full_hits; 80 }; 81 82 // Creates the safe browsing service. Need to initialize before using. 83 SafeBrowsingService(); 84 85 // Called on the UI thread to initialize the service. 86 void Initialize(); 87 88 // Called on the main thread to let us know that the io_thread is going away. 89 void ShutDown(); 90 91 // Returns true if the url's scheme can be checked. 92 bool CanCheckUrl(const GURL& url) const; 93 94 // Called on the IO thread to check if the given url is safe or not. If we 95 // can synchronously determine that the url is safe, CheckUrl returns true. 96 // Otherwise it returns false, and "client" is called asynchronously with the 97 // result when it is ready. 98 bool CheckUrl(const GURL& url, Client* client); 99 100 // Called on the IO thread to cancel a pending check if the result is no 101 // longer needed. 102 void CancelCheck(Client* client); 103 104 // Called on the IO thread to display an interstitial page. 105 // |url| is the url of the resource that matches a safe browsing list. 106 // If the request contained a chain of redirects, |url| is the last url 107 // in the chain, and |original_url| is the first one (the root of the 108 // chain). Otherwise, |original_url| = |url|. 109 void DisplayBlockingPage(const GURL& url, 110 const GURL& original_url, 111 ResourceType::Type resource_type, 112 UrlCheckResult result, 113 Client* client, 114 int render_process_host_id, 115 int render_view_id); 116 117 // Called on the IO thread when the SafeBrowsingProtocolManager has received 118 // the full hash results for prefix hits detected in the database. 119 void HandleGetHashResults( 120 SafeBrowsingCheck* check, 121 const std::vector<SBFullHashResult>& full_hashes, 122 bool can_cache); 123 124 // Called on the IO thread. 125 void HandleChunk(const std::string& list, SBChunkList* chunks); 126 void HandleChunkDelete(std::vector<SBChunkDelete>* chunk_deletes); 127 128 // Update management. Called on the IO thread. 129 void UpdateStarted(); 130 void UpdateFinished(bool update_succeeded); 131 // Whether there is an update in progress. Called on the IO thread. 132 bool IsUpdateInProgress() const; 133 134 // The blocking page on the UI thread has completed. 135 void OnBlockingPageDone(const std::vector<UnsafeResource>& resources, 136 bool proceed); 137 138 // Called on the UI thread when the SafeBrowsingProtocolManager has received 139 // updated MAC keys. 140 void OnNewMacKeys(const std::string& client_key, 141 const std::string& wrapped_key); 142 143 // Notification on the UI thread from the advanced options UI. 144 void OnEnable(bool enabled); 145 146 bool enabled() const { return enabled_; } 147 148 // Preference handling. 149 static void RegisterPrefs(PrefService* prefs); 150 151 // Called on the IO thread to try to close the database, freeing the memory 152 // associated with it. The database will be automatically reopened as needed. 153 // 154 // NOTE: Actual database closure is asynchronous, and until it happens, the IO 155 // thread is not allowed to access it; may not actually trigger a close if one 156 // is already pending or doing so would cause problems. 157 void CloseDatabase(); 158 159 // Called on the IO thread to reset the database. 160 void ResetDatabase(); 161 162 // Log the user perceived delay caused by SafeBrowsing. This delay is the time 163 // delta starting from when we would have started reading data from the 164 // network, and ending when the SafeBrowsing check completes indicating that 165 // the current page is 'safe'. 166 void LogPauseDelay(base::TimeDelta time); 167 168 private: 169 typedef std::set<SafeBrowsingCheck*> CurrentChecks; 170 typedef std::vector<SafeBrowsingCheck*> GetHashRequestors; 171 typedef base::hash_map<SBPrefix, GetHashRequestors> GetHashRequests; 172 173 // Used for whitelisting a render view when the user ignores our warning. 174 struct WhiteListedEntry { 175 int render_process_host_id; 176 int render_view_id; 177 std::string domain; 178 UrlCheckResult result; 179 }; 180 181 // Clients that we've queued up for checking later once the database is ready. 182 struct QueuedCheck { 183 Client* client; 184 GURL url; 185 base::Time start; 186 }; 187 188 friend class base::RefCountedThreadSafe<SafeBrowsingService>; 189 friend class SafeBrowsingServiceTest; 190 191 ~SafeBrowsingService(); 192 193 // Called to initialize objects that are used on the io_thread. 194 void OnIOInitialize(const std::string& client_key, 195 const std::string& wrapped_key, 196 URLRequestContextGetter* request_context_getter); 197 198 // Called to shutdown operations on the io_thread. 199 void OnIOShutdown(); 200 201 // Returns whether |database_| exists and is accessible. 202 bool DatabaseAvailable() const; 203 204 // Called on the IO thread. If the database does not exist, queues up a call 205 // on the db thread to create it. Returns whether the database is available. 206 // 207 // Note that this is only needed outside the db thread, since functions on the 208 // db thread can call GetDatabase() directly. 209 bool MakeDatabaseAvailable(); 210 211 // Should only be called on db thread as SafeBrowsingDatabase is not 212 // threadsafe. 213 SafeBrowsingDatabase* GetDatabase(); 214 215 // Called on the IO thread with the check result. 216 void OnCheckDone(SafeBrowsingCheck* info); 217 218 // Called on the database thread to retrieve chunks. 219 void GetAllChunksFromDatabase(); 220 221 // Called on the IO thread with the results of all chunks. 222 void OnGetAllChunksFromDatabase(const std::vector<SBListChunkRanges>& lists, 223 bool database_error); 224 225 // Called on the IO thread after the database reports that it added a chunk. 226 void OnChunkInserted(); 227 228 // Notification that the database is done loading its bloom filter. We may 229 // have had to queue checks until the database is ready, and if so, this 230 // checks them. 231 void DatabaseLoadComplete(); 232 233 // Called on the database thread to add/remove chunks and host keys. 234 // Callee will free the data when it's done. 235 void HandleChunkForDatabase(const std::string& list, 236 SBChunkList* chunks); 237 238 void DeleteChunks(std::vector<SBChunkDelete>* chunk_deletes); 239 240 static UrlCheckResult GetResultFromListname(const std::string& list_name); 241 242 void NotifyClientBlockingComplete(Client* client, bool proceed); 243 244 void DatabaseUpdateFinished(bool update_succeeded); 245 246 // Start up SafeBrowsing objects. This can be called at browser start, or when 247 // the user checks the "Enable SafeBrowsing" option in the Advanced options 248 // UI. 249 void Start(); 250 251 // Called on the db thread to close the database. See CloseDatabase(). 252 void OnCloseDatabase(); 253 254 // Runs on the db thread to reset the database. We assume that resetting the 255 // database is a synchronous operation. 256 void OnResetDatabase(); 257 258 // Store in-memory the GetHash response. Runs on the database thread. 259 void CacheHashResults(const std::vector<SBPrefix>& prefixes, 260 const std::vector<SBFullHashResult>& full_hashes); 261 262 // Internal worker function for processing full hashes. 263 void OnHandleGetHashResults(SafeBrowsingCheck* check, 264 const std::vector<SBFullHashResult>& full_hashes); 265 266 void HandleOneCheck(SafeBrowsingCheck* check, 267 const std::vector<SBFullHashResult>& full_hashes); 268 269 // Invoked on the UI thread to show the blocking page. 270 void DoDisplayBlockingPage(const UnsafeResource& resource); 271 272 // Report any pages that contain malware sub-resources to the SafeBrowsing 273 // service. 274 void ReportMalware(const GURL& malware_url, 275 const GURL& page_url, 276 const GURL& referrer_url, 277 bool is_subresource); 278 279 CurrentChecks checks_; 280 281 // Used for issuing only one GetHash request for a given prefix. 282 GetHashRequests gethash_requests_; 283 284 // The sqlite database. We don't use a scoped_ptr because it needs to be 285 // destructed on a different thread than this object. 286 SafeBrowsingDatabase* database_; 287 288 // Lock used to prevent possible data races due to compiler optimizations. 289 mutable Lock database_lock_; 290 291 // Handles interaction with SafeBrowsing servers. 292 SafeBrowsingProtocolManager* protocol_manager_; 293 294 std::vector<WhiteListedEntry> white_listed_entries_; 295 296 // Whether the service is running. 'enabled_' is used by SafeBrowsingService 297 // on the IO thread during normal operations. 298 bool enabled_; 299 300 // The SafeBrowsing thread that runs database operations. 301 // 302 // Note: Functions that run on this thread should run synchronously and return 303 // to the IO thread, not post additional tasks back to this thread, lest we 304 // cause a race condition at shutdown time that leads to a database leak. 305 scoped_ptr<base::Thread> safe_browsing_thread_; 306 307 // Indicates if we're currently in an update cycle. 308 bool update_in_progress_; 309 310 // When true, newly fetched chunks may not in the database yet since the 311 // database is still updating. 312 bool database_update_in_progress_; 313 314 // Indicates if we're in the midst of trying to close the database. If this 315 // is true, nothing on the IO thread should access the database. 316 bool closing_database_; 317 318 std::deque<QueuedCheck> queued_checks_; 319 320 DISALLOW_COPY_AND_ASSIGN(SafeBrowsingService); 321}; 322 323#endif // CHROME_BROWSER_SAFE_BROWSING_SAFE_BROWSING_SERVICE_H_ 324