Skip to content

Commit 215ab9e

Browse files
authored
Merge pull request #294 from Castaglia/single-payload-len-check
Attempting to keep the SSH packet reading code in `mod_proxy` more in…
2 parents 52889fd + 97fead7 commit 215ab9e

File tree

1 file changed

+51
-80
lines changed

1 file changed

+51
-80
lines changed

lib/proxy/ssh/packet.c

Lines changed: 51 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ static int read_packet_payload(conn_t *conn, struct proxy_ssh_packet *pkt,
732732
return -1;
733733
}
734734

735-
pkt->payload = pcalloc(pkt->pool, payload_len);
735+
pkt->payload = palloc(pkt->pool, payload_len);
736736
}
737737

738738
/* If there's data in the buffer we received, it's probably already part
@@ -762,7 +762,7 @@ static int read_packet_payload(conn_t *conn, struct proxy_ssh_packet *pkt,
762762
* modes.
763763
*/
764764
if (padding_len > 0) {
765-
pkt->padding = pcalloc(pkt->pool, padding_len);
765+
pkt->padding = palloc(pkt->pool, padding_len);
766766
}
767767

768768
/* If there's data in the buffer we received, it's probably already part
@@ -1082,62 +1082,6 @@ static void reset_timers(void) {
10821082
}
10831083
}
10841084

1085-
static int check_packet_lengths(conn_t *conn, struct proxy_ssh_packet *pkt) {
1086-
if (pkt->packet_len < 5) {
1087-
(void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
1088-
"packet length too short (%lu), less than minimum packet length (5)",
1089-
(unsigned long) pkt->packet_len);
1090-
read_packet_discard(conn);
1091-
return -1;
1092-
}
1093-
1094-
if (pkt->packet_len > PROXY_SSH_MAX_PACKET_LEN) {
1095-
(void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
1096-
"packet length too long (%lu), exceeds maximum packet length (%lu)",
1097-
(unsigned long) pkt->packet_len,
1098-
(unsigned long) PROXY_SSH_MAX_PACKET_LEN);
1099-
read_packet_discard(conn);
1100-
return -1;
1101-
}
1102-
1103-
/* Per Section 6 of RFC4253, the minimum padding length is 4, the
1104-
* maximum padding length is 255.
1105-
*/
1106-
1107-
if (pkt->padding_len < PROXY_SSH_MIN_PADDING_LEN) {
1108-
(void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
1109-
"padding length too short (%u), less than minimum padding length (%u)",
1110-
(unsigned int) pkt->padding_len,
1111-
(unsigned int) PROXY_SSH_MIN_PADDING_LEN);
1112-
read_packet_discard(conn);
1113-
return -1;
1114-
}
1115-
1116-
if (pkt->padding_len > pkt->packet_len) {
1117-
(void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
1118-
"padding length too long (%u), exceeds packet length (%lu)",
1119-
(unsigned int) pkt->padding_len, (unsigned long) pkt->packet_len);
1120-
read_packet_discard(conn);
1121-
return -1;
1122-
}
1123-
1124-
/* XXX I'm not so sure about this check; we SHOULD have a maximum payload
1125-
* check, but using the max packet length check for the payload length seems
1126-
* awkward. Still, better than nothing.
1127-
*/
1128-
if (pkt->payload_len > PROXY_SSH_MAX_PACKET_LEN) {
1129-
(void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
1130-
"payload length too long (%lu), exceeds maximum payload length (%lu) "
1131-
"(packet len %lu, padding len %u)", (unsigned long) pkt->payload_len,
1132-
(unsigned long) PROXY_SSH_MAX_PACKET_LEN, (unsigned long) pkt->packet_len,
1133-
(unsigned int) pkt->padding_len);
1134-
read_packet_discard(conn);
1135-
return -1;
1136-
}
1137-
1138-
return 0;
1139-
}
1140-
11411085
int proxy_ssh_packet_read(conn_t *conn, struct proxy_ssh_packet *pkt) {
11421086
unsigned char buf[PROXY_SSH_MAX_PACKET_LEN];
11431087
size_t buflen, bufsz = PROXY_SSH_MAX_PACKET_LEN, offset = 0, auth_len = 0;
@@ -1211,15 +1155,10 @@ int proxy_ssh_packet_read(conn_t *conn, struct proxy_ssh_packet *pkt) {
12111155
(unsigned int) pkt->padding_len);
12121156

12131157
pkt->payload_len = (pkt->packet_len - pkt->padding_len - 1);
1214-
1215-
if (check_packet_lengths(conn, pkt) < 0) {
1216-
return -1;
1217-
}
1158+
pr_trace_msg(trace_channel, 20, "SSH2 packet payload len = %u bytes",
1159+
(unsigned int) pkt->payload_len);
12181160
}
12191161

1220-
pr_trace_msg(trace_channel, 20, "SSH2 packet payload len = %lu bytes",
1221-
(unsigned long) pkt->payload_len);
1222-
12231162
/* Read both payload and padding, since we may need to have both before
12241163
* decrypting the data.
12251164
*/
@@ -1237,7 +1176,7 @@ int proxy_ssh_packet_read(conn_t *conn, struct proxy_ssh_packet *pkt) {
12371176

12381177
if (etm_mac == TRUE) {
12391178
bufsz2 = buflen2 = pkt->mac_len;
1240-
buf2 = pcalloc(pkt->pool, bufsz2);
1179+
buf2 = palloc(pkt->pool, bufsz2);
12411180

12421181
/* The MAC routines assume the presence of the necessary data in
12431182
* pkt->payload, so we temporarily put our encrypted packet data there.
@@ -1270,7 +1209,7 @@ int proxy_ssh_packet_read(conn_t *conn, struct proxy_ssh_packet *pkt) {
12701209
* packet from read_packet_payload().
12711210
*/
12721211
bufsz2 = buflen2 = PROXY_SSH_MAX_PACKET_LEN;
1273-
buf2 = pcalloc(pkt->pool, bufsz2);
1212+
buf2 = palloc(pkt->pool, bufsz2);
12741213

12751214
if (proxy_ssh_cipher_read_data(pkt, buf, buflen, &buf2,
12761215
(uint32_t *) &buflen2) < 0) {
@@ -1290,9 +1229,19 @@ int proxy_ssh_packet_read(conn_t *conn, struct proxy_ssh_packet *pkt) {
12901229
pr_trace_msg(trace_channel, 20, "SSH2 packet padding len = %u bytes",
12911230
(unsigned int) pkt->padding_len);
12921231

1293-
} else {
1294-
memset(buf, 0, sizeof(buf));
1232+
pkt->payload_len = (pkt->packet_len - pkt->padding_len - 1);
1233+
pr_trace_msg(trace_channel, 20, "SSH2 packet payload len = %lu bytes",
1234+
(unsigned long) pkt->payload_len);
12951235

1236+
if (pkt->payload_len > 0) {
1237+
pkt->payload = palloc(pkt->pool, pkt->payload_len);
1238+
memmove(pkt->payload, buf2 + offset, pkt->payload_len);
1239+
}
1240+
1241+
pkt->padding = palloc(pkt->pool, pkt->padding_len);
1242+
memmove(pkt->padding, buf2 + offset + pkt->payload_len, pkt->padding_len);
1243+
1244+
} else {
12961245
if (read_packet_mac(conn, pkt, buf) < 0) {
12971246
(void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
12981247
"unable to read MAC from socket %d", conn->rfd);
@@ -1319,20 +1268,42 @@ int proxy_ssh_packet_read(conn_t *conn, struct proxy_ssh_packet *pkt) {
13191268
* correct.
13201269
*/
13211270

1322-
if (etm_mac == TRUE) {
1323-
pkt->payload_len = (pkt->packet_len - pkt->padding_len - 1);
1271+
if (pkt->packet_len < 5) {
1272+
(void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
1273+
"packet length too short (%lu), less than minimum packet length (5)",
1274+
(unsigned long) pkt->packet_len);
1275+
read_packet_discard(conn);
1276+
return -1;
1277+
}
13241278

1325-
if (check_packet_lengths(conn, pkt) < 0) {
1326-
return -1;
1327-
}
1279+
if (pkt->packet_len > PROXY_SSH_MAX_PACKET_LEN) {
1280+
(void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
1281+
"packet length too long (%lu), exceeds maximum packet length (%lu)",
1282+
(unsigned long) pkt->packet_len,
1283+
(unsigned long) PROXY_SSH_MAX_PACKET_LEN);
1284+
read_packet_discard(conn);
1285+
return -1;
1286+
}
13281287

1329-
if (pkt->payload_len > 0) {
1330-
pkt->payload = pcalloc(pkt->pool, pkt->payload_len);
1331-
memmove(pkt->payload, buf2 + offset, pkt->payload_len);
1332-
}
1288+
/* Per Section 6 of RFC4253, the minimum padding length is 4, the
1289+
* maximum padding length is 255.
1290+
*/
13331291

1334-
pkt->padding = pcalloc(pkt->pool, pkt->padding_len);
1335-
memmove(pkt->padding, buf2 + offset + pkt->payload_len, pkt->padding_len);
1292+
if (pkt->padding_len < PROXY_SSH_MIN_PADDING_LEN) {
1293+
(void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
1294+
"padding length too short (%u), less than minimum padding length (%u)",
1295+
(unsigned int) pkt->padding_len,
1296+
(unsigned int) PROXY_SSH_MIN_PADDING_LEN);
1297+
read_packet_discard(conn);
1298+
return -1;
1299+
}
1300+
1301+
if (pkt->padding_len > pkt->packet_len) {
1302+
(void) pr_log_writefile(proxy_logfd, MOD_PROXY_VERSION,
1303+
"padding length too long (%u), exceeds packet length (%lu)",
1304+
(unsigned int) pkt->padding_len, (unsigned long) pkt->packet_len);
1305+
read_packet_discard(conn);
1306+
return -1;
13361307
}
13371308

13381309
/* From RFC4253, Section 6:

0 commit comments

Comments
 (0)