VIT AutoConnect (MVP)
Windows tray app that detects the VIT Wi-Fi captive portal and logs you in automatically, using credentials stored via Windows DPAPI. Implements the PRD's MVP scope (sections 1–14).
Using it
- Run
VITAutoConnect.exe. Nothing to install — it is self-contained. - Enter your VIT ID and password once in the setup screen, then Save & Connect.
- It sits in the system tray. When you join VIT Wi-Fi and the portal gets in the way, it signs you in — no browser, no typing.
Right-click the tray icon for Connect / Retry, Settings, and View log. "Start with Windows" is on by default and can be turned off in Settings.
You do not need to configure a portal address. The app reads the login page off the portal itself at the moment it intercepts you — that is how it learns the endpoint, the field names, and the hidden session fields your campus appliance requires.
Requirements to build
- .NET 8 SDK (Windows desktop workload on Windows; on Linux the project sets
EnableWindowsTargetingsodotnet publish -r win-x64works there too)
dotnet build -c Release
dotnet run
There are no external NuGet dependencies — DPAPI is called directly via
P/Invoke instead of the System.Security.Cryptography.ProtectedData package,
so dotnet restore works fully offline.
Tests
tests/PortalTests stands up a real HTTP server that behaves like a captive
portal (302-to-login, login page substituted inline, meta-refresh splash,
session cookies, hidden fields, wrong-password rejection) and drives the real
discovery and authentication code against it:
cd tests/PortalTests
dotnet run
40 checks, exit code 0 when they all pass. This runs on any OS — the portal logic is deliberately free of Windows dependencies so it can be tested away from campus.
How it decides what to do
| Step | File |
|---|---|
| FR-1 Tray app | App/TrayController.cs |
| FR-2 Network detection | Network/NetworkMonitor.cs |
| FR-3 VIT network ID | Network/VITNetworkDetector.cs, Network/WlanInterop.cs |
| FR-4 Captive portal detection | Network/ConnectivityChecker.cs |
| FR-5 Portal discovery + auth | Auth/PortalDiscovery.cs, Auth/VITAuthenticator.cs |
| FR-6 Verification | TrayController.AuthenticateAsync (re-probes after login) |
| FR-7 Retry strategy | Auth/AuthRetryPolicy.cs |
| FR-8 Credential storage | Security/CredentialStore.cs, Security/Dpapi.cs |
| FR-9 Manual control | Tray menu "Connect / Retry" |
| FR-10 Logging | Diagnostics/AppLogger.cs |
| Setup / Settings UI | UI/SetupWindow.cs, UI/SettingsWindow.cs |
| Start with Windows | App/StartupManager.cs |
If it doesn't sign you in
The tray tooltip says what it is doing, and View log has the detail. The app is deliberately honest about why it is not acting, so a network it won't touch is never a silent hang:
- "Not on Wi-Fi - monitoring" — no wireless connection is up (Wi-Fi off, not joined yet, or on ethernet). It re-checks every 30 seconds, so joining VIT Wi-Fi is picked up on its own.
- "Can't identify the Wi-Fi network (…)" — a Wi-Fi network is connected but its name couldn't be read. The app refuses to guess and send your password to an unidentified network. Open View log and send it; the SSID read is the first thing to check.
- "Ignoring 'SOME-SSID' — not a VIT network" — the Wi-Fi name isn't in the
list. Add it in Settings (comma-separated). Matching ignores case, dashes
and underscores, and matches prefixes and substrings, so
VIT-WiFialready coversVIT_WIFI,VIT-WiFi-5G,VITWIFI_MensHosteland so on. - "The saved password is forgotten" — credentials now round-trip-verify on
save, and a failed save shows a dialog with the storage path
(
%LOCALAPPDATA%\VITAutoConnect\credentials.dat) instead of silently doing nothing. If you get that dialog, View log will say which DPAPI call failed (e.g. WLAN/profile issues) — send it over. - "Could not find the Wi-Fi login page" — the portal didn't present a form we could read. Sign in through a browser once, then send the log; the three portal boxes in Settings are the manual escape hatch.
- "The portal rejected your VIT ID or password" — deliberate: the app stops instead of retrying, so a wrong password can't lock your account.
What is not verified
The portal and authentication paths are covered by the tests above. The
Windows-only pieces — reading the SSID through wlanapi.dll
(Network/WlanInterop.cs), DPAPI credential encryption, the tray icon, and
"Start with Windows" — are compiled but cannot be executed on the Linux host
that builds this release. The WLAN struct offsets were re-checked by hand
against the Windows SDK layout (WLAN_CONNECTION_ATTRIBUTES: 4-byte state +
4-byte mode + 512-byte profile name, so the SSID sits at offset 520), and the
read now retries transient failures and logs each Win32 error code. But first
run on a real laptop is still the real test — if the tray says it can't
identify the network, the log now names the exact failing WLAN call.
Security notes
- Password is never written to disk in plaintext;
CredentialStoreencrypts it with DPAPI scoped to the current Windows user (CRYPTPROTECT_UI_FORBIDDEN, noCRYPTPROTECT_LOCAL_MACHINE), so only this Windows account on this machine can decrypt it. Saves are read back and verified before the app reports success. - If the portal's HTTPS certificate can't be validated, the app refuses to send your password rather than turning validation off, and tells you so.
AppLoggeronly ever receives operational strings from this codebase and additionally redacts anything matchingpassword=/pwd=/secret=.- No functionality here attempts to bypass VIT's authentication or network controls — it automates the same login you would do by hand in a browser, using your own credentials, with your consent (per PRD section 10).