github.com/jerryclinesmith/packer@v0.3.7/communicator/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  	"github.com/mitchellh/packer/packer"
     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  // password implements the ClientPassword interface
    43  type password string
    44  
    45  func (p password) Password(user string) (string, error) {
    46  	return string(p), nil
    47  }
    48  
    49  var serverConfig = &ssh.ServerConfig{
    50  	PasswordCallback: func(c *ssh.ServerConn, user, pass string) bool {
    51  		return user == "user" && pass == "pass"
    52  	},
    53  }
    54  
    55  func init() {
    56  	// Set the private key of the server, required to accept connections
    57  	if err := serverConfig.SetRSAPrivateKey([]byte(testServerPrivateKey)); err != nil {
    58  		panic("unable to set private key: " + err.Error())
    59  	}
    60  }
    61  
    62  func newMockLineServer(t *testing.T) string {
    63  	l, err := ssh.Listen("tcp", "127.0.0.1:0", serverConfig)
    64  	if err != nil {
    65  		t.Fatalf("unable to newMockAuthServer: %s", err)
    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: %v", err)
    72  			return
    73  		}
    74  
    75  		if err := c.Handshake(); err != nil {
    76  			// not Errorf because this is expected to
    77  			// fail for some tests.
    78  			t.Logf("Handshaking error: %v", err)
    79  			return
    80  		}
    81  
    82  		t.Log("Accepted SSH connection")
    83  		defer c.Close()
    84  
    85  		channel, err := c.Accept()
    86  		if err != nil {
    87  			t.Errorf("Unable to accept a channel: %s", err)
    88  			return
    89  		}
    90  
    91  		// Just go in a loop now accepting things... we need to
    92  		// do this to handle packets for SSH.
    93  		go func() {
    94  			c.Accept()
    95  		}()
    96  
    97  		channel.Accept()
    98  		t.Log("Accepted channel")
    99  		defer channel.Close()
   100  	}()
   101  	return l.Addr().String()
   102  }
   103  
   104  func TestCommIsCommunicator(t *testing.T) {
   105  	var raw interface{}
   106  	raw = &comm{}
   107  	if _, ok := raw.(packer.Communicator); !ok {
   108  		t.Fatalf("comm must be a communicator")
   109  	}
   110  }
   111  
   112  func TestNew_Invalid(t *testing.T) {
   113  	clientConfig := &ssh.ClientConfig{
   114  		User: "user",
   115  		Auth: []ssh.ClientAuth{
   116  			ssh.ClientAuthPassword(password("i-am-invalid")),
   117  		},
   118  	}
   119  
   120  	conn := func() (net.Conn, error) {
   121  		conn, err := net.Dial("tcp", newMockLineServer(t))
   122  		if err != nil {
   123  			t.Fatalf("unable to dial to remote side: %s", err)
   124  		}
   125  		return conn, err
   126  	}
   127  
   128  	config := &Config{
   129  		Connection: conn,
   130  		SSHConfig:  clientConfig,
   131  	}
   132  
   133  	_, err := New(config)
   134  	if err == nil {
   135  		t.Fatal("should have had an error connecting")
   136  	}
   137  }
   138  
   139  func TestStart(t *testing.T) {
   140  	clientConfig := &ssh.ClientConfig{
   141  		User: "user",
   142  		Auth: []ssh.ClientAuth{
   143  			ssh.ClientAuthPassword(password("pass")),
   144  		},
   145  	}
   146  
   147  	conn := func() (net.Conn, error) {
   148  		conn, err := net.Dial("tcp", newMockLineServer(t))
   149  		if err != nil {
   150  			t.Fatalf("unable to dial to remote side: %s", err)
   151  		}
   152  		return conn, err
   153  	}
   154  
   155  	config := &Config{
   156  		Connection: conn,
   157  		SSHConfig:  clientConfig,
   158  	}
   159  
   160  	client, err := New(config)
   161  	if err != nil {
   162  		t.Fatalf("error connecting to SSH: %s", err)
   163  	}
   164  
   165  	var cmd packer.RemoteCmd
   166  	stdout := new(bytes.Buffer)
   167  	cmd.Command = "echo foo"
   168  	cmd.Stdout = stdout
   169  
   170  	client.Start(&cmd)
   171  }