1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_CHROMEOS_POLICY_SYSTEM_LOG_UPLOADER_H_
6 #define CHROME_BROWSER_CHROMEOS_POLICY_SYSTEM_LOG_UPLOADER_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
15 #include "base/macros.h"
16 #include "base/memory/ref_counted.h"
17 #include "base/memory/ref_counted_memory.h"
18 #include "base/memory/weak_ptr.h"
19 #include "base/threading/thread_checker.h"
20 #include "base/time/time.h"
21 #include "chrome/browser/chromeos/policy/upload_job.h"
22 #include "chrome/browser/chromeos/settings/cros_settings.h"
23 
24 namespace base {
25 class SequencedTaskRunner;
26 }
27 
28 namespace feedback {
29 class RedactionTool;
30 }
31 
32 namespace policy {
33 
34 // Class responsible for periodically uploading system logs, it handles the
35 // server responses by UploadJob:Delegate callbacks.
36 class SystemLogUploader : public UploadJob::Delegate {
37  public:
38   // Structure that stores the system log files as pairs: (file name, loaded
39   // from the disk binary file data).
40   using SystemLogs = std::vector<std::pair<std::string, std::string>>;
41 
42   // Remove lines from |data| that contain common PII (IP addresses, BSSIDs,
43   // SSIDs, URLs, e-mail addresses).
44   static std::string RemoveSensitiveData(feedback::RedactionTool* redactor,
45                                          const std::string& data);
46 
47   // Refresh constants.
48   static const int64_t kDefaultUploadDelayMs;
49   static const int64_t kErrorUploadDelayMs;
50 
51   static const int64_t kLogThrottleCount;
52   static const base::TimeDelta kLogThrottleWindowDuration;
53 
54   // Http header constants to upload non-zipped logs.
55   static const char* const kNameFieldTemplate;
56   static const char* const kFileTypeHeaderName;
57   static const char* const kFileTypeLogFile;
58   static const char* const kContentTypePlainText;
59 
60   // Http header constants to upload zipped logs.
61   static const char* const kFileTypeZippedLogFile;
62   static const char* const kZippedLogsName;
63   static const char* const kZippedLogsFileName;
64   static const char* const kContentTypeOctetStream;
65 
66   // UMA histogram name.
67   static const char* const kSystemLogUploadResultHistogram;
68 
69   // A delegate interface used by SystemLogUploader to read the system logs
70   // from the disk and create an upload job.
71   class Delegate {
72    public:
73     using LogUploadCallback =
74         base::OnceCallback<void(std::unique_ptr<SystemLogs> system_logs)>;
75 
76     using ZippedLogUploadCallback =
77         base::OnceCallback<void(std::string zipped_system_logs)>;
78 
~Delegate()79     virtual ~Delegate() {}
80 
81     // Returns current policy dump in JSON format.
82     virtual std::string GetPolicyAsJSON() = 0;
83 
84     // Loads system logs and invokes |upload_callback|.
85     virtual void LoadSystemLogs(LogUploadCallback upload_callback) = 0;
86 
87     // Creates a new fully configured instance of an UploadJob. This method
88     // will be called exactly once per every system log upload.
89     virtual std::unique_ptr<UploadJob> CreateUploadJob(
90         const GURL& upload_url,
91         UploadJob::Delegate* delegate) = 0;
92 
93     // Zips system logs in a single zip archive and invokes |upload_callback|.
94     virtual void ZipSystemLogs(std::unique_ptr<SystemLogs> system_logs,
95                                ZippedLogUploadCallback upload_callback) = 0;
96   };
97 
98   // Enum used for UMA. Do NOT reorder or remove entry.
99   // Don't forget to update enums.xml when adding new entries.
100   enum SystemLogUploadResult {
101     NON_ZIPPED_LOGS_UPLOAD_SUCCESS = 0,
102     ZIPPED_LOGS_UPLOAD_SUCCESS = 1,
103     NON_ZIPPED_LOGS_UPLOAD_FAILURE = 2,
104     ZIPPED_LOGS_UPLOAD_FAILURE = 3,
105 
106     // Magic constant used by the histogram macros.
107     // Always update it to the max value.
108     kMaxValue = ZIPPED_LOGS_UPLOAD_FAILURE
109   };
110 
111   // Constructor. Callers can inject their own Delegate. A nullptr can be passed
112   // for |syslog_delegate| to use the default implementation.
113   SystemLogUploader(
114       std::unique_ptr<Delegate> syslog_delegate,
115       const scoped_refptr<base::SequencedTaskRunner>& task_runner);
116 
117   ~SystemLogUploader() override;
118 
119   // Returns the time of the last upload attempt, or Time(0) if no upload has
120   // ever happened.
last_upload_attempt()121   base::Time last_upload_attempt() const { return last_upload_attempt_; }
122 
123   void ScheduleNextSystemLogUploadImmediately();
124 
125   // Removes the log upload times before the particular time window ( which were
126   // uploaded before kLogThrottleWindowDuration time from now), add the latest
127   // log upload time if any and return the oldest log upload time in the
128   // particular time window.
129   base::Time UpdateLocalStateForLogs();
130 
131   // UploadJob::Delegate:
132   // Callbacks handle success and failure results of upload, destroy the
133   // upload job.
134   void OnSuccess() override;
135   void OnFailure(UploadJob::ErrorCode error_code) override;
136 
upload_enabled()137   bool upload_enabled() const { return upload_enabled_; }
138 
139  private:
140   // Updates the system log upload enabled field from settings.
141   void RefreshUploadSettings();
142 
143   // Starts the system log loading process.
144   void StartLogUpload();
145 
146   // The callback is invoked by the Delegate if system logs have been loaded
147   // from disk, adds policy dump and calls UploadSystemLogs.
148   void OnSystemLogsLoaded(std::unique_ptr<SystemLogs> system_logs);
149 
150   // Uploads system logs.
151   void UploadSystemLogs(std::unique_ptr<SystemLogs> system_logs);
152 
153   // Uploads zipped system logs.
154   void UploadZippedSystemLogs(std::string zipped_system_logs);
155 
156   // Helper method that figures out when the next system log upload should
157   // be scheduled.
158   void ScheduleNextSystemLogUpload(base::TimeDelta frequency);
159 
160   // The number of consequent retries after the failed uploads.
161   int retry_count_;
162 
163   // How long to wait between system log uploads.
164   base::TimeDelta upload_frequency_;
165 
166   // The time the last upload attempt was performed.
167   base::Time last_upload_attempt_;
168 
169   // TaskRunner used for scheduling upload tasks.
170   const scoped_refptr<base::SequencedTaskRunner> task_runner_;
171 
172   // The upload job that is re-created on every system log upload.
173   std::unique_ptr<UploadJob> upload_job_;
174 
175   // The Delegate is used to load system logs and create UploadJobs.
176   std::unique_ptr<Delegate> syslog_delegate_;
177 
178   // True if system log upload is enabled. Kept cached in this object because
179   // CrosSettings can switch to an unstrusted state temporarily, and we want to
180   // use the last-known trusted values.
181   bool upload_enabled_;
182 
183   // Observer to changes in system log upload settings.
184   std::unique_ptr<chromeos::CrosSettings::ObserverSubscription>
185       upload_enabled_observer_;
186 
187   base::ThreadChecker thread_checker_;
188 
189   // Used to prevent a race condition where two log uploads are being executed
190   // in parallel.
191   bool log_upload_in_progress_ = false;
192 
193   // Note: This should remain the last member so it'll be destroyed and
194   // invalidate the weak pointers before any other members are destroyed.
195   base::WeakPtrFactory<SystemLogUploader> weak_factory_{this};
196 
197   DISALLOW_COPY_AND_ASSIGN(SystemLogUploader);
198 };
199 
200 }  // namespace policy
201 
202 #endif  // CHROME_BROWSER_CHROMEOS_POLICY_SYSTEM_LOG_UPLOADER_H_
203