summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2003-04-09 20:50:06 +1000
committerDamien Miller <djm@mindrot.org>2003-04-09 20:50:06 +1000
commita5539d2698ea83b4a7f9abe7cde8306e2fd76f33 (patch)
treecd95d1bf54f7496bc080a981bc55300f083939f4
parenta92a589e9716d6b10250c3eb8f4d81d64cd60dd8 (diff)
- (djm) OpenBSD CVS Sync
- markus@cvs.openbsd.org 2003/04/02 09:48:07 [clientloop.c monitor.c monitor_wrap.c packet.c packet.h readconf.c] [readconf.h serverloop.c sshconnect2.c] reapply rekeying chage, tested by henning@, ok djm@
-rw-r--r--ChangeLog7
-rw-r--r--clientloop.c7
-rw-r--r--monitor.c14
-rw-r--r--monitor_wrap.c14
-rw-r--r--packet.c145
-rw-r--r--packet.h9
-rw-r--r--readconf.c33
-rw-r--r--readconf.h3
-rw-r--r--serverloop.c10
-rw-r--r--sshconnect2.c5
10 files changed, 205 insertions, 42 deletions
diff --git a/ChangeLog b/ChangeLog
index afc34a291..140a176f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,11 @@
2 - (djm) Bug #539: Specify creation mode with O_CREAT for lastlog. Report 2 - (djm) Bug #539: Specify creation mode with O_CREAT for lastlog. Report
3 from matth@eecs.berkeley.edu 3 from matth@eecs.berkeley.edu
4 - (djm) Make the spec work with Redhat 9.0 (which renames sharutils) 4 - (djm) Make the spec work with Redhat 9.0 (which renames sharutils)
5 - (djm) OpenBSD CVS Sync
6 - markus@cvs.openbsd.org 2003/04/02 09:48:07
7 [clientloop.c monitor.c monitor_wrap.c packet.c packet.h readconf.c]
8 [readconf.h serverloop.c sshconnect2.c]
9 reapply rekeying chage, tested by henning@, ok djm@
5 10
620030402 1120030402
7 - (bal) if IP_TOS is not found or broken don't try to compile in 12 - (bal) if IP_TOS is not found or broken don't try to compile in
@@ -1304,4 +1309,4 @@
1304 save auth method before monitor_reset_key_state(); bugzilla bug #284; 1309 save auth method before monitor_reset_key_state(); bugzilla bug #284;
1305 ok provos@ 1310 ok provos@
1306 1311
1307$Id: ChangeLog,v 1.2651 2003/04/09 09:41:25 djm Exp $ 1312$Id: ChangeLog,v 1.2652 2003/04/09 10:50:06 djm Exp $
diff --git a/clientloop.c b/clientloop.c
index af207c070..a40019d08 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -59,7 +59,7 @@
59 */ 59 */
60 60
61#include "includes.h" 61#include "includes.h"
62RCSID("$OpenBSD: clientloop.c,v 1.107 2003/04/01 10:22:21 markus Exp $"); 62RCSID("$OpenBSD: clientloop.c,v 1.108 2003/04/02 09:48:07 markus Exp $");
63 63
64#include "ssh.h" 64#include "ssh.h"
65#include "ssh1.h" 65#include "ssh1.h"
@@ -968,9 +968,8 @@ client_loop(int have_pty, int escape_char_arg, int ssh2_chan_id)
968 /* Do channel operations unless rekeying in progress. */ 968 /* Do channel operations unless rekeying in progress. */
969 if (!rekeying) { 969 if (!rekeying) {
970 channel_after_select(readset, writeset); 970 channel_after_select(readset, writeset);
971 971 if (need_rekeying || packet_need_rekeying()) {
972 if (need_rekeying) { 972 debug("need rekeying");
973 debug("user requests rekeying");
974 xxx_kex->done = 0; 973 xxx_kex->done = 0;
975 kex_send_kexinit(xxx_kex); 974 kex_send_kexinit(xxx_kex);
976 need_rekeying = 0; 975 need_rekeying = 0;
diff --git a/monitor.c b/monitor.c
index bcd007e60..4cd10a108 100644
--- a/monitor.c
+++ b/monitor.c
@@ -25,7 +25,7 @@
25 */ 25 */
26 26
27#include "includes.h" 27#include "includes.h"
28RCSID("$OpenBSD: monitor.c,v 1.36 2003/04/01 10:22:21 markus Exp $"); 28RCSID("$OpenBSD: monitor.c,v 1.37 2003/04/02 09:48:07 markus Exp $");
29 29
30#include <openssl/dh.h> 30#include <openssl/dh.h>
31 31
@@ -1497,6 +1497,8 @@ mm_get_keystate(struct monitor *pmonitor)
1497 Buffer m; 1497 Buffer m;
1498 u_char *blob, *p; 1498 u_char *blob, *p;
1499 u_int bloblen, plen; 1499 u_int bloblen, plen;
1500 u_int32_t seqnr, packets;
1501 u_int64_t blocks;
1500 1502
1501 debug3("%s: Waiting for new keys", __func__); 1503 debug3("%s: Waiting for new keys", __func__);
1502 1504
@@ -1526,8 +1528,14 @@ mm_get_keystate(struct monitor *pmonitor)
1526 xfree(blob); 1528 xfree(blob);
1527 1529
1528 /* Now get sequence numbers for the packets */ 1530 /* Now get sequence numbers for the packets */
1529 packet_set_seqnr(MODE_OUT, buffer_get_int(&m)); 1531 seqnr = buffer_get_int(&m);
1530 packet_set_seqnr(MODE_IN, buffer_get_int(&m)); 1532 blocks = buffer_get_int64(&m);
1533 packets = buffer_get_int(&m);
1534 packet_set_state(MODE_OUT, seqnr, blocks, packets);
1535 seqnr = buffer_get_int(&m);
1536 blocks = buffer_get_int64(&m);
1537 packets = buffer_get_int(&m);
1538 packet_set_state(MODE_IN, seqnr, blocks, packets);
1531 1539
1532 skip: 1540 skip:
1533 /* Get the key context */ 1541 /* Get the key context */
diff --git a/monitor_wrap.c b/monitor_wrap.c
index c9714138a..f674ef78d 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -25,7 +25,7 @@
25 */ 25 */
26 26
27#include "includes.h" 27#include "includes.h"
28RCSID("$OpenBSD: monitor_wrap.c,v 1.24 2003/04/01 10:22:21 markus Exp $"); 28RCSID("$OpenBSD: monitor_wrap.c,v 1.25 2003/04/02 09:48:07 markus Exp $");
29 29
30#include <openssl/bn.h> 30#include <openssl/bn.h>
31#include <openssl/dh.h> 31#include <openssl/dh.h>
@@ -520,6 +520,8 @@ mm_send_keystate(struct monitor *pmonitor)
520 Buffer m; 520 Buffer m;
521 u_char *blob, *p; 521 u_char *blob, *p;
522 u_int bloblen, plen; 522 u_int bloblen, plen;
523 u_int32_t seqnr, packets;
524 u_int64_t blocks;
523 525
524 buffer_init(&m); 526 buffer_init(&m);
525 527
@@ -568,8 +570,14 @@ mm_send_keystate(struct monitor *pmonitor)
568 buffer_put_string(&m, blob, bloblen); 570 buffer_put_string(&m, blob, bloblen);
569 xfree(blob); 571 xfree(blob);
570 572
571 buffer_put_int(&m, packet_get_seqnr(MODE_OUT)); 573 packet_get_state(MODE_OUT, &seqnr, &blocks, &packets);
572 buffer_put_int(&m, packet_get_seqnr(MODE_IN)); 574 buffer_put_int(&m, seqnr);
575 buffer_put_int64(&m, blocks);
576 buffer_put_int(&m, packets);
577 packet_get_state(MODE_OUT, &seqnr, &blocks, &packets);
578 buffer_put_int(&m, seqnr);
579 buffer_put_int64(&m, blocks);
580 buffer_put_int(&m, packets);
573 581
574 debug3("%s: New keys have been sent", __func__); 582 debug3("%s: New keys have been sent", __func__);
575 skip: 583 skip:
diff --git a/packet.c b/packet.c
index 254e452d0..9887d25af 100644
--- a/packet.c
+++ b/packet.c
@@ -37,7 +37,9 @@
37 */ 37 */
38 38
39#include "includes.h" 39#include "includes.h"
40RCSID("$OpenBSD: packet.c,v 1.104 2003/04/01 10:22:21 markus Exp $"); 40RCSID("$OpenBSD: packet.c,v 1.105 2003/04/02 09:48:07 markus Exp $");
41
42#include <sys/queue.h>
41 43
42#include "xmalloc.h" 44#include "xmalloc.h"
43#include "buffer.h" 45#include "buffer.h"
@@ -116,8 +118,14 @@ static int interactive_mode = 0;
116 118
117/* Session key information for Encryption and MAC */ 119/* Session key information for Encryption and MAC */
118Newkeys *newkeys[MODE_MAX]; 120Newkeys *newkeys[MODE_MAX];
119static u_int32_t read_seqnr = 0; 121static struct packet_state {
120static u_int32_t send_seqnr = 0; 122 u_int32_t seqnr;
123 u_int32_t packets;
124 u_int64_t blocks;
125} p_read, p_send;
126
127static u_int64_t max_blocks_in, max_blocks_out;
128static u_int32_t rekey_limit;
121 129
122/* Session key for protocol v1 */ 130/* Session key for protocol v1 */
123static u_char ssh1_key[SSH_SESSION_KEY_LENGTH]; 131static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
@@ -126,6 +134,13 @@ static u_int ssh1_keylen;
126/* roundup current message to extra_pad bytes */ 134/* roundup current message to extra_pad bytes */
127static u_char extra_pad = 0; 135static u_char extra_pad = 0;
128 136
137struct packet {
138 TAILQ_ENTRY(packet) next;
139 u_char type;
140 Buffer payload;
141};
142TAILQ_HEAD(, packet) outgoing;
143
129/* 144/*
130 * Sets the descriptors used for communication. Disables encryption until 145 * Sets the descriptors used for communication. Disables encryption until
131 * packet_set_encryption_key is called. 146 * packet_set_encryption_key is called.
@@ -148,6 +163,7 @@ packet_set_connection(int fd_in, int fd_out)
148 buffer_init(&output); 163 buffer_init(&output);
149 buffer_init(&outgoing_packet); 164 buffer_init(&outgoing_packet);
150 buffer_init(&incoming_packet); 165 buffer_init(&incoming_packet);
166 TAILQ_INIT(&outgoing);
151 } 167 }
152 /* Kludge: arrange the close function to be called from fatal(). */ 168 /* Kludge: arrange the close function to be called from fatal(). */
153 fatal_add_cleanup((void (*) (void *)) packet_close, NULL); 169 fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
@@ -254,22 +270,26 @@ packet_get_ssh1_cipher()
254 return (cipher_get_number(receive_context.cipher)); 270 return (cipher_get_number(receive_context.cipher));
255} 271}
256 272
257 273void
258u_int32_t 274packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets)
259packet_get_seqnr(int mode)
260{ 275{
261 return (mode == MODE_IN ? read_seqnr : send_seqnr); 276 struct packet_state *state;
277
278 state = (mode == MODE_IN) ? &p_read : &p_send;
279 *seqnr = state->seqnr;
280 *blocks = state->blocks;
281 *packets = state->packets;
262} 282}
263 283
264void 284void
265packet_set_seqnr(int mode, u_int32_t seqnr) 285packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets)
266{ 286{
267 if (mode == MODE_IN) 287 struct packet_state *state;
268 read_seqnr = seqnr; 288
269 else if (mode == MODE_OUT) 289 state = (mode == MODE_IN) ? &p_read : &p_send;
270 send_seqnr = seqnr; 290 state->seqnr = seqnr;
271 else 291 state->blocks = blocks;
272 fatal("packet_set_seqnr: bad mode %d", mode); 292 state->packets = packets;
273} 293}
274 294
275/* returns 1 if connection is via ipv4 */ 295/* returns 1 if connection is via ipv4 */
@@ -562,6 +582,7 @@ set_newkeys(int mode)
562 Mac *mac; 582 Mac *mac;
563 Comp *comp; 583 Comp *comp;
564 CipherContext *cc; 584 CipherContext *cc;
585 u_int64_t *max_blocks;
565 int encrypt; 586 int encrypt;
566 587
567 debug2("set_newkeys: mode %d", mode); 588 debug2("set_newkeys: mode %d", mode);
@@ -569,9 +590,13 @@ set_newkeys(int mode)
569 if (mode == MODE_OUT) { 590 if (mode == MODE_OUT) {
570 cc = &send_context; 591 cc = &send_context;
571 encrypt = CIPHER_ENCRYPT; 592 encrypt = CIPHER_ENCRYPT;
593 p_send.packets = p_send.blocks = 0;
594 max_blocks = &max_blocks_out;
572 } else { 595 } else {
573 cc = &receive_context; 596 cc = &receive_context;
574 encrypt = CIPHER_DECRYPT; 597 encrypt = CIPHER_DECRYPT;
598 p_read.packets = p_read.blocks = 0;
599 max_blocks = &max_blocks_in;
575 } 600 }
576 if (newkeys[mode] != NULL) { 601 if (newkeys[mode] != NULL) {
577 debug("set_newkeys: rekeying"); 602 debug("set_newkeys: rekeying");
@@ -610,13 +635,16 @@ set_newkeys(int mode)
610 buffer_compress_init_recv(); 635 buffer_compress_init_recv();
611 comp->enabled = 1; 636 comp->enabled = 1;
612 } 637 }
638 *max_blocks = ((u_int64_t)1 << (enc->block_size*2));
639 if (rekey_limit)
640 *max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);
613} 641}
614 642
615/* 643/*
616 * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) 644 * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
617 */ 645 */
618static void 646static void
619packet_send2(void) 647packet_send2_wrapped(void)
620{ 648{
621 u_char type, *cp, *macbuf = NULL; 649 u_char type, *cp, *macbuf = NULL;
622 u_char padlen, pad; 650 u_char padlen, pad;
@@ -698,10 +726,10 @@ packet_send2(void)
698 726
699 /* compute MAC over seqnr and packet(length fields, payload, padding) */ 727 /* compute MAC over seqnr and packet(length fields, payload, padding) */
700 if (mac && mac->enabled) { 728 if (mac && mac->enabled) {
701 macbuf = mac_compute(mac, send_seqnr, 729 macbuf = mac_compute(mac, p_send.seqnr,
702 buffer_ptr(&outgoing_packet), 730 buffer_ptr(&outgoing_packet),
703 buffer_len(&outgoing_packet)); 731 buffer_len(&outgoing_packet));
704 DBG(debug("done calc MAC out #%d", send_seqnr)); 732 DBG(debug("done calc MAC out #%d", p_send.seqnr));
705 } 733 }
706 /* encrypt packet and append to output buffer. */ 734 /* encrypt packet and append to output buffer. */
707 cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); 735 cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
@@ -715,14 +743,64 @@ packet_send2(void)
715 buffer_dump(&output); 743 buffer_dump(&output);
716#endif 744#endif
717 /* increment sequence number for outgoing packets */ 745 /* increment sequence number for outgoing packets */
718 if (++send_seqnr == 0) 746 if (++p_send.seqnr == 0)
719 log("outgoing seqnr wraps around"); 747 log("outgoing seqnr wraps around");
748 if (++p_send.packets == 0)
749 if (!(datafellows & SSH_BUG_NOREKEY))
750 fatal("XXX too many packets with same key");
751 p_send.blocks += (packet_length + 4) / block_size;
720 buffer_clear(&outgoing_packet); 752 buffer_clear(&outgoing_packet);
721 753
722 if (type == SSH2_MSG_NEWKEYS) 754 if (type == SSH2_MSG_NEWKEYS)
723 set_newkeys(MODE_OUT); 755 set_newkeys(MODE_OUT);
724} 756}
725 757
758static void
759packet_send2(void)
760{
761 static int rekeying = 0;
762 struct packet *p;
763 u_char type, *cp;
764
765 cp = buffer_ptr(&outgoing_packet);
766 type = cp[5];
767
768 /* during rekeying we can only send key exchange messages */
769 if (rekeying) {
770 if (!((type >= SSH2_MSG_TRANSPORT_MIN) &&
771 (type <= SSH2_MSG_TRANSPORT_MAX))) {
772 debug("enqueue packet: %u", type);
773 p = xmalloc(sizeof(*p));
774 p->type = type;
775 memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
776 buffer_init(&outgoing_packet);
777 TAILQ_INSERT_TAIL(&outgoing, p, next);
778 return;
779 }
780 }
781
782 /* rekeying starts with sending KEXINIT */
783 if (type == SSH2_MSG_KEXINIT)
784 rekeying = 1;
785
786 packet_send2_wrapped();
787
788 /* after a NEWKEYS message we can send the complete queue */
789 if (type == SSH2_MSG_NEWKEYS) {
790 rekeying = 0;
791 while ((p = TAILQ_FIRST(&outgoing))) {
792 type = p->type;
793 debug("dequeue packet: %u", type);
794 buffer_free(&outgoing_packet);
795 memcpy(&outgoing_packet, &p->payload,
796 sizeof(Buffer));
797 TAILQ_REMOVE(&outgoing, p, next);
798 xfree(p);
799 packet_send2_wrapped();
800 }
801 }
802}
803
726void 804void
727packet_send(void) 805packet_send(void)
728{ 806{
@@ -966,18 +1044,22 @@ packet_read_poll2(u_int32_t *seqnr_p)
966 * increment sequence number for incoming packet 1044 * increment sequence number for incoming packet
967 */ 1045 */
968 if (mac && mac->enabled) { 1046 if (mac && mac->enabled) {
969 macbuf = mac_compute(mac, read_seqnr, 1047 macbuf = mac_compute(mac, p_read.seqnr,
970 buffer_ptr(&incoming_packet), 1048 buffer_ptr(&incoming_packet),
971 buffer_len(&incoming_packet)); 1049 buffer_len(&incoming_packet));
972 if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) 1050 if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
973 packet_disconnect("Corrupted MAC on input."); 1051 packet_disconnect("Corrupted MAC on input.");
974 DBG(debug("MAC #%d ok", read_seqnr)); 1052 DBG(debug("MAC #%d ok", p_read.seqnr));
975 buffer_consume(&input, mac->mac_len); 1053 buffer_consume(&input, mac->mac_len);
976 } 1054 }
977 if (seqnr_p != NULL) 1055 if (seqnr_p != NULL)
978 *seqnr_p = read_seqnr; 1056 *seqnr_p = p_read.seqnr;
979 if (++read_seqnr == 0) 1057 if (++p_read.seqnr == 0)
980 log("incoming seqnr wraps around"); 1058 log("incoming seqnr wraps around");
1059 if (++p_read.packets == 0)
1060 if (!(datafellows & SSH_BUG_NOREKEY))
1061 fatal("XXX too many packets with same key");
1062 p_read.blocks += (packet_length + 4) / block_size;
981 1063
982 /* get padlen */ 1064 /* get padlen */
983 cp = buffer_ptr(&incoming_packet); 1065 cp = buffer_ptr(&incoming_packet);
@@ -1416,3 +1498,22 @@ packet_send_ignore(int nbytes)
1416 rand >>= 8; 1498 rand >>= 8;
1417 } 1499 }
1418} 1500}
1501
1502#define MAX_PACKETS (1<<31)
1503int
1504packet_need_rekeying(void)
1505{
1506 if (datafellows & SSH_BUG_NOREKEY)
1507 return 0;
1508 return
1509 (p_send.packets > MAX_PACKETS) ||
1510 (p_read.packets > MAX_PACKETS) ||
1511 (max_blocks_out && (p_send.blocks > max_blocks_out)) ||
1512 (max_blocks_in && (p_read.blocks > max_blocks_in));
1513}
1514
1515void
1516packet_set_rekey_limit(u_int32_t bytes)
1517{
1518 rekey_limit = bytes;
1519}
diff --git a/packet.h b/packet.h
index 46830c3df..82ed7c747 100644
--- a/packet.h
+++ b/packet.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: packet.h,v 1.37 2003/04/01 10:22:21 markus Exp $ */ 1/* $OpenBSD: packet.h,v 1.38 2003/04/02 09:48:07 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -62,8 +62,8 @@ int packet_get_keyiv_len(int);
62void packet_get_keyiv(int, u_char *, u_int); 62void packet_get_keyiv(int, u_char *, u_int);
63int packet_get_keycontext(int, u_char *); 63int packet_get_keycontext(int, u_char *);
64void packet_set_keycontext(int, u_char *); 64void packet_set_keycontext(int, u_char *);
65u_int32_t packet_get_seqnr(int); 65void packet_get_state(int, u_int32_t *, u_int64_t *, u_int32_t *);
66void packet_set_seqnr(int, u_int32_t); 66void packet_set_state(int, u_int32_t, u_int64_t, u_int32_t);
67int packet_get_ssh1_cipher(void); 67int packet_get_ssh1_cipher(void);
68void packet_set_iv(int, u_char *); 68void packet_set_iv(int, u_char *);
69 69
@@ -96,4 +96,7 @@ do { \
96 } \ 96 } \
97} while (0) 97} while (0)
98 98
99int packet_need_rekeying(void);
100void packet_set_rekey_limit(u_int32_t);
101
99#endif /* PACKET_H */ 102#endif /* PACKET_H */
diff --git a/readconf.c b/readconf.c
index 1df5ce2d9..a10427086 100644
--- a/readconf.c
+++ b/readconf.c
@@ -12,7 +12,7 @@
12 */ 12 */
13 13
14#include "includes.h" 14#include "includes.h"
15RCSID("$OpenBSD: readconf.c,v 1.104 2003/04/01 10:22:21 markus Exp $"); 15RCSID("$OpenBSD: readconf.c,v 1.105 2003/04/02 09:48:07 markus Exp $");
16 16
17#include "ssh.h" 17#include "ssh.h"
18#include "xmalloc.h" 18#include "xmalloc.h"
@@ -114,7 +114,7 @@ typedef enum {
114 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication, 114 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
115 oHostKeyAlgorithms, oBindAddress, oSmartcardDevice, 115 oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
116 oClearAllForwardings, oNoHostAuthenticationForLocalhost, 116 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
117 oEnableSSHKeysign, 117 oEnableSSHKeysign, oRekeyLimit,
118 oDeprecated 118 oDeprecated
119} OpCodes; 119} OpCodes;
120 120
@@ -188,6 +188,7 @@ static struct {
188 { "clearallforwardings", oClearAllForwardings }, 188 { "clearallforwardings", oClearAllForwardings },
189 { "enablesshkeysign", oEnableSSHKeysign }, 189 { "enablesshkeysign", oEnableSSHKeysign },
190 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost }, 190 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
191 { "rekeylimit", oRekeyLimit },
191 { NULL, oBadOption } 192 { NULL, oBadOption }
192}; 193};
193 194
@@ -423,6 +424,31 @@ parse_flag:
423 intptr = &options->compression_level; 424 intptr = &options->compression_level;
424 goto parse_int; 425 goto parse_int;
425 426
427 case oRekeyLimit:
428 intptr = &options->rekey_limit;
429 arg = strdelim(&s);
430 if (!arg || *arg == '\0')
431 fatal("%.200s line %d: Missing argument.", filename, linenum);
432 if (arg[0] < '0' || arg[0] > '9')
433 fatal("%.200s line %d: Bad number.", filename, linenum);
434 value = strtol(arg, &endofnumber, 10);
435 if (arg == endofnumber)
436 fatal("%.200s line %d: Bad number.", filename, linenum);
437 switch (toupper(*endofnumber)) {
438 case 'K':
439 value *= 1<<10;
440 break;
441 case 'M':
442 value *= 1<<20;
443 break;
444 case 'G':
445 value *= 1<<30;
446 break;
447 }
448 if (*activep && *intptr == -1)
449 *intptr = value;
450 break;
451
426 case oIdentityFile: 452 case oIdentityFile:
427 arg = strdelim(&s); 453 arg = strdelim(&s);
428 if (!arg || *arg == '\0') 454 if (!arg || *arg == '\0')
@@ -795,6 +821,7 @@ initialize_options(Options * options)
795 options->smartcard_device = NULL; 821 options->smartcard_device = NULL;
796 options->enable_ssh_keysign = - 1; 822 options->enable_ssh_keysign = - 1;
797 options->no_host_authentication_for_localhost = - 1; 823 options->no_host_authentication_for_localhost = - 1;
824 options->rekey_limit = - 1;
798} 825}
799 826
800/* 827/*
@@ -911,6 +938,8 @@ fill_default_options(Options * options)
911 options->no_host_authentication_for_localhost = 0; 938 options->no_host_authentication_for_localhost = 0;
912 if (options->enable_ssh_keysign == -1) 939 if (options->enable_ssh_keysign == -1)
913 options->enable_ssh_keysign = 0; 940 options->enable_ssh_keysign = 0;
941 if (options->rekey_limit == -1)
942 options->rekey_limit = 0;
914 /* options->proxy_command should not be set by default */ 943 /* options->proxy_command should not be set by default */
915 /* options->user will be set in the main program if appropriate */ 944 /* options->user will be set in the main program if appropriate */
916 /* options->hostname will be set in the main program if appropriate */ 945 /* options->hostname will be set in the main program if appropriate */
diff --git a/readconf.h b/readconf.h
index 78e04fedf..d35472117 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.h,v 1.46 2003/04/01 10:22:21 markus Exp $ */ 1/* $OpenBSD: readconf.h,v 1.47 2003/04/02 09:48:07 markus Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -101,6 +101,7 @@ typedef struct {
101 int clear_forwardings; 101 int clear_forwardings;
102 102
103 int enable_ssh_keysign; 103 int enable_ssh_keysign;
104 int rekey_limit;
104 int no_host_authentication_for_localhost; 105 int no_host_authentication_for_localhost;
105} Options; 106} Options;
106 107
diff --git a/serverloop.c b/serverloop.c
index f4df9cccb..187afc716 100644
--- a/serverloop.c
+++ b/serverloop.c
@@ -35,7 +35,7 @@
35 */ 35 */
36 36
37#include "includes.h" 37#include "includes.h"
38RCSID("$OpenBSD: serverloop.c,v 1.106 2003/04/01 10:22:21 markus Exp $"); 38RCSID("$OpenBSD: serverloop.c,v 1.107 2003/04/02 09:48:07 markus Exp $");
39 39
40#include "xmalloc.h" 40#include "xmalloc.h"
41#include "packet.h" 41#include "packet.h"
@@ -771,8 +771,14 @@ server_loop2(Authctxt *authctxt)
771 &nalloc, 0); 771 &nalloc, 0);
772 772
773 collect_children(); 773 collect_children();
774 if (!rekeying) 774 if (!rekeying) {
775 channel_after_select(readset, writeset); 775 channel_after_select(readset, writeset);
776 if (packet_need_rekeying()) {
777 debug("need rekeying");
778 xxx_kex->done = 0;
779 kex_send_kexinit(xxx_kex);
780 }
781 }
776 process_input(readset); 782 process_input(readset);
777 if (connection_closed) 783 if (connection_closed)
778 break; 784 break;
diff --git a/sshconnect2.c b/sshconnect2.c
index 642b34b9e..41768bf05 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25#include "includes.h" 25#include "includes.h"
26RCSID("$OpenBSD: sshconnect2.c,v 1.114 2003/04/01 10:22:21 markus Exp $"); 26RCSID("$OpenBSD: sshconnect2.c,v 1.115 2003/04/02 09:48:07 markus Exp $");
27 27
28#include "ssh.h" 28#include "ssh.h"
29#include "ssh2.h" 29#include "ssh2.h"
@@ -108,6 +108,9 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
108 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = 108 myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
109 options.hostkeyalgorithms; 109 options.hostkeyalgorithms;
110 110
111 if (options.rekey_limit)
112 packet_set_rekey_limit(options.rekey_limit);
113
111 /* start key exchange */ 114 /* start key exchange */
112 kex = kex_setup(myproposal); 115 kex = kex_setup(myproposal);
113 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client; 116 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;