A Rust-based daemon that automatically authenticates against IIT Mandi's captive portal. It runs as a background service with intelligent hybrid network monitoring (netwatcher + adaptive polling), secure credential storage, and desktop notifications.
- Automatic Login: Detects and authenticates with the captive portal instantly upon network changes
- Hybrid Monitoring: Combines real-time network event detection with intelligent exponential backoff polling
- Secure Credentials: Stores credentials in OS keychain (macOS Keychain / Linux Secret Service / Windows Credential Manager)
- Desktop Notifications: Get notified when successfully logged in
- Smart Retry Logic: Automatic retry with exponential backoff on login failures
- Service Status: Monitor service health and login statistics with animated spinners
- Configurable: Optional
config.tomlfor customizing poll intervals, connectivity check URL, and retry behavior - Structured Logging: Async-aware structured logging with automatic log rotation
- Cross-Platform: Supports macOS (x86_64, ARM64), Linux (x86_64, ARM64), and Windows (x86_64)
- macOS, Linux, or Windows
- jq (required for the installation script on macOS/Linux):
- On macOS:
brew install jq - On Linux:
apt install jq(Debian/Ubuntu) oryum install jq(CentOS/RHEL)
- On macOS:
- Rust and Cargo (only if building from source)
To install and set up the Auto Captive Portal Login service, run:
curl -fsSL https://raw.githubusercontent.com/amansikarwar/auto-captive-portal/main/install.sh | bashThis command will:
- Download the latest
acpbinary for your platform from GitHub releases - Install it to
/usr/local/bin/acp - Prompt you for your LDAP credentials
- Store credentials securely in your OS keychain
- Create and start the background service
Note: You will be prompted for your LDAP credentials during the setup process.
- Download the latest
acp-script-windows-amd64.exefrom GitHub Releases - Rename it to
acp.exeand place it in a permanent location (e.g.,C:\Program Files\ACP\) - Run as Administrator:
acp.exe setup
The Windows version includes a UAC manifest that automatically requests administrator privileges when installing the service.
| Platform | Architecture | Binary Name |
|---|---|---|
| Linux | x86_64 | acp-script-linux-amd64 |
| Linux | ARM64 | acp-script-linux-arm64 |
| macOS | Intel (x86_64) | acp-script-macos-x86_64 |
| macOS | Apple Silicon (ARM64) | acp-script-macos-arm64 |
| Windows | x86_64 | acp-script-windows-amd64.exe |
# Show service status and statistics
acp status
# Update stored credentials
acp update-credentials
# Perform health check (verify credentials, portal detection, connectivity)
acp health
# Initialize default configuration file
acp init
# Logout from captive portal
acp logout
# Logout and clear stored credentials
acp logout --clear-credentials
# Show help and available commands
acp --help
# Run daemon directly (for testing)
acp run# Install Windows service (run as Administrator)
acp.exe service install
# Uninstall Windows service
acp.exe service uninstall
# Start/stop the service
acp.exe service start
acp.exe service stopThe acp status command provides comprehensive information:
╔══════════════════════════════════════════════════════╗
║ Auto Captive Portal - Service Status ║
╚══════════════════════════════════════════════════════╝
Credentials: ✓ Configured (user: your_username)
Service: ✓ Running
Internet: ✓ Connected
Portal Status: ✓ Not detected
─────────────────────────────────────────────────────
Last Check: 2 minutes ago
Last Login: 15 minutes ago
Last Portal: https://login.iitmandi.ac.in:1003/portal
The service runs as a LaunchAgent (com.user.acp) and starts automatically on login.
Manual Service Management:
# Check if service is running
launchctl list | grep com.user.acp
# Start service
launchctl load ~/Library/LaunchAgents/com.user.acp.plist
# Stop service
launchctl unload ~/Library/LaunchAgents/com.user.acp.plist
# View logs (last 5 minutes)
log show --predicate 'processImagePath contains "acp"' --last 5m
# Follow logs in real-time
log stream --predicate 'processImagePath contains "acp"'Credentials Storage: Uses macOS Keychain (security command)
Log File Location: ~/.local/share/acp/logs/acp.log
The service runs as a systemd user service (acp.service).
Manual Service Management:
# Check service status
systemctl --user status acp
# Start service
systemctl --user start acp
# Stop service
systemctl --user stop acp
# Restart service
systemctl --user restart acp
# View logs (last 50 lines)
journalctl --user -u acp -n 50
# Follow logs in real-time
journalctl --user -u acp -fCredentials Storage: Uses Linux Secret Service (libsecret)
Log File Location: ~/.local/share/acp/logs/acp.log
The service runs as a Windows Service (acp) and can be configured to start automatically.
Manual Service Management:
# Check service status
sc query acp
# Start service
net start acp
# Stop service
net stop acp
# View service in Services Manager
services.mscCredentials Storage: Uses Windows Credential Manager
Log File Location: %APPDATA%\acp\logs\acp.log
Note: Installing or uninstalling the Windows service requires Administrator privileges. The application will automatically prompt for elevation via UAC.
ACP uses a hybrid monitoring approach for optimal responsiveness and resource efficiency:
-
Real-time Network Event Detection (via
netwatcherlibrary)- Monitors network interface changes (new interfaces, IP address assignments)
- Triggers immediate portal check (after 3-second debounce delay)
- Detects: Wi-Fi connections, VPN changes, ethernet connections
-
Adaptive Polling (exponential backoff)
- Portal detected: Checks every 10 seconds (configurable via
min_delay_secs) - Successfully logged in: Checks every 30 minutes (configurable via
max_delay_secs) - No portal found: Gradually decreases interval (exponential decay to minimum)
- Portal detected: Checks every 10 seconds (configurable via
-
Portal Detection: Requests
http://clients3.google.com/generate_204(configurable)- No portal: Receives 204 response → Internet accessible
- Portal present: Receives 200 redirect → Extract portal URL and magic value using DOM parsing
-
Login Attempt: POSTs to
https://login.iitmandi.ac.in:1003/portal?with:- Username and password (from keychain)
- Magic value (extracted from portal HTML via CSS selectors)
- Redirect URL
-
Verification: Confirms internet connectivity after login
- Success → Desktop notification + Set max poll interval
- Failure → Retry with exponential backoff (configurable max retries)
ACP works out of the box with sensible defaults. For customization, run acp init to create a config file:
- macOS/Linux:
~/.config/acp/config.toml - Windows:
%APPDATA%\acp\config.toml
connectivity_check_url = "http://clients3.google.com/generate_204"
max_delay_secs = 1800
min_delay_secs = 10
max_retries = 3
initial_retry_delay_secs = 2
log_level = "INFO"All fields are optional — missing fields use defaults. The environment variable ACP_CONNECTIVITY_URL can also override the connectivity check URL.
- macOS: Stored in macOS Keychain using
securitycommand - Linux: Stored in Secret Service (GNOME Keyring, KWallet, etc.) using
libsecret - Windows: Stored in Windows Credential Manager
- No plaintext: Credentials never stored in configuration files
- OS-level encryption: Leverages OS native secure storage
To completely remove the Auto Captive Portal service:
curl -fsSL https://raw.githubusercontent.com/amansikarwar/auto-captive-portal/main/install.sh | bash -s uninstallThis will:
- Stop and remove the background service
- Delete stored credentials from keychain
- Remove the
acpbinary from/usr/local/bin/ - Remove logs and state files from
~/.local/share/acp/ - Clean up all service configuration files
| Issue | Solution |
|---|---|
| "Keyring error" or "Credentials not found" | Run acp setup to store credentials |
| Service not running | Check logs (see platform-specific commands above) |
| Login failed | Run acp update-credentials to update credentials |
| Portal URL/magic extraction fails | Portal format may have changed - check captive_portal.rs |
| No notifications | Check notification permissions for the application |
# Check service health and connectivity
acp health
# View detailed service status
acp status
# Check logs
# macOS:
log show --predicate 'processImagePath contains "acp"' --last 5m
# or check file log:
cat ~/.local/share/acp/logs/acp.log
# Linux:
journalctl --user -u acp -n 50
# or check file log:
cat ~/.local/share/acp/logs/acp.log
# Windows (PowerShell):
Get-Content "$env:APPDATA\acp\logs\acp.log" -Tail 50To test the service without installing:
# Build from source
cargo build --release
# Run setup (stores credentials)
./target/release/acp-script setup
# Run daemon directly (set log level via RUST_LOG env var)
RUST_LOG=debug ./target/release/acp-script
# Or run health check
./target/release/acp-script healthsrc/
├── main.rs # CLI entry point and command handlers
├── daemon.rs # Core daemon loop with hybrid monitoring
├── captive_portal.rs # Portal detection and authentication (DOM-based)
├── config.rs # Configuration file support (TOML)
├── credentials.rs # Secure credential storage (OS keychain)
├── service.rs # Platform-specific service management
├── state.rs # Persistent state tracking
├── notifications.rs # Desktop notifications
├── logging.rs # Structured logging (tracing)
└── error.rs # Error types
# Clone repository
git clone https://github.com/amansikarwar/auto-captive-portal.git
cd auto-captive-portal
# Build release binary
cargo build --release
# Run tests
cargo test
# Run clippy
cargo clippy
# Binary will be at: target/release/acp-scriptThe project uses GitHub Actions for cross-platform builds:
# Targets:
- x86_64-unknown-linux-gnu → acp-script-linux-amd64
- aarch64-unknown-linux-gnu → acp-script-linux-arm64
- x86_64-apple-darwin → acp-script-macos-x86_64
- aarch64-apple-darwin → acp-script-macos-arm64
- x86_64-pc-windows-msvc → acp-script-windows-amd64.exeFor notification support on Linux:
# Debian/Ubuntu
sudo apt-get install libgtk-3-dev libayatana-appindicator3-dev
# Fedora/RHEL
sudo dnf install gtk3-devel libappindicator-gtk3-develContributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with Rust
- HTML parsing via scraper
- Structured logging via tracing
- Network monitoring via netwatcher
- Secure credential storage via keyring-rs
- Desktop notifications via notify-rust
- CLI spinners via indicatif