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 |