func handleSshConnection(sConn *ssh.ServerConn, msgchan chan<- text.Message, addchan chan<- Client, rmchan chan<- net.Conn) { defer sConn.Close() for { ch, err := sConn.Accept() if err == io.EOF { return } if err != nil { log.Println("handleServerConn Accept:", err) break } if ch.ChannelType() != "session" { ch.Reject(ssh.UnknownChannelType, "unknown channel type") break } log.Println("Client version:", string(sConn.ClientVersion)) // Create terminal term := terminal.NewTerminal(ch, "") serverTerm := &ssh.ServerTerminal{ Term: term, Channel: ch, } ch.Accept() go handleConnection(sConn, serverTerm, term, msgchan, addchan, rmchan) } }
func handleServerConn(sConn *ssh.ServerConn) { defer sConn.Close() for { // Accept reads from the connection, demultiplexes packets // to their corresponding channels and returns when a new // channel request is seen. Some goroutine must always be // calling Accept; otherwise no messages will be forwarded // to the channels. ch, err := sConn.Accept() if err == io.EOF { return } if err != nil { log.Println("handleServerConn Accept:", err) break } // Channels have a type, depending on the application level // protocol intended. In the case of a shell, the type is // "session" and ServerShell may be used to present a simple // terminal interface. if ch.ChannelType() != "session" { ch.Reject(ssh.UnknownChannelType, "unknown channel type") break } go handleChannel(ch) } }
func handleUser(sConn *ssh.ServerConn) { if err := sConn.Handshake(); err != nil { fmt.Printf("failed to handshake\n") return } // A ServerConn multiplexes several channels, which must // themselves be Accepted. for { // Accept reads from the connection, demultiplexes packets // to their corresponding channels and returns when a new // channel request is seen. Some goroutine must always be // calling Accept; otherwise no messages will be forwarded // to the channels. channel, err := sConn.Accept() if err != nil { fmt.Printf("error from Accept\n") return } // Channels have a type, depending on the application level // protocol intended. In the case of a shell, the type is // "session" and ServerShell may be used to present a simple // terminal interface. if channel.ChannelType() != "session" { channel.Reject(ssh.UnknownChannelType, "unknown channel type") continue } channel.Accept() term := terminal.NewTerminal(channel, "> ") serverTerm := &ssh.ServerTerminal{ Term: term, Channel: channel, } go func() { defer channel.Close() for { line, err := serverTerm.ReadLine() if err != nil { break } fmt.Println(line) } }() } }