feat: Add login page with dynamic RGB effects and password toggle functionality

feat: Implement package management utilities with JSON endpoints for listing and uninstalling packages

feat: Create plugin management utilities with endpoints for listing, configuring, and installing plugins

feat: Develop schedule and trigger management utilities with CRUD operations for schedules and triggers
This commit is contained in:
infinition
2026-03-19 00:40:04 +01:00
parent 3fa4d5742a
commit b0584a1a8e
176 changed files with 7795 additions and 1781 deletions

View File

@@ -1,21 +1,6 @@
"""
Loki — HID Attack Engine for Bjorn.
"""__init__.py - Loki HID attack engine for Bjorn.
Manages USB HID gadget lifecycle, script execution, and job tracking.
Named after the Norse trickster god.
Loki is the 5th exclusive operation mode (alongside MANUAL, AUTO, AI, BIFROST).
When active, the orchestrator stops and the Pi acts as a keyboard/mouse
to the connected host via /dev/hidg0 (keyboard) and /dev/hidg1 (mouse).
HID GADGET STRATEGY:
The HID functions (keyboard + mouse) are created ONCE at boot time alongside
RNDIS networking by the usb-gadget.sh script. This avoids the impossible task
of hot-adding HID functions to a running composite gadget (UDC rebind fails
with EIO when RNDIS is active).
LokiEngine simply opens/closes the /dev/hidg0 and /dev/hidg1 device files.
If /dev/hidg0 doesn't exist, the user needs to run the setup once and reboot.
Manages USB HID gadget lifecycle, HIDScript execution, and job tracking.
"""
import os
import time
@@ -27,7 +12,7 @@ from logger import Logger
logger = Logger(name="loki", level=logging.DEBUG)
# USB HID report descriptors EXACT byte-for-byte copies from P4wnP1_aloa
# USB HID report descriptors - EXACT byte-for-byte copies from P4wnP1_aloa
# Source: P4wnP1_aloa-master/service/SubSysUSB.go lines 54-70
#
# These are written to the gadget at boot time by usb-gadget.sh.
@@ -64,7 +49,7 @@ _MOUSE_REPORT_DESC = bytes([
# The boot script that creates RNDIS + HID functions at startup.
# This replaces /usr/local/bin/usb-gadget.sh
_USB_GADGET_SCRIPT = '''#!/bin/bash
# usb-gadget.sh USB composite gadget: RNDIS networking + HID (keyboard/mouse)
# usb-gadget.sh - USB composite gadget: RNDIS networking + HID (keyboard/mouse)
# Auto-generated by Bjorn Loki. Do not edit manually.
modprobe libcomposite
@@ -196,7 +181,7 @@ _GADGET_SCRIPT_PATH = "/usr/local/bin/usb-gadget.sh"
class LokiEngine:
"""HID attack engine manages script execution and job tracking.
"""HID attack engine - manages script execution and job tracking.
The USB HID gadget (keyboard + mouse) is set up at boot time by
usb-gadget.sh. This engine simply opens /dev/hidg0 and /dev/hidg1.
@@ -242,7 +227,7 @@ class LokiEngine:
# Check if HID gadget is available (set up at boot)
if not os.path.exists("/dev/hidg0"):
logger.error(
"/dev/hidg0 not found HID gadget not configured at boot. "
"/dev/hidg0 not found - HID gadget not configured at boot. "
"Run install_hid_gadget() from the Loki API and reboot."
)
self._gadget_ready = False
@@ -287,7 +272,7 @@ class LokiEngine:
if job["status"] == "running":
self._jobs.cancel_job(job["id"])
# Close HID devices (don't remove gadget it persists)
# Close HID devices (don't remove gadget - it persists)
if self._hid:
self._hid.close()

View File

@@ -1,5 +1,5 @@
"""
Low-level USB HID controller for Loki.
"""hid_controller.py - Low-level USB HID controller for Loki.
Writes keyboard and mouse reports to /dev/hidg0 and /dev/hidg1.
"""
import os
@@ -16,7 +16,7 @@ from loki.layouts import load as load_layout
logger = Logger(name="loki.hid_controller", level=logging.DEBUG)
# ── HID Keycodes ──────────────────────────────────────────────
# USB HID Usage Tables Keyboard/Keypad Page (0x07)
# USB HID Usage Tables - Keyboard/Keypad Page (0x07)
KEY_NONE = 0x00
KEY_A = 0x04

View File

@@ -1,17 +1,6 @@
"""
HIDScript parser and executor for Loki.
"""hidscript.py - P4wnP1-compatible HIDScript parser and executor.
Supports P4wnP1-compatible HIDScript syntax:
- Function calls: type("hello"); press("GUI r"); delay(500);
- var declarations: var x = 1;
- for / while loops
- if / else conditionals
- // and /* */ comments
- String concatenation with +
- Basic arithmetic (+, -, *, /)
- console.log() for job output
Zero external dependencies — pure Python DSL parser.
Pure Python DSL parser supporting type/press/delay, loops, conditionals, and variables.
"""
import re
import time
@@ -240,7 +229,7 @@ class HIDScriptParser:
else_body = source[after_else+1:eb_end]
next_pos = eb_end + 1
elif source[after_else:after_else+2] == 'if':
# else if parse recursively
# else if - parse recursively
inner_if, next_pos = self._parse_if(source, after_else)
else_body = inner_if # will be a dict, handle in exec
else:

View File

@@ -1,5 +1,5 @@
"""
Loki job manager — tracks HIDScript execution jobs.
"""jobs.py - Loki job manager, tracks HIDScript execution jobs.
Each job runs in its own daemon thread.
"""
import uuid

View File

@@ -1,5 +1,5 @@
"""
Keyboard layout loader for Loki HID subsystem.
"""__init__.py - Keyboard layout loader for Loki HID subsystem.
Caches loaded layouts in memory.
"""
import json

View File

@@ -1,11 +1,13 @@
"""generate_layouts.py - Generates localized keyboard layout JSON files from a US base layout."""
import json
import os
# Chargement de la base US existante
# Load the US base layout
with open("us.json", "r") as f:
US_BASE = json.load(f)
# Définition des différences par rapport au clavier US
# Key differences from the US layout
# 0 = Normal, 2 = Shift, 64 = AltGr (Right Alt)
LAYOUT_DIFFS = {
"fr": {
@@ -59,20 +61,18 @@ LAYOUT_DIFFS = {
"б": [0, 54], "ю": [0, 55], "ё": [0, 53], ".": [0, 56], ",": [2, 56],
"": [2, 32], ";": [2, 33], ":": [2, 35], "?": [2, 36]
},
"zh": {} # ZH utilise exactement le layout US
"zh": {} # ZH uses the exact US layout
}
def generate_layouts():
for lang, diff in LAYOUT_DIFFS.items():
# Copie de la base US
new_layout = dict(US_BASE)
# Application des modifications
new_layout.update(diff)
filename = f"{lang}.json"
with open(filename, "w", encoding="utf-8") as f:
json.dump(new_layout, f, indent=4, ensure_ascii=False)
print(f"Généré : {filename} ({len(new_layout)} touches)")
print(f"Generated: {filename} ({len(new_layout)} keys)")
if __name__ == "__main__":
generate_layouts()