diff --git a/app.py b/app.py index 2504e59..a20216b 100644 --- a/app.py +++ b/app.py @@ -548,6 +548,28 @@ def main() -> None: print("=" * 50) print() + # Check if running as root (required for WiFi monitor mode, some BT operations) + import os + if os.geteuid() != 0: + print("\033[93m" + "=" * 50) + print(" ⚠️ WARNING: Not running as root/sudo") + print("=" * 50) + print(" Some features require root privileges:") + print(" - WiFi monitor mode and scanning") + print(" - Bluetooth low-level operations") + print(" - RTL-SDR access (on some systems)") + print() + print(" To run with full capabilities:") + print(" sudo -E venv/bin/python intercept.py") + print("=" * 50 + "\033[0m") + print() + # Store for API access + app.config['RUNNING_AS_ROOT'] = False + else: + app.config['RUNNING_AS_ROOT'] = True + print("Running as root - full capabilities enabled") + print() + # Clean up any stale processes from previous runs cleanup_stale_processes() diff --git a/routes/tscm.py b/routes/tscm.py index 5897817..d62a89b 100644 --- a/routes/tscm.py +++ b/routes/tscm.py @@ -596,7 +596,25 @@ def get_tscm_devices(): except Exception as e: logger.warning(f"Error detecting SDR devices: {e}") - return jsonify({'status': 'success', 'devices': devices}) + # Check if running as root + import os + from flask import current_app + running_as_root = current_app.config.get('RUNNING_AS_ROOT', os.geteuid() == 0) + + warnings = [] + if not running_as_root: + warnings.append({ + 'type': 'privileges', + 'message': 'Not running as root. WiFi monitor mode and some Bluetooth features require sudo.', + 'action': 'Run with: sudo -E venv/bin/python intercept.py' + }) + + return jsonify({ + 'status': 'success', + 'devices': devices, + 'running_as_root': running_as_root, + 'warnings': warnings + }) def _scan_wifi_networks(interface: str) -> list[dict]: diff --git a/templates/index.html b/templates/index.html index e954d4f..f6d4db0 100644 --- a/templates/index.html +++ b/templates/index.html @@ -2075,6 +2075,31 @@ .tscm-status-message .status-icon { font-size: 16px; } + .tscm-privilege-warning { + padding: 10px 12px; + background: rgba(255, 51, 51, 0.15); + border: 1px solid rgba(255, 51, 51, 0.4); + border-radius: 6px; + color: var(--text-primary); + font-size: 11px; + display: flex; + align-items: flex-start; + gap: 10px; + margin-bottom: 12px; + } + .tscm-privilege-warning .warning-icon { + font-size: 18px; + flex-shrink: 0; + } + .tscm-privilege-warning .warning-action { + margin-top: 4px; + font-family: 'JetBrains Mono', monospace; + font-size: 10px; + color: var(--accent-cyan); + background: rgba(0, 0, 0, 0.3); + padding: 4px 8px; + border-radius: 3px; + } .tscm-device-reasons { font-size: 10px; color: var(--text-secondary); @@ -10125,6 +10150,23 @@ sdrSelect.innerHTML = ''; } + // Show warnings (e.g., not running as root) + const warningsDiv = document.getElementById('tscmDeviceWarnings'); + if (data.warnings && data.warnings.length > 0) { + warningsDiv.innerHTML = data.warnings.map(w => + `