Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(135)

Side by Side Diff: chrome/browser/chromeos/policy/system_log_uploader.cc

Issue 1610123003: Added anonymizer to SystemLogUploader. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 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 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/chromeos/policy/system_log_uploader.h" 5 #include "chrome/browser/chromeos/policy/system_log_uploader.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "base/command_line.h" 11 #include "base/command_line.h"
12 #include "base/files/file_util.h" 12 #include "base/files/file_util.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/macros.h" 14 #include "base/macros.h"
15 #include "base/metrics/histogram_macros.h" 15 #include "base/metrics/histogram_macros.h"
16 #include "base/strings/string_number_conversions.h" 16 #include "base/strings/string_number_conversions.h"
17 #include "base/strings/string_split.h" 17 #include "base/strings/string_split.h"
18 #include "base/strings/stringprintf.h" 18 #include "base/strings/stringprintf.h"
19 #include "base/task_runner_util.h" 19 #include "base/task_runner_util.h"
20 #include "chrome/browser/browser_process.h" 20 #include "chrome/browser/browser_process.h"
21 #include "chrome/browser/chromeos/policy/upload_job_impl.h" 21 #include "chrome/browser/chromeos/policy/upload_job_impl.h"
22 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" 22 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
23 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h " 23 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h "
24 #include "chrome/common/chrome_switches.h" 24 #include "chrome/common/chrome_switches.h"
25 #include "components/policy/core/browser/browser_policy_connector.h" 25 #include "components/policy/core/browser/browser_policy_connector.h"
26 #include "components/policy/core/common/cloud/enterprise_metrics.h" 26 #include "components/policy/core/common/cloud/enterprise_metrics.h"
27 #include "content/public/browser/browser_thread.h" 27 #include "content/public/browser/browser_thread.h"
28 #include "net/http/http_request_headers.h" 28 #include "net/http/http_request_headers.h"
29 #include "third_party/re2/src/re2/re2.h"
30 29
31 namespace { 30 namespace {
32 // The maximum number of successive retries. 31 // The maximum number of successive retries.
33 const int kMaxNumRetries = 1; 32 const int kMaxNumRetries = 1;
34 33
35 // String constant defining the url tail we upload system logs to. 34 // String constant defining the url tail we upload system logs to.
36 const char* kSystemLogUploadUrlTail = "/upload"; 35 const char* kSystemLogUploadUrlTail = "/upload";
37 36
38 // The file names of the system logs to upload. 37 // The file names of the system logs to upload.
39 // Note: do not add anything to this list without checking for PII in the file. 38 // Note: do not add anything to this list without checking for PII in the file.
40 const char* const kSystemLogFileNames[] = { 39 const char* const kSystemLogFileNames[] = {
41 "/var/log/bios_info.txt", "/var/log/chrome/chrome", 40 "/var/log/bios_info.txt", "/var/log/chrome/chrome",
42 "/var/log/eventlog.txt", "/var/log/platform_info.txt", 41 "/var/log/eventlog.txt", "/var/log/platform_info.txt",
43 "/var/log/messages", "/var/log/messages.1", 42 "/var/log/messages", "/var/log/messages.1",
44 "/var/log/net.log", "/var/log/net.1.log", 43 "/var/log/net.log", "/var/log/net.1.log",
45 "/var/log/ui/ui.LATEST", "/var/log/update_engine.log"}; 44 "/var/log/ui/ui.LATEST", "/var/log/update_engine.log"};
46 45
47 const char kEmailAddress[] =
48 "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}\\@"
49 "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}(\\.[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25})+";
50 const char kIPAddress[] =
51 "((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])"
52 "\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2"
53 "[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
54 "[0-9]{2}|[1-9][0-9]|[0-9]))";
55 const char kIPv6Address[] =
56 "(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|"
57 "([0-9a-fA-F]{1,4}:){1,7}:|"
58 "([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|"
59 "([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|"
60 "([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|"
61 "([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|"
62 "([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|"
63 "[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|"
64 ":((:[0-9a-fA-F]{1,4}){1,7}|:)|"
65 "fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|"
66 "::(ffff(:0{1,4}){0,1}:){0,1}"
67 "((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}"
68 "(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|"
69 "([0-9a-fA-F]{1,4}:){1,4}:"
70 "((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}"
71 "(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))";
72
73 const char kWebUrl[] = "(http|https|Http|Https|rtsp|Rtsp):\\/\\/";
74
75 // Reads the system log files as binary files, stores the files as pairs 46 // Reads the system log files as binary files, stores the files as pairs
76 // (file name, data) and returns. Called on blocking thread. 47 // (file name, data) and returns. Called on blocking thread.
77 scoped_ptr<policy::SystemLogUploader::SystemLogs> ReadFiles() { 48 scoped_ptr<policy::SystemLogUploader::SystemLogs> ReadFiles() {
78 scoped_ptr<policy::SystemLogUploader::SystemLogs> system_logs( 49 scoped_ptr<policy::SystemLogUploader::SystemLogs> system_logs(
79 new policy::SystemLogUploader::SystemLogs()); 50 new policy::SystemLogUploader::SystemLogs());
80 for (auto const file_path : kSystemLogFileNames) { 51 for (auto const file_path : kSystemLogFileNames) {
81 if (!base::PathExists(base::FilePath(file_path))) 52 if (!base::PathExists(base::FilePath(file_path)))
82 continue; 53 continue;
83 std::string data = std::string(); 54 std::string data = std::string();
84 if (!base::ReadFileToString(base::FilePath(file_path), &data)) { 55 if (!base::ReadFileToString(base::FilePath(file_path), &data)) {
85 LOG(ERROR) << "Failed to read the system log file from the disk " 56 LOG(ERROR) << "Failed to read the system log file from the disk "
86 << file_path << std::endl; 57 << file_path << std::endl;
87 } 58 }
88 system_logs->push_back(std::make_pair( 59 system_logs->push_back(std::make_pair(file_path, data));
Thiemo Nagel 2016/01/21 14:22:29 Why have you moved the anonymizing step to UploadS
Polina Bondarenko 2016/01/21 16:16:08 Yes, you're right, I like mostly the idea of movin
89 file_path, policy::SystemLogUploader::RemoveSensitiveData(data)));
90 } 60 }
91 return system_logs; 61 return system_logs;
92 } 62 }
93 63
94 // An implementation of the |SystemLogUploader::Delegate|, that is used to 64 // An implementation of the |SystemLogUploader::Delegate|, that is used to
95 // create an upload job and load system logs from the disk. 65 // create an upload job and load system logs from the disk.
96 class SystemLogDelegate : public policy::SystemLogUploader::Delegate { 66 class SystemLogDelegate : public policy::SystemLogUploader::Delegate {
97 public: 67 public:
98 SystemLogDelegate(); 68 SystemLogDelegate();
99 ~SystemLogDelegate() override; 69 ~SystemLogDelegate() override;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII( 118 base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
149 switches::kSystemLogUploadFrequency); 119 switches::kSystemLogUploadFrequency);
150 int frequency; 120 int frequency;
151 if (base::StringToInt(string_value, &frequency)) { 121 if (base::StringToInt(string_value, &frequency)) {
152 upload_frequency = base::TimeDelta::FromMilliseconds(frequency); 122 upload_frequency = base::TimeDelta::FromMilliseconds(frequency);
153 } 123 }
154 } 124 }
155 return upload_frequency; 125 return upload_frequency;
156 } 126 }
157 127
158 void RecordSystemLogPIILeak(policy::SystemLogPIIType type) {
159 UMA_HISTOGRAM_ENUMERATION(policy::kMetricSystemLogPII, type,
160 policy::SYSTEM_LOG_PII_TYPE_SIZE);
161 }
162
163 std::string GetUploadUrl() { 128 std::string GetUploadUrl() {
164 return policy::BrowserPolicyConnector::GetDeviceManagementUrl() + 129 return policy::BrowserPolicyConnector::GetDeviceManagementUrl() +
165 kSystemLogUploadUrlTail; 130 kSystemLogUploadUrlTail;
166 } 131 }
167 132
168 } // namespace 133 } // namespace
169 134
170 namespace policy { 135 namespace policy {
171 136
172 // Determines the time between log uploads. 137 // Determines the time between log uploads.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 if (retry_count_++ < kMaxNumRetries) { 205 if (retry_count_++ < kMaxNumRetries) {
241 ScheduleNextSystemLogUpload( 206 ScheduleNextSystemLogUpload(
242 base::TimeDelta::FromMilliseconds(kErrorUploadDelayMs)); 207 base::TimeDelta::FromMilliseconds(kErrorUploadDelayMs));
243 } else { 208 } else {
244 // No more retries. 209 // No more retries.
245 retry_count_ = 0; 210 retry_count_ = 0;
246 ScheduleNextSystemLogUpload(upload_frequency_); 211 ScheduleNextSystemLogUpload(upload_frequency_);
247 } 212 }
248 } 213 }
249 214
250 // static
251 std::string SystemLogUploader::RemoveSensitiveData(const std::string& data) { 215 std::string SystemLogUploader::RemoveSensitiveData(const std::string& data) {
252 std::string result = ""; 216 std::string anonymized = anonymizer_.Anonymize(data);
253 RE2 email_pattern(kEmailAddress), ipv4_pattern(kIPAddress), 217 UMA_HISTOGRAM_BOOLEAN(policy::kMetricSystemLogPII,
254 ipv6_pattern(kIPv6Address), url_pattern(kWebUrl); 218 anonymized.compare(data) != 0);
255 219 return anonymized;
256 for (const std::string& line : base::SplitString(
257 data, "\n", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL)) {
258 // Email.
259 if (RE2::PartialMatch(line, email_pattern)) {
260 RecordSystemLogPIILeak(SYSTEM_LOG_PII_TYPE_EMAIL_ADDRESS);
261 continue;
262 }
263
264 // IPv4 address.
265 if (RE2::PartialMatch(line, ipv4_pattern)) {
266 RecordSystemLogPIILeak(SYSTEM_LOG_PII_TYPE_IP_ADDRESS);
267 continue;
268 }
269
270 // IPv6 address.
271 if (RE2::PartialMatch(line, ipv6_pattern)) {
272 RecordSystemLogPIILeak(SYSTEM_LOG_PII_TYPE_IP_ADDRESS);
273 continue;
274 }
275
276 // URL.
277 if (RE2::PartialMatch(line, url_pattern)) {
278 RecordSystemLogPIILeak(SYSTEM_LOG_PII_TYPE_WEB_URL);
279 continue;
280 }
281
282 // SSID.
283 if (line.find("SSID=") != std::string::npos) {
284 RecordSystemLogPIILeak(SYSTEM_LOG_PII_TYPE_SSID);
285 continue;
286 }
287
288 result += line + "\n";
289 }
290 return result;
291 } 220 }
292 221
293 void SystemLogUploader::RefreshUploadSettings() { 222 void SystemLogUploader::RefreshUploadSettings() {
294 // Attempt to fetch the current value of the reporting settings. 223 // Attempt to fetch the current value of the reporting settings.
295 // If trusted values are not available, register this function to be called 224 // If trusted values are not available, register this function to be called
296 // back when they are available. 225 // back when they are available.
297 chromeos::CrosSettings* settings = chromeos::CrosSettings::Get(); 226 chromeos::CrosSettings* settings = chromeos::CrosSettings::Get();
298 if (chromeos::CrosSettingsProvider::TRUSTED != 227 if (chromeos::CrosSettingsProvider::TRUSTED !=
299 settings->PrepareTrustedValues( 228 settings->PrepareTrustedValues(
300 base::Bind(&SystemLogUploader::RefreshUploadSettings, 229 base::Bind(&SystemLogUploader::RefreshUploadSettings,
(...skipping 14 matching lines...) Expand all
315 DCHECK(!upload_job_); 244 DCHECK(!upload_job_);
316 245
317 GURL upload_url(GetUploadUrl()); 246 GURL upload_url(GetUploadUrl());
318 DCHECK(upload_url.is_valid()); 247 DCHECK(upload_url.is_valid());
319 upload_job_ = syslog_delegate_->CreateUploadJob(upload_url, this); 248 upload_job_ = syslog_delegate_->CreateUploadJob(upload_url, this);
320 249
321 // Start a system log upload. 250 // Start a system log upload.
322 int file_number = 1; 251 int file_number = 1;
323 for (const auto& syslog_entry : *system_logs) { 252 for (const auto& syslog_entry : *system_logs) {
324 std::map<std::string, std::string> header_fields; 253 std::map<std::string, std::string> header_fields;
325 scoped_ptr<std::string> data = 254 scoped_ptr<std::string> data = make_scoped_ptr(
326 make_scoped_ptr(new std::string(syslog_entry.second)); 255 new std::string(RemoveSensitiveData(syslog_entry.second)));
327 header_fields.insert(std::make_pair(kFileTypeHeaderName, kFileTypeLogFile)); 256 header_fields.insert(std::make_pair(kFileTypeHeaderName, kFileTypeLogFile));
328 header_fields.insert(std::make_pair(net::HttpRequestHeaders::kContentType, 257 header_fields.insert(std::make_pair(net::HttpRequestHeaders::kContentType,
329 kContentTypePlainText)); 258 kContentTypePlainText));
330 upload_job_->AddDataSegment( 259 upload_job_->AddDataSegment(
331 base::StringPrintf(kNameFieldTemplate, file_number), syslog_entry.first, 260 base::StringPrintf(kNameFieldTemplate, file_number), syslog_entry.first,
332 header_fields, std::move(data)); 261 header_fields, std::move(data));
333 ++file_number; 262 ++file_number;
334 } 263 }
335 upload_job_->Start(); 264 upload_job_->Start();
336 } 265 }
(...skipping 20 matching lines...) Expand all
357 base::TimeDelta()); 286 base::TimeDelta());
358 // Ensure that we never have more than one pending delayed task. 287 // Ensure that we never have more than one pending delayed task.
359 weak_factory_.InvalidateWeakPtrs(); 288 weak_factory_.InvalidateWeakPtrs();
360 task_runner_->PostDelayedTask(FROM_HERE, 289 task_runner_->PostDelayedTask(FROM_HERE,
361 base::Bind(&SystemLogUploader::StartLogUpload, 290 base::Bind(&SystemLogUploader::StartLogUpload,
362 weak_factory_.GetWeakPtr()), 291 weak_factory_.GetWeakPtr()),
363 delay); 292 delay);
364 } 293 }
365 294
366 } // namespace policy 295 } // namespace policy
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698