add new test cases

This commit is contained in:
Nicola Murino 2019-07-31 14:11:44 +02:00
parent 2a8ab620f3
commit 89986b9305
4 changed files with 98 additions and 32 deletions

View file

@ -52,7 +52,7 @@ func TestMain(m *testing.M) {
configDir := ".." configDir := ".."
logfilePath := filepath.Join(configDir, "sftpgo_api_test.log") logfilePath := filepath.Join(configDir, "sftpgo_api_test.log")
confName := "sftpgo.conf" confName := "sftpgo.conf"
logger.InitLogger(logfilePath, zerolog.DebugLevel) logger.InitLogger(logfilePath, 5, 1, 28, false, zerolog.DebugLevel)
configFilePath := filepath.Join(configDir, confName) configFilePath := filepath.Join(configDir, confName)
config.LoadConfig(configFilePath) config.LoadConfig(configFilePath)
providerConf := config.GetProviderConf() providerConf := config.GetProviderConf()
@ -630,11 +630,11 @@ func waitTCPListening(address string) {
for { for {
conn, err := net.Dial("tcp", address) conn, err := net.Dial("tcp", address)
if err != nil { if err != nil {
fmt.Printf("tcp server %v not listening: %v\n", address, err) logger.WarnToConsole("tcp server %v not listening: %v\n", address, err)
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
continue continue
} }
fmt.Printf("tcp server %v now listening\n", address) logger.InfoToConsole("tcp server %v now listening\n", address)
defer conn.Close() defer conn.Close()
break break
} }

View file

@ -12,6 +12,7 @@ import (
"time" "time"
"github.com/drakkan/sftpgo/dataprovider" "github.com/drakkan/sftpgo/dataprovider"
"github.com/drakkan/sftpgo/logger"
"github.com/drakkan/sftpgo/sftpd" "github.com/drakkan/sftpgo/sftpd"
"github.com/drakkan/sftpgo/utils" "github.com/drakkan/sftpgo/utils"
"github.com/go-chi/render" "github.com/go-chi/render"
@ -186,7 +187,7 @@ func checkResponse(actual int, expected int, resp *http.Response) error {
if expected != http.StatusOK && resp != nil { if expected != http.StatusOK && resp != nil {
b, err := ioutil.ReadAll(resp.Body) b, err := ioutil.ReadAll(resp.Body)
if err == nil { if err == nil {
fmt.Printf("request: %v, response body: %v", resp.Request.URL, string(b)) logger.InfoToConsole("request: %v, response body: %v", resp.Request.URL, string(b))
} }
} }
return nil return nil

View file

@ -54,7 +54,6 @@ func (c Configuration) Initialize(configDir string) error {
logger.Warn(logSender, "error reading umask, please fix your config file: %v", err) logger.Warn(logSender, "error reading umask, please fix your config file: %v", err)
logger.WarnToConsole("error reading umask, please fix your config file: %v", err) logger.WarnToConsole("error reading umask, please fix your config file: %v", err)
} }
actions = c.Actions
serverConfig := &ssh.ServerConfig{ serverConfig := &ssh.ServerConfig{
NoClientAuth: false, NoClientAuth: false,
MaxAuthTries: c.MaxAuthTries, MaxAuthTries: c.MaxAuthTries,
@ -106,6 +105,7 @@ func (c Configuration) Initialize(configDir string) error {
return err return err
} }
actions = c.Actions
logger.Info(logSender, "server listener registered address: %v", listener.Addr().String()) logger.Info(logSender, "server listener registered address: %v", listener.Addr().String())
if c.IdleTimeout > 0 { if c.IdleTimeout > 0 {
startIdleTimer(time.Duration(c.IdleTimeout) * time.Minute) startIdleTimer(time.Duration(c.IdleTimeout) * time.Minute)

View file

@ -29,12 +29,13 @@ import (
) )
const ( const (
logSender = "sftpdTesting" logSender = "sftpdTesting"
sftpServerAddr = "127.0.0.1:2022" sftpServerAddr = "127.0.0.1:2022"
defaultUsername = "test_user_sftp" defaultUsername = "test_user_sftp"
defaultPassword = "test_password" defaultPassword = "test_password"
testPubKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC03jj0D+djk7pxIf/0OhrxrchJTRZklofJ1NoIu4752Sq02mdXmarMVsqJ1cAjV5LBVy3D1F5U6XW4rppkXeVtd04Pxb09ehtH0pRRPaoHHlALiJt8CoMpbKYMA8b3KXPPriGxgGomvtU2T2RMURSwOZbMtpsugfjYSWenyYX+VORYhylWnSXL961LTyC21ehd6d6QnW9G7E5hYMITMY9TuQZz3bROYzXiTsgN0+g6Hn7exFQp50p45StUMfV/SftCMdCxlxuyGny2CrN/vfjO7xxOo2uv7q1qm10Q46KPWJQv+pgZ/OfL+EDjy07n5QVSKHlbx+2nT4Q0EgOSQaCTYwn3YjtABfIxWwgAFdyj6YlPulCL22qU4MYhDcA6PSBwDdf8hvxBfvsiHdM+JcSHvv8/VeJhk6CmnZxGY0fxBupov27z3yEO8nAg8k+6PaUiW1MSUfuGMF/ktB8LOstXsEPXSszuyXiOv4DaryOXUiSn7bmRqKcEFlJusO6aZP0= nicola@p1" testPubKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC03jj0D+djk7pxIf/0OhrxrchJTRZklofJ1NoIu4752Sq02mdXmarMVsqJ1cAjV5LBVy3D1F5U6XW4rppkXeVtd04Pxb09ehtH0pRRPaoHHlALiJt8CoMpbKYMA8b3KXPPriGxgGomvtU2T2RMURSwOZbMtpsugfjYSWenyYX+VORYhylWnSXL961LTyC21ehd6d6QnW9G7E5hYMITMY9TuQZz3bROYzXiTsgN0+g6Hn7exFQp50p45StUMfV/SftCMdCxlxuyGny2CrN/vfjO7xxOo2uv7q1qm10Q46KPWJQv+pgZ/OfL+EDjy07n5QVSKHlbx+2nT4Q0EgOSQaCTYwn3YjtABfIxWwgAFdyj6YlPulCL22qU4MYhDcA6PSBwDdf8hvxBfvsiHdM+JcSHvv8/VeJhk6CmnZxGY0fxBupov27z3yEO8nAg8k+6PaUiW1MSUfuGMF/ktB8LOstXsEPXSszuyXiOv4DaryOXUiSn7bmRqKcEFlJusO6aZP0= nicola@p1"
testPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY----- testInvalidPublicKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCd60+/j+y8f0tLftihWV1YN9RSahMI9btQMDIMqts/jeNbD8jgoogM3nhF7KxfcaMKURuD47KC4Ey6iAJUJ0sWkSNNxOcIYuvA+5MlspfZDsa8Ag76Fe1vyz72WeHMHMeh/hwFo2TeIeIXg480T1VI6mzfDrVp2GzUx0SS0dMsQBjftXkuVR8YOiOwMCAH2a//M1OrvV7d/NBk6kBN0WnuIBb2jKm15PAA7+jQQG7tzwk2HedNH3jeL5GH31xkSRwlBczRK0xsCQXehAlx6cT/e/s44iJcJTHfpPKoSk6UAhPJYe7Z1QnuoawY9P9jQaxpyeImBZxxUEowhjpj2avBxKdRGBVK8R7EL8tSOeLbhdyWe5Mwc1+foEbq9Zz5j5Kd+hn3Wm1UnsGCrXUUUoZp1jnlNl0NakCto+5KmqnT9cHxaY+ix2RLUWAZyVFlRq71OYux1UHJnEJPiEI1/tr4jFBSL46qhQZv/TfpkfVW8FLz0lErfqu0gQEZnNHr3Fc= nicola@p1"
testPrivateKey = `-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAtN449A/nY5O6cSH/9Doa8a3ISU0WZJaHydTaCLuO+dkqtNpnV5mq NhAAAAAwEAAQAAAYEAtN449A/nY5O6cSH/9Doa8a3ISU0WZJaHydTaCLuO+dkqtNpnV5mq
zFbKidXAI1eSwVctw9ReVOl1uK6aZF3lbXdOD8W9PXobR9KUUT2qBx5QC4ibfAqDKWymDA zFbKidXAI1eSwVctw9ReVOl1uK6aZF3lbXdOD8W9PXobR9KUUT2qBx5QC4ibfAqDKWymDA
@ -72,19 +73,19 @@ NbbCNsVroqKlChT5wyPNGS+phi2bPARBno7WSDvshTZ7dAVEP2c9MJW0XwoSevwKlhgSdt
RLFFQ/5nclJSdzPBOmQouC0OBcMFSrYtMeknJ4VvueVvve5HcHFaEsaMc7ABAGaLYaBQOm RLFFQ/5nclJSdzPBOmQouC0OBcMFSrYtMeknJ4VvueVvve5HcHFaEsaMc7ABAGaLYaBQOm
iixITGvaNZh/tjAAAACW5pY29sYUBwMQE= iixITGvaNZh/tjAAAACW5pY29sYUBwMQE=
-----END OPENSSH PRIVATE KEY-----` -----END OPENSSH PRIVATE KEY-----`
configDir = ".."
confName = "sftpgo.conf"
) )
var ( var (
allPerms = []string{dataprovider.PermAny} allPerms = []string{dataprovider.PermAny}
homeBasePath string homeBasePath string
configFilePath = filepath.Join(configDir, confName)
) )
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
configDir := ".."
logfilePath := filepath.Join(configDir, "sftpgo_sftpd_test.log") logfilePath := filepath.Join(configDir, "sftpgo_sftpd_test.log")
confName := "sftpgo.conf" logger.InitLogger(logfilePath, 5, 1, 28, false, zerolog.DebugLevel)
logger.InitLogger(logfilePath, zerolog.DebugLevel)
configFilePath := filepath.Join(configDir, confName)
config.LoadConfig(configFilePath) config.LoadConfig(configFilePath)
providerConf := config.GetProviderConf() providerConf := config.GetProviderConf()
@ -101,7 +102,7 @@ func TestMain(m *testing.M) {
homeBasePath = "C:\\" homeBasePath = "C:\\"
} else { } else {
homeBasePath = "/tmp" homeBasePath = "/tmp"
sftpdConf.Actions.ExecuteOn = []string{"download", "upload", "delete"} sftpdConf.Actions.ExecuteOn = []string{"download", "upload", "rename"}
sftpdConf.Actions.Command = "/bin/true" sftpdConf.Actions.Command = "/bin/true"
sftpdConf.Actions.HTTPNotificationURL = "http://127.0.0.1:8080/" sftpdConf.Actions.HTTPNotificationURL = "http://127.0.0.1:8080/"
} }
@ -138,6 +139,16 @@ func TestMain(m *testing.M) {
os.Exit(exitCode) os.Exit(exitCode)
} }
func TestInitialization(t *testing.T) {
config.LoadConfig(configFilePath)
sftpdConf := config.GetSFTPDConfig()
sftpdConf.Umask = "invalid umask"
err := sftpdConf.Initialize(configDir)
if err == nil {
t.Errorf("Inizialize must fail, a SFTP server should be already running")
}
}
func TestBasicSFTPHandling(t *testing.T) { func TestBasicSFTPHandling(t *testing.T) {
usePubKey := false usePubKey := false
user, err := api.AddUser(getTestUser(usePubKey), http.StatusOK) user, err := api.AddUser(getTestUser(usePubKey), http.StatusOK)
@ -450,26 +461,50 @@ func TestHomeSpecialChars(t *testing.T) {
} }
} }
func TestLoginPubKey(t *testing.T) { func TestLogin(t *testing.T) {
usePubKey := true u := getTestUser(false)
user, err := api.AddUser(getTestUser(usePubKey), http.StatusOK) u.PublicKey = testPubKey
user, err := api.AddUser(u, http.StatusOK)
if err != nil { if err != nil {
t.Errorf("unable to add user: %v", err) t.Errorf("unable to add user: %v", err)
} }
client, err := getSftpClient(user, usePubKey) client, err := getSftpClient(user, false)
if err != nil { if err != nil {
t.Errorf("unable to create sftp client: %v", err) t.Errorf("unable to create sftp client: %v", err)
} else { } else {
defer client.Close() defer client.Close()
_, err := client.Getwd() _, err := client.Getwd()
if err != nil { if err != nil {
t.Errorf("unable to get working dir: %v", err) t.Errorf("sftp client with valid password must work")
} }
_, err = client.ReadDir(".") }
client, err = getSftpClient(user, true)
if err != nil {
t.Errorf("unable to create sftp client: %v", err)
} else {
defer client.Close()
_, err := client.Getwd()
if err != nil { if err != nil {
t.Errorf("unable to read remote dir: %v", err) t.Errorf("sftp client with valid public key must work")
} }
} }
user.Password = "invalid password"
client, err = getSftpClient(user, false)
if err == nil {
t.Errorf("login with invalid password must fail")
defer client.Close()
}
user.PublicKey = testInvalidPublicKey
user.Password = ""
_, err = api.UpdateUser(user, http.StatusOK)
if err != nil {
t.Errorf("unable to update user: %v", err)
}
client, err = getSftpClient(user, true)
if err == nil {
t.Errorf("login with invalid public key must fail")
defer client.Close()
}
err = api.RemoveUser(user, http.StatusOK) err = api.RemoveUser(user, http.StatusOK)
if err != nil { if err != nil {
t.Errorf("unable to remove user: %v", err) t.Errorf("unable to remove user: %v", err)
@ -580,16 +615,16 @@ func TestQuotaFileReplace(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("unable to add user: %v", err) t.Errorf("unable to add user: %v", err)
} }
testFileSize := int64(65535)
testFileName := "test_file.dat"
testFilePath := filepath.Join(homeBasePath, testFileName)
client, err := getSftpClient(user, usePubKey) client, err := getSftpClient(user, usePubKey)
if err != nil { if err != nil {
t.Errorf("unable to create sftp client: %v", err) t.Errorf("unable to create sftp client: %v", err)
} else { } else {
defer client.Close() defer client.Close()
testFileSize := int64(65535)
expectedQuotaSize := user.UsedQuotaSize + testFileSize expectedQuotaSize := user.UsedQuotaSize + testFileSize
expectedQuotaFiles := user.UsedQuotaFiles + 1 expectedQuotaFiles := user.UsedQuotaFiles + 1
testFileName := "test_file.dat"
testFilePath := filepath.Join(homeBasePath, testFileName)
err = createTestFile(testFilePath, testFileSize) err = createTestFile(testFilePath, testFileSize)
if err != nil { if err != nil {
t.Errorf("unable to create test file: %v", err) t.Errorf("unable to create test file: %v", err)
@ -623,6 +658,21 @@ func TestQuotaFileReplace(t *testing.T) {
if expectedQuotaSize != user.UsedQuotaSize { if expectedQuotaSize != user.UsedQuotaSize {
t.Errorf("quota size does not match, expected: %v, actual: %v", expectedQuotaSize, user.UsedQuotaSize) t.Errorf("quota size does not match, expected: %v, actual: %v", expectedQuotaSize, user.UsedQuotaSize)
} }
}
// now set a quota size restriction and upload the same fail, upload should fail for space limit exceeded
user.QuotaSize = testFileSize - 1
user, err = api.UpdateUser(user, http.StatusOK)
if err != nil {
t.Errorf("error updating user: %v", err)
}
client, err = getSftpClient(user, usePubKey)
if err != nil {
t.Errorf("unable to create sftp client: %v", err)
} else {
err = sftpUploadFile(testFilePath, testFileName, testFileSize, client)
if err == nil {
t.Errorf("quota size exceeded, file upload must fail")
}
err = client.Remove(testFileName) err = client.Remove(testFileName)
if err != nil { if err != nil {
t.Errorf("error removing uploaded file: %v", err) t.Errorf("error removing uploaded file: %v", err)
@ -1094,11 +1144,11 @@ func waitTCPListening(address string) {
for { for {
conn, err := net.Dial("tcp", address) conn, err := net.Dial("tcp", address)
if err != nil { if err != nil {
fmt.Printf("tcp server %v not listening: %v\n", address, err) logger.WarnToConsole("tcp server %v not listening: %v\n", address, err)
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
continue continue
} }
fmt.Printf("tcp server %v now listening\n", address) logger.InfoToConsole("tcp server %v now listening\n", address)
defer conn.Close() defer conn.Close()
break break
} }
@ -1148,10 +1198,21 @@ func doSSH(user dataprovider.User, usePubKey bool) error {
return err return err
} }
func modifyConf(sftpdConf sftpd.Configuration) {
if runtime.GOOS == "windows" {
homeBasePath = "C:\\"
} else {
homeBasePath = "/tmp"
sftpdConf.Actions.ExecuteOn = []string{"download", "upload", "rename"}
sftpdConf.Actions.Command = "/bin/true"
sftpdConf.Actions.HTTPNotificationURL = "http://127.0.0.1:8080/"
}
}
func getSftpClient(user dataprovider.User, usePubKey bool) (*sftp.Client, error) { func getSftpClient(user dataprovider.User, usePubKey bool) (*sftp.Client, error) {
var sftpClient *sftp.Client var sftpClient *sftp.Client
config := &ssh.ClientConfig{ config := &ssh.ClientConfig{
User: defaultUsername, User: user.Username,
HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error { HostKeyCallback: func(hostname string, remote net.Addr, key ssh.PublicKey) error {
return nil return nil
}, },
@ -1163,7 +1224,11 @@ func getSftpClient(user dataprovider.User, usePubKey bool) (*sftp.Client, error)
} }
config.Auth = []ssh.AuthMethod{ssh.PublicKeys(key)} config.Auth = []ssh.AuthMethod{ssh.PublicKeys(key)}
} else { } else {
config.Auth = []ssh.AuthMethod{ssh.Password(defaultPassword)} if len(user.Password) > 0 {
config.Auth = []ssh.AuthMethod{ssh.Password(user.Password)}
} else {
config.Auth = []ssh.AuthMethod{ssh.Password(defaultPassword)}
}
} }
conn, err := ssh.Dial("tcp", sftpServerAddr, config) conn, err := ssh.Dial("tcp", sftpServerAddr, config)
if err != nil { if err != nil {