Fix input and output validation with tee outputs

This commit is contained in:
Ingo Oppermann 2022-07-07 15:45:24 +02:00
parent 2ecea4b3e2
commit 337e0040c2
No known key found for this signature in database
GPG Key ID: 2AB32426E9DD229E
2 changed files with 110 additions and 28 deletions

View File

@ -585,11 +585,6 @@ func (r *restream) validateConfig(config *app.Config) (bool, error) {
if err != nil {
return false, fmt.Errorf("the address for input '#%s:%s' (%s) is invalid: %w", config.ID, io.ID, io.Address, err)
}
ok := r.ffmpeg.ValidateInputAddress(io.Address)
if !ok {
return false, fmt.Errorf("the address for input '#%s:%s' is not allowed (%s)", config.ID, io.ID, io.Address)
}
}
if len(config.Output) == 0 {
@ -628,11 +623,6 @@ func (r *restream) validateConfig(config *app.Config) (bool, error) {
if isFile {
hasFiles = true
}
ok := r.ffmpeg.ValidateOutputAddress(io.Address)
if !ok {
return false, fmt.Errorf("the address for output '#%s:%s' is not allowed (%s)", config.ID, io.ID, io.Address)
}
}
return hasFiles, nil
@ -645,6 +635,10 @@ func (r *restream) validateInputAddress(address, basedir string) (string, error)
}
}
if !r.ffmpeg.ValidateInputAddress(address) {
return address, fmt.Errorf("address is not allowed")
}
return address, nil
}
@ -683,6 +677,11 @@ func (r *restream) validateOutputAddress(address, basedir string) (string, bool,
if err := url.Validate(address); err != nil {
return address, false, err
}
if !r.ffmpeg.ValidateOutputAddress(address) {
return address, false, fmt.Errorf("address is not allowed")
}
return address, false, nil
}
@ -696,6 +695,10 @@ func (r *restream) validateOutputAddress(address, basedir string) (string, bool,
}
if strings.HasPrefix(address, "/dev/") {
if !r.ffmpeg.ValidateOutputAddress("file:" + address) {
return address, false, fmt.Errorf("address is not allowed")
}
return "file:" + address, false, nil
}
@ -703,6 +706,10 @@ func (r *restream) validateOutputAddress(address, basedir string) (string, bool,
return address, false, fmt.Errorf("%s is not inside of %s", address, basedir)
}
if !r.ffmpeg.ValidateOutputAddress("file:" + address) {
return address, false, fmt.Errorf("address is not allowed")
}
return "file:" + address, true, nil
}

View File

@ -13,15 +13,17 @@ import (
"github.com/stretchr/testify/require"
)
func getDummyRestreamer(portrange net.Portranger) (Restreamer, error) {
func getDummyRestreamer(portrange net.Portranger, validatorIn, validatorOut ffmpeg.Validator) (Restreamer, error) {
binary, err := testhelper.BuildBinary("ffmpeg", "../internal/testhelper")
if err != nil {
return nil, fmt.Errorf("failed to build helper program: %w", err)
}
ffmpeg, err := ffmpeg.New(ffmpeg.Config{
Binary: binary,
Portrange: portrange,
Binary: binary,
Portrange: portrange,
ValidatorInput: validatorIn,
ValidatorOutput: validatorOut,
})
if err != nil {
return nil, err
@ -75,7 +77,7 @@ func getDummyProcess() *app.Config {
}
func TestAddProcess(t *testing.T) {
rs, err := getDummyRestreamer(nil)
rs, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
process := getDummyProcess()
@ -95,7 +97,7 @@ func TestAddProcess(t *testing.T) {
}
func TestAutostartProcess(t *testing.T) {
rs, err := getDummyRestreamer(nil)
rs, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
process := getDummyProcess()
@ -110,7 +112,7 @@ func TestAutostartProcess(t *testing.T) {
}
func TestAddInvalidProcess(t *testing.T) {
rs, err := getDummyRestreamer(nil)
rs, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
// Invalid process ID
@ -178,7 +180,7 @@ func TestAddInvalidProcess(t *testing.T) {
}
func TestRemoveProcess(t *testing.T) {
rs, err := getDummyRestreamer(nil)
rs, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
process := getDummyProcess()
@ -194,7 +196,7 @@ func TestRemoveProcess(t *testing.T) {
}
func TestGetProcess(t *testing.T) {
rs, err := getDummyRestreamer(nil)
rs, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
process := getDummyProcess()
@ -210,7 +212,7 @@ func TestGetProcess(t *testing.T) {
}
func TestStartProcess(t *testing.T) {
rs, err := getDummyRestreamer(nil)
rs, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
process := getDummyProcess()
@ -236,7 +238,7 @@ func TestStartProcess(t *testing.T) {
}
func TestStopProcess(t *testing.T) {
rs, err := getDummyRestreamer(nil)
rs, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
process := getDummyProcess()
@ -261,7 +263,7 @@ func TestStopProcess(t *testing.T) {
}
func TestRestartProcess(t *testing.T) {
rs, err := getDummyRestreamer(nil)
rs, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
process := getDummyProcess()
@ -286,7 +288,7 @@ func TestRestartProcess(t *testing.T) {
}
func TestReloadProcess(t *testing.T) {
rs, err := getDummyRestreamer(nil)
rs, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
process := getDummyProcess()
@ -317,7 +319,7 @@ func TestReloadProcess(t *testing.T) {
}
func TestProcessData(t *testing.T) {
rs, err := getDummyRestreamer(nil)
rs, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
process := getDummyProcess()
@ -338,7 +340,7 @@ func TestProcessData(t *testing.T) {
}
func TestLog(t *testing.T) {
rs, err := getDummyRestreamer(nil)
rs, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
process := getDummyProcess()
@ -371,7 +373,7 @@ func TestLog(t *testing.T) {
}
func TestPlayoutNoRange(t *testing.T) {
rs, err := getDummyRestreamer(nil)
rs, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
process := getDummyProcess()
@ -394,7 +396,7 @@ func TestPlayoutRange(t *testing.T) {
portrange, err := net.NewPortrange(3000, 3001)
require.NoError(t, err)
rs, err := getDummyRestreamer(portrange)
rs, err := getDummyRestreamer(portrange, nil, nil)
require.NoError(t, err)
process := getDummyProcess()
@ -415,7 +417,7 @@ func TestPlayoutRange(t *testing.T) {
}
func TestAddressReference(t *testing.T) {
rs, err := getDummyRestreamer(nil)
rs, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
process1 := getDummyProcess()
@ -446,8 +448,81 @@ func TestAddressReference(t *testing.T) {
require.Equal(t, nil, err, "should resolve reference")
}
func TestConfigValidation(t *testing.T) {
rsi, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
rs := rsi.(*restream)
config := getDummyProcess()
_, err = rs.validateConfig(config)
require.NoError(t, err)
config.Input = []app.ConfigIO{}
_, err = rs.validateConfig(config)
require.Error(t, err)
config = getDummyProcess()
config.Input[0].ID = ""
_, err = rs.validateConfig(config)
require.Error(t, err)
config = getDummyProcess()
config.Input[0].Address = ""
_, err = rs.validateConfig(config)
require.Error(t, err)
config = getDummyProcess()
config.Output = []app.ConfigIO{}
_, err = rs.validateConfig(config)
require.Error(t, err)
config = getDummyProcess()
config.Output[0].ID = ""
_, err = rs.validateConfig(config)
require.Error(t, err)
config = getDummyProcess()
config.Output[0].Address = ""
_, err = rs.validateConfig(config)
require.Error(t, err)
}
func TestConfigValidationFFmpeg(t *testing.T) {
valIn, err := ffmpeg.NewValidator([]string{"^https?://"}, nil)
require.NoError(t, err)
valOut, err := ffmpeg.NewValidator([]string{"^https?://", "^rtmp://"}, nil)
require.NoError(t, err)
rsi, err := getDummyRestreamer(nil, valIn, valOut)
require.NoError(t, err)
rs := rsi.(*restream)
config := getDummyProcess()
_, err = rs.validateConfig(config)
require.Error(t, err)
config.Input[0].Address = "http://stream.example.com/master.m3u8"
config.Output[0].Address = "http://stream.example.com/master2.m3u8"
_, err = rs.validateConfig(config)
require.NoError(t, err)
config.Output[0].Address = "[f=flv]http://stream.example.com/master2.m3u8"
_, err = rs.validateConfig(config)
require.NoError(t, err)
config.Output[0].Address = "[f=hls]http://stream.example.com/master2.m3u8|[f=flv]rtmp://stream.example.com/stream"
_, err = rs.validateConfig(config)
require.NoError(t, err)
}
func TestOutputAddressValidation(t *testing.T) {
rsi, err := getDummyRestreamer(nil)
rsi, err := getDummyRestreamer(nil, nil, nil)
require.NoError(t, err)
rs := rsi.(*restream)