SSH client: a terminal on another machine (#2) #94

Merged
twisla merged 2 commits from ssh-client into main 2026-10-08 07:09:12 +00:00
Owner

Closes #2.

What it is

A new SSH App: one session to a shell on another machine, over libssh (ewpa/LibSSH-ESP32 5.10.0) on mbedTLS.

  • user@host[:port], typed in the App or as ssh user@host in the Shell. Up to eight hosts are remembered, once a login has succeeded.
  • Trust on first use, on the SHA-256 fingerprint. A changed key is a warning, with Cancel selected.
  • A password, typed each time and stored nowhere, or a key the device makes for itself (Ed25519): the public half is shown, written to /ssh/id_ed25519.pub and printed by ssh status.
  • A real terminal (lib/term, host-tested): enough for a shell, less, top, nano, vim. Sixteen colours, scroll regions, the alternate screen, 100 lines of scrollback.
  • Q257 as asked: Ctrl with + and - change the text size, five of them, from 60x20 to 26x8. The far end is told.
  • Leaving the App doesn't end the session. SSH shows in the Status Bar.

The decisions (Q254 to Q266), the measurements and every check are in docs/milestones/N1.md.

Three things beyond the App

  • Keys that aren't characters now carry Shift, Ctrl and Alt (key_mapper.cpp). The terminal needs it for Page Up and Alt+backtick. It also makes two documented keys work from the real keyboard that until now only worked from the Debug Console's key command: Ctrl+Fn+up/down in a note, Shift+Tab in Gemini.
  • IRC doesn't try to connect with less than 60 KB free. Started with a session open, its TLS handshake took the free heap down to 236 bytes, six times over. Now it says "not enough memory: close the SSH session" and waits.
  • A build script leaves libssh's own curve25519 out: libsodium (here for WireGuard) defines the same names.

What it costs

Flash 292 KB (the trial said 120: signing with the device's key links a 109 KB table). The firmware is at 71% of its slot
Heap, session open about 50 KB of 99 KB
Lowest free heap during a login 30 KB
Not started under 75 KB free: not with IRC connected

Checked on the device

Against OpenSSH 9.7 in a container: first-time trust (fingerprint compared with the server's), password, ls, top, vim, the five sizes with stty size, scrollback, leaving and coming back, Ctrl+C, backtick, both ways of ending, key login ("Accepted publickey" in the server's log), a changed host key (Cancel and Replace), a wrong password, a closed port, bad targets, forgetting a host, IRC waiting while a session is open, memory back to 99 KB after. 559 host tests pass.

Not checked: the refusal under 75 KB free; a server on the internet or through the VPN; Wi-Fi lost mid-session; servers other than OpenSSH; nano, less, tmux; two-factor prompts; a session left open for hours.

Docs

Guide page and how-to (key login), FAQ, home page, Status Bar, SD card folders, the memory how-to, the Shell page, README, glossary, N1 notes, five screenshots.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT

Closes #2. ## What it is A new **SSH App**: one session to a shell on another machine, over libssh (`ewpa/LibSSH-ESP32` 5.10.0) on mbedTLS. - `user@host[:port]`, typed in the App or as `ssh user@host` in the Shell. Up to eight hosts are remembered, once a login has succeeded. - **Trust on first use**, on the SHA-256 fingerprint. **A changed key is a warning**, with Cancel selected. - **A password, typed each time and stored nowhere**, or **a key the device makes for itself** (Ed25519): the public half is shown, written to `/ssh/id_ed25519.pub` and printed by `ssh status`. - **A real terminal** (`lib/term`, host-tested): enough for a shell, `less`, `top`, `nano`, `vim`. Sixteen colours, scroll regions, the alternate screen, 100 lines of scrollback. - **Q257 as asked: Ctrl with + and - change the text size**, five of them, from 60x20 to 26x8. The far end is told. - **Leaving the App doesn't end the session.** `SSH` shows in the Status Bar. The decisions (Q254 to Q266), the measurements and every check are in `docs/milestones/N1.md`. ## Three things beyond the App - **Keys that aren't characters now carry Shift, Ctrl and Alt** (`key_mapper.cpp`). The terminal needs it for Page Up and Alt+backtick. It also makes two documented keys work from the real keyboard that until now only worked from the Debug Console's `key` command: Ctrl+Fn+up/down in a note, Shift+Tab in Gemini. - **IRC doesn't try to connect with less than 60 KB free.** Started with a session open, its TLS handshake took the free heap down to 236 bytes, six times over. Now it says "not enough memory: close the SSH session" and waits. - **A build script** leaves libssh's own curve25519 out: libsodium (here for WireGuard) defines the same names. ## What it costs | | | |---|---| | Flash | **292 KB** (the trial said 120: signing with the device's key links a 109 KB table). The firmware is at 71% of its slot | | Heap, session open | about 50 KB of 99 KB | | Lowest free heap during a login | 30 KB | | Not started under | 75 KB free: not with IRC connected | ## Checked on the device Against OpenSSH 9.7 in a container: first-time trust (fingerprint compared with the server's), password, `ls`, `top`, `vim`, the five sizes with `stty size`, scrollback, leaving and coming back, Ctrl+C, backtick, both ways of ending, key login ("Accepted publickey" in the server's log), a changed host key (Cancel and Replace), a wrong password, a closed port, bad targets, forgetting a host, IRC waiting while a session is open, memory back to 99 KB after. 559 host tests pass. **Not checked:** the refusal under 75 KB free; a server on the internet or through the VPN; Wi-Fi lost mid-session; servers other than OpenSSH; `nano`, `less`, `tmux`; two-factor prompts; a session left open for hours. ## Docs Guide page and how-to (key login), FAQ, home page, Status Bar, SD card folders, the memory how-to, the Shell page, README, glossary, N1 notes, five screenshots. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
twisla added 1 commit 2026-10-08 02:38:58 +00:00
SSH client: a terminal on another machine (#2)
Site / build (pull_request) Successful in 10s
CI / build (pull_request) Successful in 2m22s
6b71aace4f
The SSH App opens one session to a shell, over libssh (LibSSH-ESP32 5.10.0)
on mbedTLS. A server is trusted the first time on its fingerprint, and a
changed key is a warning with Cancel selected. The password is typed each
time and kept nowhere; or the device makes itself an Ed25519 key, whose
public half is shown, written to /ssh/id_ed25519.pub and printed by
`ssh status`.

lib/term is the terminal: what a shell, less, top, nano and vim send, with
sixteen colours, scroll regions, the alternate screen and 100 lines of
scrollback. Five text sizes with Ctrl and + or -, from 60x20 to 26x8, told
to the far end. The session goes on when the App is left; SSH shows in the
Status Bar. `ssh user@host` in the Shell opens the App.

Also:
- Keys that aren't characters carry Shift, Ctrl and Alt. The terminal needs
  it, and it makes Ctrl+Fn+up/down in a note and Shift+Tab in Gemini work
  from the real keyboard.
- IRC doesn't try to connect under 60 KB free: started with a session open,
  its TLS handshake took the heap down to 236 bytes.
- libssh's own curve25519 is left out of the build (scripts/libssh_filter.py):
  libsodium's has the same names.

Costs 292 KB of flash and about 50 KB of heap while a session is open; not
started under 75 KB free.

Docs: guide page, how-to, FAQ, home page, Status Bar, SD card folders, the
memory how-to, README, glossary, N1 notes with Q254 to Q266 and the checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
twisla added 1 commit 2026-10-08 07:06:43 +00:00
N1: the SSH client ships as v0.22.0
Site / build (pull_request) Successful in 11s
CI / build (pull_request) Successful in 1m49s
079de4aec7
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
twisla merged commit 9dfe675db7 into main 2026-10-08 07:09:12 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: twisla/roro9stack#94