| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 5 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "chrome/common/url_constants.h" | 28 #include "chrome/common/url_constants.h" |
| 29 #include "net/base/registry_controlled_domain.h" | 29 #include "net/base/registry_controlled_domain.h" |
| 30 | 30 |
| 31 #if defined(OS_WIN) | 31 #if defined(OS_WIN) |
| 32 #include "chrome/installer/util/browser_distribution.h" | 32 #include "chrome/installer/util/browser_distribution.h" |
| 33 #endif | 33 #endif |
| 34 | 34 |
| 35 using base::Time; | 35 using base::Time; |
| 36 using base::TimeDelta; | 36 using base::TimeDelta; |
| 37 | 37 |
| 38 namespace { |
| 39 |
| 38 // The default URL prefix where browser fetches chunk updates, hashes, | 40 // The default URL prefix where browser fetches chunk updates, hashes, |
| 39 // and reports safe browsing hits. | 41 // and reports safe browsing hits. |
| 40 static const char* const kSbDefaultInfoURLPrefix = | 42 const char* const kSbDefaultInfoURLPrefix = |
| 41 "http://safebrowsing.clients.google.com/safebrowsing"; | 43 "http://safebrowsing.clients.google.com/safebrowsing"; |
| 42 | 44 |
| 43 // The default URL prefix where browser fetches MAC client key and reports | 45 // The default URL prefix where browser fetches MAC client key and reports |
| 44 // malware details. | 46 // malware details. |
| 45 static const char* const kSbDefaultMacKeyURLPrefix = | 47 const char* const kSbDefaultMacKeyURLPrefix = |
| 46 "https://sb-ssl.google.com/safebrowsing"; | 48 "https://sb-ssl.google.com/safebrowsing"; |
| 47 | 49 |
| 48 static Profile* GetDefaultProfile() { | 50 Profile* GetDefaultProfile() { |
| 49 FilePath user_data_dir; | 51 FilePath user_data_dir; |
| 50 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); | 52 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); |
| 51 ProfileManager* profile_manager = g_browser_process->profile_manager(); | 53 ProfileManager* profile_manager = g_browser_process->profile_manager(); |
| 52 return profile_manager->GetDefaultProfile(user_data_dir); | 54 return profile_manager->GetDefaultProfile(user_data_dir); |
| 53 } | 55 } |
| 54 | 56 |
| 57 // The full call is kind of long... |
| 58 void RecordGetHashFullMiss() { |
| 59 SafeBrowsingProtocolManager::RecordGetHashResult( |
| 60 SafeBrowsingProtocolManager::GET_HASH_NO_HITS); |
| 61 } |
| 62 |
| 63 } // namespace |
| 64 |
| 55 // static | 65 // static |
| 56 SafeBrowsingServiceFactory* SafeBrowsingService::factory_ = NULL; | 66 SafeBrowsingServiceFactory* SafeBrowsingService::factory_ = NULL; |
| 57 | 67 |
| 58 // The default SafeBrowsingServiceFactory. Global, made a singleton so we | 68 // The default SafeBrowsingServiceFactory. Global, made a singleton so we |
| 59 // don't leak it. | 69 // don't leak it. |
| 60 class SafeBrowsingServiceFactoryImpl : public SafeBrowsingServiceFactory { | 70 class SafeBrowsingServiceFactoryImpl : public SafeBrowsingServiceFactory { |
| 61 public: | 71 public: |
| 62 virtual SafeBrowsingService* CreateSafeBrowsingService() { | 72 virtual SafeBrowsingService* CreateSafeBrowsingService() { |
| 63 return new SafeBrowsingService(); | 73 return new SafeBrowsingService(); |
| 64 } | 74 } |
| (...skipping 566 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 631 GetHashRequestors requestors; | 641 GetHashRequestors requestors; |
| 632 requestors.push_back(check); | 642 requestors.push_back(check); |
| 633 gethash_requests_[prefix] = requestors; | 643 gethash_requests_[prefix] = requestors; |
| 634 } | 644 } |
| 635 | 645 |
| 636 // Reset the start time so that we can measure the network time without the | 646 // Reset the start time so that we can measure the network time without the |
| 637 // database time. | 647 // database time. |
| 638 check->start = Time::Now(); | 648 check->start = Time::Now(); |
| 639 protocol_manager_->GetFullHash(check, check->prefix_hits); | 649 protocol_manager_->GetFullHash(check, check->prefix_hits); |
| 640 } else { | 650 } else { |
| 641 // We may have cached results for previous GetHash queries. | 651 // We may have cached results for previous GetHash queries. Since |
| 652 // this data comes from cache, don't histogram any misses. |
| 642 HandleOneCheck(check, check->full_hits); | 653 HandleOneCheck(check, check->full_hits); |
| 643 } | 654 } |
| 644 } | 655 } |
| 645 | 656 |
| 646 void SafeBrowsingService::GetAllChunksFromDatabase() { | 657 void SafeBrowsingService::GetAllChunksFromDatabase() { |
| 647 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); | 658 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); |
| 648 | 659 |
| 649 bool database_error = true; | 660 bool database_error = true; |
| 650 std::vector<SBListChunkRanges> lists; | 661 std::vector<SBListChunkRanges> lists; |
| 651 DCHECK(!database_update_in_progress_); | 662 DCHECK(!database_update_in_progress_); |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 GetDatabase()->CacheHashResults(prefixes, full_hashes); | 820 GetDatabase()->CacheHashResults(prefixes, full_hashes); |
| 810 } | 821 } |
| 811 | 822 |
| 812 void SafeBrowsingService::OnHandleGetHashResults( | 823 void SafeBrowsingService::OnHandleGetHashResults( |
| 813 SafeBrowsingCheck* check, | 824 SafeBrowsingCheck* check, |
| 814 const std::vector<SBFullHashResult>& full_hashes) { | 825 const std::vector<SBFullHashResult>& full_hashes) { |
| 815 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 826 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 816 SBPrefix prefix = check->prefix_hits[0]; | 827 SBPrefix prefix = check->prefix_hits[0]; |
| 817 GetHashRequests::iterator it = gethash_requests_.find(prefix); | 828 GetHashRequests::iterator it = gethash_requests_.find(prefix); |
| 818 if (check->prefix_hits.size() > 1 || it == gethash_requests_.end()) { | 829 if (check->prefix_hits.size() > 1 || it == gethash_requests_.end()) { |
| 819 HandleOneCheck(check, full_hashes); | 830 if (HandleOneCheck(check, full_hashes)) |
| 831 RecordGetHashFullMiss(); |
| 820 return; | 832 return; |
| 821 } | 833 } |
| 822 | 834 |
| 823 // Call back all interested parties. | 835 // Call back all interested parties, counting the total number of |
| 836 // clients with no hits. |
| 824 GetHashRequestors& requestors = it->second; | 837 GetHashRequestors& requestors = it->second; |
| 838 size_t misses = 0; |
| 825 for (GetHashRequestors::iterator r = requestors.begin(); | 839 for (GetHashRequestors::iterator r = requestors.begin(); |
| 826 r != requestors.end(); ++r) { | 840 r != requestors.end(); ++r) { |
| 827 HandleOneCheck(*r, full_hashes); | 841 if (HandleOneCheck(*r, full_hashes)) |
| 842 ++ misses; |
| 828 } | 843 } |
| 829 | 844 |
| 845 // None of the requests matched a full hash. |
| 846 if (misses == requestors.size()) |
| 847 RecordGetHashFullMiss(); |
| 848 |
| 830 gethash_requests_.erase(it); | 849 gethash_requests_.erase(it); |
| 831 } | 850 } |
| 832 | 851 |
| 833 void SafeBrowsingService::HandleOneCheck( | 852 bool SafeBrowsingService::HandleOneCheck( |
| 834 SafeBrowsingCheck* check, | 853 SafeBrowsingCheck* check, |
| 835 const std::vector<SBFullHashResult>& full_hashes) { | 854 const std::vector<SBFullHashResult>& full_hashes) { |
| 836 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 855 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 856 |
| 857 // Always calculate the index for purposes of detecting requests |
| 858 // with no hits. |
| 859 int index = safe_browsing_util::CompareFullHashes(check->url, full_hashes); |
| 860 |
| 861 // |client| is NULL if the request was cancelled. |
| 837 if (check->client) { | 862 if (check->client) { |
| 838 UrlCheckResult result = URL_SAFE; | 863 UrlCheckResult result = URL_SAFE; |
| 839 int index = safe_browsing_util::CompareFullHashes(check->url, full_hashes); | 864 if (index != -1) |
| 840 if (index != -1) { | |
| 841 result = GetResultFromListname(full_hashes[index].list_name); | 865 result = GetResultFromListname(full_hashes[index].list_name); |
| 842 } else { | |
| 843 // Log the case where the SafeBrowsing servers return full hashes in the | |
| 844 // GetHash response that match the prefix we're looking up, but don't | |
| 845 // match the full hash of the URL. | |
| 846 if (!full_hashes.empty()) | |
| 847 UMA_HISTOGRAM_COUNTS("SB2.GetHashServerMiss", 1); | |
| 848 } | |
| 849 | 866 |
| 850 // Let the client continue handling the original request. | 867 // Let the client continue handling the original request. |
| 851 check->client->OnSafeBrowsingResult(check->url, result); | 868 check->client->OnSafeBrowsingResult(check->url, result); |
| 852 } | 869 } |
| 853 | 870 |
| 854 checks_.erase(check); | 871 checks_.erase(check); |
| 855 delete check; | 872 delete check; |
| 873 |
| 874 return (index == -1); |
| 856 } | 875 } |
| 857 | 876 |
| 858 void SafeBrowsingService::DoDisplayBlockingPage( | 877 void SafeBrowsingService::DoDisplayBlockingPage( |
| 859 const UnsafeResource& resource) { | 878 const UnsafeResource& resource) { |
| 860 // The tab might have been closed. | 879 // The tab might have been closed. |
| 861 TabContents* wc = | 880 TabContents* wc = |
| 862 tab_util::GetTabContentsByID(resource.render_process_host_id, | 881 tab_util::GetTabContentsByID(resource.render_process_host_id, |
| 863 resource.render_view_id); | 882 resource.render_view_id); |
| 864 | 883 |
| 865 if (!wc) { | 884 if (!wc) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 941 // checkbox on the blocking page. | 960 // checkbox on the blocking page. |
| 942 void SafeBrowsingService::ReportMalwareDetails( | 961 void SafeBrowsingService::ReportMalwareDetails( |
| 943 scoped_refptr<MalwareDetails> details) { | 962 scoped_refptr<MalwareDetails> details) { |
| 944 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 963 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 945 scoped_ptr<const std::string> serialized(details->GetSerializedReport()); | 964 scoped_ptr<const std::string> serialized(details->GetSerializedReport()); |
| 946 if (!serialized->empty()) { | 965 if (!serialized->empty()) { |
| 947 DVLOG(1) << "Sending serialized malware details."; | 966 DVLOG(1) << "Sending serialized malware details."; |
| 948 protocol_manager_->ReportMalwareDetails(*serialized); | 967 protocol_manager_->ReportMalwareDetails(*serialized); |
| 949 } | 968 } |
| 950 } | 969 } |
| OLD | NEW |