Skip to content

ethernet-gateway v0.6.2

Choose a tag to compare

@github-actions github-actions released this 19 Jun 23:41

Added

  • Session cap and idle timeout are now editable from the telnet Server
    Configuration menu
    (the C and D keys), matching the desktop GUI and the
    web configuration page that already exposed max_sessions /
    idle_timeout_secs — completing three-UI parity for both settings. Idle
    timeout accepts 0 to disable the idle disconnect. The screen's detected-IP
    hint list is now capped so the new row keeps the PETSCII menu within its
    22-row budget even on a multi-homed host (it previously overflowed at three or
    more private addresses).

Security

  • Fixed an SSRF-guard bypass for IPv6-literal URLs in the text-mode web browser. guard_public_url classified IP literals with IpAddr::parse, but url::Url::host_str() returns IPv6 literals bracketed (e.g. [::1]), which fails that parse and fell through to the resolver path — allowing http://[::1]/, http://[::ffff:127.0.0.1]/, and the like to reach loopback / link-local / internal IPv6 services (initial request and every redirect hop). The guard now strips the brackets before classifying, blocking the entire internal IPv6 space. Regression test added. IPv4 literals and DNS names were already handled correctly.
  • SSH: an unauthenticated connection no longer consumes a session slot. new_client incremented the session counter for every inbound TCP connection, before authentication, so a peer that opened many transport handshakes and stalled could exhaust max_sessions and lock out real users. The slot is now claimed only on a successful login (atomic fetch_add + rollback, mirroring the telnet accept loop) and released only if it was claimed — and the cap is now exactly max_sessions (was off-by-one, max_sessions + 1).
  • Web config: POST /save now enforces a same-origin check (CSRF defense-in-depth). A request whose Origin/Referer doesn't match our Host is rejected with 403, blocking a malicious page from riding the operator's cached Basic-auth credentials to rewrite config (including disabling auth). Requests with neither header (non-browser clients such as curl, which can't be a CSRF vector) are still allowed; Basic auth continues to gate them. Lenient-on-absent by design for the trusted-LAN threat model.
  • Kermit server: defense-in-depth subdir re-validation on save. Both the in-session receiver and the standalone (auth-bypassing) Kermit listener now re-check rx.subdir with is_safe_relative_subdir before joining it to the transfer dir. No live traversal existed (subdir is only set after that same check inside the Kermit module), but re-validating at the save site closes the door on any future producer-side bypass — the same belt-and-suspenders rationale as the existing filename re-check.

Fixed

  • Serial console bridge: a stalled telnet peer can no longer wedge server shutdown / port restart. The dedicated serial-reader thread used an unbounded blocking_send onto a bounded channel; when a bridged peer stopped reading and the channel filled, the thread parked past its shutdown/restart checks. It now polls with try_send + a short sleep, bailing on shutdown/restart or when the async pump drops its receiver.
  • Serial modem online mode (TCP): a remote host that stops reading no longer blocks shutdown. online_mode_tcp set only a read timeout, so a full remote receive window parked write_all indefinitely with the loop's shutdown/restart checks unreachable. A 5 s write timeout is now set (matching the duplex path); an expiry drops carrier (NO CARRIER).
  • XMODEM/YMODEM: YMODEM block 0 is now always validated as CRC-16. If block 0 took enough retries to cross the negotiation's CRC→checksum fallback point, the block-0 body (and then the data phase) could be misread as a 1-byte checksum, NAK-looping a CRC-only YMODEM sender to exhaustion. The block-0 read and the post-block-0 data phase are now pinned to CRC-16.
  • Logging survives a poisoned lock. logger now recovers a poisoned mutex (into_inner) instead of silently dropping the line — matching config.rs / gui.rs, and most valuable exactly when a thread has just panicked.
  • Kermit streaming: a sequence-aliased NAK now aborts cleanly instead of silently corrupting the file. In streaming mode the whole file sits in the sender's outstanding-packet set with wrapping (mod-64) sequence numbers, so a file larger than ~64 chunks aliases each seq across many packets. On a genuine mid-stream NAK/loss the sender matched the NAKed seq to the first (oldest) outstanding packet sharing it and retransmitted that stale packet; the receiver appends D-packets by sequence with no position field, so it landed the wrong data at the wrong offset. This was benign on lossless TCP/SSH (streaming's intended transport, where NAKs don't occur) and only reachable on an unreliable link such as a serial bridge. An unresolvable NAK now aborts with an actionable error ("disable kermit_streaming for this peer"); the timeout-driven retransmit path skips aliased seqs for the same reason. The reliable-transport happy path is unchanged.
  • ZMODEM: ZFERR (0x0C) is now handled instead of ignored. A sender's file read/write-error frame aborts the receive cleanly with an informative error rather than falling through to the ignore arm and waiting out a frame timeout. Every Forsberg 1988 frame is now handled.
  • Text-mode web browser: fixed a remote-triggerable panic on Back. Returning to a previous page whose re-fetched content is shorter than the saved scroll position could index past the page and panic the session task. The scroll position is now clamped on restore and again defensively at render time.

Documentation

  • Documented ZMODEM ZCOMMAND (frame 0x12) as the one optional spec frame deliberately not implemented — it is recognized but always refused (non-zero ZCOMPL), since arbitrary /bin/sh -c execution on a shared, long-lived host is an unacceptable default; use SSH for shell access. Noted in the user manual and the ZMODEM web reference.
  • Documented previously-undocumented config keys: web_enabled, web_port, gateway_debug, and ssh_gateway_auth in the README config reference, and punter_max_bad_rounds / punter_hangup_on_failure in the user manual. Added the now-handled ZFERR frame to the ZMODEM web reference, and corrected the SSH reference's auth_password lifecycle description to match the new claim-slot-on-successful-login behavior.
  • README config-reference completeness pass: the "All options" egateway.conf sample now lists disable_ip_safety and the per-port serial_a_petscii_translate / serial_b_petscii_translate keys (all three are written by the config saver), the telnet Server-Configuration menu walkthrough documents the new session-cap / idle-timeout keys, and the Other Settings list now includes the gateway debug-trace toggle.