Files
gortsplib/pkg/auth/sender.go
2025-03-16 13:58:35 +01:00

90 lines
2.2 KiB
Go

package auth
import (
"fmt"
"github.com/bluenviron/gortsplib/v4/pkg/base"
"github.com/bluenviron/gortsplib/v4/pkg/headers"
)
// NewSender allocates a Sender.
//
// Deprecated: replaced by Sender.Initialize().
func NewSender(wwwAuth base.HeaderValue, user string, pass string) (*Sender, error) {
s := &Sender{
WWWAuth: wwwAuth,
User: user,
Pass: pass,
}
err := s.Initialize()
return s, err
}
// Sender allows to send credentials.
// It requires a WWW-Authenticate header (provided by the server)
// and a set of credentials.
type Sender struct {
WWWAuth base.HeaderValue
User string
Pass string
authHeader *headers.Authenticate
}
// Initialize initializes a Sender.
func (se *Sender) Initialize() error {
for _, v := range se.WWWAuth {
var auth headers.Authenticate
err := auth.Unmarshal(base.HeaderValue{v})
if err != nil {
continue // ignore unrecognized headers
}
if se.authHeader == nil ||
(auth.Algorithm != nil && *auth.Algorithm == headers.AuthAlgorithmSHA256) ||
(se.authHeader.Method == headers.AuthMethodBasic) {
se.authHeader = &auth
}
}
if se.authHeader == nil {
return fmt.Errorf("no authentication methods available")
}
return nil
}
// AddAuthorization adds the Authorization header to a Request.
func (se *Sender) AddAuthorization(req *base.Request) {
urStr := req.URL.CloneWithoutCredentials().String()
h := headers.Authorization{
Method: se.authHeader.Method,
}
h.Username = se.User
if se.authHeader.Method == headers.AuthMethodBasic {
h.BasicPass = se.Pass
} else { // digest
h.Realm = se.authHeader.Realm
h.Nonce = se.authHeader.Nonce
h.URI = urStr
h.Algorithm = se.authHeader.Algorithm
if se.authHeader.Algorithm == nil || *se.authHeader.Algorithm == headers.AuthAlgorithmMD5 {
h.Response = md5Hex(md5Hex(se.User+":"+se.authHeader.Realm+":"+se.Pass) + ":" +
se.authHeader.Nonce + ":" + md5Hex(string(req.Method)+":"+urStr))
} else { // sha256
h.Response = sha256Hex(sha256Hex(se.User+":"+se.authHeader.Realm+":"+se.Pass) + ":" +
se.authHeader.Nonce + ":" + sha256Hex(string(req.Method)+":"+urStr))
}
}
if req.Header == nil {
req.Header = make(base.Header)
}
req.Header["Authorization"] = h.Marshal()
}