Chromium Code Reviews| 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 | |
| 62 namespace { | 69 namespace { |
| 63 | 70 |
| 64 // Used to send UMA information about missing start and end time registry | 71 // 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 | 72 // values for the reporter. Replicated in the histograms.xml file, so the order |
| 66 // MUST NOT CHANGE. | 73 // MUST NOT CHANGE. |
| 67 enum SwReporterRunningTimeRegistryError { | 74 enum SwReporterRunningTimeRegistryError { |
| 68 REPORTER_RUNNING_TIME_ERROR_NO_ERROR = 0, | 75 REPORTER_RUNNING_TIME_ERROR_NO_ERROR = 0, |
| 69 REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID = 1, | 76 REPORTER_RUNNING_TIME_ERROR_REGISTRY_KEY_INVALID = 1, |
| 70 REPORTER_RUNNING_TIME_ERROR_MISSING_START_TIME = 2, | 77 REPORTER_RUNNING_TIME_ERROR_MISSING_START_TIME = 2, |
| 71 REPORTER_RUNNING_TIME_ERROR_MISSING_END_TIME = 3, | 78 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()) { | 435 if (error->GetBubbleView()) { |
| 429 show_bubble = false; | 436 show_bubble = false; |
| 430 break; | 437 break; |
| 431 } | 438 } |
| 432 } | 439 } |
| 433 } | 440 } |
| 434 if (show_bubble) | 441 if (show_bubble) |
| 435 global_error->ShowBubbleView(browser); | 442 global_error->ShowBubbleView(browser); |
| 436 } | 443 } |
| 437 | 444 |
| 445 bool BrowserIsSafeBrowsingExtended(const Browser* browser) { | |
| 446 const Profile* profile = browser->profile(); | |
| 447 return profile && !profile->IsOffTheRecord() && | |
| 448 profile->GetPrefs()->GetBoolean( | |
| 449 prefs::kSafeBrowsingExtendedReportingEnabled); | |
| 450 } | |
| 451 | |
| 452 // Returns true if there is a profile that is not in incognito mode and the user | |
| 453 // has opted into Safe Browsing extended reporting. | |
| 454 bool SafeBrowsingExtendedReportingEnabled() { | |
| 455 BrowserList* browser_list = BrowserList::GetInstance(); | |
| 456 return std::any_of(browser_list->begin_last_active(), | |
| 457 browser_list->end_last_active(), | |
| 458 &BrowserIsSafeBrowsingExtended); | |
| 459 } | |
| 460 | |
| 438 // This function is called from a worker thread to launch the SwReporter and | 461 // 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 | 462 // 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 | 463 // interrupted by a shutdown at any time, so it shouldn't depend on anything |
| 441 // external that could be shut down beforehand. | 464 // external that could be shut down beforehand. |
| 442 int LaunchAndWaitForExit(const SwReporterInvocation& invocation) { | 465 int LaunchAndWaitForExit(const SwReporterInvocation& invocation) { |
| 443 if (g_testing_delegate_) | 466 if (g_testing_delegate_) |
| 444 return g_testing_delegate_->LaunchReporter(invocation); | 467 return g_testing_delegate_->LaunchReporter(invocation); |
| 445 base::Process reporter_process = | 468 base::Process reporter_process = |
| 446 base::LaunchProcess(invocation.command_line, base::LaunchOptions()); | 469 base::LaunchProcess(invocation.command_line, base::LaunchOptions()); |
| 447 // This exit code is used to identify that a reporter run didn't happen, so | 470 // 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 + | 744 last_time_triggered + |
| 722 base::TimeDelta::FromDays(days_between_reporter_runs_) - | 745 base::TimeDelta::FromDays(days_between_reporter_runs_) - |
| 723 base::Time::Now()); | 746 base::Time::Now()); |
| 724 if (next_trigger_delay.ToInternalValue() <= 0 || | 747 if (next_trigger_delay.ToInternalValue() <= 0 || |
| 725 // Also make sure the kSwReporterLastTimeTriggered value is not set in | 748 // Also make sure the kSwReporterLastTimeTriggered value is not set in |
| 726 // the future. | 749 // the future. |
| 727 last_time_triggered > base::Time::Now()) { | 750 last_time_triggered > base::Time::Now()) { |
| 728 if (g_testing_delegate_) | 751 if (g_testing_delegate_) |
| 729 g_testing_delegate_->NotifyLaunchReady(); | 752 g_testing_delegate_->NotifyLaunchReady(); |
| 730 | 753 |
| 754 // Creating a new invocation to add switches for users who opted into | |
| 755 // extended Safe Browsing reporting. The invocation object is changed | |
| 756 // locally right before the actual process is launched because user status | |
| 757 // can between this and the next run for this ReporterRunner object. For | |
| 758 // example, the ReporterDone() callback schedules the next run for a few | |
| 759 // days later, and the user might have changed settings in the meantime. | |
| 760 SwReporterInvocation actual_invocation(invocation_); | |
| 761 bool logging_enabled = ShouldSendReporterLogs(*local_state); | |
|
csharp
2016/09/02 21:16:25
Drop variable and just have the function call in t
ftirelo
2016/09/06 16:37:43
Done.
| |
| 762 if (logging_enabled) { | |
| 763 AddSwitchesForExtendedReporterUser(&actual_invocation); | |
| 764 local_state->SetInt64(prefs::kSwReporterLastTimeSentReport, | |
|
csharp
2016/09/02 21:16:25
Could you add a brief comment explaining why we se
ftirelo
2016/09/06 16:37:43
Done.
| |
| 765 base::Time::Now().ToInternalValue()); | |
| 766 } | |
| 731 // It's OK to simply |PostTaskAndReplyWithResult| so that | 767 // It's OK to simply |PostTaskAndReplyWithResult| so that |
| 732 // |LaunchAndWaitForExit| doesn't need to access | 768 // |LaunchAndWaitForExit| doesn't need to access |
| 733 // |main_thread_task_runner_| since the callback is not delayed and the | 769 // |main_thread_task_runner_| since the callback is not delayed and the |
| 734 // test task runner won't need to force it. | 770 // test task runner won't need to force it. |
| 735 base::PostTaskAndReplyWithResult( | 771 base::PostTaskAndReplyWithResult( |
| 736 blocking_task_runner_.get(), FROM_HERE, | 772 blocking_task_runner_.get(), FROM_HERE, |
| 737 base::Bind(&LaunchAndWaitForExit, invocation_), | 773 base::Bind(&LaunchAndWaitForExit, actual_invocation), |
| 738 base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this), | 774 base::Bind(&ReporterRunner::ReporterDone, base::Unretained(this), |
| 739 base::Time::Now(), version_, invocation_)); | 775 base::Time::Now(), version_, invocation_)); |
| 740 } else { | 776 } else { |
| 741 main_thread_task_runner_->PostDelayedTask( | 777 main_thread_task_runner_->PostDelayedTask( |
| 742 FROM_HERE, | 778 FROM_HERE, |
| 743 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), | 779 base::Bind(&ReporterRunner::TryToRun, base::Unretained(this)), |
| 744 next_trigger_delay); | 780 next_trigger_delay); |
| 745 } | 781 } |
| 746 } | 782 } |
| 747 | 783 |
| 784 // Returns true if the experiment to send reporter logs is enabled, the user | |
| 785 // opted into Safe Browsing extended reporting, and logs have been sent at | |
| 786 // least |kSwReporterLastTimeSentReport| days ago. | |
| 787 bool ShouldSendReporterLogs(const PrefService& local_state) { | |
| 788 if (!base::FeatureList::IsEnabled(kSwReporterExtendedSafeBrowsingFeature) || | |
| 789 !SafeBrowsingExtendedReportingEnabled()) { | |
| 790 return false; | |
| 791 } | |
| 792 | |
| 793 const base::Time now = base::Time::Now(); | |
| 794 const base::Time last_time_sent_logs = base::Time::FromInternalValue( | |
| 795 local_state.GetInt64(prefs::kSwReporterLastTimeSentReport)); | |
| 796 // Send the logs if the last send was in the future. This is intended as a | |
| 797 // measure for failure recovery, in case the time in local state is | |
| 798 // incorrectly set to the future. | |
| 799 if (last_time_sent_logs > now) | |
| 800 return true; | |
| 801 // Otherwise, send them if the interval has passed. | |
| 802 return last_time_sent_logs + | |
| 803 base::TimeDelta::FromDays(kDaysBetweenReporterLogsSent) <= | |
| 804 now; | |
| 805 } | |
| 806 | |
| 807 void AddSwitchesForExtendedReporterUser(SwReporterInvocation* invocation) { | |
| 808 invocation->command_line.AppendSwitch(kExtendedSafeBrowsingEnabledSwitch); | |
| 809 invocation->command_line.AppendSwitchASCII( | |
| 810 kChromeVersionSwitch, version_info::GetVersionNumber()); | |
| 811 invocation->command_line.AppendSwitchNative( | |
| 812 kChromeChannelSwitch, base::IntToString16(ChannelAsInt())); | |
| 813 } | |
| 814 | |
| 748 bool first_run_ = true; | 815 bool first_run_ = true; |
| 749 SwReporterInvocation invocation_; | 816 SwReporterInvocation invocation_; |
| 750 base::Version version_; | 817 base::Version version_; |
| 751 scoped_refptr<base::TaskRunner> main_thread_task_runner_; | 818 scoped_refptr<base::TaskRunner> main_thread_task_runner_; |
| 752 scoped_refptr<base::TaskRunner> blocking_task_runner_; | 819 scoped_refptr<base::TaskRunner> blocking_task_runner_; |
| 753 | 820 |
| 754 // This value is used to identify how long to wait before starting a new run | 821 // 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 | 822 // 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 | 823 // 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. | 824 // run before adding the global error to the Chrome menu. |
| 758 int days_between_reporter_runs_ = kDaysBetweenSuccessfulSwReporterRuns; | 825 int days_between_reporter_runs_ = kDaysBetweenSuccessfulSwReporterRuns; |
| 759 | 826 |
| 760 // A single leaky instance. | 827 // A single leaky instance. |
| 761 static ReporterRunner* instance_; | 828 static ReporterRunner* instance_; |
| 762 | 829 |
| 763 DISALLOW_COPY_AND_ASSIGN(ReporterRunner); | 830 DISALLOW_COPY_AND_ASSIGN(ReporterRunner); |
| 764 }; | 831 }; |
| 765 | 832 |
| 766 ReporterRunner* ReporterRunner::instance_ = nullptr; | 833 ReporterRunner* ReporterRunner::instance_ = nullptr; |
| 767 | 834 |
| 768 } // namespace | 835 } // namespace |
| 769 | 836 |
| 770 SwReporterInvocation::SwReporterInvocation() | 837 SwReporterInvocation::SwReporterInvocation() |
| 771 : command_line(base::CommandLine::NO_PROGRAM) {} | 838 : command_line(base::CommandLine::NO_PROGRAM) {} |
| 772 | 839 |
| 840 SwReporterInvocation::SwReporterInvocation(const SwReporterInvocation& other) | |
| 841 : command_line(other.command_line) {} | |
|
csharp
2016/09/02 21:16:25
Please also copy suffix and is_experimental
ftirelo
2016/09/06 16:37:43
Done.
| |
| 842 | |
| 773 SwReporterInvocation SwReporterInvocation::FromFilePath( | 843 SwReporterInvocation SwReporterInvocation::FromFilePath( |
| 774 const base::FilePath& exe_path) { | 844 const base::FilePath& exe_path) { |
| 775 SwReporterInvocation invocation; | 845 SwReporterInvocation invocation; |
| 776 invocation.command_line = base::CommandLine(exe_path); | 846 invocation.command_line = base::CommandLine(exe_path); |
| 777 return invocation; | 847 return invocation; |
| 778 } | 848 } |
| 779 | 849 |
| 780 SwReporterInvocation SwReporterInvocation::FromCommandLine( | 850 SwReporterInvocation SwReporterInvocation::FromCommandLine( |
| 781 const base::CommandLine& command_line) { | 851 const base::CommandLine& command_line) { |
| 782 SwReporterInvocation invocation; | 852 SwReporterInvocation invocation; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 813 KEY_QUERY_VALUE); | 883 KEY_QUERY_VALUE); |
| 814 | 884 |
| 815 return srt_cleaner_key.Valid() && srt_cleaner_key.GetValueCount() > 0; | 885 return srt_cleaner_key.Valid() && srt_cleaner_key.GetValueCount() > 0; |
| 816 } | 886 } |
| 817 | 887 |
| 818 void SetSwReporterTestingDelegate(SwReporterTestingDelegate* delegate) { | 888 void SetSwReporterTestingDelegate(SwReporterTestingDelegate* delegate) { |
| 819 g_testing_delegate_ = delegate; | 889 g_testing_delegate_ = delegate; |
| 820 } | 890 } |
| 821 | 891 |
| 822 } // namespace safe_browsing | 892 } // namespace safe_browsing |
| OLD | NEW |