diff --git a/Cargo.lock b/Cargo.lock index 6b06ae8..7a1c06b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5644,6 +5644,7 @@ dependencies = [ "rustls-pemfile", "rustls-pki-types", "tokio", + "tracing", "url", "wraith-core", ] diff --git a/crates/wraith-core/src/server/handler.rs b/crates/wraith-core/src/server/handler.rs index a6e158b..a8fae03 100644 --- a/crates/wraith-core/src/server/handler.rs +++ b/crates/wraith-core/src/server/handler.rs @@ -6,6 +6,7 @@ use async_trait::async_trait; use russh::keys::ssh_key::HashAlg; use russh::server::{Auth, Handler, Msg, Session}; use russh::Channel; +use russh::ChannelId; use crate::auth::ServerAuthConfig; use crate::server::control_channel::{ @@ -245,8 +246,13 @@ impl Handler for ServerHandler { async fn channel_open_session( &mut self, _channel: Channel, - _session: &mut Session, + session: &mut Session, ) -> Result { + tracing::warn!( + remote_addr = ?self.remote_addr, + "rejected session channel (shell/exec not supported)" + ); + let _ = session; Ok(false) } @@ -255,22 +261,208 @@ impl Handler for ServerHandler { _channel: Channel, _originator_address: &str, _originator_port: u32, - _session: &mut Session, + session: &mut Session, ) -> Result { + tracing::warn!( + remote_addr = ?self.remote_addr, + "rejected x11 channel" + ); + let _ = session; Ok(false) } async fn channel_open_forwarded_tcpip( &mut self, _channel: Channel, - _host_to_connect: &str, - _port_to_connect: u32, + host_to_connect: &str, + port_to_connect: u32, _originator_address: &str, _originator_port: u32, - _session: &mut Session, + session: &mut Session, ) -> Result { + tracing::warn!( + remote_addr = ?self.remote_addr, + target = %format!("{host_to_connect}:{port_to_connect}"), + "rejected forwarded-tcpip channel (remote port forwarding not supported)" + ); + let _ = session; Ok(false) } + + async fn exec_request( + &mut self, + channel: ChannelId, + data: &[u8], + session: &mut Session, + ) -> Result<(), Self::Error> { + tracing::warn!( + remote_addr = ?self.remote_addr, + channel = %channel, + data_len = data.len(), + "rejected exec request on channel (shell/exec not supported)" + ); + let _ = session.channel_failure(channel); + Ok(()) + } + + async fn shell_request( + &mut self, + channel: ChannelId, + session: &mut Session, + ) -> Result<(), Self::Error> { + tracing::warn!( + remote_addr = ?self.remote_addr, + channel = %channel, + "rejected shell request on channel" + ); + let _ = session.channel_failure(channel); + Ok(()) + } + + async fn subsystem_request( + &mut self, + channel: ChannelId, + name: &str, + session: &mut Session, + ) -> Result<(), Self::Error> { + tracing::warn!( + remote_addr = ?self.remote_addr, + channel = %channel, + subsystem = name, + "rejected subsystem request on channel" + ); + let _ = session.channel_failure(channel); + Ok(()) + } + + async fn pty_request( + &mut self, + channel: ChannelId, + term: &str, + col_width: u32, + row_height: u32, + pix_width: u32, + pix_height: u32, + modes: &[(russh::Pty, u32)], + session: &mut Session, + ) -> Result<(), Self::Error> { + tracing::warn!( + remote_addr = ?self.remote_addr, + channel = %channel, + term = term, + "rejected pty request on channel" + ); + let _ = (col_width, row_height, pix_width, pix_height, modes); + let _ = session.channel_failure(channel); + Ok(()) + } + + async fn env_request( + &mut self, + channel: ChannelId, + variable_name: &str, + variable_value: &str, + session: &mut Session, + ) -> Result<(), Self::Error> { + tracing::warn!( + remote_addr = ?self.remote_addr, + channel = %channel, + variable = variable_name, + "rejected env request on channel" + ); + let _ = variable_value; + let _ = session.channel_failure(channel); + Ok(()) + } + + async fn x11_request( + &mut self, + channel: ChannelId, + single_connection: bool, + x11_auth_protocol: &str, + x11_auth_cookie: &str, + x11_screen_number: u32, + session: &mut Session, + ) -> Result<(), Self::Error> { + tracing::warn!( + remote_addr = ?self.remote_addr, + channel = %channel, + "rejected x11 request on channel" + ); + let _ = (single_connection, x11_auth_protocol, x11_auth_cookie, x11_screen_number); + let _ = session.channel_failure(channel); + Ok(()) + } + + async fn agent_request( + &mut self, + channel: ChannelId, + session: &mut Session, + ) -> Result { + tracing::warn!( + remote_addr = ?self.remote_addr, + channel = %channel, + "rejected agent forwarding request on channel" + ); + let _ = session; + Ok(false) + } + + async fn tcpip_forward( + &mut self, + address: &str, + port: &mut u32, + session: &mut Session, + ) -> Result { + tracing::warn!( + remote_addr = ?self.remote_addr, + address = address, + port = *port, + "rejected tcpip-forward request (remote port forwarding not supported)" + ); + let _ = session; + Ok(false) + } + + async fn cancel_tcpip_forward( + &mut self, + address: &str, + port: u32, + session: &mut Session, + ) -> Result { + let _ = (address, port, session); + Ok(false) + } + + async fn streamlocal_forward( + &mut self, + socket_path: &str, + session: &mut Session, + ) -> Result { + tracing::warn!( + remote_addr = ?self.remote_addr, + socket_path = socket_path, + "rejected streamlocal-forward request" + ); + let _ = session; + Ok(false) + } + + async fn signal( + &mut self, + channel: ChannelId, + signal: russh::Sig, + session: &mut Session, + ) -> Result<(), Self::Error> { + tracing::debug!( + remote_addr = ?self.remote_addr, + channel = %channel, + signal = ?signal, + "received signal on channel (ignored)" + ); + let _ = session; + Ok(()) + } } #[cfg(test)] diff --git a/crates/wraith-core/src/server/serve.rs b/crates/wraith-core/src/server/serve.rs index 2ee4e93..d2d8144 100644 --- a/crates/wraith-core/src/server/serve.rs +++ b/crates/wraith-core/src/server/serve.rs @@ -255,6 +255,8 @@ impl Server { let config = Arc::new(Config { keys: vec![private_key], max_auth_attempts: opts.max_auth_attempts, + methods: russh::MethodSet::PUBLICKEY, + preferred: russh::Preferred::DEFAULT, ..Default::default() }); diff --git a/crates/wraith-napi/Cargo.toml b/crates/wraith-napi/Cargo.toml index f948059..7612c96 100644 --- a/crates/wraith-napi/Cargo.toml +++ b/crates/wraith-napi/Cargo.toml @@ -19,4 +19,5 @@ async-trait = "0.1" rustls-pemfile = "2" rustls-pki-types = "1" iroh = "0.34" -url = "2" \ No newline at end of file +url = "2" +tracing = "0.1" \ No newline at end of file diff --git a/crates/wraith-napi/src/serve.rs b/crates/wraith-napi/src/serve.rs index 2c944b3..1aa49b5 100644 --- a/crates/wraith-napi/src/serve.rs +++ b/crates/wraith-napi/src/serve.rs @@ -225,6 +225,7 @@ impl russh::server::Handler for NapiServerHandler { _channel: Channel, _session: &mut russh::server::Session, ) -> std::result::Result { + tracing::warn!("rejected session channel (shell/exec not supported)"); Ok(false) } @@ -235,20 +236,150 @@ impl russh::server::Handler for NapiServerHandler { _originator_port: u32, _session: &mut russh::server::Session, ) -> std::result::Result { + tracing::warn!("rejected x11 channel"); Ok(false) } async fn channel_open_forwarded_tcpip( &mut self, _channel: Channel, - _host_to_connect: &str, - _port_to_connect: u32, + host_to_connect: &str, + port_to_connect: u32, _originator_address: &str, _originator_port: u32, _session: &mut russh::server::Session, ) -> std::result::Result { + tracing::warn!( + target = %format!("{host_to_connect}:{port_to_connect}"), + "rejected forwarded-tcpip channel" + ); Ok(false) } + + async fn exec_request( + &mut self, + channel: russh::ChannelId, + data: &[u8], + session: &mut russh::server::Session, + ) -> std::result::Result<(), Self::Error> { + tracing::warn!(channel = %channel, data_len = data.len(), "rejected exec request"); + let _ = session.channel_failure(channel); + Ok(()) + } + + async fn shell_request( + &mut self, + channel: russh::ChannelId, + session: &mut russh::server::Session, + ) -> std::result::Result<(), Self::Error> { + tracing::warn!(channel = %channel, "rejected shell request"); + let _ = session.channel_failure(channel); + Ok(()) + } + + async fn subsystem_request( + &mut self, + channel: russh::ChannelId, + name: &str, + session: &mut russh::server::Session, + ) -> std::result::Result<(), Self::Error> { + tracing::warn!(channel = %channel, subsystem = name, "rejected subsystem request"); + let _ = session.channel_failure(channel); + Ok(()) + } + + async fn pty_request( + &mut self, + channel: russh::ChannelId, + term: &str, + col_width: u32, + row_height: u32, + pix_width: u32, + pix_height: u32, + modes: &[(russh::Pty, u32)], + session: &mut russh::server::Session, + ) -> std::result::Result<(), Self::Error> { + tracing::warn!(channel = %channel, term = term, "rejected pty request"); + let _ = (col_width, row_height, pix_width, pix_height, modes); + let _ = session.channel_failure(channel); + Ok(()) + } + + async fn env_request( + &mut self, + channel: russh::ChannelId, + variable_name: &str, + variable_value: &str, + session: &mut russh::server::Session, + ) -> std::result::Result<(), Self::Error> { + tracing::warn!(channel = %channel, variable = variable_name, "rejected env request"); + let _ = variable_value; + let _ = session.channel_failure(channel); + Ok(()) + } + + async fn x11_request( + &mut self, + channel: russh::ChannelId, + single_connection: bool, + x11_auth_protocol: &str, + x11_auth_cookie: &str, + x11_screen_number: u32, + session: &mut russh::server::Session, + ) -> std::result::Result<(), Self::Error> { + tracing::warn!(channel = %channel, "rejected x11 request"); + let _ = (single_connection, x11_auth_protocol, x11_auth_cookie, x11_screen_number); + let _ = session.channel_failure(channel); + Ok(()) + } + + async fn agent_request( + &mut self, + channel: russh::ChannelId, + _session: &mut russh::server::Session, + ) -> std::result::Result { + tracing::warn!(channel = %channel, "rejected agent forwarding request"); + Ok(false) + } + + async fn tcpip_forward( + &mut self, + address: &str, + port: &mut u32, + _session: &mut russh::server::Session, + ) -> std::result::Result { + tracing::warn!(address = address, port = *port, "rejected tcpip-forward request"); + Ok(false) + } + + async fn cancel_tcpip_forward( + &mut self, + address: &str, + port: u32, + _session: &mut russh::server::Session, + ) -> std::result::Result { + let _ = (address, port); + Ok(false) + } + + async fn streamlocal_forward( + &mut self, + socket_path: &str, + _session: &mut russh::server::Session, + ) -> std::result::Result { + tracing::warn!(socket_path = socket_path, "rejected streamlocal-forward request"); + Ok(false) + } + + async fn signal( + &mut self, + channel: russh::ChannelId, + signal: russh::Sig, + _session: &mut russh::server::Session, + ) -> std::result::Result<(), Self::Error> { + tracing::debug!(channel = %channel, signal = ?signal, "received signal (ignored)"); + Ok(()) + } } type ServerTsfn = ThreadsafeFunction; @@ -418,6 +549,8 @@ pub async fn serve(options: WraithServeOptions) -> napi::Result { let config = Arc::new(server::Config { keys: vec![private_key], + methods: russh::MethodSet::PUBLICKEY, + preferred: russh::Preferred::DEFAULT, ..Default::default() }); @@ -527,6 +660,8 @@ pub async fn serve(options: WraithServeOptions) -> napi::Result { let config = Arc::new(server::Config { keys: vec![private_key], + methods: russh::MethodSet::PUBLICKEY, + preferred: russh::Preferred::DEFAULT, ..Default::default() }); @@ -607,6 +742,8 @@ pub async fn serve(options: WraithServeOptions) -> napi::Result { let config = Arc::new(server::Config { keys: vec![private_key], + methods: russh::MethodSet::PUBLICKEY, + preferred: russh::Preferred::DEFAULT, ..Default::default() });