client_side_detection_service.h revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Helper class which handles communication with the SafeBrowsing backends for
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// client-side phishing detection.  This class is used to fetch the client-side
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// model and send it to all renderers.  This class is also used to send a ping
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// back to Google to verify if a particular site is really phishing or not.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class is not thread-safe and expects all calls to be made on the UI
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// thread.  We also expect that the calling thread runs a message loop.
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_H_
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_H_
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map>
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <queue>
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility>
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_forward.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/linked_ptr.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/time.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_observer.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_registrar.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SafeBrowsingService;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TimeDelta;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content {
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RenderProcessHost;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLFetcher;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestContextGetter;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLRequestStatus;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::vector<std::string> ResponseCookies;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace safe_browsing {
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ClientMalwareRequest;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientPhishingRequest;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientPhishingResponse;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientSideModel;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ClientSideDetectionService : public net::URLFetcherDelegate,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   public content::NotificationObserver {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // void(GURL phishing_url, bool is_phishing).
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef base::Callback<void(GURL, bool)> ClientReportPhishingRequestCallback;
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef base::Callback<void(GURL, bool)> ClientReportMalwareRequestCallback;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~ClientSideDetectionService();
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a client-side detection service.  The service is initially
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // disabled, use SetEnabledAndRefreshState() to start it.  The caller takes
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ownership of the object.  This function may return NULL.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static ClientSideDetectionService* Create(
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::URLRequestContextGetter* request_context_getter);
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enables or disables the service, and refreshes the state of all renderers.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is usually called by the SafeBrowsingService, which tracks whether
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // any profile uses these services at all.  Disabling cancels any pending
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requests; existing ClientSideDetectionHosts will have their callbacks
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called with "false" verdicts.  Enabling starts downloading the model after
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a delay.  In all cases, each render process is updated to match the state
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of the SafeBrowsing preference for that profile.
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetEnabledAndRefreshState(bool enabled);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool enabled() const {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return enabled_;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // From the net::URLFetcherDelegate interface.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // content::NotificationObserver overrides:
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type,
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationSource& source,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sends a request to the SafeBrowsing servers with the ClientPhishingRequest.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The URL scheme of the |url()| in the request should be HTTP.  This method
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // takes ownership of the |verdict| as well as the |callback| and calls the
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the callback once the result has come back from the server or if an error
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // occurs during the fetch.  If the service is disabled or an error occurs
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the phishing verdict will always be false.  The callback is always called
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // after SendClientReportPhishingRequest() returns and on the same thread as
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SendClientReportPhishingRequest() was called.  You may set |callback| to
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NULL if you don't care about the server verdict.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SendClientReportPhishingRequest(
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ClientPhishingRequest* verdict,
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const ClientReportPhishingRequestCallback& callback);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Similar to above one, instead send ClientMalwareRequest
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SendClientReportMalwareRequest(
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ClientMalwareRequest* verdict,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const ClientReportMalwareRequestCallback& callback);
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the given IP address string falls within a private
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // (unroutable) network block.  Pages which are hosted on these IP addresses
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are exempt from client-side phishing detection.  This is called by the
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ClientSideDetectionHost prior to sending the renderer a
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SafeBrowsingMsg_StartPhishingDetection IPC.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ip_address should be a dotted IPv4 address, or an unbracketed IPv6
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // address.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsPrivateIPAddress(const std::string& ip_address) const;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the given IP address is on the list of known bad IPs.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ip_address should be a dotted IPv4 address, or an unbracketed IPv6
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // address.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsBadIpAddress(const std::string& ip_address) const;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true and sets is_phishing if url is in the cache and valid.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool GetValidCachedResult(const GURL& url, bool* is_phishing);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if the url is in the cache.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool IsInCache(const GURL& url);
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if we have sent more than kMaxReportsPerInterval in the last
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // kReportsInterval.
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OverReportLimit();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use Create() method to create an instance of this object.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ClientSideDetectionService(
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::URLRequestContextGetter* request_context_getter);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enum used to keep stats about why we fail to get the client model.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ClientModelStatus {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_SUCCESS,
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_NOT_CHANGED,
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_FETCH_FAILED,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_EMPTY,
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_TOO_LARGE,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_PARSE_ERROR,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_MISSING_FIELDS,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_INVALID_VERSION_NUMBER,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_BAD_HASH_IDS,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_STATUS_MAX  // Always add new values before this one.
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starts fetching the model from the network or the cache.  This method
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is called periodically to check whether a new client model is available
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for download.
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartFetchModel();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Schedules the next fetch of the model.
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ScheduleFetchModel(int64 delay_ms);  // Virtual for testing.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method is called when we're done fetching the model either because
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we hit an error somewhere or because we're actually done fetch and
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // validating the model.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void EndFetchModel(ClientModelStatus status);  // Virtual for testing.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ClientSideDetectionServiceTest;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, FetchModelTest);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, SetBadSubnets);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           SetEnabledAndRefreshState);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, IsBadIpAddress);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           ModelHasValidHashIds);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CacheState holds all information necessary to respond to a caller without
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // actually making a HTTP request.
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct CacheState {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_phishing;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time timestamp;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CacheState(bool phish, base::Time time);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<GURL, linked_ptr<CacheState> > PhishingCache;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A tuple of (IP address block, prefix size) representing a private
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IP address range.
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::pair<net::IPAddressNumber, size_t> AddressRange;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Maps a IPv6 subnet mask to a set of hashed IPv6 subnets.  The IPv6
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // subnets are in network order and hashed with sha256.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<std::string /* subnet mask */,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   std::set<std::string /* hashed subnet */> > BadSubnetMap;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const char kClientReportMalwareUrl[];
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kClientReportPhishingUrl[];
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kClientModelUrl[];
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const size_t kMaxModelSizeBytes;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kMaxReportsPerInterval;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kClientModelFetchIntervalMs;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kInitialClientModelFetchDelayMs;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kReportsIntervalDays;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNegativeCacheIntervalDays;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kPositiveCacheIntervalMinutes;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starts sending the request to the client-side detection frontends.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method takes ownership of both pointers.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartClientReportPhishingRequest(
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ClientPhishingRequest* verdict,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const ClientReportPhishingRequestCallback& callback);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StartClientReportMalwareRequest(
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ClientMalwareRequest* verdict,
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const ClientReportMalwareRequestCallback& callback);
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by OnURLFetchComplete to handle the response from fetching the
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // model.
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleModelResponse(const net::URLFetcher* source,
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const GURL& url,
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const net::URLRequestStatus& status,
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           int response_code,
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const net::ResponseCookies& cookies,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const std::string& data);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by OnURLFetchComplete to handle the server response from
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sending the client-side phishing request.
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandlePhishingVerdict(const net::URLFetcher* source,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const GURL& url,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const net::URLRequestStatus& status,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int response_code,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const net::ResponseCookies& cookies,
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const std::string& data);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called by OnURLFetchComplete to handle the server response from
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // sending the client-side malware request.
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void HandleMalwareVerdict(const net::URLFetcher* source,
2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            const GURL& url,
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            const net::URLRequestStatus& status,
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            int response_code,
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            const net::ResponseCookies& cookies,
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            const std::string& data);
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalidate cache results which are no longer useful.
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateCache();
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get the number of phishing reports that we have sent over kReportsInterval
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int GetNumReports();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes the |private_networks_| vector with the network blocks
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that we consider non-public IP addresses.  Returns true on success.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool InitializePrivateNetworks();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send the model to the given renderer.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SendModelToProcess(content::RenderProcessHost* process);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Same as above but sends the model to all rendereres.
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SendModelToRenderers();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reads the bad subnets from the client model and inserts them into
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |bad_subnets| for faster lookups.  This method is static to simplify
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // testing.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void SetBadSubnets(const ClientSideModel& model,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            BadSubnetMap* bad_subnets);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true iff all the hash id's in the client-side model point to
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // valid hashes in the model.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool ModelHasValidHashIds(const ClientSideModel& model);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the URL that will be used for phishing requests.
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static std::string GetClientReportUrl(const std::string& report_url);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether the service is running or not.  When the service is not running,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it won't download the model nor report detected phishing URLs.
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool enabled_;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string model_str_;
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ClientSideModel> model_;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::TimeDelta> model_max_age_;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::URLFetcher> model_fetcher_;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Map of client report phishing request to the corresponding callback that
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has to be invoked when the request is done.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ClientReportInfo;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<const net::URLFetcher*, ClientReportInfo*>
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_phishing_reports_;
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<const net::URLFetcher*, ClientReportInfo*>
2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      client_malware_reports_;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cache of completed requests. Used to satisfy requests for the same urls
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as long as the next request falls within our caching window (which is
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // determined by kNegativeCacheInterval and kPositiveCacheInterval). The
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // size of this cache is limited by kMaxReportsPerDay *
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ceil(InDays(max(kNegativeCacheInterval, kPositiveCacheInterval))).
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(gcasto): Serialize this so that it doesn't reset on browser restart.
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PhishingCache cache_;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp of when we sent a phishing request. Used to limit the number
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of phishing requests that we send in a day.
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(gcasto): Serialize this so that it doesn't reset on browser restart.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::queue<base::Time> phishing_report_times_;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to asynchronously call the callbacks for
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SendClientReportPhishingRequest.
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<ClientSideDetectionService> weak_factory_;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The context we use to issue network requests.
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The network blocks that we consider private IP address ranges.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<AddressRange> private_networks_;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Map of bad subnets which are copied from the client model and put into
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this map to speed up lookups.
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BadSubnetMap bad_subnets_;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ClientSideDetectionService);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namepsace safe_browsing
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_H_
329