summaryrefslogtreecommitdiff
path: root/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'packet.c')
-rw-r--r--packet.c149
1 files changed, 1 insertions, 148 deletions
diff --git a/packet.c b/packet.c
index 31499c827..6cec93372 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.249 2017/04/30 23:13:25 djm Exp $ */ 1/* $OpenBSD: packet.c,v 1.250 2017/04/30 23:23:54 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1397,153 +1397,6 @@ ssh_packet_read_expect(struct ssh *ssh, u_int expected_type)
1397 return 0; 1397 return 0;
1398} 1398}
1399 1399
1400/* Checks if a full packet is available in the data received so far via
1401 * packet_process_incoming. If so, reads the packet; otherwise returns
1402 * SSH_MSG_NONE. This does not wait for data from the connection.
1403 *
1404 * SSH_MSG_DISCONNECT is handled specially here. Also,
1405 * SSH_MSG_IGNORE messages are skipped by this function and are never returned
1406 * to higher levels.
1407 */
1408
1409int
1410ssh_packet_read_poll1(struct ssh *ssh, u_char *typep)
1411{
1412 struct session_state *state = ssh->state;
1413 u_int len, padded_len;
1414 const char *emsg;
1415 const u_char *cp;
1416 u_char *p;
1417 u_int checksum, stored_checksum;
1418 int r;
1419
1420 *typep = SSH_MSG_NONE;
1421
1422 /* Check if input size is less than minimum packet size. */
1423 if (sshbuf_len(state->input) < 4 + 8)
1424 return 0;
1425 /* Get length of incoming packet. */
1426 len = PEEK_U32(sshbuf_ptr(state->input));
1427 if (len < 1 + 2 + 2 || len > 256 * 1024) {
1428 if ((r = sshpkt_disconnect(ssh, "Bad packet length %u",
1429 len)) != 0)
1430 return r;
1431 return SSH_ERR_CONN_CORRUPT;
1432 }
1433 padded_len = (len + 8) & ~7;
1434
1435 /* Check if the packet has been entirely received. */
1436 if (sshbuf_len(state->input) < 4 + padded_len)
1437 return 0;
1438
1439 /* The entire packet is in buffer. */
1440
1441 /* Consume packet length. */
1442 if ((r = sshbuf_consume(state->input, 4)) != 0)
1443 goto out;
1444
1445 /*
1446 * Cryptographic attack detector for ssh
1447 * (C)1998 CORE-SDI, Buenos Aires Argentina
1448 * Ariel Futoransky(futo@core-sdi.com)
1449 */
1450 if (!cipher_ctx_is_plaintext(state->receive_context)) {
1451 emsg = NULL;
1452 switch (detect_attack(&state->deattack,
1453 sshbuf_ptr(state->input), padded_len)) {
1454 case DEATTACK_OK:
1455 break;
1456 case DEATTACK_DETECTED:
1457 emsg = "crc32 compensation attack detected";
1458 break;
1459 case DEATTACK_DOS_DETECTED:
1460 emsg = "deattack denial of service detected";
1461 break;
1462 default:
1463 emsg = "deattack error";
1464 break;
1465 }
1466 if (emsg != NULL) {
1467 error("%s", emsg);
1468 if ((r = sshpkt_disconnect(ssh, "%s", emsg)) != 0 ||
1469 (r = ssh_packet_write_wait(ssh)) != 0)
1470 return r;
1471 return SSH_ERR_CONN_CORRUPT;
1472 }
1473 }
1474
1475 /* Decrypt data to incoming_packet. */
1476 sshbuf_reset(state->incoming_packet);
1477 if ((r = sshbuf_reserve(state->incoming_packet, padded_len, &p)) != 0)
1478 goto out;
1479 if ((r = cipher_crypt(state->receive_context, 0, p,
1480 sshbuf_ptr(state->input), padded_len, 0, 0)) != 0)
1481 goto out;
1482
1483 if ((r = sshbuf_consume(state->input, padded_len)) != 0)
1484 goto out;
1485
1486#ifdef PACKET_DEBUG
1487 fprintf(stderr, "read_poll plain: ");
1488 sshbuf_dump(state->incoming_packet, stderr);
1489#endif
1490
1491 /* Compute packet checksum. */
1492 checksum = ssh_crc32(sshbuf_ptr(state->incoming_packet),
1493 sshbuf_len(state->incoming_packet) - 4);
1494
1495 /* Skip padding. */
1496 if ((r = sshbuf_consume(state->incoming_packet, 8 - len % 8)) != 0)
1497 goto out;
1498
1499 /* Test check bytes. */
1500 if (len != sshbuf_len(state->incoming_packet)) {
1501 error("%s: len %d != sshbuf_len %zd", __func__,
1502 len, sshbuf_len(state->incoming_packet));
1503 if ((r = sshpkt_disconnect(ssh, "invalid packet length")) != 0 ||
1504 (r = ssh_packet_write_wait(ssh)) != 0)
1505 return r;
1506 return SSH_ERR_CONN_CORRUPT;
1507 }
1508
1509 cp = sshbuf_ptr(state->incoming_packet) + len - 4;
1510 stored_checksum = PEEK_U32(cp);
1511 if (checksum != stored_checksum) {
1512 error("Corrupted check bytes on input");
1513 if ((r = sshpkt_disconnect(ssh, "connection corrupted")) != 0 ||
1514 (r = ssh_packet_write_wait(ssh)) != 0)
1515 return r;
1516 return SSH_ERR_CONN_CORRUPT;
1517 }
1518 if ((r = sshbuf_consume_end(state->incoming_packet, 4)) < 0)
1519 goto out;
1520
1521 if (state->packet_compression) {
1522 sshbuf_reset(state->compression_buffer);
1523 if ((r = uncompress_buffer(ssh, state->incoming_packet,
1524 state->compression_buffer)) != 0)
1525 goto out;
1526 sshbuf_reset(state->incoming_packet);
1527 if ((r = sshbuf_putb(state->incoming_packet,
1528 state->compression_buffer)) != 0)
1529 goto out;
1530 }
1531 state->p_read.packets++;
1532 state->p_read.bytes += padded_len + 4;
1533 if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0)
1534 goto out;
1535 if (*typep < SSH_MSG_MIN || *typep > SSH_MSG_MAX) {
1536 error("Invalid ssh1 packet type: %d", *typep);
1537 if ((r = sshpkt_disconnect(ssh, "invalid packet type")) != 0 ||
1538 (r = ssh_packet_write_wait(ssh)) != 0)
1539 return r;
1540 return SSH_ERR_PROTOCOL_ERROR;
1541 }
1542 r = 0;
1543 out:
1544 return r;
1545}
1546
1547static int 1400static int
1548ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) 1401ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
1549{ 1402{