Repository navigation
v0.22.12
What's Changed
Added
- RDP can now authenticate NLA with Kerberos instead of NTLM (issue #351) — a host whose account is in the Active Directory Protected Users group cannot log in over the embedded client: that group disables NTLM (and CredSSP-with-NTLM) domain-wide, so IronRDP's NTLM-only NLA was rejected with
STATUS_ACCOUNT_RESTRICTION(0xc000006e), and the TLS-only fallback gave a black screen against a server that requires NLA.
IronRDP already supports Kerberos for CredSSP, but RustConn hard-codedNonefor the Kerberos config when finalising the connection, so it only ever attempted NTLM. A new opt-in "Kerberos Authentication" switch under the RDP connection editor's Features section threads anironrdp::connector::credssp::KerberosConfig(built from the local client hostname) intoconnect_finalize, so the SSPI layer negotiates Kerberos and falls back to NTLM only where the server and the local Kerberos setup permit it. It is off by default and affects the embedded IronRDP path only: Kerberos on Linux needs a working krb5 environment (a valid/etc/krb5.conf, DNS/SRV to the KDC, and a ticket viakinit). The connection editor exposes only the on/off switch — Kerberos talks to the KDC directly via the system krb5 config, which covers the common case. An MS-KKDCP KDC-proxy URL (for a KDC with no direct line of sight, typical behind an RD Gateway) is already plumbed end-to-end throughKerberosConfigand persisted per connection, but there is no editor field to set it yet, so it staysNonefor now; a malformed proxy URL, once a field exists, is logged and dropped rather than aborting the connection, falling through to direct-KDC Kerberos. The flag is persisted per connection and covered by the existing RDP config round-trip tests.
Fixed
- A SPICE connection's saved proxy and shared folders now actually reach the viewer — the connection editor let you store a SPICE proxy URL (the Proxmox VE tunnelling field) and one or more shared folders (webdav), and both were persisted correctly, but the launch path in
window/protocols.rsthat maps the storedSpiceConfigonto the runtimeSpiceClientConfignever copied either field across. As a result--spice-proxywas never emitted (so Proxmox proxy tunnelling silently did nothing) and no folder shares were passed toremote-viewer, even though the arg-building code inrustconn-core::spice_clientfully supports both. The mapping now threadsproxyand everyshared_foldersentry through to the client config, so the two fields take effect on connect as the editor implies. The root cause is that the persisted and runtime SPICE configs are two independent structs kept in sync by a hand-written mapping; the image-compression field is still not mapped (it needs an enum conversion between the two types) and is left as a separate follow-up.
Security
-
CLI-tool downloads now all pass through the same checksum policy, and the "all downloads are verified" claim is corrected — the CLI download manager (Flatpak-only, for fetching helper binaries like kubectl, tsh, tailscale, boundary and hoop) documented that "all downloads are verified using SHA256 checksums", but the custom installers for those five tools never consulted the per-component
ChecksumPolicyat all: they downloaded the binary and wrote it to diskchmod 0755without any integrity check, so a MITM or a compromised CDN could substitute an arbitrary executable. The generic and cloud installers already honoured the policy; the custom path silently did not. All install paths now funnel their downloaded bytes through one sharedenforce_checksum_policyhelper, so behaviour is identical everywhere: a component with a pinnedStaticSHA256 is verified and fails hard on mismatch, aSkipLatestcomponent (a "latest" URL with no stable published hash — which is what these five are) proceeds but is logged with a warning that the download is not integrity-verified, and aNonecomponent is refused. The module's security note is rewritten to describe this accurately rather than overclaiming blanket verification. New unit tests cover the helper for all three policy variants and a checksum mismatch. -
Saving a credential into a nested KeePass group no longer reports success when a parent group could not be created —
ensure_parent_groupsinsecret/status.rs, which walks a path likeGroups/Production/Webandmkdirs each level viakeepassxc-cli, only logged intermediatemkdirfailures atdebug!and always returnedOk(()). If a level failed (or the CLI wait errored), the subsequentaddtargeted a group that was never created, so the save appeared to succeed while the nested groups silently never appeared. It now treats success and "already exists" as fine but returns an error for any other outcome (including amkdirthat did not complete), so a genuine failure surfaces to the caller instead of being swallowed. -
Restoring settings from a backup archive now writes each file atomically —
ConfigManager::restore_from_archiveunpacked each config file with a barefs::write, unlike every other config write which goes through the atomic temp-file + fsync + rename path (write_locked) with owner-only (0600) permissions. A restore interrupted mid-write (crash, power loss) could therefore leave a half-written config on disk, and the restored files skipped the permission tightening. Since the backup files are all RustConn's own TOML (text), the restore now decodes each entry as UTF-8 and routes it throughwrite_locked, so a restore has the same crash-safety and permissions as a normal save. Covered by a new backup/restore round-trip test. -
Asbru-CM export no longer writes unusable entries for SPICE/Serial (and other unsupported) connections — the exporter emitted
method: "SPICE"/method: "serial"for those protocols, but neither Asbru-CM nor RustConn's own Asbru importer recognises those method values (the importer's protocol match has no arm for them and skips them as "Unsupported protocol"), so the exported entries were dead on both sides. Worse,supports_protocolreturnedtruefor every protocol while its comment claimed "SSH, RDP, and VNC". The exporter now reports support honestly (SSH, ZeroTrust→SSH, RDP, VNC, Telnet, SFTP — the protocols that round-trip) and, like the MobaXterm exporter already does, skips the rest: they are counted as skipped and each produces a warning instead of a silently-broken entry. New tests cover the skip path and the correctedsupports_protocol.
Changed
- The embedded RDP client's
smartcard_enabledandmicrophone_enabledconfig fields are now documented as reserved/not-yet-implemented — both were settable but had no effect: the embedded IronRDP client has no smart-card (scard) or audio-input (audin) virtual channel (handle_scard_callis a no-op), and neither field is surfaced in the GUI. Rather than remove them (which would change the config's serialized shape), their doc comments and the unusedwith_smartcardbuilder now state clearly that they are reserved and have no effect on the embedded client, so nobody mistakes them for working features. This is documentation only — no behaviour change. (FIDO2 passkey redirection, by contrast, is genuinely wired for the External FreeRDP-3.x client via the/fidoflag and needs no change.)
Documentation
- Removed a reference to a non-existent
search_parallelAPI and corrected thePropertyType::Urldoc — thesearchmodule's performance notes advised "consider usingsearch_parallelfor multi-threaded search", but no such function exists (onlySearchCacheandDebouncedSearchEngine, which do); the misleading bullet is removed. Separately,PropertyType::Url's doc claimed the value "can be rendered as a clickable link", but a URL custom property is currently displayed and edited exactly likeText— the doc now describes it accurately as a semantic type tag that is not yet rendered clickable.
Dependencies
- Updated: yoke-derive 0.8.3→0.8.4 — the 0.8.3 release was yanked from crates.io (it reached the tree transitively via
url→ IronRDP/reqwest); the semver-compatible 0.8.4 replaces it, so the lockfile no longer pins a yanked crate.
Installation
Flatpak (Recommended)
flatpak install flathub io.github.totoshko88.RustConnSnap
sudo snap install rustconnDebian/Ubuntu (.deb from this release)
sudo dpkg -i rustconn_0.22.12_amd64.deb
sudo apt-get install -f # Install dependencies if neededFedora (.rpm from this release)
sudo dnf install rustconn-0.22.12-1.fc44.x86_64.rpmAppImage
chmod +x RustConn-0.22.12-x86_64.AppImage
./RustConn-0.22.12-x86_64.AppImagemacOS (Homebrew)
brew tap totoshko88/rustconn
brew install rustconn
open $(brew --prefix)/opt/rustconn/RustConn.appAll dependencies (GTK4, libadwaita, VTE, Adwaita icons) are installed automatically.
Requires macOS 13 (Ventura) or later.
OBS Repositories
Packages available at: https://build.opensuse.org/package/show/home:totoshko88:rustconn/rustconn
# Debian 13 (Trixie)
echo 'deb http://download.opensuse.org/repositories/home:/totoshko88:/rustconn/Debian_13/ /' \
| sudo tee /etc/apt/sources.list.d/rustconn.list
curl -fsSL https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/Debian_13/Release.key \
| gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/rustconn.gpg > /dev/null
sudo apt update && sudo apt install rustconn
# Ubuntu 24.04 LTS (Noble)
echo 'deb http://download.opensuse.org/repositories/home:/totoshko88:/rustconn/xUbuntu_24.04/ /' \
| sudo tee /etc/apt/sources.list.d/rustconn.list
curl -fsSL https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/xUbuntu_24.04/Release.key \
| gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/rustconn.gpg > /dev/null
sudo apt update && sudo apt install rustconn
# Ubuntu 26.04 LTS (Resolute)
echo 'deb http://download.opensuse.org/repositories/home:/totoshko88:/rustconn/xUbuntu_26.04/ /' \
| sudo tee /etc/apt/sources.list.d/rustconn.list
curl -fsSL https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/xUbuntu_26.04/Release.key \
| gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/rustconn.gpg > /dev/null
sudo apt update && sudo apt install rustconn
# Fedora 44
sudo dnf config-manager addrepo --from-repofile=https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/Fedora_44/home:totoshko88:rustconn.repo
sudo dnf install rustconn
# Fedora 43
sudo dnf config-manager addrepo --from-repofile=https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/Fedora_43/home:totoshko88:rustconn.repo
sudo dnf install rustconn
# openSUSE Tumbleweed
sudo zypper ar https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/openSUSE_Tumbleweed/ rustconn
sudo zypper ref && sudo zypper in rustconn
# openSUSE Leap 16.0
sudo zypper ar https://download.opensuse.org/repositories/home:/totoshko88:/rustconn/openSUSE_Leap_16.0/ rustconn
sudo zypper ref && sudo zypper in rustconnArch Linux (AUR)
yay -S rustconnFreeBSD (Ports)
pkg install rustconnFull installation guide: https://github.com/totoshko88/RustConn/blob/main/docs/INSTALL.md