diff --git a/config/src/lib.rs b/config/src/lib.rs index 1367a277d..99671f78f 100644 --- a/config/src/lib.rs +++ b/config/src/lib.rs @@ -898,6 +898,9 @@ pub struct Config { #[serde(default)] pub ssh_domains: Vec, + #[serde(default)] + pub ssh_backend: SshBackend, + /// When running in server mode, defines configuration for /// each of the endpoints that we'll listen for connections #[serde(default)] diff --git a/config/src/ssh.rs b/config/src/ssh.rs index 5d4307628..162696884 100644 --- a/config/src/ssh.rs +++ b/config/src/ssh.rs @@ -2,6 +2,19 @@ use crate::*; use std::fmt::Display; use std::str::FromStr; +#[derive(Debug, Clone, Copy, Deserialize, Serialize)] +pub enum SshBackend { + Ssh2, + LibSsh, +} +impl_lua_conversion!(SshBackend); + +impl Default for SshBackend { + fn default() -> Self { + Self::LibSsh + } +} + #[derive(Default, Debug, Clone, Deserialize, Serialize)] pub struct SshDomain { /// The name of this specific domain. Must be unique amongst @@ -27,6 +40,8 @@ pub struct SshDomain { /// The path to the wezterm binary on the remote host pub remote_wezterm_path: Option, + + pub ssh_backend: Option, } impl_lua_conversion!(SshDomain); diff --git a/docs/changelog.md b/docs/changelog.md index f5810e327..d8692b212 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -26,6 +26,7 @@ As features stabilize some brief notes about them will accumulate here. * [wezterm.background_child_process](config/lua/wezterm/background_child_process.md) function to spawn a process without waiting. * [mux_env_remove](config/lua/config/mux_env_remove.md) setting to control which environment variables should be cleared prior to spawning processes in the multiplexer server [#1225](https://github.com/wez/wezterm/issues/1225) * [canonicalize_pasted_newlines](config/lua/config/canonicalize_pasted_newlines.md) option to help Windows users manage newlines in pastes [#1213](https://github.com/wez/wezterm/issues/1213) +* SSH client now uses `libssh` by default. [ssh_backend](config/lua/config/ssh_backend.md) can be used to change this. #### Changed diff --git a/docs/config/lua/config/ssh_backend.md b/docs/config/lua/config/ssh_backend.md new file mode 100644 index 000000000..79730ff83 --- /dev/null +++ b/docs/config/lua/config/ssh_backend.md @@ -0,0 +1,18 @@ +# ssh_backend = "libssh" + +*Since: nightly builds only* + +Sets which ssh backend should be used by default for the integrated ssh client. + +Possible values are: + +* `"Ssh2"` - use libssh2 +* `"LibSsh"` - use libssh + +Despite the naming, `libssh2` is not a newer version of `libssh`, they are +completely separate ssh implementations. + +In prior releases, `"Ssh2"` was the only option. `"LibSsh"` is the default +as it has broader support for newer keys and cryptography, and has clearer +feedback about authentication events that require entering a passphrase. + diff --git a/wezterm-client/src/client.rs b/wezterm-client/src/client.rs index 979402e54..f25fa4a9d 100644 --- a/wezterm-client/src/client.rs +++ b/wezterm-client/src/client.rs @@ -5,7 +5,7 @@ use anyhow::{anyhow, bail, Context}; use async_ossl::AsyncSslStream; use async_trait::async_trait; use codec::*; -use config::{configuration, SshDomain, TlsDomainClient, UnixDomain}; +use config::{configuration, SshBackend, SshDomain, TlsDomainClient, UnixDomain}; use filedescriptor::FileDescriptor; use futures::FutureExt; use mux::connui::ConnectionUI; @@ -446,6 +446,18 @@ impl Reconnectable { }; let mut ssh_config = ssh_config.for_host(&remote_host_name); + ssh_config.insert( + "wezterm_ssh_backend".to_string(), + match ssh_dom + .ssh_backend + .unwrap_or_else(|| configuration().ssh_backend) + { + SshBackend::Ssh2 => "ssh2", + SshBackend::LibSsh => "libssh", + } + .to_string(), + ); + if let Some(username) = &ssh_dom.username { ssh_config.insert("user".to_string(), username.to_string()); } diff --git a/wezterm-gui/src/main.rs b/wezterm-gui/src/main.rs index afa5905d9..1bea10318 100644 --- a/wezterm-gui/src/main.rs +++ b/wezterm-gui/src/main.rs @@ -4,6 +4,7 @@ use crate::frontend::front_end; use ::window::*; use anyhow::anyhow; +use config::SshBackend; use mux::activity::Activity; use mux::domain::{Domain, LocalDomain}; use mux::Mux; @@ -94,6 +95,8 @@ enum SubCommand { } async fn async_run_ssh(opts: SshCommand) -> anyhow::Result<()> { + let config = config::configuration(); + let mut ssh_config = Config::new(); ssh_config.add_default_config_files(); @@ -104,6 +107,15 @@ async fn async_run_ssh(opts: SshCommand) -> anyhow::Result<()> { let port = fields.next(); let mut ssh_config = ssh_config.for_host(host); + ssh_config.insert( + "wezterm_ssh_backend".to_string(), + match config.ssh_backend { + SshBackend::Ssh2 => "ssh2", + SshBackend::LibSsh => "libssh", + } + .to_string(), + ); + if let Some(username) = &opts.user_at_host_and_port.username { ssh_config.insert("user".to_string(), username.to_string()); } @@ -123,7 +135,6 @@ async fn async_run_ssh(opts: SshCommand) -> anyhow::Result<()> { None }; - let config = config::configuration(); let domain: Arc = Arc::new(mux::ssh::RemoteSshDomain::with_ssh_config( &opts.user_at_host_and_port.to_string(), ssh_config,