diff --git a/build/dependencies.lock b/build/dependencies.lock index 00a1068ea..8962c6196 100644 --- a/build/dependencies.lock +++ b/build/dependencies.lock @@ -208,8 +208,8 @@ legacy_channels = ["development"] manifest = "build/legacy-manifest.json" schema = 1 component_count = 333 -file_count = 1975 -byte_count = 261293981 +file_count = 1974 +byte_count = 261292177 source_build_components = 232 unresolved_components = 101 inherited_baseline = "07505ea58c7bba698d6b9220ff43946a43cac76b" diff --git a/build/legacy-manifest.json b/build/legacy-manifest.json index 2933c1a16..536baaf32 100644 --- a/build/legacy-manifest.json +++ b/build/legacy-manifest.json @@ -2346,9 +2346,9 @@ "id": "runtime-tmp-update-script-network", "kind": "runtime", "path": "static/build/.tmp_update/script/network", - "file_count": 6, - "byte_count": 26804, - "tree_sha256": "a48e8edfed153f6be89800965423c37ec8732217ed0047c40f5f73cd2b5f06a2", + "file_count": 5, + "byte_count": 25000, + "tree_sha256": "0a925e68531db9099042ecf3ffbb3af5249cc5ae3ed2001c1468ca4eb9b99e0e", "source": "https://github.com/OnionUI/Onion", "source_revision": "07505ea58c7bba698d6b9220ff43946a43cac76b", "license": "GPL-3.0-only", diff --git a/docs/1.0_TEST_MATRIX.md b/docs/1.0_TEST_MATRIX.md index 698edb4f2..6886fcada 100644 --- a/docs/1.0_TEST_MATRIX.md +++ b/docs/1.0_TEST_MATRIX.md @@ -52,7 +52,7 @@ shoulder button. | Critical lifecycle | Exact 640x480 and 752x560 built-in projections; source/target/path and legacy-file rejection; boot/shutdown/save/low-battery/recovery/Safe Mode ignore theme/config/media; charging reflects bounded actual level; installer uses one deterministic surface; missing optional text/font fallback; signed Full-update boot/charging/shutdown/recovery checkpoint | | Settings | One sectioned surface; inline values; capability filtering; one-layer details; hidden Developer section; optional overlapping L1/R1 list paging | | Quick Settings | START from core surfaces; immediate brightness/volume/mute; capability-gated Wi-Fi opens the dedicated detail surface; Wi-Fi left/right never mutates the radio; readable battery; B/START close | -| Network services | Desired/runtime separation; carrier without IPv4 remains acquiring/not-ready; canonical DHCP restart and bounded post-address listener reconciliation; SSH shell and SFTP independent key-only states; canonical transfer roots and modes; Saves read-only; private roots denied; traversal/symlink/path bounds; same-filesystem atomic publication; authorized-key import; quiesce/health; stale FTP/Telnet/FileBrowser/inherited-Samba/WPS/hotspot flags cannot activate listeners; process-aware listener audit; dormant FileBrowser HTTP and rejected Samba payloads absent from newly assembled stable artifacts while older-card remnants remain locked down | +| Network services | Desired/runtime separation; carrier without IPv4 remains acquiring/not-ready; canonical DHCP restart and bounded post-address listener reconciliation; SSH shell and SFTP independent key-only states; canonical transfer roots and modes; Saves read-only; private roots denied; traversal/symlink/path bounds; same-filesystem atomic publication; authorized-key import; quiesce/health; stale FTP/Telnet/FileBrowser/inherited-Samba/WPS/hotspot flags cannot activate listeners; process-aware listener audit; dormant Telnet launcher/Tweaks exposure, FileBrowser HTTP, and rejected Samba payloads absent from newly assembled stable artifacts while older-card remnants remain locked down | | Wi-Fi profile store | JFFS2 private root; stdin-only bounded replacement and `bloomctl network profile upsert ID`; requested/document ID binding; explicit `network forget ID`; inactive-ID deletion with active-profile refusal; active forget only after a separately confirmed fallback connection; schema/unknown-field/count/size enforcement; WPA2-PSK, explicit open, and manual hidden WPA2; WEP and hidden open denial; unique IDs/SSIDs; redacted status; explicit local credential-free UI list with one active marker; sanitized `network connect status` with internal profile-handle validation and public omission; mode-0600 atomic single-profile supplicant projection; symlink, occupied-slot, live-lock, invalid-profile, and prior-byte preservation | | Wi-Fi scan API | Asynchronous start; redacted status; explicit ID-scoped local results; cancel and terminal discard; one active worker; five-second rate limit; 15-second runtime; 64-KiB raw ceiling; 32 unique printable SSIDs; eight-operation history; open/WPA2-PSK/unsupported classification; duplicate signal reconciliation; backend failure, timeout, oversize, unsafe-path, stale/live-lock, and unsupported-hardware handling | | Wi-Fi UI | Original Mini hidden; Settings, Shell Quick Settings, and GameSwitcher Quick Settings converge on `--settings-wifi`; direct radio toggle removed; bounded fixed-argv profile-list load outside render; connection state and saved-network detail; selectable Scan/Cancel row and read-only discovered networks; active-only 100-ms SDL wake; deferred GameSwitcher until cancellation discard; single-flight nonblocking fixed-argv scan client; 16-KiB output and five-second deadline; child process-group cleanup; controller-owned start/status/results/discard and cancel-during-start sequencing; 250-ms status opportunities; exact profile/scan/ack schemas; 16 profiles and 32 networks; unique bounded IDs/SSIDs; one active profile; fixed scan phases/errors; terminal history discarded; open/WPA2 profile form with shared keyboard, masked secret, fixed profile-upsert argv, escaped stdin JSON, strict ID/SSID/PSK validation, explicit secret clearing, nonblocking submit/poll, 4-KiB acknowledgement cap, exact upsert response, timeout process-group cleanup, exact saved-ID reuse, 104-bit no-follow random new handles, collision/security/full-store rejection, one editing/submitting controller with 100-ms poll opportunities, exact cancellation, terminal clearing, bounded focus return, supported scan-result selection, explicit saved-not-connected result, and no implicit association; explicit inactive-profile X/confirm forget flow; active-row refusal in Shell and store; fixed nonblocking delete; exact acknowledgement; terminal projection reload; graceful TERM cleanup before bounded KILL; exact guarded-connect status model with fixed phases/operations/failures, lease consistency, 64-byte transaction-ID and 300-second deadline ceilings, and discarded transaction/overlay identity; fixed no-follow `network connect status` loader with less-than-4-KiB output, five-second read ceiling, and stale-state clearing; separately typed single-flight nonblocking status request with process-group timeout and generic-poller refusal; controller-owned single request, 100-ms opportunities, duplicate-begin refusal, typed terminal state, teardown reaping, explicit guarded-state presentation, one-second freshness, fail-closed mutation gating for stale/unavailable/lease-armed/rollback-failed results, read-only refresh without queued intent, and exit teardown; credential and unknown-field rejection; passwords absent from arguments, logs, screenshots, durable Shell state, and evidence | diff --git a/docs/SECURITY.md b/docs/SECURITY.md index 1cf60c841..b72e57bc6 100644 --- a/docs/SECURITY.md +++ b/docs/SECURITY.md @@ -21,6 +21,9 @@ process-aware check that names service classes without publishing addresses. The dormant FileBrowser executable, database, web theme, icon, and boot-time initializer are excluded from newly assembled stable payloads; detection and process cleanup remain for rollback-compatible remnants on older cards. +The inherited Telnet environment launcher, dormant start logic, and visible +Tweaks toggle are also excluded; stale-state cleanup and exact BusyBox +`telnetd` termination remain for older-card compatibility. The reviewed key-only Dropbear transport is the only stable remote listener; SFTP is independently gated and confined through that same transport. Its chroot is materialized from the versioned canonical transfer policy rather diff --git a/src/tweaks/appstate.h b/src/tweaks/appstate.h index 92234c08c..ab11096b9 100644 --- a/src/tweaks/appstate.h +++ b/src/tweaks/appstate.h @@ -17,7 +17,6 @@ bool isMenu(List *target) static List _menu_network; static List _menu_wifi; -static List _menu_telnet; static List _menu_ftp; static List _menu_wps; static List _menu_http; @@ -28,7 +27,6 @@ void menu_network_free_all(void) { list_free(&_menu_network); list_free(&_menu_wifi); - list_free(&_menu_telnet); list_free(&_menu_ftp); list_free(&_menu_wps); list_free(&_menu_http); diff --git a/src/tweaks/network.h b/src/tweaks/network.h index 5e3d2a4ed..344fb8527 100644 --- a/src/tweaks/network.h +++ b/src/tweaks/network.h @@ -29,7 +29,6 @@ static struct network_s { bool smbd; bool http; - bool telnet; bool ftp; bool hotspot; bool ntp; @@ -55,7 +54,6 @@ void network_loadState(void) network_state.smbd = config_flag_get(".smbdState"); network_state.http = config_flag_get(".httpState"); - network_state.telnet = config_flag_get(".telnetState"); network_state.ftp = config_flag_get(".ftpState"); network_state.hotspot = config_flag_get(".hotspotState"); network_state.ntp = config_flag_get(".ntpState"); @@ -260,11 +258,6 @@ void network_setFtpState(void *pt) network_commonEnableToggle(&_menu_ftp, (ListItem *)pt, &network_state.ftp, "ftp", ".ftpState"); } -void network_setTelnetState(void *pt) -{ - network_commonEnableToggle(&_menu_telnet, (ListItem *)pt, &network_state.telnet, "telnet", ".telnetState"); -} - void network_setHotspotState(void *pt) { network_setState(&network_state.hotspot, ".hotspotState", ((ListItem *)pt)->value); @@ -643,15 +636,6 @@ void menu_network(void *_) "between BloomOS and a PC, phone, or tablet.\n" "You'll need an FTP client installed on the\n" "other device."); - list_addItemWithInfoNote(&_menu_network, - (ListItem){ - .label = "Telnet: Remote shell", - .item_type = TOGGLE, - .disabled = !settings.wifi_on, - .value = (int)network_state.telnet, - .action = network_setTelnetState}, - "Telnet provides unencrypted remote shell\n" - "access to your device."); list_addItemWithInfoNote(&_menu_network, (ListItem){ .label = "VNC: Screen share...", diff --git a/src/tweaks/tweaks.c b/src/tweaks/tweaks.c index b6e00e0ee..df1a066fb 100644 --- a/src/tweaks/tweaks.c +++ b/src/tweaks/tweaks.c @@ -46,7 +46,6 @@ void check_networkChanged(void) { bool modified = temp_flag_get("network_changed"); modified |= check_menuHasChanges(&_menu_network); - modified |= check_menuHasChanges(&_menu_telnet); modified |= check_menuHasChanges(&_menu_ftp); modified |= check_menuHasChanges(&_menu_http); modified |= check_menuHasChanges(&_menu_date_time); diff --git a/static/build/.tmp_update/script/network/telnetenv.sh b/static/build/.tmp_update/script/network/telnetenv.sh deleted file mode 100644 index 8900a898d..000000000 --- a/static/build/.tmp_update/script/network/telnetenv.sh +++ /dev/null @@ -1,17 +0,0 @@ -# This file will launch telnet with the following env vars following without the need to login. -# hwclock may still need to be synced with hwclock -w -# It should also pull the TZ from the process that starts it (in the usual case, update_networking.sh) - -export sysdir="/mnt/SDCARD/.tmp_update" -export miyoodir="/mnt/SDCARD/miyoo" -export LD_LIBRARY_PATH="/lib:/config/lib:$miyoodir/lib:/customer/lib:$sysdir/lib:$sysdir/lib/parasyte:/sbin:/usr/sbin:/bin:/usr/bin" -export PATH="$sysdir/bin:$PATH" -export USER=root -export TERM=vt102 -export SHELL=/bin/sh -export PWD=/mnt/SDCARD -export HOME=/mnt/SDCARD/ -cd /mnt/SDCARD - -echo -e "Welcome to Onion\n " -/bin/sh diff --git a/static/build/.tmp_update/script/network/update_networking.sh b/static/build/.tmp_update/script/network/update_networking.sh index e2c988083..64705e4a4 100644 --- a/static/build/.tmp_update/script/network/update_networking.sh +++ b/static/build/.tmp_update/script/network/update_networking.sh @@ -299,39 +299,6 @@ check_sshstate() { disable_flag authsshState } -# Starts telnet if the toggle is set to on -# Telnet is generally already running when you boot your MMP. This will kill the firmware version and launch a passworded version if auth is turned on, if auth is off it will launch a version with env vars set -check_telnetstate() { - if is_running_exact "telnetd -l sh"; then - pkill -9 -f "telnetd -l sh" - log "Telnet: Killing firmware telnetd process" - sleep 1 # Wait for the process to die - fi - - if flag_enabled telnetState; then - if is_running telnetd; then - if wifi_disabled; then - log "Telnet: Wifi is turned off, disabling the toggle for Telnet and killing the process" - disable_flag telnetState - killall -9 telnetd - fi - else - if wifi_enabled; then - sync - log "Telnet: Starting telnet" - telnetd -l $netscript/telnetenv.sh - else - disable_flag telnetState - fi - fi - else - if is_running telnetd; then - killall -9 telnetd - log "Telnet: Killed" - fi - fi -} - # Starts the hotspot based on the results of check_hotspotstate, called twice saves repeating # We have to sleep a bit or sometimes supllicant starts before we can get the hotspot logo # Starts AP and DHCP diff --git a/test/shell/ci_validation.bats b/test/shell/ci_validation.bats index d39e896b4..15df9c128 100644 --- a/test/shell/ci_validation.bats +++ b/test/shell/ci_validation.bats @@ -111,3 +111,19 @@ [ "$status" -eq 0 ] [ "$output" = "full" ] } + +@test "stable Telnet launcher removal keeps packaging exhaustive and cppcheck scoped" { + scope=/workspace/tools/ci-scope.sh + run sh -c "printf '%s\n' static/build/.tmp_update/script/network/telnetenv.sh | '$scope' build" + [ "$status" -eq 0 ] + [ "$output" = "full" ] + run sh -c "printf '%s\n' static/build/.tmp_update/script/network/telnetenv.sh | '$scope' static-analysis" + [ "$status" -eq 0 ] + [ "$output" = "none" ] + run sh -c "printf '%s\n' static/build/.tmp_update/script/network/telnetenv.sh | '$scope' risk" + [ "$status" -eq 0 ] + [ "$output" = "3" ] + run sh -c "printf '%s\n' static/build/.tmp_update/script/network/telnetenv.sh | '$scope' shell-tests" + [ "$status" -eq 0 ] + [ "$output" = "full" ] +} diff --git a/test/shell/listener_lockdown.bats b/test/shell/listener_lockdown.bats index a9898c592..88d95cf61 100644 --- a/test/shell/listener_lockdown.bats +++ b/test/shell/listener_lockdown.bats @@ -90,6 +90,27 @@ EOF ! grep -Fq -- '5000' "$calls" } +@test "stable payload exposes no Telnet launcher or Tweaks toggle" { + network=/workspace/static/build/.tmp_update/script/network/update_networking.sh + tweaks=/workspace/src/tweaks/network.h + + [ ! -e /workspace/static/build/.tmp_update/script/network/telnetenv.sh ] + ! grep -F 'check_telnetstate()' "$network" + ! grep -F 'telnetd -l' "$network" + grep -F 'disable_flag telnetState' "$network" + grep -F 'stop_busybox_telnet' "$network" + ! grep -F 'network_state.telnet' "$tweaks" + ! grep -F 'network_setTelnetState' "$tweaks" + ! grep -F 'Telnet: Remote shell' "$tweaks" + telnet_doc=/workspace/website/docs/07-apps/03-network-features/05-telnet.md + grep -F 'BloomOS does not ship or start Telnet' "$telnet_doc" + grep -F '/docs/network/ssh' "$telnet_doc" + ! grep -F 'Enabling Telnet' "$telnet_doc" + ! grep -Fi 'telnet' /workspace/website/docs/01-features/index.md + ! grep -Fi 'telnet' /workspace/website/docs/07-apps/01-included-in-onion/tweaks.mdx + ! grep -Fi 'telnet' /workspace/website/docs/07-apps/03-network-features/06-hotspot.md +} + @test "stable compatibility reconciliation ignores stale flags and stops inherited processes" { root="$BATS_TEST_TMPDIR/root" sysdir="$root/mnt/SDCARD/.tmp_update" diff --git a/test/test_retroarch_build_identity.py b/test/test_retroarch_build_identity.py index 7ab8cf4e9..d3e2dda86 100644 --- a/test/test_retroarch_build_identity.py +++ b/test/test_retroarch_build_identity.py @@ -37,8 +37,8 @@ def test_identity_is_stable_for_unrelated_inventory_totals(self): changed = LOCK.read_text(encoding="utf-8") changed = changed.replace("component_count = 333", "component_count = 999") - changed = changed.replace("file_count = 1975", "file_count = 9999") - changed = changed.replace("byte_count = 261293981", "byte_count = 999999999") + changed = changed.replace("file_count = 1974", "file_count = 9999") + changed = changed.replace("byte_count = 261292177", "byte_count = 999999999") self.assertNotEqual(changed, LOCK.read_text(encoding="utf-8")) with tempfile.TemporaryDirectory() as directory: candidate = pathlib.Path(directory) / "dependencies.lock" diff --git a/tools/ci-scope.sh b/tools/ci-scope.sh index 95408d937..8654a113a 100755 --- a/tools/ci-scope.sh +++ b/tools/ci-scope.sh @@ -287,6 +287,11 @@ while IFS= read -r path; do # unrelated C/C++ static-analysis expansion. [ "$mode" != build ] || full=1 ;; + static/build/.tmp_update/script/network/telnetenv.sh) + # Retiring the inherited root-shell launcher changes the assembled + # stable payload and therefore retains the complete ARM gate. + [ "$mode" != build ] || full=1 + ;; build/dependencies.lock|build/legacy-manifest.json|build/core-selection-policy*.json|\ build/core-inventory-disposition*.json|\ build/save-migration-policy*.json|\ @@ -503,6 +508,13 @@ while IFS= read -r path; do add_shell_target /workspace/test/shell/provenance_policy.bats add_shell_target /workspace/test/shell/fat_payload.bats ;; + static/build/.tmp_update/script/network/telnetenv.sh) + raise_risk 3 + add_shell_target /workspace/test/shell/listener_lockdown.bats + add_shell_target /workspace/test/shell/legacy_manifest.bats + add_shell_target /workspace/test/shell/provenance_policy.bats + add_shell_target /workspace/test/shell/fat_payload.bats + ;; test/test_bloom_ui_system_view.cpp|src/bloomUi/bloom_ui_system_view.c|src/bloomUi/bloom_ui_system_view.h) raise_risk 1 add_native_filter 'BloomUiSystemView*' diff --git a/website/docs/01-features/index.md b/website/docs/01-features/index.md index 307af7398..2984b48f0 100644 --- a/website/docs/01-features/index.md +++ b/website/docs/01-features/index.md @@ -210,7 +210,7 @@ For the Miyoo Mini Plus (equipped with wifi) Onion offers many additional possib - [Automatic date/time synchronisation](apps/tweaks#set-automatically-via-the-internet) (NTP, via Tweaks app) - [Retroachivements](https://www.retroarch.com/?page=achievements) - [Scraper](/docs/apps/scraper): import game covers directly from your MMP -- [Network Services](network-features): [Samba/SMB share](network/samba), [http server](network/http), [SSH](network/ssh), [FTP](network/ftp), [Telnet](network/telnet), [Hotspot](network/hotspot), [VNC server](network/vnc)... +- [Network Services](network-features): [Samba/SMB share](network/samba), [http server](network/http), [SSH](network/ssh), [FTP](network/ftp), [Hotspot](network/hotspot), [VNC server](network/vnc)... ::: diff --git a/website/docs/07-apps/01-included-in-onion/tweaks.mdx b/website/docs/07-apps/01-included-in-onion/tweaks.mdx index 8e465f9b1..d2b88df35 100644 --- a/website/docs/07-apps/01-included-in-onion/tweaks.mdx +++ b/website/docs/07-apps/01-included-in-onion/tweaks.mdx @@ -204,12 +204,6 @@ It can be MainUI, [GameSwitcher](./game-switcher), [Retroarch](./retroarch) or [
-### Telnet: Remote shell - -
Telnet provides unencrypted remote shell access to your device.
-
-
- ### VNC: Screen share
Share your MMP Screen to another device for demonstrations or applications or themes (The MMP does not have the performance to stream game footage through this feature).
diff --git a/website/docs/07-apps/03-network-features/05-telnet.md b/website/docs/07-apps/03-network-features/05-telnet.md index 8317782a9..40cdff061 100644 --- a/website/docs/07-apps/03-network-features/05-telnet.md +++ b/website/docs/07-apps/03-network-features/05-telnet.md @@ -2,47 +2,13 @@ slug: /network/telnet --- -# Telnet +# Telnet (retired) -*![](https://github.com/OnionUI/Onion/assets/47260768/62ee0d6c-1cce-43a4-976a-c8212850bf2f)* +BloomOS does not ship or start Telnet. The inherited listener provided an +unencrypted root shell and has been retired from current stable payloads. -Telnet provides an unencrypted command line method to communicate with your Miyoo Mini+. +Use the reviewed public-key-only [SSH / SFTP service](/docs/network/ssh) for +remote access. BloomOS still detects and stops Telnet remnants on older cards. - -## Features - -*![](https://github.com/OnionUI/Onion/assets/47260768/64e1bf60-3670-4e84-b0f8-89f3575cc378)* - -- Command-Line Interface - -- Scripting and automation - -- Debugging and troubleshooting - - -## Enabling Telnet - -You'll find it in **Apps** › **Tweaks** › **Network** › **Telnet** - -This is a master level toggle only and does not contain a submenu. - - -## Connecting - -Once you've activated your telnet server in Tweaks you'll now be able to connect using software such as PuTTY, SolarPuTTY, Hyperterm. - -You'll need the IP of the device, found below (**Tweaks** › **Network**) - -![](https://github.com/OnionUI/Onion/assets/47260768/94f2ab4f-f776-4bb3-9edf-fa05ef0a88ba) - - -## Authentication - -We've made the choice to remove authentication on Telnet as it is insecure and will transmit the password in plain text - Telnet is now disabled by default. - - -## Security - -:::caution Network security -Although we've taken every precaution to offer as much security as possible, remember to keep your Onion safe. It is not recommended you use telnet on an insecure Wi-Fi network that is open or public as traffic is unencrypted and transported in plain text, for this reason we strongly recommend you toggle telnet off when you're on the move! -::: +The earlier Onion 4.2 behavior remains available in the versioned historical +documentation. diff --git a/website/docs/07-apps/03-network-features/06-hotspot.md b/website/docs/07-apps/03-network-features/06-hotspot.md index edb2176e7..0d9a9c4fe 100644 --- a/website/docs/07-apps/03-network-features/06-hotspot.md +++ b/website/docs/07-apps/03-network-features/06-hotspot.md @@ -4,7 +4,7 @@ slug: /network/hotspot # Hotspot -Your Miyoo Mini Plus just got a lot more portable. SSH/Telnet, HTTP file server, FTP on the go, no extra devices needed. Stay connected with ease, anytime, anywhere. +Your Miyoo Mini Plus just got a lot more portable. SSH, HTTP file server, and FTP on the go, no extra devices needed. Stay connected with ease, anytime, anywhere. Compatible with Netplay (best paired with [Easy Netplay](../multiplayer/easynetplay) There are reports of issues with hotspot on firmware levels below `2023 05 05``.