mirror of
https://github.com/drakkan/sftpgo.git
synced 2024-11-25 00:50:31 +00:00
EventManager: disable commands by default
Signed-off-by: Nicola Murino <nicola.murino@gmail.com>
This commit is contained in:
parent
d0f348a46a
commit
f07c9a7e01
4 changed files with 47 additions and 17 deletions
|
@ -3928,6 +3928,11 @@ func TestEventRule(t *testing.T) {
|
|||
err = os.WriteFile(uploadScriptPath, getUploadScriptContent(movedPath, "", 0), 0755)
|
||||
assert.NoError(t, err)
|
||||
|
||||
dataprovider.EnabledActionCommands = []string{uploadScriptPath}
|
||||
defer func() {
|
||||
dataprovider.EnabledActionCommands = nil
|
||||
}()
|
||||
|
||||
action1.Type = dataprovider.ActionTypeCommand
|
||||
action1.Options = dataprovider.BaseEventActionOptions{
|
||||
CmdConfig: dataprovider.EventActionCommandConfig{
|
||||
|
@ -4265,6 +4270,10 @@ func TestEventRuleDisabledCommand(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
_, _, err = httpdtest.AddEventAction(a1, http.StatusBadRequest)
|
||||
assert.NoError(t, err)
|
||||
// Enable the command to allow saving
|
||||
dataprovider.EnabledActionCommands = []string{a1.Options.CmdConfig.Cmd}
|
||||
action1, _, err := httpdtest.AddEventAction(a1, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
action2, _, err := httpdtest.AddEventAction(a2, http.StatusCreated)
|
||||
|
@ -4312,8 +4321,8 @@ func TestEventRuleDisabledCommand(t *testing.T) {
|
|||
}
|
||||
rule, _, err := httpdtest.AddEventRule(r, http.StatusCreated)
|
||||
assert.NoError(t, err)
|
||||
// restrit command execution
|
||||
dataprovider.EnabledActionCommands = []string{"/bin/ls"}
|
||||
// restrict command execution
|
||||
dataprovider.EnabledActionCommands = nil
|
||||
|
||||
lastReceivedEmail.reset()
|
||||
// create a folder to trigger the rule
|
||||
|
@ -4335,8 +4344,6 @@ func TestEventRuleDisabledCommand(t *testing.T) {
|
|||
assert.Contains(t, email.Data, fmt.Sprintf("Object name: %s object type: folder", folder.Name))
|
||||
lastReceivedEmail.reset()
|
||||
|
||||
dataprovider.EnabledActionCommands = nil
|
||||
|
||||
_, err = httpdtest.RemoveFolder(folder, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
|
||||
|
@ -4368,6 +4375,11 @@ func TestEventRuleProviderEvents(t *testing.T) {
|
|||
err = os.WriteFile(saveObjectScriptPath, getSaveProviderObjectScriptContent(outPath, 0), 0755)
|
||||
assert.NoError(t, err)
|
||||
|
||||
dataprovider.EnabledActionCommands = []string{saveObjectScriptPath}
|
||||
defer func() {
|
||||
dataprovider.EnabledActionCommands = nil
|
||||
}()
|
||||
|
||||
a1 := dataprovider.BaseEventAction{
|
||||
Name: "a1",
|
||||
Type: dataprovider.ActionTypeCommand,
|
||||
|
@ -5200,6 +5212,11 @@ func TestEventActionCommandEnvVars(t *testing.T) {
|
|||
envName := "MY_ENV"
|
||||
uploadScriptPath := filepath.Join(os.TempDir(), "upload.sh")
|
||||
|
||||
dataprovider.EnabledActionCommands = []string{uploadScriptPath}
|
||||
defer func() {
|
||||
dataprovider.EnabledActionCommands = nil
|
||||
}()
|
||||
|
||||
err := os.WriteFile(uploadScriptPath, getUploadScriptEnvContent(envName), 0755)
|
||||
assert.NoError(t, err)
|
||||
a1 := dataprovider.BaseEventAction{
|
||||
|
|
|
@ -59,7 +59,7 @@ var (
|
|||
ActionTypeDataRetentionCheck, ActionTypePasswordExpirationCheck, ActionTypeUserExpirationCheck,
|
||||
ActionTypeUserInactivityCheck, ActionTypeIDPAccountCheck, ActionTypeRotateLogs}
|
||||
// EnabledActionCommands defines the system commands that can be executed via EventManager,
|
||||
// an empty list means that any command is allowed to be executed.
|
||||
// an empty list means that no command is allowed to be executed.
|
||||
EnabledActionCommands []string
|
||||
)
|
||||
|
||||
|
@ -455,9 +455,6 @@ func (c *EventActionHTTPConfig) GetHTTPClient() *http.Client {
|
|||
|
||||
// IsActionCommandAllowed returns true if the specified command is allowed
|
||||
func IsActionCommandAllowed(cmd string) bool {
|
||||
if len(EnabledActionCommands) == 0 {
|
||||
return true
|
||||
}
|
||||
return slices.Contains(EnabledActionCommands, cmd)
|
||||
}
|
||||
|
||||
|
|
|
@ -1828,6 +1828,10 @@ func TestBasicActionRulesHandling(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
dataprovider.EnabledActionCommands = []string{a.Options.CmdConfig.Cmd}
|
||||
defer func() {
|
||||
dataprovider.EnabledActionCommands = nil
|
||||
}()
|
||||
_, _, err = httpdtest.UpdateEventAction(a, http.StatusOK)
|
||||
assert.NoError(t, err)
|
||||
// invalid type
|
||||
|
@ -2362,13 +2366,24 @@ func TestEventActionValidation(t *testing.T) {
|
|||
assert.NoError(t, err)
|
||||
assert.Contains(t, string(resp), "command is required")
|
||||
action.Options.CmdConfig.Cmd = "relative"
|
||||
dataprovider.EnabledActionCommands = []string{action.Options.CmdConfig.Cmd}
|
||||
defer func() {
|
||||
dataprovider.EnabledActionCommands = nil
|
||||
}()
|
||||
|
||||
_, resp, err = httpdtest.AddEventAction(action, http.StatusBadRequest)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, string(resp), "invalid command, it must be an absolute path")
|
||||
action.Options.CmdConfig.Cmd = filepath.Join(os.TempDir(), "cmd")
|
||||
_, resp, err = httpdtest.AddEventAction(action, http.StatusBadRequest)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, string(resp), "is not allowed")
|
||||
|
||||
dataprovider.EnabledActionCommands = []string{action.Options.CmdConfig.Cmd}
|
||||
_, resp, err = httpdtest.AddEventAction(action, http.StatusBadRequest)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, string(resp), "invalid command action timeout")
|
||||
|
||||
action.Options.CmdConfig.Timeout = 30
|
||||
action.Options.CmdConfig.EnvVars = []dataprovider.KeyValue{
|
||||
{
|
||||
|
@ -23318,6 +23333,10 @@ func TestWebEventAction(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
dataprovider.EnabledActionCommands = []string{action.Options.CmdConfig.Cmd}
|
||||
defer func() {
|
||||
dataprovider.EnabledActionCommands = nil
|
||||
}()
|
||||
form.Set("type", fmt.Sprintf("%d", action.Type))
|
||||
req, err = http.NewRequest(http.MethodPost, path.Join(webAdminEventActionPath, action.Name),
|
||||
bytes.NewBuffer([]byte(form.Encode())))
|
||||
|
|
|
@ -44,6 +44,11 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<div class="col-md-9">
|
||||
<select id="idType" name="type" class="form-select" data-control="i18n-select2" data-hide-search="true">
|
||||
{{- range .ActionTypes}}
|
||||
{{- if eq .Value 2}}
|
||||
{{- if not $.EnabledCommands}}
|
||||
{{- continue}}
|
||||
{{- end}}
|
||||
{{- end}}
|
||||
<option value="{{.Value}}" {{if eq $.Action.Type .Value }}selected{{end}} data-i18n="{{.Name}}"></option>
|
||||
{{- end}}
|
||||
</select>
|
||||
|
@ -400,21 +405,13 @@ explicit grant from the SFTPGo Team (support@sftpgo.com).
|
|||
<div class="form-group row action-type action-cmd mt-10">
|
||||
<label for="idCmdPath" data-i18n="actions.types.command" class="col-md-3 col-form-label">Command</label>
|
||||
<div class="col-md-9">
|
||||
<select id="idCmdPath" name="cmd_path" class="form-select" data-control="i18n-select2" data-hide-search="true">
|
||||
<select id="idCmdPath" name="cmd_path" class="form-select" data-control="i18n-select2" data-hide-search="false">
|
||||
{{- range .EnabledCommands}}
|
||||
<option value="{{.}}" {{if eq $.Action.Options.CmdConfig.Cmd . }}selected{{end}}>{{.}}</option>
|
||||
{{- end}}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{{- else}}
|
||||
<div class="form-group row action-type action-cmd mt-10">
|
||||
<label for="idCmdPath" data-i18n="actions.types.command" class="col-md-3 col-form-label">Command</label>
|
||||
<div class="col-md-9">
|
||||
<input id="idCmdPath" type="text" class="form-control" name="cmd_path" value="{{.Action.Options.CmdConfig.Cmd}}" aria-describedby="idCmdPathHelp" />
|
||||
<div id="idCmdPathHelp" class="form-text" data-i18n="actions.command_help"></div>
|
||||
</div>
|
||||
</div>
|
||||
{{- end}}
|
||||
|
||||
<div class="form-group row action-type action-cmd mt-10">
|
||||
|
|
Loading…
Reference in a new issue