Active PINGs on pineapd's command socket collided with the stock daemon's
own socket writes ('[PineAp] Error writing'), making the daemon watchdog
SIGTERM pineapd every ~30s while hopping. Monitor now checks pidof only
(no socket writes) and the stabilization pass pins wlan1mon hop=0.
Field-verified crash stack on this firmware: SSID-pool broadcast (segfault),
wlan2mon hopping a nonexistent 6GHz iface (segfault), wlan1mon fast-hopping
6GHz channels (ASIO thread exit), and a large refilled pool. The fix path
now enforces: pool broadcast off, pool list cleared, wlan2mon off, wlan1mon
5GHz-only, wlan0mon 2.4GHz-only — idempotent, so collect refills self-heal.
8-minute continuous-PONG stability verified on-device.
operstate reports 'unknown' on monitors (normal), so _iface_up now parses
admin flags from ip link. Discovered a second pineapd SIGSEGV source: the
wlan2mon 6GHz monitor this hardware never creates, hopping on the missing
iface (~85s crash cadence even with the SSID pool off). The monitor now
disables it in the fix path.
Mode 'active' and the advertise toggle could re-enable the SSID-pool
broadcast that segfaults pineapd. active preset now skips ssidpool/enable
(advertise stays false), the advertise endpoint refuses with an
explanation when the pool is disabled, get_ap reports the real pool
state, and the PineAP overview disables the toggle with a notice. Added
a top-bar health chip (PINEAP OK / POOL OFF / PINEAPD DOWN) polled every
15s.
The Attacks shell created its content div but never attached it to the
document, so all launcher cards rendered into a detached subtree (tabs
only were visible). Bumped views.js cache version in index.html.
Streamable-HTTP MCP server on POST /mcp: device.state, attack.deploy/stop/
status/deauth/capture/export_hc22000, loot.handshakes/enterprise_creds,
recon.aps/isearch/devices, pineap.kick_client/set_filter tools; recon DB +
bundled opencode skills resources; attack playbook prompts. Cookie or Bearer
auth. Harness page shows endpoint, token, curl snippet, capability explorer
and a copy-paste pi.dev prompt. scripts/harness_stdio.py for stdio-only
agents.
The stock daemon's enterprise config generation is broken on this firmware
(it hardcodes eap_server_erp=1, which hostapd rejects), so the enterprise
attack now runs its own karma+PineAPE hostapd instance on wlan1ent/phy1:
iw-created iface, EAP config with catch-all user file, pineape+auth capture
enabled via ctrl, mgmtiface registered in pineapd UCI so captured creds
flow into recon.db (hostap_basic/hostap_chalresp). Boot-recovery redeploys
a live attack after a Mark VIII restart.
Deploy/stop/status/capture/export-hc22000/deauth endpoints. Band-aware
deauth inject (wlan0mon for 2.4GHz), enterprise AP via wlan0ent + PineAPE,
verified writes polled from /sys, hop resumed when no radio1 AP active.
get_ap now reports radio0, radio1 and enterprise APs separately from UCI
(never a stored/cached branch), with radio channel fallback. Mode is
derived from live enabled/collect state instead of showing 'unknown';
device truth wins over stale stored presets.
- Delete the Survey stack (sampler, handlers, routes, view, recordings);
Scanning gains AP compare (cap 6), whole-page selection filter, channel
map (20 MHz lobes, the radio does not report width), and auto-follow
that prefers the newest non-empty scan
- Richer HTML scan reports: stat cards, band/encryption breakdowns,
channel occupancy, color-coded signal cells, GPS line only on a fix
- Harden live recon: bounded + retried scan-detail reads (503 on lock),
serialize recon starts (409 + scan_remaining while running), GPS and
archive discovery move to a 30s poll, GPS_GET skipped when gpsd is down
- Read-only history for pineapd-rotated databases (error-*/diagnostic-*):
archives list/detail/download endpoints, Previous Scans optgroup,
delete disabled, traversal-guarded
- Status flags: hopper-radio-offline and history-reset banners; empty
scans greyed in the picker
- Tests: recon suite grows to 99 cases; all 14 modules green
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
Reconnaissance surveys (GPSD-tethered scan recording), OUI vendor
lookup for client/AP tables, survey/report pages, and the matching
test_recon.py suite. Co-authored with the recon-feature agent whose
work was finished in this checkout.
Start scans via the Pager's native /api/pineap/recon/new so history
appends instead of rotating. Enforce finite durations (1-86400s,
default 30s), remove the unsupported Continuous mode, and refuse the
unsafe manual stop that left recon.db locked.
Rework scan list and detail reads into single-pass aggregate SQL,
shorten lock retries, and serve cached results during short exclusive
lock windows. Fall back to immutable read-only access when the
firmware leaves a stale lock after native completion.
Frontend auto-follows new scans, queues a single in-flight detail
refresh, keeps previous tables visible while a scan starts, and shows
completion toasts and daemon error details.
Add scripts/deploy.sh for macOS/Linux (zip packaging, scp/ssh install,
atomic payload replacement, service restart, portal refresh) with
README instructions, plus regression coverage for native start,
safe stop semantics, aggregate queries, and stale-lock fallback.
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>