pub struct Client { /* private fields */ }Expand description
A blocking SSH client.
Implementations§
Source§impl Client
impl Client
Sourcepub fn connect<A: ToSocketAddrs>(addr: A, cfg: Config) -> Result<Self>
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.
Sourcepub fn connect_to_host(host: &str, port: u16, cfg: Config) -> Result<Self>
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_hosts — connect accepts any ToSocketAddrs
(including IpAddr) and so cannot recover the original hostname.
Sourcepub fn authenticate(
&mut self,
user: &str,
credentials: Vec<ClientCredential>,
) -> Result<()>
pub fn authenticate( &mut self, user: &str, credentials: Vec<ClientCredential>, ) -> Result<()>
Try every credential in order until one succeeds or all are refused.
Sourcepub fn authenticate_password(
&mut self,
user: &str,
password: &str,
) -> Result<()>
pub fn authenticate_password( &mut self, user: &str, password: &str, ) -> Result<()>
Convenience: try password authentication only.
Sourcepub fn session_id(&self) -> &[u8] ⓘ
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.
Sourcepub fn authenticate_publickey(
&mut self,
user: &str,
key: Box<dyn HostKey + Send>,
) -> Result<()>
pub fn authenticate_publickey( &mut self, user: &str, key: Box<dyn HostKey + Send>, ) -> Result<()>
Convenience: try publickey authentication only.
Sourcepub fn open_session_for_agent_forward(&mut self) -> Result<u32>
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.
Sourcepub fn open_session_for_x11_forward(
&mut self,
single_connection: bool,
auth_protocol: &str,
auth_cookie: &str,
screen: u32,
) -> Result<u32>
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.
Sourcepub fn close_session(&mut self, channel: u32) -> Result<()>
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.
Sourcepub fn set_request_auth_agent_forwarding(&mut self, on: bool)
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.
Sourcepub fn set_request_x11_forwarding(
&mut self,
args: Option<(bool, String, String, u32)>,
)
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.
Sourcepub fn exec(&mut self, command: &str) -> Result<ExecOutput>
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.
Sourcepub fn shell_with_stdin(
&mut self,
term: &str,
cols: u32,
rows: u32,
stdin: &[u8],
) -> Result<ExecOutput>
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.
Sourcepub fn subsystem_once(&mut self, name: &str, stdin: &[u8]) -> Result<Vec<u8>>
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.
Sourcepub 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.
pub fn sftp(&mut self) -> Result<SftpClient<ClientChannelStream<'_>>>
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.
Sourcepub fn exec_stream(&mut self, command: &str) -> Result<ClientChannelStream<'_>>
👎Deprecated since 0.0.2: Use SharedClient::exec_stream for multi-channel support.
pub fn exec_stream(&mut self, command: &str) -> Result<ClientChannelStream<'_>>
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.
Sourcepub 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.
pub fn open_direct_tcpip( &mut self, dest_host: &str, dest_port: u16, orig_host: &str, orig_port: u16, ) -> Result<ClientChannelStream<'_>>
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.
Sourcepub fn scp_send_to(
&mut self,
sources: &[&Path],
remote_dest: &str,
opts: ScpSendOptions,
) -> Result<()>
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.
Sourcepub fn scp_recv_from(
&mut self,
remote_source: &str,
local_dest: &Path,
opts: ScpRecvOptions,
) -> Result<()>
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.
Sourcepub fn request_tcpip_forward(
&mut self,
bind_address: &str,
bind_port: u16,
) -> Result<u16>
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.
Sourcepub fn cancel_tcpip_forward(
&mut self,
bind_address: &str,
bind_port: u16,
) -> Result<()>
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.
Sourcepub fn serve(&mut self, handlers: ClientHandlers) -> Result<()>
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(())oncehandlers.stophas been set AND every accepted channel has been torn down (matching the server’sdo_connection_loopexit 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.