From 31d285813e9afe5ef89f911d0b908a8d0f8bcb83 Mon Sep 17 00:00:00 2001 From: Nicola Murino Date: Wed, 4 Mar 2020 09:27:14 +0100 Subject: [PATCH] windows: try to escape trailing double quote in user input we try to remove the trailing double quote for user input such as this one sftpgo.exe serve -c "C:\ProgramData\SFTPGO\" the value for the -c flag is parsed as: C:\ProgramData\SFTPGO" this is what the user specified, but the user want this value: C:\ProgramData\SFTPGO so we try to remove the trailing double quote. Please note that we cannot do anything for something like this: -c "C:\ProgramData\SFTPGO\" -l "sftpgo.log" in this case the -l flag will be ignored and the value for the c flag is: C:\ProgramData\SFTPGO" -l sftpgo.log and so probably it is invalid. This is definitely a bad user input --- cmd/initprovider.go | 5 ++--- cmd/install_windows.go | 4 ++-- cmd/portable.go | 2 +- cmd/root.go | 8 ++------ cmd/serve.go | 5 ++--- cmd/start_windows.go | 2 +- sftpgo.iss | 4 ++-- utils/utils.go | 17 +++++++++++++++++ 8 files changed, 29 insertions(+), 18 deletions(-) diff --git a/cmd/initprovider.go b/cmd/initprovider.go index 3a690fc3..d411327f 100644 --- a/cmd/initprovider.go +++ b/cmd/initprovider.go @@ -1,11 +1,10 @@ package cmd import ( - "path/filepath" - "github.com/drakkan/sftpgo/config" "github.com/drakkan/sftpgo/dataprovider" "github.com/drakkan/sftpgo/logger" + "github.com/drakkan/sftpgo/utils" "github.com/rs/zerolog" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -31,7 +30,7 @@ Please take a look at the usage below to customize the options.`, Run: func(cmd *cobra.Command, args []string) { logger.DisableLogger() logger.EnableConsoleLogger(zerolog.DebugLevel) - configDir = filepath.Clean(configDir) + configDir = utils.CleanDirInput(configDir) config.LoadConfig(configDir, configFile) providerConf := config.GetProviderConf() logger.DebugToConsole("Initializing provider: %#v config file: %#v", providerConf.Driver, viper.ConfigFileUsed()) diff --git a/cmd/install_windows.go b/cmd/install_windows.go index b2c89be2..b387bdaa 100644 --- a/cmd/install_windows.go +++ b/cmd/install_windows.go @@ -2,9 +2,9 @@ package cmd import ( "fmt" - "path/filepath" "github.com/drakkan/sftpgo/service" + "github.com/drakkan/sftpgo/utils" "github.com/spf13/cobra" ) @@ -19,7 +19,7 @@ sftpgo service install Please take a look at the usage below to customize the startup options`, Run: func(cmd *cobra.Command, args []string) { s := service.Service{ - ConfigDir: filepath.Clean(configDir), + ConfigDir: utils.CleanDirInput(configDir), ConfigFile: configFile, LogFilePath: logFilePath, LogMaxSize: logMaxSize, diff --git a/cmd/portable.go b/cmd/portable.go index 1f8a1355..b03ff350 100644 --- a/cmd/portable.go +++ b/cmd/portable.go @@ -138,7 +138,7 @@ func init() { portableCmd.Flags().BoolVarP(&portableAdvertiseService, "advertise-service", "S", true, "Advertise SFTP service using multicast DNS") portableCmd.Flags().BoolVarP(&portableAdvertiseCredentials, "advertise-credentials", "C", false, - "If the SFTP service is advertised via multicast DNS this flag allows to put username/password inside the advertised TXT record") + "If the SFTP service is advertised via multicast DNS, this flag allows to put username/password inside the advertised TXT record") portableCmd.Flags().IntVarP(&portableFsProvider, "fs-provider", "f", 0, "0 means local filesystem, 1 Amazon S3 compatible, "+ "2 Google Cloud Storage") portableCmd.Flags().StringVar(&portableS3Bucket, "s3-bucket", "", "") diff --git a/cmd/root.go b/cmd/root.go index 01c6e2f4..4785edc4 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -4,7 +4,6 @@ package cmd import ( "fmt" "os" - "path/filepath" "strconv" "github.com/drakkan/sftpgo/config" @@ -141,7 +140,7 @@ func addServeFlags(cmd *cobra.Command) { func getCustomServeFlags() []string { result := []string{} if configDir != defaultConfigDir { - configDir = filepath.Clean(configDir) + configDir = utils.CleanDirInput(configDir) result = append(result, "--"+configDirFlag) result = append(result, configDir) } @@ -149,10 +148,7 @@ func getCustomServeFlags() []string { result = append(result, "--"+configFileFlag) result = append(result, configFile) } - if logFilePath != defaultLogFile && utils.IsFileInputValid(logFilePath) { - if !filepath.IsAbs(logFilePath) { - logFilePath = filepath.Join(configDir, logFilePath) - } + if logFilePath != defaultLogFile { result = append(result, "--"+logFilePathFlag) result = append(result, logFilePath) } diff --git a/cmd/serve.go b/cmd/serve.go index 85112ce0..c2d7ff07 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -1,9 +1,8 @@ package cmd import ( - "path/filepath" - "github.com/drakkan/sftpgo/service" + "github.com/drakkan/sftpgo/utils" "github.com/spf13/cobra" ) @@ -18,7 +17,7 @@ sftpgo serve Please take a look at the usage below to customize the startup options`, Run: func(cmd *cobra.Command, args []string) { service := service.Service{ - ConfigDir: filepath.Clean(configDir), + ConfigDir: utils.CleanDirInput(configDir), ConfigFile: configFile, LogFilePath: logFilePath, LogMaxSize: logMaxSize, diff --git a/cmd/start_windows.go b/cmd/start_windows.go index e68f3599..7384aef8 100644 --- a/cmd/start_windows.go +++ b/cmd/start_windows.go @@ -14,7 +14,7 @@ var ( Use: "start", Short: "Start SFTPGo Windows Service", Run: func(cmd *cobra.Command, args []string) { - configDir = filepath.Clean(configDir) + configDir = utils.CleanDirInput(configDir) if !filepath.IsAbs(logFilePath) && utils.IsFileInputValid(logFilePath) { logFilePath = filepath.Join(configDir, logFilePath) } diff --git a/sftpgo.iss b/sftpgo.iss index b74365f3..f82ee13b 100644 --- a/sftpgo.iss +++ b/sftpgo.iss @@ -2,7 +2,7 @@ ; You need to change the paths for the source files to match your environment #define MyAppName "SFTPGo" -#define MyAppVersion "0.9.5-dev" +#define MyAppVersion "0.9.5.1" #define MyAppURL "https://github.com/drakkan/sftpgo" #define MyAppExeName "sftpgo.exe" #define MyAppDir "C:\Users\vbox\Desktop\sftpgo_setup" @@ -63,7 +63,7 @@ Name: "{group}\{cm:UninstallProgram,{#MyAppName}}"; Filename: "{uninstallexe}" [Run] Filename: "netsh"; Parameters: "advfirewall firewall delete rule name=""SFTPGo Service"""; Flags: runhidden Filename: "netsh"; Parameters: "advfirewall firewall add rule name=""SFTPGo Service"" dir=in action=allow program=""{app}\{#MyAppExeName}"""; Flags: runhidden -Filename: "{app}\{#MyAppExeName}"; Parameters: "service install -c ""{commonappdata}\{#MyAppName}"" -l ""{commonappdata}\{#MyAppName}\logs\sftpgo.log"""; Description: "Install SFTPGo Windows Service"; Flags: runhidden +Filename: "{app}\{#MyAppExeName}"; Parameters: "service install -c ""{commonappdata}\{#MyAppName}"" -l ""logs\sftpgo.log"""; Description: "Install SFTPGo Windows Service"; Flags: runhidden Filename: "{app}\{#MyAppExeName}"; Parameters: "service start"; Description: "Start SFTPGo Windows Service"; Flags: runhidden [UninstallRun] diff --git a/utils/utils.go b/utils/utils.go index 4b7c547d..2ecbfba4 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -20,6 +20,7 @@ import ( "os" "path" "path/filepath" + "runtime" "strings" "time" @@ -299,3 +300,19 @@ func IsFileInputValid(fileInput string) bool { } return true } + +// CleanDirInput sanitizes user input for directories. +// On Windows it removes any trailing `"`. +// We try to help windows users that set an invalid path such as "C:\ProgramData\SFTPGO\". +// This will only help if the invalid path is the last argument, for example in this command: +// sftpgo.exe serve -c "C:\ProgramData\SFTPGO\" -l "sftpgo.log" +// the -l flag will be ignored and the -c flag will get the value `C:\ProgramData\SFTPGO" -l sftpgo.log` +// since the backslash after SFTPGO escape the double quote. This is definitely a bad user input +func CleanDirInput(dirInput string) string { + if runtime.GOOS == "windows" { + for strings.HasSuffix(dirInput, "\"") { + dirInput = strings.TrimSuffix(dirInput, "\"") + } + } + return filepath.Clean(dirInput) +}