blob: 0b5f69f3be9262e7a64d620c5862330852216f43 [file] [log] [blame]
// Copyright (c) 2012 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.
//
// Helper class which handles communication with the SafeBrowsing servers for
// improved binary download protection.
#ifndef CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_SERVICE_H_
#define CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_SERVICE_H_
#include <set>
#include <string>
#include <vector>
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/safe_browsing/database_manager.h"
#include "chrome/browser/safe_browsing/ui_manager.h"
#include "url/gurl.h"
namespace content {
class DownloadItem;
class PageNavigator;
}
namespace net {
class URLRequestContextGetter;
class X509Certificate;
} // namespace net
namespace safe_browsing {
class DownloadFeedbackService;
class BinaryFeatureExtractor;
// This class provides an asynchronous API to check whether a particular
// client download is malicious or not.
class DownloadProtectionService {
public:
enum DownloadCheckResult {
SAFE,
DANGEROUS,
UNCOMMON,
DANGEROUS_HOST,
POTENTIALLY_UNWANTED
};
// Callback type which is invoked once the download request is done.
typedef base::Callback<void(DownloadCheckResult)> CheckDownloadCallback;
// Creates a download service. The service is initially disabled. You need
// to call SetEnabled() to start it. |sb_service| owns this object; we
// keep a reference to |request_context_getter|.
DownloadProtectionService(
SafeBrowsingService* sb_service,
net::URLRequestContextGetter* request_context_getter);
virtual ~DownloadProtectionService();
// Checks whether the given client download is likely to be malicious or not.
// The result is delivered asynchronously via the given callback. This
// method must be called on the UI thread, and the callback will also be
// invoked on the UI thread. This method must be called once the download
// is finished and written to disk.
virtual void CheckClientDownload(content::DownloadItem* item,
const CheckDownloadCallback& callback);
// Checks whether any of the URLs in the redirect chain of the
// download match the SafeBrowsing bad binary URL list. The result is
// delivered asynchronously via the given callback. This method must be
// called on the UI thread, and the callback will also be invoked on the UI
// thread. Pre-condition: !info.download_url_chain.empty().
virtual void CheckDownloadUrl(const content::DownloadItem& item,
const CheckDownloadCallback& callback);
// Returns true iff the download specified by |info| should be scanned by
// CheckClientDownload() for malicious content.
virtual bool IsSupportedDownload(const content::DownloadItem& item,
const base::FilePath& target_path) const;
// Display more information to the user regarding the download specified by
// |info|. This method is invoked when the user requests more information
// about a download that was marked as malicious.
void ShowDetailsForDownload(const content::DownloadItem& item,
content::PageNavigator* navigator);
// Enables or disables the service. This is usually called by the
// SafeBrowsingService, which tracks whether any profile uses these services
// at all. Disabling causes any pending and future requests to have their
// callbacks called with "SAFE" results.
void SetEnabled(bool enabled);
bool enabled() const {
return enabled_;
}
// Returns the timeout that is used by CheckClientDownload().
int64 download_request_timeout_ms() const {
return download_request_timeout_ms_;
}
DownloadFeedbackService* feedback_service() {
return feedback_service_.get();
}
protected:
// Enum to keep track why a particular download verdict was chosen.
// This is used to keep some stats around.
enum DownloadCheckResultReason {
REASON_INVALID_URL,
REASON_SB_DISABLED,
REASON_WHITELISTED_URL,
REASON_WHITELISTED_REFERRER,
REASON_INVALID_REQUEST_PROTO,
REASON_SERVER_PING_FAILED,
REASON_INVALID_RESPONSE_PROTO,
REASON_NOT_BINARY_FILE,
REASON_REQUEST_CANCELED,
REASON_DOWNLOAD_DANGEROUS,
REASON_DOWNLOAD_SAFE,
REASON_EMPTY_URL_CHAIN,
DEPRECATED_REASON_HTTPS_URL,
REASON_PING_DISABLED,
REASON_TRUSTED_EXECUTABLE,
REASON_OS_NOT_SUPPORTED,
REASON_DOWNLOAD_UNCOMMON,
REASON_DOWNLOAD_NOT_SUPPORTED,
REASON_INVALID_RESPONSE_VERDICT,
REASON_ARCHIVE_WITHOUT_BINARIES,
REASON_DOWNLOAD_DANGEROUS_HOST,
REASON_DOWNLOAD_POTENTIALLY_UNWANTED,
REASON_MAX // Always add new values before this one.
};
private:
class CheckClientDownloadRequest; // Per-request state
friend class DownloadProtectionServiceTest;
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
CheckClientDownloadWhitelistedUrl);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
CheckClientDownloadValidateRequest);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
CheckClientDownloadSuccess);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
CheckClientDownloadHTTPS);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
CheckClientDownloadZip);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
CheckClientDownloadFetchFailed);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
TestDownloadRequestTimeout);
FRIEND_TEST_ALL_PREFIXES(DownloadProtectionServiceTest,
CheckClientCrxDownloadSuccess);
static const char kDownloadRequestUrl[];
// Cancels all requests in |download_requests_|, and empties it, releasing
// the references to the requests.
void CancelPendingRequests();
// Called by a CheckClientDownloadRequest instance when it finishes, to
// remove it from |download_requests_|.
void RequestFinished(CheckClientDownloadRequest* request);
// Given a certificate and its immediate issuer certificate, generates the
// list of strings that need to be checked against the download whitelist to
// determine whether the certificate is whitelisted.
static void GetCertificateWhitelistStrings(
const net::X509Certificate& certificate,
const net::X509Certificate& issuer,
std::vector<std::string>* whitelist_strings);
// Returns the URL that will be used for download requests.
static GURL GetDownloadRequestUrl();
// These pointers may be NULL if SafeBrowsing is disabled.
scoped_refptr<SafeBrowsingUIManager> ui_manager_;
scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
// The context we use to issue network requests.
scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
// Map of client download request to the corresponding callback that
// has to be invoked when the request is done. This map contains all
// pending server requests.
std::set<scoped_refptr<CheckClientDownloadRequest> > download_requests_;
// Keeps track of the state of the service.
bool enabled_;
// BinaryFeatureExtractor object, may be overridden for testing.
scoped_refptr<BinaryFeatureExtractor> binary_feature_extractor_;
int64 download_request_timeout_ms_;
scoped_ptr<DownloadFeedbackService> feedback_service_;
DISALLOW_COPY_AND_ASSIGN(DownloadProtectionService);
};
} // namespace safe_browsing
#endif // CHROME_BROWSER_SAFE_BROWSING_DOWNLOAD_PROTECTION_SERVICE_H_