From 7425ae4b49343c287616daaeeb2ac69eb5bad949 Mon Sep 17 00:00:00 2001 From: Lorenz Leutgeb Date: Sat, 14 Feb 2026 14:10:51 +0100 Subject: [PATCH] ssh: Treat "connection refused" on Windows Slightly relax the conditions under which an error is considered to indicate that the SSH agent is not running, to accommodate differences in the API of named pipes on Windows vs. Unix domain sockets. --- crates/radicle-ssh/src/agent/client.rs | 45 +++++++++++++++----------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/crates/radicle-ssh/src/agent/client.rs b/crates/radicle-ssh/src/agent/client.rs index 6cc2c8eb..ffc1fa47 100644 --- a/crates/radicle-ssh/src/agent/client.rs +++ b/crates/radicle-ssh/src/agent/client.rs @@ -52,7 +52,20 @@ pub enum Error { impl Error { pub fn is_not_running(&self) -> bool { - matches!(self, Self::EnvVar { .. } | Self::BadAuthSock { .. }) + match self { + Self::EnvVar { .. } | Self::BadAuthSock { .. } => true, + #[cfg(windows)] + Self::Connect { source, .. } + if source.kind() == std::io::ErrorKind::ConnectionRefused => + { + // On Windows, a named pipe might be used, and if no + // agent is running, we might get a "connection refused" + // error, even though the `SSH_AUTH_SOCK` environment + // variable is set and the named pipe exists. + true + } + _ => false, + } } } @@ -104,24 +117,20 @@ impl AgentClient { pub fn connect_env() -> Result { const SSH_AUTH_SOCK: &str = "SSH_AUTH_SOCK"; - let path = match std::env::var(SSH_AUTH_SOCK) { - Ok(var) => var, - Err(err) => { - if cfg!(windows) { - // Windows uses a named pipe for the SSH agent, which - // we fall back to in case reading the environment - // variable fails. - "\\\\.\\pipe\\openssh-ssh-agent".to_string() - } else { - return Err(Error::EnvVar { - var: SSH_AUTH_SOCK.to_string(), - source: err, - }); - } - } - }; + let var = std::env::var(SSH_AUTH_SOCK); - Self::connect(path) + #[cfg(windows)] + let var = var.or({ + // Windows uses a named pipe for the SSH agent, which + // we fall back to in case reading the environment + // variable fails. + Ok(r"\\.\pipe\openssh-ssh-agent".to_string()) + }); + + Self::connect(var.map_err(|err| Error::EnvVar { + var: SSH_AUTH_SOCK.to_string(), + source: err, + })?) } }