ssh commands: fix parsing commands with space

For now we support "\" escaping style
This commit is contained in:
Nicola Murino 2020-02-08 23:33:06 +01:00
parent d6fa853a37
commit 7bfe0ddf80
4 changed files with 32 additions and 4 deletions

View file

@ -301,7 +301,7 @@ sftpgo initprovider --help
The `initprovider` command is enough for new installations. From now on, the database structure will be automatically checked and updated, if required, at startup.
If you are upgrading from version 0.9.5 or before you have to manually execute the SQL scripts to create the required database structure.Theese script can be found inside the source tree [sql](./sql "sql") directory. The SQL scripts filename is, by convention, the date as `YYYYMMDD` and the suffix `.sql`. You need to apply all the SQL scripts for your database ordered by name, for example `20190828.sql` must be applied before `20191112.sql` and so on.
If you are upgrading from version 0.9.5 or before you have to manually execute the SQL scripts to create the required database structure.These script can be found inside the source tree [sql](./sql "sql") directory. The SQL scripts filename is, by convention, the date as `YYYYMMDD` and the suffix `.sql`. You need to apply all the SQL scripts for your database ordered by name, for example `20190828.sql` must be applied before `20191112.sql` and so on.
Example for SQLite: `find sql/sqlite/ -type f -iname '*.sql' -print | sort -n | xargs cat | sqlite3 sftpgo.db`.
After applying these scripts your database structure is the same as the one obtained using `initprovider` for new installations, so from now on you don't have to manually upgrade your database anymore.

View file

@ -628,6 +628,25 @@ func TestSSHCommandPath(t *testing.T) {
if path != "/" {
t.Errorf("unexpected path: %v", path)
}
sshCommand.args = []string{"-f", "/a space.txt"}
path = sshCommand.getDestPath()
if path != "/a space.txt" {
t.Errorf("unexpected path: %v", path)
}
}
func TestSSHParseCommandPayload(t *testing.T) {
cmd := "command -a -f some\\ spaces\\ \\ .txt"
name, args, _ := parseCommandPayload(cmd)
if name != "command" {
t.Errorf("unexpected command: %v", name)
}
if len(args) != 3 {
t.Errorf("unexpected number of arguments %v/3", len(args))
}
if !utils.IsStringInSlice("some spaces .txt", args) {
t.Errorf("command parsing error, expected arguments not found: %v", args)
}
}
func TestSSHCommandErrors(t *testing.T) {

View file

@ -56,6 +56,7 @@ func (c *scpCommand) handle() error {
}
} else {
err = fmt.Errorf("scp command not supported, args: %v", c.args)
c.connection.Log(logger.LevelDebug, logSenderSCP, "unsupported scp command, args: %v", c.args)
}
c.sendExitStatus(err)
return err

View file

@ -45,7 +45,7 @@ type systemCommand struct {
func processSSHCommand(payload []byte, connection *Connection, channel ssh.Channel, enabledSSHCommands []string) bool {
var msg sshSubsystemExecMsg
if err := ssh.Unmarshal(payload, &msg); err == nil {
name, args, err := parseCommandPayload(msg.Command)
name, args, err := parseCommandPayload(strings.TrimSpace(msg.Command))
connection.Log(logger.LevelDebug, logSenderSSH, "new ssh command: %#v args: %v user: %v, error: %v",
name, args, connection.User.Username, err)
if err == nil && utils.IsStringInSlice(name, enabledSSHCommands) {
@ -421,9 +421,17 @@ func computeHashForFile(hasher hash.Hash, path string) (string, error) {
}
func parseCommandPayload(command string) (string, []string, error) {
parts := strings.Split(command, " ")
parts := strings.Split(strings.ReplaceAll(command, "\\ ", "\\"), " ")
if len(parts) < 2 {
return parts[0], []string{}, nil
}
return parts[0], parts[1:], nil
args := []string{}
for _, arg := range parts[1:] {
parsed := strings.TrimSpace(strings.ReplaceAll(arg, "\\", " "))
if len(parsed) == 0 {
continue
}
args = append(args, parsed)
}
return parts[0], args, nil
}