# VPN Tray-Apps (browsergebunden, rootlos)

Menübar-Apps, die ein VPN rootlos aufbauen (openconnect + ocproxy als SOCKS5)
und einen dedizierten Browser starten, der per PAC nur die internen Hosts über
das VPN schickt und alles andere direkt. Jede App hat eigenen SOCKS-/PAC-Port
und eigenes Browser-Profil — mehrere VPNs laufen parallel ohne Konflikt.

## Apps

- **wuerth_vpn_tray.py** — Würth, Cisco AnyConnect (`--protocol=anyconnect`),
  User+Passwort. Fertig und in Betrieb.
- **heron_vpn_tray.py** — Heron, GlobalProtect (`--protocol=gp`), Duo-SAML.
  Läuft rootlos auf macOS: Der SAML-Login (`heron_gp_saml.py`) erfolgt in einem
  nativen WKWebView (pyobjc) mit GlobalProtect-User-Agent, greift den
  `prelogin-cookie` aus den HTTP-Antwort-Headern ab (was QtWebEngine nicht kann)
  und startet damit openconnect inkl. HIP-Report (`--csd-wrapper`) über ocproxy.
  Der SAML-Teil ist ein eigener CLT-Python-Prozess (braucht pyobjc), die Tray-App
  ruft ihn und reicht den Cookie an openconnect.

## Voraussetzungen

- `openconnect` + `ocproxy` (macOS: `brew install openconnect ocproxy`)
- PyQt6 (für die Tray-App), Microsoft Edge (dedizierter Browser)
- Bauen als App-Bundle: py2app (`pip install --user py2app`)

## Bauen (macOS-App-Bundle, Menübar-Only, kein Dock-Icon)

    bash build_wuerth_app.sh      # -> ~/Applications/WuerthVPN.app
    bash build_heron_app.sh       # -> ~/Applications/HeronVPN.app

Die Build-Scripts bauen via py2app, dünnen die Qt-Frameworks aus (~79 MB),
installieren nach `~/Applications` und legen einen LaunchAgent für optionalen
Autostart an (`launchctl load ~/Library/LaunchAgents/com.<name>.vpntray.plist`).

## Ohne Bundle (nur Shell)

- **wuerth_vpn_proxy.sh** — schlanke Shell-Variante: fragt Passwort, baut das
  VPN auf und startet Edge mit PAC. Ohne Tray/Bundle.

## Konfiguration

Im Kopf der jeweiligen `*_tray.py`: SERVER, VPN_USER, PORT/PACPORT,
INTERNAL_GLOB (welche Hosts über das VPN), START_URL, BOOKMARKS. Nach Änderung
neu bauen, da das Script ins Bundle kopiert wird.
