Skip to content

Commit e0118c5

Browse files
committed
Reject a window-change on a channel with no pty
A window-change arriving before any pty-req had nothing to resize, but the size was stored and the resize callback run anyway. Dropbear refuses the same request for the same reason. - Reject it with the existing rej path, so no reply is sent for a request RFC 4254 sec 6.7 says takes none, and the session continues. - unit.c covers the rejection, and now drives a real pty-req, which had no coverage on the receive side at all.
1 parent 78810b4 commit e0118c5

2 files changed

Lines changed: 78 additions & 2 deletions

File tree

src/internal.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11537,7 +11537,13 @@ static int DoChannelRequest(WOLFSSH* ssh,
1153711537
if (ret == WS_SUCCESS)
1153811538
ret = GetUint32(&heightPixels, buf, len, &begin);
1153911539

11540-
if (ret == WS_SUCCESS) {
11540+
if (ret == WS_SUCCESS && !channel->ptyReq) {
11541+
/* Nothing to resize without a pty on this channel. Dropbear
11542+
* refuses the same request for the same reason. */
11543+
WLOG(WS_LOG_DEBUG, " no pty on this channel, rejecting.");
11544+
rej = 1;
11545+
}
11546+
else if (ret == WS_SUCCESS) {
1154111547
SetTerminalSize(ssh, widthChar, heightRows,
1154211548
widthPixels, heightPixels);
1154311549
WLOG(WS_LOG_DEBUG, " widthChar = %u", ssh->widthChar);

tests/unit.c

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6705,7 +6705,8 @@ static int test_DoChannelRequest(void)
67056705
#endif /* WOLFSSH_TERM || WOLFSSH_SHELL */
67066706

67076707
/* RFC 4254 sec 6.7: window-change must not send a reply even if the
6708-
* wire wantReply byte is 1. */
6708+
* wire wantReply byte is 1. No pty-req has been seen on this channel
6709+
* yet, so the request is also rejected and the size stays put. */
67096710
#if defined(WOLFSSH_SHELL) && defined(WOLFSSH_TERM)
67106711
{
67116712
static const byte payWindowChange[] = {
@@ -6739,6 +6740,75 @@ static int test_DoChannelRequest(void)
67396740
result = -451;
67406741
goto done;
67416742
}
6743+
if (ssh->widthChar != 0 || ssh->heightRows != 0) {
6744+
printf("DoChannelRequest[window-change]: applied %ux%u without "
6745+
"a pty\n", ssh->widthChar, ssh->heightRows);
6746+
result = -452;
6747+
goto done;
6748+
}
6749+
}
6750+
6751+
/* A pty-req establishes the pty and the size, and runs the same
6752+
* clamping the window-change branch does. */
6753+
{
6754+
static byte payPtyReq[] = {
6755+
0x00,0x00,0x00,0x00, /* channelId = 0 */
6756+
0x00,0x00,0x00,0x07, /* typeSz = 7 */
6757+
0x70,0x74,0x79,0x2D,0x72,0x65,0x71, /* "pty-req" */
6758+
0x00, /* wantReply = 0 */
6759+
0x00,0x00,0x00,0x05, /* termSz = 5 */
6760+
0x76,0x74,0x31,0x30,0x30, /* "vt100" */
6761+
0x00,0x00,0x00,0x50, /* widthChar = 80 */
6762+
0x00,0x00,0x00,0x18, /* heightRows = 24 */
6763+
0x00,0x00,0x02,0x80, /* widthPixels = 640 */
6764+
0x00,0x00,0x01,0xE0, /* heightPixels = 480 */
6765+
0x00,0x00,0x00,0x01, /* modesSz = 1 */
6766+
0x00 /* TTY_OP_END */
6767+
};
6768+
/* offsets of the four dimensions within the payload above */
6769+
const word32 pwcOff = 25, phrOff = 29, pwpOff = 33, phpOff = 37;
6770+
word32 idx2 = 0;
6771+
int ret2;
6772+
6773+
ret2 = wolfSSH_TestDoChannelRequest(ssh, payPtyReq,
6774+
(word32)sizeof(payPtyReq), &idx2);
6775+
if (ret2 != WS_SUCCESS) {
6776+
printf("DoChannelRequest[pty-req]: ret=%d, expected=%d\n",
6777+
ret2, WS_SUCCESS);
6778+
result = -453;
6779+
goto done;
6780+
}
6781+
if (ssh->widthChar != 80 || ssh->heightRows != 24 ||
6782+
ssh->widthPixels != 640 || ssh->heightPixels != 480) {
6783+
printf("DoChannelRequest[pty-req]: got %ux%u %ux%u, "
6784+
"expected 80x24 640x480\n", ssh->widthChar,
6785+
ssh->heightRows, ssh->widthPixels, ssh->heightPixels);
6786+
result = -454;
6787+
goto done;
6788+
}
6789+
6790+
/* the clamp is on the pty-req path too, pixels included */
6791+
PutU32BE(payPtyReq + pwcOff, 0x10000);
6792+
PutU32BE(payPtyReq + phrOff, 0x10000);
6793+
PutU32BE(payPtyReq + pwpOff, 0xFFFFFFFF);
6794+
PutU32BE(payPtyReq + phpOff, 0xFFFFFFFF);
6795+
idx2 = 0;
6796+
ret2 = wolfSSH_TestDoChannelRequest(ssh, payPtyReq,
6797+
(word32)sizeof(payPtyReq), &idx2);
6798+
if (ret2 != WS_SUCCESS) {
6799+
printf("DoChannelRequest[pty-req clamp]: ret=%d, expected=%d\n",
6800+
ret2, WS_SUCCESS);
6801+
result = -455;
6802+
goto done;
6803+
}
6804+
if (ssh->widthChar != 65535 || ssh->heightRows != 65535 ||
6805+
ssh->widthPixels != 65535 || ssh->heightPixels != 65535) {
6806+
printf("DoChannelRequest[pty-req clamp]: got %ux%u %ux%u, "
6807+
"expected 65535 throughout\n", ssh->widthChar,
6808+
ssh->heightRows, ssh->widthPixels, ssh->heightPixels);
6809+
result = -456;
6810+
goto done;
6811+
}
67426812
}
67436813

67446814
/* Dimensions are stored as sent, zero included, as others do.

0 commit comments

Comments
 (0)