Skip to content

v0.24.11

Latest

Choose a tag to compare

@github-actions github-actions released this 12 Nov 16:55
· 8 commits to main since this release

What's Changed

Added

  • Fallback jump hosts — PR #420, contributed by Konstantinos Patronas — a connection or a group can list saved jump hosts to try in order when its Jump Host is unreachable, for SSH, SFTP, RDP, VNC, SPICE and WinRM. Each new connection or reconnect checks for a reachable SSH server, and uses the primary again as soon as it answers. If none answers, the first is tried and the normal error is shown; a connection never falls back to going direct. Set in the connection and group editors, which show the list only for those protocols and only once the connection or group has a Jump Host of its own (saving without one drops it). SPICE over a Unix socket uses no jump host, so it gets no list either. In the CLI it is --fallback-jump-host in rustconn-cli add and update, which both refuse a list for a connection without a Jump Host of its own, since it would never be used. The editor keeps keyboard focus: after Move Up or Move Down it follows the moved entry, after Remove it goes to the entry that takes its place (or to the add dropdown when the list is empty), and after Add it returns to the add dropdown; a second click before the list redraws acts on the same entry. A screen reader hears which host each Move Up, Move Down and Remove button acts on, and the editor's add dropdown has a name of its own. rustconn-cli connect does not fail over, so it still warns that a deleted Jump Host is skipped even when a fallback exists. A group's list stays on its device like the group's Jump Host: Simple Sync leaves it out of the shared file and keeps each device's own. (rustconn-core/src/connection/gateway_failover.rs, rustconn-core/src/connection/jump_chain.rs, rustconn-core/src/connection/ssh_inheritance.rs, rustconn-core/src/models/connection.rs, rustconn-core/src/models/group.rs, rustconn-core/src/sync/full_export.rs, rustconn/src/dialogs/widgets.rs, rustconn/src/dialogs/connection/general_tab.rs, rustconn/src/dialogs/connection/builders.rs, rustconn/src/dialogs/connection/dialog/construction.rs, rustconn/src/window/edit_group.rs, rustconn/src/window/protocols.rs, rustconn/src/state/mod.rs, rustconn-cli/src/commands/add.rs, rustconn-cli/src/commands/update.rs, rustconn-cli/src/commands/sftp.rs, docs/USER_GUIDE.md)
  • Duplicate a connection into a numbered range — PR #420, contributed by Konstantinos Patronas — right-click → Duplicate as Range…, or rustconn-cli duplicate --range, turns host01 into host02 … host10 with the pattern host[02-10], and host1 into host2 … host10 with host[2-10]. The host follows the name when it contains it, or takes its own range such as 10.0.0.[2-10]. Existing names are skipped, and the GUI copies a saved vault password to each new connection. In the dialog, Enter creates the copies once the patterns are usable, the pattern at fault is marked invalid, and a screen reader reads the preview line with each pattern. A copy that cannot be stored is named in an error dialog rather than counted as created, and a password that cannot be copied to some of the copies gets a warning. (rustconn-core/src/connection/host_range.rs, rustconn/src/window/operations.rs, rustconn/src/sidebar_ui.rs, rustconn-cli/src/commands/duplicate.rs, rustconn-cli/src/cli.rs)
  • Run a local bash script on many SSH hosts — PR #420, contributed by Konstantinos Patronas — right-click connections or a group → Run Local Script…, or rustconn-cli run-script. Shows live output and a result per host, with a limit on hosts at once, a time limit and a Stop button. Each host's result also has an icon, so a failed host stands out without relying on colour. A screen reader hears each host's status together with its name, the output pane is named after the host it shows, and the end of a run is announced with its counts. Keyboard focus moves to Stop when a run starts and to the host list when it ends, a setup error is read out and marks the script field, and on a narrow window the output goes below the host list. Closing the window or pressing Escape during a run asks whether to stop the script, and closes the window once every host has stopped. Why a host could not start (no ssh or python3, no pywinrm, no WinRM password, a tunnel that did not open) is shown in the interface's language. The script goes over stdin and nothing is saved on the hosts. It is syntax-checked first, runs through each host's saved jump hosts (with failover) and credentials, and a host whose key is not yet known is refused. A run never accepts a new key for a jump host either: every jump host of a run, including the jump host of a WinRM tunnel, must already be in known_hosts (StrictHostKeyChecking=yes), in the GUI and the CLI, and a jump host with no key of its own still offers ~/.ssh/id_* and the agent's keys, unless a password is sent along the route. Three cases go through ProxyJump and follow your ssh configuration: a chain of several jump hosts whose first one has a key of its own and that sends no password and uses no PKCS#11 provider, a jump host address RustConn cannot pass to a shell safely (such as a comma-separated ProxyJump chain), and the jump hosts past the first of a WinRM tunnel that sends no password. A host with no saved jump host whose own ~/.ssh/config routes it through ProxyJump or ProxyCommand is not sent its password, in the CLI as in the GUI, since the bastion's ssh would be the one answering the prompt (the issue #191 leak). Global variables in a host or user name (${name}) are filled in, in the CLI as in the GUI; a variable that asks at connect leaves that host out in the CLI, which cannot ask, and the host counts as not succeeded in the exit status; the CLI does not read a secret variable from the secret backend, so one whose value is not in the configuration file counts as undefined there. Passwords work too: saved ones in both the GUI and the CLI, and hosts set to ask at connect are each asked before the run, or asked once for all of them with Use One Password for All Hosts in the GUI or --same-password in the CLI (an empty answer sends no password rather than reusing another host's); the GUI empties those password fields once the run is confirmed. A saved password that takes longer than 30 seconds to read is skipped with a message, in the CLI as in the GUI. rustconn-cli --quiet run-script leaves out the progress lines (connections left out, hosts that succeeded, the closing count) and keeps the script's output, hosts that did not succeed, warnings and prompts. Stop, the time limit and a lost connection stop the script on the host, and a script exiting with 255 is no longer reported as a connection failure. rustconn-cli run-script builds the jump host route the same way the GUI does, so the first jump host's PKCS#11 token reaches it from the CLI too, and so does its own key when it is the only jump host or a password is sent along the route. (rustconn-core/src/remote_script.rs, rustconn-core/src/jump_route.rs, rustconn-core/src/ssh_key_setup.rs, rustconn-core/src/ssh_tunnel.rs, rustconn/src/window/remote_script.rs, rustconn/src/window/protocols_ssh.rs, rustconn/src/window/key_setup.rs, rustconn/src/sidebar_ui.rs, rustconn-cli/src/commands/run_script.rs, rustconn-cli/src/cli.rs, rustconn-cli/src/main.rs, docs/CLI_REFERENCE.md, docs/USER_GUIDE.md)
  • WinRM connections — PR #420, contributed by Konstantinos Patronas — a new connection type opens a PowerShell session on a Windows machine in a terminal tab, using the external evil-winrm client. Supports HTTPS, domain accounts and jump hosts, in the GUI and through rustconn-cli add -P winrm, and rustconn-cli show prints a WinRM connection's jump host, certificate setting (Accept Invalid TLS, as for Web) and the custom arguments the client is given, without a refused secret option; the WinRM page's Jump Host dropdown is named for screen readers, and the sidebar's WinRM filter label goes through translation like the other protocol filters. A saved password is answered at the client's prompt and never appears on a command line. In Flatpak, RustConn finds evil-winrm on the host and runs it there, through the jump host tunnel too. When evil-winrm is missing, the message says where to get it for this package: on the host for Flatpak, not at all in the Snap. Custom Arguments refuse and drop -p/--password and -H/--hash in every form evil-winrm accepts, including an abbreviation (--pass), an attached value (-pSECRET) and a short-option group (-np), so a secret typed there cannot reach the command line either. Run Local Script runs a .ps1 file in PowerShell on WinRM hosts, using the pywinrm library. In Flatpak and Snap, Run Local Script's pywinrm library installs from Menu → Components, and a missing pywinrm is named before the run starts, with where to get it. (rustconn-core/src/protocol/winrm.rs, rustconn-core/src/models/protocol.rs, rustconn-core/src/remote_script.rs, rustconn-core/src/import/csv_import.rs, rustconn-core/src/dynamic_folder.rs, rustconn-core/src/cli_download/components.rs, rustconn-core/src/cli_download/install_pip.rs, rustconn/src/dialogs/connection/winrm.rs, rustconn/src/dialogs/flatpak_components.rs, rustconn/src/window/protocols.rs, rustconn/src/window/remote_script.rs, rustconn/src/sidebar/mod.rs, rustconn-cli/src/commands/add.rs, rustconn-cli/src/commands/connect.rs, rustconn-cli/src/commands/run_script.rs, rustconn-cli/src/commands/show.rs, docs/USER_GUIDE.md, docs/SNAP.md)
  • Browse through an existing SOCKS5 proxy — PR #420, contributed by Konstantinos Patronas — Web connections have a SOCKS5 Proxy field (--socks-proxy in the CLI) alongside Tunnel Through SSH, including proxies that need a login, which RustConn relays for as long as the browser using it runs. The login's password comes from a secret global variable: the GUI and rustconn-cli add/update --socks-proxy-password-var refuse a plain one, whose value would sit in the configuration file. Group Sync exports that variable as a template, without its value, whichever connection mentions it first, so the other device knows which secret to fill in. rustconn-cli add and update refuse the proxy settings the editor refuses (a proxy together with a tunnel, a login without a proxy, a username or a password variable), and update --socks-proxy "" removes the login along with the proxy; rustconn-cli show prints the proxy, its username and the name of its password variable, never the password. In the editor a SOCKS5 Proxy group of its own, apart from the embedded browser's settings, holds both SOCKS5 routes: Tunnel Through SSH, and the proxy's Address, Username and Password Variable, since both apply to external browsers too. It works in the embedded browser, Chromium-based browsers and Firefox, and the tunnel now works with Firefox too; a Firefox behind the proxy or the tunnel keeps private mode (--private-window next to its temporary profile), in the GUI and in rustconn-cli connect. If no browser can use the proxy the page is not opened, so traffic never goes direct; an external Chromium or Firefox also keeps WebRTC on the proxy, so a page cannot learn this computer's own addresses through it. The GUI now counts Opera as a Chromium-based browser for the proxy and the tunnel, also when it is the system default browser or in $BROWSER, and a LibreWolf opened without a proxy gets private mode (--private-window) as Firefox does. (rustconn-core/src/protocol/web.rs, rustconn-core/src/socks_relay.rs, rustconn-core/src/sync/group_export.rs, rustconn/src/dialogs/connection/web.rs, rustconn/src/window/edit_actions.rs, rustconn/src/embedded_web/mod.rs, rustconn-cli/src/commands/add.rs, rustconn-cli/src/commands/update.rs, rustconn-cli/src/commands/connect.rs, rustconn-cli/src/commands/show.rs, docs/CLI_REFERENCE.md, docs/USER_GUIDE.md)

Fixed

  • The "Routing changed" warning now notices jump hosts chosen from the picker — PR #420, contributed by Konstantinos Patronas — it compared free-text ProxyJump values only, so re-pointing a connection's saved Jump Host went unseen. Connections that use one will show the warning once after updating, because their route is now recorded for the first time. (rustconn-core/src/connection/gateway_failover.rs, rustconn/src/state/mod.rs)
  • Tunnelled and proxied browsers no longer leave their profiles behind — Open Browser via Tunnel started Chromium in a fresh rustconn-tunnel-browser-* profile that nothing deleted, so the cookies, history and cache of every tunnelled session piled up in $XDG_RUNTIME_DIR (on macOS in $TMPDIR, on disk), and the new SOCKS proxy launches did the same. A proxied browser's profile is now deleted when the browser exits, or when RustConn quits and closes it; Stop Tracking leaves it until the browser exits. Profiles left by a crash or by rustconn-cli connect, which hands itself over to the browser, are removed at the next start of RustConn, or the next rustconn-cli connect that opens a Web page through a SOCKS proxy, once they are 12 hours old and no browser holds their lock, including the old rustconn-tunnel-browser-* ones. (rustconn-core/src/protocol/web.rs, rustconn/src/external_session.rs, rustconn/src/window/edit_actions.rs, rustconn/src/app.rs)
  • A split tab is named after the pane you work in (issue #421) — a tab holding a split layout kept the name of whichever session joined it last, so clicking into another pane left it on the wrong server. The tab title now follows the focused pane, whether focus moves by a click, by the Focus Next Pane shortcut or because a pane closed, and whatever the pane shows: SSH, Telnet, Serial, Kubernetes, MOSH, Zero Trust, RDP, VNC or a web page. Its tooltip describes the same session (name, host and working directory) and gains a Panes: line listing every session in the split; the tab's own tooltip comes back when the split ends. Names such as R&D no longer blank the tooltip while the tab is split; the tab's own tooltip that comes back afterwards still can. A rename of any session in the split reaches the tab title, the Panes: line and that session's pane header. Rename Tab… is offered when the session the tab is named after is a local shell, and renames that session. The window title follows the tab title as soon as it changes rather than at the next tab switch, so the two never disagree; on a tab with a single pane too, it now follows a rename, a group change and the REC and ⇄ markers at once, which matters if you track time by the window title (issue #211). With Show hierarchy path in header on, the header subtitle shows the focused pane's group path and follows pane focus. A tab with a single pane is titled as before; its tab menu's Set Group… and Remove from Group now keep the working-directory line. (rustconn/src/terminal/split_title.rs, rustconn/src/split_view/bridge.rs, rustconn/src/split_view/mod.rs, rustconn/src/terminal/mod.rs, rustconn/src/terminal/tab_lifecycle.rs, rustconn/src/terminal/tab_menu.rs, rustconn/src/window/mod.rs, rustconn/src/window/split_view_actions.rs, rustconn/src/window/navigation_actions.rs, po/POTFILES.in, po/)
  • A jump host's password no longer reaches the jump hosts behind it in a tunnel — an RDP, VNC, SPICE, WinRM or Web (SOCKS) connection whose jump host is itself reached through further jump hosts started the tunnel's ssh with -J for those (or, in Flatpak and with a PKCS#11 token, with a ProxyCommand of its own), and every ssh started for them inherited the askpass helper that answers with the nearest jump host's password, so a farther bastion could be sent it (the issue #191 leak). When the tunnel sends a password, the farther jump hosts now go through a ProxyCommand built by the shared jump host route, which starts each of them without that helper; they must log in with a key or the agent. A GUI tunnel has no terminal to ask on, so there a farther jump host that accepts only a password now fails where it used to be sent the nearest jump host's password; a tunnel that rustconn-cli connect or run-script starts from a terminal may have that jump host ask for its password in the terminal. Sending each farther jump host its own saved password is a later item. A farther jump host whose address RustConn does not pass to a shell (such as a comma-separated ProxyJump chain) keeps -J, and the password is then not sent; create_tunnel refuses to send it along any such route. The same holds for the WinRM tunnel of rustconn-cli connect and run-script, which says so on stderr, and in a script run, in the GUI as in the CLI, those farther jump hosts must already be in known_hosts. In the Flatpak, rustconn-cli's WinRM tunnel now hands those jump hosts the writable known_hosts, as the GUI does. (rustconn-core/src/jump_route.rs, rustconn-core/src/ssh_tunnel.rs, rustconn/src/window/protocols.rs, rustconn/src/window/rdp_vnc.rs, rustconn/src/window/edit_actions.rs, rustconn/src/window/remote_script.rs, rustconn-cli/src/commands/run_script.rs)
  • A tunnel no longer sends its jump host's password when your ssh configuration routes that jump host through a proxy — an RDP, VNC, SPICE, WinRM or Web (SOCKS) tunnel whose jump host ~/.ssh/config reaches through ProxyJump or ProxyCommand started that proxy's ssh with the tunnel's askpass helper, so the bastion in front could be sent the jump host's password (the issue #191 leak). The tunnel now asks ssh -G first, as an SSH session does, and opens without sending the password when a proxy is declared; in the GUI and in rustconn-cli connect and run-script. A route RustConn puts on the tunnel's command line overrides the configuration and needs no check. (rustconn-core/src/ssh_tunnel.rs, docs/USER_GUIDE.md)
  • SFTP through Midnight Commander signs in with the saved password — a password-authenticated SSH connection opened in mc stopped at shell: Waiting for initial line... with a warning that password authentication is not supported, until the password was typed blind into the tab. RustConn now reads the password as Connect does (the session cache first, then the vault; a connection set to ask at connect is asked once), and the ssh that mc starts gets it through the askpass helper from an owner-only file, only when it connects to the connection's own host, user and port; any other sh:// link opened in that mc gets nothing, and the password never enters mc's environment. Saved jump hosts are reached through RustConn's own ProxyCommand, so none is sent the target's password; they log in with a key or the agent, or ask in the tab as before. Where an SSH session would not send the password either (Keyboard Interactive, a PKCS#11 token, a custom routing option, a proxy in ~/.ssh/config), and for a chain whose farther jump hosts have keys of their own, mc opens without it and a warning says to type it. The same warning appears, and the log says why, when mc's first ssh does not have the form RustConn hands the password to, as an mc build with an extra flag would give. When the saved password is refused, it is dropped from the session cache as soon as that mc exits, also when its tab is closed, so a Connect reads the vault again, and the next mc open of that connection, even one made while the first mc is still open or after RustConn was restarted in the same login session, says so and opens without it, so you can type the right one in the tab; the open after that reads the vault again. Every SFTP entry point that opens mc now checks that mc is installed first. A password-authenticated connection that also has a key file, its own or one from its group, gets the password too, as an SSH session does; when the key signs in, the password is never used. Key and agent connections open as before; rustconn-cli sftp --mc still leaves the password to you. (rustconn-core/src/mc_ssh.rs, rustconn/src/window/mc_launch.rs, rustconn/src/window/edit_actions.rs, rustconn/src/window/mod.rs, rustconn/src/terminal/mod.rs, rustconn-cli/src/commands/sftp.rs, docs/USER_GUIDE.md, po/POTFILES.in, po/)
  • Flatpak: a home folder with a space in its path no longer splits the writable known_hosts in two — SSH sessions, tunnels, port forwards, session recordings and the monitoring probe passed -o UserKnownHostsFile=<path> straight to ssh, which reads that option as a space-separated list, so /home/my name/…/known_hosts became the two files /home/my and name/…/known_hosts, and host keys were looked up in, and saved to, the wrong place. The path is now passed quoted (UserKnownHostsFile="<path>"), as the SSH key setup already did, through one shared helper; a path holding " or \ is left out, and ssh then uses its default known_hosts. A % in the path is passed as %%, so ssh no longer reads it as the start of a token such as %u. A GCP IAP connection hands the path to gcloud through the same helper; gcloud splits each --ssh-flag value at spaces, so there a path with a space is left out as well. (rustconn-core/src/ssh_tunnel.rs, rustconn-core/src/models/protocol.rs, rustconn-core/src/tunnel_manager.rs, rustconn-core/src/monitoring/ssh_exec.rs, rustconn-core/src/ssh_key_setup.rs, rustconn/src/terminal/mod.rs, rustconn/src/terminal/recording.rs, rustconn/src/window/protocols_ssh.rs)
  • Linux without XDG_RUNTIME_DIR: SFTP through Midnight Commander no longer uses a wrapper directory another user created — without XDG_RUNTIME_DIR, the ssh wrapper that carries a connection's jump host and SSH options to mc (issue #255) lived in /tmp/rustconn-mc-ssh, which RustConn reused whoever owned it, so a local user who created it first could replace the wrapper script, which runs as you and now also names the file holding the saved password. The directory is now created owner-only (mode 0700), an older one of yours is made owner-only, and one that is a symbolic link or belongs to another user is not used: mc then opens without the wrapper and without the password, and the log says why. macOS, whose temp directory is per user, and Linux desktop sessions with XDG_RUNTIME_DIR were not affected. (rustconn-core/src/mc_ssh.rs, rustconn-core/Cargo.toml)
  • macOS: SFTP through Midnight Commander finds a Homebrew mc when RustConn starts from the Dock or Finder (issue #422) — the check found mc in /opt/homebrew/bin or /usr/local/bin, but the tab then started it with the PATH the app inherits from launchd (/usr/bin:/bin:/usr/sbin:/sbin), so it reported 'mc' is not installed; from a terminal it worked. mc, and the ssh wrapper it goes through, now get the same PATH as every other session: the Homebrew prefixes and the sandbox tool directories in front of the inherited one. (rustconn-core/src/mc_ssh.rs, docs/USER_GUIDE.md)
  • Flatpak: a host evil-winrm installed through rbenv, rvm or a gem directory in the profile now starts — RustConn found the client through a host login shell but started it with the Flatpak session helper's environment, which lacks the profile's PATH and GEM_HOME, so a client that was found could fail to start. It now starts in the same login shell (flatpak-spawn --host … -- sh -lc 'exec "$0" "$@"' <client> <arguments>), which passes the path and every argument through unparsed; the password is still typed only at the client's prompt, never on its command line or in its environment. When the client is missing, the Flatpak message now says it must be on the PATH of the host's login shell (set in ~/.profile, not only in ~/.bashrc). rustconn-cli connect builds a WinRM launch from the WinRM handler itself, so the client is never started with another command's arguments. (rustconn-core/src/protocol/winrm.rs, rustconn/src/window/protocols.rs, rustconn-cli/src/commands/connect.rs, docs/USER_GUIDE.md, po/)
  • Ukrainian: one form for "script" and for WinRM hosts — the interface mixed the genitive «скрипта» and «скрипту»; every string now uses the dictionary form «скрипту», and «на WinRM-гостах» reads «на гостах WinRM» like the other strings. (po/uk.po)
  • A slow Match exec in ~/.ssh/config no longer stalls a connect or a script run — the ssh -G check that decides whether a password may be handed to ssh gives up after 5 seconds and then keeps the password back, as it does when the check fails. (rustconn-core/src/ssh_tunnel.rs)
  • Flatpak: a home folder whose path a shell would split no longer breaks jump hosts reached through RustConn's ProxyCommand — the writable known_hosts path went into the command unquoted, so a home folder with a space, a ; or a quote in its path broke the command or ran part of it as another command. Such a path is now left out of the ProxyCommand: carrying it would take quoting twice, once for the shell and once for ssh, which is not worth it for so rare a home path. Those jump hosts then use ssh's default known_hosts. A jump host already known there connects as before; one that is not is handled by the host key policy as usual, so under accept-new it still connects, but its key cannot be recorded in the Flatpak's read-only ~/.ssh and is accepted anew each time. Sessions, SFTP and tunnels that pass the path straight to ssh keep it, quoted when it holds a space. (rustconn-core/src/jump_route.rs, rustconn-core/src/ssh_tunnel.rs, rustconn/src/window/protocols.rs)
  • Ctrl+W closes an open dialog, a playback tab, or the window when no tab is open — Ctrl+W did nothing on the Welcome page, and a recording playback tab could not be closed with it. With no session tab open it now closes the main window the way its close button does: it asks first when detached or external sessions are still running, and hides to the tray when that is enabled. Pressed in a dialog such as Settings, Ctrl+W closed the session tab behind the dialog, in the main window and in a detached window; it now closes the dialog. Inside a terminal Ctrl+W still goes to the shell (issues #197, #216) and Ctrl+Shift+W closes the tab; the Keyboard Shortcuts window now says so under Close Tab. (rustconn/src/window/terminal_actions.rs, rustconn/src/window/detach_actions.rs, rustconn/src/terminal/tab_lifecycle.rs, rustconn/src/dialogs/shortcuts.rs, docs/USER_GUIDE.md, po/)
  • Ctrl+, and F10 work in a detached session window — a session moved into its own window had no Settings action and no menu, so Ctrl+, and F10 did nothing there, and Keyboard Shortcuts (Ctrl+?) and About opened on the main window, which could be behind it or hidden in the tray. The detached window now has a main menu button (F10) with Settings, Keyboard Shortcuts, Help and About; like the main window's, F10 goes to the session while keyboard passthrough is on. Ctrl+, opens Settings on the main window and raises it, since Settings belong to the whole application, and Keyboard Shortcuts and About open on the window you are in. (rustconn/src/detached_window.rs, rustconn/src/window/detach_actions.rs, rustconn/src/app.rs, docs/USER_GUIDE.md, po/)
  • A screen reader names each session view — Orca announced every terminal as just "terminal", so the panes of a split sounded the same, and an embedded RDP or VNC view as an unnamed image. A terminal, in a tab, a split pane or a detached window, is now named after its session, and follows a rename; a recording playback is named like its tab. An embedded RDP or VNC view is called "Remote desktop" with the connection's name, and its description says how to get the keyboard back: the Toggle Keyboard Passthrough shortcut as currently bound, and Super+Escape for the desktop shortcuts in GNOME. The status line of an RDP tab whose session runs in an external window is now translated. The terminal highlight and failed-command overlays and the theme preview in the connection editor are hidden from screen readers as decoration. The Jump Host dropdowns of the SSH, RDP, VNC and SPICE pages, the new-connection wizard, the group editor, the tunnel builder and the Global Jump Host in Settings now have names of their own. (rustconn/src/embedded.rs, rustconn/src/terminal/mod.rs, rustconn/src/terminal/split_title.rs, rustconn/src/terminal/tab_lifecycle.rs, rustconn/src/terminal/playback.rs, rustconn/src/terminal/highlight_overlay.rs, rustconn/src/terminal/failed_marker.rs, rustconn/src/session/vnc.rs, rustconn/src/dialogs/connection/advanced_tab.rs, rustconn/src/dialogs/connection/ssh.rs, rustconn/src/dialogs/connection/rdp.rs, rustconn/src/dialogs/connection/vnc.rs, rustconn/src/dialogs/connection/spice.rs, rustconn/src/dialogs/connection_wizard/connection_page.rs, rustconn/src/dialogs/settings/network_tab.rs, rustconn/src/dialogs/tunnel_builder/step_connection.rs, rustconn/src/window/edit_group.rs, po/)
  • The sidebar context menu shows a focus ring — the focused item had only a 15% accent tint and its focus outline was removed, which left it close to invisible in high contrast, and a mouse click left the tint behind. The tint now appears only for keyboard focus, together with a 2px focus ring in the theme's focus colour, as on other libadwaita buttons. (rustconn/assets/style.css)
  • Split-pane colours are visible in light and dark themes — the pane borders, pane headers, tab stripes and sidebar markers of a split used shades such as #33d17a green and #00b4d8 cyan, which have less than 3:1 contrast against a light window. They now use six GNOME palette shades with at least 3:1 against both white and the dark theme's #222226: Blue 3 #3584e4 (unchanged), Green 5 #26a269, Orange 4 #e66100, Purple 2 #c061cb, Teal #2190a4 (was cyan) and Red 2 #ed333b (was pink). The order is kept, so a saved split layout keeps its colours. (rustconn/src/split_view/bridge.rs, rustconn/assets/style.css, rustconn/src/sidebar_types.rs, rustconn-core/src/split/color.rs)

Changed

  • Update every device that shares or syncs a configuration before using WinRM or a SOCKS5 proxy — RustConn 0.24.10 and older cannot read a connections.toml, a Simple Sync file or a Group Sync .rcn file that holds a WinRM connection: the whole file fails to load, not only that connection. They also do not know the new SOCKS5 proxy fields of a Web connection, so they open its page directly instead of through the proxy, and saving there drops the fields, which sync then carries to the other devices. (docs/USER_GUIDE.md)
  • Shorter software-center summary and a more accurate description — the AppStream summary reads "Manage remote connections" (it had 36 characters, one over Flathub's limit, and named only three of the protocols), and the description no longer claims that no external dependencies are needed: it says that some features use external command-line tools, such as a cloud provider's CLI for Zero Trust connections or a password manager's client. The Debian, OBS (Debian and RPM), Nix and Snap package descriptions say the same in place of "no external dependencies required". (rustconn/assets/io.github.totoshko88.RustConn.metainfo.xml, debian/control, packaging/obs/debian.control, packaging/obs/rustconn.spec, packaging/nixpkgs/package.nix, snap/snapcraft.yaml)
  • F1 opens the user guide; the Keyboard Shortcuts window keeps Ctrl+? — F1 is Help in the GNOME HIG, but it opened the shortcuts window. It now opens the user guide in the browser, as does the new Help item in the main menu, and it is remappable under Settings → Keybindings like any other shortcut. A shortcut you bound yourself now wins over a default on the same keys, so if you had given F1 to the shortcuts window, or to anything else, F1 still does what you chose. The Keyboard Shortcuts window and Settings → Keybindings show the keys that are in use, so a default your own binding took is no longer listed next to its old action. (rustconn-core/src/config/keybindings.rs, rustconn/src/app.rs, rustconn/src/window/ui.rs, rustconn/src/dialogs/shortcuts.rs, rustconn/src/dialogs/settings/keybindings_tab.rs, docs/USER_GUIDE.md, po/)
  • Additional license terms for the author's code — from this release, the material in RustConn written by Anton Isaiev carries additional terms under section 7 of GPL-3.0, set out in the new NOTICE file: keep the author attribution "Anton Isaiev, Ukraine" in copyright notices and in the About dialog's copyright line and "Made in Ukraine" section (7(b)); a modified version distributed as a separate project is not named "RustConn" alone, uses neither an application ID beginning with io.github.totoshko88 nor the RustConn icon, and says that it is modified and by whom (7(c)); the author's name is not used to promote a modified version without permission (7(d)); no trademark rights beyond TRADEMARKS.md (7(e)). Packaging by an operating-system distribution that does not change the program's features is not a separate project. The license stays GPL-3.0-or-later; 0.24.10 and earlier releases, and code contributed by other people, are not affected. (NOTICE, README.md)
  • The copyright line names Ukraine — the About dialog now reads "© 2024-2026 Anton Isaiev, Ukraine", next to its unchanged "Made in Ukraine" section, and the Debian and OBS copyright files and the RPM spec carry the same line; the two copyright files also point to NOTICE. (rustconn/src/app.rs, debian/copyright, packaging/obs/debian.copyright, packaging/obs/rustconn.spec)
  • Flatpak — FreeRDP 3.33.0→3.33.1 — the bundled FreeRDP used for the external RDP client; version and sha256 updated. (packaging/flatpak/io.github.totoshko88.RustConn.yml, packaging/flatpak/io.github.totoshko88.RustConn.local.yml)

Documentation

  • RustConn now follows the GNOME Code of Conduct — it replaces the Contributor Covenant 2.1 for the project's issues, pull requests, discussions and code review. CODE_OF_CONDUCT.md now links to conduct.gnome.org and says how to report a problem, to the maintainer or to the GNOME Code of Conduct Committee; the README has a Code of Conduct section, and CONTRIBUTING.md points to it. (CODE_OF_CONDUCT.md, README.md, CONTRIBUTING.md)
  • Use of the name, icon and application ID — a new TRADEMARKS.md covers the unregistered name "RustConn", the application icon and the application ID prefix io.github.totoshko88. Official builds, unmodified redistribution, distribution packaging that does not change the program's features, referring to the project by name and saying "based on RustConn" need no permission; a fork distributed as a separate project uses its own name, application ID and icon. (TRADEMARKS.md)
  • How AI tools are used in RustConn — a new "AI-assisted development" section in CONTRIBUTING.md says that the maintainer works with AI coding agents (Kiro, with Claude models) whose configuration is public in .kiro/ and the AGENTS.md files; that every change is read by the maintainer, passes scripts/verify.sh --tests and is tested by hand; that Flathub manifests and submissions are written by hand; and that since 12 November 2026 agent-made commits carry a Co-Authored-By trailer (most earlier ones, including most of the 0.24.11 cycle, do not). Contributors may use AI tools if they understand and can explain what they submit. (CONTRIBUTING.md, AGENTS.md)
  • Translation policy written down — CONTRIBUTING.md now says that every language is welcome except Russian, which the project does not ship, as a product decision explained in the maintainer's reply on PR #413; new languages of the region such as Bashkir, Tatar and Nogai are welcome like every other. The translation issue form, the README and po/AGENTS.md say the same. (CONTRIBUTING.md, po/AGENTS.md, .github/ISSUE_TEMPLATE/translation.yml, README.md)
  • Official sources listed in the README — a new "Official sources" section under Installation lists the channels RustConn is published through: GitHub Releases with build-provenance attestations, Flathub, the Snap Store, the openSUSE Build Service, the Homebrew tap, the AUR package rustconn, FreeBSD ports and the Nix flake. It says that forks are not affiliated with the project and that their bugs belong in their own trackers, while packages from other distributions are reported here. (README.md)
  • NOTICE and TRADEMARKS.md ship with the packages — the release .deb, the release .rpm and the OBS packages now install LICENSE and NOTICE as license files and TRADEMARKS.md as documentation, so the section 7 terms travel with the binaries. The release .rpm previously shipped no license file at all. (.github/workflows/release.yml, packaging/obs/rustconn.spec)
  • The bug report form asks where RustConn came from — the required install-source field now lists the official channels, a build from this repository's source, "Another distribution's package" and "Other / a fork", and says that reports about forks are handled in the fork's own tracker. (.github/ISSUE_TEMPLATE/bug_report.yml)

Dependencies

  • Updated (semver-compatible): libz-sys 1.1.32→1.1.33, openh264 0.9.9→0.9.10 (with openh264-sys2), rpassword 7.5.4→7.5.5, rustls-pki-types 1.15.1→1.16.0, zip 9.5.0→9.5.1, and patch releases of bit-vec, bit_field, const-oid, crc32fast and errno. cargo deny check advisories is clean; cargo-sources.json regenerated for the Flatpak/Flathub manifests. GNOME runtime 51, cJSON 1.7.19, OpenH264 2.7.0, VTE 0.84.1 and the pinned TigerVNC 1.16.2 download were already current. resvg 0.50 is a breaking release and waits for its own change; zbus 6 / oo7 0.7 stay deferred as in 0.24.10.

Installation

Flatpak (Recommended)

flatpak install flathub io.github.totoshko88.RustConn

Snap

sudo snap install rustconn

Debian/Ubuntu (.deb from this release)

sudo dpkg -i rustconn_0.24.11_amd64.deb
sudo apt-get install -f  # Install dependencies if needed

Fedora (.rpm from this release)

sudo dnf install rustconn-0.24.11-1.fc44.x86_64.rpm

AppImage

chmod +x RustConn-0.24.11-x86_64.AppImage
./RustConn-0.24.11-x86_64.AppImage

macOS (Homebrew)

brew tap totoshko88/rustconn
brew install rustconn
open $(brew --prefix)/opt/rustconn/RustConn.app

All 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 rustconn

Arch Linux (AUR)

yay -S rustconn

FreeBSD (Ports)

pkg install rustconn

Full installation guide: https://github.com/totoshko88/RustConn/blob/main/docs/INSTALL.md

Verifying your download

Every binary on this release (deb, rpm, AppImage, Flatpak) is covered two ways.

Plain checksums — download SHA256SUMS alongside the asset, then:

sha256sum -c SHA256SUMS

Signed build provenance (SLSA, via Sigstore) — proves the file was built by this
workflow from this commit:

gh attestation verify RustConn-0.24.11-x86_64.AppImage --repo totoshko88/RustConn

(The snap is signed by the Snap Store; the macOS build is delivered via the Homebrew tap.)