From 053cb11e9f4f2a860f7d478f05d4c8015caae158 Mon Sep 17 00:00:00 2001 From: Wez Furlong Date: Sat, 24 Apr 2021 21:56:32 -0700 Subject: [PATCH] improve ssh domain support for ssh_config This tidies up how we pass the ssh config to the connection ui logic, by moving the ssh_config setup to the two callers. A couple of notable adjustments: * SshDomain::username is now optional; it will default to the values computed by the ssh config file loader * no_agent_auth value wasn't hooked up to anything, but now it is refs: https://github.com/wez/wezterm/issues/730 --- config/src/ssh.rs | 2 +- mux/src/ssh.rs | 27 +++---------------- wezterm-client/src/client.rs | 50 +++++++++++++++++++++++++++++++----- wezterm-client/src/domain.rs | 6 ++++- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/config/src/ssh.rs b/config/src/ssh.rs index aebbf9fe0..5d4307628 100644 --- a/config/src/ssh.rs +++ b/config/src/ssh.rs @@ -16,7 +16,7 @@ pub struct SshDomain { pub no_agent_auth: bool, /// The username to use for authenticating with the remote host - pub username: String, + pub username: Option, /// If true, connect to this domain automatically at startup #[serde(default)] diff --git a/mux/src/ssh.rs b/mux/src/ssh.rs index b84553c89..e0ab1e349 100644 --- a/mux/src/ssh.rs +++ b/mux/src/ssh.rs @@ -52,33 +52,14 @@ impl LineEditorHost for PasswordPromptHost { } pub fn ssh_connect_with_ui( - remote_address: &str, - username: Option<&str>, + ssh_config: wezterm_ssh::ConfigMap, ui: &mut ConnectionUI, ) -> anyhow::Result { let cloned_ui = ui.clone(); cloned_ui.run_and_log_error(move || { - let mut ssh_config = wezterm_ssh::Config::new(); - ssh_config.add_default_config_files(); - - let (remote_host_name, port) = { - let parts: Vec<&str> = remote_address.split(':').collect(); - - if parts.len() == 2 { - (parts[0], Some(parts[1].parse::()?)) - } else { - (remote_address, None) - } - }; - - let mut ssh_config = ssh_config.for_host(&remote_host_name); - if let Some(username) = username { - ssh_config.insert("user".to_string(), username.to_string()); - } - if let Some(port) = port { - ssh_config.insert("port".to_string(), port.to_string()); - } - + let remote_address = ssh_config + .get("hostname") + .expect("ssh config to always set hostname"); ui.output_str(&format!("Connecting to {} using SSH\n", remote_address)); let (session, events) = Session::connect(ssh_config.clone())?; diff --git a/wezterm-client/src/client.rs b/wezterm-client/src/client.rs index 612db8be8..875b478c3 100644 --- a/wezterm-client/src/client.rs +++ b/wezterm-client/src/client.rs @@ -427,7 +427,31 @@ impl Reconnectable { initial: bool, ui: &mut ConnectionUI, ) -> anyhow::Result<()> { - let sess = ssh_connect_with_ui(&ssh_dom.remote_address, Some(&ssh_dom.username), ui)?; + let mut ssh_config = wezterm_ssh::Config::new(); + ssh_config.add_default_config_files(); + + let (remote_host_name, port) = { + let parts: Vec<&str> = ssh_dom.remote_address.split(':').collect(); + + if parts.len() == 2 { + (parts[0], Some(parts[1].parse::()?)) + } else { + (ssh_dom.remote_address.as_str(), None) + } + }; + + let mut ssh_config = ssh_config.for_host(&remote_host_name); + if let Some(username) = &ssh_dom.username { + ssh_config.insert("user".to_string(), username.to_string()); + } + if let Some(port) = port { + ssh_config.insert("port".to_string(), port.to_string()); + } + if ssh_dom.no_agent_auth { + ssh_config.insert("identitiesonly".to_string(), "yes".to_string()); + } + + let sess = ssh_connect_with_ui(ssh_config, ui)?; let proxy_bin = Self::wezterm_bin_path(&ssh_dom.remote_wezterm_path); let cmd = if initial { @@ -579,11 +603,25 @@ impl Reconnectable { if let Some(Ok(ssh_params)) = tls_client.ssh_parameters() { if self.tls_creds.is_none() { // We need to bootstrap via an ssh session - let sess = ssh_connect_with_ui( - &ssh_params.host_and_port, - ssh_params.username.as_ref().map(|s| s.as_str()), - ui, - )?; + + let mut ssh_config = wezterm_ssh::Config::new(); + ssh_config.add_default_config_files(); + + let mut fields = ssh_params.host_and_port.split(':'); + let host = fields + .next() + .ok_or_else(|| anyhow::anyhow!("no host component somehow"))?; + let port = fields.next(); + + let mut ssh_config = ssh_config.for_host(host); + if let Some(username) = &ssh_params.username { + ssh_config.insert("user".to_string(), username.to_string()); + } + if let Some(port) = port { + ssh_config.insert("port".to_string(), port.to_string()); + } + + let sess = ssh_connect_with_ui(ssh_config, ui)?; let creds = ui.run_and_log_error(|| { // The `tlscreds` command will start the server if needed and then diff --git a/wezterm-client/src/domain.rs b/wezterm-client/src/domain.rs index a48419a30..a03447d38 100644 --- a/wezterm-client/src/domain.rs +++ b/wezterm-client/src/domain.rs @@ -129,7 +129,11 @@ impl ClientDomainConfig { ClientDomainConfig::Unix(unix) => format!("unix mux {}", unix.socket_path().display()), ClientDomainConfig::Tls(tls) => format!("TLS mux {}", tls.remote_address), ClientDomainConfig::Ssh(ssh) => { - format!("SSH mux {}@{}", ssh.username, ssh.remote_address) + if let Some(user) = &ssh.username { + format!("SSH mux {}@{}", user, ssh.remote_address) + } else { + format!("SSH mux {}", ssh.remote_address) + } } } }