fix(ssh): linear host-pattern matching, per-hop forwarding gates, loopback remote forwards
- known_hosts: the @cert-authority pattern matcher was recursive and backtracking; a pattern of a few hundred thousand stars overflowed the connect thread's stack on every handshake and '*a*a*a…b' went exponential. It is now the iterative two-pointer match, and patterns over 1 KiB are refused on import and in Trust a CA. - Agent-forward and remote-forward channels are only honoured on the final hop: a jump host could previously open auth-agent channels and reach remote-forward destinations on the client machine. - Remote forwards with no bind address listen on the server's loopback (as ssh -R does) instead of every interface. - Keyboard-interactive gives up after 10 rounds; dials through jump hosts and run_command have timeouts; the handshake timeout leaves room for the host-key prompt so a slow reader isn't timed out mid-decision. - Known hosts are looked up per key type, so an imported known_hosts with ed25519 and RSA rows no longer produces a false 'key changed' warning. - SFTP download suggests a sanitised base name in the save dialog.
This commit is contained in:
@@ -393,7 +393,9 @@ impl Sftp {
|
||||
|
||||
fn download(&mut self, s: &Shared, session: &str, files: Vec<FileEntry>) {
|
||||
let targets: Vec<(FileEntry, PathBuf)> = if files.len() == 1 {
|
||||
let Some(p) = rfd::FileDialog::new().set_file_name(&files[0].name).save_file() else {
|
||||
// The name comes from the server: keep only a safe base name for the dialog's default.
|
||||
let suggested = safe_sftp_upload_name(&files[0].name).unwrap_or_else(|_| "download".into());
|
||||
let Some(p) = rfd::FileDialog::new().set_file_name(suggested).save_file() else {
|
||||
return;
|
||||
};
|
||||
vec![(files[0].clone(), p)]
|
||||
|
||||
Reference in New Issue
Block a user