Repository navigation
Expand file tree
/
Copy pathdigest.go
More file actions
77 lines (64 loc) · 1.98 KB
/
Copy pathdigest.go
File metadata and controls
77 lines (64 loc) · 1.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Shamelessly stolen from http://play.golang.org/p/ABoHSHoTmu
// I merely fixed the weirdness around the return in GetAuthorization -- mhenkel
package main
import (
"crypto/md5"
"encoding/hex"
"fmt"
"io"
"net/http"
"net/url"
"strings"
)
type Authorization struct {
Username, Password, Realm, NONCE, QOP, Opaque, Algorithm string
}
func GetAuthorization(username, password string, resp *http.Response) *Authorization {
header := resp.Header.Get("www-authenticate")
parts := strings.SplitN(header, " ", 2)
parts = strings.Split(parts[1], ", ")
opts := make(map[string]string)
for _, part := range parts {
vals := strings.SplitN(part, "=", 2)
key := vals[0]
val := strings.Trim(vals[1], "\",")
opts[key] = val
}
return &Authorization{
username, password,
opts["realm"], opts["nonce"], opts["qop"], "", "",
}
}
func GetAuthString(auth *Authorization, url *url.URL, method string, nc int) string {
uri := url.Path
// I'm not certain if this is necessary, but curl includes the query.
if url.RawQuery != "" {
uri = uri + "?" + url.RawQuery
}
a1 := auth.Username + ":" + auth.Realm + ":" + auth.Password
h := md5.New()
io.WriteString(h, a1)
ha1 := hex.EncodeToString(h.Sum(nil))
h = md5.New()
a2 := method + ":" + uri
io.WriteString(h, a2)
ha2 := hex.EncodeToString(h.Sum(nil))
nc_str := fmt.Sprintf("%08x", nc)
hnc := "MTM3MDgw"
respdig := fmt.Sprintf("%s:%s:%s:%s:%s:%s", ha1, auth.NONCE, nc_str, hnc, auth.QOP, ha2)
h = md5.New()
io.WriteString(h, respdig)
respdig = hex.EncodeToString(h.Sum(nil))
base := "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", response=\"%s\""
base = fmt.Sprintf(base, auth.Username, auth.Realm, auth.NONCE, uri, respdig)
if auth.Opaque != "" {
base += fmt.Sprintf(", opaque=\"%s\"", auth.Opaque)
}
if auth.QOP != "" {
base += fmt.Sprintf(", qop=\"%s\", nc=%s, cnonce=\"%s\"", auth.QOP, nc_str, hnc)
}
if auth.Algorithm != "" {
base += fmt.Sprintf(", algorithm=\"%s\"", auth.Algorithm)
}
return "Digest " + base
}