OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/srt_fetcher_win.h" | 5 #include "chrome/browser/safe_browsing/srt_fetcher_win.h" |
6 | 6 |
7 #include <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <algorithm> | |
9 #include <memory> | 10 #include <memory> |
10 #include <utility> | 11 #include <utility> |
11 #include <vector> | 12 #include <vector> |
12 | 13 |
13 #include "base/bind.h" | 14 #include "base/bind.h" |
14 #include "base/bind_helpers.h" | 15 #include "base/bind_helpers.h" |
15 #include "base/callback_helpers.h" | 16 #include "base/callback_helpers.h" |
16 #include "base/command_line.h" | 17 #include "base/command_line.h" |
17 #include "base/files/file_path.h" | 18 #include "base/files/file_path.h" |
18 #include "base/macros.h" | 19 #include "base/macros.h" |
19 #include "base/metrics/field_trial.h" | 20 #include "base/metrics/field_trial.h" |
20 #include "base/metrics/histogram.h" | 21 #include "base/metrics/histogram.h" |
21 #include "base/metrics/sparse_histogram.h" | 22 #include "base/metrics/sparse_histogram.h" |
22 #include "base/process/launch.h" | 23 #include "base/process/launch.h" |
23 #include "base/strings/string_number_conversions.h" | 24 #include "base/strings/string_number_conversions.h" |
24 #include "base/strings/stringprintf.h" | 25 #include "base/strings/stringprintf.h" |
25 #include "base/strings/utf_string_conversions.h" | 26 #include "base/strings/utf_string_conversions.h" |
26 #include "base/task_runner_util.h" | 27 #include "base/task_runner_util.h" |
27 #include "base/time/time.h" | 28 #include "base/time/time.h" |
28 #include "base/win/registry.h" | 29 #include "base/win/registry.h" |
29 #include "chrome/browser/browser_process.h" | 30 #include "chrome/browser/browser_process.h" |
30 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" | 31 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" |
31 #include "chrome/browser/profiles/profile.h" | 32 #include "chrome/browser/profiles/profile.h" |
32 #include "chrome/browser/profiles/profile_io_data.h" | 33 #include "chrome/browser/profiles/profile_io_data.h" |
34 #include "chrome/browser/safe_browsing/srt_client_info_win.h" | |
33 #include "chrome/browser/safe_browsing/srt_global_error_win.h" | 35 #include "chrome/browser/safe_browsing/srt_global_error_win.h" |
34 #include "chrome/browser/ui/browser_finder.h" | 36 #include "chrome/browser/ui/browser_finder.h" |
35 #include "chrome/browser/ui/browser_list.h" | 37 #include "chrome/browser/ui/browser_list.h" |
36 #include "chrome/browser/ui/browser_list_observer.h" | 38 #include "chrome/browser/ui/browser_list_observer.h" |
37 #include "chrome/browser/ui/global_error/global_error_service.h" | 39 #include "chrome/browser/ui/global_error/global_error_service.h" |
38 #include "chrome/browser/ui/global_error/global_error_service_factory.h" | 40 #include "chrome/browser/ui/global_error/global_error_service_factory.h" |
41 #include "chrome/common/pref_names.h" | |
39 #include "components/component_updater/pref_names.h" | 42 #include "components/component_updater/pref_names.h" |
40 #include "components/prefs/pref_service.h" | 43 #include "components/prefs/pref_service.h" |
41 #include "components/rappor/rappor_service.h" | 44 #include "components/rappor/rappor_service.h" |
42 #include "components/variations/net/variations_http_headers.h" | 45 #include "components/variations/net/variations_http_headers.h" |
46 #include "components/version_info/version_info.h" | |
43 #include "content/public/browser/browser_thread.h" | 47 #include "content/public/browser/browser_thread.h" |
44 #include "net/base/load_flags.h" | 48 #include "net/base/load_flags.h" |
45 #include "net/http/http_status_code.h" | 49 #include "net/http/http_status_code.h" |
46 #include "net/url_request/url_fetcher.h" | 50 #include "net/url_request/url_fetcher.h" |
47 #include "net/url_request/url_fetcher_delegate.h" | 51 #include "net/url_request/url_fetcher_delegate.h" |
48 #include "net/url_request/url_request_context_getter.h" | 52 #include "net/url_request/url_request_context_getter.h" |
49 | 53 |
50 using content::BrowserThread; | 54 using content::BrowserThread; |
51 | 55 |
52 namespace safe_browsing { | 56 namespace safe_browsing { |
53 | 57 |
54 const wchar_t kSoftwareRemovalToolRegistryKey[] = | 58 const wchar_t kSoftwareRemovalToolRegistryKey[] = |
55 L"Software\\Google\\Software Removal Tool"; | 59 L"Software\\Google\\Software Removal Tool"; |
56 | 60 |
57 const wchar_t kCleanerSubKey[] = L"Cleaner"; | 61 const wchar_t kCleanerSubKey[] = L"Cleaner"; |
58 | 62 |
59 const wchar_t kEndTimeValueName[] = L"EndTime"; | 63 const wchar_t kEndTimeValueName[] = L"EndTime"; |
60 const wchar_t kStartTimeValueName[] = L"StartTime"; | 64 const wchar_t kStartTimeValueName[] = L"StartTime"; |
61 | 65 |
66 const char kExtendedSafeBrowsingEnabledSwitch[] = | |
67 "extended-safebrowsing-enabled"; | |
68 | |
69 const base::Feature kSwReporterExtendedSafeBrowsingFeature{ | |
70 "SwReporterExtendedSafeBrowsingFeature", base::FEATURE_DISABLED_BY_DEFAULT}; | |
71 | |
62 namespace { | 72 namespace { |
63 | 73 |
64 // Used to send UMA information about missing start and end time registry | 74 // Used to send UMA information about missing start and end time registry |
65 // values for the reporter. Replicated in the histograms.xml file, so the order | 75 // values for the reporter. Replicated in the histograms.xml file, so the order |
66 // MUST NOT CHANGE. | 76 // MUST NOT CHANGE. |
67 enum SwReporterRunningTimeRegistryError { | 77 enum SwReporterRunningTimeRegistryError { |
68 REPORTER_RUNNING_TIME_ERROR_NO_ERROR = 0, | 78 REPORTER_RUNNING_TIME_ERROR_NO_ERROR = 0, |
69 REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID = 1, | 79 REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID = 1, |
70 REPORTER_RUNNING_TIME_ERROR_MISSING_START_TIME = 2, | 80 REPORTER_RUNNING_TIME_ERROR_MISSING_START_TIME = 2, |
71 REPORTER_RUNNING_TIME_ERROR_MISSING_END_TIME = 3, | 81 REPORTER_RUNNING_TIME_ERROR_MISSING_END_TIME = 3, |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
428 if (error->GetBubbleView()) { | 438 if (error->GetBubbleView()) { |
429 show_bubble = false; | 439 show_bubble = false; |
430 break; | 440 break; |
431 } | 441 } |
432 } | 442 } |
433 } | 443 } |
434 if (show_bubble) | 444 if (show_bubble) |
435 global_error->ShowBubbleView(browser); | 445 global_error->ShowBubbleView(browser); |
436 } | 446 } |
437 | 447 |
448 bool BrowserIsSafeBrowsingExtended(const Browser* browser) { | |
robertshield
2016/09/07 14:32:09
super-optional nit, only if you think it's a good
Fabio Tirelo
2016/09/07 16:48:56
Done.
| |
449 const Profile* profile = browser->profile(); | |
450 return profile && !profile->IsOffTheRecord() && | |
451 profile->GetPrefs()->GetBoolean( | |
452 prefs::kSafeBrowsingExtendedReportingEnabled); | |
453 } | |
454 | |
455 // Returns true if there is a profile that is not in incognito mode and the user | |
456 // has opted into Safe Browsing extended reporting. | |
457 bool SafeBrowsingExtendedReportingEnabled() { | |
458 BrowserList* browser_list = BrowserList::GetInstance(); | |
459 return std::any_of(browser_list->begin_last_active(), | |
460 browser_list->end_last_active(), | |
461 &BrowserIsSafeBrowsingExtended); | |
462 } | |
463 | |
438 // This function is called from a worker thread to launch the SwReporter and | 464 // This function is called from a worker thread to launch the SwReporter and |
439 // wait for termination to collect its exit code. This task could be | 465 // wait for termination to collect its exit code. This task could be |
440 // interrupted by a shutdown at any time, so it shouldn't depend on anything | 466 // interrupted by a shutdown at any time, so it shouldn't depend on anything |
441 // external that could be shut down beforehand. | 467 // external that could be shut down beforehand. |
442 int LaunchAndWaitForExit(const SwReporterInvocation& invocation) { | 468 int LaunchAndWaitForExit(const SwReporterInvocation& invocation) { |
443 if (g_testing_delegate_) | 469 if (g_testing_delegate_) |
444 return g_testing_delegate_->LaunchReporter(invocation); | 470 return g_testing_delegate_->LaunchReporter(invocation); |
445 base::Process reporter_process = | 471 base::Process reporter_process = |
446 base::LaunchProcess(invocation.command_line, base::LaunchOptions()); | 472 base::LaunchProcess(invocation.command_line, base::LaunchOptions()); |
447 // This exit code is used to identify that a reporter run didn't happen, so | 473 // This exit code is used to identify that a reporter run didn't happen, so |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
721 last_time_triggered + | 747 last_time_triggered + |
722 base::TimeDelta::FromDays(days_between_reporter_runs_) - | 748 base::TimeDelta::FromDays(days_between_reporter_runs_) - |
723 base::Time::Now()); | 749 base::Time::Now()); |
724 if (next_trigger_delay.ToInternalValue() <= 0 || | 750 if (next_trigger_delay.ToInternalValue() <= 0 || |
725 // Also make sure the kSwReporterLastTimeTriggered value is not set in | 751 // Also make sure the kSwReporterLastTimeTriggered value is not set in |
726 // the future. | 752 // the future. |
727 last_time_triggered > base::Time::Now()) { | 753 last_time_triggered > base::Time::Now()) { |
728 if (g_testing_delegate_) | 754 if (g_testing_delegate_) |
729 g_testing_delegate_->NotifyLaunchReady(); | 755 g_testing_delegate_->NotifyLaunchReady(); |
730 | 756 |
757 // Creating a new invocation to add switches for users who opted into | |
758 // extended Safe Browsing reporting. The invocation object is changed | |
759 // locally right before the actual process is launched because user status | |
760 // can between this and the next run for this ReporterRunner object. For | |
robertshield
2016/09/07 14:32:09
s/can/can change/
Fabio Tirelo
2016/09/07 16:48:56
Done.
| |
761 // example, the ReporterDone() callback schedules the next run for a few | |
762 // days later, and the user might have changed settings in the meantime. | |
763 SwReporterInvocation actual_invocation(invocation_); | |
764 if (ShouldSendReporterLogs(*local_state)) { | |
765 AddSwitchesForExtendedReporterUser(&actual_invocation); | |
766 // Set the local state value before the first attempt to run the | |
767 // reporter, because we only want to upload logs once in the window | |
768 // defined by |kDaysBetweenReporterLogsSent|. If we set with other local | |
769 // state values after the reporter runs, we could send logs again too | |
770 // quickly (for example, if Chrome stops before the reporter finishes). | |
771 local_state->SetInt64(prefs::kSwReporterLastTimeSentReport, | |
772 base::Time::Now().ToInternalValue()); | |
773 } | |
731 // It's OK to simply |PostTaskAndReplyWithResult| so that | 774 // It's OK to simply |PostTaskAndReplyWithResult| so that |
732 // |LaunchAndWaitForExit| doesn't need to access | 775 // |LaunchAndWaitForExit| doesn't need to access |
733 // |main_thread_task_runner_| since the callback is not delayed and the | 776 // |main_thread_task_runner_| since the callback is not delayed and the |
734 // test task runner won't need to force it. | 777 // test task runner won't need to force it. |
735 base::PostTaskAndReplyWithResult( | 778 base::PostTaskAndReplyWithResult( |
736 blocking_task_runner_.get(), FROM_HERE, | 779 blocking_task_runner_.get(), FROM_HERE, |
737 base::Bind(&LaunchAndWaitForExit, invocation_), | 780 base::Bind(&LaunchAndWaitForExit, actual_invocation), |
738 base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this), | 781 base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this), |
739 base::Time::Now(), version_, invocation_)); | 782 base::Time::Now(), version_, invocation_)); |
740 } else { | 783 } else { |
741 main_thread_task_runner_->PostDelayedTask( | 784 main_thread_task_runner_->PostDelayedTask( |
742 FROM_HERE, | 785 FROM_HERE, |
743 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), | 786 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), |
744 next_trigger_delay); | 787 next_trigger_delay); |
745 } | 788 } |
746 } | 789 } |
747 | 790 |
791 // Returns true if the experiment to send reporter logs is enabled, the user | |
792 // opted into Safe Browsing extended reporting, and logs have been sent at | |
793 // least |kSwReporterLastTimeSentReport| days ago. | |
794 bool ShouldSendReporterLogs(const PrefService& local_state) { | |
795 if (!base::FeatureList::IsEnabled(kSwReporterExtendedSafeBrowsingFeature) || | |
796 !SafeBrowsingExtendedReportingEnabled()) { | |
797 return false; | |
798 } | |
799 | |
800 const base::Time now = base::Time::Now(); | |
801 const base::Time last_time_sent_logs = base::Time::FromInternalValue( | |
802 local_state.GetInt64(prefs::kSwReporterLastTimeSentReport)); | |
803 // Send the logs if the last send was in the future. This is intended as a | |
804 // measure for failure recovery, in case the time in local state is | |
805 // incorrectly set to the future. | |
806 if (last_time_sent_logs > now) | |
807 return true; | |
808 // Otherwise, send them if the interval has passed. | |
809 return last_time_sent_logs + | |
810 base::TimeDelta::FromDays(kDaysBetweenReporterLogsSent) <= | |
811 now; | |
812 } | |
813 | |
814 void AddSwitchesForExtendedReporterUser(SwReporterInvocation* invocation) { | |
815 invocation->command_line.AppendSwitch(kExtendedSafeBrowsingEnabledSwitch); | |
816 invocation->command_line.AppendSwitchASCII( | |
817 kChromeVersionSwitch, version_info::GetVersionNumber()); | |
818 invocation->command_line.AppendSwitchNative( | |
819 kChromeChannelSwitch, base::IntToString16(ChannelAsInt())); | |
820 } | |
821 | |
748 bool first_run_ = true; | 822 bool first_run_ = true; |
749 SwReporterInvocation invocation_; | 823 SwReporterInvocation invocation_; |
750 base::Version version_; | 824 base::Version version_; |
751 scoped_refptr<base::TaskRunner> main_thread_task_runner_; | 825 scoped_refptr<base::TaskRunner> main_thread_task_runner_; |
752 scoped_refptr<base::TaskRunner> blocking_task_runner_; | 826 scoped_refptr<base::TaskRunner> blocking_task_runner_; |
753 | 827 |
754 // This value is used to identify how long to wait before starting a new run | 828 // This value is used to identify how long to wait before starting a new run |
755 // of the reporter. It's initialized with the default value and may be changed | 829 // of the reporter. It's initialized with the default value and may be changed |
756 // to a different value when a prompt is pending and the reporter should be | 830 // to a different value when a prompt is pending and the reporter should be |
757 // run before adding the global error to the Chrome menu. | 831 // run before adding the global error to the Chrome menu. |
758 int days_between_reporter_runs_ = kDaysBetweenSuccessfulSwReporterRuns; | 832 int days_between_reporter_runs_ = kDaysBetweenSuccessfulSwReporterRuns; |
759 | 833 |
760 // A single leaky instance. | 834 // A single leaky instance. |
761 static ReporterRunner* instance_; | 835 static ReporterRunner* instance_; |
762 | 836 |
763 DISALLOW_COPY_AND_ASSIGN(ReporterRunner); | 837 DISALLOW_COPY_AND_ASSIGN(ReporterRunner); |
764 }; | 838 }; |
765 | 839 |
766 ReporterRunner* ReporterRunner::instance_ = nullptr; | 840 ReporterRunner* ReporterRunner::instance_ = nullptr; |
767 | 841 |
768 } // namespace | 842 } // namespace |
769 | 843 |
770 SwReporterInvocation::SwReporterInvocation() | 844 SwReporterInvocation::SwReporterInvocation() |
771 : command_line(base::CommandLine::NO_PROGRAM) {} | 845 : command_line(base::CommandLine::NO_PROGRAM) {} |
772 | 846 |
847 SwReporterInvocation::SwReporterInvocation(const SwReporterInvocation& other) | |
848 : command_line(other.command_line), | |
849 suffix(other.suffix), | |
850 is_experimental(other.is_experimental) {} | |
851 | |
773 SwReporterInvocation SwReporterInvocation::FromFilePath( | 852 SwReporterInvocation SwReporterInvocation::FromFilePath( |
774 const base::FilePath& exe_path) { | 853 const base::FilePath& exe_path) { |
775 SwReporterInvocation invocation; | 854 SwReporterInvocation invocation; |
776 invocation.command_line = base::CommandLine(exe_path); | 855 invocation.command_line = base::CommandLine(exe_path); |
777 return invocation; | 856 return invocation; |
778 } | 857 } |
779 | 858 |
780 SwReporterInvocation SwReporterInvocation::FromCommandLine( | 859 SwReporterInvocation SwReporterInvocation::FromCommandLine( |
781 const base::CommandLine& command_line) { | 860 const base::CommandLine& command_line) { |
782 SwReporterInvocation invocation; | 861 SwReporterInvocation invocation; |
(...skipping 30 matching lines...) Expand all Loading... | |
813 KEY_QUERY_VALUE); | 892 KEY_QUERY_VALUE); |
814 | 893 |
815 return srt_cleaner_key.Valid() && srt_cleaner_key.GetValueCount() > 0; | 894 return srt_cleaner_key.Valid() && srt_cleaner_key.GetValueCount() > 0; |
816 } | 895 } |
817 | 896 |
818 void SetSwReporterTestingDelegate(SwReporterTestingDelegate* delegate) { | 897 void SetSwReporterTestingDelegate(SwReporterTestingDelegate* delegate) { |
819 g_testing_delegate_ = delegate; | 898 g_testing_delegate_ = delegate; |
820 } | 899 } |
821 | 900 |
822 } // namespace safe_browsing | 901 } // namespace safe_browsing |
OLD | NEW |