Health-mode safety net — the INVERSE of the presence alert. Fires when a home that should be occupied shows NO activity for N awake-hours (a fall, not getting out of bed). The quiet/sleep window is excluded: the gap is measured from the LATER of the last real activity or this morning's
(po, notify_on, now, present)
| 622 | '/api/wardriving/bluetooth', '/api/wardriving/cells', |
| 623 | '/api/wardriving/diagnostics', |
| 624 | ) |
| 625 | write_api = ('/api/wardriving/stop', '/api/system/restart-service') |
| 626 | if path in ('/', '/wardrive') or (request.method == 'GET' and path in readonly_api): |
| 627 | return |
| 628 | if request.method == 'POST' and path in write_api: |
| 629 | return |
| 630 | |
| 631 | # Kiosk loopback bypass: any request originating from the Pi itself |
| 632 | # (the on-screen kiosk runs chromium pointed at localhost) bypasses auth. |
| 633 | # Anyone with local access already has shell on the device, so this |
| 634 | # adds no attack surface vs. the existing network-facing auth. |
| 635 | if request.remote_addr in ('127.0.0.1', '::1') and shared_data.config.get('kiosk_enabled'): |
| 636 | return |
| 637 | |
| 638 | # Mesh machine auth: let a *peer Ragnar* reach this node's mesh endpoints |
| 639 | # without a session. Identity is proven by WireGuard, not by a shared |
| 640 | # secret — tailscaled tells us which tailnet node owns the source IP, and |
| 641 | # we require that node to carry the mesh tag. Scoped hard on purpose: |
| 642 | # * reads — any GET under /api/mesh/* (observe the unit's data); |
| 643 | # * one write — POST /api/mesh/control ONLY, whose body is itself an |
| 644 | # allowlist (start/stop the four monitors, nothing else). Matched by |
| 645 | # exact path so join/leave/serve/peer-control stay session-only; |
| 646 | # * every other route stays session-gated; |
| 647 | # * fails closed — no tailscaled, no answer, or no tag means 401. |
| 648 | # Tailnet membership alone is NOT enough. Every laptop and phone on the |
| 649 | # tailnet would otherwise inherit Ragnar's full offensive toolset. |
| 650 | if shared_data.config.get('mesh_enabled'): |
| 651 | peer_read = request.method == 'GET' and path.startswith('/api/mesh/') |
| 652 | peer_control = request.method == 'POST' and path == '/api/mesh/control' |
| 653 | # Scan delegation writes a peer may make: start a scan on this unit, and |
| 654 | # cancel one it started. Both exact-path allowlisted (cancel by prefix + |
| 655 | # id) — this is the "worker" role. The operator's own scan endpoints |
| 656 | # (/api/vuln-advanced/*) stay session-only, so a peer can run a |
| 657 | # delegated scan here but can't drive this unit's UI. |
| 658 | peer_scan_write = request.method == 'POST' and ( |
| 659 | path == '/api/mesh/scan/start' |
| 660 | or path.startswith('/api/mesh/scan/cancel/')) |
| 661 | # The fleet-update fan-out: a peer's "Update mesh" lands here to run this |
| 662 | # unit's own git update. Exact-path allowlisted like the control write, and |
| 663 | # the handler only ever runs git_updater against this checkout — a peer |
| 664 | # cannot pick what runs, only that an update runs. |
| 665 | peer_update = request.method == 'POST' and path == '/api/mesh/update' |
| 666 | # File transfer: a peer may push a file to this unit's quarantined inbox. |
| 667 | # Exact-path allowlisted; the handler itself only ever writes into the |
| 668 | # inbox (never a live path) and can be turned off (mesh_file_receive). |
| 669 | peer_file_push = request.method == 'POST' and path == '/api/mesh/files/push' |
| 670 | if (peer_read or peer_control or peer_scan_write or peer_update |
| 671 | or peer_file_push) and _is_mesh_peer_request(): |
| 672 | return |
| 673 | |
| 674 | # Share-only guest role. A device carrying the SHARE tag (tag:ragnar-share) |
| 675 | # but NOT the mesh tag may ONLY drop a file into this unit's inbox — no |
| 676 | # roster, no reads, no scans, no control. It never appears as a mesh unit |
| 677 | # and cannot enumerate anything about this box. Optionally (operator |
| 678 | # opt-in) it may also browse/fetch this unit's Mesh Share folder. The push |
| 679 | # handler still honours mesh_file_receive, so "stop accepting" also stops |
| 680 | # guests. Exact-path allowlisted and fail-closed. |
| 681 | share_push = request.method == 'POST' and path == '/api/mesh/files/push' |
no test coverage detected