Commit Graph
38 Commits
Author SHA1 Message Date
Andy Dixon bd1dc54e20 fix: validate Quick Connect and ~/.ssh/config imports; unknown enum values no longer reset a profile's config
- Quick Connect runs the same validation as saved profiles, so an SSH
  connection without a username fails up front with a clear message (F5).
- ~/.ssh/config imports fill a missing User (and jump-host user) with the
  local user name, as ssh does, and skip blocks that still don't validate,
  reporting how many (F6).
- An unrecognised hostKeyPolicy/lineEnding/parity/flowControl/direction in
  a stored config falls back to that field's default instead of failing
  the whole JSON column and silently resetting every other setting; parse
  failures that remain are logged (F7).
2026-10-12 09:19:03 +01:00
Andy Dixon 3b490fa6c3 fix: redact scripted login passwords from secret-free exports; secret kinds are an enum
- A JSON export without secrets now blanks login-script 'send' steps that
  answer a password-like 'wait' prompt (SSH and Telnet), not just the
  proxy password and inline TOTP seed (SEC-20261012-011, partial).
- Credential kinds were string literals in the session manager, profile
  editor and secret store; they are now SecretKind with one ALL list, so
  the profile-delete purge can't miss a kind (F19).

Moving proxyPassword out of the profile record is left open: it changes
.link/.nexus compatibility with the Go app and needs an owner decision.
2026-10-12 09:16:14 +01:00
Andy Dixon 3843351365 fix: the vault checks the master password even when it holds no secrets
An empty vault accepted any password, so a typo at the first unlock
encrypted later secrets under the wrong key. New vaults store a verifier
(a known value sealed under the key) that every unlock must open. Vaults
from Go or older builds keep today's behaviour and gain a verifier on
their next write; Go ignores the extra field (SEC-20261012-016, F8).
2026-10-12 09:13:34 +01:00
Andy Dixon 4d6595588b fix: bound IRC state, read recording metadata from the file tail, cap the audit log
- IRC: channel state is kept only for rooms the client itself joined, so
  JOIN/PART/KICK/NAMES for other rooms can't grow it; users per channel
  are capped at 10 000 and the view keeps at most 200 conversations,
  dropping the oldest idle query (SEC-20261012-014, F14).
- Recordings: the list reads the header line and the last 64 KiB for the
  duration instead of whole files of up to 250 MiB, falling back to a
  full scan only when the final event is longer than the window
  (SEC-20261012-020, F9).
- Audit log: keeps the newest 10 000 entries (F17).
2026-10-12 09:12:25 +01:00
Andy Dixon f09300fd95 fix: a panic on one thread no longer takes the whole app down
Every shared lock was std::sync::Mutex with lock().unwrap() (~150 sites),
so a panic in any session's reader or callback poisoned the lock and the
next UI frame panicked too, dropping every open session. Locks are now
parking_lot::Mutex (no poisoning; already in the dependency tree), and a
panic hook reports worker panics as an error toast instead of the session
silently stopping (F3, F4).
2026-10-12 09:07:32 +01:00
Andy Dixon afec95bb36 fix: save typed credentials only after the connection succeeds, and re-ask when a saved one is rejected
A password typed at a 'saved' prompt was stored before the server
accepted it, so a typo was persisted and silently retried on every
reconnect. Typed values are now held per attempt and written once the
session connects; when the server refuses a saved credential the next
attempt asks again and the new value replaces it on success. A store
failure (keychain refused, vault locked) now shows a toast instead of
being swallowed, and reconnect prompts wait 5 minutes like the first
connect (SEC-20261012-015, F1, F2, F20).
2026-10-12 09:02:43 +01:00
Andy Dixon 534310b56d feat: preferences for remote clipboard writes, multi-line paste confirmation and the launch update check
OSC 52 and VNC ServerCutText now go through one handler that honours
'allow remote clipboard' and always toasts the first line, so a silent
clipboard swap can't set up a paste into another shell (SEC-20261012-010).
Multi-line pastes into a terminal without bracketed paste ask first, with a
preview (SEC-20261012-017). The launch-time update check can be turned off
and the updater docs no longer claim it is opt-in; the unused GitHub
fallback is removed (SEC-20261012-013, F15).
2026-10-12 08:57:30 +01:00
Andy Dixon 33b17223aa feat: changed host keys can be rejected, accepted once, or accepted and updated
Under the 'ask' policy a changed host key used to be a hard error. The
prompt now shows the stored and received fingerprints and offers Reject,
Accept Once (connect, keep the record) and Accept & Update (replace the
record; audited). Unknown keys gain an Accept Once option too. Strict and
accept-new still refuse changed keys without prompting. Known-host rows
written by the old app are confirmed removable by id (test).
2026-10-12 08:19:41 +01:00
Andy Dixon 17a5b4fbb5 fix: keep session-only credentials across reconnects so NickServ re-identifies without re-prompting
The NickServ password (and any other "remember for this session" secret) was
resolved through a fresh per-connect cache, so every auto-reconnect prompted
again with a 60 s timeout and an unanswered prompt failed the reconnect.
Session-only secrets now live on the session, survive auto and explicit
reconnects, and IDENTIFY is sent on every registration as before.
2026-10-12 07:53:03 +01:00
Andy Dixon aac986d78b fix: bound VNC server-announced sizes and only open http(s) links from network data
- The VNC client refuses desktop sizes over 64 Mpx (ServerInit and
  DesktopSize/ExtendedDesktopSize) and ZRLE rectangles over 64 MiB before
  allocating, so a hostile server can't force a multi-gigabyte allocation.
- Release URLs from the update manifest and repository URLs from the GitHub
  API are handed to the system opener only when they are http(s) links.
2026-10-12 07:23:40 +01:00
Andy Dixon 0a18f7e578 fix: generate SSH keys in-process, verify loopback tunnel peer, bound SSH command output
- SSH key pairs are generated with ssh-key (Ed25519/ECDSA P-256/RSA) and
  encrypted in-process, so the passphrase no longer appears as an ssh-keygen
  command-line argument visible in the process list.
- open_tunnel's loopback bridge checks the accepted peer is our own client
  socket, so a local process racing for the ephemeral port can't be spliced
  into the IRC/VNC SSH tunnel.
- run_command caps buffered output at 1 MiB; local-forward abort handles are
  pruned as connections finish; SOCKS5 host/credential lengths over 255 bytes
  are rejected instead of being truncated into a malformed request.
2026-10-12 07:22:31 +01:00
Andy Dixon 9cf221779b fix: purge keychain credentials on profile delete, atomic owner-only secret writes, zeroize derived keys
- Secrets::delete_profile removes every profile credential kind from the OS
  keychain as well as the vault (previously only the vault was purged, so
  keychain passwords/tokens outlived the profile).
- write_private writes to a sibling temp file and renames it into place, so a
  crash mid-write cannot truncate the vault or an export, and a pre-existing
  world-readable file is replaced rather than reused.
- Argon2-derived vault/export keys are Zeroizing and wiped on drop.
- Recordings (which capture typed input), JSON exports and --data-dir
  directories are created owner-only.
2026-10-12 07:20:11 +01:00
Andy Dixon ce9c5c6b44 Screenshot automation (--connect repeatable, --do, --answer, --shot-delay), SFTP Browser palette entry, centred dialogs, IRC opens the first joined room; demo_data example 2026-10-11 19:41:30 +01:00
Andy Dixon 84eff02c15 Move update and release URLs to dixon.cx/downloads/nexus 2026-10-11 19:06:48 +01:00
Andy Dixon 7b92b81ecd Serial/Telnet Send Break and DTR/RTS tab controls; fix Help and hints; drop unused log path; docs 2026-10-11 17:54:11 +01:00
Andy Dixon 1c16079584 Remove the Go backend, JS frontend, Wails config and old build scripts; release.sh now wraps rust/release.sh 2026-10-11 17:43:55 +01:00
Andy Dixon e1707e4751 rust: VNC remote clipboard to the local clipboard 2026-10-11 17:43:35 +01:00
Andy Dixon 2bb12c3a58 rust: merge UI feature modules; fix Ctrl+key on Linux/Windows (egui command_only shadowing); clippy clean; rustfmt config 2026-10-11 17:40:48 +01:00
Andy Dixon 0f4a906914 rust: keychain calls off the tokio runtime; plan reflects as-built crate choices 2026-10-11 17:04:24 +01:00
Andy Dixon 328507c57b rust: packaging (Linux desktop entry, macOS bundle), cargo release script with update manifests, CI 2026-10-11 16:53:19 +01:00
Andy Dixon c36f4633a1 rust: wire VNC client into the session manager (password asked only when required, SSH tunnel) 2026-10-11 16:38:07 +01:00
Andy Dixon 2e9fdffeeb Merge branch 'vnc-work' into rust-port 2026-10-11 16:37:04 +01:00
Andy Dixon d654671bc1 rust: Service facade (profiles, credentials, TOTP, import/export, SSH keys, SFTP, updates) 2026-10-11 16:36:37 +01:00
Andy Dixon 81360cc4c2 rust: native VNC (RFB) client 2026-10-11 16:36:32 +01:00
Andy Dixon cbd83489b2 rust: session manager (lifecycle, reconnect backoff, login scripts, recording, host-key policy, credential modes) and SSH tunnels 2026-10-11 16:33:17 +01:00
Andy Dixon 03bb1db936 Merge GitHub and IRC clients, IRC formatting 2026-10-11 16:23:31 +01:00
Andy Dixon 55e65410ce rust: use terminalenv for SSH and local shell env 2026-10-11 16:23:05 +01:00
Andy Dixon d20d16e8c8 rust: port GitHub and IRC clients, IRC formatting 2026-10-11 16:21:08 +01:00
Andy Dixon 1a42f65af1 Merge telnet, raw and serial clients 2026-10-11 16:20:27 +01:00
Andy Dixon 0b846e90d0 Merge utility ports (recording, sshconfig, terminalenv, validation, updater, keyfiles) 2026-10-11 16:19:14 +01:00
Andy Dixon fb3e49a2a8 rust: port telnet and raw clients; add serial client 2026-10-11 16:18:04 +01:00
Andy Dixon 25e5f67a4d rust: commit DB and vault fixtures (were gitignored) 2026-10-11 16:17:44 +01:00
Andy Dixon fd54c988b6 rust: port recording, sshconfig, terminalenv, validation, updater, keyfiles 2026-10-11 16:17:03 +01:00
Andy Dixon 5ffee4a7c4 rust: local shell client on portable-pty 2026-10-11 16:15:58 +01:00
Andy Dixon 026f27add6 rust: SSH client on russh (auth chain, TOTP, jump hosts, proxies, forwards, agent forwarding) and SFTP, with sshd integration tests 2026-10-11 16:14:55 +01:00
Andy Dixon 38dff53485 rust: client callback conventions 2026-10-11 16:05:31 +01:00
Andy Dixon e03298de11 rust: nexus-core storage, vault, keychain, export/import, data-dir migration 2026-10-11 16:05:13 +01:00
Andy Dixon f588a797f9 rust: Go-generated compatibility fixtures (db, vault, export, recording) 2026-10-10 12:58:10 +01:00