@@ -4,10 +4,13 @@ import (
4
4
"bytes"
5
5
"crypto/md5"
6
6
"crypto/sha256"
7
+ "encoding/hex"
7
8
"fmt"
8
9
"hash"
9
10
"io"
11
+ "net/url"
10
12
"regexp"
13
+ "strings"
11
14
"time"
12
15
)
13
16
@@ -26,64 +29,79 @@ type authorization struct {
26
29
Username_ string // quoted
27
30
}
28
31
29
- func newAuthorization (wa * wwwAuthenticate , dr * DigestRequest ) ( * authorization , error ) {
32
+ func newAuthorization (dr * DigestRequest ) * authorization {
30
33
31
- auth := authorization {
34
+ ah := authorization {
32
35
Algorithm : wa .Algorithm ,
33
36
Cnonce : "" ,
34
- Nc : 1 , // TODO
37
+ Nc : 0 ,
35
38
Nonce : wa .Nonce ,
36
39
Opaque : wa .Opaque ,
37
40
Qop : "" ,
38
41
Realm : wa .Realm ,
39
42
Response : "" ,
40
- Uri : dr . Uri ,
43
+ Uri : "" ,
41
44
Userhash : wa .Userhash ,
42
45
Username : dr .Username ,
43
46
Username_ : "" , // TODO
44
47
}
45
48
46
- auth .Cnonce = auth .hash (fmt .Sprintf ("%d:%s:dfjosbn3kjd01" , time .Now ().UnixNano (), dr .Username ))
49
+ if ah .Userhash {
50
+ ah .Username = ah .hash (fmt .Sprintf ("%s:%s" , ah .Username , ah .Realm ))
51
+ }
52
+
53
+ ah .refreshAuthorization (dr )
54
+
55
+ return & ah
56
+ }
57
+
58
+ func (ah * authorization ) refreshAuthorization (dr * DigestRequest ) (* authorization , error ) {
59
+
60
+ ah .Nc ++
61
+
62
+ ah .Cnonce = ah .hash (fmt .Sprintf ("%d:%s:my_value" , time .Now ().UnixNano (), dr .Username ))
47
63
48
- if auth .Userhash {
49
- auth .Username = auth .hash (fmt .Sprintf ("%s:%s" , auth .Username , auth .Realm ))
64
+ url , err := url .Parse (dr .Uri )
65
+ if err != nil {
66
+ return nil , err
50
67
}
68
+ ah .Uri = url .RequestURI ()
51
69
52
- auth .Response = auth .computeResponse (wa , dr )
70
+ ah .Response = ah .computeResponse (dr )
53
71
54
- return & auth , nil
72
+ return ah , nil
55
73
}
56
74
57
- func (ah * authorization ) computeResponse (wa * wwwAuthenticate , dr * DigestRequest ) (s string ) {
75
+ func (ah * authorization ) computeResponse (dr * DigestRequest ) (s string ) {
58
76
59
- kdSecret := ah .hash (ah .computeA1 (wa , dr ))
60
- kdData := fmt .Sprintf ("%s:%s :%s:%s:%s" , ah .Nonce , ah .Nc , ah .Cnonce , ah .Qop , ah .hash (ah .computeA2 (wa , dr )))
77
+ kdSecret := ah .hash (ah .computeA1 (dr ))
78
+ kdData := fmt .Sprintf ("%s:%08x :%s:%s:%s" , ah .Nonce , ah .Nc , ah .Cnonce , ah .Qop , ah .hash (ah .computeA2 (dr )))
61
79
62
80
return ah .hash (fmt .Sprintf ("%s:%s" , kdSecret , kdData ))
63
81
}
64
82
65
- func (ah * authorization ) computeA1 (wa * wwwAuthenticate , dr * DigestRequest ) string {
83
+ func (ah * authorization ) computeA1 (dr * DigestRequest ) string {
66
84
67
85
if ah .Algorithm == "" || ah .Algorithm == "MD5" || ah .Algorithm == "SHA-256" {
68
86
return fmt .Sprintf ("%s:%s:%s" , ah .Username , ah .Realm , dr .Password )
69
87
}
70
88
71
89
if ah .Algorithm == "MD5-sess" || ah .Algorithm == "SHA-256-sess" {
72
90
upHash := ah .hash (fmt .Sprintf ("%s:%s:%s" , ah .Username , ah .Realm , dr .Password ))
73
- return fmt .Sprintf ("%s:%s:%s" , upHash , ah .Nc )
91
+ return fmt .Sprintf ("%s:%s:%s" , upHash , ah .Nonce , ah . Cnonce )
74
92
}
75
93
76
94
return ""
77
95
}
78
96
79
- func (ah * authorization ) computeA2 (wa * wwwAuthenticate , dr * DigestRequest ) string {
97
+ func (ah * authorization ) computeA2 (dr * DigestRequest ) string {
80
98
81
99
if matched , _ := regexp .MatchString ("auth-int" , wa .Qop ); matched {
82
100
ah .Qop = "auth-int"
83
101
return fmt .Sprintf ("%s:%s:%s" , dr .Method , ah .Uri , ah .hash (dr .Body ))
84
102
}
85
103
86
- if ah .Qop == "auth" || ah .Qop == "" {
104
+ if wa .Qop == "auth" || wa .Qop == "" {
87
105
ah .Qop = "auth"
88
106
return fmt .Sprintf ("%s:%s" , dr .Method , ah .Uri )
89
107
}
@@ -95,14 +113,14 @@ func (ah *authorization) hash(a string) (s string) {
95
113
96
114
var h hash.Hash
97
115
98
- if ah .Algorithm == "MD5" || ah .Algorithm == "MD5-sess" {
116
+ if ah .Algorithm == "" || ah . Algorithm == " MD5" || ah .Algorithm == "MD5-sess" {
99
117
h = md5 .New ()
100
118
} else if ah .Algorithm == "SHA-256" || ah .Algorithm == "SHA-256-sess" {
101
119
h = sha256 .New ()
102
120
}
103
121
104
122
io .WriteString (h , a )
105
- s = string (h .Sum (nil ))
123
+ s = hex . EncodeToString (h .Sum (nil ))
106
124
107
125
return
108
126
}
@@ -121,13 +139,17 @@ func (ah *authorization) toString() string {
121
139
}
122
140
123
141
if ah .Nc != 0 {
124
- buffer .WriteString (fmt .Sprintf ("nc=%08d , " , ah .Nc ))
142
+ buffer .WriteString (fmt .Sprintf ("nc=%08x , " , ah .Nc ))
125
143
}
126
144
127
145
if ah .Opaque != "" {
128
146
buffer .WriteString (fmt .Sprintf ("opaque=\" %s\" , " , ah .Opaque ))
129
147
}
130
148
149
+ if ah .Nonce != "" {
150
+ buffer .WriteString (fmt .Sprintf ("nonce=\" %s\" , " , ah .Nonce ))
151
+ }
152
+
131
153
if ah .Qop != "" {
132
154
buffer .WriteString (fmt .Sprintf ("qop=%s, " , ah .Qop ))
133
155
}
@@ -140,10 +162,6 @@ func (ah *authorization) toString() string {
140
162
buffer .WriteString (fmt .Sprintf ("response=\" %s\" , " , ah .Response ))
141
163
}
142
164
143
- if ah .Response != "" {
144
- buffer .WriteString (fmt .Sprintf ("response=\" %s\" , " , ah .Response ))
145
- }
146
-
147
165
if ah .Uri != "" {
148
166
buffer .WriteString (fmt .Sprintf ("uri=\" %s\" , " , ah .Uri ))
149
167
}
@@ -156,5 +174,7 @@ func (ah *authorization) toString() string {
156
174
buffer .WriteString (fmt .Sprintf ("username=\" %s\" , " , ah .Username ))
157
175
}
158
176
159
- return buffer .String ()
177
+ s := buffer .String ()
178
+
179
+ return strings .TrimSuffix (s , ", " )
160
180
}
0 commit comments