ssh_transfer/
authentication.rs

1use crate::error::{Error::AuthenticationError, Result};
2use ssh2::Session;
3use std::path::PathBuf;
4
5#[derive(Clone, Debug, Eq, PartialEq)]
6pub enum AuthenticationType {
7  Interactive,
8  Agent,
9  KeyFile(PathBuf),
10  KeyMemory(String),
11  Password(String),
12}
13
14impl AuthenticationType {
15  pub(crate) fn authenticate(&self, session: &Session, username: &str) -> Result<()> {
16    if session.authenticated() {
17      return Ok(());
18    }
19
20    match &self {
21      AuthenticationType::Interactive => {
22        unimplemented!()
23      }
24      AuthenticationType::Agent => {
25        session.userauth_agent(username)?;
26      }
27      AuthenticationType::KeyFile(private_key_file_path) => {
28        session.userauth_pubkey_file(username, None, private_key_file_path, None)?;
29      }
30      AuthenticationType::KeyMemory(private_key) => {
31        session.userauth_pubkey_memory(username, None, private_key, None)?;
32      }
33      AuthenticationType::Password(password) => {
34        if session
35          .auth_methods(username)?
36          .split(',')
37          .map(String::from)
38          .any(|method| method == *"password")
39        {
40          session.userauth_password(username, password)?;
41        }
42      }
43    }
44
45    if !session.authenticated() {
46      return Err(AuthenticationError(format!(
47        "Could not authenticate user: {}.",
48        username
49      )));
50    }
51
52    Ok(())
53  }
54}