diff options
Diffstat (limited to 'packet.c')
-rw-r--r-- | packet.c | 149 |
1 files changed, 1 insertions, 148 deletions
@@ -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 | |||
1409 | int | ||
1410 | ssh_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 | |||
1547 | static int | 1400 | static int |
1548 | ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | 1401 | ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) |
1549 | { | 1402 | { |