@@ -2,6 +2,7 @@ package auth
2
2
3
3
import (
4
4
"crypto/md5"
5
+ "crypto/sha256"
5
6
"encoding/hex"
6
7
"fmt"
7
8
@@ -14,6 +15,7 @@ const Realm = "sing-box"
14
15
type Challenge struct {
15
16
Username string
16
17
Nonce string
18
+ Algorithm string
17
19
CNonce string
18
20
Nc string
19
21
Response string
@@ -57,10 +59,17 @@ func (au *Authenticator) VerifyDigest(method string, uri string, s string) (stri
57
59
passwordList , ok := au .userMap [c .Username ]
58
60
if ok {
59
61
for _ , password := range passwordList {
60
- ha1 := md5str (c .Username + ":" + Realm + ":" + password )
61
- ha2 := md5str (method + ":" + uri )
62
- resp := md5str (ha1 + ":" + c .Nonce + ":" + c .Nc + ":" + c .CNonce + ":auth:" + ha2 )
63
- if resp == c .Response {
62
+ resp := ""
63
+ if c .Algorithm == "SHA-256" {
64
+ ha1 := sha256str (c .Username + ":" + Realm + ":" + password )
65
+ ha2 := sha256str (method + ":" + uri )
66
+ resp = sha256str (ha1 + ":" + c .Nonce + ":" + c .Nc + ":" + c .CNonce + ":auth:" + ha2 )
67
+ } else {
68
+ ha1 := md5str (c .Username + ":" + Realm + ":" + password )
69
+ ha2 := md5str (method + ":" + uri )
70
+ resp = md5str (ha1 + ":" + c .Nonce + ":" + c .Nc + ":" + c .CNonce + ":auth:" + ha2 )
71
+ }
72
+ if resp != "" && resp == c .Response {
64
73
return c .Username , true
65
74
}
66
75
}
@@ -81,6 +90,8 @@ func ParseChallenge(s string) (*Challenge, error) {
81
90
c .Username = p .Value
82
91
case "nonce" :
83
92
c .Nonce = p .Value
93
+ case "algorithm" :
94
+ c .Algorithm = p .Value
84
95
case "cnonce" :
85
96
c .CNonce = p .Value
86
97
case "nc" :
@@ -97,3 +108,9 @@ func md5str(str string) string {
97
108
h .Write ([]byte (str ))
98
109
return hex .EncodeToString (h .Sum (nil ))
99
110
}
111
+
112
+ func sha256str (str string ) string {
113
+ h := sha256 .New ()
114
+ h .Write ([]byte (str ))
115
+ return hex .EncodeToString (h .Sum (nil ))
116
+ }
0 commit comments