Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions russh/examples/echoserver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ impl server::Server for Server {

impl server::Handler for Server {
type Error = russh::Error;
type Data = ();

async fn channel_open_session(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions russh/examples/ratatui_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ impl Server for AppServer {

impl Handler for AppServer {
type Error = anyhow::Error;
type Data = ();

async fn channel_open_session(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions russh/examples/ratatui_shared_app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ impl Server for AppServer {

impl Handler for AppServer {
type Error = anyhow::Error;
type Data = ();

async fn channel_open_session(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions russh/examples/sftp_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl SshSession {

impl russh::server::Handler for SshSession {
type Error = anyhow::Error;
type Data = ();

async fn auth_password(&mut self, user: &str, password: &str) -> Result<Auth, Self::Error> {
info!("credentials: {user}, {password}");
Expand Down
1 change: 1 addition & 0 deletions russh/examples/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ impl server::Server for Server {

impl server::Handler for Server {
type Error = anyhow::Error;
type Data = ();

async fn channel_open_session(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions russh/src/client/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ mod tests {

impl ServerHandler for TestServer {
type Error = Error;
type Data = ();

async fn channel_open_session(
&mut self,
Expand Down
53 changes: 53 additions & 0 deletions russh/src/server/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ impl Auth {
#[cfg_attr(feature = "async-trait", async_trait::async_trait)]
pub trait Handler: Sized {
type Error: From<crate::Error> + Send;
type Data: Send;

/// Check authentication using the "none" method. Russh makes
/// sure rejection happens in time `config.auth_rejection_time`,
Expand Down Expand Up @@ -792,6 +793,58 @@ pub trait Handler: Sized {
Ok(Some(best_group.clone()))
}
}

/// Called when the handler needs to be updated.
/// ['trigger'] should be used with ['process']
///
/// # Cancel safety
///
/// The safety of this method depends entirely on how you implement it;
/// it provides no inherent security guarantees.
///
/// # Example
///
/// ```
/// use tokio::sync::mpsc::Receiver;
/// use russh::server::{Handler, Session};
///
/// struct App{
/// foo: String,
/// recv: Receiver<String>,
/// trigger: Receiver<String>,
/// }
///
/// impl Handler for App {
/// type Error = russh::Error;
/// type Data = String;
/// async fn trigger(&mut self) -> Result<Self::Data, Self::Error> {
/// match self.trigger.recv().await {
/// Some(d) => Ok(d),
/// None => std::future::pending().await,
/// }
/// }
///
/// async fn process(&mut self, s: Self::Data, session: &mut Session) -> Result<(), Self::Error> {
/// let s = self.recv.recv().await.unwrap();
/// self.foo = s;
/// Ok(())
/// }
/// }
/// ```
///
fn trigger(&mut self) -> impl Future<Output = Result<Self::Data, Self::Error>> + Send {
std::future::pending()
}

/// Called after [`trigger`], See [`trigger`] for more.
#[allow(unused_variables)]
fn process(
&mut self,
data: Self::Data,
session: &mut Session,
) -> impl Future<Output = Result<(), Self::Error>> + Send {
async { Ok(()) }
}
}

pub struct RunningServerHandle {
Expand Down
7 changes: 7 additions & 0 deletions russh/src/server/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -542,6 +542,13 @@ impl Session {
}
reading.set(start_reading(stream_read, buffer, opening_cipher));
}
t = handler.trigger() => {
debug!("handler trigger is invoked");
match t {
Ok(d) => handler.process(d,&mut self).await?,
Err(e) => return Err(e)
}
}
() = &mut keepalive_timer => {
self.common.alive_timeouts = self.common.alive_timeouts.saturating_add(1);
if self.common.config.keepalive_max != 0 && self.common.alive_timeouts > self.common.config.keepalive_max {
Expand Down
6 changes: 6 additions & 0 deletions russh/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ mod compress {

impl server::Handler for Server {
type Error = super::Error;
type Data = ();

async fn channel_open_session(
&mut self,
Expand Down Expand Up @@ -256,6 +257,7 @@ mod channels {

impl server::Handler for ServerHandle {
type Error = crate::Error;
type Data = ();

async fn auth_publickey(
&mut self,
Expand Down Expand Up @@ -327,6 +329,7 @@ mod channels {

impl server::Handler for ServerHandle {
type Error = crate::Error;
type Data = ();

async fn auth_publickey(
&mut self,
Expand Down Expand Up @@ -411,6 +414,7 @@ mod channels {

impl server::Handler for ServerHandle {
type Error = crate::Error;
type Data = ();

async fn auth_publickey(
&mut self,
Expand Down Expand Up @@ -496,6 +500,7 @@ mod channels {

impl server::Handler for ServerHandle {
type Error = crate::Error;
type Data = ();

async fn auth_publickey(
&mut self,
Expand Down Expand Up @@ -615,5 +620,6 @@ mod server_kex_junk {

impl server::Handler for Server {
type Error = super::Error;
type Data = ();
}
}
1 change: 1 addition & 0 deletions russh/tests/test_backpressure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ impl russh::server::Server for Server {

impl russh::server::Handler for Server {
type Error = anyhow::Error;
type Data = ();

async fn auth_publickey(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions russh/tests/test_data_stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ impl russh::server::Server for Server {

impl russh::server::Handler for Server {
type Error = anyhow::Error;
type Data = ();

async fn auth_publickey(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions russh/tests/test_kex_shared_secret.rs
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,7 @@ struct TestServer {}

impl server::Handler for TestServer {
type Error = russh::Error;
type Data = ();

async fn auth_publickey(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions russh/tests/test_mlkem_kex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,7 @@ struct TestServer {}

impl server::Handler for TestServer {
type Error = russh::Error;
type Data = ();

async fn auth_publickey(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions russh/tests/test_rekey_strict_kex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ struct TestServer {}
// Insecure server that accepts any public key and echos back data it receives; ONLY FOR TESTS
impl server::Handler for TestServer {
type Error = russh::Error;
type Data = ();

async fn auth_publickey(
&mut self,
Expand Down
Loading