Russh: Unknown server key

Hello! :slightly_smiling_face: I have some problem that I want you to help me to fix.

Here's the part of my code:

use russh::client;
use std::sync::Arc;

...

struct SshClient {}
impl client::Handler for SshClient {
    type Error = russh::Error;
}

...

impl App {
	...
	
	let runtime = tokio::runtime::Runtime::new().map_err(|e| format!("Failed to create async runtime: {e}"))?;
	
	runtime.block_on(async { 
        start_ssh_tunnel(password).await
    }).map_err(|e| format!("Failed to create SSH tunnel: {e}"))?;
    
    ...
}

...

async fn start_ssh_tunnel(password: String) -> Result<(), Box<dyn std::error::Error>> {
    let ssh_client = SshClient {};
    let mut session = russh::client::connect(
        Arc::new(client::Config::default()),
        format!("{}:{}", "example.com", 22),
        ssh_client
    ).await?;
    session.authenticate_password("someuser", password).await?;
	
    Ok(())
}

So, when I tries to launch the app, I gets the error:

Failed to create SSH tunnel: Unknown server key

And... Yeap! Some parts of the code was be written by AI, honestly :sweat_smile:. But it's a long story :slightly_smiling_face: (Maybe I will tell about this on my website... For my regular readers :thinking:). Here's only the start of the app was be written by it. But... start_ssh_tunnel function and the client "Handler" (that tiny-tiny-tiny thing) was be written by me :thinking:. But it doesn't matter :slightly_smiling_face:

So, how can I solve Unknown server key issue? :slightly_smiling_face:

Thanks... in... Advance! :grin:

And... Yeap...

All that you can see in that "Handler" is everything that exists there :thinking:

Maybe I will need to "extend" this? Or it doesn't matter? :slightly_smiling_face:

Your client::Handler handler misses a check_server_key impl. The default rejects all keys.

Thanks for you help me :handshake:

Can you fast write me an example about how do I should to include it? :slightly_smiling_face:

For in the future I will understand how to do these things :grin:

But then I will try to "extend" this by my own :slightly_smiling_face:

And...

It's for a public key option? :thinking:

But I use a password for authentication :worried:

Or explain me how to do that? :thinking:

If you don't need/want to check the server's public key, then implement the method returning Ok(true):

impl client::Handler for Client {
    type Error = russh::Error;

    async fn check_server_key(
        &mut self,
        _server_public_key: &ssh_key::PublicKey,
    ) -> Result<bool, Self::Error> {
        Ok(true)
    }
}

Thanks to you so much! :grin:

Will try it now :slightly_smiling_face:

Thanks to you! :grinning_face_with_smiling_eyes:

It works! :grin::+1:

btw! I don't know why, but the rust-analizer in VSCodium suggest me this:

impl client::Handler for Client {
    type Error = russh::Error;

    fn check_server_key(
        &mut self,
        server_public_key: &ssh_key::PublicKey,
    ) -> impl Future<Output = Result<bool, Self::Error>> + Send {
        
    }
}

So, I've try just to modify that to this:

impl client::Handler for Client {
    type Error = russh::Error;

    fn check_server_key(
        &mut self,
        server_public_key: &ssh_key::PublicKey,
    ) -> impl Future<Output = Result<bool, Self::Error>> + Send {
        async {
			Ok(true)
		}
    }
}

For saving my time, and it also works! :slightly_smiling_face:

So, thanks to you again! :grin: