Skip to content

v1.5.2

Choose a tag to compare

@gregorkrebs gregorkrebs released this 27 Jul 20:51
· 23 commits to main since this release
b1504bb

Added

  • Windows installer (installer/NeoSSHWinManager.iss, built with Inno Setup 6): a proper Setup.exe alongside the existing standalone executables, with a setup wizard offering desktop shortcut and "start with Windows" tasks, an optional CLI component (NeoSSHWinManager-cli.exe can be excluded via a Compact install), and an app-preferences page to pre-select the application's language and dark/light theme before first launch. The installer's own UI is available in English, German, Spanish, Russian and Dutch. Preferences chosen in the wizard are written to install_prefs.json and applied by AuthManager.register() when the first local user account is created, instead of the hardcoded en/dark defaults.
  • CLI companion executable restored: NeoSSHWinManager-cli.exe (console subsystem, cli_main.py) is back in the build (NeoSSHWinManager-cli.spec, build_dual.ps1) after being dropped from distribution in 1.5.1. Lets a saved connection with CLI access enabled be reached non-interactively via NeoSSHWinManager-cli.exe --connect-cli <access_key> [--exec "command"] while the main GUI is running and logged in. The GUI's own build stays a standalone onefile executable, unaffected.
  • FTP and FTPS support: Connections now carry a protocol (SFTP / FTPS / FTP). The file browser speaks all three — the new src/ftp_client.py implements FTP over ftplib with explicit TLS (AUTH TLS, port 21), implicit TLS (port 990) and plain unencrypted FTP, MLSD listings with a LIST fallback for older servers, passive/active mode, progress-reporting up- and downloads and automatic re-login after an idle timeout.
  • Add/Edit form gained a protocol selector plus FTP options (implicit TLS, passive mode, certificate verification); the port follows the protocol default (22 / 21 / 990) unless a custom port was entered, and SSH-only fields (key file, drive letter, CLI access, PuTTY key) are hidden for FTP connections.
  • Plain-FTP connections can be handed to the on-board Windows Explorer FTP client from the card context menu (the password stays out of the URL — Explorer asks for it).

Changed

  • FTP/FTPS connections cannot be mounted as a drive and have no SSH terminal: their card shows a protocol badge and opens the file browser, and mount/terminal/system-info actions report that they are unavailable instead of failing later.
  • Database migrations now run each ALTER TABLE independently, so one column that SQLite refuses (e.g. adding a UNIQUE column to an old table) no longer silently skips every migration after it.

Fixed

  • SSHFS write corruption: Files could end up as pure NUL bytes after writing/overwriting through a mounted drive. Caused by FileInfoTimeout=-1, which turns on WinFsp's write-back file data caching; a hard-killed sshfs.exe (e.g. on unmount) could drop not-yet-flushed pages and leave the server-side zero-fill in place. Mounts now use a finite FileInfoTimeout, synchronous SFTP writes (sshfs_sync) and disabled read-ahead (no_readahead) instead.
  • New folders/files invisible until refresh: sshfs.exe carries its own directory-entry cache (dir_cache/dcache_dir_timeout, default 20s) entirely separate from — and underneath — the WinFsp-side cache timeouts this app already sets, so the existing "disable directory cache" setting never fully applied. Mounts now also tune the sshfs-side cache (fully disabled when that setting is on, tightened to match otherwise).
  • "New Folder"/new file silently duplicated 4x in Explorer: on a mounted drive, creating an item in Windows Explorer could appear to fail (no rename prompt) and then show up to 4 times after a manual refresh. Root cause is an upstream WinFsp/Windows security-token mismatch (TokenUser vs TokenOwner) that only affects the built-in Administrator account when UAC Admin Approval Mode is disabled for it (Windows' default for that account) — not fixable from the app's mount options. Documented for anyone else hitting it: enable "User Account Control: Admin Approval Mode for the Built-in Administrator account" (secpol.msc or FilterAdministratorToken=1) and log back in.
  • Startup crash after fixing the account-token issue above: files created earlier under the affected account end up owned by the BUILTIN\Administrators group instead of the user; once that account's token no longer carries the group, the app's own permission-hardening (SetFileSecurity) started failing with access denied and crashing startup. That call is now best-effort (logs a warning instead of crashing), and the app now detects this exact ownership mismatch on its own at startup and offers a one-time, UAC-elevated automatic repair (src/permission_repair.py) — so anyone hitting this after an update or reinstall gets a guided fix instead of a crash.
  • CLI access key could never match, for any connection: get_by_cli_key() re-encrypted the incoming key with a fresh random AES-GCM IV and compared the result against the stored ciphertext — which uses a different random IV from when the key was originally saved, so the comparison could never succeed even for the correct key. Lookup now uses a deterministic cli_access_key_hash (SHA-256 of the plaintext key) instead; existing connections get this hash backfilled automatically on next login.
  • CLI SSH connections always rejected: launch_ssh_in_current_terminal() (used by --connect-cli) set a RejectPolicy host-key policy but never actually loaded known_hosts into paramiko first, so every connection was rejected as "unknown host" regardless of what was already trusted on disk. Now loads the same known_hosts file the rest of the app uses before checking the policy.
  • Embedded terminal froze the whole window while connecting: opening an SSH session in the integrated xterm.js terminal (terminal_client setting = "xterm") called TerminalBridgeServer.create_session_token() — which runs a blocking paramiko.SSHClient.connect() — directly on the Qt main thread. A slow or unresponsive host could freeze the entire UI for the length of paramiko's auth timeout (30s by default) on top of the connect timeout. Connection setup now runs in a background TerminalConnectWorker (src/ui/worker.py), matching the existing MountWorker/UnmountWorker pattern; the tab is only created once the SSH session is actually up.

Security

  • CLI access over --connect-cli now also works for password-authenticated connections: the local IPC response includes the password (previously withheld per an earlier finding). The pipe was already restricted to the current user's SID (_make_pipe_security_attributes), the 64-byte access key itself is a strong bearer secret, and requests are already rate-limited per PID — sending the password over this already-restricted channel was the missing piece for a CLI feature whose whole purpose is unattended access to saved connections, not an added exposure.

Full Changelog: v1.5.1...v1.5.2