From 0371d3dc7c003c2793bf7e6a2c88fa525b68c97a Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Thu, 1 Oct 2020 23:31:14 +0200 Subject: [PATCH] Authenticate streams --- main.go | 2 +- stream/forwarding/forwarding_test.go | 4 +-- stream/srt/srt.go | 44 +++++++++++++++++++++++----- stream/srt/srt_test.go | 4 +-- 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/main.go b/main.go index 7f42fd3..016786e 100644 --- a/main.go +++ b/main.go @@ -96,7 +96,7 @@ func main() { // Start stream, web and monitoring server, and stream forwarding go forwarding.Serve(cfg.Forwarding, forwardingChannel) go monitoring.Serve(&cfg.Monitoring) - go srt.Serve(&cfg.Srt, forwardingChannel) + go srt.Serve(&cfg.Srt, authBackend, forwardingChannel) go web.Serve(remoteSdpChan, localSdpChan, &cfg.Web) go webrtc.Serve(remoteSdpChan, localSdpChan, &cfg.WebRTC) diff --git a/stream/forwarding/forwarding_test.go b/stream/forwarding/forwarding_test.go index 79d22f1..fbbcdd0 100644 --- a/stream/forwarding/forwarding_test.go +++ b/stream/forwarding/forwarding_test.go @@ -59,11 +59,11 @@ func TestForwardStream(t *testing.T) { go Serve(forwardingList, forwardingChannel) // Serve HTTP Server - go srt.Serve(&srt.Options{ListenAddress: ":9712", MaxClients: 2}, forwardingChannel) + go srt.Serve(&srt.Options{ListenAddress: ":9712", MaxClients: 2}, nil, forwardingChannel) ffmpeg := exec.Command("ffmpeg", "-re", "-f", "lavfi", "-i", "testsrc=size=640x480:rate=10", - "-f", "flv", "srt://127.0.0.1:9712") + "-f", "flv", "srt://127.0.0.1:9712?streamid=demo|") output, err := ffmpeg.StdoutPipe() errOutput, err := ffmpeg.StderrPipe() diff --git a/stream/srt/srt.go b/stream/srt/srt.go index 62ca740..8b6e7e7 100644 --- a/stream/srt/srt.go +++ b/stream/srt/srt.go @@ -1,9 +1,12 @@ package srt import ( + "gitlab.crans.org/nounous/ghostream/auth" + "gitlab.crans.org/nounous/ghostream/auth/bypass" "log" "net" "strconv" + "strings" "github.com/haivision/srtgo" ) @@ -38,14 +41,18 @@ func splitHostPort(hostport string) (string, uint16) { } // Serve SRT server -func Serve(cfg *Options, forwardingChannel chan Packet) { +func Serve(cfg *Options, authBackend auth.Backend, forwardingChannel chan Packet) { + if authBackend == nil { + authBackend, _ = bypass.New() + } + options := make(map[string]string) options["transtype"] = "live" // Start SRT in listen mode log.Printf("SRT server listening on %s", cfg.ListenAddress) host, port := splitHostPort(cfg.ListenAddress) - sck := srtgo.NewSrtSocket(host, uint16(port), options) + sck := srtgo.NewSrtSocket(host, port, options) if err := sck.Listen(cfg.MaxClients); err != nil { log.Fatal("Unable to listen to SRT clients:", err) } @@ -61,12 +68,34 @@ func Serve(cfg *Options, forwardingChannel chan Packet) { break // FIXME: should not break here } + streamId, err := s.GetSockOptString(46) // SRTO_STREAMID + if err != nil { + log.Println("Error while fetching stream key:", err) + s.Close() + continue + } + if !strings.Contains(streamId, "|") { + log.Printf("Warning: stream id must be at the format streamId|password. Input: %s", streamId) + s.Close() + continue + } + + splittedStreamId := strings.SplitN(streamId, "|", 2) + streamName, password := splittedStreamId[0], splittedStreamId[1] + loggedIn, err := authBackend.Login(streamName, password) + if !loggedIn { + log.Printf("Invalid credentials for stream %s.", streamName) + s.Close() + continue + } + + log.Printf("Starting stream %s...", streamName) + // Create a new buffer buff := make([]byte, 2048) // Setup stream forwarding - // FIXME: demo should be replaced by stream name - forwardingChannel <- Packet{StreamName: "demo", PacketType: "register", Data: nil} + forwardingChannel <- Packet{StreamName: streamName, PacketType: "register", Data: nil} // Read RTP packets forever and send them to the WebRTC Client for { @@ -81,20 +110,21 @@ func Serve(cfg *Options, forwardingChannel chan Packet) { log.Printf("Received no bytes, stopping stream.") break } - // log.Printf("Received %d bytes", n) // Send raw packet to other streams // Copy data in another buffer to ensure that the data would not be overwritten data := make([]byte, n) copy(data, buff[:n]) - forwardingChannel <- Packet{StreamName: "demo", PacketType: "sendData", Data: data} + forwardingChannel <- Packet{StreamName: streamName, PacketType: "sendData", Data: data} // TODO: Send to WebRTC // See https://github.com/ebml-go/webm/blob/master/reader.go //err := videoTrack.WriteSample(media.Sample{Data: data, Samples: uint32(sampleCount)}) } - forwardingChannel <- Packet{StreamName: "demo", PacketType: "close", Data: nil} + forwardingChannel <- Packet{StreamName: streamName, PacketType: "close", Data: nil} } + + sck.Close() } diff --git a/stream/srt/srt_test.go b/stream/srt/srt_test.go index d6c480a..e174a27 100644 --- a/stream/srt/srt_test.go +++ b/stream/srt/srt_test.go @@ -36,11 +36,11 @@ func TestServeSRT(t *testing.T) { t.Skip("WARNING: FFMPEG is not installed. Skipping stream test") } - go Serve(&Options{ListenAddress: ":9711", MaxClients: 2}, nil) + go Serve(&Options{ListenAddress: ":9711", MaxClients: 2}, nil, nil) ffmpeg := exec.Command("ffmpeg", "-i", "http://ftp.crans.org/events/Blender%20OpenMovies/big_buck_bunny_480p_stereo.ogg", - "-f", "flv", "srt://127.0.0.1:9711") + "-f", "flv", "srt://127.0.0.1:9711??streamid=demo|") output, err := ffmpeg.StdoutPipe() errOutput, err := ffmpeg.StderrPipe()