Skip to main content

Client

Struct Client 

Source
pub struct Client {
    pub session: Arc<Handle<ClientHandler>>,
    /* private fields */
}
Expand description

A ssh connection to a remote server.

After creating a Client by connecting to a remote host, use execute to send commands and receive results through the connections.

§Examples

use bssh::ssh::tokio_client::{Client, AuthMethod, ServerCheckMethod};
#[tokio::main]
async fn main() -> Result<(), bssh::ssh::tokio_client::Error> {
    let mut client = Client::connect(
        ("10.10.10.2", 22),
        "root",
        AuthMethod::with_password("root"),
        ServerCheckMethod::NoCheck,
    ).await?;

    let result = client.execute("echo Hello SSH").await?;
    assert_eq!(result.stdout, "Hello SSH\n");
    assert_eq!(result.exit_status, 0);

    Ok(())
}

Fields§

§session: Arc<Handle<ClientHandler>>

Public access to the SSH session for jump host operations

Implementations§

Source§

impl Client

Source

pub async fn get_channel(&self) -> Result<Channel<Msg>, Error>

Get a new SSH channel for communication.

Source

pub async fn open_direct_tcpip_channel<T: ToSocketAddrsWithHostname, S: Into<Option<SocketAddr>>>( &self, target: T, src: S, ) -> Result<Channel<Msg>, Error>

Open a TCP/IP forwarding channel.

This opens a direct-tcpip channel to the given target.

Source

pub async fn execute_streaming( &self, command: &str, sender: Sender<CommandOutput>, ) -> Result<u32, Error>

Execute a remote command via the ssh connection with streaming output.

This method sends command output in real-time to the provided sender channel. Output is sent as CommandOutput::StdOut or CommandOutput::StdErr variants.

Returns only the exit status of the command. Stdout and stderr are streamed through the sender channel.

Make sure your commands don’t read from stdin and exit after bounded time.

Can be called multiple times, but every invocation is a new shell context. Thus cd, setting variables and alike have no effect on future invocations.

§Backpressure Handling

If the channel fills up (receiver is slower than output production), this method will apply backpressure by blocking until space is available. This prevents unbounded memory growth but may slow down command execution for high-throughput commands.

§Error Handling
  • If the receiver drops the channel, this method will stop processing output and return the last known exit status.
  • Command sanitization errors are propagated as CommandValidationFailed.
§Arguments
  • command - The command to execute
  • sender - Channel sender for streaming output
§Returns

The exit status of the command

Source

pub async fn execute_with_sudo( &self, command: &str, sender: Sender<CommandOutput>, sudo_password: &SudoPassword, ) -> Result<u32, Error>

Execute a remote command with sudo password support.

This method handles automatic sudo password injection when sudo prompts are detected in the command output. It monitors both stdout and stderr for sudo password prompts and automatically sends the password when detected.

§Arguments
  • command - The command to execute (typically starts with sudo)
  • sender - Channel sender for streaming output
  • sudo_password - The sudo password to inject when prompted
§Returns

The exit status of the command

§Security
  • Password is only sent when a sudo prompt is detected
  • Password is never logged or included in error messages
  • Detects sudo authentication failures and reports them appropriately
Source

pub async fn execute( &self, command: &str, ) -> Result<CommandExecutedResult, Error>

Execute a remote command via the ssh connection.

Returns stdout, stderr and the exit code of the command, packaged in a CommandExecutedResult struct. If you need the stderr output interleaved within stdout, you should postfix the command with a redirection, e.g. echo foo 2>&1. If you dont want any output at all, use something like echo foo >/dev/null 2>&1.

Make sure your commands don’t read from stdin and exit after bounded time.

Can be called multiple times, but every invocation is a new shell context. Thus cd, setting variables and alike have no effect on future invocations.

Source

pub async fn request_interactive_shell( &self, _term_type: &str, _width: u32, _height: u32, ) -> Result<Channel<Msg>, Error>

Request an interactive shell channel.

This method opens a new SSH channel suitable for interactive shell sessions. Note: This method no longer requests PTY directly. The PTY should be requested by the caller (e.g., PtySession) with appropriate terminal modes.

§Arguments
  • _term_type - Terminal type (unused, kept for API compatibility)
  • _width - Terminal width (unused, kept for API compatibility)
  • _height - Terminal height (unused, kept for API compatibility)
§Returns

A Channel that can be used for bidirectional communication with the remote shell.

§Note

The caller is responsible for:

  1. Requesting PTY with proper terminal modes via channel.request_pty()
  2. Requesting shell via channel.request_shell()

This change fixes issue #40: PTY should be requested once with proper terminal modes by PtySession::initialize() rather than twice with empty modes.

Source

pub async fn resize_pty( &self, channel: &mut Channel<Msg>, width: u32, height: u32, ) -> Result<(), Error>

Request window size change for an existing PTY channel.

This should be called when the local terminal is resized to update the remote PTY dimensions.

Source§

impl Client

Source

pub async fn connect( addr: impl ToSocketAddrsWithHostname, username: &str, auth: AuthMethod, server_check: ServerCheckMethod, ) -> Result<Self, Error>

Open a ssh connection to a remote host with default keepalive settings.

addr is an address of the remote host. Anything which implements ToSocketAddrsWithHostname trait can be supplied for the address; ToSocketAddrsWithHostname reimplements all of [ToSocketAddrs]; see this trait’s documentation for concrete examples.

If addr yields multiple addresses, connect will be attempted with each of the addresses until a connection is successful. Authentification is tried on the first successful connection and the whole process aborted if this fails.

This method uses default keepalive settings (60s interval, 3 max attempts) to prevent idle connection timeouts.

Source

pub async fn connect_with_ssh_config( addr: impl ToSocketAddrsWithHostname, username: &str, auth: AuthMethod, server_check: ServerCheckMethod, ssh_config: &SshConnectionConfig, ) -> Result<Self, Error>

Connect with custom SSH connection configuration.

This method allows specifying keepalive settings and other connection parameters through SshConnectionConfig.

§Example
use bssh::ssh::tokio_client::{Client, AuthMethod, ServerCheckMethod, SshConnectionConfig};

#[tokio::main]
async fn main() -> Result<(), bssh::ssh::tokio_client::Error> {
    let ssh_config = SshConnectionConfig::new()
        .with_keepalive_interval(Some(30))
        .with_keepalive_max(5);

    let client = Client::connect_with_ssh_config(
        ("example.com", 22),
        "user",
        AuthMethod::with_key_file("~/.ssh/id_rsa", None),
        ServerCheckMethod::DefaultKnownHostsFile,
        &ssh_config,
    ).await?;

    Ok(())
}
Source

pub async fn connect_with_config( addr: impl ToSocketAddrsWithHostname, username: &str, auth: AuthMethod, server_check: ServerCheckMethod, config: Config, ) -> Result<Self, Error>

Same as connect, but with the option to specify a non default russh::client::Config.

For most use cases, prefer [connect_with_ssh_config] which provides a higher-level API with sensible defaults.

Source

pub fn from_handle_and_address( handle: Arc<Handle<ClientHandler>>, username: String, address: SocketAddr, ) -> Self

Create a Client from an existing russh handle and address.

This is used internally for jump host connections where we already have an authenticated russh handle from connect_stream.

Source

pub fn get_connection_username(&self) -> &String

A debugging function to get the username this client is connected as.

Source

pub fn get_connection_address(&self) -> &SocketAddr

A debugging function to get the address this client is connected to.

Source

pub async fn disconnect(&self) -> Result<(), Error>

Disconnect from the remote host.

Source

pub fn is_closed(&self) -> bool

Check if the connection is closed.

Source

pub async fn request_port_forward( &self, _bind_address: String, _bind_port: u32, ) -> Result<u32, Error>

Request remote port forwarding (tcpip-forward) - Future Implementation Placeholder

TODO: This method needs to be implemented once russh provides global request functionality or we find the appropriate API.

This sends a global request to the SSH server to bind a port on the remote end and forward connections back to the client. This is used for remote port forwarding (-R).

§Arguments
  • bind_address - Address to bind on the remote server (e.g., “localhost”, “0.0.0.0”)
  • bind_port - Port to bind on the remote server (0 to let server choose)
§Returns

The actual port number that was bound by the server (useful when bind_port is 0)

Source

pub async fn cancel_port_forward( &self, _bind_address: String, _bind_port: u32, ) -> Result<(), Error>

Cancel remote port forwarding (cancel-tcpip-forward) - Future Implementation Placeholder

TODO: This method needs to be implemented once russh provides global request functionality or we find the appropriate API.

This sends a global request to cancel a previously established remote port forward.

§Arguments
  • bind_address - Address that was bound on the remote server
  • bind_port - Port that was bound on the remote server
Source§

impl Client

Source

pub async fn upload_file<T: AsRef<Path>, U: Into<String>>( &self, src_file_path: T, dest_file_path: U, ) -> Result<(), Error>

Upload a file with sftp to the remote server.

src_file_path is the path to the file on the local machine. dest_file_path is the path to the file on the remote machine. Some sshd_config does not enable sftp by default, so make sure it is enabled. A config line like a Subsystem sftp internal-sftp or Subsystem sftp /usr/lib/openssh/sftp-server is needed in the sshd_config in remote machine.

Source

pub async fn download_file<T: AsRef<Path>, U: Into<String>>( &self, remote_file_path: U, local_file_path: T, ) -> Result<(), Error>

Download a file from the remote server using sftp.

remote_file_path is the path to the file on the remote machine. local_file_path is the path to the file on the local machine. Some sshd_config does not enable sftp by default, so make sure it is enabled. A config line like a Subsystem sftp internal-sftp or Subsystem sftp /usr/lib/openssh/sftp-server is needed in the sshd_config in remote machine.

Source

pub async fn upload_dir<T: AsRef<Path>, U: Into<String>>( &self, local_dir_path: T, remote_dir_path: U, ) -> Result<(), Error>

Upload a directory to the remote server using sftp recursively.

local_dir_path is the path to the directory on the local machine. remote_dir_path is the path to the directory on the remote machine. All files and subdirectories will be uploaded recursively.

Source

pub async fn download_dir<T: AsRef<Path>, U: Into<String>>( &self, remote_dir_path: U, local_dir_path: T, ) -> Result<(), Error>

Download a directory from the remote server using sftp recursively.

remote_dir_path is the path to the directory on the remote machine. local_dir_path is the path to the directory on the local machine. All files and subdirectories will be downloaded recursively.

Trait Implementations§

Source§

impl Clone for Client

Source§

fn clone(&self) -> Client

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Client

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FutureExt for T

Source§

fn with_context(self, otel_cx: Context) -> WithContext<Self>

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
Source§

fn with_current_context(self) -> WithContext<Self>

Attaches the current Context to this type, returning a WithContext wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<D> OwoColorize for D

Source§

fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>
where C: Color,

Set the foreground color generically Read more
Source§

fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>
where C: Color,

Set the background color generically. Read more
Source§

fn black(&self) -> FgColorDisplay<'_, Black, Self>

Change the foreground color to black
Source§

fn on_black(&self) -> BgColorDisplay<'_, Black, Self>

Change the background color to black
Source§

fn red(&self) -> FgColorDisplay<'_, Red, Self>

Change the foreground color to red
Source§

fn on_red(&self) -> BgColorDisplay<'_, Red, Self>

Change the background color to red
Source§

fn green(&self) -> FgColorDisplay<'_, Green, Self>

Change the foreground color to green
Source§

fn on_green(&self) -> BgColorDisplay<'_, Green, Self>

Change the background color to green
Source§

fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>

Change the foreground color to yellow
Source§

fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>

Change the background color to yellow
Source§

fn blue(&self) -> FgColorDisplay<'_, Blue, Self>

Change the foreground color to blue
Source§

fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>

Change the background color to blue
Source§

fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to magenta
Source§

fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to magenta
Source§

fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>

Change the foreground color to purple
Source§

fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>

Change the background color to purple
Source§

fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>

Change the foreground color to cyan
Source§

fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>

Change the background color to cyan
Source§

fn white(&self) -> FgColorDisplay<'_, White, Self>

Change the foreground color to white
Source§

fn on_white(&self) -> BgColorDisplay<'_, White, Self>

Change the background color to white
Source§

fn default_color(&self) -> FgColorDisplay<'_, Default, Self>

Change the foreground color to the terminal default
Source§

fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>

Change the background color to the terminal default
Source§

fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>

Change the foreground color to bright black
Source§

fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>

Change the background color to bright black
Source§

fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>

Change the foreground color to bright red
Source§

fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>

Change the background color to bright red
Source§

fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>

Change the foreground color to bright green
Source§

fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>

Change the background color to bright green
Source§

fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>

Change the foreground color to bright yellow
Source§

fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>

Change the background color to bright yellow
Source§

fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>

Change the foreground color to bright blue
Source§

fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>

Change the background color to bright blue
Source§

fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright magenta
Source§

fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright magenta
Source§

fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>

Change the foreground color to bright purple
Source§

fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>

Change the background color to bright purple
Source§

fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>

Change the foreground color to bright cyan
Source§

fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>

Change the background color to bright cyan
Source§

fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>

Change the foreground color to bright white
Source§

fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>

Change the background color to bright white
Source§

fn bold(&self) -> BoldDisplay<'_, Self>

Make the text bold
Source§

fn dimmed(&self) -> DimDisplay<'_, Self>

Make the text dim
Source§

fn italic(&self) -> ItalicDisplay<'_, Self>

Make the text italicized
Source§

fn underline(&self) -> UnderlineDisplay<'_, Self>

Make the text underlined
Make the text blink
Make the text blink (but fast!)
Source§

fn reversed(&self) -> ReversedDisplay<'_, Self>

Swap the foreground and background colors
Source§

fn hidden(&self) -> HiddenDisplay<'_, Self>

Hide the text
Source§

fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>

Cross out the text
Source§

fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the foreground color at runtime. Only use if you do not know which color will be used at compile-time. If the color is constant, use either OwoColorize::fg or a color-specific method, such as OwoColorize::green, Read more
Source§

fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>
where Color: DynColor,

Set the background color at runtime. Only use if you do not know what color to use at compile-time. If the color is constant, use either OwoColorize::bg or a color-specific method, such as OwoColorize::on_yellow, Read more
Source§

fn fg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> FgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the foreground color to a specific RGB value.
Source§

fn bg_rgb<const R: u8, const G: u8, const B: u8>( &self, ) -> BgColorDisplay<'_, CustomColor<R, G, B>, Self>

Set the background color to a specific RGB value.
Source§

fn truecolor(&self, r: u8, g: u8, b: u8) -> FgDynColorDisplay<'_, Rgb, Self>

Sets the foreground color to an RGB value.
Source§

fn on_truecolor(&self, r: u8, g: u8, b: u8) -> BgDynColorDisplay<'_, Rgb, Self>

Sets the background color to an RGB value.
Source§

fn style(&self, style: Style) -> Styled<&Self>

Apply a runtime-determined style
Source§

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

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more