|
|
|
@ -1,6 +1,7 @@
@@ -1,6 +1,7 @@
|
|
|
|
|
package main |
|
|
|
|
|
|
|
|
|
import ( |
|
|
|
|
"errors" |
|
|
|
|
"fmt" |
|
|
|
|
"io" |
|
|
|
|
"log" |
|
|
|
@ -108,7 +109,8 @@ type serverClient struct {
@@ -108,7 +109,8 @@ type serverClient struct {
|
|
|
|
|
conn *gortsplib.ConnServer |
|
|
|
|
state clientState |
|
|
|
|
path string |
|
|
|
|
as *gortsplib.AuthServer |
|
|
|
|
publishAuth *gortsplib.AuthServer |
|
|
|
|
readAuth *gortsplib.AuthServer |
|
|
|
|
streamSdpText []byte // filled only if publisher
|
|
|
|
|
streamSdpParsed *sdp.Message // filled only if publisher
|
|
|
|
|
streamProtocol streamProtocol |
|
|
|
@ -240,6 +242,44 @@ func (c *serverClient) writeResError(req *gortsplib.Request, code gortsplib.Stat
@@ -240,6 +242,44 @@ func (c *serverClient) writeResError(req *gortsplib.Request, code gortsplib.Stat
|
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var errAuthCritical = errors.New("auth critical") |
|
|
|
|
var errAuthNotCritical = errors.New("auth not critical") |
|
|
|
|
|
|
|
|
|
func (c *serverClient) validateAuth(req *gortsplib.Request, user string, pass string, auth **gortsplib.AuthServer) error { |
|
|
|
|
if user == "" { |
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
initialRequest := false |
|
|
|
|
if *auth == nil { |
|
|
|
|
initialRequest = true |
|
|
|
|
*auth = gortsplib.NewAuthServer(user, pass) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err := (*auth).ValidateHeader(req.Header["Authorization"], req.Method, req.Url) |
|
|
|
|
if err != nil { |
|
|
|
|
if !initialRequest { |
|
|
|
|
c.log("ERR: Unauthorized: %s", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
c.conn.WriteResponse(&gortsplib.Response{ |
|
|
|
|
StatusCode: gortsplib.StatusUnauthorized, |
|
|
|
|
Header: gortsplib.Header{ |
|
|
|
|
"CSeq": []string{req.Header["CSeq"][0]}, |
|
|
|
|
"WWW-Authenticate": (*auth).GenerateHeader(), |
|
|
|
|
}, |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
if !initialRequest { |
|
|
|
|
return errAuthCritical |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return errAuthNotCritical |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (c *serverClient) handleRequest(req *gortsplib.Request) bool { |
|
|
|
|
c.log(string(req.Method)) |
|
|
|
|
|
|
|
|
@ -293,6 +333,14 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -293,6 +333,14 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
|
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err := c.validateAuth(req, c.p.args.readUser, c.p.args.readPass, &c.readAuth) |
|
|
|
|
if err != nil { |
|
|
|
|
if err == errAuthCritical { |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sdp, err := func() ([]byte, error) { |
|
|
|
|
c.p.tcpl.mutex.RLock() |
|
|
|
|
defer c.p.tcpl.mutex.RUnlock() |
|
|
|
@ -326,33 +374,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -326,33 +374,12 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
|
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if c.p.args.publishUser != "" { |
|
|
|
|
initialRequest := false |
|
|
|
|
if c.as == nil { |
|
|
|
|
initialRequest = true |
|
|
|
|
c.as = gortsplib.NewAuthServer(c.p.args.publishUser, c.p.args.publishPass) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
err := c.as.ValidateHeader(req.Header["Authorization"], gortsplib.ANNOUNCE, req.Url) |
|
|
|
|
if err != nil { |
|
|
|
|
if !initialRequest { |
|
|
|
|
c.log("ERR: Unauthorized: %s", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
c.conn.WriteResponse(&gortsplib.Response{ |
|
|
|
|
StatusCode: gortsplib.StatusUnauthorized, |
|
|
|
|
Header: gortsplib.Header{ |
|
|
|
|
"CSeq": []string{cseq[0]}, |
|
|
|
|
"WWW-Authenticate": c.as.GenerateHeader(), |
|
|
|
|
}, |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
if !initialRequest { |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return true |
|
|
|
|
err := c.validateAuth(req, c.p.args.publishUser, c.p.args.publishPass, &c.publishAuth) |
|
|
|
|
if err != nil { |
|
|
|
|
if err == errAuthCritical { |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
ct, ok := req.Header["Content-Type"] |
|
|
|
@ -420,6 +447,14 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
@@ -420,6 +447,14 @@ func (c *serverClient) handleRequest(req *gortsplib.Request) bool {
|
|
|
|
|
switch c.state { |
|
|
|
|
// play
|
|
|
|
|
case _CLIENT_STATE_STARTING, _CLIENT_STATE_PRE_PLAY: |
|
|
|
|
err := c.validateAuth(req, c.p.args.readUser, c.p.args.readPass, &c.readAuth) |
|
|
|
|
if err != nil { |
|
|
|
|
if err == errAuthCritical { |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
return true |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// play via UDP
|
|
|
|
|
if func() bool { |
|
|
|
|
_, ok := th["RTP/AVP"] |
|
|
|
|