Expand description
Rust bindings to libssh2, an SSH client library.
This library intends to provide a safe interface to the libssh2 library. It will build the library if it’s not available on the local system, and otherwise link to an installed copy.
Note that libssh2 only supports SSH clients, not SSH servers. Additionally it only supports protocol v2, not protocol v1.
§Examples
§Inspecting ssh-agent
use ssh2::Session;
// Almost all APIs require a `Session` to be available
let sess = Session::new().unwrap();
let mut agent = sess.agent().unwrap();
// Connect the agent and request a list of identities
agent.connect().unwrap();
agent.list_identities().unwrap();
for identity in agent.identities().unwrap() {
println!("{}", identity.comment());
let pubkey = identity.blob();
}
§Authenticating with ssh-agent
use std::net::TcpStream;
use ssh2::Session;
// Connect to the local SSH server
let tcp = TcpStream::connect("127.0.0.1:22").unwrap();
let mut sess = Session::new().unwrap();
sess.set_tcp_stream(tcp);
sess.handshake().unwrap();
// Try to authenticate with the first identity in the agent.
sess.userauth_agent("username").unwrap();
// Make sure we succeeded
assert!(sess.authenticated());
§Authenticating with a password
use std::net::TcpStream;
use ssh2::Session;
// Connect to the local SSH server
let tcp = TcpStream::connect("127.0.0.1:22").unwrap();
let mut sess = Session::new().unwrap();
sess.set_tcp_stream(tcp);
sess.handshake().unwrap();
sess.userauth_password("username", "password").unwrap();
assert!(sess.authenticated());
§Run a command
use std::io::prelude::*;
use std::net::TcpStream;
use ssh2::Session;
// Connect to the local SSH server
let tcp = TcpStream::connect("127.0.0.1:22").unwrap();
let mut sess = Session::new().unwrap();
sess.set_tcp_stream(tcp);
sess.handshake().unwrap();
sess.userauth_agent("username").unwrap();
let mut channel = sess.channel_session().unwrap();
channel.exec("ls").unwrap();
let mut s = String::new();
channel.read_to_string(&mut s).unwrap();
println!("{}", s);
channel.wait_close().unwrap();
println!("{}", channel.exit_status().unwrap());
§Upload a file
use std::io::prelude::*;
use std::net::TcpStream;
use std::path::Path;
use ssh2::Session;
// Connect to the local SSH server
let tcp = TcpStream::connect("127.0.0.1:22").unwrap();
let mut sess = Session::new().unwrap();
sess.set_tcp_stream(tcp);
sess.handshake().unwrap();
sess.userauth_agent("username").unwrap();
// Write the file
let mut remote_file = sess.scp_send(Path::new("remote"),
0o644, 10, None).unwrap();
remote_file.write(b"1234567890").unwrap();
// Close the channel and wait for the whole content to be transferred
remote_file.send_eof().unwrap();
remote_file.wait_eof().unwrap();
remote_file.close().unwrap();
remote_file.wait_close().unwrap();
§Download a file
use std::io::prelude::*;
use std::net::TcpStream;
use std::path::Path;
use ssh2::Session;
// Connect to the local SSH server
let tcp = TcpStream::connect("127.0.0.1:22").unwrap();
let mut sess = Session::new().unwrap();
sess.set_tcp_stream(tcp);
sess.handshake().unwrap();
sess.userauth_agent("username").unwrap();
let (mut remote_file, stat) = sess.scp_recv(Path::new("remote")).unwrap();
println!("remote file size: {}", stat.size());
let mut contents = Vec::new();
remote_file.read_to_end(&mut contents).unwrap();
// Close the channel and wait for the whole content to be tranferred
remote_file.send_eof().unwrap();
remote_file.wait_eof().unwrap();
remote_file.close().unwrap();
remote_file.wait_close().unwrap();
§Execute a Netconf XML payload
use ssh2::{Channel, Session};
use std::error::Error;
use std::io::prelude::*;
use std::net::TcpStream;
const HELLO: &str = "<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">
<capabilities>
<capability>urn:ietf:params:netconf:base:1.1</capability>
</capabilities>
</hello>
]]>]]>";
const PAYLOAD: &str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<rpc xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.1\" message-id=\"2\">
<cli xmlns=\"http://cisco.com/ns/yang/cisco-nx-os-device\"><mode>EXEC</mode><cmdline>show version</cmdline></cli>
</rpc>";
fn read(channel: &mut Channel) -> Result<String, Box<dyn Error>> {
let mut result = String::new();
loop {
// If you plan to use this, be aware that reading 1 byte at a time is terribly
// inefficient and should be optimized for your usecase. This is just an example.
let mut buffer = [1u8; 1];
let bytes_read = channel.read(&mut buffer[..])?;
let s = String::from_utf8_lossy(&buffer[..bytes_read]);
result.push_str(&s);
if result.ends_with("]]>]]>") {
println!("Found netconf 1.0 terminator, breaking read loop");
break;
}
if result.ends_with("##") {
println!("Found netconf 1.1 terminator, breaking read loop");
break;
}
if bytes_read == 0 || channel.eof() {
println!("Buffer is empty, SSH channel read terminated");
break;
}
}
Ok(result)
}
fn main() -> Result<(), Box<dyn Error>> {
let tcp = TcpStream::connect("127.0.0.1:830")?;
let mut sess = Session::new()?;
sess.set_tcp_stream(tcp);
sess.handshake().unwrap();
sess.userauth_password("user", "pass")?;
let mut channel = sess.channel_session()?;
channel.subsystem("netconf")?;
let result = read(&mut channel)?;
println!("Result from connection:\n{}", result);
let payload = format!("{}\n#{}\n{}\n##\n", HELLO, PAYLOAD.len(), PAYLOAD);
let a = channel.write(payload.as_bytes())?;
println!("Written {} bytes payload", a);
let result = read(&mut channel)?;
println!("Result from payload execution:\n{}", result);
channel.send_eof()?;
channel.wait_eof()?;
channel.close()?;
channel.wait_close()?;
Ok(())
}
Re-exports§
pub use DisconnectCode::AuthCancelledByUser;
pub use DisconnectCode::TooManyConnections;
pub use DisconnectCode::ByApplication;
pub use DisconnectCode::ConnectionLost;
pub use DisconnectCode::HostKeyNotVerifiable;
pub use DisconnectCode::CompressionError;
pub use DisconnectCode::KeyExchangeFailed;
pub use DisconnectCode::MacError;
pub use DisconnectCode::Reserved;
pub use DisconnectCode::HostNotAllowedToConnect;
pub use DisconnectCode::ProtocolError;
pub use DisconnectCode::IllegalUserName;
pub use DisconnectCode::NoMoreAuthMethodsAvailable;
pub use DisconnectCode::ProtocolVersionNotSupported;
pub use DisconnectCode::ServiceNotAvailable;
Structs§
- Agent
- A structure representing a connection to an SSH agent.
- Channel
- A channel represents a portion of an SSH connection on which data can be read and written.
- Error
- Representation of an error that can occur within libssh2
- Exit
Signal - Data received from when a program exits with a signal.
- File
- A file handle to an SFTP connection.
- File
Stat - Metadata information about a remote file.
- Host
- Structure representing a known host as part of a
KnownHosts
structure. - Known
Hosts - A set of known hosts which can be used to verify the identity of a remote server.
- Listener
- A listener represents a forwarding port from the remote server.
- Open
Flags - Options that can be used to configure how a file is opened
- Prompt
- A prompt/challenge returned as part of keyboard-interactive authentication
- PtyModes
- Encodes modes for Pty allocation requests. The modes documented in https://tools.ietf.org/html/rfc4250#section-4.5 are supported.
- Public
Key - A public key which is extracted from an SSH agent.
- Read
Window - Description of the read window as returned by
Channel::read_window
- Rename
Flags - Options to
Sftp::rename
. - ScpFile
Stat - Metadata returned about a remote file when received via
scp
. - Session
- An SSH session, typically representing one TCP connection.
- Sftp
- A handle to a remote filesystem over SFTP.
- Stream
- A channel can have a number of streams, each identified by an id, each of
which implements the
Read
andWrite
traits. - Trace
Flags - Flags which can be used with the session trace method to set the trace level.
- Write
Window - Description of the write window as returned by
Channel::write_window
Enums§
- Block
Directions - The io direction an application has to wait for in order not to block.
- Check
Result - Possible results of a call to
KnownHosts::check
- Disconnect
Code - Error
Code - An error code originating from a particular source.
- Extended
Data - How to handle extended data streams, such as stderr
- Extensible
PtyMode Opcode - An opcode for setting a Pty terminal mode
- File
Type - An enum representing a type of file.
- Hash
Type - Host
KeyType - Known
Host File Kind - Known
Host KeyFormat - Method
Type - Open
Type - How to open a file handle with libssh2.
- PtyMode
Opcode - The modes described in https://tools.ietf.org/html/rfc4250#section-4.5.2
Statics§
- EXTENDED_
DATA_ STDERR - Stream ID of the stderr channel for stream-related methods on
Channel
- FLUSH_
ALL - When passed to
Channel::flush_stream
, flushes all substream. - FLUSH_
EXTENDED_ DATA - When passed to
Channel::flush_stream
, flushes all extended data substreams.
Traits§
- Keyboard
Interactive Prompt - Called by libssh2 to respond to some number of challenges as part of keyboard interactive authentication.
Functions§
- init
- Initialize the libssh2 library.