diff --git a/config.toml b/config.toml index c0ba75a..0e84112 100644 --- a/config.toml +++ b/config.toml @@ -30,6 +30,17 @@ ask_cmd = "contrib/ask-bemenu.sh" # will not be filtered whatever this command does. notify_cmd = "contrib/notify-libnotify.sh" +[logging] +# If true, log all known requests (client -> server) at the DEBUG level +# log_all_requests = false + +# If true, log all known events (server -> client) at the DEBUG level +# log_all_events = false + +# Set the maximum log level output to stdout +# Overrides the RUST_LOG environmet variable if set +# log_level = "info" + [filter] # A list of Wayland global singleton objects that's allowed # Each of them generally correspond to an implemented protocol diff --git a/src/config.rs b/src/config.rs index eb684c9..68d4c36 100644 --- a/src/config.rs +++ b/src/config.rs @@ -9,7 +9,10 @@ use serde_derive::Deserialize; #[derive(Deserialize)] pub struct Config { pub socket: WlSockets, + #[serde(default)] pub exec: WlExec, + #[serde(default)] + pub logging: WlLogging, pub filter: WlFilter, } @@ -52,7 +55,16 @@ impl WlSockets { } } -#[derive(Deserialize)] +#[derive(Default, Deserialize)] +pub struct WlLogging { + #[serde(default)] + pub log_all_requests: bool, + #[serde(default)] + pub log_all_events: bool, + pub log_level: Option, +} + +#[derive(Default, Deserialize)] pub struct WlExec { pub ask_cmd: Option, pub notify_cmd: Option, diff --git a/src/main.rs b/src/main.rs index 300e6fe..36e0bea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ mod proto; mod config; mod state; -use std::{io, ops::ControlFlow, path::Path, sync::Arc}; +use std::{io, ops::ControlFlow, path::Path, str::FromStr, sync::Arc}; use codec::DecoderOutcome; use config::Config; @@ -14,12 +14,10 @@ use io_util::{WlMsgReader, WlMsgWriter}; use proto::{WL_DISPLAY_OBJECT_ID, WlConstructableMessage, WlDisplayErrorEvent}; use state::{WlMitmOutcome, WlMitmState, WlMitmVerdict}; use tokio::net::{UnixListener, UnixStream}; -use tracing::{Instrument, Level, debug, error, info, span, warn}; +use tracing::{Instrument, Level, error, info, level_filters::LevelFilter, span, warn}; #[tokio::main] async fn main() { - tracing_subscriber::fmt::init(); - let mut conf_file = "config.toml"; let args: Vec<_> = std::env::args().collect(); @@ -33,6 +31,15 @@ async fn main() { let config: Arc = Arc::new(toml::from_str(&conf_str).expect("Can't decode config file")); + let mut tracing_builder = tracing_subscriber::fmt(); + + if let Some(ref level) = config.logging.log_level { + tracing_builder = tracing_builder + .with_max_level(LevelFilter::from_str(level).expect("Invalid log level")); + } + + tracing_builder.init(); + let src = config.socket.upstream_socket_path(); let proxied = config.socket.listen_socket_path(); @@ -119,13 +126,6 @@ impl<'a> ConnDuplex<'a> { ) -> io::Result> { match decoded_raw { codec::DecoderOutcome::Decoded(mut wl_raw_msg) => { - debug!( - obj_id = wl_raw_msg.obj_id, - opcode = wl_raw_msg.opcode, - num_fds = wl_raw_msg.fds.len(), - "s2c event" - ); - let WlMitmOutcome(num_consumed_fds, mut verdict) = self.state.on_s2c_event(&wl_raw_msg).await; self.upstream_read @@ -165,13 +165,6 @@ impl<'a> ConnDuplex<'a> { ) -> io::Result> { match decoded_raw { codec::DecoderOutcome::Decoded(mut wl_raw_msg) => { - debug!( - obj_id = wl_raw_msg.obj_id, - opcode = wl_raw_msg.opcode, - num_fds = wl_raw_msg.fds.len(), - "c2s request" - ); - let WlMitmOutcome(num_consumed_fds, mut verdict) = self.state.on_c2s_request(&wl_raw_msg).await; self.downstream_read diff --git a/src/state.rs b/src/state.rs index f00a7ce..60716e7 100644 --- a/src/state.rs +++ b/src/state.rs @@ -243,6 +243,17 @@ impl WlMitmState { outcome.set_consumed_fds(msg.num_consumed_fds()); + if self.config.logging.log_all_requests { + debug!( + raw_payload_bytes = ?raw_msg.payload(), + num_fds = raw_msg.fds.len(), + num_consumed_fds = msg.num_consumed_fds(), + "{}::{}", + msg.self_object_type().interface(), + msg.self_msg_name(), + ) + } + // To get here, the object referred to in raw_msg must exist, but it might already be destroyed by the client // In that case, the client is broken! if self.objects.is_half_destroyed(msg.obj_id()) { @@ -439,6 +450,17 @@ impl WlMitmState { outcome.set_consumed_fds(msg.num_consumed_fds()); + if self.config.logging.log_all_events { + debug!( + raw_payload_bytes = ?raw_msg.payload(), + num_fds = raw_msg.fds.len(), + num_consumed_fds = msg.num_consumed_fds(), + "{}::{}", + msg.self_object_type().interface(), + msg.self_msg_name(), + ) + } + if !self.handle_created_or_destroyed_objects(&*msg, false) { return outcome.terminate(); }