diff --git a/internal/servers/rtsp/server_test.go b/internal/servers/rtsp/server_test.go index 9ece2ff7..b0d1d7b6 100644 --- a/internal/servers/rtsp/server_test.go +++ b/internal/servers/rtsp/server_test.go @@ -75,6 +75,8 @@ func TestServerPublish(t *testing.T) { pathManager := &test.PathManager{ AddPublisherImpl: func(req defs.PathAddPublisherReq) (defs.Path, error) { if ca == "basic" { + require.Nil(t, req.AccessRequest.CustomVerifyFunc) + if req.AccessRequest.Credentials.User == "" && req.AccessRequest.Credentials.Pass == "" { return nil, auth.Error{Message: "", AskCredentials: true} } @@ -91,6 +93,7 @@ func TestServerPublish(t *testing.T) { } require.True(t, ok) } + return path, nil }, } @@ -191,6 +194,8 @@ func TestServerRead(t *testing.T) { pathManager := &test.PathManager{ DescribeImpl: func(req defs.PathDescribeReq) defs.PathDescribeRes { if ca == "basic" { + require.Nil(t, req.AccessRequest.CustomVerifyFunc) + if req.AccessRequest.Credentials.User == "" && req.AccessRequest.Credentials.Pass == "" { return defs.PathDescribeRes{Err: auth.Error{Message: "", AskCredentials: true}} } @@ -216,6 +221,8 @@ func TestServerRead(t *testing.T) { }, AddReaderImpl: func(req defs.PathAddReaderReq) (defs.Path, *stream.Stream, error) { if ca == "basic" { + require.Nil(t, req.AccessRequest.CustomVerifyFunc) + require.Equal(t, "teststream", req.AccessRequest.Name) require.Equal(t, "param=value", req.AccessRequest.Query) require.Equal(t, "myuser", req.AccessRequest.Credentials.User) diff --git a/internal/servers/rtsp/session.go b/internal/servers/rtsp/session.go index dadfa5f4..cdbc50ae 100644 --- a/internal/servers/rtsp/session.go +++ b/internal/servers/rtsp/session.go @@ -215,18 +215,25 @@ func (s *session) onSetup(c *conn, ctx *gortsplib.ServerHandlerOnSetupCtx, } } + // CustomVerifyFunc prevents hashed credentials from working. + // Use it only when strictly needed. + var customVerifyFunc func(expectedUser, expectedPass string) bool + if contains(c.authMethods, rtspauth.VerifyMethodDigestMD5) { + customVerifyFunc = func(expectedUser, expectedPass string) bool { + return c.rconn.VerifyCredentials(ctx.Request, expectedUser, expectedPass) + } + } + switch s.rsession.State() { case gortsplib.ServerSessionStateInitial, gortsplib.ServerSessionStatePrePlay: // play req := defs.PathAccessRequest{ - Name: ctx.Path, - Query: ctx.Query, - Proto: auth.ProtocolRTSP, - ID: &c.uuid, - Credentials: rtsp.Credentials(ctx.Request), - IP: c.ip(), - CustomVerifyFunc: func(expectedUser, expectedPass string) bool { - return c.rconn.VerifyCredentials(ctx.Request, expectedUser, expectedPass) - }, + Name: ctx.Path, + Query: ctx.Query, + Proto: auth.ProtocolRTSP, + ID: &c.uuid, + Credentials: rtsp.Credentials(ctx.Request), + IP: c.ip(), + CustomVerifyFunc: customVerifyFunc, } path, stream, err := s.pathManager.AddReader(defs.PathAddReaderReq{