summaryrefslogtreecommitdiff
path: root/packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'packet.c')
-rw-r--r--packet.c94
1 files changed, 58 insertions, 36 deletions
diff --git a/packet.c b/packet.c
index dcf35e6e6..36e352b44 100644
--- a/packet.c
+++ b/packet.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.c,v 1.277 2018/07/16 03:09:13 djm Exp $ */ 1/* $OpenBSD: packet.c,v 1.283 2019/03/01 03:29:32 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
@@ -58,6 +58,7 @@
58#include <string.h> 58#include <string.h>
59#include <unistd.h> 59#include <unistd.h>
60#include <limits.h> 60#include <limits.h>
61#include <poll.h>
61#include <signal.h> 62#include <signal.h>
62#include <time.h> 63#include <time.h>
63 64
@@ -228,6 +229,7 @@ ssh_alloc_session_state(void)
228 229
229 if ((ssh = calloc(1, sizeof(*ssh))) == NULL || 230 if ((ssh = calloc(1, sizeof(*ssh))) == NULL ||
230 (state = calloc(1, sizeof(*state))) == NULL || 231 (state = calloc(1, sizeof(*state))) == NULL ||
232 (ssh->kex = kex_new()) == NULL ||
231 (state->input = sshbuf_new()) == NULL || 233 (state->input = sshbuf_new()) == NULL ||
232 (state->output = sshbuf_new()) == NULL || 234 (state->output = sshbuf_new()) == NULL ||
233 (state->outgoing_packet = sshbuf_new()) == NULL || 235 (state->outgoing_packet = sshbuf_new()) == NULL ||
@@ -250,6 +252,10 @@ ssh_alloc_session_state(void)
250 ssh->state = state; 252 ssh->state = state;
251 return ssh; 253 return ssh;
252 fail: 254 fail:
255 if (ssh) {
256 kex_free(ssh->kex);
257 free(ssh);
258 }
253 if (state) { 259 if (state) {
254 sshbuf_free(state->input); 260 sshbuf_free(state->input);
255 sshbuf_free(state->output); 261 sshbuf_free(state->output);
@@ -257,7 +263,6 @@ ssh_alloc_session_state(void)
257 sshbuf_free(state->outgoing_packet); 263 sshbuf_free(state->outgoing_packet);
258 free(state); 264 free(state);
259 } 265 }
260 free(ssh);
261 return NULL; 266 return NULL;
262} 267}
263 268
@@ -272,8 +277,7 @@ ssh_packet_set_input_hook(struct ssh *ssh, ssh_packet_hook_fn *hook, void *ctx)
272int 277int
273ssh_packet_is_rekeying(struct ssh *ssh) 278ssh_packet_is_rekeying(struct ssh *ssh)
274{ 279{
275 return ssh->state->rekeying || 280 return ssh->state->rekeying || ssh->kex->done == 0;
276 (ssh->kex != NULL && ssh->kex->done == 0);
277} 281}
278 282
279/* 283/*
@@ -837,6 +841,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
837 u_int64_t *max_blocks; 841 u_int64_t *max_blocks;
838 const char *wmsg; 842 const char *wmsg;
839 int r, crypt_type; 843 int r, crypt_type;
844 const char *dir = mode == MODE_OUT ? "out" : "in";
840 845
841 debug2("set_newkeys: mode %d", mode); 846 debug2("set_newkeys: mode %d", mode);
842 847
@@ -852,14 +857,12 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
852 max_blocks = &state->max_blocks_in; 857 max_blocks = &state->max_blocks_in;
853 } 858 }
854 if (state->newkeys[mode] != NULL) { 859 if (state->newkeys[mode] != NULL) {
855 debug("set_newkeys: rekeying, input %llu bytes %llu blocks, " 860 debug("%s: rekeying %s, input %llu bytes %llu blocks, "
856 "output %llu bytes %llu blocks", 861 "output %llu bytes %llu blocks", __func__, dir,
857 (unsigned long long)state->p_read.bytes, 862 (unsigned long long)state->p_read.bytes,
858 (unsigned long long)state->p_read.blocks, 863 (unsigned long long)state->p_read.blocks,
859 (unsigned long long)state->p_send.bytes, 864 (unsigned long long)state->p_send.bytes,
860 (unsigned long long)state->p_send.blocks); 865 (unsigned long long)state->p_send.blocks);
861 cipher_free(*ccp);
862 *ccp = NULL;
863 kex_free_newkeys(state->newkeys[mode]); 866 kex_free_newkeys(state->newkeys[mode]);
864 state->newkeys[mode] = NULL; 867 state->newkeys[mode] = NULL;
865 } 868 }
@@ -877,7 +880,9 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
877 return r; 880 return r;
878 } 881 }
879 mac->enabled = 1; 882 mac->enabled = 1;
880 DBG(debug("cipher_init_context: %d", mode)); 883 DBG(debug("%s: cipher_init_context: %s", __func__, dir));
884 cipher_free(*ccp);
885 *ccp = NULL;
881 if ((r = cipher_init(ccp, enc->cipher, enc->key, enc->key_len, 886 if ((r = cipher_init(ccp, enc->cipher, enc->key, enc->key_len,
882 enc->iv, enc->iv_len, crypt_type)) != 0) 887 enc->iv, enc->iv_len, crypt_type)) != 0)
883 return r; 888 return r;
@@ -916,7 +921,8 @@ ssh_set_newkeys(struct ssh *ssh, int mode)
916 if (state->rekey_limit) 921 if (state->rekey_limit)
917 *max_blocks = MINIMUM(*max_blocks, 922 *max_blocks = MINIMUM(*max_blocks,
918 state->rekey_limit / enc->block_size); 923 state->rekey_limit / enc->block_size);
919 debug("rekey after %llu blocks", (unsigned long long)*max_blocks); 924 debug("rekey %s after %llu blocks", dir,
925 (unsigned long long)*max_blocks);
920 return 0; 926 return 0;
921} 927}
922 928
@@ -932,7 +938,7 @@ ssh_packet_need_rekeying(struct ssh *ssh, u_int outbound_packet_len)
932 return 0; 938 return 0;
933 939
934 /* Haven't keyed yet or KEX in progress. */ 940 /* Haven't keyed yet or KEX in progress. */
935 if (ssh->kex == NULL || ssh_packet_is_rekeying(ssh)) 941 if (ssh_packet_is_rekeying(ssh))
936 return 0; 942 return 0;
937 943
938 /* Peer can't rekey */ 944 /* Peer can't rekey */
@@ -1805,10 +1811,10 @@ sshpkt_fmt_connection_id(struct ssh *ssh, char *s, size_t l)
1805/* 1811/*
1806 * Pretty-print connection-terminating errors and exit. 1812 * Pretty-print connection-terminating errors and exit.
1807 */ 1813 */
1808void 1814static void
1809sshpkt_fatal(struct ssh *ssh, const char *tag, int r) 1815sshpkt_vfatal(struct ssh *ssh, int r, const char *fmt, va_list ap)
1810{ 1816{
1811 char remote_id[512]; 1817 char *tag = NULL, remote_id[512];
1812 1818
1813 sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id)); 1819 sshpkt_fmt_connection_id(ssh, remote_id, sizeof(remote_id));
1814 1820
@@ -1842,6 +1848,11 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r)
1842 } 1848 }
1843 /* FALLTHROUGH */ 1849 /* FALLTHROUGH */
1844 default: 1850 default:
1851 if (vasprintf(&tag, fmt, ap) == -1) {
1852 ssh_packet_clear_keys(ssh);
1853 logdie("%s: could not allocate failure message",
1854 __func__);
1855 }
1845 ssh_packet_clear_keys(ssh); 1856 ssh_packet_clear_keys(ssh);
1846 logdie("%s%sConnection %s %s: %s", 1857 logdie("%s%sConnection %s %s: %s",
1847 tag != NULL ? tag : "", tag != NULL ? ": " : "", 1858 tag != NULL ? tag : "", tag != NULL ? ": " : "",
@@ -1850,6 +1861,18 @@ sshpkt_fatal(struct ssh *ssh, const char *tag, int r)
1850 } 1861 }
1851} 1862}
1852 1863
1864void
1865sshpkt_fatal(struct ssh *ssh, int r, const char *fmt, ...)
1866{
1867 va_list ap;
1868
1869 va_start(ap, fmt);
1870 sshpkt_vfatal(ssh, r, fmt, ap);
1871 /* NOTREACHED */
1872 va_end(ap);
1873 logdie("%s: should have exited", __func__);
1874}
1875
1853/* 1876/*
1854 * Logs the error plus constructs and sends a disconnect packet, closes the 1877 * Logs the error plus constructs and sends a disconnect packet, closes the
1855 * connection, and exits. This function never returns. The error message 1878 * connection, and exits. This function never returns. The error message
@@ -1885,10 +1908,10 @@ ssh_packet_disconnect(struct ssh *ssh, const char *fmt,...)
1885 * for it to get sent. 1908 * for it to get sent.
1886 */ 1909 */
1887 if ((r = sshpkt_disconnect(ssh, "%s", buf)) != 0) 1910 if ((r = sshpkt_disconnect(ssh, "%s", buf)) != 0)
1888 sshpkt_fatal(ssh, __func__, r); 1911 sshpkt_fatal(ssh, r, "%s", __func__);
1889 1912
1890 if ((r = ssh_packet_write_wait(ssh)) != 0) 1913 if ((r = ssh_packet_write_wait(ssh)) != 0)
1891 sshpkt_fatal(ssh, __func__, r); 1914 sshpkt_fatal(ssh, r, "%s", __func__);
1892 1915
1893 /* Close the connection. */ 1916 /* Close the connection. */
1894 ssh_packet_close(ssh); 1917 ssh_packet_close(ssh);
@@ -2123,6 +2146,7 @@ void
2123ssh_packet_set_server(struct ssh *ssh) 2146ssh_packet_set_server(struct ssh *ssh)
2124{ 2147{
2125 ssh->state->server_side = 1; 2148 ssh->state->server_side = 1;
2149 ssh->kex->server = 1; /* XXX unify? */
2126} 2150}
2127 2151
2128void 2152void
@@ -2175,9 +2199,9 @@ kex_to_blob(struct sshbuf *m, struct kex *kex)
2175 (r = sshbuf_put_u32(m, kex->kex_type)) != 0 || 2199 (r = sshbuf_put_u32(m, kex->kex_type)) != 0 ||
2176 (r = sshbuf_put_stringb(m, kex->my)) != 0 || 2200 (r = sshbuf_put_stringb(m, kex->my)) != 0 ||
2177 (r = sshbuf_put_stringb(m, kex->peer)) != 0 || 2201 (r = sshbuf_put_stringb(m, kex->peer)) != 0 ||
2178 (r = sshbuf_put_u32(m, kex->flags)) != 0 || 2202 (r = sshbuf_put_stringb(m, kex->client_version)) != 0 ||
2179 (r = sshbuf_put_cstring(m, kex->client_version_string)) != 0 || 2203 (r = sshbuf_put_stringb(m, kex->server_version)) != 0 ||
2180 (r = sshbuf_put_cstring(m, kex->server_version_string)) != 0) 2204 (r = sshbuf_put_u32(m, kex->flags)) != 0)
2181 return r; 2205 return r;
2182 return 0; 2206 return 0;
2183} 2207}
@@ -2327,12 +2351,8 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp)
2327 struct kex *kex; 2351 struct kex *kex;
2328 int r; 2352 int r;
2329 2353
2330 if ((kex = calloc(1, sizeof(struct kex))) == NULL || 2354 if ((kex = kex_new()) == NULL)
2331 (kex->my = sshbuf_new()) == NULL || 2355 return SSH_ERR_ALLOC_FAIL;
2332 (kex->peer = sshbuf_new()) == NULL) {
2333 r = SSH_ERR_ALLOC_FAIL;
2334 goto out;
2335 }
2336 if ((r = sshbuf_get_string(m, &kex->session_id, &kex->session_id_len)) != 0 || 2356 if ((r = sshbuf_get_string(m, &kex->session_id, &kex->session_id_len)) != 0 ||
2337 (r = sshbuf_get_u32(m, &kex->we_need)) != 0 || 2357 (r = sshbuf_get_u32(m, &kex->we_need)) != 0 ||
2338 (r = sshbuf_get_cstring(m, &kex->hostkey_alg, NULL)) != 0 || 2358 (r = sshbuf_get_cstring(m, &kex->hostkey_alg, NULL)) != 0 ||
@@ -2341,23 +2361,20 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp)
2341 (r = sshbuf_get_u32(m, &kex->kex_type)) != 0 || 2361 (r = sshbuf_get_u32(m, &kex->kex_type)) != 0 ||
2342 (r = sshbuf_get_stringb(m, kex->my)) != 0 || 2362 (r = sshbuf_get_stringb(m, kex->my)) != 0 ||
2343 (r = sshbuf_get_stringb(m, kex->peer)) != 0 || 2363 (r = sshbuf_get_stringb(m, kex->peer)) != 0 ||
2344 (r = sshbuf_get_u32(m, &kex->flags)) != 0 || 2364 (r = sshbuf_get_stringb(m, kex->client_version)) != 0 ||
2345 (r = sshbuf_get_cstring(m, &kex->client_version_string, NULL)) != 0 || 2365 (r = sshbuf_get_stringb(m, kex->server_version)) != 0 ||
2346 (r = sshbuf_get_cstring(m, &kex->server_version_string, NULL)) != 0) 2366 (r = sshbuf_get_u32(m, &kex->flags)) != 0)
2347 goto out; 2367 goto out;
2348 kex->server = 1; 2368 kex->server = 1;
2349 kex->done = 1; 2369 kex->done = 1;
2350 r = 0; 2370 r = 0;
2351 out: 2371 out:
2352 if (r != 0 || kexp == NULL) { 2372 if (r != 0 || kexp == NULL) {
2353 if (kex != NULL) { 2373 kex_free(kex);
2354 sshbuf_free(kex->my);
2355 sshbuf_free(kex->peer);
2356 free(kex);
2357 }
2358 if (kexp != NULL) 2374 if (kexp != NULL)
2359 *kexp = NULL; 2375 *kexp = NULL;
2360 } else { 2376 } else {
2377 kex_free(*kexp);
2361 *kexp = kex; 2378 *kexp = kex;
2362 } 2379 }
2363 return r; 2380 return r;
@@ -2468,6 +2485,12 @@ sshpkt_put_stringb(struct ssh *ssh, const struct sshbuf *v)
2468 return sshbuf_put_stringb(ssh->state->outgoing_packet, v); 2485 return sshbuf_put_stringb(ssh->state->outgoing_packet, v);
2469} 2486}
2470 2487
2488int
2489sshpkt_getb_froms(struct ssh *ssh, struct sshbuf **valp)
2490{
2491 return sshbuf_froms(ssh->state->incoming_packet, valp);
2492}
2493
2471#ifdef WITH_OPENSSL 2494#ifdef WITH_OPENSSL
2472#ifdef OPENSSL_HAS_ECC 2495#ifdef OPENSSL_HAS_ECC
2473int 2496int
@@ -2544,11 +2567,10 @@ sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g)
2544} 2567}
2545#endif /* OPENSSL_HAS_ECC */ 2568#endif /* OPENSSL_HAS_ECC */
2546 2569
2547
2548int 2570int
2549sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v) 2571sshpkt_get_bignum2(struct ssh *ssh, BIGNUM **valp)
2550{ 2572{
2551 return sshbuf_get_bignum2(ssh->state->incoming_packet, v); 2573 return sshbuf_get_bignum2(ssh->state->incoming_packet, valp);
2552} 2574}
2553#endif /* WITH_OPENSSL */ 2575#endif /* WITH_OPENSSL */
2554 2576