rust-integration-services 0.5.15

A modern, fast, and lightweight integration library written in Rust, designed for memory safety and stability.
Documentation
use std::sync::Arc;

use russh::keys::{HashAlg, PrivateKeyWithHashAlg};
use russh_sftp::client::SftpSession;

use crate::sftp::{sftp_authentication::SftpAuthentication, ssh_client::SshClient};

pub async fn connect_and_authenticate(host: &String, auth: &SftpAuthentication) -> anyhow::Result<SftpSession> {
    let config = russh::client::Config::default();
    let ssh = SshClient {};

    tracing::debug!("connecting to {}", host);
    let mut session = russh::client::connect(Arc::new(config), host, ssh).await?;
    
    if let Some(auth) = &auth.basic {
        session.authenticate_password(&auth.user, &auth.password).await?;
    }

    if let Some(auth) = &auth.key {
        let key = russh::keys::load_secret_key(&auth.key_path, auth.passphrase.as_deref())?;
        let hash_alg = match &key.algorithm() {
            russh::keys::Algorithm::Rsa { .. } => Some(HashAlg::Sha256),
            _ => None,
        };

        let key_with_alg = PrivateKeyWithHashAlg::new(Arc::new(key), hash_alg);
        session.authenticate_publickey(&auth.user, key_with_alg).await?;
        tracing::debug!("authenticated using key");
    }

    let channel = session.channel_open_session().await?;
    channel.request_subsystem(true, "sftp").await?;
    let sftp = SftpSession::new(channel.into_stream()).await?;

    tracing::debug!("connected to {}", host);
    Ok(sftp)
}