Browse Source

webrtc: send session ID to external auth server (#1981) (#2098)

pull/2099/head
Alessandro Ros 3 years ago committed by GitHub
parent
commit
36298f8bc8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      internal/core/hls_http_server.go
  2. 5
      internal/core/hls_manager_test.go
  3. 2
      internal/core/path.go
  4. 9
      internal/core/webrtc_http_server.go
  5. 3
      internal/core/webrtc_manager.go
  6. 33
      internal/core/webrtc_session.go

2
internal/core/hls_http_server.go

@ -161,7 +161,7 @@ func (s *hlsHTTPServer) onRequest(ctx *gin.Context) {
return return
} }
s.Log(logger.Info, "authentication error: %v", terr.wrapped) s.Log(logger.Info, "authentication failed: %v", terr.wrapped)
ctx.Writer.WriteHeader(http.StatusUnauthorized) ctx.Writer.WriteHeader(http.StatusUnauthorized)
return return
} }

5
internal/core/hls_manager_test.go

@ -22,6 +22,7 @@ type testHTTPAuthenticator struct {
action string action string
s *http.Server s *http.Server
firstReceived bool
} }
func newTestHTTPAuthenticator(t *testing.T, protocol string, action string) *testHTTPAuthenticator { func newTestHTTPAuthenticator(t *testing.T, protocol string, action string) *testHTTPAuthenticator {
@ -75,7 +76,7 @@ func (ts *testHTTPAuthenticator) onAuth(ctx *gin.Context) {
in.Password != "testpass" || in.Password != "testpass" ||
in.Path != "teststream" || in.Path != "teststream" ||
in.Protocol != ts.protocol || in.Protocol != ts.protocol ||
// in.ID == "" || (ts.firstReceived && in.ID == "") ||
in.Action != ts.action || in.Action != ts.action ||
(in.Query != "user=testreader&pass=testpass&param=value" && (in.Query != "user=testreader&pass=testpass&param=value" &&
in.Query != "user=testpublisher&pass=testpass&param=value" && in.Query != "user=testpublisher&pass=testpass&param=value" &&
@ -83,6 +84,8 @@ func (ts *testHTTPAuthenticator) onAuth(ctx *gin.Context) {
ctx.AbortWithStatus(http.StatusBadRequest) ctx.AbortWithStatus(http.StatusBadRequest)
return return
} }
ts.firstReceived = true
} }
func httpPullFile(t *testing.T, hc *http.Client, u string) []byte { func httpPullFile(t *testing.T, hc *http.Client, u string) []byte {

2
internal/core/path.go

@ -30,7 +30,7 @@ type pathErrAuth struct {
// Error implements the error interface. // Error implements the error interface.
func (e pathErrAuth) Error() string { func (e pathErrAuth) Error() string {
return "authentication error" return "authentication failed"
} }
type pathErrNoOnePublishing struct { type pathErrNoOnePublishing struct {

9
internal/core/webrtc_http_server.go

@ -293,9 +293,10 @@ func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) {
ip := ctx.ClientIP() ip := ctx.ClientIP()
_, port, _ := net.SplitHostPort(ctx.Request.RemoteAddr) _, port, _ := net.SplitHostPort(ctx.Request.RemoteAddr)
user, pass, hasCredentials := ctx.Request.BasicAuth() user, pass, hasCredentials := ctx.Request.BasicAuth()
// if request doesn't belong to a session, check authentication here
if !isWHIPorWHEP || ctx.Request.Method == http.MethodOptions {
res := s.pathManager.getConfForPath(pathGetConfForPathReq{ res := s.pathManager.getConfForPath(pathGetConfForPathReq{
name: dir, name: dir,
publish: publish, publish: publish,
@ -315,7 +316,7 @@ func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) {
return return
} }
s.Log(logger.Info, "authentication error: %v", terr.wrapped) s.Log(logger.Info, "authentication failed: %v", terr.wrapped)
ctx.Writer.WriteHeader(http.StatusUnauthorized) ctx.Writer.WriteHeader(http.StatusUnauthorized)
return return
} }
@ -323,6 +324,7 @@ func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) {
ctx.Writer.WriteHeader(http.StatusNotFound) ctx.Writer.WriteHeader(http.StatusNotFound)
return return
} }
}
switch fname { switch fname {
case "": case "":
@ -357,6 +359,9 @@ func (s *webRTCHTTPServer) onRequest(ctx *gin.Context) {
res := s.parent.sessionNew(webRTCSessionNewReq{ res := s.parent.sessionNew(webRTCSessionNewReq{
pathName: dir, pathName: dir,
remoteAddr: net.JoinHostPort(ip, port), remoteAddr: net.JoinHostPort(ip, port),
query: ctx.Request.URL.RawQuery,
user: user,
pass: pass,
offer: offer, offer: offer,
publish: (fname == "whip"), publish: (fname == "whip"),
}) })

3
internal/core/webrtc_manager.go

@ -97,6 +97,9 @@ type webRTCSessionNewRes struct {
type webRTCSessionNewReq struct { type webRTCSessionNewReq struct {
pathName string pathName string
remoteAddr string remoteAddr string
query string
user string
pass string
offer []byte offer []byte
publish bool publish bool
res chan webRTCSessionNewRes res chan webRTCSessionNewRes

33
internal/core/webrtc_session.go

@ -4,6 +4,7 @@ import (
"context" "context"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
"net"
"net/http" "net/http"
"strings" "strings"
"sync" "sync"
@ -223,13 +224,25 @@ func (s *webRTCSession) runInner2() (int, error) {
} }
func (s *webRTCSession) runPublish() (int, error) { func (s *webRTCSession) runPublish() (int, error) {
ip, _, _ := net.SplitHostPort(s.req.remoteAddr)
res := s.pathManager.publisherAdd(pathPublisherAddReq{ res := s.pathManager.publisherAdd(pathPublisherAddReq{
author: s, author: s,
pathName: s.req.pathName, pathName: s.req.pathName,
skipAuth: true, credentials: authCredentials{
query: s.req.query,
ip: net.ParseIP(ip),
user: s.req.user,
pass: s.req.pass,
proto: authProtocolWebRTC,
id: &s.uuid,
},
}) })
if res.err != nil { if res.err != nil {
return http.StatusInternalServerError, res.err if _, ok := res.err.(pathErrAuth); ok {
return http.StatusUnauthorized, res.err
}
return http.StatusBadRequest, res.err
} }
defer res.path.publisherRemove(pathPublisherRemoveReq{author: s}) defer res.path.publisherRemove(pathPublisherRemoveReq{author: s})
@ -334,16 +347,28 @@ func (s *webRTCSession) runPublish() (int, error) {
} }
func (s *webRTCSession) runRead() (int, error) { func (s *webRTCSession) runRead() (int, error) {
ip, _, _ := net.SplitHostPort(s.req.remoteAddr)
res := s.pathManager.readerAdd(pathReaderAddReq{ res := s.pathManager.readerAdd(pathReaderAddReq{
author: s, author: s,
pathName: s.req.pathName, pathName: s.req.pathName,
skipAuth: true, credentials: authCredentials{
query: s.req.query,
ip: net.ParseIP(ip),
user: s.req.user,
pass: s.req.pass,
proto: authProtocolWebRTC,
id: &s.uuid,
},
}) })
if res.err != nil { if res.err != nil {
if _, ok := res.err.(pathErrAuth); ok {
return http.StatusUnauthorized, res.err
}
if strings.HasPrefix(res.err.Error(), "no one is publishing") { if strings.HasPrefix(res.err.Error(), "no one is publishing") {
return http.StatusNotFound, res.err return http.StatusNotFound, res.err
} }
return http.StatusInternalServerError, res.err return http.StatusBadRequest, res.err
} }
defer res.path.readerRemove(pathReaderRemoveReq{author: s}) defer res.path.readerRemove(pathReaderRemoveReq{author: s})

Loading…
Cancel
Save