func handleChannel(newChannel ssh.NewChannel, rClient *ssh.Client) { if newChannel.ChannelType() != "session" { newChannel.Reject(ssh.UnknownChannelType, "unknown channel type: "+newChannel.ChannelType()) return } psChannel, psRequests, err := newChannel.Accept() if err != nil { panic("could not accept channel.") } sChannel, sRequests, err := rClient.OpenChannel(newChannel.ChannelType(), nil) if err != nil { panic("Failed to create session: " + err.Error()) } go pipeRequests(psChannel, sChannel, psRequests, sRequests) time.Sleep(50 * time.Millisecond) go pipe(sChannel, psChannel) go pipe(psChannel, sChannel) }
// SSHAttach returns a stream connection to the requested session // The ssh client is assumed to be connected to the Executor hosting the session func SSHAttach(client *ssh.Client, id string) (SessionInteraction, error) { defer trace.End(trace.Begin("")) sessionSSH := &attachSSH{ client: client, } var err error sessionSSH.channel, sessionSSH.requests, err = client.OpenChannel(attachChannelType, []byte(id)) if err != nil { return nil, err } // we have to handle incoming requests to the client on this channel but we don't support any currently go func() { for req := range sessionSSH.requests { // default, preserving OpenSSH behaviour req.Reply(false, nil) } }() return sessionSSH, nil }
It("does not terminate the session", func() { response, err := session.Output("/bin/echo -n Hello") Expect(err).NotTo(HaveOccurred()) Expect(response).To(Equal([]byte("Hello"))) }) }) }) Context("when a session channel is opened", func() { var channel ssh.Channel var requests <-chan *ssh.Request BeforeEach(func() { var err error channel, requests, err = client.OpenChannel("session", nil) Expect(err).NotTo(HaveOccurred()) go ssh.DiscardRequests(requests) }) AfterEach(func() { if channel != nil { channel.Close() } }) Context("and an exec request fails to unmarshal", func() { It("rejects the request", func() { accepted, err := channel.SendRequest("exec", true, ssh.Marshal(struct{ Bogus uint32 }{Bogus: 1138})) Expect(err).NotTo(HaveOccurred())
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") } })
}) }) Context("when the client requests a new channel", func() { var newChannelHandler *fake_handlers.FakeNewChannelHandler BeforeEach(func() { newChannelHandler = &fake_handlers.FakeNewChannelHandler{} newChannelHandler.HandleNewChannelStub = func(logger lager.Logger, newChannel ssh.NewChannel) { newChannel.Reject(ssh.Prohibited, "not now") } daemonNewChannelHandlers["test"] = newChannelHandler }) It("gets forwarded to the daemon", func() { _, _, err := client.OpenChannel("test", nil) Expect(err).To(Equal(&ssh.OpenChannelError{Reason: ssh.Prohibited, Message: "not now"})) }) }) }) Describe("target requests to client", func() { var ( connectionHandler *server_fakes.FakeConnectionHandler target *server.Server listener net.Listener targetAddress string clientConn ssh.Conn clientChannels <-chan ssh.NewChannel
AfterEach(func() { client.Close() }) Context("when a new channel request is received", func() { var ( channelType string sshChannel ssh.Channel requestChan <-chan *ssh.Request openError error ) JustBeforeEach(func() { sshChannel, requestChan, openError = client.OpenChannel(channelType, []byte("extra-data")) }) Context("and there is an associated handler", func() { BeforeEach(func() { channelType = "known-channel-type" fakeHandler.HandleNewChannelStub = func(logger lager.Logger, newChannel ssh.NewChannel) { ch, _, err := newChannel.Accept() Expect(err).NotTo(HaveOccurred()) ch.Close() } }) It("calls the handler to process the new channel request", func() { Expect(fakeHandler.HandleNewChannelCallCount()).To(Equal(1))