summaryrefslogtreecommitdiffstats
path: root/chrome/browser/safe_browsing
diff options
context:
space:
mode:
authorlzheng@chromium.org <lzheng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-29 21:53:18 +0000
committerlzheng@chromium.org <lzheng@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-29 21:53:18 +0000
commit894c4e8a8146bfa89c66d4e4ab629d589fabd9ba (patch)
treec8bb18e20e6115b340cc9e62b3f9639626d58cac /chrome/browser/safe_browsing
parent878f43f91009570f2ddf3380236259635d26c82a (diff)
downloadchromium_src-894c4e8a8146bfa89c66d4e4ab629d589fabd9ba.zip
chromium_src-894c4e8a8146bfa89c66d4e4ab629d589fabd9ba.tar.gz
chromium_src-894c4e8a8146bfa89c66d4e4ab629d589fabd9ba.tar.bz2
Add switches and apis in safebrowsing protocol_manager that will allow end-to-end test later.
BUG=6787,47318 TEST=protocol_manager_unittest.cc Review URL: http://codereview.chromium.org/2868030 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@51177 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/safe_browsing')
-rw-r--r--chrome/browser/safe_browsing/protocol_manager.cc164
-rw-r--r--chrome/browser/safe_browsing/protocol_manager.h94
-rw-r--r--chrome/browser/safe_browsing/protocol_manager_unittest.cc122
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_service.cc31
-rw-r--r--chrome/browser/safe_browsing/safe_browsing_service.h2
5 files changed, 330 insertions, 83 deletions
diff --git a/chrome/browser/safe_browsing/protocol_manager.cc b/chrome/browser/safe_browsing/protocol_manager.cc
index 5a8baae..ff4338a 100644
--- a/chrome/browser/safe_browsing/protocol_manager.cc
+++ b/chrome/browser/safe_browsing/protocol_manager.cc
@@ -34,26 +34,6 @@ static const int kSbTimerStartIntervalSec = 5 * 60;
// The maximum time, in seconds, to wait for a response to an update request.
static const int kSbMaxUpdateWaitSec = 10;
-// Update URL for querying about the latest set of chunk updates.
-static const char* const kSbUpdateUrl =
- "http://safebrowsing.clients.google.com/safebrowsing/downloads?client=%s"
- "&appver=%s&pver=2.2";
-
-// GetHash request URL for retrieving full hashes.
-static const char* const kSbGetHashUrl =
- "http://safebrowsing.clients.google.com/safebrowsing/gethash?client=%s"
- "&appver=%s&pver=2.2";
-
-// New MAC client key requests URL.
-static const char* const kSbNewKeyUrl =
- "https://sb-ssl.google.com/safebrowsing/newkey?client=%s&appver=%s"
- "&pver=2.2";
-
-// URL for reporting malware pages.
-static const char* const kSbMalwareReportUrl =
- "http://safebrowsing.clients.google.com/safebrowsing/report?evts=malblhit"
- "&evtd=%s&evtr=%s&evhr=%s&client=%s&appver=%s";
-
// Maximum back off multiplier.
static const int kSbMaxBackOff = 8;
@@ -65,7 +45,10 @@ SafeBrowsingProtocolManager::SafeBrowsingProtocolManager(
const std::string& client_name,
const std::string& client_key,
const std::string& wrapped_key,
- URLRequestContextGetter* request_context_getter)
+ URLRequestContextGetter* request_context_getter,
+ const std::string& info_url_prefix,
+ const std::string& mackey_url_prefix,
+ bool disable_auto_update)
: sb_service_(sb_service),
request_type_(NO_REQUEST),
update_error_count_(0),
@@ -80,15 +63,18 @@ SafeBrowsingProtocolManager::SafeBrowsingProtocolManager(
wrapped_key_(wrapped_key),
update_size_(0),
client_name_(client_name),
- request_context_getter_(request_context_getter) {
+ request_context_getter_(request_context_getter),
+ info_url_prefix_(info_url_prefix),
+ mackey_url_prefix_(mackey_url_prefix),
+ disable_auto_update_(disable_auto_update) {
+ DCHECK(!info_url_prefix_.empty() && !mackey_url_prefix_.empty());
+
// Set the backoff multiplier fuzz to a random value between 0 and 1.
back_off_fuzz_ = static_cast<float>(base::RandDouble());
-
// The first update must happen between 1-5 minutes of start up.
next_update_sec_ = base::RandInt(60, kSbTimerStartIntervalSec);
- scoped_ptr<FileVersionInfo> version_info(
- chrome_app::GetChromeVersionInfo());
+ scoped_ptr<FileVersionInfo> version_info(chrome_app::GetChromeVersionInfo());
if (!version_info.get())
version_ = "0.1";
else
@@ -122,16 +108,8 @@ void SafeBrowsingProtocolManager::GetFullHash(
sb_service_->HandleGetHashResults(check, full_hashes, false);
return;
}
-
- std::string url = StringPrintf(kSbGetHashUrl,
- client_name_.c_str(),
- version_.c_str());
- if (!client_key_.empty()) {
- url.append("&wrkey=");
- url.append(wrapped_key_);
- }
-
- GURL gethash_url(url);
+ bool use_mac = !client_key_.empty();
+ GURL gethash_url = GetHashUrl(use_mac);
URLFetcher* fetcher = new URLFetcher(gethash_url, URLFetcher::POST, this);
hash_requests_[fetcher] = check;
@@ -448,14 +426,24 @@ void SafeBrowsingProtocolManager::Initialize() {
}
void SafeBrowsingProtocolManager::ScheduleNextUpdate(bool back_off) {
- DCHECK(next_update_sec_ > 0);
-
- // Unschedule any current timer.
- update_timer_.Stop();
+ DCHECK_GT(next_update_sec_, 0);
+ if (disable_auto_update_) {
+ // Unschedule any current timer.
+ update_timer_.Stop();
+ return;
+ }
// Reschedule with the new update.
const int next_update = GetNextUpdateTime(back_off);
- update_timer_.Start(TimeDelta::FromMilliseconds(next_update), this,
+ ForceScheduleNextUpdate(next_update);
+}
+
+void SafeBrowsingProtocolManager::ForceScheduleNextUpdate(
+ const int next_update_msec) {
+ DCHECK_GE(next_update_msec, 0);
+ // Unschedule any current timer.
+ update_timer_.Stop();
+ update_timer_.Start(TimeDelta::FromMilliseconds(next_update_msec), this,
&SafeBrowsingProtocolManager::GetNextUpdate);
}
@@ -513,10 +501,7 @@ void SafeBrowsingProtocolManager::IssueChunkRequest() {
ChunkUrl next_chunk = chunk_request_urls_.front();
DCHECK(!next_chunk.url.empty());
- if (!StartsWithASCII(next_chunk.url, "http://", false) &&
- !StartsWithASCII(next_chunk.url, "https://", false))
- next_chunk.url = "http://" + next_chunk.url;
- GURL chunk_url(next_chunk.url);
+ GURL chunk_url = NextChunkUrl(next_chunk.url);
request_type_ = CHUNK_REQUEST;
request_.reset(new URLFetcher(chunk_url, URLFetcher::GET, this));
request_->set_load_flags(net::LOAD_DISABLE_CACHE);
@@ -526,9 +511,7 @@ void SafeBrowsingProtocolManager::IssueChunkRequest() {
}
void SafeBrowsingProtocolManager::IssueKeyRequest() {
- GURL key_url(StringPrintf(kSbNewKeyUrl,
- client_name_.c_str(),
- version_.c_str()));
+ GURL key_url = MacKeyUrl();
request_type_ = GETKEY_REQUEST;
request_.reset(new URLFetcher(key_url, URLFetcher::GET, this));
request_->set_load_flags(net::LOAD_DISABLE_CACHE);
@@ -538,7 +521,7 @@ void SafeBrowsingProtocolManager::IssueKeyRequest() {
void SafeBrowsingProtocolManager::OnGetChunksComplete(
const std::vector<SBListChunkRanges>& lists, bool database_error) {
- DCHECK(request_type_ == UPDATE_REQUEST);
+ DCHECK_EQ(request_type_, UPDATE_REQUEST);
if (database_error) {
UpdateFinished(false);
ScheduleNextUpdate(false);
@@ -570,15 +553,7 @@ void SafeBrowsingProtocolManager::OnGetChunksComplete(
list_data.append(FormatList(
SBListChunkRanges(safe_browsing_util::kMalwareList), use_mac));
- std::string url = StringPrintf(kSbUpdateUrl,
- client_name_.c_str(),
- version_.c_str());
- if (use_mac) {
- url.append("&wrkey=");
- url.append(wrapped_key_);
- }
-
- GURL update_url(url);
+ GURL update_url = UpdateUrl(use_mac);
request_.reset(new URLFetcher(update_url, URLFetcher::POST, this));
request_->set_load_flags(net::LOAD_DISABLE_CACHE);
request_->set_request_context(request_context_getter_);
@@ -593,7 +568,7 @@ void SafeBrowsingProtocolManager::OnGetChunksComplete(
// If we haven't heard back from the server with an update response, this method
// will run. Close the current update session and schedule another update.
void SafeBrowsingProtocolManager::UpdateResponseTimeout() {
- DCHECK(request_type_ == UPDATE_REQUEST);
+ DCHECK_EQ(request_type_, UPDATE_REQUEST);
request_.reset();
UpdateFinished(false);
ScheduleNextUpdate(false);
@@ -613,14 +588,7 @@ void SafeBrowsingProtocolManager::OnChunkInserted() {
void SafeBrowsingProtocolManager::ReportMalware(const GURL& malware_url,
const GURL& page_url,
const GURL& referrer_url) {
- std::string report_str = StringPrintf(
- kSbMalwareReportUrl,
- EscapeQueryParamValue(malware_url.spec(), true).c_str(),
- EscapeQueryParamValue(page_url.spec(), true).c_str(),
- EscapeQueryParamValue(referrer_url.spec(), true).c_str(),
- client_name_.c_str(),
- version_.c_str());
- GURL report_url(report_str);
+ GURL report_url = MalwareReportUrl(malware_url, page_url, referrer_url);
URLFetcher* report = new URLFetcher(report_url, URLFetcher::GET, this);
report->set_load_flags(net::LOAD_DISABLE_CACHE);
report->set_request_context(request_context_getter_);
@@ -667,3 +635,67 @@ void SafeBrowsingProtocolManager::UpdateFinished(bool success) {
update_size_ = 0;
sb_service_->UpdateFinished(success);
}
+
+std::string SafeBrowsingProtocolManager::ComposeUrl(
+ const std::string& prefix, const std::string& method,
+ const std::string& client_name, const std::string& version,
+ const std::string& additional_query) {
+ DCHECK(!prefix.empty() && !method.empty() &&
+ !client_name.empty() && !version.empty());
+ std::string url = StringPrintf("%s/%s?client=%s&appver=%s&pver=2.2",
+ prefix.c_str(), method.c_str(),
+ client_name.c_str(), version.c_str());
+ if (!additional_query.empty()) {
+ url.append(additional_query);
+ }
+ return url;
+}
+
+GURL SafeBrowsingProtocolManager::UpdateUrl(bool use_mac) const {
+ std::string url = ComposeUrl(info_url_prefix_, "downloads", client_name_,
+ version_, additional_query_);
+ if (use_mac) {
+ url.append("&wrkey=");
+ url.append(wrapped_key_);
+ }
+ return GURL(url);
+}
+
+GURL SafeBrowsingProtocolManager::GetHashUrl(bool use_mac) const {
+ std::string url= ComposeUrl(info_url_prefix_, "gethash", client_name_,
+ version_, additional_query_);
+ if (use_mac) {
+ url.append("&wrkey=");
+ url.append(wrapped_key_);
+ }
+ return GURL(url);
+}
+
+GURL SafeBrowsingProtocolManager::MacKeyUrl() const {
+ return GURL(ComposeUrl(mackey_url_prefix_, "newkey", client_name_, version_,
+ additional_query_));
+}
+
+GURL SafeBrowsingProtocolManager::MalwareReportUrl(
+ const GURL& malware_url, const GURL& page_url,
+ const GURL& referrer_url) const {
+ std::string url = ComposeUrl(info_url_prefix_, "report", client_name_,
+ version_, additional_query_);
+ return GURL(StringPrintf("%s&evts=malblhit&evtd=%s&evtr=%s&evhr=%s",
+ url.c_str(), EscapeQueryParamValue(malware_url.spec(), true).c_str(),
+ EscapeQueryParamValue(page_url.spec(), true).c_str(),
+ EscapeQueryParamValue(referrer_url.spec(), true).c_str()));
+}
+
+GURL SafeBrowsingProtocolManager::NextChunkUrl(const std::string& url) const {
+ std::string next_url;
+ if (!StartsWithASCII(url, "http://", false) &&
+ !StartsWithASCII(url, "https://", false)) {
+ next_url = "http://" + url;
+ } else {
+ next_url = url;
+ }
+ if (!additional_query_.empty())
+ next_url += additional_query_;
+ return GURL(next_url);
+}
diff --git a/chrome/browser/safe_browsing/protocol_manager.h b/chrome/browser/safe_browsing/protocol_manager.h
index 1526fe5..4bd997c 100644
--- a/chrome/browser/safe_browsing/protocol_manager.h
+++ b/chrome/browser/safe_browsing/protocol_manager.h
@@ -46,20 +46,31 @@ struct hash<const URLFetcher*> {
class SafeBrowsingProtocolManager : public URLFetcher::Delegate {
FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest, TestBackOffTimes);
FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest, TestChunkStrings);
+ FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest, TestGetHashUrl);
FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest,
TestGetHashBackOffTimes);
+ FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest, TestMacKeyUrl);
+ FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest,
+ TestMalwareReportUrl);
+ FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest, TestNextChunkUrl);
+ FRIEND_TEST_ALL_PREFIXES(SafeBrowsingProtocolManagerTest, TestUpdateUrl);
public:
// Constructs a SafeBrowsingProtocolManager for |sb_service| that issues
- // network requests using |request_context_getter|.
+ // network requests using |request_context_getter|. When |disable_auto_update|
+ // is true, protocol manager won't schedule next update until
+ // ForceScheduleNextUpdate is called.
SafeBrowsingProtocolManager(SafeBrowsingService* sb_service,
const std::string& client_name,
const std::string& client_key,
const std::string& wrapped_key,
- URLRequestContextGetter* request_context_getter);
+ URLRequestContextGetter* request_context_getter,
+ const std::string& info_url_prefix,
+ const std::string& mackey_url_prefix,
+ bool disable_auto_update);
~SafeBrowsingProtocolManager();
- // Set up the update schedule and internal state for making periodic requests
+ // Sets up the update schedule and internal state for making periodic requests
// of the SafeBrowsing service.
void Initialize();
@@ -76,6 +87,11 @@ class SafeBrowsingProtocolManager : public URLFetcher::Delegate {
void GetFullHash(SafeBrowsingService::SafeBrowsingCheck* check,
const std::vector<SBPrefix>& prefixes);
+ // Forces the start of next update after |next_update_msec| in msec.
+ void ForceScheduleNextUpdate(int next_update_msec);
+
+ bool is_initial_request() const { return initial_request_; }
+
// Scheduled update callback.
void GetNextUpdate();
@@ -92,11 +108,22 @@ class SafeBrowsingProtocolManager : public URLFetcher::Delegate {
// The last time we received an update.
base::Time last_update() const { return last_update_; }
- // Report a malware resource to the SafeBrowsing service.
+ // Reports a malware resource to the SafeBrowsing service.
void ReportMalware(const GURL& malware_url,
const GURL& page_url,
const GURL& referrer_url);
+ // Setter for additional_query_. To make sure the additional_query_ won't
+ // be changed in the middle of an update, caller (e.g.: SafeBrowsingService)
+ // should call this after callbacks triggered in UpdateFinished() or before
+ // IssueUpdateRequest().
+ void set_additional_query(const std::string& query) {
+ additional_query_ = query;
+ }
+ const std::string& additional_query() const {
+ return additional_query_;
+ }
+
private:
// Internal API for fetching information from the SafeBrowsing servers. The
// GetHash requests are higher priority since they can block user requests
@@ -108,6 +135,29 @@ class SafeBrowsingProtocolManager : public URLFetcher::Delegate {
GETKEY_REQUEST // Update the client's MAC key
};
+ // Composes a URL using |prefix|, |method| (e.g.: gethash, download,
+ // newkey, report), |client_name| and |version|. When not empty,
+ // |additional_query| is appended to the URL.
+ static std::string ComposeUrl(const std::string& prefix,
+ const std::string& method,
+ const std::string& client_name,
+ const std::string& version,
+ const std::string& additional_query);
+
+ // Generates Update URL for querying about the latest set of chunk updates.
+ // Append "wrkey=xxx" to the URL when |use_mac| is true.
+ GURL UpdateUrl(bool use_mac) const;
+ // Generates GetHash request URL for retrieving full hashes.
+ // Append "wrkey=xxx" to the URL when |use_mac| is true.
+ GURL GetHashUrl(bool use_mac) const;
+ // Generates new MAC client key request URL.
+ GURL MacKeyUrl() const;
+ // Generates URL for reporting malware pages.
+ GURL MalwareReportUrl(const GURL& malware_url, const GURL& page_url,
+ const GURL& referrer_url) const;
+ // Composes a ChunkUrl based on input string.
+ GURL NextChunkUrl(const std::string& input) const;
+
// Returns the time (in milliseconds) for the next update request. If
// 'back_off' is true, the time returned will increment an error count and
// return the appriate next time (see ScheduleNextUpdate below).
@@ -118,38 +168,41 @@ class SafeBrowsingProtocolManager : public URLFetcher::Delegate {
// 2nd and 5th, and 'error_count' is incremented with each call.
int GetNextBackOffTime(int* error_count, int* multiplier);
- // Manage our update with the next allowable update time. If 'back_off_' is
+ // Manages our update with the next allowable update time. If 'back_off_' is
// true, we must decrease the frequency of requests of the SafeBrowsing
// service according to section 5 of the protocol specification.
+ // When disable_auto_update_ is set, ScheduleNextUpdate will do nothing.
+ // ForceScheduleNextUpdate has to be called to trigger the update.
void ScheduleNextUpdate(bool back_off);
- // Send a request for a list of chunks we should download to the SafeBrowsing
+ // Sends a request for a list of chunks we should download to the SafeBrowsing
// servers. In order to format this request, we need to send all the chunk
// numbers for each list that we have to the server. Getting the chunk numbers
// requires a database query (run on the database thread), and the request
// is sent upon completion of that query in OnGetChunksComplete.
void IssueUpdateRequest();
- // Send a request for a chunk to the SafeBrowsing servers.
+ // Sends a request for a chunk to the SafeBrowsing servers.
void IssueChunkRequest();
- // Get a key from the SafeBrowsing servers for use with MAC. This should only
+ // Gets a key from the SafeBrowsing servers for use with MAC. This should only
// be called once per client unless the server directly tells us to update.
void IssueKeyRequest();
- // Format a string returned from the database into:
+ // Formats a string returned from the database into:
// "list_name;a:<add_chunk_ranges>:s:<sub_chunk_ranges>:mac\n"
static std::string FormatList(const SBListChunkRanges& list, bool use_mac);
- // Run the protocol parser on received data and update the SafeBrowsingService
- // with the new content. Returns 'true' on successful parse, 'false' on error.
+ // Runs the protocol parser on received data and update the
+ // SafeBrowsingService with the new content. Returns 'true' on successful
+ // parse, 'false' on error.
bool HandleServiceResponse(const GURL& url, const char* data, int length);
// If the SafeBrowsing service wants us to re-key, we clear our key state and
// issue the request.
void HandleReKey();
- // Update internal state for each GetHash response error, assuming that the
+ // Updates internal state for each GetHash response error, assuming that the
// current time is |now|.
void HandleGetHashError(const base::Time& now);
@@ -232,7 +285,7 @@ class SafeBrowsingProtocolManager : public URLFetcher::Delegate {
// Used for measuring chunk request latency.
base::Time chunk_request_start_;
- // Track the size of each update (in bytes).
+ // Tracks the size of each update (in bytes).
int update_size_;
// Track outstanding malware report fetchers for clean up.
@@ -241,9 +294,24 @@ class SafeBrowsingProtocolManager : public URLFetcher::Delegate {
// The safe browsing client name sent in each request.
std::string client_name_;
+ // A string that is appended to the end of URLs for download, gethash,
+ // newkey, malware report and chunk update requests.
+ std::string additional_query_;
+
// The context we use to issue network requests.
scoped_refptr<URLRequestContextGetter> request_context_getter_;
+ // URL prefix where browser fetches safebrowsing chunk updates, hashes, and
+ // reports malware.
+ std::string info_url_prefix_;
+
+ // URL prefix where browser fetches MAC client key.
+ std::string mackey_url_prefix_;
+
+ // When true, protocol manager will not start an update unless
+ // ForceScheduleNextUpdate() is called. This is set for testing purpose.
+ bool disable_auto_update_;
+
DISALLOW_COPY_AND_ASSIGN(SafeBrowsingProtocolManager);
};
diff --git a/chrome/browser/safe_browsing/protocol_manager_unittest.cc b/chrome/browser/safe_browsing/protocol_manager_unittest.cc
index e8d64d0..4f45893 100644
--- a/chrome/browser/safe_browsing/protocol_manager_unittest.cc
+++ b/chrome/browser/safe_browsing/protocol_manager_unittest.cc
@@ -11,12 +11,23 @@
using base::Time;
using base::TimeDelta;
+static const char kInfoUrlPrefix[] = "http://info.prefix.com/foo";
+static const char kMacKeyUrlPrefix[] = "https://key.prefix.com/bar";
+static const char kClient[] = "unittest";
+static const char kAppVer[] = "1.0";
+static const char kClientKey[] = "SCg9lcLHd0dfksXgYsacwQ==";
+static const char kWrappedKey[] =
+ "AKEgNisjLl7iRYrjWHmpd_XwCiilxrw8nNaYH47tiQ7pDe9cEErjVHGZaPPUau5h61tbXSDqA"
+ "BiJZnDFByc_g8B5vTwxkhBf9g==";
+static const char kAdditionalQuery[] = "&additional_query";
+
class SafeBrowsingProtocolManagerTest : public testing::Test {
};
// Ensure that we respect section 5 of the SafeBrowsing protocol specification.
TEST_F(SafeBrowsingProtocolManagerTest, TestBackOffTimes) {
- SafeBrowsingProtocolManager pm(NULL, "", "", "", NULL);
+ SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
+ kInfoUrlPrefix, kMacKeyUrlPrefix, false);
pm.next_update_sec_ = 1800;
DCHECK(pm.back_off_fuzz_ >= 0.0 && pm.back_off_fuzz_ <= 1.0);
@@ -54,7 +65,8 @@ TEST_F(SafeBrowsingProtocolManagerTest, TestBackOffTimes) {
// Test string combinations with and without MAC.
TEST_F(SafeBrowsingProtocolManagerTest, TestChunkStrings) {
- SafeBrowsingProtocolManager pm(NULL, "", "", "", NULL);
+ SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
+ kInfoUrlPrefix, kMacKeyUrlPrefix, false);
// Add and Sub chunks.
SBListChunkRanges phish("goog-phish-shavar");
@@ -87,7 +99,8 @@ TEST_F(SafeBrowsingProtocolManagerTest, TestChunkStrings) {
}
TEST_F(SafeBrowsingProtocolManagerTest, TestGetHashBackOffTimes) {
- SafeBrowsingProtocolManager pm(NULL, "", "", "", NULL);
+ SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
+ kInfoUrlPrefix, kMacKeyUrlPrefix, false);
// No errors or back off time yet.
EXPECT_EQ(pm.gethash_error_count_, 0);
@@ -137,3 +150,106 @@ TEST_F(SafeBrowsingProtocolManagerTest, TestGetHashBackOffTimes) {
EXPECT_EQ(pm.gethash_error_count_, 7);
EXPECT_TRUE(pm.next_gethash_time_== now + TimeDelta::FromMinutes(480));
}
+
+TEST_F(SafeBrowsingProtocolManagerTest, TestGetHashUrl) {
+ SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
+ kInfoUrlPrefix, kMacKeyUrlPrefix, false);
+ pm.version_ = kAppVer;
+ EXPECT_EQ("http://info.prefix.com/foo/gethash?client=unittest&appver=1.0&"
+ "pver=2.2", pm.GetHashUrl(false).spec());
+ EXPECT_EQ("http://info.prefix.com/foo/gethash?client=unittest&appver=1.0&"
+ "pver=2.2&wrkey=AKEgNisjLl7iRYrjWHmpd_XwCiilxrw8nNaYH47tiQ7pDe9cE"
+ "ErjVHGZaPPUau5h61tbXSDqABiJZnDFByc_g8B5vTwxkhBf9g==",
+ pm.GetHashUrl(true).spec());
+
+ pm.set_additional_query("&additional_query");
+ EXPECT_EQ("http://info.prefix.com/foo/gethash?client=unittest&appver=1.0&"
+ "pver=2.2&additional_query",
+ pm.GetHashUrl(false).spec());
+ EXPECT_EQ("http://info.prefix.com/foo/gethash?client=unittest&appver=1.0&"
+ "pver=2.2&additional_query&wrkey=AKEgNisjLl7iRYrjWHmpd_XwCiilxrw8"
+ "nNaYH47tiQ7pDe9cEErjVHGZaPPUau5h61tbXSDqABiJZnDFByc_g8B5vTwxkhBf"
+ "9g==", pm.GetHashUrl(true).spec());
+}
+
+TEST_F(SafeBrowsingProtocolManagerTest, TestUpdateUrl) {
+ SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
+ kInfoUrlPrefix, kMacKeyUrlPrefix, false);
+ pm.version_ = kAppVer;
+
+ EXPECT_EQ("http://info.prefix.com/foo/downloads?client=unittest&appver=1.0&"
+ "pver=2.2", pm.UpdateUrl(false).spec());
+ EXPECT_EQ("http://info.prefix.com/foo/downloads?client=unittest&appver=1.0&"
+ "pver=2.2&wrkey=AKEgNisjLl7iRYrjWHmpd_XwCiilxrw8nNaYH47tiQ7pDe9cE"
+ "ErjVHGZaPPUau5h61tbXSDqABiJZnDFByc_g8B5vTwxkhBf9g==",
+ pm.UpdateUrl(true).spec());
+
+ pm.set_additional_query("&additional_query");
+ EXPECT_EQ("http://info.prefix.com/foo/downloads?client=unittest&appver=1.0&"
+ "pver=2.2&additional_query", pm.UpdateUrl(false).spec());
+ EXPECT_EQ("http://info.prefix.com/foo/downloads?client=unittest&appver=1.0&"
+ "pver=2.2&additional_query&wrkey=AKEgNisjLl7iRYrjWHmpd_XwCiilxrw8"
+ "nNaYH47tiQ7pDe9cEErjVHGZaPPUau5h61tbXSDqABiJZnDFByc_g8B5vTwxkhBf"
+ "9g==", pm.UpdateUrl(true).spec());
+}
+
+TEST_F(SafeBrowsingProtocolManagerTest, TestMalwareReportUrl) {
+ SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
+ kInfoUrlPrefix, kMacKeyUrlPrefix, false);
+ pm.version_ = kAppVer;
+
+ GURL malware_url("http://malware.url.com");
+ GURL page_url("http://page.url.com");
+ GURL referrer_url("http://referrer.url.com");
+ EXPECT_EQ("http://info.prefix.com/foo/report?client=unittest&appver=1.0&"
+ "pver=2.2&evts=malblhit&evtd=http%3A%2F%2Fmalware.url.com%2F&"
+ "evtr=http%3A%2F%2Fpage.url.com%2F&evhr=http%3A%2F%2Freferrer."
+ "url.com%2F",
+ pm.MalwareReportUrl(malware_url, page_url, referrer_url).spec());
+
+ pm.set_additional_query("&additional_query");
+ EXPECT_EQ("http://info.prefix.com/foo/report?client=unittest&appver=1.0&"
+ "pver=2.2&additional_query&evts=malblhit&"
+ "evtd=http%3A%2F%2Fmalware.url.com%2F&"
+ "evtr=http%3A%2F%2Fpage.url.com%2F&evhr=http%3A%2F%2Freferrer."
+ "url.com%2F",
+ pm.MalwareReportUrl(malware_url, page_url, referrer_url).spec());
+}
+
+TEST_F(SafeBrowsingProtocolManagerTest, TestMacKeyUrl) {
+ SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
+ kInfoUrlPrefix, kMacKeyUrlPrefix, false);
+ pm.version_ = kAppVer;
+
+ EXPECT_EQ("https://key.prefix.com/bar/newkey?client=unittest&appver=1.0&"
+ "pver=2.2", pm.MacKeyUrl().spec());
+
+ pm.set_additional_query("&additional_query");
+ EXPECT_EQ("https://key.prefix.com/bar/newkey?client=unittest&appver=1.0&"
+ "pver=2.2&additional_query", pm.MacKeyUrl().spec());
+}
+
+TEST_F(SafeBrowsingProtocolManagerTest, TestNextChunkUrl) {
+ SafeBrowsingProtocolManager pm(NULL, kClient, kClientKey, kWrappedKey, NULL,
+ kInfoUrlPrefix, kMacKeyUrlPrefix, false);
+ pm.version_ = kAppVer;
+
+ std::string url_partial = "localhost:1234/foo/bar?foo";
+ std::string url_http_full = "http://localhost:1234/foo/bar?foo";
+ std::string url_https_full = "https://localhost:1234/foo/bar?foo";
+
+ EXPECT_EQ("http://localhost:1234/foo/bar?foo",
+ pm.NextChunkUrl(url_partial).spec());
+ EXPECT_EQ("http://localhost:1234/foo/bar?foo",
+ pm.NextChunkUrl(url_http_full).spec());
+ EXPECT_EQ("https://localhost:1234/foo/bar?foo",
+ pm.NextChunkUrl(url_https_full).spec());
+
+ pm.set_additional_query("&additional_query");
+ EXPECT_EQ("http://localhost:1234/foo/bar?foo&additional_query",
+ pm.NextChunkUrl(url_partial).spec());
+ EXPECT_EQ("http://localhost:1234/foo/bar?foo&additional_query",
+ pm.NextChunkUrl(url_http_full).spec());
+ EXPECT_EQ("https://localhost:1234/foo/bar?foo&additional_query",
+ pm.NextChunkUrl(url_https_full).spec());
+}
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.cc b/chrome/browser/safe_browsing/safe_browsing_service.cc
index ea5da62..a5aaa12 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_service.cc
@@ -6,6 +6,7 @@
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "base/callback.h"
+#include "base/command_line.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "chrome/browser/browser_process.h"
@@ -20,6 +21,7 @@
#include "chrome/browser/chrome_thread.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_paths.h"
+#include "chrome/common/chrome_switches.h"
#include "chrome/common/net/url_request_context_getter.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
@@ -32,6 +34,15 @@
using base::Time;
using base::TimeDelta;
+// The default URL prefix where browser fetches chunk updates, hashes,
+// and reports malware.
+static const char* const kSbDefaultInfoURLPrefix =
+ "http://safebrowsing.clients.google.com/safebrowsing";
+
+// The default URL prefix where browser fetches MAC client key.
+static const char* const kSbDefaultMacKeyURLPrefix =
+ "https://sb-ssl.google.com/safebrowsing";
+
static Profile* GetDefaultProfile() {
FilePath user_data_dir;
PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
@@ -233,6 +244,11 @@ void SafeBrowsingService::UpdateFinished(bool update_succeeded) {
}
}
+bool SafeBrowsingService::IsUpdateInProgress() const {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::IO));
+ return update_in_progress_;
+}
+
void SafeBrowsingService::OnBlockingPageDone(
const std::vector<UnsafeResource>& resources,
bool proceed) {
@@ -345,12 +361,25 @@ void SafeBrowsingService::OnIOInitialize(
std::string client_name("chromium");
#endif
#endif
+ CommandLine* cmdline = CommandLine::ForCurrentProcess();
+ bool disable_auto_update = cmdline->HasSwitch(switches::kSbDisableAutoUpdate);
+ std::string info_url_prefix =
+ cmdline->HasSwitch(switches::kSbInfoURLPrefix) ?
+ cmdline->GetSwitchValueASCII(switches::kSbInfoURLPrefix) :
+ kSbDefaultInfoURLPrefix;
+ std::string mackey_url_prefix =
+ cmdline->HasSwitch(switches::kSbMacKeyURLPrefix) ?
+ cmdline->GetSwitchValueASCII(switches::kSbMacKeyURLPrefix) :
+ kSbDefaultMacKeyURLPrefix;
protocol_manager_ = new SafeBrowsingProtocolManager(this,
client_name,
client_key,
wrapped_key,
- request_context_getter);
+ request_context_getter,
+ info_url_prefix,
+ mackey_url_prefix,
+ disable_auto_update);
// Balance the reference added by Start().
request_context_getter->Release();
diff --git a/chrome/browser/safe_browsing/safe_browsing_service.h b/chrome/browser/safe_browsing/safe_browsing_service.h
index 873dcb3..c8415b1 100644
--- a/chrome/browser/safe_browsing/safe_browsing_service.h
+++ b/chrome/browser/safe_browsing/safe_browsing_service.h
@@ -122,6 +122,8 @@ class SafeBrowsingService
// Update management. Called on the IO thread.
void UpdateStarted();
void UpdateFinished(bool update_succeeded);
+ // Whether there is an update in progress. Called on the IO thread.
+ bool IsUpdateInProgress() const;
// The blocking page on the UI thread has completed.
void OnBlockingPageDone(const std::vector<UnsafeResource>& resources,