harmony/harmony/src/infra/executors/russh/mod.rs
Jean-Gabriel Gill-Couture f9906cb419
All checks were successful
Run Check Script / check (pull_request) Successful in 1m15s
refact: Move basic types to harmony_types crate to avoid external dependencies.
This includes Id, IpAddress, Url and some other heavily used types
2025-08-30 18:01:14 -04:00

57 lines
1.5 KiB
Rust

use async_trait::async_trait;
use std::sync::Arc;
use russh::{client, keys::key};
use crate::domain::executors::{ExecutorError, SshClient};
use harmony_types::net::IpAddress;
pub struct RusshClient;
#[async_trait]
impl SshClient for RusshClient {
async fn test_connection(
&self,
address: IpAddress,
_username: &str,
_password: &str,
) -> Result<(), crate::domain::executors::ExecutorError> {
let config = client::Config::default();
let c = Client {};
let mut client = client::connect(Arc::new(config), (address, 22), c).await?;
match client
.authenticate_password("nationtech", "opnsense")
.await?
{
true => Ok(()),
false => Err(ExecutorError::AuthenticationError(
"ssh authentication failed".to_string(),
)),
}
}
}
struct Client {}
// More SSH event handlers
// can be defined in this trait
// In this example, we're only using Channel, so these aren't needed.
#[async_trait]
impl client::Handler for Client {
type Error = ExecutorError;
async fn check_server_key(
&mut self,
_server_public_key: &key::PublicKey,
) -> Result<bool, Self::Error> {
Ok(true)
}
}
impl From<russh::Error> for ExecutorError {
fn from(_value: russh::Error) -> Self {
// TODO handle various russh errors properly
ExecutorError::NetworkError("Russh client error".to_string())
}
}