mirror of
https://github.com/meshtastic/firmware.git
synced 2026-09-16 00:10:11 -04:00
The only local-admin is_managed refusal sat inside #ifndef MESHTASTIC_PHONEAPI_ACCESS_CONTROL, so it was compiled out of every build with -DMESHTASTIC_ENABLE_LOCKDOWN=1. The comment justifying that says lockdown's per-connection gate covers it, but that gate only applies once lockdown is ACTIVE: PhoneAPI::handleToRadioPacket drops unauthorized local admin only while isLockdownActive(), and getAdminAuthorized() returns true for every connection when it is not. So a lockdown-capable build that has never been provisioned accepted local admin from any client regardless of security.is_managed, silently. Confirmed on a RAK4631: with is_managed set and an admin key present, a local set_owner over USB serial was accepted and the owner changed. SECURITY.md already promises local config changes are "subject to managed mode". Gate on isLockdownActive() instead of the build flag, so the passphrase gate supersedes is_managed only once it is actually in force. A blanket removal of the #ifndef would also refuse local admin after a successful passphrase unlock, which is not the intent. Behaviour on stock builds is unchanged. Adds a paired test: local admin is refused with is_managed set, and applied without it. Both pass (test_admin_radio, 119/119 green), and the refusal test fails as expected when the gate is bypassed.