Skip to content

Instantly share code, notes, and snippets.

@nicerobot
Last active July 22, 2020 00:51
Show Gist options
  • Save nicerobot/4375261 to your computer and use it in GitHub Desktop.
Save nicerobot/4375261 to your computer and use it in GitHub Desktop.
HTTPS Basic Authentication in Go :Gish
#!/bin/sh
# Shows the missing certiicate portion of the rosettacode.org example
exec 3>&1 4>&2
exec >/dev/null 2>&1
PASS=$(date +%A%w%Y%m%d%H%M%S%B)$$${RANDOM}${RANDOM}
echo ${PASS}
openssl genrsa -des3 -passout pass:${PASS} -out server.key 1024
openssl req -new -key server.key -passin pass:${PASS} -out server.csr <<CERT
EA
n/a
127.0.0.1
${USER}@127.0.0.1
CERT
openssl rsa -in server.key -passin pass:${PASS} -out server.key
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
go build server.go && {
./server & server=$!
trap "kill ${server}" 0
go run client.go >&3
}
rm server.{key,crt,csr}
exit 0
package main
import (
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"log"
"net/http"
)
const (
userid = "rosetta"
password = "code"
)
func main() {
// Use custom certificate for testing. Not exactly required by task.
b, err := ioutil.ReadFile("server.crt")
if err != nil {
log.Fatal(err)
}
pool := x509.NewCertPool()
if ok := pool.AppendCertsFromPEM(b); !ok {
log.Fatal("Failed to append cert")
}
tc := &tls.Config{RootCAs: pool}
tr := &http.Transport{TLSClientConfig: tc}
client := &http.Client{Transport: tr}
req, err := http.NewRequest("GET", "https://127.0.0.1:8080", nil)
if err != nil {
log.Fatal(err)
}
// This one line implements the authentication required for the task.
req.SetBasicAuth(userid, password)
// Make request and show output.
resp, err := client.Do(req)
if err != nil {
log.Fatal(err)
}
b, err = ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
log.Fatal(err)
}
fmt.Println(string(b))
}
<html><head><meta http-equiv="refresh" content="0;URL='https://gist.github.com/4375261'"></head></html>
#!/bin/sh
for f in client.go server.go authenticated.sh; do
[ -f ${f} ] || curl -ksO https://gist.github.com/raw/4375261/${f} &
done
wait
sh authenticated.sh
exit 0
package main
import (
"encoding/base64"
"io"
"log"
"net/http"
"strings"
)
const userPass = "rosetta:code"
const unauth = http.StatusUnauthorized
func hw(w http.ResponseWriter, req *http.Request) {
auth := req.Header.Get("Authorization")
if !strings.HasPrefix(auth, "Basic ") {
log.Print("Invalid authorization:", auth)
http.Error(w, http.StatusText(unauth), unauth)
return
}
up, err := base64.StdEncoding.DecodeString(auth[6:])
if err != nil {
log.Print("authorization decode error:", err)
http.Error(w, http.StatusText(unauth), unauth)
return
}
if string(up) != userPass {
log.Print("invalid username:password:", string(up))
http.Error(w, http.StatusText(unauth), unauth)
return
}
io.WriteString(w, "Goodbye, World!")
}
func main() {
http.HandleFunc("/", hw)
log.Fatal(http.ListenAndServeTLS(":8080", "server.crt", "server.key", nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment