""" backend/routes/sentinel_routes.py §2.18 — Sentinel: Credential Capture, USB Threat Monitor, OSINT Threat Intelligence """ from fastapi import HTTPException, APIRouter from pydantic import BaseModel from typing import List router = APIRouter() class ThreatRequest(BaseModel): target: str threat_type: str = "general" # general | network | credential | physical class ThreatReport(BaseModel): threat_id: str severity: str # LOW | MEDIUM | HIGH | CRITICAL description: str mitigations: List[str] = [] @router.get("/status") async def sentinel_status(): """Return live Sentinel threat-monitoring status.""" from backend.services.usb_monitor import get_active_usb_drives try: drives = get_active_usb_drives() return { "status": "active", "usb_threat_monitor": "online", "active_usb_devices": len(drives), "credential_capture": "active", "osint_engine": "ready", } except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.post("/threat_model") async def generate_threat_model(req: ThreatRequest): """ Generates a structured threat model for the given target. Uses the OSINT/Internet layer for live reconnaissance. """ if not req.target: raise HTTPException(status_code=400, detail="target is required") try: from backend.tools.web_search_tools import search_web findings = await search_web( f'"{req.target}" vulnerability CVE threat {req.threat_type}', num_results=5 ) return { "status": "ok", "target": req.target, "threat_type": req.threat_type, "threat_vectors": findings, "recommendation": "Deploy countermeasures. Monitor via Sentinel dashboard.", } except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/credentials/captured") async def get_captured_credentials(): """Return credentials captured by the Sentinel CredentialCapture service.""" from backend.services.usb_monitor import get_db_path import sqlite3 try: db_path = get_db_path() with sqlite3.connect(db_path) as conn: conn.execute('PRAGMA journal_mode=WAL') cursor = conn.cursor() cursor.execute( "SELECT id, site, username, captured_at, source FROM vault_credentials ORDER BY captured_at DESC" ) rows = cursor.fetchall() return [ {"id": r[0], "site": r[1], "username": r[2], "captured_at": r[3], "source": r[4]} for r in rows ] except Exception as e: raise HTTPException(status_code=500, detail=str(e)) @router.get("/network_scan") async def network_scan(): """ Run a local network scan using psutil to identify active connections. Maps to the 'Battlefield Intel' system capability. """ import psutil try: connections = psutil.net_connections(kind="inet") active = [ { "local_addr": f"{c.laddr.ip}:{c.laddr.port}" if c.laddr else None, "remote_addr": f"{c.raddr.ip}:{c.raddr.port}" if c.raddr else None, "status": c.status, "pid": c.pid, } for c in connections if c.status == "ESTABLISHED" ] return {"status": "ok", "active_connections": len(active), "connections": active} except Exception as e: raise HTTPException(status_code=500, detail=str(e))