package main import ( "fmt" "io" "net/http" "net/http/cookiejar" "net/url" "os" "regexp" "strings" ) func main() { if len(os.Args) < 4 { fmt.Fprintf(os.Stderr, "Usage: %s [domain...]\n", os.Args[0]) os.Exit(1) } username := os.Args[1] password := os.Args[2] domains := os.Args[3:] jar, _ := cookiejar.New(nil) client := &http.Client{Jar: jar} // Step 1: Fetch login page to get CSRF token resp, err := client.Get("http://127.0.0.1:8000/login.html") if err != nil { fmt.Fprintf(os.Stderr, "FAIL: fetching login page: %v\n", err) os.Exit(1) } body, _ := io.ReadAll(resp.Body) resp.Body.Close() re := regexp.MustCompile(`content="([^"]+)"`) match := re.FindStringSubmatch(string(body)) var csrf string for _, m := range match { if len(m) > 20 { csrf = m break } } if csrf == "" { fmt.Fprintf(os.Stderr, "FAIL: could not extract CSRF token\n") os.Exit(1) } // Step 2: Login form := url.Values{"username": {username}, "password": {password}} req, _ := http.NewRequest("POST", "http://127.0.0.1:8000/api/auth/login", strings.NewReader(form.Encode())) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("X-CSRF-Token", csrf) resp, err = client.Do(req) if err != nil { fmt.Fprintf(os.Stderr, "FAIL: login request: %v\n", err) os.Exit(1) } body, _ = io.ReadAll(resp.Body) resp.Body.Close() if resp.StatusCode != 200 || !strings.Contains(string(body), `"ok"`) { fmt.Fprintf(os.Stderr, "FAIL: login failed (status=%d): %s\n", resp.StatusCode, strings.TrimSpace(string(body))) os.Exit(1) } fmt.Printf("OK: Logged in as %s\n", username) // Step 3: Upload cert for each domain certsDir := "/opt/nextworkspace/config/zoraxy/conf/certs" success := true for _, domain := range domains { // Try .pem first, then .crt for backward compatibility certFile := certsDir + "/" + domain + ".pem" if _, err := os.Stat(certFile); os.IsNotExist(err) { certFile = certsDir + "/" + domain + ".crt" } certData, err := os.ReadFile(certFile) if err != nil { fmt.Printf("SKIP: %s (no cert file)\n", domain) continue } // Get fresh CSRF for each upload resp, err := client.Get("http://127.0.0.1:8000/login.html") if err != nil { fmt.Printf("WARN: %s csrf fetch failed: %v\n", domain, err) continue } body, _ := io.ReadAll(resp.Body) resp.Body.Close() match = re.FindStringSubmatch(string(body)) csrf = "" for _, m := range match { if len(m) > 20 { csrf = m break } } if csrf == "" { fmt.Printf("WARN: %s no CSRF token\n", domain) continue } uploadURL := fmt.Sprintf("http://127.0.0.1:8000/api/cert/upload?ktype=pub&domain=%s", domain) req, _ := http.NewRequest("POST", uploadURL, strings.NewReader(string(certData))) req.Header.Set("X-CSRF-Token", csrf) req.Header.Set("Content-Type", "application/x-pem-file") resp, err = client.Do(req) if err != nil { fmt.Printf("WARN: %s upload failed: %v\n", domain, err) success = false continue } body, _ = io.ReadAll(resp.Body) resp.Body.Close() if resp.StatusCode == 200 { fmt.Printf("OK: %s cert uploaded\n", domain) } else { fmt.Printf("FAIL: %s (status=%d): %s\n", domain, resp.StatusCode, strings.TrimSpace(string(body))) success = false } } if !success { os.Exit(1) } }