diff options
| author | Linus Färnstrand <linus@mullvad.net> | 2017-11-08 14:30:16 +0100 |
|---|---|---|
| committer | Linus Färnstrand <linus@mullvad.net> | 2017-11-08 14:30:16 +0100 |
| commit | 2833754f1c863bf30dea4b1769078ffd9dce254a (patch) | |
| tree | 3b1e63c82e81f7cbb61b2fe055124f4cd60823ca | |
| parent | 3899bc25ace5ae802e0890d5b045b21675f93066 (diff) | |
| parent | aaeee003fcb5c27c24ecc87b2a5273e9f5d600b4 (diff) | |
| download | mullvadvpn-2833754f1c863bf30dea4b1769078ffd9dce254a.tar.xz mullvadvpn-2833754f1c863bf30dea4b1769078ffd9dce254a.zip | |
Merge branch 'censor-problem-report-logs'
| -rw-r--r-- | CHANGELOG.md | 1 | ||||
| -rwxr-xr-x | format.sh | 2 | ||||
| -rw-r--r-- | mullvad-cli/src/cmds/account.rs | 10 | ||||
| -rw-r--r-- | mullvad-daemon/src/bin/problem-report.rs | 52 | ||||
| -rw-r--r-- | mullvad-daemon/src/settings.rs | 19 | ||||
| -rw-r--r-- | socket-relay/src/udp.rs | 32 |
6 files changed, 74 insertions, 42 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index e20a2ecce5..24d64395f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). ## [Unreleased] ### Added - Possibility to shut down the daemon via an RPC call. +- Problem reports, for collecting and sending app logs to Mullvad support. ## [2017.1-beta5] - 2017-10-17 @@ -5,7 +5,7 @@ set -u -VERSION="0.2.13" +VERSION="0.2.15" CMD="rustfmt" INSTALL_CMD="cargo install --vers $VERSION --force rustfmt-nightly" diff --git a/mullvad-cli/src/cmds/account.rs b/mullvad-cli/src/cmds/account.rs index 854ce8fc91..1475c333a7 100644 --- a/mullvad-cli/src/cmds/account.rs +++ b/mullvad-cli/src/cmds/account.rs @@ -50,10 +50,12 @@ impl Command for Account { impl Account { fn set(&self, token: Option<&str>) -> Result<()> { - rpc::call("set_account", &[token]).map(|_: Option<()>| if let Some(token) = token { - println!("Mullvad account \"{}\" set", token); - } else { - println!("Mullvad account removed"); + rpc::call("set_account", &[token]).map(|_: Option<()>| { + if let Some(token) = token { + println!("Mullvad account \"{}\" set", token); + } else { + println!("Mullvad account removed"); + } }) } diff --git a/mullvad-daemon/src/bin/problem-report.rs b/mullvad-daemon/src/bin/problem-report.rs index 3d617b4bf6..582d9cd659 100644 --- a/mullvad-daemon/src/bin/problem-report.rs +++ b/mullvad-daemon/src/bin/problem-report.rs @@ -14,7 +14,9 @@ extern crate error_chain; extern crate mullvad_rpc; use error_chain::ChainedError; + use std::cmp::min; +use std::env; use std::fmt; use std::fs::File; use std::io::{self, Read, Seek, SeekFrom, Write}; @@ -59,18 +61,28 @@ fn run() -> Result<()> { .about("Collect problem report") .arg( clap::Arg::with_name("output") + .help("The destination path for saving the collected report.") .long("output") .short("o") + .value_name("PATH") .takes_value(true) - .help("The destination path for saving the collected report.") .required(true), ) .arg( clap::Arg::with_name("logs") .help("The paths to log files to include in the problem report.") .multiple(true) + .value_name("LOG PATHS") .takes_value(true) .required(false), + ) + .arg( + clap::Arg::with_name("redact") + .help("List of words and expressions to remove from the report") + .long("redact") + .value_name("PHRASE") + .multiple(true) + .takes_value(true), ), ) .subcommand( @@ -105,12 +117,15 @@ fn run() -> Result<()> { let matches = app.get_matches(); if let Some(collect_matches) = matches.subcommand_matches("collect") { + let redacts = collect_matches + .values_of_lossy("redact") + .unwrap_or(Vec::new()); let log_paths = collect_matches .values_of_os("logs") .map(|os_values| os_values.map(Path::new).collect()) .unwrap_or(Vec::new()); let output_path = Path::new(collect_matches.value_of_os("output").unwrap()); - collect_report(&log_paths, output_path) + collect_report(&log_paths, output_path, redacts) } else if let Some(send_matches) = matches.subcommand_matches("send") { let report_path = Path::new(send_matches.value_of_os("report").unwrap()); let user_email = send_matches.value_of("email").unwrap_or(""); @@ -121,8 +136,8 @@ fn run() -> Result<()> { } } -fn collect_report(log_paths: &[&Path], output_path: &Path) -> Result<()> { - let mut problem_report = ProblemReport::new(); +fn collect_report(log_paths: &[&Path], output_path: &Path, redacts: Vec<String>) -> Result<()> { + let mut problem_report = ProblemReport::new(redacts); for log_path in log_paths { problem_report.add_log(log_path); } @@ -155,13 +170,17 @@ fn write_problem_report(path: &Path, problem_report: ProblemReport) -> io::Resul struct ProblemReport { system_info: Vec<String>, logs: Vec<(String, String)>, + redacts: Vec<String>, } impl ProblemReport { - pub fn new() -> Self { + /// Creates a new problem report with system information. Logs can be added with `add_log`. + /// Logs will have all strings in `redacts` removed from them. + pub fn new(redacts: Vec<String>) -> Self { ProblemReport { system_info: Self::collect_system_info(), logs: Vec::new(), + redacts, } } @@ -175,11 +194,24 @@ impl ProblemReport { /// Attach file log to this report. This method uses the error chain instead of log /// contents if error occurred when reading log file. pub fn add_log(&mut self, path: &Path) { - let content = read_file_lossy(path, LOG_MAX_READ_BYTES) - .chain_err(|| ErrorKind::ReadLogError(path.to_path_buf())) - .unwrap_or_else(|e| e.display_chain().to_string()); - self.logs - .push((path.to_string_lossy().into_owned(), content)); + let content = self.redact( + read_file_lossy(path, LOG_MAX_READ_BYTES) + .chain_err(|| ErrorKind::ReadLogError(path.to_path_buf())) + .unwrap_or_else(|e| e.display_chain().to_string()), + ); + let path = self.redact(path.to_string_lossy().into_owned()); + self.logs.push((path, content)); + } + + fn redact(&self, input: String) -> String { + let mut out = match env::home_dir() { + Some(home) => input.replace(home.to_string_lossy().as_ref(), "~"), + None => input, + }; + for redact in &self.redacts { + out = out.replace(redact, "[REDACTED]") + } + out } } diff --git a/mullvad-daemon/src/settings.rs b/mullvad-daemon/src/settings.rs index 10cf63123a..cb9c0daabb 100644 --- a/mullvad-daemon/src/settings.rs +++ b/mullvad-daemon/src/settings.rs @@ -111,11 +111,13 @@ impl Settings { account_token = None; } if account_token != self.account_token { - info!( - "Changing account token from {} to {}", - Self::format_account_token(&self.account_token), - Self::format_account_token(&account_token), - ); + if account_token.is_none() { + info!("Unsetting account token"); + } else if self.account_token.is_none() { + info!("Setting account token"); + } else { + info!("Changing account token") + } self.account_token = account_token; self.save().map(|_| true) } else { @@ -123,13 +125,6 @@ impl Settings { } } - fn format_account_token(account_token: &Option<String>) -> String { - match *account_token { - Some(ref account_token) => format!("\"{}\"", account_token), - None => "[none]".to_owned(), - } - } - pub fn get_relay_constraints(&self) -> RelayConstraints { self.relay_constraints.clone() } diff --git a/socket-relay/src/udp.rs b/socket-relay/src/udp.rs index 032b238442..c5b48ffb7c 100644 --- a/socket-relay/src/udp.rs +++ b/socket-relay/src/udp.rs @@ -97,21 +97,23 @@ impl Relay { }); let recv_stream = forward_stream - .filter_map(move |(addr, data)| if addr == destination { - trace!( - "Returning {} byte response from {} to {}", - data.len(), - addr, - client_addr - ); - Some((client_addr, data)) - } else { - trace!( - "Discarding data from {}, expecting data from {}", - addr, - destination - ); - None + .filter_map(move |(addr, data)| { + if addr == destination { + trace!( + "Returning {} byte response from {} to {}", + data.len(), + addr, + client_addr + ); + Some((client_addr, data)) + } else { + trace!( + "Discarding data from {}, expecting data from {}", + addr, + destination + ); + None + } }) .map_err(|e| { error!("Error reading datagrams from forward socket: {}", e) |
