]> andersk Git - openssh.git/commitdiff
- markus@cvs.openbsd.org 2001/04/04 20:25:38
authormouring <mouring>
Wed, 4 Apr 2001 23:46:07 +0000 (23:46 +0000)
committermouring <mouring>
Wed, 4 Apr 2001 23:46:07 +0000 (23:46 +0000)
     [channels.c channels.h clientloop.c kex.c kex.h serverloop.c
      sshconnect2.c sshd.c]
     more robust rekeying
     don't send channel data after rekeying is started.

ChangeLog
channels.c
channels.h
clientloop.c
kex.c
kex.h
serverloop.c
sshconnect2.c
sshd.c

index 11dafeac576952ff2ba0fefef1d742128265ee67..1fc59f33a782f689ee682ae5c5941a811bd5ada7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
    - markus@cvs.openbsd.org 2001/04/04 15:50:55
      [compat.c]
      f-secure 1.3.2 does not handle IGNORE; from milliondl@ornl.gov
+   - markus@cvs.openbsd.org 2001/04/04 20:25:38
+     [channels.c channels.h clientloop.c kex.c kex.h serverloop.c 
+      sshconnect2.c sshd.c]
+     more robust rekeying
+     don't send channel data after rekeying is started.
 
 20010404
  - OpenBSD CVS Sync
index 941556ace0c5253ff424b324f618f7126154bfdf..7790564cc123ea303f169d7936f3e6226f10e3c7 100644 (file)
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.99 2001/03/16 19:06:29 markus Exp $");
+RCSID("$OpenBSD: channels.c,v 1.100 2001/04/04 20:25:35 markus Exp $");
 
 #include <openssl/rsa.h>
 #include <openssl/dsa.h>
@@ -1005,7 +1005,8 @@ channel_handler(chan_fn *ftab[], fd_set * readset, fd_set * writeset)
 }
 
 void
-channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp)
+channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
+    int rekeying)
 {
        int n;
        u_int sz;
@@ -1025,7 +1026,8 @@ channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp)
        memset(*readsetp, 0, sz);
        memset(*writesetp, 0, sz);
 
-       channel_handler(channel_pre, *readsetp, *writesetp);
+       if (!rekeying)
+               channel_handler(channel_pre, *readsetp, *writesetp);
 }
 
 void
index 493b04aa2903e2d5da5b681510cda245c517309b..2cd82148e55259824403ca88a2eb1b31e64b0019 100644 (file)
@@ -32,7 +32,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-/* RCSID("$OpenBSD: channels.h,v 1.28 2001/03/16 19:06:29 markus Exp $"); */
+/* RCSID("$OpenBSD: channels.h,v 1.29 2001/04/04 20:25:36 markus Exp $"); */
 
 #ifndef CHANNELS_H
 #define CHANNELS_H
@@ -171,7 +171,8 @@ void    channel_free(int channel);
  * select bitmasks.
  */
 void
-channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp);
+channel_prepare_select(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
+    int rekeying);
 
 /*
  * After select, perform any appropriate operations for channels which have
index 1d09a8dd9fe60d937cc2e866a0543d871fbc1c78..4b87e3b6d76fac1f8911a308d9aae44f6ceea940 100644 (file)
@@ -59,7 +59,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: clientloop.c,v 1.55 2001/04/04 14:34:58 markus Exp $");
+RCSID("$OpenBSD: clientloop.c,v 1.56 2001/04/04 20:25:37 markus Exp $");
 
 #include "ssh.h"
 #include "ssh1.h"
@@ -127,6 +127,7 @@ static u_long stdin_bytes, stdout_bytes, stderr_bytes;
 static u_int buffer_high;/* Soft max buffer size. */
 static int connection_in;      /* Connection to server (input). */
 static int connection_out;     /* Connection to server (output). */
+static int need_rekeying;      /* Set to non-zero if rekeying is requested. */
 
 void   client_init_dispatch(void);
 int    session_ident = -1;
@@ -367,10 +368,10 @@ client_check_window_change(void)
 
 void
 client_wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp,
-    int *maxfdp)
+    int *maxfdp, int rekeying)
 {
        /* Add any selections by the channel mechanism. */
-       channel_prepare_select(readsetp, writesetp, maxfdp);
+       channel_prepare_select(readsetp, writesetp, maxfdp, rekeying);
 
        if (!compat20) {
                /* Read from the connection, unless our buffers are full. */
@@ -553,8 +554,8 @@ process_escapes(Buffer *bin, Buffer *bout, Buffer *berr, char *buf, int len)
                                continue;
 
                        case 'R':
-                               debug("Rekeying");
-                               kex_send_kexinit(xxx_kex);
+                               if (compat20)
+                                       need_rekeying = 1;
                                continue;
 
                        case '&':
@@ -794,9 +795,8 @@ int
 client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
 {
        fd_set *readset = NULL, *writeset = NULL;
-       int max_fd = 0;
        double start_time, total_time;
-       int len;
+       int max_fd = 0, len, rekeying = 0;
        char buf[100];
 
        debug("Entering interactive session.");
@@ -858,45 +858,60 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
                /* Process buffered packets sent by the server. */
                client_process_buffered_input_packets();
 
+               rekeying = (xxx_kex != NULL && !xxx_kex->done);
+
                if (compat20 && !channel_still_open()) {
                        debug2("!channel_still_open.");
                        break;
                }
 
-               /*
-                * Make packets of buffered stdin data, and buffer them for
-                * sending to the server.
-                */
-               if (!compat20)
-                       client_make_packets_from_stdin_data();
-
-               /*
-                * Make packets from buffered channel data, and enqueue them
-                * for sending to the server.
-                */
-               if (packet_not_very_much_data_to_write())
-                       channel_output_poll();
+               if (rekeying) {
+                       debug("rekeying in progress");
+               } else {
+                       /*
+                        * Make packets of buffered stdin data, and buffer
+                        * them for sending to the server.
+                        */
+                       if (!compat20)
+                               client_make_packets_from_stdin_data();
 
-               /*
-                * Check if the window size has changed, and buffer a message
-                * about it to the server if so.
-                */
-               client_check_window_change();
+                       /*
+                        * Make packets from buffered channel data, and
+                        * enqueue them for sending to the server.
+                        */
+                       if (packet_not_very_much_data_to_write())
+                               channel_output_poll();
 
-               if (quit_pending)
-                       break;
+                       /*
+                        * Check if the window size has changed, and buffer a
+                        * message about it to the server if so.
+                        */
+                       client_check_window_change();
 
+                       if (quit_pending)
+                               break;
+               }
                /*
                 * Wait until we have something to do (something becomes
                 * available on one of the descriptors).
                 */
-               client_wait_until_can_do_something(&readset, &writeset, &max_fd);
+               client_wait_until_can_do_something(&readset, &writeset,
+                   &max_fd, rekeying);
 
                if (quit_pending)
                        break;
 
-               /* Do channel operations. */
-               channel_after_select(readset, writeset);
+               /* Do channel operations unless rekeying in progress. */
+               if (!rekeying) {
+                       channel_after_select(readset, writeset);
+
+                       if (need_rekeying) {
+                               debug("user requests rekeying");
+                               xxx_kex->done = 0;
+                               kex_send_kexinit(xxx_kex);
+                               need_rekeying = 0;
+                       }
+               }
 
                /* Buffer input from the connection.  */
                client_process_net_input(readset);
diff --git a/kex.c b/kex.c
index ee1e17e02a6a4b4a7591b59979bef5def413d97d..da9c56eb0abc788f4aa9f2673459b3529dfeed52 100644 (file)
--- a/kex.c
+++ b/kex.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kex.c,v 1.29 2001/04/04 14:34:58 markus Exp $");
+RCSID("$OpenBSD: kex.c,v 1.30 2001/04/04 20:25:37 markus Exp $");
 
 #include <openssl/crypto.h>
 
@@ -136,7 +136,7 @@ kex_finish(Kex *kex)
         debug("waiting for SSH2_MSG_NEWKEYS");
         packet_read_expect(&plen, SSH2_MSG_NEWKEYS);
        debug("SSH2_MSG_NEWKEYS received");
-       kex->newkeys = 1;
+       kex->done = 1;
        buffer_clear(&kex->peer);
        /* buffer_clear(&kex->my); */
        kex->flags &= ~KEX_INIT_SENT;
@@ -153,6 +153,7 @@ kex_send_kexinit(Kex *kex)
                debug("KEX_INIT_SENT");
                return;
        }
+       kex->done = 0;
        packet_start(SSH2_MSG_KEXINIT);
        packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my));
        packet_send();
@@ -187,7 +188,7 @@ kex_setup(char *proposal[PROPOSAL_MAX])
        buffer_init(&kex->peer);
        buffer_init(&kex->my);
        kex_prop2buf(&kex->my, proposal);
-       kex->newkeys = 0;
+       kex->done = 0;
 
        kex_send_kexinit(kex);                                  /* we start */
        kex_clear_dispatch();
@@ -307,10 +308,11 @@ kex_choose_conf(Kex *kex)
                sprop=peer;
        }
 
+       /* Algorithm Negotiation */
        for (mode = 0; mode < MODE_MAX; mode++) {
                newkeys = xmalloc(sizeof(*newkeys));
                memset(newkeys, 0, sizeof(*newkeys));
-               kex->keys[mode] = newkeys;
+               kex->newkeys[mode] = newkeys;
                ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
                nenc  = ctos ? PROPOSAL_ENC_ALGS_CTOS  : PROPOSAL_ENC_ALGS_STOC;
                nmac  = ctos ? PROPOSAL_MAC_ALGS_CTOS  : PROPOSAL_MAC_ALGS_STOC;
@@ -329,7 +331,7 @@ kex_choose_conf(Kex *kex)
            sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);
        need = 0;
        for (mode = 0; mode < MODE_MAX; mode++) {
-               newkeys = kex->keys[mode];
+               newkeys = kex->newkeys[mode];
                if (need < newkeys->enc.cipher->key_len)
                        need = newkeys->enc.cipher->key_len;
                if (need < newkeys->enc.cipher->block_size)
@@ -353,19 +355,24 @@ derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)
        char c = id;
        int have;
        int mdsz = evp_md->md_size;
-       u_char *digest = xmalloc(((need+mdsz-1)/mdsz)*mdsz);
+       u_char *digest = xmalloc(roundup(need, mdsz));
 
        buffer_init(&b);
        buffer_put_bignum2(&b, shared_secret);
 
+       /* K1 = HASH(K || H || "A" || session_id) */
        EVP_DigestInit(&md, evp_md);
-       EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));  /* shared_secret K */
-       EVP_DigestUpdate(&md, hash, mdsz);              /* transport-06 */
-       EVP_DigestUpdate(&md, &c, 1);                   /* key id */
+       EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
+       EVP_DigestUpdate(&md, hash, mdsz);
+       EVP_DigestUpdate(&md, &c, 1);
        EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);
        EVP_DigestFinal(&md, digest, NULL);
 
-       /* expand */
+       /*
+        * expand key:
+        * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
+        * Key = K1 || K2 || ... || Kn
+        */
        for (have = mdsz; need > have; have += mdsz) {
                EVP_DigestInit(&md, evp_md);
                EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
@@ -381,13 +388,12 @@ derive_key(Kex *kex, int id, int need, u_char *hash, BIGNUM *shared_secret)
        return digest;
 }
 
-Newkeys *x_newkeys[MODE_MAX];
+Newkeys *current_keys[MODE_MAX];
 
 #define NKEYS  6
 void
 kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret)
 {
-       Newkeys *newkeys;
        u_char *keys[NKEYS];
        int i, mode, ctos;
 
@@ -396,19 +402,23 @@ kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret)
 
        debug("kex_derive_keys");
        for (mode = 0; mode < MODE_MAX; mode++) {
-               newkeys = kex->keys[mode];
+               current_keys[mode] = kex->newkeys[mode];
+               kex->newkeys[mode] = NULL;
                ctos = (!kex->server && mode == MODE_OUT) || (kex->server && mode == MODE_IN);
-               newkeys->enc.iv  = keys[ctos ? 0 : 1];
-               newkeys->enc.key = keys[ctos ? 2 : 3];
-               newkeys->mac.key = keys[ctos ? 4 : 5];
-               x_newkeys[mode] = newkeys;
+               current_keys[mode]->enc.iv  = keys[ctos ? 0 : 1];
+               current_keys[mode]->enc.key = keys[ctos ? 2 : 3];
+               current_keys[mode]->mac.key = keys[ctos ? 4 : 5];
        }
 }
 
 Newkeys *
 kex_get_newkeys(int mode)
 {
-       return x_newkeys[mode];
+       Newkeys *ret;
+
+       ret = current_keys[mode];
+       current_keys[mode] = NULL;
+       return ret;
 }
 
 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH)
diff --git a/kex.h b/kex.h
index 54134221ff0a120662bdda83a9d1e71ca2ea2861..8758804c55444321a982ef4554fa3e280d751677 100644 (file)
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kex.h,v 1.21 2001/04/04 14:34:58 markus Exp $ */
+/*     $OpenBSD: kex.h,v 1.22 2001/04/04 20:25:37 markus Exp $ */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -95,7 +95,7 @@ struct Newkeys {
 struct Kex {
        u_char  *session_id;
        int     session_id_len;
-       Newkeys *keys[MODE_MAX];
+       Newkeys *newkeys[MODE_MAX];
        int     we_need;
        int     server;
        char    *name;
@@ -103,7 +103,7 @@ struct Kex {
        int     kex_type;
        Buffer  my;
        Buffer  peer;
-       int     newkeys;
+       int     done;
        int     flags;
        char    *client_version_string;
        char    *server_version_string;
index 4ae02fd1007d28ddb238a4e5fe1e37f339e637c7..ab7472b778dc5bb2a99078ef07497ec6bbbe09e3 100644 (file)
@@ -35,7 +35,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: serverloop.c,v 1.56 2001/04/04 14:34:58 markus Exp $");
+RCSID("$OpenBSD: serverloop.c,v 1.57 2001/04/04 20:25:37 markus Exp $");
 
 #include "xmalloc.h"
 #include "packet.h"
@@ -194,7 +194,7 @@ wait_until_can_do_something(fd_set **readsetp, fd_set **writesetp, int *maxfdp,
 retry_select:
 
        /* Allocate and update select() masks for channel descriptors. */
-       channel_prepare_select(readsetp, writesetp, maxfdp);
+       channel_prepare_select(readsetp, writesetp, maxfdp, 0);
 
        if (compat20) {
                /* wrong: bad condition XXX */
index 2f26aa5699711438bbf3518304dc61e8b11d418e..918ab38e82bdf3476c5138f0fef2765f40d4c74b 100644 (file)
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect2.c,v 1.65 2001/04/04 14:34:58 markus Exp $");
+RCSID("$OpenBSD: sshconnect2.c,v 1.66 2001/04/04 20:25:38 markus Exp $");
 
 #include <openssl/bn.h>
 #include <openssl/md5.h>
@@ -119,7 +119,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
 
        xxx_kex = kex;
 
-       dispatch_run(DISPATCH_BLOCK, &kex->newkeys, kex);
+       dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
 
        session_id2 = kex->session_id;
        session_id2_len = kex->session_id_len;
diff --git a/sshd.c b/sshd.c
index ea29e75ac304ea9fbc289aae985fbe28d96f19f5..5b592885836073e72db05cde08a39a0dd83153fb 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -40,7 +40,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshd.c,v 1.189 2001/04/04 14:34:58 markus Exp $");
+RCSID("$OpenBSD: sshd.c,v 1.190 2001/04/04 20:25:38 markus Exp $");
 
 #include <openssl/dh.h>
 #include <openssl/bn.h>
@@ -1437,7 +1437,7 @@ do_ssh2_kex(void)
 
        xxx_kex = kex;
 
-       dispatch_run(DISPATCH_BLOCK, &kex->newkeys, kex);
+       dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
 
        session_id2 = kex->session_id;
        session_id2_len = kex->session_id_len;
This page took 0.289673 seconds and 5 git commands to generate.