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