Files
lkm/rtsp/http_digst.go
2024-06-03 19:19:20 +08:00

71 lines
1.7 KiB
Go

package rtsp
import (
"crypto/md5"
"encoding/base64"
"encoding/hex"
"fmt"
"strings"
)
import "math/rand"
func generateNonce() string {
k := make([]byte, 12)
for bytes := 0; bytes < len(k); {
n, err := rand.Read(k[bytes:])
if err != nil {
panic("rand.Read() failed")
}
bytes += n
}
return base64.StdEncoding.EncodeToString(k)
}
func generateAuthHeader(realm string) string {
return fmt.Sprintf(`Digest realm="%s", nonce="%s" algorithm=MD5`,
realm, generateNonce())
}
func h(data string) string {
hash := md5.New()
hash.Write([]byte(data))
return hex.EncodeToString(hash.Sum(nil))
}
func calculateResponse(username, realm, nonce, uri, password string) string {
//H(data) = MD5(data)
//KD(secret, data) = H(concat(secret, ":", data))
//request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <">
A1 := fmt.Sprintf("%s:%s:%s", username, realm, password)
A2 := fmt.Sprintf("%s:%s", "DESCRIBE", uri)
return h(h(A1) + ":" + nonce + ":" + h(A2))
}
func parseAuthParams(value string) (map[string]string, error) {
index := strings.Index(value, "Digest ")
if index == -1 {
return nil, fmt.Errorf("unknow scheme %s", value)
}
pairs := strings.Split(value[len("Digest "):], ",")
m := make(map[string]string, len(pairs))
for _, pair := range pairs {
i := strings.Index(pair, "=")
if i < 0 {
m[pair] = ""
} else if i == len(pair)-1 {
m[pair[:i]] = ""
} else {
m[strings.TrimSpace(pair[:i])] = strings.Trim(pair[i+1:], "\"")
}
}
return m, nil
}
func DoAuthenticatePlainTextPassword(params map[string]string, password string) bool {
response := calculateResponse(params["username"], params["realm"], params["nonce"], params["uri"], password)
return response == params["response"]
}