Based on rosettacode.org's HTTPS/Authenticated#Go.
Run:
curl -ks https://gist.github.com/raw/4375261/run.sh | sh
The client will respond with the message from the server:
Goodbye, World!
Based on rosettacode.org's HTTPS/Authenticated#Go.
Run:
curl -ks https://gist.github.com/raw/4375261/run.sh | sh
The client will respond with the message from the server:
Goodbye, World!
| #!/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)) | |
| } |