| // Copyright 2016 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_SAFE_BROWSING_DB_V4_UPDATE_PROTOCOL_MANAGER_H_ |
| #define COMPONENTS_SAFE_BROWSING_DB_V4_UPDATE_PROTOCOL_MANAGER_H_ |
| |
| // A class that implements Chrome's interface with the SafeBrowsing V4 update |
| // protocol. |
| // |
| // The V4UpdateProtocolManager handles formatting and making requests of, and |
| // handling responses from, Google's SafeBrowsing servers. The purpose of this |
| // class is to get hash prefixes from the SB server for the given set of lists. |
| |
| #include <memory> |
| #include <string> |
| #include <vector> |
| |
| #include "base/gtest_prod_util.h" |
| #include "base/macros.h" |
| #include "base/sequence_checker.h" |
| #include "base/time/time.h" |
| #include "base/timer/timer.h" |
| #include "components/safe_browsing/common/safe_browsing_prefs.h" |
| #include "components/safe_browsing/web_ui/webui.pb.h" |
| #include "components/safe_browsing_db/safebrowsing.pb.h" |
| #include "components/safe_browsing_db/util.h" |
| #include "components/safe_browsing_db/v4_protocol_manager_util.h" |
| #include "net/url_request/url_fetcher_delegate.h" |
| |
| class GURL; |
| |
| namespace net { |
| class URLFetcher; |
| class URLRequestContextGetter; |
| } // namespace net |
| |
| namespace safe_browsing { |
| |
| class V4UpdateProtocolManagerFactory; |
| |
| // V4UpdateCallback is invoked when a scheduled update completes. |
| // Parameters: |
| // - The vector of update response protobufs received from the server for |
| // each list type. |
| typedef base::Callback<void(std::unique_ptr<ParsedServerResponse>)> |
| V4UpdateCallback; |
| |
| typedef base::Callback<ExtendedReportingLevel()> ExtendedReportingLevelCallback; |
| |
| class V4UpdateProtocolManager : public net::URLFetcherDelegate { |
| public: |
| ~V4UpdateProtocolManager() override; |
| |
| // Makes the passed |factory| the factory used to instantiate |
| // a V4UpdateProtocolManager. Useful for tests. |
| static void RegisterFactory(V4UpdateProtocolManagerFactory* factory) { |
| factory_ = factory; |
| } |
| |
| // Create an instance of the safe browsing v4 protocol manager. |
| static std::unique_ptr<V4UpdateProtocolManager> Create( |
| net::URLRequestContextGetter* request_context_getter, |
| const V4ProtocolConfig& config, |
| V4UpdateCallback update_callback, |
| ExtendedReportingLevelCallback extended_reporting_level_callback); |
| |
| // net::URLFetcherDelegate interface. |
| void OnURLFetchComplete(const net::URLFetcher* source) override; |
| |
| // Schedule the next update without backoff. |
| void ScheduleNextUpdate(std::unique_ptr<StoreStateMap> store_state_map); |
| |
| // Populates the UpdateInfo message. |
| void CollectUpdateInfo(DatabaseManagerInfo::UpdateInfo* database_info); |
| |
| protected: |
| // Constructs a V4UpdateProtocolManager that issues network requests using |
| // |request_context_getter|. It schedules updates to get the hash prefixes for |
| // SafeBrowsing lists, and invoke |callback| when the results are retrieved. |
| // The callback may be invoked synchronously. |
| V4UpdateProtocolManager( |
| net::URLRequestContextGetter* request_context_getter, |
| const V4ProtocolConfig& config, |
| V4UpdateCallback update_callback, |
| ExtendedReportingLevelCallback extended_reporting_level_callback); |
| |
| private: |
| FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest, |
| TestGetUpdatesErrorHandlingNetwork); |
| FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest, |
| TestGetUpdatesErrorHandlingResponseCode); |
| FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest, TestGetUpdatesNoError); |
| FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest, |
| TestGetUpdatesWithOneBackoff); |
| FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest, |
| TestBase64EncodingUsesUrlEncoding); |
| FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest, TestDisableAutoUpdates); |
| FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest, |
| TestGetUpdatesHasTimeout); |
| FRIEND_TEST_ALL_PREFIXES(V4UpdateProtocolManagerTest, |
| TestExtendedReportingLevelIncluded); |
| friend class V4UpdateProtocolManagerFactoryImpl; |
| |
| // Fills a FetchThreatListUpdatesRequest protocol buffer for a request. |
| // Returns the serialized and base64 URL encoded request as a string. |
| std::string GetBase64SerializedUpdateRequestProto(); |
| |
| // Records the network response code of the last update |
| int last_response_code_ = 0; |
| |
| // The method to populate |gurl| with the URL to be sent to the server. |
| // |request_base64| is the base64 encoded form of an instance of the protobuf |
| // FetchThreatListUpdatesRequest. Also sets the appropriate header values for |
| // sending PVer4 requests in |headers|. |
| void GetUpdateUrlAndHeaders(const std::string& request_base64, |
| GURL* gurl, |
| net::HttpRequestHeaders* headers) const; |
| |
| // Parses the base64 encoded response received from the server as a |
| // FetchThreatListUpdatesResponse protobuf and returns each of the |
| // ListUpdateResponse protobufs contained in it as a vector. |
| // Returns true if parsing is successful, false otherwise. |
| bool ParseUpdateResponse(const std::string& data_base64, |
| ParsedServerResponse* parsed_server_response); |
| |
| // Resets the update error counter and multiplier. |
| void ResetUpdateErrors(); |
| |
| // Called when update request times out. Cancels the existing request and |
| // re-sends the update request. |
| void HandleTimeout(); |
| |
| // Updates internal update and backoff state for each update response error, |
| // assuming that the current time is |now|. |
| void HandleUpdateError(const base::Time& now); |
| |
| // Generates the URL for the update request and issues the request for the |
| // lists passed to the constructor. |
| void IssueUpdateRequest(); |
| |
| // Returns whether another update is currently scheduled. |
| bool IsUpdateScheduled() const; |
| |
| // Schedule the next update with backoff specified. |
| void ScheduleNextUpdateWithBackoff(bool back_off); |
| |
| // Schedule the next update, after the given interval. |
| void ScheduleNextUpdateAfterInterval(base::TimeDelta interval); |
| |
| // Get the next update interval, considering whether we are in backoff. |
| base::TimeDelta GetNextUpdateInterval(bool back_off); |
| |
| // The factory that controls the creation of V4UpdateProtocolManager. |
| // This is used by tests. |
| static V4UpdateProtocolManagerFactory* factory_; |
| |
| // The last known state of the lists. |
| // Updated after every successful update of the database. |
| std::unique_ptr<StoreStateMap> store_state_map_; |
| |
| // The number of HTTP response errors since the the last successful HTTP |
| // response, used for request backoff timing. |
| size_t update_error_count_; |
| |
| // Multiplier for the backoff error after the second. |
| size_t update_back_off_mult_; |
| |
| // The time delta after which the next update request may be sent. |
| // It is set to a random interval between 60 and 300 seconds at start. |
| // The server can set it by setting the minimum_wait_duration. |
| base::TimeDelta next_update_interval_; |
| |
| // The config of the client making Pver4 requests. |
| const V4ProtocolConfig config_; |
| |
| // The context we use to issue network requests. |
| scoped_refptr<net::URLRequestContextGetter> request_context_getter_; |
| |
| // ID for URLFetchers for testing. |
| int url_fetcher_id_; |
| |
| // The callback that's called when GetUpdates completes. |
| V4UpdateCallback update_callback_; |
| |
| // The pending update request. The request must be canceled when the object is |
| // destroyed. |
| std::unique_ptr<net::URLFetcher> request_; |
| |
| // Timer to setup the next update request. |
| base::OneShotTimer update_timer_; |
| |
| base::Time last_response_time_; |
| |
| // Used to interrupt and re-schedule update requests that take too long to |
| // complete. |
| base::OneShotTimer timeout_timer_; |
| |
| ExtendedReportingLevelCallback extended_reporting_level_callback_; |
| |
| SEQUENCE_CHECKER(sequence_checker_); |
| |
| DISALLOW_COPY_AND_ASSIGN(V4UpdateProtocolManager); |
| }; |
| |
| // Interface of a factory to create V4UpdateProtocolManager. Useful for tests. |
| class V4UpdateProtocolManagerFactory { |
| public: |
| V4UpdateProtocolManagerFactory() {} |
| virtual ~V4UpdateProtocolManagerFactory() {} |
| virtual std::unique_ptr<V4UpdateProtocolManager> CreateProtocolManager( |
| net::URLRequestContextGetter* request_context_getter, |
| const V4ProtocolConfig& config, |
| V4UpdateCallback update_callback, |
| ExtendedReportingLevelCallback extended_reporting_level_callback) = 0; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(V4UpdateProtocolManagerFactory); |
| }; |
| |
| } // namespace safe_browsing |
| |
| #endif // COMPONENTS_SAFE_BROWSING_DB_V4_UPDATE_PROTOCOL_MANAGER_H_ |