|
1 | 1 | use std::{ops::DerefMut, sync::Arc, task::ready};
|
2 | 2 |
|
3 | 3 | use russh::{
|
4 |
| - client::Handle, |
5 |
| - client::{Config, Handler}, |
| 4 | + client::{Config, Handle, Handler}, |
| 5 | + MethodSet, |
6 | 6 | };
|
7 | 7 |
|
8 | 8 | pub enum AuthMode {
|
9 | 9 | UsernamePassword { username: String, password: String },
|
| 10 | + PublicKey { username: String }, |
10 | 11 | }
|
11 | 12 |
|
12 | 13 | #[derive(Clone)]
|
@@ -36,11 +37,40 @@ impl Client {
|
36 | 37 | } => Err(super::Error::AuthenticationFailed(remaining_methods)),
|
37 | 38 | }
|
38 | 39 | }
|
| 40 | + AuthMode::PublicKey { username } => { |
| 41 | + let mut agent = russh::keys::agent::client::AgentClient::connect_env().await?; |
| 42 | + let rsa_hash = handle.best_supported_rsa_hash().await?.flatten(); |
| 43 | + let mut methods = MethodSet::empty(); |
| 44 | + for key in agent.request_identities().await? { |
| 45 | + match handle |
| 46 | + .authenticate_publickey_with(&username, key, rsa_hash, &mut agent) |
| 47 | + .await? |
| 48 | + { |
| 49 | + russh::client::AuthResult::Success => return Ok(()), |
| 50 | + russh::client::AuthResult::Failure { |
| 51 | + remaining_methods, |
| 52 | + partial_success: _, |
| 53 | + } => methods = remaining_methods, |
| 54 | + } |
| 55 | + } |
| 56 | + Err(super::Error::AuthenticationFailed(methods)) |
| 57 | + } |
39 | 58 | }
|
40 | 59 | }
|
41 | 60 |
|
42 |
| - pub async fn open_session(&mut self) -> Result<Session, super::Error> { |
| 61 | + pub async fn open_session( |
| 62 | + &mut self, |
| 63 | + cmd: impl Into<String>, |
| 64 | + env: Vec<(String, String)>, |
| 65 | + ) -> Result<Session, super::Error> { |
43 | 66 | let channel = self.handle.channel_open_session().await?;
|
| 67 | + |
| 68 | + for (key, value) in env { |
| 69 | + channel.set_env(false, key, value).await?; |
| 70 | + } |
| 71 | + |
| 72 | + channel.exec(false, cmd.into().bytes().collect::<Vec<_>>()).await?; |
| 73 | + |
44 | 74 | let stream = channel.into_stream();
|
45 | 75 | Ok(Session {
|
46 | 76 | stream: Arc::new(std::sync::Mutex::new(stream)),
|
|
0 commit comments