- Go stdlib-only gateway: serves noVNC client, password auth, WS<->TCP relay - auth: PBKDF2-HMAC-SHA256 password hash, HMAC session cookies, login rate limit - relay: hand-written RFC 6455 WebSocket + transparent RFB bridge - vncspawner: cross-OS VNC server detection/launch (Windows/Linux/macOS) - server: /login /logout /vnc /api/status routes, session middleware, embed.FS - scripts: get-novnc, get-vnc (zip-verified), list-ips, open-firewall - run.bat: one-click launcher (asks only password), lists access IPs - README/AGENTS.md (Russian), .gitignore (root-anchored binaries)
82 lines
2.1 KiB
Go
82 lines
2.1 KiB
Go
//go:build windows
|
|
|
|
package vncspawner
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// detectWindows looks for UltraVNC and TightVNC in common install locations,
|
|
// in a project-local "vnc" folder, and in WEBVNC_VNC_DIR.
|
|
func candidates() []Candidate {
|
|
var cands []Candidate
|
|
|
|
// 1. Project-local vnc/ folder (current working directory) — used by get-vnc.ps1.
|
|
cands = append(cands, scanDir(filepath.Join(mustCwd(), "vnc"))...)
|
|
// 2. Explicit env override.
|
|
if dir := os.Getenv("WEBVNC_VNC_DIR"); dir != "" {
|
|
cands = append(cands, scanDir(dir)...)
|
|
}
|
|
// 3. Standard install paths.
|
|
for _, base := range []string{
|
|
`C:\Program Files\uvnc bvba\UltraVNC\winvnc.exe`,
|
|
`C:\Program Files (x86)\uvnc bvba\UltraVNC\winvnc.exe`,
|
|
`C:\Program Files\UltraVNC\winvnc.exe`,
|
|
`C:\Program Files (x86)\UltraVNC\winvnc.exe`,
|
|
`C:\Program Files\TightVNC\tvnserver.exe`,
|
|
`C:\Program Files (x86)\TightVNC\tvnserver.exe`,
|
|
} {
|
|
if fileExists(base) {
|
|
cands = append(cands, Candidate{Path: base, Args: []string{"-run"}, Desc: filepath.Base(base)})
|
|
}
|
|
}
|
|
// 4. Scan Program Files dirs (covers custom install paths).
|
|
for _, d := range programDirs() {
|
|
for _, pat := range []string{"UltraVNC*\\winvnc.exe", "TightVNC*\\tvnserver.exe"} {
|
|
matches, _ := filepath.Glob(filepath.Join(d, pat))
|
|
for _, m := range matches {
|
|
if fileExists(m) {
|
|
cands = append(cands, Candidate{Path: m, Args: []string{"-run"}, Desc: filepath.Base(m)})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return cands
|
|
}
|
|
|
|
// scanDir looks for winvnc.exe / tvnserver.exe in dir.
|
|
func scanDir(dir string) []Candidate {
|
|
var out []Candidate
|
|
for _, name := range []string{"winvnc.exe", "tvnserver.exe"} {
|
|
p := filepath.Join(dir, name)
|
|
if fileExists(p) {
|
|
out = append(out, Candidate{Path: p, Args: []string{"-run"}, Desc: name})
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func mustCwd() string {
|
|
wd, err := os.Getwd()
|
|
if err != nil {
|
|
return "."
|
|
}
|
|
return wd
|
|
}
|
|
|
|
func programDirs() []string {
|
|
var dirs []string
|
|
for _, env := range []string{"ProgramFiles", "ProgramFiles(x86)", "ProgramW6432"} {
|
|
if v := os.Getenv(env); v != "" {
|
|
dirs = append(dirs, v)
|
|
}
|
|
}
|
|
return dirs
|
|
}
|
|
|
|
func fileExists(p string) bool {
|
|
_, err := os.Stat(p)
|
|
return err == nil
|
|
}
|