package zsshrpc_server import ( "fmt" "golang.org/x/crypto/ssh" "net" "strings" ) type ZSshRpcServer struct { sshcfg *ssh.ServerConfig stopchan chan int logger SvrLogFunc ioBlockSize int OperationHandelr ZSshRpcOperationHandler } func NewZSshRpcServer(conf *ZSshRpcServerCfg) *ZSshRpcServer { o := &ZSshRpcServer{} o.sshcfg = &ssh.ServerConfig{ ServerVersion: "SSH-2.0-zSshRpcTest-1.0", NoClientAuth: conf.NoClientAuth, MaxAuthTries: conf.MaxAuthTries, PasswordCallback: conf.PasswordCallback, PublicKeyCallback: conf.PublicKeyCallback, KeyboardInteractiveCallback: conf.KeyboardInteractiveCallback, AuthLogCallback: conf.AuthLogCallback, } ciphers := []string{ "aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-gcm@openssh.com", "arcfour256", "arcfour128", } if conf.Support_AES128_CBC { ciphers = append(ciphers, "aes128-cbc") } o.sshcfg.Ciphers = ciphers o.sshcfg.AddHostKey(conf.HostKey) o.logger = conf.ServerLogger o.OperationHandelr = conf.OperationHandler o.ioBlockSize = conf.IOBlockSize return o } func (this *ZSshRpcServer) Stop() { this.stopchan <- 1 } func (this *ZSshRpcServer) StartWithListener(listener net.Listener) error { this.stopchan = make(chan int) go func() { <-this.stopchan listener.Close() }() go func() { for { nconn, err := listener.Accept() if err == nil { this.logger(SvrLogLevel_INFO, fmt.Sprintf("Client '%v' Come In.", nconn.RemoteAddr()), nil) go HandleNewSession(nconn, this.sshcfg, this.logger, this.OperationHandelr, this.ioBlockSize) } else { if strings.Contains(err.Error(), "use of closed network connection") { this.logger(SvrLogLevel_INFO, "Server Terminated By User.", err) } else { this.logger(SvrLogLevel_ERROR, fmt.Sprintf("Failed Handle Connection From Client '%v'", nconn.RemoteAddr()), err) } } } }() return nil } func (this *ZSshRpcServer) ListenTCP(network string, addr *net.TCPAddr) error { lis, err := net.ListenTCP(network, addr) if err != nil { return err } this.StartWithListener(lis) return nil }