Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions build/dependencies.lock
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,10 @@ legacy_channels = ["development"]
[legacy_inventory]
manifest = "build/legacy-manifest.json"
schema = 1
component_count = 326
file_count = 1967
byte_count = 260663152
source_build_components = 232
component_count = 327
file_count = 1968
byte_count = 260664576
source_build_components = 233
unresolved_components = 94
inherited_baseline = "07505ea58c7bba698d6b9220ff43946a43cac76b"

Expand Down
2 changes: 1 addition & 1 deletion build/display-profile-policy.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"platform_helper": {
"path": "static/build/.tmp_update/bin/bloom-platform",
"hash_mode": "text-lf",
"sha256": "ccc3d1ad7efd29c8864a2b274c6af1ab6aff5efe9c5098dbe1b542ceaa11258d"
"sha256": "e840764164c3eca35131a5cca99872341ad433c5fb096b6788f54821a226402e"
},
"built_in_profiles": {
"path": "build/display-built-in-profiles.json",
Expand Down
2 changes: 1 addition & 1 deletion build/display-visual-pack-providers.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"authorities": {
"display_profile_policy": {
"path": "build/display-profile-policy.json",
"sha256": "3e575603d133478d706783b5f3b3df18561403aaaac346afa0cf3f733d599f0a"
"sha256": "6b171937cbc705dd742bb1ce23efaaea33b4d1cca767b8832d395a0e18e88a8f"
},
"ui_asset_manifest": {
"path": "assets/ui/manifest.json",
Expand Down
27 changes: 20 additions & 7 deletions build/legacy-manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -462,8 +462,8 @@
"kind": "runtime",
"path": "static/build/.tmp_update/bin/bloom-dev-deploy",
"file_count": 1,
"byte_count": 33126,
"tree_sha256": "225e52c83020c0ebd88732688e8731125cc56fd912b77a010eb9696f2ade7ec9",
"byte_count": 33204,
"tree_sha256": "0e3a8f926886a6f759e2c72bac34682ba450e40de3cd136f27fe857aa0c7ffc0",
"source": "https://github.com/boburning/BloomOS",
"source_revision": "release-commit",
"license": "GPL-3.0-only",
Expand All @@ -475,8 +475,8 @@
"kind": "runtime",
"path": "static/build/.tmp_update/bin/bloom-dev-ssh",
"file_count": 1,
"byte_count": 15073,
"tree_sha256": "70773fe6f7eaad77eda356ba3ee3b0a37fcd4d8a4d42c9c2c1af2cab8f15bc66",
"byte_count": 15525,
"tree_sha256": "a5ddf4075869bc207eb604fea194b6b6f149332aec1f4710406dc11f78437645",
"source": "https://github.com/boburning/BloomOS",
"source_revision": "release-commit",
"license": "GPL-3.0-only",
Expand Down Expand Up @@ -670,8 +670,8 @@
"kind": "runtime",
"path": "static/build/.tmp_update/bin/bloom-platform",
"file_count": 1,
"byte_count": 17120,
"tree_sha256": "f585d4ec2f23f2d91235a9b82f57fa92404b605246daf792093f205f7353db24",
"byte_count": 17216,
"tree_sha256": "b3fb607da7c08fb1ad0b4a52f0388e22bc2c16adbaed99b1bf93ed0640a452f2",
"source": "https://github.com/boburning/BloomOS",
"source_revision": "release-commit",
"license": "GPL-3.0-only",
Expand Down Expand Up @@ -834,6 +834,19 @@
"build_recipe": "Makefile",
"resolution": "source-build"
},
{
"id": "runtime-tmp-update-bin-bloom-ssh-gate",
"kind": "runtime",
"path": "static/build/.tmp_update/bin/bloom-ssh-gate",
"file_count": 1,
"byte_count": 798,
"tree_sha256": "3c8d1cc7509ec43526ff796d01804b61b87500e6195a785d2384cf0c6f58d831",
"source": "https://github.com/boburning/BloomOS",
"source_revision": "release-commit",
"license": "GPL-3.0-only",
"build_recipe": "Makefile",
"resolution": "source-build"
},
{
"id": "runtime-tmp-update-bin-bloom-test-runner",
"kind": "runtime",
Expand Down Expand Up @@ -1893,7 +1906,7 @@
"path": "static/build/.tmp_update/res/bloom",
"file_count": 7,
"byte_count": 72678,
"tree_sha256": "d480b8649c62bd40b1e8eb8f2ebc812cf5179b9fc3839b67b442f11fa17ceb01",
"tree_sha256": "21791c8c83e9b100d67d8d287bcd6fd66d7953645d92147ba961860f8c3d6374",
"source": "https://github.com/boburning/BloomOS",
"source_revision": "release-commit",
"license": "GPL-3.0-or-later",
Expand Down
12 changes: 11 additions & 1 deletion docs/1.0_TEST_MATRIX.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,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/VNC flags cannot activate listeners; process-aware listener audit including inherited TCP/5900 and vncserver; inherited FTP/Telnet/FileBrowser HTTP, rejected Samba, and unresolved VNC launchers, configurations, libraries, 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 |
| 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; every authenticated developer shell/exec request enters a fixed non-login gate with inherited profile startup disabled; exact SFTP dispatch; missing-gate fail-closed behavior; 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/VNC flags cannot activate listeners, including after an interactive SSH login; process-aware listener audit including inherited TCP/5900 and vncserver; inherited FTP/Telnet/FileBrowser HTTP, rejected Samba, and unresolved VNC launchers, configurations, libraries, 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 |
Expand Down Expand Up @@ -242,6 +242,16 @@ identity/configuration, and a measured ~16 MiB idle memory increase that left
only 8,000 KiB available after buffers. Stable UI therefore hides Samba unless
a future Bloom source build passes every required gate. SFTP remains supported.

The signed interactive-SSH lockdown checkpoint is recorded in
[`validation/network/plus-interactive-ssh-lockdown-20260831.json`](validation/network/plus-interactive-ssh-lockdown-20260831.json).
On one Mini Plus, a fresh no-command key-only SSH request entered the fixed
non-login gate with `ENV=/dev/null`, non-interactive execution remained
functional, password-only authentication and disabled SFTP were refused, and
an immediate independent audit found no Telnet process or listener. The exact
candidate was promoted to known-good with aggregate health green. This does not
certify another device or enabled SFTP, and inactive retired configuration
remnants found during the Full checkpoint remain under issue #629.

## Exit criteria

No stable tag is permitted while an automated gate fails, a P0/P1 remains open,
Expand Down
11 changes: 9 additions & 2 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1008,7 +1008,13 @@ of the remaining inherited auxiliary services remain follow-up work.

`bloom-network-services` separately owns desired and runtime state for SSH,
SFTP, and the capability-gated Samba candidate. SSH shell permission and SFTP
permission are independent. In SFTP-only mode every authorized key receives a
permission are independent. When SSH shell permission is enabled, Dropbear
forces every authenticated shell, exec, and subsystem request through the fixed
`bloom-ssh-gate`. Empty requests start a non-login `/bin/sh` with
`ENV=/dev/null`, preventing inherited `/etc/profile` from reactivating retired
listeners; non-empty requests preserve the authenticated original command, and
the exact built-in SFTP request enters the confined SFTP gate. A missing gate
fails closed before the listener starts. In SFTP-only mode every authorized key receives a
Dropbear forced command with forwarding, agent, X11, and PTY access disabled;
shell and arbitrary exec requests therefore enter only the SFTP protocol gate.
The pinned OpenSSH SFTP subsystem is statically built with a fixed root identity
Expand Down Expand Up @@ -1078,7 +1084,8 @@ Monotonic deadlines make wall-clock repair irrelevant to recovery.

SSH/SFTP helper changes use the fixed `ssh-shadow` transaction operation. The
existing key-only port 22 process remains active while a separately tracked,
transaction-authorized key-only process listens on port 2222. The host proves a
transaction-authorized key-only process listens on port 2222 through the same
non-login shell gate. The host proves a
new non-multiplexed connection through that listener; confirmation then closes
it through port 22. Rollback and watchdog paths close it before restoring prior
service preferences. Outside that bounded transaction the listener audit marks
Expand Down
9 changes: 8 additions & 1 deletion docs/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ developer installations retain automatic SSH until it is disabled in Network
settings. Removing `.bloom-dev` also disables that compatibility behavior unless
SSH has already been explicitly enabled in Network settings.

Developer SSH never starts a firmware login shell. The fixed
`bloom-ssh-gate` launches interactive `/bin/sh` without login semantics and
sets `ENV=/dev/null`, while authenticated non-interactive commands retain their
normal command behavior. This prevents inherited `/etc/profile` actions from
reactivating retired listeners. SFTP-only mode remains independently restricted
by the authorized-key forced command and confined SFTP gate.

## Wi-Fi device harness

Copy `tools/targets.example.toml` to the ignored `tools/targets.toml` and replace
Expand Down Expand Up @@ -235,7 +242,7 @@ temporary executable over the same key-only channel, verify its byte count and
SHA-256 on both ends, and remove it after rollback.

The complete settings, platform, Wi-Fi, listener/service, transaction, remote
key, SFTP, transfer-policy, and boot-recovery runtime set forms one guarded 17-file
key, SSH shell gate, SFTP, transfer-policy, and boot-recovery runtime set forms one guarded 21-file
`network-helpers` deployment group. Host and device manifest validation reject
every partial group so incompatible schema generations cannot be mixed on a
live device. Activate that bundle only through the rollback-timed network
Expand Down
Loading
Loading