diff options
Diffstat (limited to 'packet.c')
-rw-r--r-- | packet.c | 395 |
1 files changed, 106 insertions, 289 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.248 2017/04/30 23:10:43 djm Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.249 2017/04/30 23:13:25 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 |
@@ -278,8 +278,8 @@ ssh_packet_set_input_hook(struct ssh *ssh, ssh_packet_hook_fn *hook, void *ctx) | |||
278 | int | 278 | int |
279 | ssh_packet_is_rekeying(struct ssh *ssh) | 279 | ssh_packet_is_rekeying(struct ssh *ssh) |
280 | { | 280 | { |
281 | return compat20 && | 281 | return ssh->state->rekeying || |
282 | (ssh->state->rekeying || (ssh->kex != NULL && ssh->kex->done == 0)); | 282 | (ssh->kex != NULL && ssh->kex->done == 0); |
283 | } | 283 | } |
284 | 284 | ||
285 | /* | 285 | /* |
@@ -698,7 +698,7 @@ ssh_packet_start_compression(struct ssh *ssh, int level) | |||
698 | { | 698 | { |
699 | int r; | 699 | int r; |
700 | 700 | ||
701 | if (ssh->state->packet_compression && !compat20) | 701 | if (ssh->state->packet_compression) |
702 | return SSH_ERR_INTERNAL_ERROR; | 702 | return SSH_ERR_INTERNAL_ERROR; |
703 | ssh->state->packet_compression = 1; | 703 | ssh->state->packet_compression = 1; |
704 | if ((r = ssh_packet_init_compression(ssh)) != 0 || | 704 | if ((r = ssh_packet_init_compression(ssh)) != 0 || |
@@ -814,99 +814,6 @@ ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, | |||
814 | fatal("no SSH protocol 1 support"); | 814 | fatal("no SSH protocol 1 support"); |
815 | } | 815 | } |
816 | 816 | ||
817 | /* | ||
818 | * Finalizes and sends the packet. If the encryption key has been set, | ||
819 | * encrypts the packet before sending. | ||
820 | */ | ||
821 | |||
822 | int | ||
823 | ssh_packet_send1(struct ssh *ssh) | ||
824 | { | ||
825 | struct session_state *state = ssh->state; | ||
826 | u_char buf[8], *cp; | ||
827 | int r, padding, len; | ||
828 | u_int checksum; | ||
829 | |||
830 | /* | ||
831 | * If using packet compression, compress the payload of the outgoing | ||
832 | * packet. | ||
833 | */ | ||
834 | if (state->packet_compression) { | ||
835 | sshbuf_reset(state->compression_buffer); | ||
836 | /* Skip padding. */ | ||
837 | if ((r = sshbuf_consume(state->outgoing_packet, 8)) != 0) | ||
838 | goto out; | ||
839 | /* padding */ | ||
840 | if ((r = sshbuf_put(state->compression_buffer, | ||
841 | "\0\0\0\0\0\0\0\0", 8)) != 0) | ||
842 | goto out; | ||
843 | if ((r = compress_buffer(ssh, state->outgoing_packet, | ||
844 | state->compression_buffer)) != 0) | ||
845 | goto out; | ||
846 | sshbuf_reset(state->outgoing_packet); | ||
847 | if ((r = sshbuf_putb(state->outgoing_packet, | ||
848 | state->compression_buffer)) != 0) | ||
849 | goto out; | ||
850 | } | ||
851 | /* Compute packet length without padding (add checksum, remove padding). */ | ||
852 | len = sshbuf_len(state->outgoing_packet) + 4 - 8; | ||
853 | |||
854 | /* Insert padding. Initialized to zero in packet_start1() */ | ||
855 | padding = 8 - len % 8; | ||
856 | if (!cipher_ctx_is_plaintext(state->send_context)) { | ||
857 | cp = sshbuf_mutable_ptr(state->outgoing_packet); | ||
858 | if (cp == NULL) { | ||
859 | r = SSH_ERR_INTERNAL_ERROR; | ||
860 | goto out; | ||
861 | } | ||
862 | arc4random_buf(cp + 8 - padding, padding); | ||
863 | } | ||
864 | if ((r = sshbuf_consume(state->outgoing_packet, 8 - padding)) != 0) | ||
865 | goto out; | ||
866 | |||
867 | /* Add check bytes. */ | ||
868 | checksum = ssh_crc32(sshbuf_ptr(state->outgoing_packet), | ||
869 | sshbuf_len(state->outgoing_packet)); | ||
870 | POKE_U32(buf, checksum); | ||
871 | if ((r = sshbuf_put(state->outgoing_packet, buf, 4)) != 0) | ||
872 | goto out; | ||
873 | |||
874 | #ifdef PACKET_DEBUG | ||
875 | fprintf(stderr, "packet_send plain: "); | ||
876 | sshbuf_dump(state->outgoing_packet, stderr); | ||
877 | #endif | ||
878 | |||
879 | /* Append to output. */ | ||
880 | POKE_U32(buf, len); | ||
881 | if ((r = sshbuf_put(state->output, buf, 4)) != 0) | ||
882 | goto out; | ||
883 | if ((r = sshbuf_reserve(state->output, | ||
884 | sshbuf_len(state->outgoing_packet), &cp)) != 0) | ||
885 | goto out; | ||
886 | if ((r = cipher_crypt(state->send_context, 0, cp, | ||
887 | sshbuf_ptr(state->outgoing_packet), | ||
888 | sshbuf_len(state->outgoing_packet), 0, 0)) != 0) | ||
889 | goto out; | ||
890 | |||
891 | #ifdef PACKET_DEBUG | ||
892 | fprintf(stderr, "encrypted: "); | ||
893 | sshbuf_dump(state->output, stderr); | ||
894 | #endif | ||
895 | state->p_send.packets++; | ||
896 | state->p_send.bytes += len + | ||
897 | sshbuf_len(state->outgoing_packet); | ||
898 | sshbuf_reset(state->outgoing_packet); | ||
899 | |||
900 | /* | ||
901 | * Note that the packet is now only buffered in output. It won't be | ||
902 | * actually sent until ssh_packet_write_wait or ssh_packet_write_poll | ||
903 | * is called. | ||
904 | */ | ||
905 | r = 0; | ||
906 | out: | ||
907 | return r; | ||
908 | } | ||
909 | |||
910 | int | 817 | int |
911 | ssh_set_newkeys(struct ssh *ssh, int mode) | 818 | ssh_set_newkeys(struct ssh *ssh, int mode) |
912 | { | 819 | { |
@@ -1397,13 +1304,6 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1397 | r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p); | 1304 | r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p); |
1398 | if (r != 0) | 1305 | if (r != 0) |
1399 | break; | 1306 | break; |
1400 | if (!compat20 && ( | ||
1401 | *typep == SSH_SMSG_SUCCESS | ||
1402 | || *typep == SSH_SMSG_FAILURE | ||
1403 | || *typep == SSH_CMSG_EOF | ||
1404 | || *typep == SSH_CMSG_EXIT_CONFIRMATION)) | ||
1405 | if ((r = sshpkt_get_end(ssh)) != 0) | ||
1406 | break; | ||
1407 | /* If we got a packet, return it. */ | 1307 | /* If we got a packet, return it. */ |
1408 | if (*typep != SSH_MSG_NONE) | 1308 | if (*typep != SSH_MSG_NONE) |
1409 | break; | 1309 | break; |
@@ -1924,75 +1824,48 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1924 | 1824 | ||
1925 | for (;;) { | 1825 | for (;;) { |
1926 | msg = NULL; | 1826 | msg = NULL; |
1927 | if (compat20) { | 1827 | r = ssh_packet_read_poll2(ssh, typep, seqnr_p); |
1928 | r = ssh_packet_read_poll2(ssh, typep, seqnr_p); | 1828 | if (r != 0) |
1929 | if (r != 0) | 1829 | return r; |
1930 | return r; | 1830 | if (*typep) { |
1931 | if (*typep) { | 1831 | state->keep_alive_timeouts = 0; |
1932 | state->keep_alive_timeouts = 0; | 1832 | DBG(debug("received packet type %d", *typep)); |
1933 | DBG(debug("received packet type %d", *typep)); | 1833 | } |
1934 | } | 1834 | switch (*typep) { |
1935 | switch (*typep) { | 1835 | case SSH2_MSG_IGNORE: |
1936 | case SSH2_MSG_IGNORE: | 1836 | debug3("Received SSH2_MSG_IGNORE"); |
1937 | debug3("Received SSH2_MSG_IGNORE"); | 1837 | break; |
1938 | break; | 1838 | case SSH2_MSG_DEBUG: |
1939 | case SSH2_MSG_DEBUG: | 1839 | if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || |
1940 | if ((r = sshpkt_get_u8(ssh, NULL)) != 0 || | 1840 | (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || |
1941 | (r = sshpkt_get_string(ssh, &msg, NULL)) != 0 || | 1841 | (r = sshpkt_get_string(ssh, NULL, NULL)) != 0) { |
1942 | (r = sshpkt_get_string(ssh, NULL, NULL)) != 0) { | ||
1943 | free(msg); | ||
1944 | return r; | ||
1945 | } | ||
1946 | debug("Remote: %.900s", msg); | ||
1947 | free(msg); | ||
1948 | break; | ||
1949 | case SSH2_MSG_DISCONNECT: | ||
1950 | if ((r = sshpkt_get_u32(ssh, &reason)) != 0 || | ||
1951 | (r = sshpkt_get_string(ssh, &msg, NULL)) != 0) | ||
1952 | return r; | ||
1953 | /* Ignore normal client exit notifications */ | ||
1954 | do_log2(ssh->state->server_side && | ||
1955 | reason == SSH2_DISCONNECT_BY_APPLICATION ? | ||
1956 | SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, | ||
1957 | "Received disconnect from %s port %d:" | ||
1958 | "%u: %.400s", ssh_remote_ipaddr(ssh), | ||
1959 | ssh_remote_port(ssh), reason, msg); | ||
1960 | free(msg); | ||
1961 | return SSH_ERR_DISCONNECTED; | ||
1962 | case SSH2_MSG_UNIMPLEMENTED: | ||
1963 | if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0) | ||
1964 | return r; | ||
1965 | debug("Received SSH2_MSG_UNIMPLEMENTED for %u", | ||
1966 | seqnr); | ||
1967 | break; | ||
1968 | default: | ||
1969 | return 0; | ||
1970 | } | ||
1971 | } else { | ||
1972 | r = ssh_packet_read_poll1(ssh, typep); | ||
1973 | switch (*typep) { | ||
1974 | case SSH_MSG_NONE: | ||
1975 | return SSH_MSG_NONE; | ||
1976 | case SSH_MSG_IGNORE: | ||
1977 | break; | ||
1978 | case SSH_MSG_DEBUG: | ||
1979 | if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0) | ||
1980 | return r; | ||
1981 | debug("Remote: %.900s", msg); | ||
1982 | free(msg); | ||
1983 | break; | ||
1984 | case SSH_MSG_DISCONNECT: | ||
1985 | if ((r = sshpkt_get_string(ssh, &msg, NULL)) != 0) | ||
1986 | return r; | ||
1987 | error("Received disconnect from %s port %d: " | ||
1988 | "%.400s", ssh_remote_ipaddr(ssh), | ||
1989 | ssh_remote_port(ssh), msg); | ||
1990 | free(msg); | 1842 | free(msg); |
1991 | return SSH_ERR_DISCONNECTED; | 1843 | return r; |
1992 | default: | ||
1993 | DBG(debug("received packet type %d", *typep)); | ||
1994 | return 0; | ||
1995 | } | 1844 | } |
1845 | debug("Remote: %.900s", msg); | ||
1846 | free(msg); | ||
1847 | break; | ||
1848 | case SSH2_MSG_DISCONNECT: | ||
1849 | if ((r = sshpkt_get_u32(ssh, &reason)) != 0 || | ||
1850 | (r = sshpkt_get_string(ssh, &msg, NULL)) != 0) | ||
1851 | return r; | ||
1852 | /* Ignore normal client exit notifications */ | ||
1853 | do_log2(ssh->state->server_side && | ||
1854 | reason == SSH2_DISCONNECT_BY_APPLICATION ? | ||
1855 | SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, | ||
1856 | "Received disconnect from %s port %d:" | ||
1857 | "%u: %.400s", ssh_remote_ipaddr(ssh), | ||
1858 | ssh_remote_port(ssh), reason, msg); | ||
1859 | free(msg); | ||
1860 | return SSH_ERR_DISCONNECTED; | ||
1861 | case SSH2_MSG_UNIMPLEMENTED: | ||
1862 | if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0) | ||
1863 | return r; | ||
1864 | debug("Received SSH2_MSG_UNIMPLEMENTED for %u", | ||
1865 | seqnr); | ||
1866 | break; | ||
1867 | default: | ||
1868 | return 0; | ||
1996 | } | 1869 | } |
1997 | } | 1870 | } |
1998 | } | 1871 | } |
@@ -2044,27 +1917,19 @@ ssh_packet_send_debug(struct ssh *ssh, const char *fmt,...) | |||
2044 | va_list args; | 1917 | va_list args; |
2045 | int r; | 1918 | int r; |
2046 | 1919 | ||
2047 | if (compat20 && (ssh->compat & SSH_BUG_DEBUG)) | 1920 | if ((ssh->compat & SSH_BUG_DEBUG)) |
2048 | return; | 1921 | return; |
2049 | 1922 | ||
2050 | va_start(args, fmt); | 1923 | va_start(args, fmt); |
2051 | vsnprintf(buf, sizeof(buf), fmt, args); | 1924 | vsnprintf(buf, sizeof(buf), fmt, args); |
2052 | va_end(args); | 1925 | va_end(args); |
2053 | 1926 | ||
2054 | if (compat20) { | 1927 | if ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 || |
2055 | if ((r = sshpkt_start(ssh, SSH2_MSG_DEBUG)) != 0 || | 1928 | (r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */ |
2056 | (r = sshpkt_put_u8(ssh, 0)) != 0 || /* always display */ | 1929 | (r = sshpkt_put_cstring(ssh, buf)) != 0 || |
2057 | (r = sshpkt_put_cstring(ssh, buf)) != 0 || | 1930 | (r = sshpkt_put_cstring(ssh, "")) != 0 || |
2058 | (r = sshpkt_put_cstring(ssh, "")) != 0 || | 1931 | (r = sshpkt_send(ssh)) != 0 || |
2059 | (r = sshpkt_send(ssh)) != 0) | 1932 | (r = ssh_packet_write_wait(ssh)) != 0) |
2060 | fatal("%s: %s", __func__, ssh_err(r)); | ||
2061 | } else { | ||
2062 | if ((r = sshpkt_start(ssh, SSH_MSG_DEBUG)) != 0 || | ||
2063 | (r = sshpkt_put_cstring(ssh, buf)) != 0 || | ||
2064 | (r = sshpkt_send(ssh)) != 0) | ||
2065 | fatal("%s: %s", __func__, ssh_err(r)); | ||
2066 | } | ||
2067 | if ((r = ssh_packet_write_wait(ssh)) != 0) | ||
2068 | fatal("%s: %s", __func__, ssh_err(r)); | 1933 | fatal("%s: %s", __func__, ssh_err(r)); |
2069 | } | 1934 | } |
2070 | 1935 | ||
@@ -2385,8 +2250,7 @@ ssh_packet_send_ignore(struct ssh *ssh, int nbytes) | |||
2385 | u_int32_t rnd = 0; | 2250 | u_int32_t rnd = 0; |
2386 | int r, i; | 2251 | int r, i; |
2387 | 2252 | ||
2388 | if ((r = sshpkt_start(ssh, compat20 ? | 2253 | if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 || |
2389 | SSH2_MSG_IGNORE : SSH_MSG_IGNORE)) != 0 || | ||
2390 | (r = sshpkt_put_u32(ssh, nbytes)) != 0) | 2254 | (r = sshpkt_put_u32(ssh, nbytes)) != 0) |
2391 | fatal("%s: %s", __func__, ssh_err(r)); | 2255 | fatal("%s: %s", __func__, ssh_err(r)); |
2392 | for (i = 0; i < nbytes; i++) { | 2256 | for (i = 0; i < nbytes; i++) { |
@@ -2531,38 +2395,22 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) | |||
2531 | struct session_state *state = ssh->state; | 2395 | struct session_state *state = ssh->state; |
2532 | u_char *p; | 2396 | u_char *p; |
2533 | size_t slen, rlen; | 2397 | size_t slen, rlen; |
2534 | int r, ssh1cipher; | 2398 | int r; |
2535 | 2399 | ||
2536 | if (!compat20) { | 2400 | if ((r = kex_to_blob(m, ssh->kex)) != 0 || |
2537 | ssh1cipher = cipher_ctx_get_number(state->receive_context); | 2401 | (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 || |
2538 | slen = cipher_get_keyiv_len(state->send_context); | 2402 | (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 || |
2539 | rlen = cipher_get_keyiv_len(state->receive_context); | 2403 | (r = sshbuf_put_u64(m, state->rekey_limit)) != 0 || |
2540 | if ((r = sshbuf_put_u32(m, state->remote_protocol_flags)) != 0 || | 2404 | (r = sshbuf_put_u32(m, state->rekey_interval)) != 0 || |
2541 | (r = sshbuf_put_u32(m, ssh1cipher)) != 0 || | 2405 | (r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 || |
2542 | (r = sshbuf_put_string(m, state->ssh1_key, state->ssh1_keylen)) != 0 || | 2406 | (r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 || |
2543 | (r = sshbuf_put_u32(m, slen)) != 0 || | 2407 | (r = sshbuf_put_u32(m, state->p_send.packets)) != 0 || |
2544 | (r = sshbuf_reserve(m, slen, &p)) != 0 || | 2408 | (r = sshbuf_put_u64(m, state->p_send.bytes)) != 0 || |
2545 | (r = cipher_get_keyiv(state->send_context, p, slen)) != 0 || | 2409 | (r = sshbuf_put_u32(m, state->p_read.seqnr)) != 0 || |
2546 | (r = sshbuf_put_u32(m, rlen)) != 0 || | 2410 | (r = sshbuf_put_u64(m, state->p_read.blocks)) != 0 || |
2547 | (r = sshbuf_reserve(m, rlen, &p)) != 0 || | 2411 | (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 || |
2548 | (r = cipher_get_keyiv(state->receive_context, p, rlen)) != 0) | 2412 | (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0) |
2549 | return r; | 2413 | return r; |
2550 | } else { | ||
2551 | if ((r = kex_to_blob(m, ssh->kex)) != 0 || | ||
2552 | (r = newkeys_to_blob(m, ssh, MODE_OUT)) != 0 || | ||
2553 | (r = newkeys_to_blob(m, ssh, MODE_IN)) != 0 || | ||
2554 | (r = sshbuf_put_u64(m, state->rekey_limit)) != 0 || | ||
2555 | (r = sshbuf_put_u32(m, state->rekey_interval)) != 0 || | ||
2556 | (r = sshbuf_put_u32(m, state->p_send.seqnr)) != 0 || | ||
2557 | (r = sshbuf_put_u64(m, state->p_send.blocks)) != 0 || | ||
2558 | (r = sshbuf_put_u32(m, state->p_send.packets)) != 0 || | ||
2559 | (r = sshbuf_put_u64(m, state->p_send.bytes)) != 0 || | ||
2560 | (r = sshbuf_put_u32(m, state->p_read.seqnr)) != 0 || | ||
2561 | (r = sshbuf_put_u64(m, state->p_read.blocks)) != 0 || | ||
2562 | (r = sshbuf_put_u32(m, state->p_read.packets)) != 0 || | ||
2563 | (r = sshbuf_put_u64(m, state->p_read.bytes)) != 0) | ||
2564 | return r; | ||
2565 | } | ||
2566 | 2414 | ||
2567 | slen = cipher_get_keycontext(state->send_context, NULL); | 2415 | slen = cipher_get_keycontext(state->send_context, NULL); |
2568 | rlen = cipher_get_keycontext(state->receive_context, NULL); | 2416 | rlen = cipher_get_keycontext(state->receive_context, NULL); |
@@ -2701,53 +2549,34 @@ int | |||
2701 | ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) | 2549 | ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) |
2702 | { | 2550 | { |
2703 | struct session_state *state = ssh->state; | 2551 | struct session_state *state = ssh->state; |
2704 | const u_char *ssh1key, *ivin, *ivout, *keyin, *keyout, *input, *output; | 2552 | const u_char *keyin, *keyout, *input, *output; |
2705 | size_t ssh1keylen, rlen, slen, ilen, olen; | 2553 | size_t rlen, slen, ilen, olen; |
2706 | int r; | 2554 | int r; |
2707 | u_int ssh1cipher = 0; | 2555 | |
2708 | 2556 | if ((r = kex_from_blob(m, &ssh->kex)) != 0 || | |
2709 | if (!compat20) { | 2557 | (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 || |
2710 | if ((r = sshbuf_get_u32(m, &state->remote_protocol_flags)) != 0 || | 2558 | (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 || |
2711 | (r = sshbuf_get_u32(m, &ssh1cipher)) != 0 || | 2559 | (r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 || |
2712 | (r = sshbuf_get_string_direct(m, &ssh1key, &ssh1keylen)) != 0 || | 2560 | (r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 || |
2713 | (r = sshbuf_get_string_direct(m, &ivout, &slen)) != 0 || | 2561 | (r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 || |
2714 | (r = sshbuf_get_string_direct(m, &ivin, &rlen)) != 0) | 2562 | (r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 || |
2715 | return r; | 2563 | (r = sshbuf_get_u32(m, &state->p_send.packets)) != 0 || |
2716 | if (ssh1cipher > INT_MAX) | 2564 | (r = sshbuf_get_u64(m, &state->p_send.bytes)) != 0 || |
2717 | return SSH_ERR_KEY_UNKNOWN_CIPHER; | 2565 | (r = sshbuf_get_u32(m, &state->p_read.seqnr)) != 0 || |
2718 | ssh_packet_set_encryption_key(ssh, ssh1key, ssh1keylen, | 2566 | (r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 || |
2719 | (int)ssh1cipher); | 2567 | (r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 || |
2720 | if (cipher_get_keyiv_len(state->send_context) != (int)slen || | 2568 | (r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0) |
2721 | cipher_get_keyiv_len(state->receive_context) != (int)rlen) | 2569 | return r; |
2722 | return SSH_ERR_INVALID_FORMAT; | 2570 | /* |
2723 | if ((r = cipher_set_keyiv(state->send_context, ivout)) != 0 || | 2571 | * We set the time here so that in post-auth privsep slave we |
2724 | (r = cipher_set_keyiv(state->receive_context, ivin)) != 0) | 2572 | * count from the completion of the authentication. |
2725 | return r; | 2573 | */ |
2726 | } else { | 2574 | state->rekey_time = monotime(); |
2727 | if ((r = kex_from_blob(m, &ssh->kex)) != 0 || | 2575 | /* XXX ssh_set_newkeys overrides p_read.packets? XXX */ |
2728 | (r = newkeys_from_blob(m, ssh, MODE_OUT)) != 0 || | 2576 | if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 || |
2729 | (r = newkeys_from_blob(m, ssh, MODE_IN)) != 0 || | 2577 | (r = ssh_set_newkeys(ssh, MODE_OUT)) != 0) |
2730 | (r = sshbuf_get_u64(m, &state->rekey_limit)) != 0 || | 2578 | return r; |
2731 | (r = sshbuf_get_u32(m, &state->rekey_interval)) != 0 || | 2579 | |
2732 | (r = sshbuf_get_u32(m, &state->p_send.seqnr)) != 0 || | ||
2733 | (r = sshbuf_get_u64(m, &state->p_send.blocks)) != 0 || | ||
2734 | (r = sshbuf_get_u32(m, &state->p_send.packets)) != 0 || | ||
2735 | (r = sshbuf_get_u64(m, &state->p_send.bytes)) != 0 || | ||
2736 | (r = sshbuf_get_u32(m, &state->p_read.seqnr)) != 0 || | ||
2737 | (r = sshbuf_get_u64(m, &state->p_read.blocks)) != 0 || | ||
2738 | (r = sshbuf_get_u32(m, &state->p_read.packets)) != 0 || | ||
2739 | (r = sshbuf_get_u64(m, &state->p_read.bytes)) != 0) | ||
2740 | return r; | ||
2741 | /* | ||
2742 | * We set the time here so that in post-auth privsep slave we | ||
2743 | * count from the completion of the authentication. | ||
2744 | */ | ||
2745 | state->rekey_time = monotime(); | ||
2746 | /* XXX ssh_set_newkeys overrides p_read.packets? XXX */ | ||
2747 | if ((r = ssh_set_newkeys(ssh, MODE_IN)) != 0 || | ||
2748 | (r = ssh_set_newkeys(ssh, MODE_OUT)) != 0) | ||
2749 | return r; | ||
2750 | } | ||
2751 | if ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 || | 2580 | if ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 || |
2752 | (r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0) | 2581 | (r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0) |
2753 | return r; | 2582 | return r; |
@@ -2925,15 +2754,13 @@ sshpkt_ptr(struct ssh *ssh, size_t *lenp) | |||
2925 | int | 2754 | int |
2926 | sshpkt_start(struct ssh *ssh, u_char type) | 2755 | sshpkt_start(struct ssh *ssh, u_char type) |
2927 | { | 2756 | { |
2928 | u_char buf[9]; | 2757 | u_char buf[6]; /* u32 packet length, u8 pad len, u8 type */ |
2929 | int len; | ||
2930 | 2758 | ||
2931 | DBG(debug("packet_start[%d]", type)); | 2759 | DBG(debug("packet_start[%d]", type)); |
2932 | len = compat20 ? 6 : 9; | 2760 | memset(buf, 0, sizeof(buf)); |
2933 | memset(buf, 0, len - 1); | 2761 | buf[sizeof(buf) - 1] = type; |
2934 | buf[len - 1] = type; | ||
2935 | sshbuf_reset(ssh->state->outgoing_packet); | 2762 | sshbuf_reset(ssh->state->outgoing_packet); |
2936 | return sshbuf_put(ssh->state->outgoing_packet, buf, len); | 2763 | return sshbuf_put(ssh->state->outgoing_packet, buf, sizeof(buf)); |
2937 | } | 2764 | } |
2938 | 2765 | ||
2939 | static int | 2766 | static int |
@@ -2973,10 +2800,7 @@ sshpkt_send(struct ssh *ssh) | |||
2973 | { | 2800 | { |
2974 | if (ssh->state && ssh->state->mux) | 2801 | if (ssh->state && ssh->state->mux) |
2975 | return ssh_packet_send_mux(ssh); | 2802 | return ssh_packet_send_mux(ssh); |
2976 | if (compat20) | 2803 | return ssh_packet_send2(ssh); |
2977 | return ssh_packet_send2(ssh); | ||
2978 | else | ||
2979 | return ssh_packet_send1(ssh); | ||
2980 | } | 2804 | } |
2981 | 2805 | ||
2982 | int | 2806 | int |
@@ -2990,19 +2814,12 @@ sshpkt_disconnect(struct ssh *ssh, const char *fmt,...) | |||
2990 | vsnprintf(buf, sizeof(buf), fmt, args); | 2814 | vsnprintf(buf, sizeof(buf), fmt, args); |
2991 | va_end(args); | 2815 | va_end(args); |
2992 | 2816 | ||
2993 | if (compat20) { | 2817 | if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || |
2994 | if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 || | 2818 | (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 || |
2995 | (r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 || | 2819 | (r = sshpkt_put_cstring(ssh, buf)) != 0 || |
2996 | (r = sshpkt_put_cstring(ssh, buf)) != 0 || | 2820 | (r = sshpkt_put_cstring(ssh, "")) != 0 || |
2997 | (r = sshpkt_put_cstring(ssh, "")) != 0 || | 2821 | (r = sshpkt_send(ssh)) != 0) |
2998 | (r = sshpkt_send(ssh)) != 0) | 2822 | return r; |
2999 | return r; | ||
3000 | } else { | ||
3001 | if ((r = sshpkt_start(ssh, SSH_MSG_DISCONNECT)) != 0 || | ||
3002 | (r = sshpkt_put_cstring(ssh, buf)) != 0 || | ||
3003 | (r = sshpkt_send(ssh)) != 0) | ||
3004 | return r; | ||
3005 | } | ||
3006 | return 0; | 2823 | return 0; |
3007 | } | 2824 | } |
3008 | 2825 | ||