func startTestSftpServer(port int, login string, password string, pubKeyRsa string, isDebug bool) (net.Listener, string, int) {
	debugStream := ioutil.Discard
	if isDebug {
		debugStream = os.Stderr
	}
	listener, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%v", port))
	if err != nil {
		panic(err)
	}
	host, portStr, err := net.SplitHostPort(listener.Addr().String())
	if err != nil {
		panic(err)
	}
	port, err = strconv.Atoi(portStr)
	if err != nil {
		panic(err)
	}
	config := &ssh.ServerConfig{}
	if login != "" {
		config.PasswordCallback = func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) {
			fmt.Fprintf(debugStream, "Login: %s\n", c.User())
			if c.User() == login && string(pass) == password {
				return nil, nil
			}
			return nil, fmt.Errorf("password rejected for %q", c.User())
		}
	}
	if pubKeyRsa != "" {
		config.PublicKeyCallback = func(c ssh.ConnMetadata, pubKey ssh.PublicKey) (*ssh.Permissions, error) {
			pubKeyParsed, _, _, _, err := ssh.ParseAuthorizedKey([]byte(pubKeyRsa))
			if err != nil {
				log.Fatal(err)
			}
			expected := pubKeyParsed.Marshal()
			fact := pubKey.Marshal()
			if bytes.Equal(expected, fact) {
				return nil, nil
			}
			return nil, fmt.Errorf("unknown public key for %q", c.User())
		}
	}
	private, err := ssh.ParsePrivateKey([]byte(`-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAkTMV7QOcMKwJj8g9CLr5p09TP82lu8F/nfs3csK6Ft2vfev0
GJKAZAaIk3BjdQzOKeT7bpXdbofjF6NGEOgqG7IneKIuDNlt6Rr/pnQtwtFlq8iH
Qzj2kjkMN7AoHvcQ2O/FJD5I494E2Emn/CdreX1QSUIzZCfox4IQH/Iygwd28+zT
+IZgVLLyqB9xogYqRtY/aCRPFlXsVll5b9yYI5Po2Ztm3GKHR725PFC+gNZkqaL6
IO4qWJzZ+m6WWyFn+2cLs2AAz/FWDEeiGyrSbbkDxRG65OibuIexE26rl6FFxUtO
iHxe11WKHxvIMfTIXbwn/9E0ijbFkjQ9np2JMQIDAQABAoIBACyqSlReh+1w/n/8
WMoWujV9cV5vJExdeaRfYu8qd5QRHareqnfkmRor6FdyeyXGiqTYi3+5GiSmKHVd
BHCu+kUKyJmTShcpy2WpqHrLwkfrohr11KYZH8BbTCbVSYI8/jG9kCdWAZYW9eaS
wdoPRkBZDBl9A9ILdM/qcothNaiYaj4ex1BE8H8zOfE06kuS3wWuWD/rOKTKIj1L
2UlTAzY+VKATctcTqjwmbCBuTM9/74QlcuekyYuL5kb4Tp5vfO/hy71XgjCVpAjC
/OvKIb1DzJ4d1A6WaGiQ09bMeoE7j0+sUpwOZpXV1PBa328iZeFWCymSJZgFwae8
B8VAwwECgYEA649O0vuCus0l1NfYqUv4DBzXodceQE/z+jEDtMtc0g2YEKkTkvbJ
BFBXh6SUWGu6maRd56VFCUu7S6l7zmWpxVY7WixMh+tLTdzem1aPoy770PnYVgIq
oE1n+wdbT9an2Xm8RyQc4rN0DRki2JjlYYKQEnc2uN/Yo3NzgoqgEZ8CgYEAncyH
LebqcXbX+MeN82coZV6mdsg+OnUT1mt0XSk4GN0TRlSX12ucvue/FD+hAVX2a+IO
vCu3Ig/cDAt7Ck+zbWvkO0p9IQTamHWel6WiU7j61oc7Me80wBrAq8qmPLJ4zn0w
Ug3OyoMDFBtO4aeqXD5fiCEEwQWm8zf51EFkky8CgYEAo7hxArcIf6kCOFLlJZXF
izWosbWAMxbe7e+PMeN+WghUvo+lKSoZQMROcdpzuJj3kr3o/o2h0/os7UOY5zVF
sABlNCFB994T8sQmfDTHlJWdM/vS3sSWt9/U+2Z7kpwRAVhZAeEZqn8rk8b6ryxl
kUZbuFnfUNNUERa3G+4ZnuUCgYEAi+MuyyB0IVYLq72sN2TxyLuZsp9dmxEDHwhv
Rc8urcv+NFD1ssDxWcOz/s1RfA+qvoTOLz5JwOZyWjMrRj7Vf2EwGOe1+bmF17Yd
e64YM0Q/CkMj1OaLyulseF7T8+b7dYJBfdxDv/9YkVCMIzsxqUiaA+HRhxPtppuu
292EvX0CgYBtBjuCeEbNSMN8b9OHYHBexTqBkx8nDHTNW61R7cBo6gH30jAKmLSm
5uA1MemHJXEFtYm42g9fVai6ydWLSb44WISID1G5oF+/Nh/1j93aGSBBzFXq9ccH
MMpP/Pinco5UsoxgxQYBFD2HgGWt3FEuTG5p1ACmsDvl7MnXOJgmRQ==
-----END RSA PRIVATE KEY-----`))
	if err != nil {
		log.Fatal("Failed to parse private key", err)
	}
	config.AddHostKey(private)
	go func() {
		for {
			conn, err := listener.Accept()
			if err != nil {
				fmt.Fprintf(debugStream, "ssh server socket closed: %v\n", err)
				break
			}
			go func() {
				defer conn.Close()
				sshSvr, err := sshServerFromConn(conn, config, debugStream)
				if err != nil {
					fmt.Fprintf(debugStream, "ssh server error: %v\n", err)
					return
				}
				err = sshSvr.Wait()
				fmt.Fprintf(debugStream, "ssh server finished, err: %v\n", err)
			}()
		}
	}()
	return listener, host, port
}
starts an ssh server to test. returns: host string and port
package sftp
import (
	"bytes"
	"encoding/hex"
	"github.com/pkg/sftp"
	"io"
	"io/ioutil"
	"log"
	"fmt"
	"net"
	"os"
	"strconv"
	"strings"
	"golang.org/x/crypto/ssh"
)