| src/iceyou | ||
| .gitignore | ||
| config.example.json | ||
| face_enrollment.py | ||
| main.py | ||
| README.md | ||
| requirements.txt | ||
| test_email.py | ||
ICEYOU - Personal Anti-Intrusion Monitor
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.
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 |
Quick Start
-
Create a virtualenv (recommended — opencv-contrib requires numpy < 2):
python -m venv .venv .\.venv\Scripts\Activate.ps1 pip install -r requirements.txt -
Copy & edit config:
copy config.example.json config.json notepad config.json- Set
unlock_passwordto your phrase. - Fill SMTP details (Gmail App Password recommended).
- Pick the correct
camera_device_index(runpython face_enrollment.py --list-camerasto enumerate).
- Set
-
(Optional) Enroll your face:
python face_enrollment.py --name ownerRe-run with the same
--namefor each accessory combination (glasses, headphones, hat) to build a robust model. -
Run:
python main.pyA red shield tray icon appears. Right-click for the menu.
-
(Optional) Use the Add to Windows Startup option (via
startup.py) so ICEYOU launches at login.
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) |
Ctrl+Alt+M |
Toggle Monitoring — Pause or resume monitoring (motion + intrusion detection) |
Ctrl+Alt+S |
Stop Monitoring — Immediately pause motion recording and intrusion detection |
Combos are configurable in config.json → hotkeys using pynput syntax (<ctrl>+<shift>+<alt>+p, etc.). Restart ICEYOU after editing.
Automatic behavior: When the user successfully unlocks the whiteout, monitoring is automatically paused (no more motion recording or intrusion detection). It will automatically resume the next time the machine idles for the configured timeout.
Tray Menu
| Item | Description |
|---|---|
| Stop Monitoring | Immediately pauses motion recording, intrusion detection, and releases the camera |
| Resume Monitoring | Re-enables idle detection, motion recording, and intrusion triggers |
| 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
- Detect — Idle ≥
idle_timeout_seconds(or you pressedCtrl+Alt+L) → away mode + whiteout up. - Trigger — Any keyboard, mouse, USB, or camera-obscured event during away fires an intrusion:
- Snapshot captured (saved to
snapshots/) intrusion_detectedevent logged- Email alert sent with photo
- Whiteout stays up with the password / face-unlock prompt
- Snapshot captured (saved to
- Locked state —
manual_lockis set; ordinary activity cannot clear away mode. Only a correct unlock does. - 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. - 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_<timestamp>_unlock_<success|fail>_<password|face>.jpg - Structured log entry appended to
events.log(one JSON object per line):method—"password"or"face"success— booleansnapshot— path to the photoentered— only on failed password attempts — the literal text the intruder typedlabel,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 Faceclicks 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.
-
Install the contrib OpenCV build (required for
cv2.face):pip install --upgrade --force-reinstall opencv-contrib-python -
Enroll your face — multi-pose, multi-look:
python face_enrollment.py --name owner python face_enrollment.py --camera 1 --list-camerasThe 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
Backend selection:
- Default (
--backend lbph): Trains the lightweight LBPH model (faces/model.yml). - DNN (
--backend dnn): Trains a much more accurate FaceNet-style model usingface_recognition(requirespip install face-recognition+ build tools on Windows). Saves tofaces/face_encodings.pkl.
For glasses / headphones / hats, re-run with the same
--nameso the model learns all your looks under one identity. -
Enable in
config.json:"face_recognition_enabled": true, "face_unlock": { "enabled": true, "confidence_threshold": 85.0, "auto_attempt": true, "attempt_interval_seconds": 4.0, "frames_per_attempt": 4, "allowed_labels": ["owner"] }confidence_threshold— lower = stricter (LBPH distance). 50 = very strong, 70 = balanced, 85 = lenient. Tune based on theconf=…value shown on misses.allowed_labels— list of enrolled identities allowed to unlock.null= any enrolled label.auto_attempt— background tries everyattempt_interval_secondswhile the whiteout is up.
While the whiteout is shown:
- Auto-attempts run silently every 4 s (default).
- The Unlock by Face button lets you trigger a manual attempt (this is logged + emailed; auto attempts are not).
- Face failures do not count toward the 3-strike OS-lock — only typed passwords do, so a bad camera angle can never lock you out.
Status hint: failed face attempts show Face not recognised (best=<label>, conf=<value>) on the whiteout. If you consistently see conf slightly above your threshold, either raise the threshold or enroll more samples.
Camera Tamper Detection
When the whiteout is active, ICEYOU periodically samples the camera (default every 12 s). If the frame mean brightness or pixel variance drops below thresholds (lens covered, sticker over webcam, etc.), it immediately triggers full lockdown — email alert + OS workstation lock — without waiting for input. Configure in config.json → camera_obscured_detection.
Motion Recording
While the whiteout is up, src/iceyou/motion_recorder.py continuously samples the webcam and keeps a rolling 5 s pre-buffer of frames. When motion is detected (frame differencing above sensitivity), it writes the buffered pre-roll + the event + 5 s of post-roll to motion_clips/motion_<timestamp>.avi (MJPG codec). Each finalized clip:
- Logs a
motion_recordedline toevents.logwith the clip path. - Pops a system-tray notification ("Motion event saved: motion_…avi").
- Does not trigger an email (snapshots + unlock attempts already cover that).
Recording starts on WhiteScreen.show() and stops on WhiteScreen.hide() — there is no recording when ICEYOU is not in the locked state.
Viewing clips post-authentication: the tray menu has a View Motion Clips item that opens the motion_clips/ folder in Explorer. While the whiteout is up the escape-key hook prevents the intruder from reaching the tray icon, so this item is effectively post-authentication. Once you unlock, right-click the tray icon and pick View Motion Clips to review.
Config (config.json → motion_recording):
"motion_recording": {
"enabled": true,
"clips_dir": "motion_clips",
"fps": 15,
"pre_seconds": 5.0,
"post_seconds": 5.0,
"sensitivity": 2500, // min contour area in pixels; lower = more sensitive
"cooldown_seconds": 8.0 // min gap between separate clips
}
Escape-Key Blocking
While the whiteout is shown, a low-level Windows keyboard hook (src/iceyou/keyboard_block.py) swallows:
WIN(left + right)CTRL+ESC(Start menu)ALT+TAB,ALT+ESC(task switching)ALT+F4(close window)ALT+SPACE(window menu)CTRL+SHIFT+ESC(Task Manager hotkey)
Disable with "block_escape_keys": false if needed (e.g. development). The hook is removed automatically on unlock.
Hard limits (Windows-enforced, cannot be intercepted from user mode):
CTRL+ALT+DEL— Secure Attention Sequence is kernel-enforced. An intruder can still reach the security screen → Task Manager → killpython.exe.- Hard power off, pulling the keyboard.
- Logging in as a different Windows user.
To harden against CTRL+ALT+DEL → Task Manager, run as Administrator and set the registry value HKCU\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableTaskMgr = 1 (DWORD). ICEYOU does not apply this automatically because it's a system-wide setting affecting every program.
Configuration Reference (config.json)
{
"idle_timeout_seconds": 100, // Idle seconds before auto-away
"monitoring_enabled": true, // Master on/off (start in monitoring mode)
"camera_device_index": 1, // (Legacy single-cam fallback - used only if camera_device_indices is omitted)
"camera_device_indices": [0, 1], // Multi-cam: probe each of these. Dead indices are auto-skipped.
"camera_probe_timeout_seconds": 2.5, // Per-camera open+first-frame budget; phantom devices that block longer are marked DEAD
"snapshot_on_trigger": true, // Save a photo on every intrusion / attempt (one per alive camera)
"snapshot_dir": "snapshots",
"log_file": "events.log",
"email": {
"enabled": true,
"smtp_server": "smtp.gmail.com",
"smtp_port": 587,
"use_tls": true,
"username": "you@gmail.com",
"password": "APP_PASSWORD", // Gmail App Password, no spaces
"from_addr": "you@gmail.com",
"to_addr": "alerts@you.com",
"subject_prefix": "[ICEYOU Alert]"
},
"lock_workstation": true, // OS lock after max_unlock_attempts password fails
"device_monitoring": true, // Watch USB drives
"white_screen_on_away": true, // Show the whiteout when away
"unlock_password": "iceyou2026!", // Your secret phrase
"max_unlock_attempts": 3, // Wrong passwords before OS lock
"block_escape_keys": true, // Install OS keyboard hook while locked
"camera_obscured_detection": {
"enabled": true,
"brightness_threshold": 25,
"variance_threshold": 10,
"check_interval_seconds": 6
},
"hotkeys": {
"force_away": "<ctrl>+<alt>+l",
"unlock": "<ctrl>+<alt>+u"
},
"face_recognition_enabled": true,
"face_unlock": {
"enabled": true,
"confidence_threshold": 85.0, // Lower = stricter (LBPH distance)
"auto_attempt": true,
"attempt_interval_seconds": 4.0,
"frames_per_attempt": 4,
"allowed_labels": ["owner"] // null = accept any enrolled label
}
}
Troubleshooting
| Symptom | Fix |
|---|---|
| No tray icon | Make sure python main.py is running; check events.log for startup errors. |
| Email alerts not arriving | Check Spam folder. Use Send Test Email in tray (or python test_email.py). Look for email_failed in events.log. |
| Face unlock never matches | Status line shows conf=<value>. Either raise confidence_threshold in config.json or re-enroll with more samples / better lighting / same accessories you're wearing now. |
| Password field clears mid-typing | Already fixed — input while the whiteout is up is treated as challenge, not re-intrusion. Pull latest monitor.py + white_screen.py. |
Tk error Tcl_AsyncDelete: async handler deleted by the wrong thread |
Already fixed — WhiteScreen uses a persistent Tk root on a dedicated thread. |
Tk error can't set fullscreen attribute… override-redirect flag is set |
Already fixed — WhiteScreen sizes to screen via geometry() instead of -fullscreen. |
numpy<2 conflict with opencv-contrib-python |
Use the recommended .venv virtualenv. |
| Antivirus flags ICEYOU | Low-level keyboard hooks trigger heuristics. Whitelist the project folder. |
Project Structure
ICEYOU/
├── main.py Tray app entrypoint
├── face_enrollment.py Standalone face capture + LBPH training
├── test_email.py CLI SMTP sanity check
├── config.json Runtime settings (gitignored)
├── config.example.json Template
├── events.log JSON-lines event audit trail
├── snapshots/ All captured webcam photos
├── motion_clips/ 5s-before + event + 5s-after AVI clips from the whiteout
├── faces/
│ ├── model.yml Trained LBPH model
│ ├── labels.json Label id → name map
│ └── <label>/capture_NN.png Enrolled photos per identity
└── src/iceyou/
├── tray_app.py System tray + wiring
├── monitor.py Away state machine + intrusion trigger
├── white_screen.py Persistent Tk fullscreen lockout + unlock UI
├── face_recognizer.py LBPH recognizer with multi-crop verification
├── motion_recorder.py Rolling-buffer motion clips while locked
├── keyboard_block.py Low-level Windows keyboard hook
├── camera.py Webcam capture, snapshots, obscured detection
├── input_hooks.py pynput keyboard + mouse global hooks
├── device_monitor.py Drive insertion/removal poller
├── actions.py Email alerts (intrusion + unlock attempts)
├── utils.py Win32 idle time, lock workstation, timestamps
├── startup.py HKCU Run registry add/remove
└── config.py Deep-merged config loader with dotted-key get
Privacy & Use
ICEYOU accesses your camera, keyboard, mouse, and writes intruder photos + entered text to local disk and email. It is intended strictly for protecting your own machine. Do not use it for unauthorized surveillance of others.
Roadmap
- Encrypted at-rest storage of snapshots and log
- Optional cloud upload of evidence
- Windows service mode (run without an interactive session)
- Web dashboard for remote review
- DNN-based face recognition (FaceNet / dlib) for higher accuracy than LBPH