From df7bb23744d35804e144f4257c812994afcb22e8 Mon Sep 17 00:00:00 2001 From: Damien Miller Date: Tue, 17 Jan 2012 20:57:35 +1100 Subject: [PATCH] defatal kex_send_kexinit --- ssh/clientloop.c | 8 ++++++-- ssh/kex.c | 50 ++++++++++++++++++++++++------------------------ ssh/kex.h | 2 +- ssh/serverloop.c | 8 ++++++-- 4 files changed, 38 insertions(+), 30 deletions(-) diff --git a/ssh/clientloop.c b/ssh/clientloop.c index 406660c..3db8f0a 100644 --- a/ssh/clientloop.c +++ b/ssh/clientloop.c @@ -104,6 +104,7 @@ #include "match.h" #include "msg.h" #include "roaming.h" +#include "err.h" /* import options */ extern Options options; @@ -1380,7 +1381,7 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) { fd_set *readset = NULL, *writeset = NULL; double start_time, total_time; - int max_fd = 0, max_fd2 = 0, len, rekeying = 0; + int r, max_fd = 0, max_fd2 = 0, len, rekeying = 0; u_int64_t ibytes, obytes; u_int nalloc = 0; char buf[100]; @@ -1511,7 +1512,10 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id) if (need_rekeying || packet_need_rekeying()) { debug("need rekeying"); active_state->kex->done = 0; - kex_send_kexinit(active_state); + if ((r = kex_send_kexinit(active_state)) != 0) { + fatal("%s: kex_send_kexinit: %s", + __func__, ssh_err(r)); + } need_rekeying = 0; } } diff --git a/ssh/kex.c b/ssh/kex.c index 26a7d26..7466ee0 100644 --- a/ssh/kex.c +++ b/ssh/kex.c @@ -189,39 +189,36 @@ kex_input_newkeys(int type, u_int32_t seq, struct ssh *ssh) return 0; } -void +int kex_send_kexinit(struct ssh *ssh) { - u_int32_t rnd = 0; u_char *cookie; - u_int i; Kex *kex = ssh->kex; + int r; - if (kex == NULL) { - error("kex_send_kexinit: no kex, cannot rekey"); - return; - } - if (kex->flags & KEX_INIT_SENT) { - debug("KEX_INIT_SENT"); - return; - } + if (kex == NULL) + return SSH_ERR_INTERNAL_ERROR; + if (kex->flags & KEX_INIT_SENT) + return 0; kex->done = 0; /* generate a random cookie */ if (buffer_len(&kex->my) < KEX_COOKIE_LEN) - fatal("kex_send_kexinit: kex proposal too short"); - cookie = buffer_ptr(&kex->my); - for (i = 0; i < KEX_COOKIE_LEN; i++) { - if (i % 4 == 0) - rnd = arc4random(); - cookie[i] = rnd; - rnd >>= 8; - } - ssh_packet_start(ssh, SSH2_MSG_KEXINIT); - ssh_packet_put_raw(ssh, buffer_ptr(&kex->my), buffer_len(&kex->my)); - ssh_packet_send(ssh); + return SSH_ERR_INVALID_FORMAT; + if ((cookie = sshbuf_ptr(&kex->my)) == NULL) + return SSH_ERR_INTERNAL_ERROR; + arc4random_buf(cookie, KEX_COOKIE_LEN); + + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXINIT)) != 0) + return r; + if ((r = sshpkt_put(ssh, buffer_ptr(&kex->my), + buffer_len(&kex->my))) != 0) + return r; + if ((r = sshpkt_send(ssh)) != 0) + return r; debug("SSH2_MSG_KEXINIT sent"); kex->flags |= KEX_INIT_SENT; + return 0; } /* ARGSUSED */ @@ -254,8 +251,10 @@ kex_input_kexinit(int type, u_int32_t seq, struct ssh *ssh) return r; /* XXX check error */ - if (!(kex->flags & KEX_INIT_SENT)) - kex_send_kexinit(ssh); + if (!(kex->flags & KEX_INIT_SENT)) { + if ((r = kex_send_kexinit(ssh)) != 0) + return r; + } kex_choose_conf(ssh); if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX && @@ -296,7 +295,8 @@ Kex * kex_setup(struct ssh *ssh, char *proposal[PROPOSAL_MAX]) { ssh->kex = kex_new(ssh, proposal); - kex_send_kexinit(ssh); /* we start */ + if (kex_send_kexinit(ssh) != 0) /* we start */ + return NULL; /* XXX */ return ssh->kex; } diff --git a/ssh/kex.h b/ssh/kex.h index caac4de..e1b5e87 100644 --- a/ssh/kex.h +++ b/ssh/kex.h @@ -144,7 +144,7 @@ char **kex_buf2prop(Buffer *, int *); void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]); void kex_prop_free(char **); -void kex_send_kexinit(struct ssh *); +int kex_send_kexinit(struct ssh *); int kex_input_kexinit(int, u_int32_t, struct ssh *); int kex_derive_keys(struct ssh *, u_char *, u_int, BIGNUM *); diff --git a/ssh/serverloop.c b/ssh/serverloop.c index 9730077..cf156b1 100644 --- a/ssh/serverloop.c +++ b/ssh/serverloop.c @@ -77,6 +77,7 @@ #include "serverloop.h" #include "misc.h" #include "roaming.h" +#include "err.h" extern ServerOptions options; @@ -787,7 +788,7 @@ void server_loop2(Authctxt *authctxt) { fd_set *readset = NULL, *writeset = NULL; - int rekeying = 0, max_fd, nalloc = 0; + int r, rekeying = 0, max_fd, nalloc = 0; debug("Entering interactive session for SSH2."); @@ -832,7 +833,10 @@ server_loop2(Authctxt *authctxt) if (packet_need_rekeying()) { debug("need rekeying"); active_state->kex->done = 0; - kex_send_kexinit(active_state); + if ((r = kex_send_kexinit(active_state)) != 0) { + fatal("%s: kex_send_kexinit: %s", + __func__, ssh_err(r)); + } } } process_input(readset);