summaryrefslogtreecommitdiff
path: root/packet.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2003-09-01 18:52:37 +0000
committerColin Watson <cjwatson@debian.org>2003-09-01 18:52:37 +0000
commit854156dd39acbde9b4a47ec0fc54a042ea7358e0 (patch)
tree96755f8590acc2146f4b4ef5b5cdba600e5d9353 /packet.c
parentfad82e8999e790899083f9e22a1841148d746df6 (diff)
parent053db7da5ce09acdf742789d9d1a05e81d4861d0 (diff)
Import OpenSSH 3.6.1p2.
Diffstat (limited to 'packet.c')
-rw-r--r--packet.c165
1 files changed, 30 insertions, 135 deletions
diff --git a/packet.c b/packet.c
index 2abfeddb8..3e21df722 100644
--- a/packet.c
+++ b/packet.c
@@ -37,9 +37,7 @@
37 */ 37 */
38 38
39#include "includes.h" 39#include "includes.h"
40RCSID("$OpenBSD: packet.c,v 1.105 2003/04/02 09:48:07 markus Exp $"); 40RCSID("$OpenBSD: packet.c,v 1.104 2003/04/01 10:22:21 markus Exp $");
41
42#include "openbsd-compat/sys-queue.h"
43 41
44#include "xmalloc.h" 42#include "xmalloc.h"
45#include "buffer.h" 43#include "buffer.h"
@@ -118,14 +116,8 @@ static int interactive_mode = 0;
118 116
119/* Session key information for Encryption and MAC */ 117/* Session key information for Encryption and MAC */
120Newkeys *newkeys[MODE_MAX]; 118Newkeys *newkeys[MODE_MAX];
121static struct packet_state { 119static u_int32_t read_seqnr = 0;
122 u_int32_t seqnr; 120static u_int32_t send_seqnr = 0;
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;
129 121
130/* Session key for protocol v1 */ 122/* Session key for protocol v1 */
131static u_char ssh1_key[SSH_SESSION_KEY_LENGTH]; 123static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
@@ -134,13 +126,6 @@ static u_int ssh1_keylen;
134/* roundup current message to extra_pad bytes */ 126/* roundup current message to extra_pad bytes */
135static u_char extra_pad = 0; 127static u_char extra_pad = 0;
136 128
137struct packet {
138 TAILQ_ENTRY(packet) next;
139 u_char type;
140 Buffer payload;
141};
142TAILQ_HEAD(, packet) outgoing;
143
144/* 129/*
145 * Sets the descriptors used for communication. Disables encryption until 130 * Sets the descriptors used for communication. Disables encryption until
146 * packet_set_encryption_key is called. 131 * packet_set_encryption_key is called.
@@ -163,7 +148,6 @@ packet_set_connection(int fd_in, int fd_out)
163 buffer_init(&output); 148 buffer_init(&output);
164 buffer_init(&outgoing_packet); 149 buffer_init(&outgoing_packet);
165 buffer_init(&incoming_packet); 150 buffer_init(&incoming_packet);
166 TAILQ_INIT(&outgoing);
167 } 151 }
168 /* Kludge: arrange the close function to be called from fatal(). */ 152 /* Kludge: arrange the close function to be called from fatal(). */
169 fatal_add_cleanup((void (*) (void *)) packet_close, NULL); 153 fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
@@ -270,26 +254,22 @@ packet_get_ssh1_cipher()
270 return (cipher_get_number(receive_context.cipher)); 254 return (cipher_get_number(receive_context.cipher));
271} 255}
272 256
273void
274packet_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets)
275{
276 struct packet_state *state;
277 257
278 state = (mode == MODE_IN) ? &p_read : &p_send; 258u_int32_t
279 *seqnr = state->seqnr; 259packet_get_seqnr(int mode)
280 *blocks = state->blocks; 260{
281 *packets = state->packets; 261 return (mode == MODE_IN ? read_seqnr : send_seqnr);
282} 262}
283 263
284void 264void
285packet_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets) 265packet_set_seqnr(int mode, u_int32_t seqnr)
286{ 266{
287 struct packet_state *state; 267 if (mode == MODE_IN)
288 268 read_seqnr = seqnr;
289 state = (mode == MODE_IN) ? &p_read : &p_send; 269 else if (mode == MODE_OUT)
290 state->seqnr = seqnr; 270 send_seqnr = seqnr;
291 state->blocks = blocks; 271 else
292 state->packets = packets; 272 fatal("packet_set_seqnr: bad mode %d", mode);
293} 273}
294 274
295/* returns 1 if connection is via ipv4 */ 275/* returns 1 if connection is via ipv4 */
@@ -582,7 +562,6 @@ set_newkeys(int mode)
582 Mac *mac; 562 Mac *mac;
583 Comp *comp; 563 Comp *comp;
584 CipherContext *cc; 564 CipherContext *cc;
585 u_int64_t *max_blocks;
586 int encrypt; 565 int encrypt;
587 566
588 debug2("set_newkeys: mode %d", mode); 567 debug2("set_newkeys: mode %d", mode);
@@ -590,13 +569,9 @@ set_newkeys(int mode)
590 if (mode == MODE_OUT) { 569 if (mode == MODE_OUT) {
591 cc = &send_context; 570 cc = &send_context;
592 encrypt = CIPHER_ENCRYPT; 571 encrypt = CIPHER_ENCRYPT;
593 p_send.packets = p_send.blocks = 0;
594 max_blocks = &max_blocks_out;
595 } else { 572 } else {
596 cc = &receive_context; 573 cc = &receive_context;
597 encrypt = CIPHER_DECRYPT; 574 encrypt = CIPHER_DECRYPT;
598 p_read.packets = p_read.blocks = 0;
599 max_blocks = &max_blocks_in;
600 } 575 }
601 if (newkeys[mode] != NULL) { 576 if (newkeys[mode] != NULL) {
602 debug("set_newkeys: rekeying"); 577 debug("set_newkeys: rekeying");
@@ -635,16 +610,13 @@ set_newkeys(int mode)
635 buffer_compress_init_recv(); 610 buffer_compress_init_recv();
636 comp->enabled = 1; 611 comp->enabled = 1;
637 } 612 }
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);
641} 613}
642 614
643/* 615/*
644 * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) 616 * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
645 */ 617 */
646static void 618static void
647packet_send2_wrapped(void) 619packet_send2(void)
648{ 620{
649 u_char type, *cp, *macbuf = NULL; 621 u_char type, *cp, *macbuf = NULL;
650 u_char padlen, pad; 622 u_char padlen, pad;
@@ -726,10 +698,10 @@ packet_send2_wrapped(void)
726 698
727 /* compute MAC over seqnr and packet(length fields, payload, padding) */ 699 /* compute MAC over seqnr and packet(length fields, payload, padding) */
728 if (mac && mac->enabled) { 700 if (mac && mac->enabled) {
729 macbuf = mac_compute(mac, p_send.seqnr, 701 macbuf = mac_compute(mac, send_seqnr,
730 buffer_ptr(&outgoing_packet), 702 buffer_ptr(&outgoing_packet),
731 buffer_len(&outgoing_packet)); 703 buffer_len(&outgoing_packet));
732 DBG(debug("done calc MAC out #%d", p_send.seqnr)); 704 DBG(debug("done calc MAC out #%d", send_seqnr));
733 } 705 }
734 /* encrypt packet and append to output buffer. */ 706 /* encrypt packet and append to output buffer. */
735 cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); 707 cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
@@ -743,64 +715,14 @@ packet_send2_wrapped(void)
743 buffer_dump(&output); 715 buffer_dump(&output);
744#endif 716#endif
745 /* increment sequence number for outgoing packets */ 717 /* increment sequence number for outgoing packets */
746 if (++p_send.seqnr == 0) 718 if (++send_seqnr == 0)
747 logit("outgoing seqnr wraps around"); 719 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;
752 buffer_clear(&outgoing_packet); 720 buffer_clear(&outgoing_packet);
753 721
754 if (type == SSH2_MSG_NEWKEYS) 722 if (type == SSH2_MSG_NEWKEYS)
755 set_newkeys(MODE_OUT); 723 set_newkeys(MODE_OUT);
756} 724}
757 725
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
804void 726void
805packet_send(void) 727packet_send(void)
806{ 728{
@@ -862,7 +784,7 @@ packet_read_seqnr(u_int32_t *seqnr_p)
862 /* Read data from the socket. */ 784 /* Read data from the socket. */
863 len = read(connection_in, buf, sizeof(buf)); 785 len = read(connection_in, buf, sizeof(buf));
864 if (len == 0) { 786 if (len == 0) {
865 logit("Connection closed by %.200s", get_remote_ipaddr()); 787 log("Connection closed by %.200s", get_remote_ipaddr());
866 fatal_cleanup(); 788 fatal_cleanup();
867 } 789 }
868 if (len < 0) 790 if (len < 0)
@@ -1044,22 +966,18 @@ packet_read_poll2(u_int32_t *seqnr_p)
1044 * increment sequence number for incoming packet 966 * increment sequence number for incoming packet
1045 */ 967 */
1046 if (mac && mac->enabled) { 968 if (mac && mac->enabled) {
1047 macbuf = mac_compute(mac, p_read.seqnr, 969 macbuf = mac_compute(mac, read_seqnr,
1048 buffer_ptr(&incoming_packet), 970 buffer_ptr(&incoming_packet),
1049 buffer_len(&incoming_packet)); 971 buffer_len(&incoming_packet));
1050 if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) 972 if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
1051 packet_disconnect("Corrupted MAC on input."); 973 packet_disconnect("Corrupted MAC on input.");
1052 DBG(debug("MAC #%d ok", p_read.seqnr)); 974 DBG(debug("MAC #%d ok", read_seqnr));
1053 buffer_consume(&input, mac->mac_len); 975 buffer_consume(&input, mac->mac_len);
1054 } 976 }
1055 if (seqnr_p != NULL) 977 if (seqnr_p != NULL)
1056 *seqnr_p = p_read.seqnr; 978 *seqnr_p = read_seqnr;
1057 if (++p_read.seqnr == 0) 979 if (++read_seqnr == 0)
1058 logit("incoming seqnr wraps around"); 980 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;
1063 981
1064 /* get padlen */ 982 /* get padlen */
1065 cp = buffer_ptr(&incoming_packet); 983 cp = buffer_ptr(&incoming_packet);
@@ -1124,7 +1042,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
1124 case SSH2_MSG_DISCONNECT: 1042 case SSH2_MSG_DISCONNECT:
1125 reason = packet_get_int(); 1043 reason = packet_get_int();
1126 msg = packet_get_string(NULL); 1044 msg = packet_get_string(NULL);
1127 logit("Received disconnect from %s: %u: %.400s", 1045 log("Received disconnect from %s: %u: %.400s",
1128 get_remote_ipaddr(), reason, msg); 1046 get_remote_ipaddr(), reason, msg);
1129 xfree(msg); 1047 xfree(msg);
1130 fatal_cleanup(); 1048 fatal_cleanup();
@@ -1150,7 +1068,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p)
1150 break; 1068 break;
1151 case SSH_MSG_DISCONNECT: 1069 case SSH_MSG_DISCONNECT:
1152 msg = packet_get_string(NULL); 1070 msg = packet_get_string(NULL);
1153 logit("Received disconnect from %s: %.400s", 1071 log("Received disconnect from %s: %.400s",
1154 get_remote_ipaddr(), msg); 1072 get_remote_ipaddr(), msg);
1155 fatal_cleanup(); 1073 fatal_cleanup();
1156 xfree(msg); 1074 xfree(msg);
@@ -1309,7 +1227,7 @@ packet_disconnect(const char *fmt,...)
1309 va_end(args); 1227 va_end(args);
1310 1228
1311 /* Display the error locally */ 1229 /* Display the error locally */
1312 logit("Disconnecting: %.100s", buf); 1230 log("Disconnecting: %.100s", buf);
1313 1231
1314 /* Send the disconnect message to the other side, and wait for it to get sent. */ 1232 /* Send the disconnect message to the other side, and wait for it to get sent. */
1315 if (compat20) { 1233 if (compat20) {
@@ -1396,8 +1314,6 @@ packet_not_very_much_data_to_write(void)
1396 return buffer_len(&output) < 128 * 1024; 1314 return buffer_len(&output) < 128 * 1024;
1397} 1315}
1398 1316
1399
1400#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
1401static void 1317static void
1402packet_set_tos(int interactive) 1318packet_set_tos(int interactive)
1403{ 1319{
@@ -1411,7 +1327,6 @@ packet_set_tos(int interactive)
1411 error("setsockopt IP_TOS %d: %.100s:", 1327 error("setsockopt IP_TOS %d: %.100s:",
1412 tos, strerror(errno)); 1328 tos, strerror(errno));
1413} 1329}
1414#endif
1415 1330
1416/* Informs that the current session is interactive. Sets IP flags for that. */ 1331/* Informs that the current session is interactive. Sets IP flags for that. */
1417 1332
@@ -1429,7 +1344,6 @@ packet_set_interactive(int interactive)
1429 1344
1430 /* Only set socket options if using a socket. */ 1345 /* Only set socket options if using a socket. */
1431 if (!packet_connection_is_on_socket()) 1346 if (!packet_connection_is_on_socket())
1432 return;
1433 if (interactive) 1347 if (interactive)
1434 set_nodelay(connection_in); 1348 set_nodelay(connection_in);
1435#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) 1349#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
@@ -1452,12 +1366,12 @@ packet_set_maxsize(int s)
1452 static int called = 0; 1366 static int called = 0;
1453 1367
1454 if (called) { 1368 if (called) {
1455 logit("packet_set_maxsize: called twice: old %d new %d", 1369 log("packet_set_maxsize: called twice: old %d new %d",
1456 max_packet_size, s); 1370 max_packet_size, s);
1457 return -1; 1371 return -1;
1458 } 1372 }
1459 if (s < 4 * 1024 || s > 1024 * 1024) { 1373 if (s < 4 * 1024 || s > 1024 * 1024) {
1460 logit("packet_set_maxsize: bad size %d", s); 1374 log("packet_set_maxsize: bad size %d", s);
1461 return -1; 1375 return -1;
1462 } 1376 }
1463 called = 1; 1377 called = 1;
@@ -1499,22 +1413,3 @@ packet_send_ignore(int nbytes)
1499 rand >>= 8; 1413 rand >>= 8;
1500 } 1414 }
1501} 1415}
1502
1503#define MAX_PACKETS (1<<31)
1504int
1505packet_need_rekeying(void)
1506{
1507 if (datafellows & SSH_BUG_NOREKEY)
1508 return 0;
1509 return
1510 (p_send.packets > MAX_PACKETS) ||
1511 (p_read.packets > MAX_PACKETS) ||
1512 (max_blocks_out && (p_send.blocks > max_blocks_out)) ||
1513 (max_blocks_in && (p_read.blocks > max_blocks_in));
1514}
1515
1516void
1517packet_set_rekey_limit(u_int32_t bytes)
1518{
1519 rekey_limit = bytes;
1520}