Crate thrussh [] [src]

Server and client SSH library. See the two example crates thrussh_client and thrussh_client on crates.io. More information here.

Here is an example, using Vecs as instances of Read and Write, instead of network sockets.

 use std::sync::Arc;
 use thrussh::{key, auth, server, client, Server, Client, CryptoBuf};
 let client_keypair = key::Algorithm::generate_keypair(key::ED25519).unwrap();
 let server_keypair = key::Algorithm::generate_keypair(key::ED25519).unwrap();

 // Server instance

 struct S<'p> {
     client_pubkey: &'p key::PublicKey
 }
 impl<'p> Server for S<'p> {
     fn auth(&self, _:auth::M, method:&auth::Method<key::PublicKey>) -> auth::Answer {
         match *method {
             auth::Method::PublicKey { ref user, ref public_key }
               if *user == "pe" && public_key == self.client_pubkey=> {
                 // If the user and public key match, accept the public key.
                 auth::Answer::Success
             },
             _ =>
                 // Else, reject and provide no other methods.
                 auth::Answer::Reject {
                     partial_success:false, remaining_methods:
                     auth::M::empty()
                 }
         }
     }
 }

 // Client instance

 struct C<'p> {
     server_pk: &'p key::PublicKey
 }
 impl<'p> Client for C<'p> {
     fn check_server_key(&self, server_pk:&key::PublicKey) -> bool {

         // This is an important part of the protocol: check the
         // server's public key against the known one, to help prevent
         // man-in-the-middle attacks.

         self.server_pk == server_pk
     }
 }

 
 // Initialize the server
 
 let server_config = {
     let mut config:server::Config = Default::default();
     config.keys.push(server_keypair.clone());
     Arc::new(config)
 };
 let mut server = S{
     client_pubkey: &client_keypair.public_key()
 };
 let mut server_connection = server::Connection::new(server_config.clone());


 // Initialize the client
 
 let client_config = Arc::new(Default::default());
 let mut client = C{
     server_pk: &server_keypair.public_key()
 };
 let mut client_connection = client::Connection::new(client_config);
 client_connection.session.set_auth_public_key("pe", client_keypair);

 // Now, run the protocol (it is obviously more useful when the
 // instances of Read and Write are networks sockets instead of Vec).


 // Fake sockets.
 let mut server_read:Vec<u8> = Vec::new();
 let mut server_write:Vec<u8> = Vec::new();

 // The server and client need extra workspace, we allocate these here.
 let mut buffer0 = CryptoBuf::new();
 let mut buffer1 = CryptoBuf::new();

 let mut run_protocol = |client_connection:&mut client::Connection| {
     {
         let mut swrite = &server_write[..];
         client_connection.read(&mut client, &mut swrite, &mut buffer0, &mut buffer1).unwrap();
     }
     server_write.clear();
     client_connection.write(&mut server_read).unwrap();
     {
         let mut sread = &server_read[..];
         server_connection.read(&mut server, &mut sread, &mut buffer0, &mut buffer1).unwrap();
     }
     server_read.clear();
     server_connection.write(&mut server_write).unwrap();
 };

 // Run the protocol until authentication is complete.
 while !client_connection.session.is_authenticated() {
     run_protocol(&mut client_connection)
 }

 // From the client, ask the server to open a channel (prepare buffers to do so).
 let channel = client_connection.session.channel_open_session().unwrap();


 // Then run the protocol again, until our channel is confirmed.
 loop {
     if let Some(chan) = client_connection.session.channels().and_then(|x| x.get(&channel)) {
         if chan.confirmed {
             break
         }
     }
     run_protocol(&mut client_connection);
 }

Modules

auth
client
key

Key generation and use.

server

Structs

Channel

The parameters of a channel.

CryptoBuf

A buffer which zeroes its memory on .clear(), .truncate() and reallocations, to avoid copying secrets around.

Limits

The number of bytes read/written, and the number of seconds before a key re-exchange is requested.

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
Pty
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

Client
Server

Functions

load_public_key

Load a public key from a file. Only ed25519 keys are currently supported.

load_secret_key

Load a secret key from a file. Only ed25519 keys are currently supported.