From 24cd01e46cb3067f9a925147ab40627c890bd063 Mon Sep 17 00:00:00 2001 From: Subinacls Date: Thu, 4 Jun 2026 21:19:44 -0400 Subject: [PATCH] Initial commit - ICEYOU v1.2 (production ready, sanitized) --- .gitignore | 51 ++++ README.md | 495 ++++++++++++++++++++++++++++++++++ config.example.json | 65 +++++ face_enrollment.py | 361 +++++++++++++++++++++++++ main.py | 20 ++ requirements.txt | 16 ++ src/iceyou/__init__.py | 3 + src/iceyou/actions.py | 175 ++++++++++++ src/iceyou/camera.py | 243 +++++++++++++++++ src/iceyou/config.py | 81 ++++++ src/iceyou/device_monitor.py | 66 +++++ src/iceyou/face_recognizer.py | 200 ++++++++++++++ src/iceyou/input_hooks.py | 65 +++++ src/iceyou/keyboard_block.py | 156 +++++++++++ src/iceyou/monitor.py | 195 ++++++++++++++ src/iceyou/motion_recorder.py | 179 ++++++++++++ src/iceyou/startup.py | 50 ++++ src/iceyou/tray_app.py | 368 +++++++++++++++++++++++++ src/iceyou/utils.py | 34 +++ 19 files changed, 2823 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 config.example.json create mode 100644 face_enrollment.py create mode 100644 main.py create mode 100644 requirements.txt create mode 100644 src/iceyou/__init__.py create mode 100644 src/iceyou/actions.py create mode 100644 src/iceyou/camera.py create mode 100644 src/iceyou/config.py create mode 100644 src/iceyou/device_monitor.py create mode 100644 src/iceyou/face_recognizer.py create mode 100644 src/iceyou/input_hooks.py create mode 100644 src/iceyou/keyboard_block.py create mode 100644 src/iceyou/monitor.py create mode 100644 src/iceyou/motion_recorder.py create mode 100644 src/iceyou/startup.py create mode 100644 src/iceyou/tray_app.py create mode 100644 src/iceyou/utils.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..18dab12 --- /dev/null +++ b/.gitignore @@ -0,0 +1,51 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# Virtualenv +.venv/ +venv/ +ENV/ +env/ + +# Config & secrets +config.json +*.log +snapshots/ +faces/ +events.log +motion_clips/ +backup/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo + +# OS +Thumbs.db +.DS_Store + +# PyInstaller +*.spec +build/ +dist/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..fb3c034 --- /dev/null +++ b/README.md @@ -0,0 +1,495 @@ +# ICEYOU - Personal Anti-Intrusion Monitor v:1.2 + +ICEYOU watches your Windows machine while you're away. The moment any input, USB event, or camera tamper happens after idle, it locks the screen behind a full-screen white overlay with a mandatory password / face-unlock gate, snaps a photo of whoever is at the keyboard, records what they typed, and emails you the evidence. + +## Why do it +This project was derived for the traveler or the individual who has a creeper in their proximity. Individuals can allow the system to perform baseline security measures to ensure tampering is not being performed, at an event, a hotel, even at home. Usage is based on a lack of trust with accountability. + +## What It Does + +| Capability | Detail | +|---|---| +| Idle / away detection | Configurable idle timeout flips ICEYOU into "away" mode | +| Whiteout lockout | Full-screen overlay with embedded password + face unlock | +| Motion recording | Rolling 5s pre + event + 5s post AVI clips saved to `motion_clips/` while locked | +| Escape-key blocking | Low-level Windows keyboard hook blocks CTRL+ESC, ALT+TAB, WIN, ALT+F4, CTRL+SHIFT+ESC, etc. while locked | +| Snapshot on attempt | Webcam photo for every unlock attempt (success or failure) | +| Credential logging | Failed password attempts saved to `events.log` and emailed | +| Face recognition unlock | LBPH-based owner verification with `Unlock by Face` button + auto-attempt | +| Camera tamper detection | Triggers full lockdown if lens is covered while locked | +| USB / device monitor | Drive insertions/removals during away are treated as intrusions | +| Email alerts | SMTP with photo attachment + entered credentials | +| OS workstation lock | After N failed password attempts, Windows lock kicks in (whiteout reappears on resume) | +| System tray UI | Pause/resume monitoring, force away, send test email, open snapshots/log | +| Hotkeys | Force away & re-show unlock prompt globally | + +--- + +## Security Notice (Important for Gitea / Remote Hosting) + +**Never commit `config.json`** — it contains your unlock passphrase and email credentials. + +- `config.json` is already listed in `.gitignore`. +- Only `config.example.json` (with placeholders) should ever be pushed to Gitea or any remote repository. +- Before pushing, always run: + ```powershell + git status + git diff --cached --name-only + ``` + and verify that `config.json`, `events.log`, `faces/`, `snapshots/`, and `motion_clips/` do **not** appear. + +If you accidentally stage `config.json`, use `git rm --cached config.json` immediately. + +--- + +## Prerequisites + +- **Windows 10 or 11** (the DirectShow camera backend and low-level keyboard hook are Windows-specific) +- **Python 3.11 or 3.12** (3.11 recommended for best OpenCV compatibility) +- A webcam (USB or built-in). Multiple cameras are supported. +- (Optional but recommended) A Gmail account with **App Password** enabled for email alerts + +## Full Installation + +### 1. Create and activate a virtual environment + +```powershell +python -m venv .venv +.\.venv\Scripts\Activate.ps1 +``` + +### 2. Install dependencies + +```powershell +pip install --upgrade pip +pip install -r requirements.txt +``` + +> **Important**: ICEYOU requires `opencv-contrib-python` (for LBPH face recognition). The requirements file pins a compatible version. + +### 3. Copy the configuration template + +```powershell +copy config.example.json config.json +notepad.exe config.json +``` + +Edit at minimum: +- `unlock_password` — your secret phrase +- `email` section (if you want alerts) +- `camera_device_indices` — list the cameras you want to use (run the list command below to discover indices) + +### 3.5 Configuring Gmail for Email Alerts (Requires 2FA) + +Gmail no longer accepts regular account passwords for SMTP. You **must** use an **App Password**. + +**Steps:** + +1. Go to your Google Account → **Security** +2. Enable **2-Step Verification** (if not already enabled) +3. Under “Signing in to Google”, click **App passwords** +4. Select **Mail** as the app and **Other (Custom name)** → name it `ICEYOU` +5. Copy the **16-character App Password** that Google generates (e.g. `abcd efgh ijkl mnop`) +6. Paste it into `config.json`: + +```json +"email": { + "enabled": true, + "smtp_server": "smtp.gmail.com", + "smtp_port": 587, + "use_tls": true, + "username": "your.email@gmail.com", + "password": "abcd efgh ijkl mnop", // ← the 16-char App Password (spaces optional) + "from_addr": "your.email@gmail.com", + "to_addr": "your.alerts@domain.com" +} +``` + +**Notes:** +- Regular password → “Username and Password not accepted” error. +- The App Password is **not** your normal Gmail password. +- You can revoke App Passwords anytime from the same Google Security page. +- Gmail often delivers the first few alerts to **Spam** — mark them “Not spam” so future alerts go to Inbox. + +### 4. Discover available cameras (optional but recommended) + +```powershell +python face_enrollment.py --list-cameras +``` + +Note the indices of your real webcams (ignore virtual cameras like OBS unless you want them). + +### 5. (Strongly Recommended) Enroll your face for password-less unlock + +Run the enrollment tool multiple times with different appearances / accessories / hair styles: + +```powershell +# Basic enrollment (no accessories) +python face_enrollment.py --name owner + +# With glasses +python face_enrollment.py --name owner_glasses + +# With headphones +python face_enrollment.py --name owner_headphone + +# With both glasses + headphones + hair in a bun +python face_enrollment.py --name owner_headphones_bun +``` + +Each run captures 5 poses (straight, left, right, up, down). The tool automatically retrains `faces/model.yml`. + +**Tips for good enrollment**: +- Good, even lighting (avoid strong back-lighting) +- Neutral expression + slight smile +- Hold still for ~2 seconds per pose +- Remove the camera cover / ensure the lens is clean + +After enrollment you should see: +- `faces/owner/` containing many `.png` images +- `faces/model.yml` (the trained model) +- `faces/labels.json` + +### 6. Enable face unlock (optional) + +In `config.json`: + +```json +"face_recognition_enabled": true, +"face_unlock": { + "enabled": true, + "confidence_threshold": 70.0, + "min_successful_matches": 2, + "auto_attempt": true +} +``` + +- `min_successful_matches: 2` requires two successful frames before unlocking (protects against look-alikes). +- Lower `confidence_threshold` = stricter matching. + +### 7. Run ICEYOU + +```powershell +python main.py +``` + +A red-shield tray icon appears in the system tray. Right-click it for the full menu. + +### 8. (Optional) Add to Windows Startup + +Create a shortcut to `main.py` (or use the `startup.py` helper if present) and place it in: + +``` +%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup +``` + +Or run as a scheduled task (recommended for reliability). + +## First Run Checklist + +- [ ] `config.json` has a strong `unlock_password` +- [ ] Email settings tested with tray → **Send Test Email** +- [ ] At least one camera index works (`camera_device_indices`) +- [ ] Face model trained and `face_unlock.enabled: true` (if desired) +- [ ] White screen dimming settings reviewed (`white_screen_dimming`) +- [ ] Motion recording enabled (default = on) +- [ ] Test the full flow: Force away (`Ctrl+Alt+L`) → wait for whiteout → type wrong password → verify email arrives with snapshot + +## Generated Files & Directories (Ignored by Git) + +| Path | Purpose | Safe to delete? | +|-----------------------|----------------------------------------------|---------------------| +| `faces/` | Enrollment photos + trained `model.yml` | Yes (re-enroll) | +| `snapshots/` | Intrusion & unlock attempt photos | Yes | +| `motion_clips/` | Pre/post-motion AVI recordings | Yes | +| `events.log` | JSON audit trail of all events | Yes (rotates) | +| `config.json` | Your personal settings (never commit) | No (backup first) | + +--- + +## Hotkeys & Manual Control + +| Hotkey (default) | Action | +|---|---| +| `Ctrl+Alt+L` | Force away mode + show whiteout immediately | +| `Ctrl+Alt+U` | Re-show the whiteout password prompt (useful if it was hidden) | + +Combos are configurable in `config.json → hotkeys` using pynput syntax (`+++p`, etc.). Restart ICEYOU after editing. + +--- + +## Tray Menu + +| Item | Description | +|---|---| +| Start / Stop Monitoring | Toggle monitor thread | +| Toggle Away Mode | Manual away on/off (away forces the whiteout) | +| Toggle White Screen | Disable the whiteout while still monitoring | +| Open Snapshots Folder | Browse all captured photos | +| View Motion Clips | Open `motion_clips/` (post-auth in practice) | +| Open Log File | View `events.log` | +| **Send Test Email** | Sanity-check SMTP without triggering an intrusion | +| Settings | Opens `config.json` in Notepad (restart to apply) | +| Exit | Stops everything cleanly | + +--- + +## Intrusion Response Flow + +1. **Detect** — Idle ≥ `idle_timeout_seconds` (or you pressed `Ctrl+Alt+L`) → away mode + whiteout up. +2. **Trigger** — Any keyboard, mouse, USB, or camera-obscured event during away fires an intrusion: + - Snapshot captured (saved to `snapshots/`) + - `intrusion_detected` event logged + - Email alert sent with photo + - Whiteout stays up with the password / face-unlock prompt +3. **Locked state** — `manual_lock` is set; ordinary activity **cannot** clear away mode. Only a correct unlock does. +4. **Password gate** — Cannot be cancelled or closed. After `max_unlock_attempts` (default 3) wrong passwords, Windows workstation lock kicks in. When the user returns from the Windows lock screen the **ICEYOU whiteout is still there** — unlocking Windows alone is not enough. +5. **Success** — Whiteout dismisses, failure counter resets, auto-away is snoozed briefly so you can work. + +--- + +## Unlock Attempt Audit Trail + +Every interaction with the unlock prompt is recorded: + +- **Snapshot** of whoever is at the keyboard: `snapshots/snapshot__unlock__.jpg` +- **Structured log entry** appended to `events.log` (one JSON object per line): + - `method` — `"password"` or `"face"` + - `success` — boolean + - `snapshot` — path to the photo + - `entered` — **only on failed password attempts** — the literal text the intruder typed + - `label`, `confidence` — for face attempts +- **Email alert** (if `email.enabled`) with the snapshot attached: + - Failed password attempts include the typed text in the body + - Successful unlocks confirm but **never** include your real password +- Auto face attempts (every 4 s) are silent (no log / no email) to avoid flooding. Only **manual** `Unlock by Face` clicks and **successful** matches are recorded. + +If alerts aren't arriving: tray → **Send Test Email** (or `python test_email.py`). SMTP errors land in `events.log` as `email_failed`. Gmail → external-domain alerts often hit **Spam** — check there first and mark "Not spam" to whitelist. + +--- + +## Face Recognition Unlock + +Optional second unlock path next to the password. + +1. **Install the contrib OpenCV build** (required for `cv2.face`): + ```powershell + pip install --upgrade --force-reinstall opencv-contrib-python + ``` + +2. **Enroll** your face — multi-pose, multi-look: + ```powershell + python face_enrollment.py --name owner + python face_enrollment.py --camera 1 --list-cameras + ``` + The capture window cycles through 5 poses (straight, left, right, up, down). Controls: + - **Click** the preview window — most reliable capture + - **SPACE / ENTER / C** — capture (window must have focus) + - Hold a steady face ≥ 2 s — auto-capture + - **R** restart, **Q / ESC** quit + + For glasses / headphones / hats, **re-run with the same `--name`** so LBPH learns all your looks under one identity. Each session appends to `faces/