add VLC authentication workaround

This commit is contained in:
aler9
2021-10-30 14:47:58 +02:00
parent 146b923b1e
commit 1d5f3c92ae
7 changed files with 49 additions and 21 deletions

View File

@@ -975,7 +975,7 @@ func TestClientReadAutomaticProtocol(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, base.Describe, req.Method) require.Equal(t, base.Describe, req.Method)
err = v.ValidateRequest(req, nil) err = v.ValidateRequest(req)
require.NoError(t, err) require.NoError(t, err)
track, err := NewTrackH264(96, &TrackConfigH264{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}}) track, err := NewTrackH264(96, &TrackConfigH264{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}})
@@ -1063,7 +1063,7 @@ func TestClientReadAutomaticProtocol(t *testing.T) {
require.Equal(t, base.Setup, req.Method) require.Equal(t, base.Setup, req.Method)
require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream/trackID=0"), req.URL) require.Equal(t, mustParseURL("rtsp://localhost:8554/teststream/trackID=0"), req.URL)
err = v.ValidateRequest(req, nil) err = v.ValidateRequest(req)
require.NoError(t, err) require.NoError(t, err)
inTH = headers.Transport{} inTH = headers.Transport{}

View File

@@ -146,7 +146,7 @@ func TestClientAuth(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, base.Describe, req.Method) require.Equal(t, base.Describe, req.Method)
err = v.ValidateRequest(req, nil) err = v.ValidateRequest(req)
require.NoError(t, err) require.NoError(t, err)
track, err := NewTrackH264(96, &TrackConfigH264{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}}) track, err := NewTrackH264(96, &TrackConfigH264{[]byte{0x01, 0x02, 0x03, 0x04}, []byte{0x01, 0x02, 0x03, 0x04}})

View File

@@ -77,7 +77,7 @@ func TestAuth(t *testing.T) {
req.URL = mustParseURL("rtsp://myhost/mypath") req.URL = mustParseURL("rtsp://myhost/mypath")
err = va.ValidateRequest(req, nil) err = va.ValidateRequest(req)
if conf != "nofail" { if conf != "nofail" {
require.Error(t, err) require.Error(t, err)
@@ -110,14 +110,14 @@ func TestAuthVLC(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
req := &base.Request{ req := &base.Request{
Method: base.Announce, Method: base.Setup,
URL: mustParseURL(ca.clientURL), URL: mustParseURL(ca.clientURL),
} }
se.AddAuthorization(req) se.AddAuthorization(req)
req.URL = mustParseURL(ca.serverURL) req.URL = mustParseURL(ca.serverURL)
err = va.ValidateRequest(req, mustParseURL(ca.clientURL)) err = va.ValidateRequest(req)
require.NoError(t, err) require.NoError(t, err)
} }
} }
@@ -154,7 +154,7 @@ func TestAuthHashed(t *testing.T) {
} }
va.AddAuthorization(req) va.AddAuthorization(req)
err = se.ValidateRequest(req, nil) err = se.ValidateRequest(req)
if conf != "nofail" { if conf != "nofail" {
require.Error(t, err) require.Error(t, err)

View File

@@ -10,6 +10,34 @@ import (
"github.com/aler9/gortsplib/pkg/headers" "github.com/aler9/gortsplib/pkg/headers"
) )
func stringsReverseIndex(s, substr string) int {
for i := len(s) - 1 - len(substr); i >= 0; i-- {
if s[i:i+len(substr)] == substr {
return i
}
}
return -1
}
func generateAltURL(req *base.Request) (*base.URL, bool) {
if req.Method != base.Setup {
return nil, false
}
pathAndQuery, ok := req.URL.RTSPPathAndQuery()
if !ok {
return nil, false
}
i := stringsReverseIndex(pathAndQuery, "/trackID=")
if i < 0 {
return nil, false
}
ur, _ := base.ParseURL(req.URL.Scheme + "://" + req.URL.Host + "/" + pathAndQuery[:i+1])
return ur, true
}
// Validator allows to validate credentials generated by a Sender. // Validator allows to validate credentials generated by a Sender.
type Validator struct { type Validator struct {
user string user string
@@ -84,8 +112,7 @@ func (va *Validator) Header() base.HeaderValue {
} }
// ValidateRequest validates a request sent by a client. // ValidateRequest validates a request sent by a client.
func (va *Validator) ValidateRequest(req *base.Request, func (va *Validator) ValidateRequest(req *base.Request) error {
altURL *base.URL) error {
var auth headers.Authorization var auth headers.Authorization
err := auth.Read(req.Header["Authorization"]) err := auth.Read(req.Header["Authorization"])
if err != nil { if err != nil {
@@ -150,8 +177,9 @@ func (va *Validator) ValidateRequest(req *base.Request,
ur := req.URL ur := req.URL
if *auth.DigestValues.URI != ur.String() { if *auth.DigestValues.URI != ur.String() {
// do another try with the alternative URL // in SETUP requests, VLC strips the control attribute.
if altURL != nil { // try again with an alternative URL without the control attribute.
if altURL, ok := generateAltURL(req); ok {
ur = altURL ur = altURL
if *auth.DigestValues.URI != ur.String() { if *auth.DigestValues.URI != ur.String() {

View File

@@ -64,7 +64,7 @@ func TestValidatorErrors(t *testing.T) {
Header: base.Header{ Header: base.Header{
"Authorization": ca.hv, "Authorization": ca.hv,
}, },
}, nil) })
require.Equal(t, ca.err, err.Error()) require.Equal(t, ca.err, err.Error())
}) })
} }

View File

@@ -19,15 +19,6 @@ const (
serverConnWriteBufferSize = 4096 serverConnWriteBufferSize = 4096
) )
func stringsReverseIndex(s, substr string) int {
for i := len(s) - 1 - len(substr); i >= 0; i-- {
if s[i:i+len(substr)] == substr {
return i
}
}
return -1
}
func getSessionID(header base.Header) string { func getSessionID(header base.Header) string {
if h, ok := header["Session"]; ok && len(h) == 1 { if h, ok := header["Session"]; ok && len(h) == 1 {
return h[0] return h[0]

View File

@@ -20,6 +20,15 @@ const (
serverSessionCheckStreamPeriod = 1 * time.Second serverSessionCheckStreamPeriod = 1 * time.Second
) )
func stringsReverseIndex(s, substr string) int {
for i := len(s) - 1 - len(substr); i >= 0; i-- {
if s[i:i+len(substr)] == substr {
return i
}
}
return -1
}
func setupGetTrackIDPathQuery( func setupGetTrackIDPathQuery(
url *base.URL, url *base.URL,
thMode *headers.TransportMode, thMode *headers.TransportMode,