Browse Source

move decoding of more configuration into JSON decoding

pull/639/head
aler9 4 years ago committed by Alessandro Ros
parent
commit
ab71f22560
  1. 37
      internal/conf/credential.go
  2. 50
      internal/conf/path.go
  3. 12
      internal/core/api.go
  4. 2
      internal/core/hls_muxer.go
  5. 6
      internal/core/path.go
  6. 6
      internal/core/path_manager.go
  7. 12
      internal/core/rtmp_conn.go
  8. 14
      internal/core/rtsp_conn.go
  9. 4
      internal/core/rtsp_session.go

37
internal/conf/credential.go

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
package conf
import (
"encoding/json"
"fmt"
"regexp"
"strings"
)
var reCredential = regexp.MustCompile(`^[a-zA-Z0-9!\$\(\)\*\+\.;<=>\[\]\^_\-\{\}]+$`)
const credentialSupportedChars = "A-Z,0-9,!,$,(,),*,+,.,;,<,=,>,[,],^,_,-,{,}"
// Credential is a parameter that is used as username or password.
type Credential string
// MarshalJSON marshals a Credential into JSON.
func (d Credential) MarshalJSON() ([]byte, error) {
return json.Marshal(string(d))
}
// UnmarshalJSON unmarshals a Credential from JSON.
func (d *Credential) UnmarshalJSON(b []byte) error {
var in string
if err := json.Unmarshal(b, &in); err != nil {
return err
}
if in != "" &&
!strings.HasPrefix(in, "sha256:") &&
!reCredential.MatchString(in) {
return fmt.Errorf("contains unsupported characters (supported are %s)", credentialSupportedChars)
}
*d = Credential(in)
return nil
}

50
internal/conf/path.go

@ -11,10 +11,6 @@ import ( @@ -11,10 +11,6 @@ import (
"github.com/aler9/gortsplib/pkg/base"
)
const userPassSupportedChars = "A-Z,0-9,!,$,(,),*,+,.,;,<,=,>,[,],^,_,-,{,}"
var reUserPass = regexp.MustCompile(`^[a-zA-Z0-9!\$\(\)\*\+\.;<=>\[\]\^_\-\{\}]+$`)
var rePathName = regexp.MustCompile(`^[0-9a-zA-Z_\-/\.~]+$`)
// IsValidPathName checks if a path name is valid.
@ -55,12 +51,12 @@ type PathConf struct { @@ -55,12 +51,12 @@ type PathConf struct {
Fallback string `json:"fallback"`
// authentication
PublishUser string `json:"publishUser"`
PublishPass string `json:"publishPass"`
PublishIPs IPsOrNets `json:"publishIPs"`
ReadUser string `json:"readUser"`
ReadPass string `json:"readPass"`
ReadIPs IPsOrNets `json:"readIPs"`
PublishUser Credential `json:"publishUser"`
PublishPass Credential `json:"publishPass"`
PublishIPs IPsOrNets `json:"publishIPs"`
ReadUser Credential `json:"readUser"`
ReadPass Credential `json:"readPass"`
ReadIPs IPsOrNets `json:"readIPs"`
// custom commands
RunOnInit string `json:"runOnInit"`
@ -211,25 +207,9 @@ func (pconf *PathConf) checkAndFillMissing(name string) error { @@ -211,25 +207,9 @@ func (pconf *PathConf) checkAndFillMissing(name string) error {
return fmt.Errorf("read username and password must be both filled")
}
if pconf.PublishUser != "" {
if pconf.Source != "publisher" {
return fmt.Errorf("'publishUser' is useless when source is not 'publisher'")
}
if !strings.HasPrefix(pconf.PublishUser, "sha256:") && !reUserPass.MatchString(pconf.PublishUser) {
return fmt.Errorf("publish username contains unsupported characters (supported are %s)", userPassSupportedChars)
}
}
if pconf.PublishPass != "" {
if pconf.Source != "publisher" {
return fmt.Errorf("'publishPass' is useless when source is not 'publisher', since " +
"the stream is not provided by a publisher, but by a fixed source")
}
if !strings.HasPrefix(pconf.PublishPass, "sha256:") && !reUserPass.MatchString(pconf.PublishPass) {
return fmt.Errorf("publish password contains unsupported characters (supported are %s)", userPassSupportedChars)
}
if pconf.PublishUser != "" && pconf.Source != "publisher" {
return fmt.Errorf("'publishUser' is useless when source is not 'publisher', since " +
"the stream is not provided by a publisher, but by a fixed source")
}
if len(pconf.PublishIPs) > 0 && pconf.Source != "publisher" {
@ -242,18 +222,6 @@ func (pconf *PathConf) checkAndFillMissing(name string) error { @@ -242,18 +222,6 @@ func (pconf *PathConf) checkAndFillMissing(name string) error {
return fmt.Errorf("read username and password must be both filled")
}
if pconf.ReadUser != "" {
if !strings.HasPrefix(pconf.ReadUser, "sha256:") && !reUserPass.MatchString(pconf.ReadUser) {
return fmt.Errorf("read username contains unsupported characters (supported are %s)", userPassSupportedChars)
}
}
if pconf.ReadPass != "" {
if !strings.HasPrefix(pconf.ReadPass, "sha256:") && !reUserPass.MatchString(pconf.ReadPass) {
return fmt.Errorf("read password contains unsupported characters (supported are %s)", userPassSupportedChars)
}
}
if pconf.RunOnInit != "" && pconf.Regexp != nil {
return fmt.Errorf("a path with a regular expression does not support option 'runOnInit'; use another path")
}

12
internal/core/api.go

@ -112,12 +112,12 @@ func loadConfPathData(ctx *gin.Context) (interface{}, error) { @@ -112,12 +112,12 @@ func loadConfPathData(ctx *gin.Context) (interface{}, error) {
Fallback *string `json:"fallback"`
// authentication
PublishUser *string `json:"publishUser"`
PublishPass *string `json:"publishPass"`
PublishIPs *conf.IPsOrNets `json:"publishIPs"`
ReadUser *string `json:"readUser"`
ReadPass *string `json:"readPass"`
ReadIPs *conf.IPsOrNets `json:"readIPs"`
PublishUser *conf.Credential `json:"publishUser"`
PublishPass *conf.Credential `json:"publishPass"`
PublishIPs *conf.IPsOrNets `json:"publishIPs"`
ReadUser *conf.Credential `json:"readUser"`
ReadPass *conf.Credential `json:"readPass"`
ReadIPs *conf.IPsOrNets `json:"readIPs"`
// custom commands
RunOnInit *string `json:"runOnInit"`

2
internal/core/hls_muxer.go

@ -424,7 +424,7 @@ func (r *hlsMuxer) handleRequest(req hlsMuxerRequest) { @@ -424,7 +424,7 @@ func (r *hlsMuxer) handleRequest(req hlsMuxerRequest) {
if conf.ReadUser != "" {
user, pass, ok := req.Req.BasicAuth()
if !ok || user != conf.ReadUser || pass != conf.ReadPass {
if !ok || user != string(conf.ReadUser) || pass != string(conf.ReadPass) {
req.W.Header().Set("WWW-Authenticate", `Basic realm="rtsp-simple-server"`)
req.W.WriteHeader(http.StatusUnauthorized)
req.Res <- nil

6
internal/core/path.go

@ -123,7 +123,7 @@ type pathDescribeReq struct { @@ -123,7 +123,7 @@ type pathDescribeReq struct {
PathName string
URL *base.URL
IP net.IP
ValidateCredentials func(pathUser string, pathPass string) error
ValidateCredentials func(pathUser conf.Credential, pathPass conf.Credential) error
Res chan pathDescribeRes
}
@ -137,7 +137,7 @@ type pathReaderSetupPlayReq struct { @@ -137,7 +137,7 @@ type pathReaderSetupPlayReq struct {
Author reader
PathName string
IP net.IP
ValidateCredentials func(pathUser string, pathPass string) error
ValidateCredentials func(pathUser conf.Credential, pathPass conf.Credential) error
Res chan pathReaderSetupPlayRes
}
@ -150,7 +150,7 @@ type pathPublisherAnnounceReq struct { @@ -150,7 +150,7 @@ type pathPublisherAnnounceReq struct {
Author publisher
PathName string
IP net.IP
ValidateCredentials func(pathUser string, pathPass string) error
ValidateCredentials func(pathUser conf.Credential, pathPass conf.Credential) error
Res chan pathPublisherAnnounceRes
}

6
internal/core/path_manager.go

@ -312,11 +312,11 @@ func (pm *pathManager) findPathConf(name string) (string, *conf.PathConf, error) @@ -312,11 +312,11 @@ func (pm *pathManager) findPathConf(name string) (string, *conf.PathConf, error)
func (pm *pathManager) authenticate(
ip net.IP,
validateCredentials func(pathUser string, pathPass string) error,
validateCredentials func(pathUser conf.Credential, pathPass conf.Credential) error,
pathName string,
pathIPs []interface{},
pathUser string,
pathPass string,
pathUser conf.Credential,
pathPass conf.Credential,
) error {
// validate ip
if pathIPs != nil && ip != nil {

12
internal/core/rtmp_conn.go

@ -205,7 +205,7 @@ func (c *rtmpConn) runRead(ctx context.Context) error { @@ -205,7 +205,7 @@ func (c *rtmpConn) runRead(ctx context.Context) error {
Author: c,
PathName: pathName,
IP: c.ip(),
ValidateCredentials: func(pathUser string, pathPass string) error {
ValidateCredentials: func(pathUser conf.Credential, pathPass conf.Credential) error {
return c.validateCredentials(pathUser, pathPass, query)
},
})
@ -440,7 +440,7 @@ func (c *rtmpConn) runPublish(ctx context.Context) error { @@ -440,7 +440,7 @@ func (c *rtmpConn) runPublish(ctx context.Context) error {
Author: c,
PathName: pathName,
IP: c.ip(),
ValidateCredentials: func(pathUser string, pathPass string) error {
ValidateCredentials: func(pathUser conf.Credential, pathPass conf.Credential) error {
return c.validateCredentials(pathUser, pathPass, query)
},
})
@ -548,12 +548,12 @@ func (c *rtmpConn) runPublish(ctx context.Context) error { @@ -548,12 +548,12 @@ func (c *rtmpConn) runPublish(ctx context.Context) error {
}
func (c *rtmpConn) validateCredentials(
pathUser string,
pathPass string,
pathUser conf.Credential,
pathPass conf.Credential,
query url.Values,
) error {
if query.Get("user") != pathUser ||
query.Get("pass") != pathPass {
if query.Get("user") != string(pathUser) ||
query.Get("pass") != string(pathPass) {
return pathErrAuthCritical{
Message: "wrong username or password",
}

14
internal/core/rtsp_conn.go

@ -99,16 +99,16 @@ func (c *rtspConn) ip() net.IP { @@ -99,16 +99,16 @@ func (c *rtspConn) ip() net.IP {
}
func (c *rtspConn) validateCredentials(
pathUser string,
pathPass string,
pathUser conf.Credential,
pathPass conf.Credential,
pathName string,
req *base.Request,
) error {
// reset authValidator every time the credentials change
if c.authValidator == nil || c.authUser != pathUser || c.authPass != pathPass {
c.authUser = pathUser
c.authPass = pathPass
c.authValidator = auth.NewValidator(pathUser, pathPass, c.authMethods)
if c.authValidator == nil || c.authUser != string(pathUser) || c.authPass != string(pathPass) {
c.authUser = string(pathUser)
c.authPass = string(pathPass)
c.authValidator = auth.NewValidator(string(pathUser), string(pathPass), c.authMethods)
}
// VLC strips the control attribute
@ -193,7 +193,7 @@ func (c *rtspConn) OnDescribe(ctx *gortsplib.ServerHandlerOnDescribeCtx, @@ -193,7 +193,7 @@ func (c *rtspConn) OnDescribe(ctx *gortsplib.ServerHandlerOnDescribeCtx,
PathName: ctx.Path,
URL: ctx.Req.URL,
IP: c.ip(),
ValidateCredentials: func(pathUser string, pathPass string) error {
ValidateCredentials: func(pathUser conf.Credential, pathPass conf.Credential) error {
return c.validateCredentials(pathUser, pathPass, ctx.Path, ctx.Req)
},
})

4
internal/core/rtsp_session.go

@ -134,7 +134,7 @@ func (s *rtspSession) OnAnnounce(c *rtspConn, ctx *gortsplib.ServerHandlerOnAnno @@ -134,7 +134,7 @@ func (s *rtspSession) OnAnnounce(c *rtspConn, ctx *gortsplib.ServerHandlerOnAnno
Author: s,
PathName: ctx.Path,
IP: ctx.Conn.NetConn().RemoteAddr().(*net.TCPAddr).IP,
ValidateCredentials: func(pathUser string, pathPass string) error {
ValidateCredentials: func(pathUser conf.Credential, pathPass conf.Credential) error {
return c.validateCredentials(pathUser, pathPass, ctx.Path, ctx.Req)
},
})
@ -198,7 +198,7 @@ func (s *rtspSession) OnSetup(c *rtspConn, ctx *gortsplib.ServerHandlerOnSetupCt @@ -198,7 +198,7 @@ func (s *rtspSession) OnSetup(c *rtspConn, ctx *gortsplib.ServerHandlerOnSetupCt
Author: s,
PathName: ctx.Path,
IP: ctx.Conn.NetConn().RemoteAddr().(*net.TCPAddr).IP,
ValidateCredentials: func(pathUser string, pathPass string) error {
ValidateCredentials: func(pathUser conf.Credential, pathPass conf.Credential) error {
return c.validateCredentials(pathUser, pathPass, ctx.Path, ctx.Req)
},
})

Loading…
Cancel
Save