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