rtsp server support basic auth

pull/184/head
ZSC714725 3 years ago
parent 01a079accf
commit b3d142503c

@ -17,6 +17,7 @@ import (
"github.com/q191201771/lal/pkg/base"
"github.com/q191201771/lal/pkg/hls"
"github.com/q191201771/lal/pkg/rtsp"
"github.com/q191201771/naza/pkg/nazajson"
"github.com/q191201771/naza/pkg/nazalog"
)
@ -87,6 +88,7 @@ type RtspConfig struct {
Enable bool `json:"enable"`
Addr string `json:"addr"`
OutWaitKeyFrameFlag bool `json:"out_wait_key_frame_flag"`
rtsp.RtspServerAuthConfig
}
type RecordConfig struct {

@ -11,13 +11,14 @@ package logic
import (
"flag"
"fmt"
"github.com/q191201771/naza/pkg/nazalog"
"net/http"
"os"
"path/filepath"
"sync"
"time"
"github.com/q191201771/naza/pkg/nazalog"
"github.com/q191201771/naza/pkg/defertaskthread"
"github.com/q191201771/lal/pkg/hls"
@ -125,7 +126,7 @@ Doc: %s
sm.rtmpServer = rtmp.NewServer(sm.config.RtmpConfig.Addr, sm)
}
if sm.config.RtspConfig.Enable {
sm.rtspServer = rtsp.NewServer(sm.config.RtspConfig.Addr, sm)
sm.rtspServer = rtsp.NewServer(sm.config.RtspConfig.Addr, sm, sm.config.RtspConfig.RtspServerAuthConfig)
}
if sm.config.HttpApiConfig.Enable {
sm.httpApiServer = NewHttpApiServer(sm.config.HttpApiConfig.Addr, sm)

@ -77,6 +77,12 @@ var ResponseTeardownTmpl = "RTSP/1.0 200 OK\r\n" +
"CSeq: %s\r\n" +
"\r\n"
var ResponseBasicAuthorizedTmpl = "RTSP/1.0 401 Unauthorized\r\n" +
"CSeq: %s\r\n" +
"Date: %s\r\n" +
"WWW-Authenticate: %s realm=\"Lal Server\"\r\n" +
"\r\n"
func PackResponseOptions(cseq string) string {
return fmt.Sprintf(ResponseOptionsTmpl, cseq)
}
@ -109,6 +115,11 @@ func PackResponseTeardown(cseq string) string {
return fmt.Sprintf(ResponseTeardownTmpl, cseq)
}
func PackResponseBasicAuthorized(cseq, authMethod string) string {
date := time.Now().Format(time.RFC1123)
return fmt.Sprintf(ResponseBasicAuthorizedTmpl, cseq, date, authMethod)
}
// PackRequest @param body 可以为空
func PackRequest(method, uri string, headers map[string]string, body string) (ret string) {
ret = method + " " + uri + " RTSP/1.0\r\n"

@ -49,17 +49,26 @@ type IServerObserver interface {
OnDelRtspSubSession(session *SubSession)
}
type RtspServerAuthConfig struct {
AuthEnable bool `json:"auth_enable"`
AuthMethod int `json:"auth_method"`
UserName string `json:"username"`
PassWord string `json:"password"`
}
type Server struct {
addr string
observer IServerObserver
ln net.Listener
ln net.Listener
auth RtspServerAuthConfig
}
func NewServer(addr string, observer IServerObserver) *Server {
func NewServer(addr string, observer IServerObserver, auth RtspServerAuthConfig) *Server {
return &Server{
addr: addr,
observer: observer,
auth: auth,
}
}
@ -116,7 +125,7 @@ func (s *Server) OnDelRtspSubSession(session *SubSession) {
// ---------------------------------------------------------------------------------------------------------------------
func (s *Server) handleTcpConnect(conn net.Conn) {
session := NewServerCommandSession(s, conn)
session := NewServerCommandSession(s, conn, s.auth)
s.observer.OnNewRtspSessionConnect(session)
err := session.RunLoop()

@ -10,6 +10,7 @@ package rtsp
import (
"bufio"
"encoding/base64"
"fmt"
"net"
"strings"
@ -54,16 +55,18 @@ type ServerCommandSession struct {
prevConnStat connection.Stat
staleStat *connection.Stat
stat base.StatSession
auth RtspServerAuthConfig
pubSession *PubSession
subSession *SubSession
}
func NewServerCommandSession(observer IServerCommandSessionObserver, conn net.Conn) *ServerCommandSession {
func NewServerCommandSession(observer IServerCommandSessionObserver, conn net.Conn, auth RtspServerAuthConfig) *ServerCommandSession {
uk := base.GenUkRtspServerCommandSession()
s := &ServerCommandSession{
uniqueKey: uk,
observer: observer,
auth: auth,
conn: connection.New(conn, func(option *connection.Option) {
option.ReadBufSize = serverCommandSessionReadBufSize
option.WriteChanSize = serverCommandSessionWriteChanSize
@ -251,6 +254,19 @@ func (session *ServerCommandSession) handleAnnounce(requestCtx nazahttp.HttpReqM
func (session *ServerCommandSession) handleDescribe(requestCtx nazahttp.HttpReqMsgCtx) error {
Log.Infof("[%s] < R DESCRIBE", session.uniqueKey)
if session.auth.AuthEnable {
// 鉴权处理
authresp, err := session.handleAuthorized(requestCtx)
if err != nil {
return err
}
if authresp != "" {
_, err := session.conn.Write([]byte(authresp))
return err
}
}
urlCtx, err := base.ParseRtspUrl(requestCtx.Uri)
if err != nil {
Log.Errorf("[%s] parse presentation failed. uri=%s", session.uniqueKey, requestCtx.Uri)
@ -273,6 +289,38 @@ func (session *ServerCommandSession) handleDescribe(requestCtx nazahttp.HttpReqM
return err
}
func (session *ServerCommandSession) handleAuthorized(requestCtx nazahttp.HttpReqMsgCtx) (string, error) {
if requestCtx.Headers.Get(HeaderAuthorization) != "" {
auth_str := requestCtx.Headers.Get(HeaderAuthorization)
if strings.Contains(auth_str, AuthTypeBasic) {
// Basic 鉴权
auth_base64_client := strings.TrimLeft(auth_str, "Basic ")
authstr := fmt.Sprintf("%s:%s", session.auth.UserName, session.auth.PassWord)
auth_base64_server := base64.StdEncoding.EncodeToString([]byte(authstr))
if auth_base64_server == auth_base64_client {
Log.Infof("[%s] Rtsp Basic auth success. uri=%s", session.uniqueKey, requestCtx.Uri)
} else {
err := fmt.Errorf("Rtsp Basic auth failed, auth:%s", auth_base64_client)
return "", err
}
} else {
err := fmt.Errorf("unsupport, auth method:%d", session.auth.AuthMethod)
return "", err
}
} else {
if session.auth.AuthMethod == 0 {
resp := PackResponseBasicAuthorized(requestCtx.Headers.Get(HeaderCSeq), AuthTypeBasic)
return resp, nil
} else {
err := fmt.Errorf("unsupport, auth method:%d", session.auth.AuthMethod)
return "", err
}
}
return "", nil
}
// 一次SETUP对应一路流音频或视频
func (session *ServerCommandSession) handleSetup(requestCtx nazahttp.HttpReqMsgCtx) error {
Log.Infof("[%s] < R SETUP", session.uniqueKey)

Loading…
Cancel
Save