summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorLinus Färnstrand <linus@mullvad.net>2017-11-08 14:30:16 +0100
committerLinus Färnstrand <linus@mullvad.net>2017-11-08 14:30:16 +0100
commit2833754f1c863bf30dea4b1769078ffd9dce254a (patch)
tree3b1e63c82e81f7cbb61b2fe055124f4cd60823ca
parent3899bc25ace5ae802e0890d5b045b21675f93066 (diff)
parentaaeee003fcb5c27c24ecc87b2a5273e9f5d600b4 (diff)
downloadmullvadvpn-2833754f1c863bf30dea4b1769078ffd9dce254a.tar.xz
mullvadvpn-2833754f1c863bf30dea4b1769078ffd9dce254a.zip
Merge branch 'censor-problem-report-logs'
-rw-r--r--CHANGELOG.md1
-rwxr-xr-xformat.sh2
-rw-r--r--mullvad-cli/src/cmds/account.rs10
-rw-r--r--mullvad-daemon/src/bin/problem-report.rs52
-rw-r--r--mullvad-daemon/src/settings.rs19
-rw-r--r--socket-relay/src/udp.rs32
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
diff --git a/format.sh b/format.sh
index 79ffc82f2e..1603a29b3f 100755
--- a/format.sh
+++ b/format.sh
@@ -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)