Skip to content

Repository files navigation

HITSZ AutoNet

Automated HITSZ (Harbin Institute of Technology, Shenzhen) campus network authentication.

Overview

Two independent implementations sharing the same operational logic:

Platform Approach Status
Python daemon (macOS) Pure HTTP — Srun portal API Active
Android App (Kotlin) WebView + JavaScript injection Active

Both detect captive portals by probing baidu.com and authenticate against the campus Srun portal on a 60-second loop.

Quick Start — Python Daemon (macOS)

# Install deps
uv sync

# Create config
cat > .env << EOF
HITSZ_USERNAME=your_student_id
HITSZ_PASSWORD=your_password
EOF

# Single check
uv run hitsz_net/hitsz_net.py --once

# Install as background service (auto-starts on boot)
uv run service/install.py install --config .env

# Manage
uv run service/install.py status
uv run service/install.py uninstall

Logs: ~/Library/Logs/hitsz-autonet/service.log

How It Works

check_internet() ──→ baidu.com reachable? ──→ OK, sleep 60s
         │ no (captive portal redirect)
         └──→ GET /cgi-bin/get_challenge
              Compute HMAC-MD5 + XXTEA-encrypted credentials
              GET /cgi-bin/srun_portal
              Verify connectivity

No browser, no ChromeDriver — pure HTTP requests against the Srun portal API.

Stateful interface handoff

On macOS, the daemon remembers each account's observed interface/IP sessions in ~/Library/Application Support/hitsz-autonet/session-state.json (mode 0600). This survives DHCP changes and restarts.

Each monitor cycle:

  1. finds the current default interface and its IPv4 address;
  2. queries every remembered non-current IP directly with rad_user_info?ip=<historical-ip>;
  3. requires the historical IP to still be online under the configured account;
  4. reports a MAC change through a notification, but does not block logout because macOS private/random MACs can change;
  5. rechecks the default route, sends an IP-targeted rad_user_dm, and requires a follow-up query to report the old IP offline before deleting it from state; and
  6. records the current default-interface session after a successful login or online check.

The daemon never chooses an unrelated account session. When Srun rejects login because the online-device limit was reached (for example E2620), the notification includes the portal code/message, current interface/IP, device total, and any returned device summary.

Android App

cd android-app
export JAVA_HOME=/opt/homebrew/opt/openjdk@17
export ANDROID_HOME=/opt/homebrew/share/android-commandlinetools
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk

See android-app/README.md for details.

Project Structure

hitsz-autonet/
├── hitsz_net/              # Python daemon
│   ├── hitsz_net.py        # Main daemon (connectivity check, login, notifications, daemon loop)
│   └── srun_crypto.py      # Srun portal crypto (XXTEA, custom base64, HMAC-MD5, SHA1)
├── service/                # macOS LaunchAgent installer
│   └── install.py
├── android-app/            # Android app (Kotlin, Gradle)
│   └── app/src/main/java/com/hitsz/autonet/
├── requirements.txt        # Python deps (pip-compatible)
└── AGENTS.md               # AI assistant guidelines

Requirements

  • Python >= 3.13 (managed via uv)
  • Android: JDK 17, Gradle 8.7, AGP 8.5.0, minSdk 24

License

MIT — adapted from siliconx/hitsz_net.

About

Automated HITSZ campus network authentication - Python daemon and Android app

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages