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  }