From ccbdca4a310968802eef83fc88247cb209425597 Mon Sep 17 00:00:00 2001 From: boburning Date: Mon, 31 Aug 2026 03:40:25 -0400 Subject: [PATCH] security(network): retire inherited hotspot controls (NET-10) --- build/dependencies.lock | 8 +- build/legacy-manifest.json | 43 +--------- docs/1.0_TEST_MATRIX.md | 2 +- docs/SECURITY.md | 3 + src/tweaks/appstate.h | 4 - src/tweaks/network.h | 75 +----------------- src/tweaks/tweaks.c | 6 +- static/build/.tmp_update/res/wpsconnected.png | Bin 11672 -> 0 bytes static/build/.tmp_update/res/wpsfail.png | Bin 10953 -> 0 bytes static/build/.tmp_update/res/wpstrying.png | Bin 11409 -> 0 bytes .../script/network/update_networking.sh | 67 +--------------- test/shell/ci_validation.bats | 16 ++++ test/shell/legacy_manifest.bats | 2 +- test/shell/listener_lockdown.bats | 22 +++++ test/test_retroarch_build_identity.py | 6 +- tools/ci-scope.sh | 16 ++++ website/docs/01-features/index.md | 2 +- .../07-apps/01-included-in-onion/tweaks.mdx | 19 ----- .../07-apps/03-network-features/06-hotspot.md | 40 ++++------ 19 files changed, 89 insertions(+), 242 deletions(-) delete mode 100644 static/build/.tmp_update/res/wpsconnected.png delete mode 100644 static/build/.tmp_update/res/wpsfail.png delete mode 100644 static/build/.tmp_update/res/wpstrying.png diff --git a/build/dependencies.lock b/build/dependencies.lock index dad34c748..5dfb86d74 100644 --- a/build/dependencies.lock +++ b/build/dependencies.lock @@ -207,11 +207,11 @@ legacy_channels = ["development"] [legacy_inventory] manifest = "build/legacy-manifest.json" schema = 1 -component_count = 331 -file_count = 1972 -byte_count = 260958446 +component_count = 328 +file_count = 1969 +byte_count = 260922113 source_build_components = 232 -unresolved_components = 99 +unresolved_components = 96 inherited_baseline = "07505ea58c7bba698d6b9220ff43946a43cac76b" [themes] diff --git a/build/legacy-manifest.json b/build/legacy-manifest.json index ce1ee0032..59eeb579e 100644 --- a/build/legacy-manifest.json +++ b/build/legacy-manifest.json @@ -2043,45 +2043,6 @@ "build_recipe": "Makefile", "resolution": "source-build" }, - { - "id": "runtime-tmp-update-res-wpsconnected-png", - "kind": "runtime", - "path": "static/build/.tmp_update/res/wpsconnected.png", - "file_count": 1, - "byte_count": 11671, - "tree_sha256": "e4d1745e83b077fec29ddb90406d9b5aecda2c84c6ed6b089042984e3c0ef76c", - "source": null, - "source_revision": null, - "license": null, - "build_recipe": null, - "resolution": "replace-source-build-or-exclude" - }, - { - "id": "runtime-tmp-update-res-wpsfail-png", - "kind": "runtime", - "path": "static/build/.tmp_update/res/wpsfail.png", - "file_count": 1, - "byte_count": 10951, - "tree_sha256": "5b645131dd40065c4e5dd96ea44bea87c1e12aad39ce272f89005d1cbc5ebdda", - "source": null, - "source_revision": null, - "license": null, - "build_recipe": null, - "resolution": "replace-source-build-or-exclude" - }, - { - "id": "runtime-tmp-update-res-wpstrying-png", - "kind": "runtime", - "path": "static/build/.tmp_update/res/wpstrying.png", - "file_count": 1, - "byte_count": 11408, - "tree_sha256": "b50c1b13ba01e27a02a03d25d8c6a7b015fee2aedf59b1e3e8a96b059829dfcf", - "source": null, - "source_revision": null, - "license": null, - "build_recipe": null, - "resolution": "replace-source-build-or-exclude" - }, { "id": "runtime-tmp-update-script-app-sorter-sh", "kind": "runtime", @@ -2321,8 +2282,8 @@ "kind": "runtime", "path": "static/build/.tmp_update/script/network", "file_count": 5, - "byte_count": 22264, - "tree_sha256": "5ba1040d9523790b3d6c57ac31bf9cf3819eef365567f9af2f4057daf96d4562", + "byte_count": 19961, + "tree_sha256": "13e9a2fbae9c29f9f1909ef750630d8e04c6ecdd9b4e4cb958477ec5228d330b", "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 a3d6e95c5..bb21cccb9 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; inherited FTP/Telnet/FileBrowser HTTP and rejected Samba launchers, configurations, and Tweaks exposure 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; inherited FTP/Telnet/FileBrowser HTTP and rejected Samba launchers, configurations, and Tweaks exposure absent from newly assembled stable artifacts; WPS progress assets, WPS controls, inherited hotspot controls, and dormant hotspot mutation functions absent while fail-closed entrypoints and older-card process cleanup remain | | 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 77070c3a2..a011f00ab 100644 --- a/docs/SECURITY.md +++ b/docs/SECURITY.md @@ -35,6 +35,9 @@ configuration, dormant start logic, share editor, default credentials, and visible Tweaks controls are no longer shipped or exposed. The signed disable migration, stale-state cleanup, and exact `smbd` termination remain for older-card compatibility. +Stable Tweaks does not expose WPS or the inherited hotspot. The WPS compatibility +entry point remains only to reject inherited callers, while hotspot state is +migration-only until NET-08 supplies a separately reviewed transactional owner. 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 cb08e8b52..74cc1c719 100644 --- a/src/tweaks/appstate.h +++ b/src/tweaks/appstate.h @@ -16,15 +16,11 @@ bool isMenu(List *target) } static List _menu_network; -static List _menu_wifi; -static List _menu_wps; static List _menu_vnc; void menu_network_free_all(void) { list_free(&_menu_network); - list_free(&_menu_wifi); - list_free(&_menu_wps); list_free(&_menu_vnc); } diff --git a/src/tweaks/network.h b/src/tweaks/network.h index 3bc299e85..e6753e8db 100644 --- a/src/tweaks/network.h +++ b/src/tweaks/network.h @@ -26,7 +26,6 @@ #define NET_SCRIPT_PATH "/mnt/SDCARD/.tmp_update/script/network" static struct network_s { - bool hotspot; bool ntp; bool ntp_wait; bool manual_tz; @@ -45,7 +44,6 @@ void network_loadState(void) if (network_state.loaded) return; - network_state.hotspot = config_flag_get(".hotspotState"); network_state.ntp = config_flag_get(".ntpState"); network_state.ntp_wait = config_flag_get(".ntpWait"); network_state.force_wifi_on_startup = config_flag_get(".ntpForce"); @@ -79,14 +77,6 @@ void network_execServiceState(const char *service_name, bool background) printf_debug("network_execServiceState: %s\n", state); } -void network_setHotspotState(void *pt) -{ - network_setState(&network_state.hotspot, ".hotspotState", ((ListItem *)pt)->value); - network_execServiceState("hotspot", false); - reset_menus = true; - all_changed = true; -} - void network_setNtpState(void *pt) { network_setState(&network_state.ntp, ".ntpState", ((ListItem *)pt)->value); @@ -116,11 +106,6 @@ void network_keepServicesAlive(void *pt) network_setState(&network_state.keep_alive, ".keepServicesAlive", !((ListItem *)pt)->value); } -void network_wpsConnect(void *pt) -{ - system("sh " NET_SCRIPT_PATH "/wpsclient.sh"); -} - void network_setTzManualState(void *pt) { bool enabled = ((ListItem *)pt)->value; @@ -203,20 +188,6 @@ void network_setVNCFPS(void *pt) } } -void menu_wps(void *_) -{ - if (!_menu_wps._created) { - _menu_wps = list_create(1, LIST_SMALL); - strcpy(_menu_wps.title, "WPS"); - list_addItem(&_menu_wps, - (ListItem){ - .label = "WPS connect", - .action = network_wpsConnect}); - } - menu_stack[++menu_level] = &_menu_wps; - header_changed = true; -} - void menu_vnc(void *pt) { ListItem *item = (ListItem *)pt; @@ -246,50 +217,10 @@ void menu_vnc(void *pt) header_changed = true; } -void menu_wifi(void *_) -{ - if (!_menu_wifi._created) { - _menu_wifi = list_create(3, LIST_SMALL); - strcpy(_menu_wifi.title, "WiFi"); - list_addItem(&_menu_wifi, - (ListItem){ - .label = "IP address: N/A", - .disabled = true, - .action = NULL}); - list_addItemWithInfoNote(&_menu_wifi, - (ListItem){ - .label = "WiFi Hotspot", - .item_type = TOGGLE, - .value = (int)network_state.hotspot, - .action = network_setHotspotState}, - "Use hotspot to host all the network\n" - "services on the go, no router needed.\n" - "Stay connected at anytime, anywhere.\n" - "Compatible with Easy Netplay and\n" - "regular netplay."); - list_addItemWithInfoNote(&_menu_wifi, - (ListItem){ - .label = "WPS connect", - .action = network_wpsConnect}, - "Use your WiFi router's WPS function\n" - "to connect your device with a single press.\n" - " \n" - "First press the WPS button on your router,\n" - "then click this option to connect."); - // list_addItem(&_menu_wifi, - // (ListItem){ - // .label = "WPS...", - // .action = menu_wps}); - } - strcpy(_menu_wifi.items[0].label, ip_address_label); - menu_stack[++menu_level] = &_menu_wifi; - header_changed = true; -} - void menu_network(void *_) { if (!_menu_network._created) { - _menu_network = list_create(6, LIST_SMALL); + _menu_network = list_create(3, LIST_SMALL); strcpy(_menu_network.title, "Network"); network_loadState(); @@ -299,10 +230,6 @@ void menu_network(void *_) .label = "IP address: N/A", .disabled = true, .action = NULL}); - list_addItem(&_menu_network, - (ListItem){ - .label = "WiFi: Hotspot/WPS...", - .action = menu_wifi}); list_addItemWithInfoNote(&_menu_network, (ListItem){ .label = "VNC: Screen share...", diff --git a/src/tweaks/tweaks.c b/src/tweaks/tweaks.c index e79148561..4edc6b21a 100644 --- a/src/tweaks/tweaks.c +++ b/src/tweaks/tweaks.c @@ -217,13 +217,11 @@ int main(int argc, char *argv[]) } } } - if (isMenu(&_menu_network) || isMenu(&_menu_wifi)) { + if (isMenu(&_menu_network)) { network_loadState(); - if (netinfo_getIpAddress(ip_address_label, network_state.hotspot ? "wlan1" : "wlan0")) { + if (netinfo_getIpAddress(ip_address_label, "wlan0")) { if (_menu_network._created) strcpy(_menu_network.items[0].label, ip_address_label); - if (_menu_wifi._created) - strcpy(_menu_wifi.items[0].label, ip_address_label); list_changed = true; } } diff --git a/static/build/.tmp_update/res/wpsconnected.png b/static/build/.tmp_update/res/wpsconnected.png deleted file mode 100644 index cf8eb765d9287ec2595841deafb1d7e8c5e310aa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11672 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 H*hT&iDQ-L} diff --git a/static/build/.tmp_update/res/wpsfail.png b/static/build/.tmp_update/res/wpsfail.png deleted file mode 100644 index f9a9260cb63626c7df661001638594d726a57a60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10953 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 G@c#kzWWIp_ diff --git a/static/build/.tmp_update/res/wpstrying.png b/static/build/.tmp_update/res/wpstrying.png deleted file mode 100644 index 1da0c95cc24be235df10ff136167fa479850ef51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11409 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 /dev/null 2>&1 - ifconfig wlan0 down >> /dev/null 2>&1 - - sleep 1 - # IP setup - hotspot0addr=$(grep -E '^dhcp-range=' "$sysdir/config/dnsmasq.conf" | cut -d',' -f1 | cut -d'=' -f2) - hotspot0addr=$(echo $hotspot0addr | awk -F'.' -v OFS='.' '{$NF-=1; print}') - gateway0addr=$(grep -E '^dhcp-option=3' $sysdir/config/dnsmasq.conf | awk -F, '{print $2}') - subnetmask=$(grep -E '^dhcp-range=.*,[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+,' "$sysdir/config/dnsmasq.conf" | cut -d',' -f3) - - # Set IP route / If details - ifconfig wlan1 $hotspot0addr netmask $subnetmask >> /dev/null 2>&1 - - # Start - $sysdir/bin/dnsmasq --conf-file=$sysdir/config/dnsmasq.conf -u root & - $sysdir/bin/hostapd -i wlan1 $sysdir/config/hostapd.conf >> /dev/null 2>&1 & - - ip route add default via $gateway0addr - - if is_running hostapd; then - log "Hotspot: Started with IP of: $hotspot0addr, subnet of: $subnetmask" - else - log "Hotspot: Failed to start, please try turning off/on. If this doesn't resolve the issue reboot your device." - disable_flag hotspotState - fi - -} - -# Starts personal hotspot if toggle is set to on -# Calls start_hotspot from above -# IF toggle is disabled, shuts down hotspot and bounces wifi. -check_hotspotstate() { - sync - if [ ! -f $sysdir/config/.hotspotState ]; then - if is_running hostapd; then - log "Hotspot: Killed" - pkill -9 hostapd - pkill -9 dnsmasq - ifconfig wlan0 up - ifconfig wlan1 down - killall -9 udhcpc - udhcpc -i wlan0 -s /etc/init.d/udhcpc.script & - check_wifi - else - return - fi - else - if is_running hostapd; then - if wifi_disabled; then - log "Hotspot: Wifi is turned off, disabling the toggle for hotspot and killing the process" - rm $sysdir/config/.hotspotState - pkill -9 hostapd - pkill -9 dnsmasq - fi - else - start_hotspot & - fi - fi -} - # Utility functions # create/pop the json file for remembering states diff --git a/test/shell/ci_validation.bats b/test/shell/ci_validation.bats index 944bde24f..e3164d675 100644 --- a/test/shell/ci_validation.bats +++ b/test/shell/ci_validation.bats @@ -118,6 +118,22 @@ [ "$output" = "full" ] } +@test "stable WPS asset retirement keeps packaging exhaustive" { + scope=/workspace/tools/ci-scope.sh + run sh -c "printf '%s\n' static/build/.tmp_update/res/wpstrying.png | '$scope' build" + [ "$status" -eq 0 ] + [ "$output" = "full" ] + run sh -c "printf '%s\n' static/build/.tmp_update/res/wpstrying.png | '$scope' static-analysis" + [ "$status" -eq 0 ] + [ "$output" = "none" ] + run sh -c "printf '%s\n' static/build/.tmp_update/res/wpstrying.png | '$scope' risk" + [ "$status" -eq 0 ] + [ "$output" = "3" ] + run sh -c "printf '%s\n' static/build/.tmp_update/res/wpstrying.png | '$scope' shell-tests" + [ "$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" diff --git a/test/shell/legacy_manifest.bats b/test/shell/legacy_manifest.bats index 67a4bbfd6..935398432 100644 --- a/test/shell/legacy_manifest.bats +++ b/test/shell/legacy_manifest.bats @@ -6,7 +6,7 @@ --manifest /workspace/build/legacy-manifest.json [ "$status" -eq 0 ] - [[ "$output" == "legacy manifest validate: 331 components" ]] + [[ "$output" == "legacy manifest validate: 328 components" ]] [ ! -e "/workspace/static/packages/RApp/SNK - Neo Geo (GnGeo)" ] [ ! -e "/workspace/static/packages/RApp/PICO-8 (PICO-8 standalone)" ] [ ! -e "/workspace/static/packages/RApp/SCUMM (ScummVM standalone)" ] diff --git a/test/shell/listener_lockdown.bats b/test/shell/listener_lockdown.bats index 51956a9a6..4fd3d5273 100644 --- a/test/shell/listener_lockdown.bats +++ b/test/shell/listener_lockdown.bats @@ -184,3 +184,25 @@ EOF [ "$status" -eq 3 ] [[ "$output" == *'"code":"unsupported"'* ]] } + +@test "stable WPS and inherited hotspot controls remain retired" { + network=/workspace/static/build/.tmp_update/script/network/update_networking.sh + tweaks=/workspace/src/tweaks/network.h + hotspot_doc=/workspace/website/docs/07-apps/03-network-features/06-hotspot.md + + [ ! -e /workspace/static/build/.tmp_update/res/wpsconnected.png ] + [ ! -e /workspace/static/build/.tmp_update/res/wpsfail.png ] + [ ! -e /workspace/static/build/.tmp_update/res/wpstrying.png ] + ! grep -F 'start_hotspot()' "$network" + ! grep -F 'check_hotspotstate()' "$network" + grep -F 'legacy_services="httpState ftpState telnetState smbdState authftpState authhttpState hotspotState"' "$network" + grep -F 'ftp | telnet | http | smbd | hotspot)' "$network" + ! grep -F 'network_state.hotspot' "$tweaks" + ! grep -F 'network_setHotspotState' "$tweaks" + ! grep -F 'network_wpsConnect' "$tweaks" + ! grep -F 'WiFi: Hotspot/WPS' "$tweaks" + grep -F 'BloomOS does not expose the inherited hotspot or WPS controls' "$hotspot_doc" + grep -F '/docs/network/ssh' "$hotspot_doc" + ! grep -F 'Enabling hotspot' "$hotspot_doc" + ! grep -F 'WiFi: Hotspot/WPS' /workspace/website/docs/07-apps/01-included-in-onion/tweaks.mdx +} diff --git a/test/test_retroarch_build_identity.py b/test/test_retroarch_build_identity.py index e38b7dc37..fe1f73084 100644 --- a/test/test_retroarch_build_identity.py +++ b/test/test_retroarch_build_identity.py @@ -36,9 +36,9 @@ def test_identity_is_stable_for_unrelated_inventory_totals(self): self.assertRegex(baseline.stdout.strip(), r"^[0-9a-f]{64}$") changed = LOCK.read_text(encoding="utf-8") - changed = changed.replace("component_count = 331", "component_count = 999") - changed = changed.replace("file_count = 1972", "file_count = 9999") - changed = changed.replace("byte_count = 260958446", "byte_count = 999999999") + changed = changed.replace("component_count = 328", "component_count = 999") + changed = changed.replace("file_count = 1969", "file_count = 9999") + changed = changed.replace("byte_count = 260922113", "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 4163b769c..437df910e 100755 --- a/tools/ci-scope.sh +++ b/tools/ci-scope.sh @@ -293,6 +293,13 @@ while IFS= read -r path; do # stable payload and therefore retains the complete ARM gate. [ "$mode" != build ] || full=1 ;; + static/build/.tmp_update/res/wpsconnected.png|\ + static/build/.tmp_update/res/wpsfail.png|\ + static/build/.tmp_update/res/wpstrying.png) + # Removing inherited WPS UI assets changes stable packaging and + # therefore keeps the complete ARM release gate. + [ "$mode" != build ] || full=1 + ;; static/build/.tmp_update/bin/bftpd|static/build/.tmp_update/bin/bftpdutmp|\ static/configs/.tmp_update/config/bftpd.conf|static/configs/.tmp_update/config/bftpdauth.conf) # Stable FTP payload deletion requires complete ARM packaging but @@ -523,6 +530,15 @@ 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/res/wpsconnected.png|\ + static/build/.tmp_update/res/wpsfail.png|\ + static/build/.tmp_update/res/wpstrying.png) + 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 + ;; static/build/.tmp_update/bin/bftpd|static/build/.tmp_update/bin/bftpdutmp|\ static/configs/.tmp_update/config/bftpd.conf|static/configs/.tmp_update/config/bftpdauth.conf) raise_risk 3 diff --git a/website/docs/01-features/index.md b/website/docs/01-features/index.md index f4cf49604..7753d39ac 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): [HTTP server (retired)](network/http), [SSH/SFTP](network/ssh), [Hotspot](network/hotspot), [VNC server](network/vnc)... +- [Network Services](network-features): [HTTP server (retired)](network/http), [SSH/SFTP](network/ssh), [Hotspot/WPS (retired pending transactional replacement)](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 ae5f33088..3f741ca4d 100644 --- a/website/docs/07-apps/01-included-in-onion/tweaks.mdx +++ b/website/docs/07-apps/01-included-in-onion/tweaks.mdx @@ -155,25 +155,6 @@ It can be MainUI, [GameSwitcher](./game-switcher), [Retroarch](./retroarch) or [
- -### WiFi: Hotspot/WPS... - -
- - -#### WiFi Hotspot - -
Use hotspot to host all the network services on the go, no router needed. Stay connected at anytime, anywhere. Compatible with Easy Netplay and regular netplay.
-
-
- -#### WPS connect - -
Use your WiFi router's WPS function to connect your device with a single press. First press the WPS button on your router, then click this option to connect.
-
-
-
- ### SSH: Secure shell...
SSH provides a secure command line host for communicating with your device remotely. SFTP provides a secure file transfer protocol.
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 da50e7623..c305d4a88 100644 --- a/website/docs/07-apps/03-network-features/06-hotspot.md +++ b/website/docs/07-apps/03-network-features/06-hotspot.md @@ -4,32 +4,24 @@ slug: /network/hotspot # Hotspot -Your Miyoo Mini Plus just got a lot more portable. Use the reviewed key-only SSH/SFTP service on the go, no extra devices needed. Stay connected with ease, anytime, anywhere. -Compatible with Netplay (best paired with [Easy Netplay](../multiplayer/easynetplay) +BloomOS does not expose the inherited hotspot or WPS controls. The inherited +implementation can replace station configuration, interfaces, routes, and DHCP +state without Bloom's rollback transaction, so stable Tweaks cannot invoke it. -There are reports of issues with hotspot on firmware levels below `2023 05 05``. +Stale `.hotspotState` files are migration input only. Compatibility +reconciliation disables the marker and stops inherited `hostapd` and `dnsmasq` +processes instead of starting an access point. +WPS is also unsupported. Its retained compatibility entry point fails closed +without changing the active station profile. -## Features +## Planned replacement -- Transfer files on the move +The v3 work program tracks a separately gated transactional Bloom hotspot as +NET-08. It must use the same begin/apply/confirm/rollback safeguards as other +network mutations and requires Mini Plus device evidence before it can appear in +stable settings. -- Use Netplay without access to a Wi-Fi router - - -## Enabling hotspot - -![](https://github.com/OnionUI/Onion/assets/47260768/cf548301-8936-4615-82b8-0309ece7d449) - -You'll find it in **Apps** › **Tweaks** › **Network** › **WiFi: Hotspot/WPS** - -Press A or use the arrow keys to enable to the hotspot. - - -## Connecting - -On another device you'll now see that your MMP is broadcasting an SSID. - -![](https://github.com/OnionUI/Onion/assets/47260768/09d21b12-d488-461a-a31a-fef511ca6d0f) - -Connect to this as you would any other Wi-Fi network and use the **password:** `onionos+` +Until that work is certified, use the reviewed key-only [SSH/SFTP +service](/docs/network/ssh) while the Mini Plus is connected to a trusted Wi-Fi +network.