Skip to content
This repository has been archived by the owner on Dec 21, 2019. It is now read-only.

A rough version allowing to skip cert verification and allows username and password to be input as arguments #5

Open
farthinder opened this issue Jun 4, 2018 · 0 comments

Comments

@farthinder
Copy link

farthinder commented Jun 4, 2018

Hi and thanks for this project!

I needed it to work with an expired cert and I wanted to be able to set the user and password as arguments so here is my very quick and dirty modification. I've never touched Go before so this is pretty much trial and error but works.

I figured i´d add it as an issue so that others can find the modification.

package main

import (
	"bufio"
	"encoding/xml"
	"fmt"
	"golang.org/x/crypto/ssh/terminal"
	"net/http"
	"os"
	"strings"
	"syscall"
	"crypto/tls"
)

// The XML response returned by the WatchGuard server
type Resp struct {
	Action      string `xml:"action"`
	LogonStatus int    `xml:"logon_status"`
	LogonId     int    `xml:"logon_id"`
	Error       string `xml:"errStr"`
	Challenge   string `xml:"chaStr"`
}

func main() {
	args := os.Args[1:]

	if len(args) < 1 {
		fmt.Fprintln(os.Stderr, "Usage: watchblob <vpn-host>")
		os.Exit(1)
	}

	host := args[0]
	//username, password, err := readCredentials()
	username := args[1]
	password := args[2]
	//if err != nil {
	//	fmt.Fprintf(os.Stderr, "Could not read credentials: %v\n", err)
	//}

	fmt.Printf("Requesting challenge from %s as user %s\n", host, username)
	challenge, err := triggerChallengeResponse(&host, &username, &password)

	if err != nil || challenge.LogonStatus != 4 {
		fmt.Fprintln(os.Stderr, "Did not receive challenge from server")
		fmt.Fprintf(os.Stderr, "Response: %v\nError: %v\n", challenge, err)
		os.Exit(1)
	}

	token := getToken(&challenge)
	err = logon(&host, &challenge, &token)

	if err != nil {
		fmt.Fprintf(os.Stderr, "Logon failed: %v\n", err)
		os.Exit(1)
	}

	fmt.Printf("Login succeeded, you may now (quickly) authenticate OpenVPN with %s as your password\n", token)
}

func readCredentials() (string, string, error) {
	fmt.Printf("Username: ")
	reader := bufio.NewReader(os.Stdin)
	username, err := reader.ReadString('\n')


	fmt.Printf("Password: ")
	password, err := terminal.ReadPassword(syscall.Stdin)
	fmt.Println()

	// If an error occured, I don't care about which one it is.
	return strings.TrimSpace(username), strings.TrimSpace(string(password)), err
}

func triggerChallengeResponse(host *string, username *string, password *string) (r Resp, err error) {
	return request(templateUrl(host, templateChallengeTriggerUri(username, password)))
}

func getToken(challenge *Resp) string {
	fmt.Println(challenge.Challenge)

	reader := bufio.NewReader(os.Stdin)
	token, _ := reader.ReadString('\n')

	return strings.TrimSpace(token)
}

func logon(host *string, challenge *Resp, token *string) (err error) {
	resp, err := request(templateUrl(host, templateResponseUri(challenge.LogonId, token)))
	if err != nil {
		return
	}

	if resp.LogonStatus != 1 {
		err = fmt.Errorf("Challenge/response authentication failed: %v", resp)
	}

	return
}

func request(url string) (r Resp, err error) {
	http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
	resp, err := http.Get(url)
	if err != nil {
		return
	}

	defer resp.Body.Close()
	decoder := xml.NewDecoder(resp.Body)

	err = decoder.Decode(&r)
	return
}
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant