Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion lib/srv/regular/sshserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,14 @@ func (s *Server) HandleRequest(ctx context.Context, r *ssh.Request) {
case teleport.VersionRequest:
s.handleVersionRequest(r)
case teleport.TerminalSizeRequest:
s.termHandlers.HandleTerminalSize(r)
if err := s.termHandlers.HandleTerminalSize(r); err != nil {
s.Logger.WithError(err).Warn("failed to handle terminal size request")
if r.WantReply {
if err := r.Reply(false, nil); err != nil {
s.Logger.Warnf("Failed to reply to %q request: %v", r.Type, err)
}
}
}
default:
if r.WantReply {
if err := r.Reply(false, nil); err != nil {
Expand Down
42 changes: 42 additions & 0 deletions lib/srv/regular/sshserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package regular

import (
"context"
"encoding/json"
"fmt"
"io"
"io/fs"
Expand All @@ -40,6 +41,7 @@ import (
"github.com/gravitational/trace"
"github.com/jonboulle/clockwork"
"github.com/mailgun/timetools"
"github.com/moby/term"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/ssh"
Expand Down Expand Up @@ -302,6 +304,46 @@ func newCustomFixture(t *testing.T, mutateCfg func(*auth.TestServerConfig), sshO
return f
}

// TestTerminalSizeRequest validates that terminal size requests are processed and
// responded to appropriately. Namely, it ensures that a response is sent if the client
// requests a reply whether processing the request was successful or not.
func TestTerminalSizeRequest(t *testing.T) {
f := newFixtureWithoutDiskBasedLogging(t)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

t.Run("Invalid session", func(t *testing.T) {
ok, resp, err := f.ssh.clt.SendRequest(ctx, teleport.TerminalSizeRequest, true, []byte("1234"))
require.NoError(t, err)
require.False(t, ok)
require.Empty(t, resp)
})

t.Run("Active session", func(t *testing.T) {
se, err := f.ssh.clt.NewSession(ctx)
require.NoError(t, err)
defer se.Close()

require.NoError(t, se.Shell(ctx))

expectedSize := term.Winsize{Height: 100, Width: 200}
require.NoError(t, se.WindowChange(ctx, int(expectedSize.Height), int(expectedSize.Width)))

sessions, err := f.ssh.srv.termHandlers.SessionRegistry.SessionTrackerService.GetActiveSessionTrackers(ctx)
require.NoError(t, err)
require.Len(t, sessions, 1)

ok, resp, err := f.ssh.clt.SendRequest(ctx, teleport.TerminalSizeRequest, true, []byte(sessions[0].GetSessionID()))
require.NoError(t, err)
require.True(t, ok)
require.NotNil(t, resp)

var ws term.Winsize
require.NoError(t, json.Unmarshal(resp, &ws))
require.Empty(t, cmp.Diff(expectedSize, ws, cmp.AllowUnexported(term.Winsize{})))
})
}

// TestMultipleExecCommands asserts that multiple SSH exec commands can not be
// sent over a single SSH channel, which is disallowed by the SSH standard
// https://www.ietf.org/rfc/rfc4254.txt
Expand Down