github.com/adamar/terraform@v0.2.2-0.20141016210445-2e703afdad0e/helper/ssh/communicator_test.go (about) 1 // +build !race 2 3 package ssh 4 5 import ( 6 "bytes" 7 "code.google.com/p/go.crypto/ssh" 8 "fmt" 9 "net" 10 "testing" 11 ) 12 13 // private key for mock server 14 const testServerPrivateKey = `-----BEGIN RSA PRIVATE KEY----- 15 MIIEpAIBAAKCAQEA19lGVsTqIT5iiNYRgnoY1CwkbETW5cq+Rzk5v/kTlf31XpSU 16 70HVWkbTERECjaYdXM2gGcbb+sxpq6GtXf1M3kVomycqhxwhPv4Cr6Xp4WT/jkFx 17 9z+FFzpeodGJWjOH6L2H5uX1Cvr9EDdQp9t9/J32/qBFntY8GwoUI/y/1MSTmMiF 18 tupdMODN064vd3gyMKTwrlQ8tZM6aYuyOPsutLlUY7M5x5FwMDYvnPDSeyT/Iw0z 19 s3B+NCyqeeMd2T7YzQFnRATj0M7rM5LoSs7DVqVriOEABssFyLj31PboaoLhOKgc 20 qoM9khkNzr7FHVvi+DhYM2jD0DwvqZLN6NmnLwIDAQABAoIBAQCGVj+kuSFOV1lT 21 +IclQYA6bM6uY5mroqcSBNegVxCNhWU03BxlW//BE9tA/+kq53vWylMeN9mpGZea 22 riEMIh25KFGWXqXlOOioH8bkMsqA8S7sBmc7jljyv+0toQ9vCCtJ+sueNPhxQQxH 23 D2YvUjfzBQ04I9+wn30BByDJ1QA/FoPsunxIOUCcRBE/7jxuLYcpR+JvEF68yYIh 24 atXRld4W4in7T65YDR8jK1Uj9XAcNeDYNpT/M6oFLx1aPIlkG86aCWRO19S1jLPT 25 b1ZAKHHxPMCVkSYW0RqvIgLXQOR62D0Zne6/2wtzJkk5UCjkSQ2z7ZzJpMkWgDgN 26 ifCULFPBAoGBAPoMZ5q1w+zB+knXUD33n1J+niN6TZHJulpf2w5zsW+m2K6Zn62M 27 MXndXlVAHtk6p02q9kxHdgov34Uo8VpuNjbS1+abGFTI8NZgFo+bsDxJdItemwC4 28 KJ7L1iz39hRN/ZylMRLz5uTYRGddCkeIHhiG2h7zohH/MaYzUacXEEy3AoGBANz8 29 e/msleB+iXC0cXKwds26N4hyMdAFE5qAqJXvV3S2W8JZnmU+sS7vPAWMYPlERPk1 30 D8Q2eXqdPIkAWBhrx4RxD7rNc5qFNcQWEhCIxC9fccluH1y5g2M+4jpMX2CT8Uv+ 31 3z+NoJ5uDTXZTnLCfoZzgZ4nCZVZ+6iU5U1+YXFJAoGBANLPpIV920n/nJmmquMj 32 orI1R/QXR9Cy56cMC65agezlGOfTYxk5Cfl5Ve+/2IJCfgzwJyjWUsFx7RviEeGw 33 64o7JoUom1HX+5xxdHPsyZ96OoTJ5RqtKKoApnhRMamau0fWydH1yeOEJd+TRHhc 34 XStGfhz8QNa1dVFvENczja1vAoGABGWhsd4VPVpHMc7lUvrf4kgKQtTC2PjA4xoc 35 QJ96hf/642sVE76jl+N6tkGMzGjnVm4P2j+bOy1VvwQavKGoXqJBRd5Apppv727g 36 /SM7hBXKFc/zH80xKBBgP/i1DR7kdjakCoeu4ngeGywvu2jTS6mQsqzkK+yWbUxJ 37 I7mYBsECgYB/KNXlTEpXtz/kwWCHFSYA8U74l7zZbVD8ul0e56JDK+lLcJ0tJffk 38 gqnBycHj6AhEycjda75cs+0zybZvN4x65KZHOGW/O/7OAWEcZP5TPb3zf9ned3Hl 39 NsZoFj52ponUM6+99A2CmezFCN16c4mbA//luWF+k3VVqR6BpkrhKw== 40 -----END RSA PRIVATE KEY-----` 41 42 var serverConfig = &ssh.ServerConfig{ 43 PasswordCallback: func(c ssh.ConnMetadata, pass []byte) (*ssh.Permissions, error) { 44 if c.User() == "user" && string(pass) == "pass" { 45 return nil, nil 46 } 47 return nil, fmt.Errorf("password rejected for %q", c.User()) 48 }, 49 } 50 51 func init() { 52 // Parse and set the private key of the server, required to accept connections 53 signer, err := ssh.ParsePrivateKey([]byte(testServerPrivateKey)) 54 if err != nil { 55 panic("unable to parse private key: " + err.Error()) 56 } 57 serverConfig.AddHostKey(signer) 58 } 59 60 func newMockLineServer(t *testing.T) string { 61 l, err := net.Listen("tcp", "127.0.0.1:0") 62 if err != nil { 63 t.Fatalf("Unable to listen for connection: %s", err) 64 } 65 66 go func() { 67 defer l.Close() 68 c, err := l.Accept() 69 if err != nil { 70 t.Errorf("Unable to accept incoming connection: %s", err) 71 } 72 defer c.Close() 73 conn, chans, _, err := ssh.NewServerConn(c, serverConfig) 74 if err != nil { 75 t.Logf("Handshaking error: %v", err) 76 } 77 t.Log("Accepted SSH connection") 78 for newChannel := range chans { 79 channel, _, err := newChannel.Accept() 80 if err != nil { 81 t.Errorf("Unable to accept channel.") 82 } 83 t.Log("Accepted channel") 84 85 go func(newChannel ssh.NewChannel) { 86 defer channel.Close() 87 conn.OpenChannel(newChannel.ChannelType(), nil) 88 }(newChannel) 89 } 90 conn.Close() 91 }() 92 93 return l.Addr().String() 94 } 95 96 func TestNew_Invalid(t *testing.T) { 97 clientConfig := &ssh.ClientConfig{ 98 User: "user", 99 Auth: []ssh.AuthMethod{ 100 ssh.Password("i-am-invalid"), 101 }, 102 } 103 104 address := newMockLineServer(t) 105 conn := func() (net.Conn, error) { 106 conn, err := net.Dial("tcp", address) 107 if err != nil { 108 t.Errorf("Unable to accept incoming connection: %v", err) 109 } 110 return conn, err 111 } 112 113 config := &Config{ 114 Connection: conn, 115 SSHConfig: clientConfig, 116 } 117 118 _, err := New(address, config) 119 if err == nil { 120 t.Fatal("should have had an error connecting") 121 } 122 } 123 124 func TestStart(t *testing.T) { 125 clientConfig := &ssh.ClientConfig{ 126 User: "user", 127 Auth: []ssh.AuthMethod{ 128 ssh.Password("pass"), 129 }, 130 } 131 132 address := newMockLineServer(t) 133 conn := func() (net.Conn, error) { 134 conn, err := net.Dial("tcp", address) 135 if err != nil { 136 t.Fatalf("unable to dial to remote side: %s", err) 137 } 138 return conn, err 139 } 140 141 config := &Config{ 142 Connection: conn, 143 SSHConfig: clientConfig, 144 } 145 146 client, err := New(address, config) 147 if err != nil { 148 t.Fatalf("error connecting to SSH: %s", err) 149 } 150 151 var cmd RemoteCmd 152 stdout := new(bytes.Buffer) 153 cmd.Command = "echo foo" 154 cmd.Stdout = stdout 155 156 client.Start(&cmd) 157 }