| 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 // Records disposition information about the check. |hit| should be |
| 58 // |true| if there were any prefix hits in |full_hashes|. |
| 59 void RecordGetHashCheckStatus( |
| 60 bool hit, const std::vector<SBFullHashResult>& full_hashes) { |
| 61 SafeBrowsingProtocolManager::ResultType result; |
| 62 if (full_hashes.empty()) { |
| 63 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_EMPTY; |
| 64 } else if (hit) { |
| 65 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_HIT; |
| 66 } else { |
| 67 result = SafeBrowsingProtocolManager::GET_HASH_FULL_HASH_MISS; |
| 68 } |
| 69 SafeBrowsingProtocolManager::RecordGetHashResult(result); |
| 70 } |
| 71 |
| 72 } // namespace |
| 73 |
| 55 // static | 74 // static |
| 56 SafeBrowsingServiceFactory* SafeBrowsingService::factory_ = NULL; | 75 SafeBrowsingServiceFactory* SafeBrowsingService::factory_ = NULL; |
| 57 | 76 |
| 58 // The default SafeBrowsingServiceFactory. Global, made a singleton so we | 77 // The default SafeBrowsingServiceFactory. Global, made a singleton so we |
| 59 // don't leak it. | 78 // don't leak it. |
| 60 class SafeBrowsingServiceFactoryImpl : public SafeBrowsingServiceFactory { | 79 class SafeBrowsingServiceFactoryImpl : public SafeBrowsingServiceFactory { |
| 61 public: | 80 public: |
| 62 virtual SafeBrowsingService* CreateSafeBrowsingService() { | 81 virtual SafeBrowsingService* CreateSafeBrowsingService() { |
| 63 return new SafeBrowsingService(); | 82 return new SafeBrowsingService(); |
| 64 } | 83 } |
| (...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 GetHashRequestors requestors; | 652 GetHashRequestors requestors; |
| 634 requestors.push_back(check); | 653 requestors.push_back(check); |
| 635 gethash_requests_[prefix] = requestors; | 654 gethash_requests_[prefix] = requestors; |
| 636 } | 655 } |
| 637 | 656 |
| 638 // Reset the start time so that we can measure the network time without the | 657 // Reset the start time so that we can measure the network time without the |
| 639 // database time. | 658 // database time. |
| 640 check->start = Time::Now(); | 659 check->start = Time::Now(); |
| 641 protocol_manager_->GetFullHash(check, check->prefix_hits); | 660 protocol_manager_->GetFullHash(check, check->prefix_hits); |
| 642 } else { | 661 } else { |
| 643 // We may have cached results for previous GetHash queries. | 662 // We may have cached results for previous GetHash queries. Since |
| 663 // this data comes from cache, don't histogram hits. |
| 644 HandleOneCheck(check, check->full_hits); | 664 HandleOneCheck(check, check->full_hits); |
| 645 } | 665 } |
| 646 } | 666 } |
| 647 | 667 |
| 648 void SafeBrowsingService::GetAllChunksFromDatabase() { | 668 void SafeBrowsingService::GetAllChunksFromDatabase() { |
| 649 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); | 669 DCHECK_EQ(MessageLoop::current(), safe_browsing_thread_->message_loop()); |
| 650 | 670 |
| 651 bool database_error = true; | 671 bool database_error = true; |
| 652 std::vector<SBListChunkRanges> lists; | 672 std::vector<SBListChunkRanges> lists; |
| 653 DCHECK(!database_update_in_progress_); | 673 DCHECK(!database_update_in_progress_); |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 GetDatabase()->CacheHashResults(prefixes, full_hashes); | 830 GetDatabase()->CacheHashResults(prefixes, full_hashes); |
| 811 } | 831 } |
| 812 | 832 |
| 813 void SafeBrowsingService::OnHandleGetHashResults( | 833 void SafeBrowsingService::OnHandleGetHashResults( |
| 814 SafeBrowsingCheck* check, | 834 SafeBrowsingCheck* check, |
| 815 const std::vector<SBFullHashResult>& full_hashes) { | 835 const std::vector<SBFullHashResult>& full_hashes) { |
| 816 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 836 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 817 SBPrefix prefix = check->prefix_hits[0]; | 837 SBPrefix prefix = check->prefix_hits[0]; |
| 818 GetHashRequests::iterator it = gethash_requests_.find(prefix); | 838 GetHashRequests::iterator it = gethash_requests_.find(prefix); |
| 819 if (check->prefix_hits.size() > 1 || it == gethash_requests_.end()) { | 839 if (check->prefix_hits.size() > 1 || it == gethash_requests_.end()) { |
| 820 HandleOneCheck(check, full_hashes); | 840 const bool hit = HandleOneCheck(check, full_hashes); |
| 841 RecordGetHashCheckStatus(hit, full_hashes); |
| 821 return; | 842 return; |
| 822 } | 843 } |
| 823 | 844 |
| 824 // Call back all interested parties. | 845 // Call back all interested parties, noting if any has a hit. |
| 825 GetHashRequestors& requestors = it->second; | 846 GetHashRequestors& requestors = it->second; |
| 847 bool hit = false; |
| 826 for (GetHashRequestors::iterator r = requestors.begin(); | 848 for (GetHashRequestors::iterator r = requestors.begin(); |
| 827 r != requestors.end(); ++r) { | 849 r != requestors.end(); ++r) { |
| 828 HandleOneCheck(*r, full_hashes); | 850 if (HandleOneCheck(*r, full_hashes)) |
| 851 hit = true; |
| 829 } | 852 } |
| 853 RecordGetHashCheckStatus(hit, full_hashes); |
| 830 | 854 |
| 831 gethash_requests_.erase(it); | 855 gethash_requests_.erase(it); |
| 832 } | 856 } |
| 833 | 857 |
| 834 void SafeBrowsingService::HandleOneCheck( | 858 bool SafeBrowsingService::HandleOneCheck( |
| 835 SafeBrowsingCheck* check, | 859 SafeBrowsingCheck* check, |
| 836 const std::vector<SBFullHashResult>& full_hashes) { | 860 const std::vector<SBFullHashResult>& full_hashes) { |
| 837 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 861 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 862 |
| 863 // Always calculate the index, for recording hits. |
| 864 int index = safe_browsing_util::CompareFullHashes(check->url, full_hashes); |
| 865 |
| 866 // |client| is NULL if the request was cancelled. |
| 838 if (check->client) { | 867 if (check->client) { |
| 839 UrlCheckResult result = URL_SAFE; | 868 UrlCheckResult result = URL_SAFE; |
| 840 int index = safe_browsing_util::CompareFullHashes(check->url, full_hashes); | 869 if (index != -1) |
| 841 if (index != -1) { | |
| 842 result = GetResultFromListname(full_hashes[index].list_name); | 870 result = GetResultFromListname(full_hashes[index].list_name); |
| 843 } else { | |
| 844 // Log the case where the SafeBrowsing servers return full hashes in the | |
| 845 // GetHash response that match the prefix we're looking up, but don't | |
| 846 // match the full hash of the URL. | |
| 847 if (!full_hashes.empty()) | |
| 848 UMA_HISTOGRAM_COUNTS("SB2.GetHashServerMiss", 1); | |
| 849 } | |
| 850 | 871 |
| 851 // Let the client continue handling the original request. | 872 // Let the client continue handling the original request. |
| 852 check->client->OnSafeBrowsingResult(check->url, result); | 873 check->client->OnSafeBrowsingResult(check->url, result); |
| 853 } | 874 } |
| 854 | 875 |
| 855 checks_.erase(check); | 876 checks_.erase(check); |
| 856 delete check; | 877 delete check; |
| 878 |
| 879 return (index != -1); |
| 857 } | 880 } |
| 858 | 881 |
| 859 void SafeBrowsingService::DoDisplayBlockingPage( | 882 void SafeBrowsingService::DoDisplayBlockingPage( |
| 860 const UnsafeResource& resource) { | 883 const UnsafeResource& resource) { |
| 861 // The tab might have been closed. | 884 // The tab might have been closed. |
| 862 TabContents* wc = | 885 TabContents* wc = |
| 863 tab_util::GetTabContentsByID(resource.render_process_host_id, | 886 tab_util::GetTabContentsByID(resource.render_process_host_id, |
| 864 resource.render_view_id); | 887 resource.render_view_id); |
| 865 | 888 |
| 866 if (!wc) { | 889 if (!wc) { |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 942 // checkbox on the blocking page. | 965 // checkbox on the blocking page. |
| 943 void SafeBrowsingService::ReportMalwareDetails( | 966 void SafeBrowsingService::ReportMalwareDetails( |
| 944 scoped_refptr<MalwareDetails> details) { | 967 scoped_refptr<MalwareDetails> details) { |
| 945 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 968 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 946 scoped_ptr<const std::string> serialized(details->GetSerializedReport()); | 969 scoped_ptr<const std::string> serialized(details->GetSerializedReport()); |
| 947 if (!serialized->empty()) { | 970 if (!serialized->empty()) { |
| 948 DVLOG(1) << "Sending serialized malware details."; | 971 DVLOG(1) << "Sending serialized malware details."; |
| 949 protocol_manager_->ReportMalwareDetails(*serialized); | 972 protocol_manager_->ReportMalwareDetails(*serialized); |
| 950 } | 973 } |
| 951 } | 974 } |
| OLD | NEW |