Skip to content

ESP32-S3 native SSH transport for the shared device shell #33

Open

Description

@atomicdeploy

Requested native SSH directly on ESP32-S3, reusing the current shell/TUI and command owners. Related #29 and #2. Source implementation only in this side task; no production flash is authorized here.

  • Optional application-only build flag and pinned LibSSH-ESP32 dependency.
  • Persistent per-device host key; required SSH authentication even when HTTP auth is disabled; no keys or passwords in responses/logs.
  • Bounded worker/queues, session leases, security-revision fencing, shared shell/TUI, Telnet and USB recovery retained.
  • Durable enable/port settings, unversioned API, shell properties and SSH service discovery.
  • Focused regression tests and ESP32-S3 enabled/disabled builds; exact scoped resource/compile evidence in docs/SSH.md and the reuse receipt (not live device acceptance).
  • Separately authorized device deployment, OpenSSH login, wrong-password/host-key stability, resize/TUI and concurrency/LED acceptance.

Implemented source scope is interactive SSH plus gated transactional SCP uploads/downloads, a bounded SFTP put/get/list/stat/timestamp subset, and independently gated passive FTP. These share the managed public /user namespace (128 KiB/file), chunk readback, SHA-256 publication and maintenance ownership; no private settings, raw flash, arbitrary OS execution or forwarding. Build flags exclude all services by default; included listeners require saved runtime opt-in. FTP is plaintext and always requires configured credentials; prefer SSH/SFTP outside trusted LANs. Live ESP encrypted transfers, heap/TLS/LED coexistence and deployment remain unchecked. The checked implementation items below are source/fixture results, not live acceptance. Dependency: ewpa/LibSSH-ESP32 5.10.0 at 343fce1c5d1d0e3d629807dece6ae1b68ef1d322 (libssh 0.11.5). Arduino archive SHA256 e1b6ab338ff2087ab4427363350849416c371f90ae675d1304c6b78721e5b9e3. Upstream security release history reviewed; library recommends disabling SDK hardware SHA for concurrency, so crypto/LED coexistence remains a real hardware gate, not a passed source claim.

Activity

  1. atomicdeploy commented on Oct 27, 2026

    @atomicdeploy
    OwnerAuthor

    Source implementation is present in the shared checkout (not yet committed/deployed): -S3Ssh / PAKAR_SSH_ENABLED; native libssh worker; persistent unique ECDSA host key in protected NVS; mandatory SSH username/password auth independent of HTTP enabled state; bounded session/revision queues, PTY resize, one interactive session, shared DeviceShellSession/TUI/commands; persistent enabled/port settings, /api/ssh and /api/shell status, ssh.enabled/ssh.port descriptors, _ssh._tcp discovery. Telnet/USB retained. Exec/SFTP/forwarding explicitly unsupported.

    Passed tools/test-ssh.ps1: actual portable policy, actual settings owner with NVS test double, actual production transport parsed against the pinned real LibSSH-ESP32 public headers. Passed tools/test-shell.ps1 and tools/test-shell-properties.ps1 including new SSH-enabled descriptor profile, preauthenticated initializer and mDNS registration fixtures. No encrypted SSH login or physical acceptance is claimed.

    Canonical S3 Plan is blocked by concurrent LedGrid.cpp evidence drift (esp32WS2811 mapping), after narrow review/rebinding of SSH-affected dependency/shell targets. Main-chat mini-game source/build additions are preserved, not overwritten or certified. Full enabled/disabled target link, RAM/crypto coexistence, authorized deployment and real OpenSSH acceptance remain open. Conservative resource admission: 90,000 free internal heap before starting the 24 KiB worker; low-memory starts report a failure rather than silently exhausting the board. Production firmware, running game, LEDs, apps and Telnet session have not been changed by this source task.

  2. atomicdeploy commented on Oct 28, 2026

    @atomicdeploy
    OwnerAuthor

    Native SSH/SCP checkpoint 4028373 — 2026-10-28

    Pushed 4028373 in PR #27. Preserved unrelated native/mobile drafts and edits; no production device/app/router was changed.

    • -S3Ssh / PAKAR_SSH_ENABLED includes native SSH; -S3Scp / PAKAR_SCP_ENABLED additionally includes read-only SCP. No flags = omitted; SCP without SSH and network-disabled SSH builds are rejected. Included listener remains disabled until explicitly configured. /api/ssh and shell/TUI enable/port settings report actual state; _ssh._tcp is advertised only while listening.
    • One authenticated password-based session/channel, unique persistent ECDSA host key with SHA256 fingerprint, 24 KiB low-priority crypto task, bounded queues/deadlines, security-revision and boot-local session fencing. Commands continue through the existing loop-owned shell/TUI and owners, preserving Telnet/framed USB recovery.
    • Inspected actual pinned libssh bind/options/channel code and fixed two integration hazards: explicitly set the listening FD nonblocking (the upstream setter changes only a flag), and boundedly flush final close/exit packets. No SDK-wide crypto or concurrency settings were silently changed.
    • SCP supports one exact /user/name public managed file per connection, raw binary and empty files, queue backpressure and read/hash/revision checks via the existing UserFileStore. Private settings/host keys/firmware partitions, uploads, recursion, preserved timestamps, arbitrary exec, SFTP and FTP remain unsupported and are explicitly reported. Use the existing integrity-checked file API for uploads. No plaintext FTP listener is added.
    • After an approved install, use set ssh.enabled true, then ssh -tt <configured-device-user>@keycontroller.local. Public file example: scp -O -P 22 <configured-device-user>@keycontroller.local:/user/example.bin ./. Same configured device username/password required even if HTTP auth is disabled. See docs/SSH.md for flags, identity and limits.

    Verification:

    • tools/test-ssh.ps1 passed policy, actual NVS settings with doubles, actual transport compilation against LibSSH-ESP32 5.10.0 with SCP included/excluded, protocol bytes/ACK/backpressure, and actual SCP binding + public file store with filesystem/transport doubles.
    • The real OpenSSH SCP client downloaded exact binary and zero-byte files over a stdio fixture. This is protocol compatibility, NOT an encrypted board session. Windows fixture stdio is explicitly binary to avoid CRT CRLF rewriting.
    • Shell/TUI/property/lease/audio-dispatch/DNS-SD regressions, script tooling/syntax and docs checks pass. Owned staged-source projection also passed the new transport/file tests. Existing donor ledger/report/receipt updated with exact target hashes and a new issue ESP32-S3 native SSH transport for the shared device shell #33 consultation route.
    • Final SSH+SCP ESP32-S3 SDK 3.3.12 build passed after socket fixes: 2,657,491 / 3,342,336 program bytes; 129,204 / 327,680 static RAM. Live heap/crypto budget is not measured by these figures. Buffered UART, 16 MB/OPI, keycontroller, GPIO+RMT included, Ethernet included, BLE disabled; no runtime instance settings were applied. SHA256 ea17dba7e1c44afb157d48ee763df8fb76f8804dd0b03d0628fff679960126b7.
    • Final excluded SDK rebuild is not claimed in this continuation; excluded shell/policy fixtures pass and CI now compiles the opt-in variant before restoring the ordinary artifact. The prior unrelated AVR contract-mapping CI failure is not declared repaired.

    Blocker: ASUS localhost:8022 repeatedly refused SSH. No authorized board SSH login, NVS host-key persistence, wrong-password, PTY resize or encrypted SCP/hardware/API/UART/LED/TLS coexistence test could be performed. Production deployment remains subject to the existing explicit approval hold. Source/fixtures/SDK linking do not close live acceptance. Transactional SCP uploads, SFTP and optional FTP remain separate unfinished capabilities, not hidden stubs advertised as complete.

  3. atomicdeploy commented on Oct 28, 2026

    @atomicdeploy
    OwnerAuthor

    Checkpoint b09650e3b424a2dac87b18581c404ef04c6e56d3 pushed to PR #27. Implemented real SCP uploads over SSH, SFTP v3 file operations and passive FTP using the shared protected public-file store. Flags: -S3Ssh -S3Scp -S3Sftp / independent -S3Ftp; excluded by default, persistent runtime opt-in when included. No additional FTP/SFTP dependency beyond the pinned existing SSH port.

    Measured SDK profile (table, flash16/OPI, buffered UART0, Ethernet/RGB48, both LED backends/RMT default, BLE off):

    Build Raw image bytes Static RAM bytes
    Ordinary 2,387,744 140,156
    FTP 2,401,440 144,748
    SSH/SCP/SFTP/FTP 2,694,000 147,556

    OTA capacity 3,342,336 bytes; full option 80.60%. FTP overhead +13,696 flash/+4,592 static RAM; full bundle +306,256/+7,400. Dynamic worker/crypto memory is separate: SSH stack 24 KiB, admission 90,000 free internal heap, SFTP receive buffer 33,024 bytes preferring PSRAM. These are not live free-heap observations. Exact hashes/profiles and client commands: docs/SSH.md. Ordinary artifact restored in the same canonical cache.

    Passed tools/test-ssh.ps1, tools/test-user-files.ps1, actual shell service fixtures for both architectures, and all three canonical SDK builds. Real OpenSSH clients exercised SCP binary/empty uploads and SFTP default-buffer 65 KiB put/list/get roundtrip over stdio. Actual FTP binding doubles exercised same-IP passive admission, byte integrity, partial sends, abort/reset, deadlines, NVS opt-in and auth/flash-fence cleanup. These are not real encrypted ESP sockets or hardware acceptance.

    No board flash/reboot/configuration/output, ASUS/tablet or app deployment occurred. Live transfers, identity persistence and runtime heap/TLS/LED acceptance remain open; no merge or production-issue closure. Unrelated local desktop/mobile edits preserved. Repository-wide CI is not claimed green (the prior AVR source-certificate mismatch is separate).

  4. atomicdeploy commented on Oct 29, 2026

    @atomicdeploy
    OwnerAuthor

    SSH exec / direct TUI checkpoint: 2e5c9da on the existing PR #37 branch.

    • Ordinary authenticated ssh USER@BOARD status and ssh USER@BOARD 'get hostname' requests use the same loop-owned DeviceShellSession/command dispatcher as interactive SSH, Telnet and framed USB.
    • ssh -t USER@BOARD tui (or edit) launches the actual contextual TUI directly. Missing PTY produces an actionable failure; resize/navigation/exit use existing owners. Exiting closes the exec channel, not an unexpected second prompt.
    • Bounded printable command, no banner/prompt/editor echo for exec, nonzero command failures, no command replay/chaining/OS shell, stdin-EOF-safe output draining before exit status, and no late watch/resize redraw after closure starts.
    • Existing authentication/security-revision, maintenance, SCP/SFTP/public-file and default-off inclusion/runtime opt-in policies retained. /api/ssh advertises exec and bounds truthfully.
    • tools/test-ssh.ps1, tools/test-shell.ps1, living-contract guard and hash-bound reuse/comparison checks passed. New fixtures compile actual transport/dispatcher/SSH/TUI functions for both roles. Queue/socket/FS/peripheral doubles and OpenSSH-over-stdio are explicitly not encrypted ESP login evidence.
    • Canonical ESP32-S3 keycontroller build with all four optional services, existing 16 MiB/OPI/buffered-UART/W5500/both-LED-backend/acknowledged-ISP profile and BLE initialization excluded passed. Raw image 2,734,096 / 3,342,336 bytes (81.80%); static RAM 136,436 bytes, not runtime free heap. SHA-256 6715191bb505fcc587673e0c37c102619ff35d719d79f1e96507882dc0b02ed1.
    • Live encrypted SSH one-line commands/exit codes, direct TUI navigation/resize/reconnect, host-key stability and resource/LED coexistence on a separately deployed board remain unverified. No production board/client deployment or actuation occurred in this checkpoint. Issue ESP32-S3 native SSH transport for the shared device shell #33 remains open.

    Documentation and exact source/test hashes are in docs/SSH.md and the existing donor evidence/receipt. No concurrent PortableShell integration checkout or vendored component was replaced. This is an SSH-enabled build candidate, not permission to alter a production instance's enabled services or scene.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions