Skip to content
This repository was archived by the owner on Jun 21, 2022. It is now read-only.

Commit 87372fa

Browse files
committed
still missing some authentication
1 parent cb42ea2 commit 87372fa

File tree

3 files changed

+102
-44
lines changed

3 files changed

+102
-44
lines changed

digest_auth_client.go

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"bytes"
55
"fmt"
66
"net/http"
7-
"strings"
87
"time"
98
)
109

@@ -28,34 +27,55 @@ func (dr *DigestRequest) NewRequest(
2827
return *dr
2928
}
3029

31-
func (dr *DigestRequest) Execute() (*http.Response, error) {
32-
33-
req, err := http.NewRequest(dr.Method, dr.Uri, bytes.NewReader([]byte(dr.Body)))
34-
if err != nil {
30+
func (dr *DigestRequest) Execute() (resp *http.Response, err error) {
31+
var req *http.Request
32+
if req, err = http.NewRequest(dr.Method, dr.Uri, bytes.NewReader([]byte(dr.Body))); err != nil {
3533
return nil, err
3634
}
3735

3836
client := &http.Client{
3937
Timeout: 30 * time.Second,
4038
}
41-
resp, err := client.Do(req)
39+
resp, err = client.Do(req)
4240

4341
if resp.StatusCode == 401 {
4442
return dr.executeDigest(resp)
4543
}
4644

47-
return resp, err
45+
return
4846
}
4947

5048
func (dr *DigestRequest) executeDigest(resp *http.Response) (*http.Response, error) {
49+
var (
50+
err error
51+
wa *wwwAuthenticate
52+
auth *authorization
53+
req *http.Request
54+
)
5155

52-
wwwAuthenticateHeaderString := resp.Header.Get("WWW-Authenticate")
53-
54-
if strings.Compare(wwwAuthenticateHeaderString, "") == 0 {
56+
waString := resp.Header.Get("WWW-Authenticate")
57+
if waString == "" {
5558
return nil, fmt.Errorf("Failed to get WWW-Authenticate header, please check your server configuration.")
5659
}
5760

58-
wwwAuthenticateHeader, err = newWwwAuthenticateHeader(wwwAuthenticateHeaderString)
61+
if wa, err = newWAHeader(waString); err != nil {
62+
return nil, err
63+
}
64+
65+
if auth, err = newAuthorization(wa, dr); err != nil {
66+
return nil, err
67+
}
68+
69+
authString := fmt.Sprintf("Digest %s", auth.toString())
70+
if req, err = http.NewRequest(dr.Method, dr.Uri, bytes.NewReader([]byte(dr.Body))); err != nil {
71+
return nil, err
72+
}
73+
74+
req.Header.Add("Authorization", authString)
75+
76+
client := &http.Client{
77+
Timeout: 30 * time.Second,
78+
}
5979

60-
return nil, nil
80+
return client.Do(req)
6181
}

header_authorization.go

Lines changed: 63 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,67 +6,97 @@ import (
66
"fmt"
77
"hash"
88
"io"
9-
"strings"
9+
"regexp"
10+
"time"
1011
)
1112

12-
type authorizationHeader struct {
13+
type authorization struct {
1314
Algorithm string // unquoted
1415
Cnonce string // quoted
15-
Nc string // unquoted
16-
Nounce string // quoted
16+
Nc int // unquoted
17+
Nonce string // quoted
1718
Opaque string // quoted
1819
Qop string // unquoted
1920
Realm string // quoted
20-
Resposne string // quoted
21+
Response string // quoted
2122
Uri string // quoted
22-
Userhash string // quoted
23+
Userhash bool // quoted
2324
Username string // quoted
2425
Username_ string // quoted
2526
}
2627

27-
func (ah *authorizationHeader) ComputeResponse() authorizationHeader {
28-
return *ah
28+
func newAuthorization(wa *wwwAuthenticate, dr *DigestRequest) (*authorization, error) {
29+
30+
auth := authorization{
31+
Algorithm: wa.Algorithm,
32+
Cnonce: "",
33+
Nc: 1, // TODO
34+
Nonce: wa.Nonce,
35+
Opaque: wa.Opaque,
36+
Qop: "",
37+
Realm: wa.Realm,
38+
Response: "",
39+
Uri: dr.Uri,
40+
Userhash: wa.Userhash,
41+
Username: dr.Username,
42+
Username_: "", // TODO
43+
}
44+
45+
auth.Cnonce = auth.hash(fmt.Sprintf("%d:%s:dfjosbn3kjd01", time.Now().UnixNano(), dr.Username))
46+
47+
if auth.Userhash {
48+
auth.Username = auth.hash(fmt.Sprintf("%s:%s", auth.Username, auth.Realm))
49+
}
50+
51+
auth.Response = auth.computeResponse(wa, dr)
52+
53+
return &auth, nil
54+
}
55+
56+
func (ah *authorization) computeResponse(wa *wwwAuthenticate, dr *DigestRequest) (s string) {
57+
58+
kdSecret := ah.hash(ah.computeA1(wa, dr))
59+
kdData := fmt.Sprintf("%s:%s:%s:%s:%s", ah.Nonce, ah.Nc, ah.Cnonce, ah.Qop, ah.hash(ah.computeA2(wa, dr)))
60+
61+
return ah.hash(fmt.Sprintf("%s:%s", kdSecret, kdData))
2962
}
3063

31-
func (ah *authorizationHeader) ComputeA1(password string) (s string) {
64+
func (ah *authorization) computeA1(wa *wwwAuthenticate, dr *DigestRequest) string {
3265

33-
if strings.Compare(ah.Algorithm, "") == 0 ||
34-
strings.Compare(ah.Algorithm, "MD5") == 0 ||
35-
strings.Compare(ah.Algorithm, "SHA-256") == 0 {
36-
s = fmt.Sprintf("%s:%s:%s", ah.Username, ah.Realm, password)
66+
if ah.Algorithm == "" || ah.Algorithm == "MD5" || ah.Algorithm == "SHA-256" {
67+
return fmt.Sprintf("%s:%s:%s", ah.Username, ah.Realm, dr.Password)
3768
}
3869

39-
if strings.Compare(ah.Algorithm, "MD5-sess") ||
40-
strings.Compare(ah.Algorithm, "SHA-256-sess") {
41-
upHash := ah.Hash(fmt.Sprintf("%s:%s:%s", ah.Username, ah.Realm, password))
42-
s = fmt.Sprintf("%s:%s:%s", upHash, ah.Nc)
70+
if ah.Algorithm == "MD5-sess" || ah.Algorithm == "SHA-256-sess" {
71+
upHash := ah.hash(fmt.Sprintf("%s:%s:%s", ah.Username, ah.Realm, dr.Password))
72+
return fmt.Sprintf("%s:%s:%s", upHash, ah.Nc)
4373
}
4474

45-
return
75+
return ""
4676
}
4777

48-
func (ah *authorizationHeader) ComputeA2() (s string) {
78+
func (ah *authorization) computeA2(wa *wwwAuthenticate, dr *DigestRequest) string {
4979

50-
if strings.Compare(ah.Qop, "auth") == 0 || strings.Compare(ah.Qop, "") == 0 {
51-
s = fmt.Sprintf("%s:%s", ah.Method, ah.Uri)
80+
if matched, _ := regexp.MatchString("auth-int", wa.Qop); matched {
81+
ah.Qop = "auth-int"
82+
return fmt.Sprintf("%s:%s:%s", dr.Method, ah.Uri, ah.hash(dr.Body))
5283
}
5384

54-
if strings.Compare(ah.Qop, "auth-int") == 0 {
55-
s = fmt.Sprintf("%s:%s", s, ah.Hash(ah.Body))
85+
if ah.Qop == "auth" || ah.Qop == "" {
86+
ah.Qop = "auth"
87+
return fmt.Sprintf("%s:%s", dr.Method, ah.Uri)
5688
}
5789

58-
return
90+
return ""
5991
}
6092

61-
func (ah *authorizationHeader) Hash(a string) (s string) {
93+
func (ah *authorization) hash(a string) (s string) {
6294

6395
var h hash.Hash
6496

65-
if strings.Compare(ah.Algorithm, "MD5") == 0 ||
66-
strings.Compare(ah.Algorithm, "MD5-sess") == 0 {
97+
if ah.Algorithm == "MD5" || ah.Algorithm == "MD5-sess" {
6798
h = md5.New()
68-
} else if strings.Compare(ah.Algorithm, "SHA-256") == 0 ||
69-
strings.Compare(ah.Algorithm, "SHA-256-sess") == 0 {
99+
} else if ah.Algorithm == "SHA-256" || ah.Algorithm == "SHA-256-sess" {
70100
h = sha256.New()
71101
}
72102

@@ -75,3 +105,7 @@ func (ah *authorizationHeader) Hash(a string) (s string) {
75105

76106
return
77107
}
108+
109+
func (ah *authorization) toString() string {
110+
return ""
111+
}

header_www_authenticate.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ type wwwAuthenticate struct {
88
Qop string // quoted
99
Realm string // quoted
1010
Stale bool // unquoted
11-
charset string // quoted
12-
userhash bool // quoted
11+
Charset string // quoted
12+
Userhash bool // quoted
1313
}
1414

15-
func newWwwAuthenticateHeader(newWwwAuthenticateHeaderString string) (*wwwAuthenticate, error) {
15+
func newWAHeader(newWAHeaderString string) (*wwwAuthenticate, error) {
16+
return nil, nil
17+
}
1618

19+
func (wa *wwwAuthenticate) fromString(s string) (*wwwAuthenticate, error) {
20+
return wa, nil
1721
}

0 commit comments

Comments
 (0)