example_test.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // Copyright 2011 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package ssh
  5. import (
  6. "bytes"
  7. "fmt"
  8. "io/ioutil"
  9. "log"
  10. "net"
  11. "net/http"
  12. "code.google.com/p/go.crypto/ssh/terminal"
  13. )
  14. func ExampleNewServerConn() {
  15. // An SSH server is represented by a ServerConfig, which holds
  16. // certificate details and handles authentication of ServerConns.
  17. config := &ServerConfig{
  18. PasswordCallback: func(c ConnMetadata, pass []byte) (*Permissions, error) {
  19. // Should use constant-time compare (or better, salt+hash) in
  20. // a production setting.
  21. if c.User() == "testuser" && string(pass) == "tiger" {
  22. return nil, nil
  23. }
  24. return nil, fmt.Errorf("password rejected for %q", c.User())
  25. },
  26. }
  27. privateBytes, err := ioutil.ReadFile("id_rsa")
  28. if err != nil {
  29. panic("Failed to load private key")
  30. }
  31. private, err := ParsePrivateKey(privateBytes)
  32. if err != nil {
  33. panic("Failed to parse private key")
  34. }
  35. config.AddHostKey(private)
  36. // Once a ServerConfig has been configured, connections can be
  37. // accepted.
  38. listener, err := net.Listen("tcp", "0.0.0.0:2022")
  39. if err != nil {
  40. panic("failed to listen for connection")
  41. }
  42. nConn, err := listener.Accept()
  43. if err != nil {
  44. panic("failed to accept incoming connection")
  45. }
  46. // Before use, a handshake must be performed on the incoming
  47. // net.Conn.
  48. _, chans, reqs, err := NewServerConn(nConn, config)
  49. if err != nil {
  50. panic("failed to handshake")
  51. }
  52. // The incoming Request channel must be serviced.
  53. go DiscardRequests(reqs)
  54. // Service the incoming Channel channel.
  55. for newChannel := range chans {
  56. // Channels have a type, depending on the application level
  57. // protocol intended. In the case of a shell, the type is
  58. // "session" and ServerShell may be used to present a simple
  59. // terminal interface.
  60. if newChannel.ChannelType() != "session" {
  61. newChannel.Reject(UnknownChannelType, "unknown channel type")
  62. continue
  63. }
  64. channel, requests, err := newChannel.Accept()
  65. if err != nil {
  66. panic("could not accept channel.")
  67. }
  68. // Sessions have out-of-band requests such as "shell",
  69. // "pty-req" and "env". Here we handle only the
  70. // "shell" request.
  71. go func(in <-chan *Request) {
  72. for req := range in {
  73. ok := false
  74. switch req.Type {
  75. case "shell":
  76. ok = true
  77. if len(req.Payload) > 0 {
  78. // We don't accept any
  79. // commands, only the
  80. // default shell.
  81. ok = false
  82. }
  83. }
  84. req.Reply(ok, nil)
  85. }
  86. }(requests)
  87. term := terminal.NewTerminal(channel, "> ")
  88. go func() {
  89. defer channel.Close()
  90. for {
  91. line, err := term.ReadLine()
  92. if err != nil {
  93. break
  94. }
  95. fmt.Println(line)
  96. }
  97. }()
  98. }
  99. }
  100. func ExampleDial() {
  101. // An SSH client is represented with a ClientConn. Currently only
  102. // the "password" authentication method is supported.
  103. //
  104. // To authenticate with the remote server you must pass at least one
  105. // implementation of AuthMethod via the Auth field in ClientConfig.
  106. config := &ClientConfig{
  107. User: "username",
  108. Auth: []AuthMethod{
  109. Password("yourpassword"),
  110. },
  111. }
  112. client, err := Dial("tcp", "yourserver.com:22", config)
  113. if err != nil {
  114. panic("Failed to dial: " + err.Error())
  115. }
  116. // Each ClientConn can support multiple interactive sessions,
  117. // represented by a Session.
  118. session, err := client.NewSession()
  119. if err != nil {
  120. panic("Failed to create session: " + err.Error())
  121. }
  122. defer session.Close()
  123. // Once a Session is created, you can execute a single command on
  124. // the remote side using the Run method.
  125. var b bytes.Buffer
  126. session.Stdout = &b
  127. if err := session.Run("/usr/bin/whoami"); err != nil {
  128. panic("Failed to run: " + err.Error())
  129. }
  130. fmt.Println(b.String())
  131. }
  132. func ExampleClient_Listen() {
  133. config := &ClientConfig{
  134. User: "username",
  135. Auth: []AuthMethod{
  136. Password("password"),
  137. },
  138. }
  139. // Dial your ssh server.
  140. conn, err := Dial("tcp", "localhost:22", config)
  141. if err != nil {
  142. log.Fatalf("unable to connect: %s", err)
  143. }
  144. defer conn.Close()
  145. // Request the remote side to open port 8080 on all interfaces.
  146. l, err := conn.Listen("tcp", "0.0.0.0:8080")
  147. if err != nil {
  148. log.Fatalf("unable to register tcp forward: %v", err)
  149. }
  150. defer l.Close()
  151. // Serve HTTP with your SSH server acting as a reverse proxy.
  152. http.Serve(l, http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
  153. fmt.Fprintf(resp, "Hello world!\n")
  154. }))
  155. }
  156. func ExampleSession_RequestPty() {
  157. // Create client config
  158. config := &ClientConfig{
  159. User: "username",
  160. Auth: []AuthMethod{
  161. Password("password"),
  162. },
  163. }
  164. // Connect to ssh server
  165. conn, err := Dial("tcp", "localhost:22", config)
  166. if err != nil {
  167. log.Fatalf("unable to connect: %s", err)
  168. }
  169. defer conn.Close()
  170. // Create a session
  171. session, err := conn.NewSession()
  172. if err != nil {
  173. log.Fatalf("unable to create session: %s", err)
  174. }
  175. defer session.Close()
  176. // Set up terminal modes
  177. modes := TerminalModes{
  178. ECHO: 0, // disable echoing
  179. TTY_OP_ISPEED: 14400, // input speed = 14.4kbaud
  180. TTY_OP_OSPEED: 14400, // output speed = 14.4kbaud
  181. }
  182. // Request pseudo terminal
  183. if err := session.RequestPty("xterm", 80, 40, modes); err != nil {
  184. log.Fatalf("request for pseudo terminal failed: %s", err)
  185. }
  186. // Start remote shell
  187. if err := session.Shell(); err != nil {
  188. log.Fatalf("failed to start shell: %s", err)
  189. }
  190. }