thrussh 0.3.4

A client and server SSH library. Memory-safe, doesn't do its own crypto (based on libsodium).
Documentation

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, server, client, Server, Client, CryptoBuf, Error}; let client_keypair = key::Algorithm::generate_keypair(key::ED25519).unwrap(); let server_keypair = key::Algorithm::generate_keypair(key::ED25519).unwrap();

// Server instance

struct S { client_pubkey: key::PublicKey } impl Server for S { fn auth_publickey(&mut self, user:&str, publickey:&key::PublicKey) -> bool { user == "pe" && publickey == &self.client_pubkey } }

// Client instance

struct C { server_pk: key::PublicKey, channel_confirmed: Option } impl Client for C { fn check_server_key(&mut self, server_pk:&key::PublicKey) -> Result<bool, Error> {

    // 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.

    Ok(&self.server_pk == server_pk)
}
fn channel_open_confirmation(&mut self, channel:u32, _:&mut client::Session) -> Result<(), Error> {
    self.channel_confirmed = Some(channel);
    Ok(())
}

}

// 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.clone_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.clone_public_key(), channel_confirmed: None }; let mut client_connection = client::Connection::new(client_config); client_connection.session.set_auth_public_key("pe".to_string(), 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 = Vec::new(); let mut server_write:Vec = 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, client:&mut C| { { let mut swrite = &server_write[..]; client_connection.read(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, &mut client) }

// 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 client.channel_confirmed == Some(channel) { break }; run_protocol(&mut client_connection, &mut client); }

``