Aligns with XDG Base Directory spec: $XDG_RUNTIME_DIR is the defined
location for non-essential runtime files (ephemeral, user-owned,
session-scoped). sshfs mounts fit that definition exactly, and the
tmpfs backing means orphaned mountpoint dirs vanish on logout instead
of accumulating.
- verify_mount_dir reads $XDG_RUNTIME_DIR, falls back to
/run/user/<uid>/ via os.Getuid().
- Existing path-traversal guard and symlink rejection carry over
unchanged.
- Tests switched from t.Setenv("HOME") to t.Setenv("XDG_RUNTIME_DIR").
File-manager sidebar visibility is unaffected — gvfs surfaces FUSE
mounts via /proc/mounts regardless of mountpoint location.
- New `-r` / `--remote-dir` flag to mount a specific remote subdirectory;
empty default preserves prior home-dir behaviour.
- Validate the flag value via a dedicated `rxRemoteDir` allowlist before it
reaches the sshfs argv.
- Use the ssh_config alias (not the resolved HostName) as the local
mountpoint name and as the sshfs source. File managers now show the
human-readable label instead of the raw IP.
- Validate `args[0]` against `rxHostUser` since it now flows into argv.
- Rename `verify_mount_dir` parameter `hostname -> name` and `mount_sshfs`
first parameter `hostname -> alias` for clarity.
Three rounds of audit-driven hardening, fully documented in DECISIONS.md:
- argv hardening: validate HostName/User/IdentityFile via allowlist regexes,
parse Port via strconv.Atoi, surface ssh_config parse errors instead of
silently swallowing them. Switch -o kernel_cache to auto_cache for network-
FS correctness, pin StrictHostKeyChecking=accept-new.
- LOW-severity cleanup: -v verbose flag (default output is just the mount
path), run_editor returns errors and main exits 7 on failure, ABOUTME
headers, golang.org/x/sys v0.43.0 (go 1.25.0).
- Defense-in-depth + UX: rxIdentityFile first-character anchor rejects
leading "-"/"."/":"/etc., verify_mount_dir resolves base via EvalSymlinks
and refuses pre-existing symlinks at the mount path, flag.Usage shows the
positional <Host> argument, run_editor uses cmd.Start() so cold-start
Sublime does not block the terminal.
- CI: empty-PKGVER guard in update-pkgver workflow.
- Tests: verify_mount_dir path-traversal + symlink-reject coverage,
rxHostUser/rxIdentityFile boundary cases.
Addresses audit findings from 2026-04-19:
- Q-H1: replace Println with Printf for %s-formatted error (line 42)
- Q-H2/Q-M2/Q-M3: verify_mount_dir and mount_sshfs now return error;
main exits on failure instead of continuing with invalid state
- Q-M1: default Port to "22" when ssh_config has no entry
- S-M1: create mount dir with 0700 instead of 0777
- S-M2: filepath.Clean + base-prefix check rejects HostName values
that would escape ~/Servers/
- Q-L1: correct "~/.ssh_config" typo to "~/.ssh/config"
Also: use os.Exit(2) for usage error (was 80), route user-facing
errors to stderr.
Replace minimal mount flags (dir_cache=no) with aggressive caching
and connection tuning: kernel_cache, attr/entry/negative timeouts,
fast cipher (aes128-gcm), reconnect with keepalive.