ssh_transfer/
connection.rs

1use crate::configuration::Configuration;
2use crate::error::Result;
3use crate::known_host::KnownHost;
4use crate::known_hosts::KnownHosts;
5use crate::sftp::{SftpEntry, SftpReader, SftpWriter, list};
6use ssh2::{HostKeyType, Session};
7use std::net::TcpStream;
8
9pub struct Connection {
10  pub config: Configuration,
11  pub session: Session,
12  pub known_hosts: KnownHosts,
13}
14
15unsafe impl Send for Connection {}
16
17impl Connection {
18  pub fn new(config: &Configuration) -> Result<Self> {
19    let session = Self::open_session(config)?;
20    let known_hosts = KnownHosts::new(&session)?;
21    Ok(Connection {
22      config: config.clone(),
23      session,
24      known_hosts,
25    })
26  }
27
28  fn open_session(config: &Configuration) -> Result<Session> {
29    let tcp_stream = TcpStream::connect((config.hostname.as_str(), config.port))?;
30
31    let mut session = Session::new()?;
32    session.set_timeout(config.timeout);
33    session.set_compress(config.compress);
34
35    session.set_tcp_stream(tcp_stream);
36    session.handshake()?;
37
38    Ok(session)
39  }
40
41  pub fn add_known_host(&mut self, known_host: &KnownHost) -> Result<()> {
42    self.known_hosts.add_known_host(known_host)
43  }
44
45  pub fn get_remote_host_key(&self) -> Option<(String, HostKeyType)> {
46    self
47      .session
48      .host_key()
49      .map(|(key, key_type)| (base64::encode(key), key_type))
50  }
51
52  pub fn start(&mut self) -> Result<()> {
53    self.known_hosts.check_remote(
54      &self.session,
55      &self.config.hostname,
56      self.config.port,
57      self.config.trust_host,
58    )?;
59    self.authenticate()
60  }
61
62  fn authenticate(&self) -> Result<()> {
63    self
64      .config
65      .authentication
66      .authenticate(&self.session, &self.config.username)
67  }
68
69  pub fn read_over_sftp(&self, path: &str) -> Result<SftpReader> {
70    SftpReader::new(&self.session, path)
71  }
72
73  pub fn write_over_sftp(&self, path: &str) -> Result<SftpWriter> {
74    SftpWriter::new(&self.session, path)
75  }
76
77  pub fn list_over_sftp(&self, path: &str) -> Result<Vec<SftpEntry>> {
78    list(&self.session, path)
79  }
80}