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"
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/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 "net/base/net_util.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_fetcher_delegate.h"
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.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)
13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Returns true if we have sent more than kMaxReportsPerInterval phishing
13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // reports in the last kReportsInterval.
13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual bool OverPhishingReportLimit();
13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Returns true if we have sent more than kMaxReportsPerInterval malware
14090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // reports in the last kReportsInterval.
14190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  virtual bool OverMalwareReportLimit();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Use Create() method to create an instance of this object.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit ClientSideDetectionService(
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::URLRequestContextGetter* request_context_getter);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Enum used to keep stats about why we fail to get the client model.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum ClientModelStatus {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_SUCCESS,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_NOT_CHANGED,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_FETCH_FAILED,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_EMPTY,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_TOO_LARGE,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_PARSE_ERROR,
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_MISSING_FIELDS,
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_INVALID_VERSION_NUMBER,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_BAD_HASH_IDS,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    MODEL_STATUS_MAX  // Always add new values before this one.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starts fetching the model from the network or the cache.  This method
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is called periodically to check whether a new client model is available
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for download.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartFetchModel();
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Schedules the next fetch of the model.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ScheduleFetchModel(int64 delay_ms);  // Virtual for testing.
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method is called when we're done fetching the model either because
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we hit an error somewhere or because we're actually done fetch and
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // validating the model.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void EndFetchModel(ClientModelStatus status);  // Virtual for testing.
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  friend class ClientSideDetectionServiceTest;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, FetchModelTest);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, SetBadSubnets);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           SetEnabledAndRefreshState);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest, IsBadIpAddress);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(ClientSideDetectionServiceTest,
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           ModelHasValidHashIds);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CacheState holds all information necessary to respond to a caller without
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // actually making a HTTP request.
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct CacheState {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool is_phishing;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::Time timestamp;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CacheState(bool phish, base::Time time);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<GURL, linked_ptr<CacheState> > PhishingCache;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // A tuple of (IP address block, prefix size) representing a private
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IP address range.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::pair<net::IPAddressNumber, size_t> AddressRange;
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Maps a IPv6 subnet mask to a set of hashed IPv6 subnets.  The IPv6
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // subnets are in network order and hashed with sha256.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::map<std::string /* subnet mask */,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   std::set<std::string /* hashed subnet */> > BadSubnetMap;
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static const char kClientReportMalwareUrl[];
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kClientReportPhishingUrl[];
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const char kClientModelUrl[];
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const size_t kMaxModelSizeBytes;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kMaxReportsPerInterval;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kClientModelFetchIntervalMs;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kInitialClientModelFetchDelayMs;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kReportsIntervalDays;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kNegativeCacheIntervalDays;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kPositiveCacheIntervalMinutes;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Starts sending the request to the client-side detection frontends.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method takes ownership of both pointers.
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void StartClientReportPhishingRequest(
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ClientPhishingRequest* verdict,
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const ClientReportPhishingRequestCallback& callback);
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void StartClientReportMalwareRequest(
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ClientMalwareRequest* verdict,
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const ClientReportMalwareRequestCallback& callback);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by OnURLFetchComplete to handle the response from fetching the
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // model.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleModelResponse(const net::URLFetcher* source,
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const GURL& url,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const net::URLRequestStatus& status,
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           int response_code,
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const net::ResponseCookies& cookies,
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const std::string& data);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called by OnURLFetchComplete to handle the server response from
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sending the client-side phishing request.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandlePhishingVerdict(const net::URLFetcher* source,
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const GURL& url,
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const net::URLRequestStatus& status,
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             int response_code,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const net::ResponseCookies& cookies,
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const std::string& data);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called by OnURLFetchComplete to handle the server response from
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // sending the client-side malware request.
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void HandleMalwareVerdict(const net::URLFetcher* source,
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            const GURL& url,
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            const net::URLRequestStatus& status,
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            int response_code,
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            const net::ResponseCookies& cookies,
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            const std::string& data);
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Invalidate cache results which are no longer useful.
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateCache();
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Get the number of malware reports that we have sent over kReportsInterval.
25690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int GetMalwareNumReports();
25790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
25890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Get the number of phishing reports that we have sent over kReportsInterval.
25990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int GetPhishingNumReports();
26090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
26190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Get the number of reports that we have sent over kReportsInterval, and
26290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // trims off the old elements.
26390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  int GetNumReports(std::queue<base::Time>* report_times);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes the |private_networks_| vector with the network blocks
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that we consider non-public IP addresses.  Returns true on success.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool InitializePrivateNetworks();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send the model to the given renderer.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SendModelToProcess(content::RenderProcessHost* process);
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Same as above but sends the model to all rendereres.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SendModelToRenderers();
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reads the bad subnets from the client model and inserts them into
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |bad_subnets| for faster lookups.  This method is static to simplify
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // testing.
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void SetBadSubnets(const ClientSideModel& model,
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            BadSubnetMap* bad_subnets);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true iff all the hash id's in the client-side model point to
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // valid hashes in the model.
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool ModelHasValidHashIds(const ClientSideModel& model);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the URL that will be used for phishing requests.
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static std::string GetClientReportUrl(const std::string& report_url);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether the service is running or not.  When the service is not running,
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // it won't download the model nor report detected phishing URLs.
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool enabled_;
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string model_str_;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ClientSideModel> model_;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::TimeDelta> model_max_age_;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<net::URLFetcher> model_fetcher_;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Map of client report phishing request to the corresponding callback that
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // has to be invoked when the request is done.
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  struct ClientReportInfo;
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::map<const net::URLFetcher*, ClientReportInfo*>
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      client_phishing_reports_;
3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<const net::URLFetcher*, ClientReportInfo*>
3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      client_malware_reports_;
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Cache of completed requests. Used to satisfy requests for the same urls
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // as long as the next request falls within our caching window (which is
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // determined by kNegativeCacheInterval and kPositiveCacheInterval). The
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // size of this cache is limited by kMaxReportsPerDay *
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ceil(InDays(max(kNegativeCacheInterval, kPositiveCacheInterval))).
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(gcasto): Serialize this so that it doesn't reset on browser restart.
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PhishingCache cache_;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Timestamp of when we sent a phishing request. Used to limit the number
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of phishing requests that we send in a day.
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(gcasto): Serialize this so that it doesn't reset on browser restart.
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::queue<base::Time> phishing_report_times_;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // Timestamp of when we sent a malware request. Used to limit the number
32090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  // of malware requests that we send in a day.
32190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::queue<base::Time> malware_report_times_;
32290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to asynchronously call the callbacks for
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SendClientReportPhishingRequest.
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WeakPtrFactory<ClientSideDetectionService> weak_factory_;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The context we use to issue network requests.
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The network blocks that we consider private IP address ranges.
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<AddressRange> private_networks_;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Map of bad subnets which are copied from the client model and put into
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this map to speed up lookups.
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BadSubnetMap bad_subnets_;
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ClientSideDetectionService);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namepsace safe_browsing
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_SAFE_BROWSING_CLIENT_SIDE_DETECTION_SERVICE_H_
344