mirror of
https://github.com/veeso/termscp.git
synced 2025-12-06 09:05:36 -08:00
Fix SSH auth with id keys (#347)
I fixed the id_rsa/id_ed25519 SSH auth issue on Mac and now termscp should respect the key-based authentication, just like the regular ssh user@hostname, without the need for any ssh agents. --- Co-authored-by: Lucas Czekaj <lukasz@czekaj.us>
This commit is contained in:
committed by
GitHub
parent
783da22ca2
commit
81ae0035c3
@@ -46,6 +46,7 @@
|
||||
Released on 31/07/2025
|
||||
|
||||
- **Updated dependencies** and updated the Rust edition to `2024`
|
||||
- [Issue 345](https://github.com/veeso/termscp/issues/345): Default keys are used from `~/.ssh` directory if no keys are resolved for the host.
|
||||
|
||||
## 0.17.0
|
||||
|
||||
|
||||
4
dist/build/macos.sh
vendored
4
dist/build/macos.sh
vendored
@@ -81,7 +81,7 @@ fi
|
||||
# Build release (x86_64)
|
||||
X86_TARGET=""
|
||||
X86_TARGET_DIR=""
|
||||
if [ "$ARCH" = "aarch64" ]; then
|
||||
if [ "$ARCH" = "x86_64" ]; then
|
||||
X86_TARGET="--target x86_64-apple-darwin"
|
||||
X86_TARGET_DIR="target/x86_64-apple-darwin/release/"
|
||||
fi
|
||||
@@ -92,7 +92,7 @@ RET_X86_64=$?
|
||||
|
||||
ARM64_TARGET=""
|
||||
ARM64_TARGET_DIR=""
|
||||
if [ "$ARCH" = "aarch64" ]; then
|
||||
if [ "$ARCH" = "aarch64" ] || [ "$ARCH" = "arm64" ]; then
|
||||
ARM64_TARGET="--target aarch64-apple-darwin"
|
||||
ARM64_TARGET_DIR="target/aarch64-apple-darwin/release/"
|
||||
fi
|
||||
|
||||
@@ -233,8 +233,12 @@ impl RemoteFsBuilder {
|
||||
debug!("no username was provided, using current username");
|
||||
opts = opts.username(whoami::username());
|
||||
}
|
||||
// For SSH protocols, only set password if explicitly provided and non-empty.
|
||||
// This allows the SSH library to prioritize key-based and agent authentication.
|
||||
if let Some(password) = params.password {
|
||||
opts = opts.password(password);
|
||||
if !password.is_empty() {
|
||||
opts = opts.password(password);
|
||||
}
|
||||
}
|
||||
if let Some(config_path) = config_client.get_ssh_config() {
|
||||
opts = opts.config_file(
|
||||
|
||||
@@ -50,6 +50,23 @@ impl SshKeyStorage {
|
||||
.and_then(|x| x.first().cloned())
|
||||
})
|
||||
}
|
||||
|
||||
/// Get default SSH identity files that SSH would normally try
|
||||
/// This mirrors the behavior of OpenSSH client
|
||||
fn get_default_identity_files(&self) -> Vec<PathBuf> {
|
||||
let Some(home_dir) = dirs::home_dir() else {
|
||||
return Vec::new();
|
||||
};
|
||||
|
||||
let ssh_dir = home_dir.join(".ssh");
|
||||
|
||||
// Standard SSH identity files in order of preference (matches OpenSSH)
|
||||
["id_ed25519", "id_ecdsa", "id_rsa", "id_dsa"]
|
||||
.iter()
|
||||
.map(|key_name| ssh_dir.join(key_name))
|
||||
.filter(|key_path| key_path.exists())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl SshKeyStorageTrait for SshKeyStorage {
|
||||
@@ -63,9 +80,13 @@ impl SshKeyStorageTrait for SshKeyStorage {
|
||||
username, host
|
||||
);
|
||||
// otherwise search in configuration
|
||||
let key = self.resolve_host_in_ssh2_configuration(host)?;
|
||||
debug!("Found key in SSH config for {host}: {}", key.display());
|
||||
Some(key)
|
||||
if let Some(key) = self.resolve_host_in_ssh2_configuration(host) {
|
||||
debug!("Found key in SSH config for {host}: {}", key.display());
|
||||
return Some(key);
|
||||
}
|
||||
|
||||
// As a final fallback, try default SSH identity files (like regular ssh does)
|
||||
self.get_default_identity_files().into_iter().next()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,8 +155,14 @@ mod tests {
|
||||
*storage.resolve("192.168.1.31", "pi").unwrap(),
|
||||
exp_key_path
|
||||
);
|
||||
// Verify unexisting key
|
||||
assert!(storage.resolve("deskichup", "veeso").is_none());
|
||||
// Verify key is a default key or none
|
||||
let default_keys: Vec<PathBuf> = storage.get_default_identity_files().into_iter().collect();
|
||||
|
||||
if let Some(key) = storage.resolve("deskichup", "veeso") {
|
||||
assert!(default_keys.contains(&key));
|
||||
} else {
|
||||
assert!(default_keys.is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user