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
impl Client
Sourcepub async fn get_channel(&self) -> Result<Channel<Msg>, Error>
pub async fn get_channel(&self) -> Result<Channel<Msg>, Error>
Get a new SSH channel for communication.
Sourcepub async fn open_direct_tcpip_channel<T: ToSocketAddrsWithHostname, S: Into<Option<SocketAddr>>>(
&self,
target: T,
src: S,
) -> Result<Channel<Msg>, Error>
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.
Sourcepub async fn execute_streaming(
&self,
command: &str,
sender: Sender<CommandOutput>,
) -> Result<u32, Error>
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 executesender- Channel sender for streaming output
§Returns
The exit status of the command
Sourcepub async fn execute_with_sudo(
&self,
command: &str,
sender: Sender<CommandOutput>,
sudo_password: &SudoPassword,
) -> Result<u32, Error>
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 withsudo)sender- Channel sender for streaming outputsudo_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
Sourcepub async fn execute(
&self,
command: &str,
) -> Result<CommandExecutedResult, Error>
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.
Sourcepub async fn request_interactive_shell(
&self,
_term_type: &str,
_width: u32,
_height: u32,
) -> Result<Channel<Msg>, Error>
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:
- Requesting PTY with proper terminal modes via
channel.request_pty() - 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§impl Client
impl Client
Sourcepub async fn connect(
addr: impl ToSocketAddrsWithHostname,
username: &str,
auth: AuthMethod,
server_check: ServerCheckMethod,
) -> Result<Self, Error>
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.
Sourcepub async fn connect_with_ssh_config(
addr: impl ToSocketAddrsWithHostname,
username: &str,
auth: AuthMethod,
server_check: ServerCheckMethod,
ssh_config: &SshConnectionConfig,
) -> Result<Self, Error>
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(())
}Sourcepub async fn connect_with_config(
addr: impl ToSocketAddrsWithHostname,
username: &str,
auth: AuthMethod,
server_check: ServerCheckMethod,
config: Config,
) -> Result<Self, Error>
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.
Sourcepub fn from_handle_and_address(
handle: Arc<Handle<ClientHandler>>,
username: String,
address: SocketAddr,
) -> Self
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.
Sourcepub fn get_connection_username(&self) -> &String
pub fn get_connection_username(&self) -> &String
A debugging function to get the username this client is connected as.
Sourcepub fn get_connection_address(&self) -> &SocketAddr
pub fn get_connection_address(&self) -> &SocketAddr
A debugging function to get the address this client is connected to.
Sourcepub async fn disconnect(&self) -> Result<(), Error>
pub async fn disconnect(&self) -> Result<(), Error>
Disconnect from the remote host.
Sourcepub async fn request_port_forward(
&self,
_bind_address: String,
_bind_port: u32,
) -> Result<u32, Error>
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)
Sourcepub async fn cancel_port_forward(
&self,
_bind_address: String,
_bind_port: u32,
) -> Result<(), Error>
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 serverbind_port- Port that was bound on the remote server
Source§impl Client
impl Client
Sourcepub async fn upload_file<T: AsRef<Path>, U: Into<String>>(
&self,
src_file_path: T,
dest_file_path: U,
) -> Result<(), Error>
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.
Sourcepub async fn download_file<T: AsRef<Path>, U: Into<String>>(
&self,
remote_file_path: U,
local_file_path: T,
) -> Result<(), Error>
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.
Sourcepub async fn upload_dir<T: AsRef<Path>, U: Into<String>>(
&self,
local_dir_path: T,
remote_dir_path: U,
) -> Result<(), Error>
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.
Sourcepub async fn download_dir<T: AsRef<Path>, U: Into<String>>(
&self,
remote_dir_path: U,
local_dir_path: T,
) -> Result<(), Error>
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§
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> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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 moreSource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::RequestSource§impl<D> OwoColorize for D
impl<D> OwoColorize for D
Source§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
Source§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
Source§fn black(&self) -> FgColorDisplay<'_, Black, Self>
fn black(&self) -> FgColorDisplay<'_, Black, Self>
Source§fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
Source§fn red(&self) -> FgColorDisplay<'_, Red, Self>
fn red(&self) -> FgColorDisplay<'_, Red, Self>
Source§fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
Source§fn green(&self) -> FgColorDisplay<'_, Green, Self>
fn green(&self) -> FgColorDisplay<'_, Green, Self>
Source§fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
Source§fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
Source§fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
Source§fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
Source§fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
Source§fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
Source§fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
Source§fn white(&self) -> FgColorDisplay<'_, White, Self>
fn white(&self) -> FgColorDisplay<'_, White, Self>
Source§fn on_white(&self) -> BgColorDisplay<'_, White, Self>
fn on_white(&self) -> BgColorDisplay<'_, White, Self>
Source§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
Source§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
Source§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
Source§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
Source§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
Source§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
Source§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
Source§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
Source§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
Source§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
Source§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
Source§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
Source§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
Source§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
Source§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
Source§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
Source§fn bold(&self) -> BoldDisplay<'_, Self>
fn bold(&self) -> BoldDisplay<'_, Self>
Source§fn dimmed(&self) -> DimDisplay<'_, Self>
fn dimmed(&self) -> DimDisplay<'_, Self>
Source§fn italic(&self) -> ItalicDisplay<'_, Self>
fn italic(&self) -> ItalicDisplay<'_, Self>
Source§fn underline(&self) -> UnderlineDisplay<'_, Self>
fn underline(&self) -> UnderlineDisplay<'_, Self>
Source§fn blink(&self) -> BlinkDisplay<'_, Self>
fn blink(&self) -> BlinkDisplay<'_, Self>
Source§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
Source§fn reversed(&self) -> ReversedDisplay<'_, Self>
fn reversed(&self) -> ReversedDisplay<'_, Self>
Source§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
Source§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg or
a color-specific method, such as OwoColorize::green, Read moreSource§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg or
a color-specific method, such as OwoColorize::on_yellow, Read more