예제 #1
0
func newServerShell(ch *serverChan, prompt string) *ServerTerminal {
	term := terminal.NewTerminal(ch, prompt)
	return &ServerTerminal{
		Term:    term,
		Channel: ch,
	}
}
예제 #2
0
func ExampleListen() {
	// An SSH server is represented by a ServerConfig, which holds
	// certificate details and handles authentication of ServerConns.
	config := &ServerConfig{
		PasswordCallback: func(conn *ServerConn, user, pass string) bool {
			return user == "testuser" && pass == "tiger"
		},
	}

	privateBytes, err := ioutil.ReadFile("id_rsa")
	if err != nil {
		panic("Failed to load private key")
	}

	private, err := ParsePrivateKey(privateBytes)
	if err != nil {
		panic("Failed to parse private key")
	}

	config.AddHostKey(private)

	// Once a ServerConfig has been configured, connections can be
	// accepted.
	listener, err := Listen("tcp", "0.0.0.0:2022", config)
	if err != nil {
		panic("failed to listen for connection")
	}
	sConn, err := listener.Accept()
	if err != nil {
		panic("failed to accept incoming connection")
	}
	if err := sConn.Handshake(); err != nil {
		panic("failed to handshake")
	}

	// 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 {
			panic("error from Accept")
		}

		// 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(UnknownChannelType, "unknown channel type")
			continue
		}
		channel.Accept()

		term := terminal.NewTerminal(channel, "> ")
		serverTerm := &ServerTerminal{
			Term:    term,
			Channel: channel,
		}
		go func() {
			defer channel.Close()
			for {
				line, err := serverTerm.ReadLine()
				if err != nil {
					break
				}
				fmt.Println(line)
			}
		}()
	}
}