Skip to main content

Client

Struct Client 

Source
pub struct Client { /* private fields */ }
Expand description

A blocking SSH client.

Implementations§

Source§

impl Client

Source

pub fn connect<A: ToSocketAddrs>(addr: A, cfg: Config) -> Result<Self>

Connect, complete version exchange + KEX + NEWKEYS, leave the codec keyed and ready for userauth.

Source

pub fn connect_to_host(host: &str, port: u16, cfg: Config) -> Result<Self>

Like Self::connect, but threads the user-supplied host name and port through so HostKeyPolicy::KnownHosts has something stable to look up. Use this instead of connect whenever the host key policy reads known_hostsconnect accepts any ToSocketAddrs (including IpAddr) and so cannot recover the original hostname.

Source

pub fn authenticate( &mut self, user: &str, credentials: Vec<ClientCredential>, ) -> Result<()>

Try every credential in order until one succeeds or all are refused.

Source

pub fn authenticate_password( &mut self, user: &str, password: &str, ) -> Result<()>

Convenience: try password authentication only.

Source

pub fn session_id(&self) -> &[u8]

Session identifier for this connection — the exchange hash H of the first key exchange (RFC 4253 §7.2). Stable across re-keys.

Source

pub fn authenticate_publickey( &mut self, user: &str, key: Box<dyn HostKey + Send>, ) -> Result<()>

Convenience: try publickey authentication only.

Source

pub fn open_session_for_agent_forward(&mut self) -> Result<u32>

Open a session channel that exists solely to host an auth-agent-req@openssh.com request, then send that request and return the channel’s local id. The caller is expected to keep this channel open for the lifetime of any agent-forwarding work (Self::serve with ClientHandlers::on_auth_agent installed), then tear it down with Self::close_session.

On the server side, the matching auth-agent-req arms a per-session-channel Unix-socket listener; closing this channel unlinks the socket and stops accepting agent calls. See crate::forwarding::agent for the server side.

Source

pub fn open_session_for_x11_forward( &mut self, single_connection: bool, auth_protocol: &str, auth_cookie: &str, screen: u32, ) -> Result<u32>

Open a session channel that exists solely to host an x11-req request, then send that request and return the channel’s local id. The caller is expected to keep this channel open for the lifetime of any X11-forwarding work (Self::serve with ClientHandlers::on_x11 installed), then tear it down with Self::close_session.

On the server side, the matching x11-req arms a per-session TCP display listener (127.0.0.1:6000+N); closing this channel stops it. See crate::forwarding::x11 for the server side.

Source

pub fn close_session(&mut self, channel: u32) -> Result<()>

Send SSH_MSG_CHANNEL_CLOSE for channel. Used to tear down a session channel opened by Self::open_session_for_agent_forward once the matching serve loop has returned. Best-effort: silently swallows codec errors for channels already torn down by the peer.

Source

pub fn set_request_auth_agent_forwarding(&mut self, on: bool)

Toggle whether the next session-channel helper (Self::exec, Self::exec_stream, Self::shell_with_stdin, Self::sftp) prefaces its shell/exec/subsystem request with auth-agent-req@openssh.com (the channel request that asks the server to set up an SSH_AUTH_SOCK Unix socket for this session channel and call back via auth-agent@openssh.com channels — OpenSSH’s ssh -A).

Sticky: stays set until cleared. The agent-req is sent with want_reply = false, matching OpenSSH; the server’s response (acceptance / refusal) is observable only via whether a callback channel ever lands on a peer-installed ClientHandlers::on_auth_agent.

Source

pub fn set_request_x11_forwarding( &mut self, args: Option<(bool, String, String, u32)>, )

Arm x11-req to be emitted on every subsequent session-channel helper (Self::exec, Self::exec_stream, Self::shell_with_stdin, Self::sftp) between OpenConfirmed and the matching shell/exec/subsystem request.

single_connection follows RFC 4254 §6.3.1: true accepts exactly one X-client connection on the forwarded display, false accepts any number (the OpenSSH default for both -X and -Y).

auth_protocol is typically "MIT-MAGIC-COOKIE-1"; auth_cookie is the matching cookie as a hex string. The server forwards both verbatim into crate::server::X11ForwardHandler::setup — cookie substitution at the X-protocol level is the responsibility of the on_x11 handler. screen is the X screen number (0 in nearly all uses). Pass None to clear the toggle.

Source

pub fn exec(&mut self, command: &str) -> Result<ExecOutput>

Run a remote command, draining stdout/stderr and capturing the exit status (or signal). Returns once the server has closed the channel.

Source

pub fn shell_with_stdin( &mut self, term: &str, cols: u32, rows: u32, stdin: &[u8], ) -> Result<ExecOutput>

Open an interactive "shell" session with an allocated PTY, push stdin into the channel once, EOF, and drain the response until the server closes the channel.

This is a one-shot helper aimed at scripted tests and simple interop checks — a real interactive client would interleave reads and writes with the terminal. It exists primarily so the server’s pty-req / shell wiring can be exercised end-to-end.

Source

pub fn subsystem_once(&mut self, name: &str, stdin: &[u8]) -> Result<Vec<u8>>

One-shot subsystem helper: open a session channel, send a subsystem request with the given name, push stdin once, send EOF, then drain the response until the peer CLOSEs. Returns the accumulated channel data (the stream’s stdout half).

This is the subsystem analogue of exec: it doesn’t expose the channel for streaming use (a Client::sftp streaming wrapper will land in a follow-up phase), but it’s enough to exercise the server’s subsystem dispatch end-to-end and to drive small request/response protocols.

Source

pub fn sftp(&mut self) -> Result<SftpClient<ClientChannelStream<'_>>>

👎Deprecated since 0.0.2:

Use SharedClient::sftp instead; the borrow-based API prevents multiple concurrent channels on one connection.

Open an SFTP session: opens a session channel, requests the sftp subsystem, performs the SFTP INIT/VERSION handshake, and returns a SftpClient borrowing the channel for its lifetime.

The returned client serialises one request/response at a time. When it’s dropped, the channel is closed.

Source

pub fn exec_stream(&mut self, command: &str) -> Result<ClientChannelStream<'_>>

👎Deprecated since 0.0.2:

Use SharedClient::exec_stream for multi-channel support.

Open a session channel and ask the server to execute command, returning a ClientChannelStream borrowing the client for the channel’s lifetime. The stream’s Read half delivers the command’s stdout, Write feeds stdin, and the channel is closed on drop. Stderr is buffered and can be drained with ClientChannelStream::take_stderr.

Mirrors Client::sftp but issues ChannelRequest::Exec instead of Subsystem. Used by Client::scp_send_to / Client::scp_recv_from to drive the remote scp -t / scp -f helper over the channel. For one-shot commands whose output you just want to collect, use Client::exec instead.

Source

pub fn open_direct_tcpip( &mut self, dest_host: &str, dest_port: u16, orig_host: &str, orig_port: u16, ) -> Result<ClientChannelStream<'_>>

👎Deprecated since 0.0.2:

Use SharedClient::open_direct_tcpip for multi-channel support.

Open a direct-tcpip channel (RFC 4254 §7.2) that asks the server to connect to dest_host:dest_port and proxy bytes. Returns a Read + Write stream borrowing the client for the channel’s lifetime; dropping it closes the channel.

orig_host/orig_port are informational (the server logs them but makes no routing decision on them); pass ("127.0.0.1", 0) if you don’t have a meaningful source.

Like Client::sftp / Client::exec, this is a single-channel helper: while the returned stream is alive, the client cannot be used for anything else. Multi-channel multiplexing comes later via the Client::serve event loop.

Source

pub fn scp_send_to( &mut self, sources: &[&Path], remote_dest: &str, opts: ScpSendOptions, ) -> Result<()>

Upload one or more local sources to a remote destination via SCP.

Issues scp -t [-r] [-p] -- <quoted dest> on the peer (a remote scp binary, or our own sshd’s in-process crate::server::ExecStreamHandler reading the SCP protocol). For each source we then drive crate::scp::Sender::send_path over the channel.

Remote-path quoting refuses ', \n, and \0 to prevent shell injection on the remote side. On error, any buffered server-side stderr is appended to the message via ClientChannelStream::take_stderr.

Source

pub fn scp_recv_from( &mut self, remote_source: &str, local_dest: &Path, opts: ScpRecvOptions, ) -> Result<()>

Download from a remote source to a local destination via SCP.

Issues scp -f [-r] [-p] -- <quoted source> on the peer, then drives crate::scp::Receiver::run over the channel.

local_dest is interpreted as a target directory unless opts.recursive is false AND local_dest doesn’t exist as a directory — in which case it’s treated as the literal file path (matches scp remote:foo /tmp/bar). To force file-target behaviour set the recv options’ target_is_file flag.

Source

pub fn request_tcpip_forward( &mut self, bind_address: &str, bind_port: u16, ) -> Result<u16>

Send a tcpip-forward global request (RFC 4254 §7.1; the outbound bookend of ssh -R) and block until the server replies.

bind_port == 0 asks the server to pick a port; the actual port is returned. Any other value asks the server to bind that exact port and is returned verbatim on success.

Returns Err(Error::Protocol(_)) if the server replies REQUEST_FAILURE or if the reply tail is malformed.

Note: at the time of writing the server side is bind-and-drop — connections accepted on the bound port are closed immediately. End-to-end byte forwarding (server-initiated forwarded-tcpip channel-opens back to the client) lands in a follow-up commit.

Source

pub fn cancel_tcpip_forward( &mut self, bind_address: &str, bind_port: u16, ) -> Result<()>

Send a cancel-tcpip-forward global request (RFC 4254 §7.1) and block until the server replies. The (bind_address, bind_port) pair must match a previous successful request_tcpip_forward.

Source

pub fn serve(&mut self, handlers: ClientHandlers) -> Result<()>

Multi-channel event loop. Run after a Self::request_tcpip_forward so server-initiated forwarded-tcpip channel opens land in ClientHandlers::on_forwarded_tcpip.

The loop polls the socket with a small read timeout (SERVE_POLL_INTERVAL, currently 50ms) so it can interleave wire reads with per-channel egress draining. Returns:

  • Ok(()) once handlers.stop has been set AND every accepted channel has been torn down (matching the server’s do_connection_loop exit condition).
  • Err(Error::Protocol(_)) on protocol violation.
  • Err(Error::Io(_)) if the peer hangs up the socket.

Channel opens whose handler is unset are rejected with SSH_OPEN_ADMINISTRATIVELY_PROHIBITED; unrelated channel-events (e.g. for direct-tcpip channels the user opened via Self::open_direct_tcpip before calling serve) are NOT dispatched — those types own their own ClientChannelStream which would also try to drain the socket. In other words: while serve is running, no other Client method may be used on this client.

Trait Implementations§

Source§

impl From<Client> for SharedClient

Source§

fn from(client: Client) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl Freeze for Client

§

impl !RefUnwindSafe for Client

§

impl Send for Client

§

impl !Sync for Client

§

impl Unpin for Client

§

impl UnsafeUnpin for Client

§

impl !UnwindSafe for Client

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.