Crate thrussh[−][src]
Server and client SSH library, based on ring for its crypto, and tokio/futures for its network management. More information at pijul.org/thrussh.
Here is an example client and server:
extern crate thrussh; extern crate thrussh_keys; extern crate futures; extern crate tokio; extern crate env_logger; use std::sync::Arc; use thrussh::*; use thrussh::server::{Auth, Session}; use thrussh_keys::*; #[derive(Clone)] struct Server { client_pubkey: Arc<thrussh_keys::key::PublicKey> } impl server::Server for Server { type Handler = Self; fn new(&self) -> Self { self.clone() } } impl server::Handler for Server { type Error = std::io::Error; type FutureAuth = futures::Finished<(Self, server::Auth), Self::Error>; type FutureUnit = futures::Finished<(Self, server::Session), Self::Error>; type FutureBool = futures::Finished<(Self, server::Session, bool), Self::Error>; fn finished_auth(self, auth: Auth) -> Self::FutureAuth { futures::finished((self, auth)) } fn finished_bool(self, session: Session, b: bool) -> Self::FutureBool { futures::finished((self, session, b)) } fn finished(self, session: Session) -> Self::FutureUnit { futures::finished((self, session)) } fn auth_publickey(self, _: &str, _: &key::PublicKey) -> Self::FutureAuth { futures::finished((self, server::Auth::Accept)) } fn data(self, channel: ChannelId, data: &[u8], mut session: server::Session) -> Self::FutureUnit { println!("data on channel {:?}: {:?}", channel, std::str::from_utf8(data)); session.data(channel, None, data); futures::finished((self, session)) } } use futures::Future; use std::io::Read; struct Client { key: Arc<thrussh_keys::key::KeyPair> } impl client::Handler for Client { type Error = (); type FutureBool = futures::Finished<(Self, bool), Self::Error>; type FutureUnit = futures::Finished<Self, Self::Error>; type FutureSign = futures::Finished<(Self, thrussh::CryptoVec), Self::Error>; type SessionUnit = futures::Finished<(Self, client::Session), Self::Error>; fn check_server_key(self, server_public_key: &key::PublicKey) -> Self::FutureBool { println!("check_server_key: {:?}", server_public_key); futures::finished((self, true)) } fn channel_open_confirmation(self, channel: ChannelId, session: client::Session) -> Self::SessionUnit { println!("channel_open_confirmation: {:?}", channel); futures::finished((self, session)) } fn data(self, channel: ChannelId, ext: Option<u32>, data: &[u8], session: client::Session) -> Self::SessionUnit { println!("data on channel {:?} {:?}: {:?}", ext, channel, std::str::from_utf8(data)); futures::finished((self, session)) } } impl Client { fn run(self, config: Arc<client::Config>, _: &str) { let key = self.key.clone(); tokio::run( client::connect_future( "127.0.0.1:2222", config, None, self, |connection| { connection.authenticate_key("pe", key) .and_then(|session| { session.channel_open_session().and_then(|(session, channelid)| { session.data(channelid, None, "Hello, world!").and_then(|(mut session, _)| { session.disconnect(Disconnect::ByApplication, "Ciao", ""); session }) }) }) }).unwrap().map_err(|_| ()) ) } } fn main() { env_logger::init(); // Starting the server thread. let client_key = thrussh_keys::key::KeyPair::generate(thrussh_keys::key::ED25519).unwrap(); let client_pubkey = Arc::new(client_key.clone_public_key()); let t = std::thread::spawn(|| { let mut config = thrussh::server::Config::default(); config.connection_timeout = Some(std::time::Duration::from_secs(600)); config.auth_rejection_time = std::time::Duration::from_secs(3); config.keys.push(thrussh_keys::key::KeyPair::generate(thrussh_keys::key::ED25519).unwrap()); let config = Arc::new(config); let sh = Server{ client_pubkey }; thrussh::server::run(config, "0.0.0.0:2222", sh); }); std::thread::sleep(std::time::Duration::from_secs(1)); let mut config = thrussh::client::Config::default(); config.connection_timeout = Some(std::time::Duration::from_secs(600)); let config = Arc::new(config); let sh = Client { key: Arc::new(client_key) }; sh.run(config, "127.0.0.1:2222"); // Kill the server thread after the client has ended. std::mem::forget(t) }
Modules
client |
Client side of this library. |
server |
Server side of this library. |
Structs
ChannelId |
The identifier of a channel. |
CryptoVec |
A buffer which zeroes its memory on |
Limits |
The number of bytes read/written, and the number of seconds before a key re-exchange is requested. |
MethodSet |
Set of methods, represented by bit flags. |
Preferred |
Lists of preferred algorithms. This is normally hard-coded into implementations. |
Enums
ChannelOpenFailure |
Reason for not being able to open a channel. |
Disconnect |
A reason for disconnection. |
Error |
Errors. |
HandlerError |
Errors including those coming from handler. These are not included in this crate's "main" error type to allow for a simpler API (the "handler error" type cannot be inferred by the compiler in some functions). |
Pty |
Standard pseudo-terminal codes. |
Sig |
The type of signals that can be sent to a remote process. If you plan to use custom signals, read the RFC to understand the encoding. |
Traits
FromFinished |
Since handlers are large, their associated future types must implement this trait to provide reasonable default implementations (basically, rejecting all requests). |
Named |
Named algorithms. |
Tcp |
Types that have a "TCP shutdown" operation. |