async_ssh2_lite/
agent.rs

1use std::sync::Arc;
2
3#[cfg(unix)]
4use std::os::unix::io::AsRawFd;
5#[cfg(windows)]
6use std::os::windows::io::{AsRawSocket, BorrowedSocket};
7
8use ssh2::{Agent, PublicKey, Session};
9
10use crate::{error::Error, session::get_session, session_stream::AsyncSessionStream};
11
12//
13pub struct AsyncAgent<S> {
14    inner: Agent,
15    sess: Session,
16    stream: Arc<S>,
17}
18
19#[cfg(unix)]
20impl<S> AsyncAgent<S>
21where
22    S: AsRawFd + 'static,
23{
24    pub fn new(stream: S) -> Result<Self, Error> {
25        let mut session = get_session(None)?;
26        session.set_tcp_stream(stream.as_raw_fd());
27
28        let stream = Arc::new(stream);
29
30        let agent = session.agent()?;
31
32        Ok(Self {
33            inner: agent,
34            sess: session,
35            stream,
36        })
37    }
38}
39
40#[cfg(windows)]
41impl<S> AsyncAgent<S>
42where
43    S: AsRawSocket + 'static,
44{
45    pub fn new(stream: S) -> Result<Self, Error> {
46        let mut session = get_session(None)?;
47        session.set_tcp_stream(unsafe { BorrowedSocket::borrow_raw(stream.as_raw_socket()) });
48
49        let stream = Arc::new(stream);
50
51        let agent = session.agent()?;
52
53        Ok(Self {
54            inner: agent,
55            sess: session,
56            stream,
57        })
58    }
59}
60
61impl<S> AsyncAgent<S> {
62    pub(crate) fn from_parts(inner: Agent, sess: Session, stream: Arc<S>) -> Self {
63        Self {
64            inner,
65            sess,
66            stream,
67        }
68    }
69}
70
71impl<S> AsyncAgent<S> {
72    pub fn identities(&self) -> Result<Vec<PublicKey>, Error> {
73        self.inner.identities().map_err(Into::into)
74    }
75}
76
77impl<S> AsyncAgent<S>
78where
79    S: AsyncSessionStream + Send + Sync + 'static,
80{
81    pub async fn connect(&mut self) -> Result<(), Error> {
82        self.stream
83            .none_with(|| self.inner.connect(), &self.sess)
84            .await
85    }
86
87    pub async fn disconnect(&mut self) -> Result<(), Error> {
88        self.stream
89            .none_with(|| self.inner.disconnect(), &self.sess)
90            .await
91    }
92
93    pub async fn list_identities(&mut self) -> Result<(), Error> {
94        self.stream
95            .rw_with(|| self.inner.list_identities(), &self.sess)
96            .await
97    }
98
99    pub async fn userauth(&self, username: &str, identity: &PublicKey) -> Result<(), Error> {
100        self.stream
101            .rw_with(|| self.inner.userauth(username, identity), &self.sess)
102            .await
103    }
104}