Exemple #1
0
func (sc *SshSession) RequestPty(term string, h int, w int, termmodes ssh.TerminalModes) (err error) {
	if sc.session != nil {
		return sc.session.RequestPty(term, h, w, termmodes)
	} else {
		var tm []byte
		for k, v := range termmodes {
			kv := struct {
				Key byte
				Val uint32
			}{k, v}

			tm = append(tm, ssh.Marshal(&kv)...)
		}
		tm = append(tm, tty_OP_END)
		req := ptyRequestMsg{
			Term:     term,
			Columns:  uint32(w),
			Rows:     uint32(h),
			Width:    uint32(w * 8),
			Height:   uint32(h * 8),
			Modelist: string(tm),
		}
		ok, err := sc.ch.SendRequest("pty-req", true, ssh.Marshal(&req))
		if err == nil && !ok {
			err = errors.New("ssh: pty-req failed")
		}
		return err
	}
}
Exemple #2
0
func (c *client) insertCert(s interface{}, cert *ssh.Certificate, comment string, constraints []byte) error {
	var req []byte
	switch k := s.(type) {
	case *rsa.PrivateKey:
		if len(k.Primes) != 2 {
			return fmt.Errorf("agent: unsupported RSA key with %d primes", len(k.Primes))
		}
		k.Precompute()
		req = ssh.Marshal(rsaCertMsg{
			Type:        cert.Type(),
			CertBytes:   cert.Marshal(),
			D:           k.D,
			Iqmp:        k.Precomputed.Qinv,
			P:           k.Primes[0],
			Q:           k.Primes[1],
			Comments:    comment,
			Constraints: constraints,
		})
	case *dsa.PrivateKey:
		req = ssh.Marshal(dsaCertMsg{
			Type:      cert.Type(),
			CertBytes: cert.Marshal(),
			X:         k.X,
			Comments:  comment,
		})
	case *ecdsa.PrivateKey:
		req = ssh.Marshal(ecdsaCertMsg{
			Type:      cert.Type(),
			CertBytes: cert.Marshal(),
			D:         k.D,
			Comments:  comment,
		})
	default:
		return fmt.Errorf("agent: unsupported key type %T", s)
	}

	// if constraints are present then the message type needs to be changed.
	if len(constraints) != 0 {
		req[0] = agentAddIdConstrained
	}

	signer, err := ssh.NewSignerFromKey(s)
	if err != nil {
		return err
	}
	if bytes.Compare(cert.Key.Marshal(), signer.PublicKey().Marshal()) != 0 {
		return errors.New("agent: signer and cert have different public key")
	}

	resp, err := c.call(req)
	if err != nil {
		return err
	}
	if _, ok := resp.(*successAgentMsg); ok {
		return nil
	}
	return errors.New("agent: failure")
}
Exemple #3
0
// Insert adds a private key to the agent.
func (c *client) insertKey(s interface{}, comment string, constraints []byte) error {
	var req []byte
	switch k := s.(type) {
	case *rsa.PrivateKey:
		if len(k.Primes) != 2 {
			return fmt.Errorf("agent: unsupported RSA key with %d primes", len(k.Primes))
		}
		k.Precompute()
		req = ssh.Marshal(rsaKeyMsg{
			Type:        ssh.KeyAlgoRSA,
			N:           k.N,
			E:           big.NewInt(int64(k.E)),
			D:           k.D,
			Iqmp:        k.Precomputed.Qinv,
			P:           k.Primes[0],
			Q:           k.Primes[1],
			Comments:    comment,
			Constraints: constraints,
		})
	case *dsa.PrivateKey:
		req = ssh.Marshal(dsaKeyMsg{
			Type:        ssh.KeyAlgoDSA,
			P:           k.P,
			Q:           k.Q,
			G:           k.G,
			Y:           k.Y,
			X:           k.X,
			Comments:    comment,
			Constraints: constraints,
		})
	case *ecdsa.PrivateKey:
		nistID := fmt.Sprintf("nistp%d", k.Params().BitSize)
		req = ssh.Marshal(ecdsaKeyMsg{
			Type:        "ecdsa-sha2-" + nistID,
			Curve:       nistID,
			KeyBytes:    elliptic.Marshal(k.Curve, k.X, k.Y),
			D:           k.D,
			Comments:    comment,
			Constraints: constraints,
		})
	default:
		return fmt.Errorf("agent: unsupported key type %T", s)
	}

	// if constraints are present then the message type needs to be changed.
	if len(constraints) != 0 {
		req[0] = agentAddIdConstrained
	}

	resp, err := c.call(req)
	if err != nil {
		return err
	}
	if _, ok := resp.(*successAgentMsg); ok {
		return nil
	}
	return errors.New("agent: failure")
}
func (sess *session) sendExitMessage(err error) {
	logger := sess.logger.Session("send-exit-message")
	logger.Info("started")
	defer logger.Info("finished")

	if err != nil {
		logger.Error("building-exit-message-from-error", err)
	}

	if err == nil {
		_, sendErr := sess.channel.SendRequest("exit-status", false, ssh.Marshal(exitStatusMsg{}))
		if sendErr != nil {
			logger.Error("send-exit-status-failed", sendErr)
		}
		return
	}

	exitError, ok := err.(*exec.ExitError)
	if !ok {
		exitMessage := exitStatusMsg{Status: 255}
		_, sendErr := sess.channel.SendRequest("exit-status", false, ssh.Marshal(exitMessage))
		if sendErr != nil {
			logger.Error("send-exit-status-failed", sendErr)
		}
		return
	}

	waitStatus, ok := exitError.Sys().(syscall.WaitStatus)
	if !ok {
		exitMessage := exitStatusMsg{Status: 255}
		_, sendErr := sess.channel.SendRequest("exit-status", false, ssh.Marshal(exitMessage))
		if sendErr != nil {
			logger.Error("send-exit-status-failed", sendErr)
		}
		return
	}

	if waitStatus.Signaled() {
		exitMessage := exitSignalMsg{
			Signal:     string(signals.SSHSignals[waitStatus.Signal()]),
			CoreDumped: waitStatus.CoreDump(),
		}
		_, sendErr := sess.channel.SendRequest("exit-signal", false, ssh.Marshal(exitMessage))
		if sendErr != nil {
			logger.Error("send-exit-status-failed", sendErr)
		}
		return
	}

	exitMessage := exitStatusMsg{Status: uint32(waitStatus.ExitStatus())}
	_, sendErr := sess.channel.SendRequest("exit-status", false, ssh.Marshal(exitMessage))
	if sendErr != nil {
		logger.Error("send-exit-status-failed", sendErr)
	}
}
Exemple #5
0
func (ss *SecureShell) resize(resized <-chan os.Signal, session SecureSession, terminalFd uintptr, initialWidth, initialHeight int) {
	type resizeMessage struct {
		Width       uint32
		Height      uint32
		PixelWidth  uint32
		PixelHeight uint32
	}

	var previousWidth, previousHeight int
	previousWidth = initialWidth
	previousHeight = initialHeight

	for _ = range resized {
		width, height := ss.Term.GetWinsize(terminalFd)

		if width == previousWidth && height == previousHeight {
			continue
		}

		message := resizeMessage{
			Width:  uint32(width),
			Height: uint32(height),
		}

		session.SendRequest("window-change", false, ssh.Marshal(message))

		previousWidth = width
		previousHeight = height
	}
}
Exemple #6
0
func (f *File) ReadAt(b []byte, off int64) (n int, err error) {
	req := fxpReadMsg{Handle: f.handle}
	fxpCh, err := f.sftp.chans.newChan()
	if err != nil {
		return
	}
	defer f.sftp.chans.remove(fxpCh.id)
	req.SetID(fxpCh.id)

	for len(b) > 0 {
		req.Offset = uint64(n) + uint64(off)
		req.Length = uint32(min(uint64(len(b)), maxDataBytes))
		if err = f.sftp.writePacket(ssh.Marshal(req)); err != nil {
			return
		}
		resp := fxpCh.waitForResponse()
		switch msg := resp.(type) {
		case *fxpStatusResp:
			if msg.Status == eof {
				err = io.EOF
				return
			}
			err = msg
			return
		case *fxpDataResp:
			n += copy(b, msg.Data)
			b = b[len(msg.Data):]
		default:
			panic("unexpected message type returned from server")
		}
	}
	return
}
Exemple #7
0
func handleSSHChannel(newChan ssh.NewChannel, session *Session) {
	ch, reqs, err := newChan.Accept()
	if err != nil {
		log.Println("handle channel failed:", err)
		return
	}
	exitCh := make(chan int)
	go func() {
		status := struct{ Status uint32 }{uint32(<-exitCh)}
		_, err = ch.SendRequest("exit-status", false, ssh.Marshal(&status))
		assert(err)
		ch.Close()
	}()
	for req := range reqs {
		go func(req *ssh.Request) {
			if req.WantReply {
				req.Reply(true, nil)
			}
			switch req.Type {
			case "exec":
				var payload = struct{ Value string }{}
				ssh.Unmarshal(req.Payload, &payload)
				line := strings.Trim(payload.Value, "\n")
				var args []string
				if line != "" {
					args = strings.Split(line, " ")
				}
				RunCmd(args, ch, ch, ch.Stderr(), exitCh, session)
			}
		}(req)
	}
}
Exemple #8
0
func (c *secureShell) resize(resized <-chan os.Signal, session SecureSession, terminalFd uintptr) {
	type resizeMessage struct {
		Width       uint32
		Height      uint32
		PixelWidth  uint32
		PixelHeight uint32
	}

	var previousWidth, previousHeight int

	for range resized {
		width, height := c.getWindowDimensions(terminalFd)

		if width == previousWidth && height == previousHeight {
			continue
		}

		message := resizeMessage{
			Width:  uint32(width),
			Height: uint32(height),
		}

		_, _ = session.SendRequest("window-change", false, ssh.Marshal(message))

		previousWidth = width
		previousHeight = height
	}
}
Exemple #9
0
func (f *File) WriteAt(b []byte, off int64) (n int, err error) {
	req := fxpWriteMsg{Handle: f.handle}
	fxpCh, err := f.sftp.chans.newChan()
	if err != nil {
		return
	}
	defer f.sftp.chans.remove(fxpCh.id)
	req.SetID(fxpCh.id)

	for len(b) > 0 {
		req.Offset = uint64(n) + uint64(off)
		l := min(uint64(len(b)), maxDataBytes)
		req.Data = b[:l]
		if err = f.sftp.writePacket(ssh.Marshal(req)); err != nil {
			return
		}
		resp := fxpCh.waitForResponse()
		switch msg := resp.(type) {
		case *fxpStatusResp:
			if msg.Status != OK {
				err = msg
				return
			}
			n += int(l)
			b = b[l:]
		default:
			panic("unexpected message type returned from server")
		}
	}
	return
}
Exemple #10
0
func forwardLocalConn(logger lager.Logger, localConn net.Conn, conn *ssh.ServerConn, forwardIP string, forwardPort uint32) {
	defer localConn.Close()

	var req forwardTCPIPChannelRequest
	req.ForwardIP = forwardIP
	req.ForwardPort = forwardPort

	host, port, err := net.SplitHostPort(localConn.RemoteAddr().String())
	if err != nil {
		logger.Error("failed-to-split-host-port", err)
		return
	}

	req.OriginIP = host
	_, err = fmt.Sscanf(port, "%d", &req.OriginPort)
	if err != nil {
		logger.Error("failed-to-parse-port", err)
		return
	}

	channel, reqs, err := conn.OpenChannel("forwarded-tcpip", ssh.Marshal(req))
	if err != nil {
		logger.Error("failed-to-open-channel", err)
		return
	}

	defer channel.Close()

	go func() {
		for r := range reqs {
			logger.Info("ignoring-request", lager.Data{
				"type": r.Type,
			})

			r.Reply(false, nil)
		}
	}()

	wg := new(sync.WaitGroup)

	pipe := func(to io.WriteCloser, from io.ReadCloser) {
		// if either end breaks, close both ends to ensure they're both unblocked,
		// otherwise io.Copy can block forever if e.g. reading after write end has
		// gone away
		defer to.Close()
		defer from.Close()
		defer wg.Done()

		io.Copy(to, from)
	}

	wg.Add(1)
	go pipe(localConn, channel)

	wg.Add(1)
	go pipe(channel, localConn)

	wg.Wait()
}
Exemple #11
0
func marshalKey(k *Key) []byte {
	var record struct {
		Blob    []byte
		Comment string
	}
	record.Blob = k.Marshal()
	record.Comment = k.Comment

	return ssh.Marshal(&record)
}
Exemple #12
0
func (ek *Ed25519PublicKey) Marshal() []byte {
	wirekey := struct {
		Name string
		Pub  []byte
	}{
		ek.Type(),
		(*ek.bytes)[:],
	}
	return ssh.Marshal(&wirekey)
}
Exemple #13
0
// init starts the SFTP protocol by negotiating the protocol version to use and
// starts the response handler in a goroutine.
func (s *Client) init() error {
	msg := fxpInitMsg{
		Version: 3,
	}
	if err := s.writePacket(ssh.Marshal(msg)); err != nil {
		return err
	}
	packet, err := s.readOnePacket()
	if err != nil {
		return err
	}
	resp, err := decodeClient(packet)
	if err != nil {
		return err
	}
	switch resp := resp.(type) {
	case *fxpVersionMsg:
		if resp.Version != 3 {
			return errors.New("only version 3 of Client protocol supported")
		}
	default:
		return errors.New("invalid packet received during initialization")
	}
	vers := resp.(*fxpVersionMsg)
	s.exts = make(map[string]extension)
	if len(vers.Ext) > 0 {
		exts := vers.Ext
		for len(exts) > 0 {
			ew := extensionWire{}
			if err := ssh.Unmarshal(exts, &ew); err != nil {
				return err
			}
			if len(exts) < 2 {
				break
			}
			exts = ew.Rest

			e := extension{
				Name: ew.Name,
				Data: ew.Data,
			}
			// OpenSSH's sftp-server implementation specifies that
			// the data portion of an extension is an ASCII-encoded
			// version number. This is not part of the SFTP
			// specification, however.
			if n, err := strconv.Atoi(ew.Data); err == nil {
				e.version = n
			}
			s.exts[e.Name] = e
		}
	}
	go s.mainLoop()

	return nil
}
Exemple #14
0
// sendRequests sends a request to the server and returns a new channel on
// which the response will be sent.
func (s *Client) sendRequest(req ider) (*fxpChan, error) {
	fxpCh, err := s.chans.newChan()
	if err != nil {
		return nil, err
	}
	req.SetID(fxpCh.id)
	if err := s.writePacket(ssh.Marshal(req)); err != nil {
		return nil, err
	}
	return fxpCh, nil
}
Exemple #15
0
func (inst *instance) SendWindowSize() {
	if w, h, err := inst.terminal.GetSize(); err != nil {
		color.Redln("Error getting term size:", err)
	} else {
		msg := ssh.Marshal(&winchMsg{uint32(w), uint32(h), 0, 0})
		_, err = inst.session.SendRequest("window-change", false, msg)
		if err != nil {
			color.Redln("Error sending winch:", err)
		}
	}
}
func (chsvr *sshSessionChannelServer) handleSubsystem(req *ssh.Request) error {
	defer func() {
		err1 := chsvr.ch.CloseWrite()
		err2 := chsvr.ch.Close()
		fmt.Fprintf(sshServerDebugStream, "ssh server subsystem request complete, err: %v %v\n", err1, err2)
	}()

	subsystemReq := &sshSubsystemRequest{}
	if err := ssh.Unmarshal(req.Payload, subsystemReq); err != nil {
		return rejectRequestUnmarshalError(req, subsystemReq, err)
	}

	// reply to the ssh client

	// no idea if this is actually correct spec-wise.
	// just enough for an sftp server to start.
	if subsystemReq.Name != "sftp" {
		return req.Reply(false, nil)
	}

	req.Reply(true, nil)

	if !chsvr.svr.useSubsystem {
		// use the openssh sftp server backend; this is to test the ssh code, not the sftp code,
		// or is used for comparison between our sftp subsystem and the openssh sftp subsystem
		cmd := exec.Command(*testSftp, "-e", "-l", "DEBUG") // log to stderr
		cmd.Stdin = chsvr.ch
		cmd.Stdout = chsvr.ch
		cmd.Stderr = sftpServerDebugStream
		if err := cmd.Start(); err != nil {
			return err
		}
		return cmd.Wait()
	}

	sftpServer, err := NewServer(
		chsvr.ch,
		chsvr.ch,
		WithDebug(sftpServerDebugStream),
	)
	if err != nil {
		return err
	}

	// wait for the session to close
	runErr := sftpServer.Serve()
	exitStatus := uint32(1)
	if runErr == nil {
		exitStatus = uint32(0)
	}

	_, exitStatusErr := chsvr.ch.SendRequest("exit-status", false, ssh.Marshal(sshSubsystemExitStatus{exitStatus}))
	return exitStatusErr
}
func (s *Session) Resize(width, height int) error {
	message := struct {
		Width       uint32
		Height      uint32
		PixelWidth  uint32
		PixelHeight uint32
	}{uint32(width), uint32(height), 0, 0}

	_, err := s.sshSession.SendRequest("window-change", false, ssh.Marshal(message))
	return err
}
Exemple #18
0
// Exit sends an exit-status request to the channel based on the err.
func (h *sshHandler) Exit(err error) error {
	defer h.channel.Close()

	status, err := exitStatus(err)
	if !h.assert("exit", err) {
		_, err := h.channel.SendRequest("exit-status", false, ssh.Marshal(&status))
		h.assert("status", err)
		return err
	}
	return err
}
func sendCmdResult(channel ssh.Channel, result []byte, statusCode uint32) error {
	if _, err := channel.Write(result); err != nil {
		return fmt.Errorf("failed to write to ssh-channel: %v", err)
	}
	status := struct {
		Status uint32
	}{
		statusCode,
	}
	_, err := channel.SendRequest("exit-status", false, ssh.Marshal(&status))
	if err != nil {
		return fmt.Errorf("failed to SendRequest: %v", err)
	}
	return nil
}
Exemple #20
0
func (s *server) processRequestBytes(reqData []byte) []byte {
	rep, err := s.processRequest(reqData)
	if err != nil {
		if err != errLocked {
			// TODO(hanwen): provide better logging interface?
			log.Printf("agent %d: %v", reqData[0], err)
		}
		return []byte{agentFailure}
	}

	if err == nil && rep == nil {
		return []byte{agentSuccess}
	}

	return ssh.Marshal(rep)
}
func (sess *session) sendSCPExitMessage(err error) {
	logger := sess.logger.Session("send-scp-exit-message")
	logger.Info("started")
	defer logger.Info("finished")

	var exitMessage exitStatusMsg
	if err != nil {
		logger.Error("building-scp-exit-message-from-error", err)
		exitMessage = exitStatusMsg{Status: 1}
	}

	_, sendErr := sess.channel.SendRequest("exit-status", false, ssh.Marshal(exitMessage))
	if sendErr != nil {
		logger.Error("send-exit-status-failed", sendErr)
	}
}
Exemple #22
0
func handleSSHChannel(newChan ssh.NewChannel) {
	ch, reqs, err := newChan.Accept()
	if err != nil {
		log.Println("handle channel failed:", err)
		return
	}
	for req := range reqs {
		go func(req *ssh.Request) {
			if req.WantReply {
				req.Reply(true, nil)
			}
			switch req.Type {
			case "exec":
				defer ch.Close()
				var payload = struct{ Value string }{}
				ssh.Unmarshal(req.Payload, &payload)
				line := strings.Trim(payload.Value, "\n")
				var args []string
				if line != "" {
					args = strings.Split(line, " ")
				}
				cmd := exec.Command("/bin/envy", args...)
				cmd.Stdout = ch
				cmd.Stderr = ch.Stderr()
				err := cmd.Run()
				status := struct{ Status uint32 }{0}
				if err != nil {
					if exiterr, ok := err.(*exec.ExitError); ok {
						if stat, ok := exiterr.Sys().(syscall.WaitStatus); ok {
							status = struct{ Status uint32 }{uint32(stat.ExitStatus())}
						} else {
							assert(err)
						}
					}
				}
				_, err = ch.SendRequest("exit-status", false, ssh.Marshal(&status))
				assert(err)
				return
			}
		}(req)
	}
}
Exemple #23
0
func (s *sshServer) run(c *gc.C) {
	netconn, err := s.listener.Accept()
	c.Assert(err, jc.ErrorIsNil)
	defer func() {
		err := netconn.Close()
		c.Assert(err, jc.ErrorIsNil)
	}()
	conn, chans, reqs, err := cryptossh.NewServerConn(netconn, s.cfg)
	c.Assert(err, jc.ErrorIsNil)
	s.client = cryptossh.NewClient(conn, chans, reqs)
	var wg sync.WaitGroup
	defer wg.Wait()
	sessionChannels := s.client.HandleChannelOpen("session")
	c.Assert(sessionChannels, gc.NotNil)
	for newChannel := range sessionChannels {
		c.Assert(newChannel.ChannelType(), gc.Equals, "session")
		channel, reqs, err := newChannel.Accept()
		c.Assert(err, jc.ErrorIsNil)
		wg.Add(1)
		go func() {
			defer wg.Done()
			defer channel.Close()
			for req := range reqs {
				switch req.Type {
				case "exec":
					c.Assert(req.WantReply, jc.IsTrue)
					n := binary.BigEndian.Uint32(req.Payload[:4])
					command := string(req.Payload[4 : n+4])
					c.Assert(command, gc.Equals, testCommandFlat)
					req.Reply(true, nil)
					channel.Write([]byte("abc value\n"))
					_, err := channel.SendRequest("exit-status", false, cryptossh.Marshal(&struct{ n uint32 }{0}))
					c.Assert(err, jc.ErrorIsNil)
					return
				default:
					c.Fatalf("Unexpected request type: %v", req.Type)
				}
			}
		}()
	}
}
Exemple #24
0
func (chsvr *sshSessionChannelServer) handleSubsystem(req *ssh.Request) error {
	defer func() {
		err1 := chsvr.ch.CloseWrite()
		err2 := chsvr.ch.Close()
		fmt.Fprintf(sshServerDebugStream, "ssh server subsystem request complete, err: %v %v\n", err1, err2)
	}()

	subsystemReq := &sshSubsystemRequest{}
	if err := ssh.Unmarshal(req.Payload, subsystemReq); err != nil {
		return rejectRequestUnmarshalError(req, subsystemReq, err)
	}

	// reply to the ssh client

	// no idea if this is actually correct spec-wise.
	// just enough for an sftp server to start.
	if subsystemReq.Name == "sftp" {
		req.Reply(true, nil)

		sftpServer, err := sftp.NewServer(chsvr.ch, chsvr.ch, sftpServerDebugStream, 0, false, ".")
		if err != nil {
			return err
		}

		// wait for the session to close
		runErr := sftpServer.Serve()
		exitStatus := uint32(1)
		if runErr == nil {
			exitStatus = uint32(0)
		}

		_, exitStatusErr := chsvr.ch.SendRequest("exit-status", false, ssh.Marshal(sshSubsystemExitStatus{exitStatus}))
		return exitStatusErr
	} else {
		return req.Reply(false, nil)
	}
}
Exemple #25
0
// Sign has the agent sign the data using a protocol 2 key as defined
// in [PROTOCOL.agent] section 2.6.2.
func (c *client) Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error) {
	req := ssh.Marshal(signRequestAgentMsg{
		KeyBlob: key.Marshal(),
		Data:    data,
	})

	msg, err := c.call(req)
	if err != nil {
		return nil, err
	}

	switch msg := msg.(type) {
	case *signResponseAgentMsg:
		var sig ssh.Signature
		if err := ssh.Unmarshal(msg.SigBlob, &sig); err != nil {
			return nil, err
		}

		return &sig, nil
	case *failureAgentMsg:
		return nil, errors.New("agent: failed to sign challenge")
	}
	panic("unreachable")
}
		})

		Context("when a window change request is received", func() {
			type winChangeMsg struct {
				Columns  uint32
				Rows     uint32
				WidthPx  uint32
				HeightPx uint32
			}

			var result []byte

			Context("before a pty is allocated", func() {
				BeforeEach(func() {
					_, err := session.SendRequest("window-change", false, ssh.Marshal(winChangeMsg{
						Rows:    50,
						Columns: 132,
					}))
					Expect(err).NotTo(HaveOccurred())

					err = session.RequestPty("vt100", 43, 80, ssh.TerminalModes{})
					Expect(err).NotTo(HaveOccurred())

					result, err = session.Output("stty size")
					Expect(err).NotTo(HaveOccurred())
				})

				It("ignores the request", func() {
					Expect(result).To(ContainSubstring("43 80"))
				})
			})
Exemple #27
0
func (s *SignalMsg) Marshal() []byte {
	return ssh.Marshal(*s)
}
Exemple #28
0
func (wc *WindowChangeMsg) Marshal() []byte {
	return ssh.Marshal(*wc)
}
Exemple #29
0
func (s *ContainersMsg) Marshal() []byte {
	return ssh.Marshal(*s)
}
				It("the handler returns", func() {
					Consistently(completed).ShouldNot(Receive())

					Expect(echoHandler.HandleConnectionCallCount()).To(Equal(1))
					echoConn := echoHandler.HandleConnectionArgsForCall(0)
					echoConn.Close()

					Eventually(completed).Should(Receive())
				})
			})
		})
	})

	Context("when the direct-tcpip extra data fails to unmarshal", func() {
		It("rejects the open channel request", func() {
			_, _, err := client.OpenChannel("direct-tcpip", ssh.Marshal(struct{ Bogus int }{Bogus: 1234}))
			Expect(err).To(Equal(&ssh.OpenChannelError{
				Reason:  ssh.ConnectionFailed,
				Message: "Failed to parse open channel message",
			}))

		})
	})

	Context("when dialing the target fails", func() {
		BeforeEach(func() {
			testDialer.DialStub = func(net, addr string) (net.Conn, error) {
				return nil, errors.New("woops")
			}
		})