diff options
Diffstat (limited to 'packet.c')
-rw-r--r-- | packet.c | 220 |
1 files changed, 143 insertions, 77 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.204 2015/01/28 21:15:47 djm Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.205 2015/01/30 01:13:33 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 |
@@ -272,20 +272,26 @@ ssh_packet_set_connection(struct ssh *ssh, int fd_in, int fd_out) | |||
272 | const struct sshcipher *none = cipher_by_name("none"); | 272 | const struct sshcipher *none = cipher_by_name("none"); |
273 | int r; | 273 | int r; |
274 | 274 | ||
275 | if (none == NULL) | 275 | if (none == NULL) { |
276 | fatal("%s: cannot load cipher 'none'", __func__); | 276 | error("%s: cannot load cipher 'none'", __func__); |
277 | return NULL; | ||
278 | } | ||
277 | if (ssh == NULL) | 279 | if (ssh == NULL) |
278 | ssh = ssh_alloc_session_state(); | 280 | ssh = ssh_alloc_session_state(); |
279 | if (ssh == NULL) | 281 | if (ssh == NULL) { |
280 | fatal("%s: cound not allocate state", __func__); | 282 | error("%s: cound not allocate state", __func__); |
283 | return NULL; | ||
284 | } | ||
281 | state = ssh->state; | 285 | state = ssh->state; |
282 | state->connection_in = fd_in; | 286 | state->connection_in = fd_in; |
283 | state->connection_out = fd_out; | 287 | state->connection_out = fd_out; |
284 | if ((r = cipher_init(&state->send_context, none, | 288 | if ((r = cipher_init(&state->send_context, none, |
285 | (const u_char *)"", 0, NULL, 0, CIPHER_ENCRYPT)) != 0 || | 289 | (const u_char *)"", 0, NULL, 0, CIPHER_ENCRYPT)) != 0 || |
286 | (r = cipher_init(&state->receive_context, none, | 290 | (r = cipher_init(&state->receive_context, none, |
287 | (const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0) | 291 | (const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0) { |
288 | fatal("%s: cipher_init failed: %s", __func__, ssh_err(r)); | 292 | error("%s: cipher_init failed: %s", __func__, ssh_err(r)); |
293 | return NULL; | ||
294 | } | ||
289 | state->newkeys[MODE_IN] = state->newkeys[MODE_OUT] = NULL; | 295 | state->newkeys[MODE_IN] = state->newkeys[MODE_OUT] = NULL; |
290 | deattack_init(&state->deattack); | 296 | deattack_init(&state->deattack); |
291 | return ssh; | 297 | return ssh; |
@@ -893,8 +899,8 @@ ssh_packet_send1(struct ssh *ssh) | |||
893 | 899 | ||
894 | /* | 900 | /* |
895 | * Note that the packet is now only buffered in output. It won't be | 901 | * Note that the packet is now only buffered in output. It won't be |
896 | * actually sent until packet_write_wait or packet_write_poll is | 902 | * actually sent until ssh_packet_write_wait or ssh_packet_write_poll |
897 | * called. | 903 | * is called. |
898 | */ | 904 | */ |
899 | r = 0; | 905 | r = 0; |
900 | out: | 906 | out: |
@@ -1263,8 +1269,12 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1263 | if (setp == NULL) | 1269 | if (setp == NULL) |
1264 | return SSH_ERR_ALLOC_FAIL; | 1270 | return SSH_ERR_ALLOC_FAIL; |
1265 | 1271 | ||
1266 | /* Since we are blocking, ensure that all written packets have been sent. */ | 1272 | /* |
1267 | ssh_packet_write_wait(ssh); | 1273 | * Since we are blocking, ensure that all written packets have |
1274 | * been sent. | ||
1275 | */ | ||
1276 | if ((r = ssh_packet_write_wait(ssh)) != 0) | ||
1277 | return r; | ||
1268 | 1278 | ||
1269 | /* Stay in the loop until we have received a complete packet. */ | 1279 | /* Stay in the loop until we have received a complete packet. */ |
1270 | for (;;) { | 1280 | for (;;) { |
@@ -1351,16 +1361,22 @@ ssh_packet_read(struct ssh *ssh) | |||
1351 | * that given, and gives a fatal error and exits if there is a mismatch. | 1361 | * that given, and gives a fatal error and exits if there is a mismatch. |
1352 | */ | 1362 | */ |
1353 | 1363 | ||
1354 | void | 1364 | int |
1355 | ssh_packet_read_expect(struct ssh *ssh, int expected_type) | 1365 | ssh_packet_read_expect(struct ssh *ssh, u_int expected_type) |
1356 | { | 1366 | { |
1357 | int type; | 1367 | int r; |
1368 | u_char type; | ||
1358 | 1369 | ||
1359 | type = ssh_packet_read(ssh); | 1370 | if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) |
1360 | if (type != expected_type) | 1371 | return r; |
1361 | ssh_packet_disconnect(ssh, | 1372 | if (type != expected_type) { |
1373 | if ((r = sshpkt_disconnect(ssh, | ||
1362 | "Protocol error: expected packet type %d, got %d", | 1374 | "Protocol error: expected packet type %d, got %d", |
1363 | expected_type, type); | 1375 | expected_type, type)) != 0) |
1376 | return r; | ||
1377 | return SSH_ERR_PROTOCOL_ERROR; | ||
1378 | } | ||
1379 | return 0; | ||
1364 | } | 1380 | } |
1365 | 1381 | ||
1366 | /* Checks if a full packet is available in the data received so far via | 1382 | /* Checks if a full packet is available in the data received so far via |
@@ -1377,6 +1393,7 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) | |||
1377 | { | 1393 | { |
1378 | struct session_state *state = ssh->state; | 1394 | struct session_state *state = ssh->state; |
1379 | u_int len, padded_len; | 1395 | u_int len, padded_len; |
1396 | const char *emsg; | ||
1380 | const u_char *cp; | 1397 | const u_char *cp; |
1381 | u_char *p; | 1398 | u_char *p; |
1382 | u_int checksum, stored_checksum; | 1399 | u_int checksum, stored_checksum; |
@@ -1389,9 +1406,12 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) | |||
1389 | return 0; | 1406 | return 0; |
1390 | /* Get length of incoming packet. */ | 1407 | /* Get length of incoming packet. */ |
1391 | len = PEEK_U32(sshbuf_ptr(state->input)); | 1408 | len = PEEK_U32(sshbuf_ptr(state->input)); |
1392 | if (len < 1 + 2 + 2 || len > 256 * 1024) | 1409 | if (len < 1 + 2 + 2 || len > 256 * 1024) { |
1393 | ssh_packet_disconnect(ssh, "Bad packet length %u.", | 1410 | if ((r = sshpkt_disconnect(ssh, "Bad packet length %u", |
1394 | len); | 1411 | len)) != 0) |
1412 | return r; | ||
1413 | return SSH_ERR_CONN_CORRUPT; | ||
1414 | } | ||
1395 | padded_len = (len + 8) & ~7; | 1415 | padded_len = (len + 8) & ~7; |
1396 | 1416 | ||
1397 | /* Check if the packet has been entirely received. */ | 1417 | /* Check if the packet has been entirely received. */ |
@@ -1410,19 +1430,27 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) | |||
1410 | * Ariel Futoransky(futo@core-sdi.com) | 1430 | * Ariel Futoransky(futo@core-sdi.com) |
1411 | */ | 1431 | */ |
1412 | if (!state->receive_context.plaintext) { | 1432 | if (!state->receive_context.plaintext) { |
1433 | emsg = NULL; | ||
1413 | switch (detect_attack(&state->deattack, | 1434 | switch (detect_attack(&state->deattack, |
1414 | sshbuf_ptr(state->input), padded_len)) { | 1435 | sshbuf_ptr(state->input), padded_len)) { |
1415 | case DEATTACK_OK: | 1436 | case DEATTACK_OK: |
1416 | break; | 1437 | break; |
1417 | case DEATTACK_DETECTED: | 1438 | case DEATTACK_DETECTED: |
1418 | ssh_packet_disconnect(ssh, | 1439 | emsg = "crc32 compensation attack detected"; |
1419 | "crc32 compensation attack: network attack detected" | 1440 | break; |
1420 | ); | ||
1421 | case DEATTACK_DOS_DETECTED: | 1441 | case DEATTACK_DOS_DETECTED: |
1422 | ssh_packet_disconnect(ssh, | 1442 | emsg = "deattack denial of service detected"; |
1423 | "deattack denial of service detected"); | 1443 | break; |
1424 | default: | 1444 | default: |
1425 | ssh_packet_disconnect(ssh, "deattack error"); | 1445 | emsg = "deattack error"; |
1446 | break; | ||
1447 | } | ||
1448 | if (emsg != NULL) { | ||
1449 | error("%s", emsg); | ||
1450 | if ((r = sshpkt_disconnect(ssh, "%s", emsg)) != 0 || | ||
1451 | (r = ssh_packet_write_wait(ssh)) != 0) | ||
1452 | return r; | ||
1453 | return SSH_ERR_CONN_CORRUPT; | ||
1426 | } | 1454 | } |
1427 | } | 1455 | } |
1428 | 1456 | ||
@@ -1451,16 +1479,24 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) | |||
1451 | goto out; | 1479 | goto out; |
1452 | 1480 | ||
1453 | /* Test check bytes. */ | 1481 | /* Test check bytes. */ |
1454 | if (len != sshbuf_len(state->incoming_packet)) | 1482 | if (len != sshbuf_len(state->incoming_packet)) { |
1455 | ssh_packet_disconnect(ssh, | 1483 | error("%s: len %d != sshbuf_len %zd", __func__, |
1456 | "packet_read_poll1: len %d != sshbuf_len %zd.", | ||
1457 | len, sshbuf_len(state->incoming_packet)); | 1484 | len, sshbuf_len(state->incoming_packet)); |
1485 | if ((r = sshpkt_disconnect(ssh, "invalid packet length")) != 0 || | ||
1486 | (r = ssh_packet_write_wait(ssh)) != 0) | ||
1487 | return r; | ||
1488 | return SSH_ERR_CONN_CORRUPT; | ||
1489 | } | ||
1458 | 1490 | ||
1459 | cp = sshbuf_ptr(state->incoming_packet) + len - 4; | 1491 | cp = sshbuf_ptr(state->incoming_packet) + len - 4; |
1460 | stored_checksum = PEEK_U32(cp); | 1492 | stored_checksum = PEEK_U32(cp); |
1461 | if (checksum != stored_checksum) | 1493 | if (checksum != stored_checksum) { |
1462 | ssh_packet_disconnect(ssh, | 1494 | error("Corrupted check bytes on input"); |
1463 | "Corrupted check bytes on input."); | 1495 | if ((r = sshpkt_disconnect(ssh, "connection corrupted")) != 0 || |
1496 | (r = ssh_packet_write_wait(ssh)) != 0) | ||
1497 | return r; | ||
1498 | return SSH_ERR_CONN_CORRUPT; | ||
1499 | } | ||
1464 | if ((r = sshbuf_consume_end(state->incoming_packet, 4)) < 0) | 1500 | if ((r = sshbuf_consume_end(state->incoming_packet, 4)) < 0) |
1465 | goto out; | 1501 | goto out; |
1466 | 1502 | ||
@@ -1478,9 +1514,13 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) | |||
1478 | state->p_read.bytes += padded_len + 4; | 1514 | state->p_read.bytes += padded_len + 4; |
1479 | if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) | 1515 | if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) |
1480 | goto out; | 1516 | goto out; |
1481 | if (*typep < SSH_MSG_MIN || *typep > SSH_MSG_MAX) | 1517 | if (*typep < SSH_MSG_MIN || *typep > SSH_MSG_MAX) { |
1482 | ssh_packet_disconnect(ssh, | 1518 | error("Invalid ssh1 packet type: %d", *typep); |
1483 | "Invalid ssh1 packet type: %d", *typep); | 1519 | if ((r = sshpkt_disconnect(ssh, "invalid packet type")) != 0 || |
1520 | (r = ssh_packet_write_wait(ssh)) != 0) | ||
1521 | return r; | ||
1522 | return SSH_ERR_PROTOCOL_ERROR; | ||
1523 | } | ||
1484 | r = 0; | 1524 | r = 0; |
1485 | out: | 1525 | out: |
1486 | return r; | 1526 | return r; |
@@ -1634,7 +1674,6 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1634 | if ((r = sshbuf_consume(state->input, mac->mac_len)) != 0) | 1674 | if ((r = sshbuf_consume(state->input, mac->mac_len)) != 0) |
1635 | goto out; | 1675 | goto out; |
1636 | } | 1676 | } |
1637 | /* XXX now it's safe to use fatal/packet_disconnect */ | ||
1638 | if (seqnr_p != NULL) | 1677 | if (seqnr_p != NULL) |
1639 | *seqnr_p = state->p_read.seqnr; | 1678 | *seqnr_p = state->p_read.seqnr; |
1640 | if (++state->p_read.seqnr == 0) | 1679 | if (++state->p_read.seqnr == 0) |
@@ -1648,9 +1687,13 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1648 | /* get padlen */ | 1687 | /* get padlen */ |
1649 | padlen = sshbuf_ptr(state->incoming_packet)[4]; | 1688 | padlen = sshbuf_ptr(state->incoming_packet)[4]; |
1650 | DBG(debug("input: padlen %d", padlen)); | 1689 | DBG(debug("input: padlen %d", padlen)); |
1651 | if (padlen < 4) | 1690 | if (padlen < 4) { |
1652 | ssh_packet_disconnect(ssh, | 1691 | if ((r = sshpkt_disconnect(ssh, |
1653 | "Corrupted padlen %d on input.", padlen); | 1692 | "Corrupted padlen %d on input.", padlen)) != 0 || |
1693 | (r = ssh_packet_write_wait(ssh)) != 0) | ||
1694 | return r; | ||
1695 | return SSH_ERR_CONN_CORRUPT; | ||
1696 | } | ||
1654 | 1697 | ||
1655 | /* skip packet size + padlen, discard padding */ | 1698 | /* skip packet size + padlen, discard padding */ |
1656 | if ((r = sshbuf_consume(state->incoming_packet, 4 + 1)) != 0 || | 1699 | if ((r = sshbuf_consume(state->incoming_packet, 4 + 1)) != 0 || |
@@ -1677,9 +1720,13 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1677 | */ | 1720 | */ |
1678 | if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) | 1721 | if ((r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) |
1679 | goto out; | 1722 | goto out; |
1680 | if (*typep < SSH2_MSG_MIN || *typep >= SSH2_MSG_LOCAL_MIN) | 1723 | if (*typep < SSH2_MSG_MIN || *typep >= SSH2_MSG_LOCAL_MIN) { |
1681 | ssh_packet_disconnect(ssh, | 1724 | if ((r = sshpkt_disconnect(ssh, |
1682 | "Invalid ssh2 packet type: %d", *typep); | 1725 | "Invalid ssh2 packet type: %d", *typep)) != 0 || |
1726 | (r = ssh_packet_write_wait(ssh)) != 0) | ||
1727 | return r; | ||
1728 | return SSH_ERR_PROTOCOL_ERROR; | ||
1729 | } | ||
1683 | if (*typep == SSH2_MSG_NEWKEYS) | 1730 | if (*typep == SSH2_MSG_NEWKEYS) |
1684 | r = ssh_set_newkeys(ssh, MODE_IN); | 1731 | r = ssh_set_newkeys(ssh, MODE_IN); |
1685 | else if (*typep == SSH2_MSG_USERAUTH_SUCCESS && !state->server_side) | 1732 | else if (*typep == SSH2_MSG_USERAUTH_SUCCESS && !state->server_side) |
@@ -1816,9 +1863,8 @@ ssh_packet_remaining(struct ssh *ssh) | |||
1816 | * message is printed immediately, but only if the client is being executed | 1863 | * message is printed immediately, but only if the client is being executed |
1817 | * in verbose mode. These messages are primarily intended to ease debugging | 1864 | * in verbose mode. These messages are primarily intended to ease debugging |
1818 | * authentication problems. The length of the formatted message must not | 1865 | * authentication problems. The length of the formatted message must not |
1819 | * exceed 1024 bytes. This will automatically call packet_write_wait. | 1866 | * exceed 1024 bytes. This will automatically call ssh_packet_write_wait. |
1820 | */ | 1867 | */ |
1821 | |||
1822 | void | 1868 | void |
1823 | ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...) | 1869 | ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...) |
1824 | { | 1870 | { |
@@ -1846,7 +1892,29 @@ ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...) | |||
1846 | (r = sshpkt_send(ssh)) != 0) | 1892 | (r = sshpkt_send(ssh)) != 0) |
1847 | fatal("%s: %s", __func__, ssh_err(r)); | 1893 | fatal("%s: %s", __func__, ssh_err(r)); |
1848 | } | 1894 | } |
1849 | ssh_packet_write_wait(ssh); | 1895 | if ((r = ssh_packet_write_wait(ssh)) != 0) |
1896 | fatal("%s: %s", __func__, ssh_err(r)); | ||
1897 | } | ||
1898 | |||
1899 | /* | ||
1900 | * Pretty-print connection-terminating errors and exit. | ||
1901 | */ | ||
1902 | void | ||
1903 | sshpkt_fatal(struct ssh *ssh, const char *tag, int r) | ||
1904 | { | ||
1905 | switch (r) { | ||
1906 | case SSH_ERR_CONN_CLOSED: | ||
1907 | logit("Connection closed by %.200s", ssh_remote_ipaddr(ssh)); | ||
1908 | cleanup_exit(255); | ||
1909 | case SSH_ERR_CONN_TIMEOUT: | ||
1910 | logit("Connection to %.200s timed out while " | ||
1911 | "waiting to write", ssh_remote_ipaddr(ssh)); | ||
1912 | cleanup_exit(255); | ||
1913 | default: | ||
1914 | fatal("%s%sConnection to %.200s: %s", | ||
1915 | tag != NULL ? tag : "", tag != NULL ? ": " : "", | ||
1916 | ssh_remote_ipaddr(ssh), ssh_err(r)); | ||
1917 | } | ||
1850 | } | 1918 | } |
1851 | 1919 | ||
1852 | /* | 1920 | /* |
@@ -1855,7 +1923,6 @@ ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...) | |||
1855 | * should not contain a newline. The length of the formatted message must | 1923 | * should not contain a newline. The length of the formatted message must |
1856 | * not exceed 1024 bytes. | 1924 | * not exceed 1024 bytes. |
1857 | */ | 1925 | */ |
1858 | |||
1859 | void | 1926 | void |
1860 | ssh_packet_disconnect(struct ssh *ssh, const char *fmt,...) | 1927 | ssh_packet_disconnect(struct ssh *ssh, const char *fmt,...) |
1861 | { | 1928 | { |
@@ -1879,30 +1946,26 @@ ssh_packet_disconnect(struct ssh *ssh, const char *fmt,...) | |||
1879 | /* Display the error locally */ | 1946 | /* Display the error locally */ |
1880 | logit("Disconnecting: %.100s", buf); | 1947 | logit("Disconnecting: %.100s", buf); |
1881 | 1948 | ||
1882 | /* Send the disconnect message to the other side, and wait for it to get sent. */ | 1949 | /* |
1883 | if (compat20) { | 1950 | * Send the disconnect message to the other side, and wait |
1884 | if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || | 1951 | * for it to get sent. |
1885 | (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 || | 1952 | */ |
1886 | (r = sshpkt_put_cstring(ssh, buf)) != 0 || | 1953 | if ((r = sshpkt_disconnect(ssh, "%s", buf)) != 0) |
1887 | (r = sshpkt_put_cstring(ssh, "")) != 0 || | 1954 | sshpkt_fatal(ssh, __func__, r); |
1888 | (r = sshpkt_send(ssh)) != 0) | 1955 | |
1889 | fatal("%s: %s", __func__, ssh_err(r)); | 1956 | if ((r = ssh_packet_write_wait(ssh)) != 0) |
1890 | } else { | 1957 | sshpkt_fatal(ssh, __func__, r); |
1891 | if ((r = sshpkt_start(ssh, SSH_MSG_DISCONNECT)) != 0 || | ||
1892 | (r = sshpkt_put_cstring(ssh, buf)) != 0 || | ||
1893 | (r = sshpkt_send(ssh)) != 0) | ||
1894 | fatal("%s: %s", __func__, ssh_err(r)); | ||
1895 | } | ||
1896 | ssh_packet_write_wait(ssh); | ||
1897 | 1958 | ||
1898 | /* Close the connection. */ | 1959 | /* Close the connection. */ |
1899 | ssh_packet_close(ssh); | 1960 | ssh_packet_close(ssh); |
1900 | cleanup_exit(255); | 1961 | cleanup_exit(255); |
1901 | } | 1962 | } |
1902 | 1963 | ||
1903 | /* Checks if there is any buffered output, and tries to write some of the output. */ | 1964 | /* |
1904 | 1965 | * Checks if there is any buffered output, and tries to write some of | |
1905 | void | 1966 | * the output. |
1967 | */ | ||
1968 | int | ||
1906 | ssh_packet_write_poll(struct ssh *ssh) | 1969 | ssh_packet_write_poll(struct ssh *ssh) |
1907 | { | 1970 | { |
1908 | struct session_state *state = ssh->state; | 1971 | struct session_state *state = ssh->state; |
@@ -1916,33 +1979,33 @@ ssh_packet_write_poll(struct ssh *ssh) | |||
1916 | if (len == -1) { | 1979 | if (len == -1) { |
1917 | if (errno == EINTR || errno == EAGAIN || | 1980 | if (errno == EINTR || errno == EAGAIN || |
1918 | errno == EWOULDBLOCK) | 1981 | errno == EWOULDBLOCK) |
1919 | return; | 1982 | return 0; |
1920 | fatal("Write failed: %.100s", strerror(errno)); | 1983 | return SSH_ERR_SYSTEM_ERROR; |
1921 | } | 1984 | } |
1922 | if (len == 0 && !cont) | 1985 | if (len == 0 && !cont) |
1923 | fatal("Write connection closed"); | 1986 | return SSH_ERR_CONN_CLOSED; |
1924 | if ((r = sshbuf_consume(state->output, len)) != 0) | 1987 | if ((r = sshbuf_consume(state->output, len)) != 0) |
1925 | fatal("%s: %s", __func__, ssh_err(r)); | 1988 | return r; |
1926 | } | 1989 | } |
1990 | return 0; | ||
1927 | } | 1991 | } |
1928 | 1992 | ||
1929 | /* | 1993 | /* |
1930 | * Calls packet_write_poll repeatedly until all pending output data has been | 1994 | * Calls packet_write_poll repeatedly until all pending output data has been |
1931 | * written. | 1995 | * written. |
1932 | */ | 1996 | */ |
1933 | 1997 | int | |
1934 | void | ||
1935 | ssh_packet_write_wait(struct ssh *ssh) | 1998 | ssh_packet_write_wait(struct ssh *ssh) |
1936 | { | 1999 | { |
1937 | fd_set *setp; | 2000 | fd_set *setp; |
1938 | int ret, ms_remain = 0; | 2001 | int ret, r, ms_remain = 0; |
1939 | struct timeval start, timeout, *timeoutp = NULL; | 2002 | struct timeval start, timeout, *timeoutp = NULL; |
1940 | struct session_state *state = ssh->state; | 2003 | struct session_state *state = ssh->state; |
1941 | 2004 | ||
1942 | setp = (fd_set *)calloc(howmany(state->connection_out + 1, | 2005 | setp = (fd_set *)calloc(howmany(state->connection_out + 1, |
1943 | NFDBITS), sizeof(fd_mask)); | 2006 | NFDBITS), sizeof(fd_mask)); |
1944 | if (setp == NULL) | 2007 | if (setp == NULL) |
1945 | fatal("%s: calloc failed", __func__); | 2008 | return SSH_ERR_ALLOC_FAIL; |
1946 | ssh_packet_write_poll(ssh); | 2009 | ssh_packet_write_poll(ssh); |
1947 | while (ssh_packet_have_data_to_write(ssh)) { | 2010 | while (ssh_packet_have_data_to_write(ssh)) { |
1948 | memset(setp, 0, howmany(state->connection_out + 1, | 2011 | memset(setp, 0, howmany(state->connection_out + 1, |
@@ -1973,13 +2036,16 @@ ssh_packet_write_wait(struct ssh *ssh) | |||
1973 | } | 2036 | } |
1974 | } | 2037 | } |
1975 | if (ret == 0) { | 2038 | if (ret == 0) { |
1976 | logit("Connection to %.200s timed out while " | 2039 | free(setp); |
1977 | "waiting to write", ssh_remote_ipaddr(ssh)); | 2040 | return SSH_ERR_CONN_TIMEOUT; |
1978 | cleanup_exit(255); | 2041 | } |
2042 | if ((r = ssh_packet_write_poll(ssh)) != 0) { | ||
2043 | free(setp); | ||
2044 | return r; | ||
1979 | } | 2045 | } |
1980 | ssh_packet_write_poll(ssh); | ||
1981 | } | 2046 | } |
1982 | free(setp); | 2047 | free(setp); |
2048 | return 0; | ||
1983 | } | 2049 | } |
1984 | 2050 | ||
1985 | /* Returns true if there is buffered data to write to the connection. */ | 2051 | /* Returns true if there is buffered data to write to the connection. */ |