X-Git-Url: http://andersk.mit.edu/gitweb/openssh.git/blobdiff_plain/782e2103cd27c76c374b89baddcabbfc5ebd265f..a77673cc8616ce641dc550efceff3a488f3e9f12:/packet.c diff --git a/packet.c b/packet.c index 258085d2..0a8baa5b 100644 --- a/packet.c +++ b/packet.c @@ -37,7 +37,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: packet.c,v 1.93 2002/03/24 16:01:13 markus Exp $"); +RCSID("$OpenBSD: packet.c,v 1.100 2002/11/21 22:45:31 markus Exp $"); #include "xmalloc.h" #include "buffer.h" @@ -60,6 +60,7 @@ RCSID("$OpenBSD: packet.c,v 1.93 2002/03/24 16:01:13 markus Exp $"); #include "log.h" #include "canohost.h" #include "misc.h" +#include "ssh.h" #ifdef PACKET_DEBUG #define DBG(x) x @@ -118,6 +119,10 @@ Newkeys *newkeys[MODE_MAX]; static u_int32_t read_seqnr = 0; static u_int32_t send_seqnr = 0; +/* Session key for protocol v1 */ +static u_char ssh1_key[SSH_SESSION_KEY_LENGTH]; +static u_int ssh1_keylen; + /* roundup current message to extra_pad bytes */ static u_char extra_pad = 0; @@ -129,6 +134,7 @@ void packet_set_connection(int fd_in, int fd_out) { Cipher *none = cipher_by_name("none"); + if (none == NULL) fatal("packet_set_connection: cannot load cipher 'none'"); connection_in = fd_in; @@ -263,7 +269,7 @@ packet_set_seqnr(int mode, u_int32_t seqnr) else if (mode == MODE_OUT) send_seqnr = seqnr; else - fatal("%s: bad mode %d", __FUNCTION__, mode); + fatal("packet_set_seqnr: bad mode %d", mode); } /* returns 1 if connection is via ipv4 */ @@ -391,19 +397,34 @@ packet_start_compression(int level) * key is used for both sending and reception. However, both directions are * encrypted independently of each other. */ + void packet_set_encryption_key(const u_char *key, u_int keylen, int number) { Cipher *cipher = cipher_by_number(number); + if (cipher == NULL) fatal("packet_set_encryption_key: unknown cipher number %d", number); if (keylen < 20) fatal("packet_set_encryption_key: keylen too small: %d", keylen); + if (keylen > SSH_SESSION_KEY_LENGTH) + fatal("packet_set_encryption_key: keylen too big: %d", keylen); + memcpy(ssh1_key, key, keylen); + ssh1_keylen = keylen; cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT); cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT); } +u_int +packet_get_encryption_key(u_char *key) +{ + if (key == NULL) + return (ssh1_keylen); + memcpy(key, ssh1_key, ssh1_keylen); + return (ssh1_keylen); +} + /* Start constructing a packet to send. */ void packet_start(u_char type) @@ -424,6 +445,7 @@ void packet_put_char(int value) { char ch = value; + buffer_append(&outgoing_packet, &ch, 1); } void @@ -542,7 +564,7 @@ set_newkeys(int mode) CipherContext *cc; int encrypt; - debug("newkeys: mode %d", mode); + debug2("set_newkeys: mode %d", mode); if (mode == MODE_OUT) { cc = &send_context; @@ -552,7 +574,7 @@ set_newkeys(int mode) encrypt = CIPHER_DECRYPT; } if (newkeys[mode] != NULL) { - debug("newkeys: rekeying"); + debug("set_newkeys: rekeying"); cipher_cleanup(cc); enc = &newkeys[mode]->enc; mac = &newkeys[mode]->mac; @@ -818,7 +840,7 @@ packet_read_poll1(void) cp = buffer_ptr(&input); len = GET_32BIT(cp); if (len < 1 + 2 + 2 || len > 256 * 1024) - packet_disconnect("Bad packet length %d.", len); + packet_disconnect("Bad packet length %u.", len); padded_len = (len + 8) & ~7; /* Check if the packet has been entirely received. */ @@ -914,9 +936,9 @@ packet_read_poll2(u_int32_t *seqnr_p) packet_length = GET_32BIT(cp); if (packet_length < 1 + 4 || packet_length > 256 * 1024) { buffer_dump(&incoming_packet); - packet_disconnect("Bad packet length %d.", packet_length); + packet_disconnect("Bad packet length %u.", packet_length); } - DBG(debug("input: packet len %d", packet_length+4)); + DBG(debug("input: packet len %u", packet_length+4)); buffer_consume(&input, block_size); } /* we have a partial packet of block_size bytes */ @@ -975,7 +997,8 @@ packet_read_poll2(u_int32_t *seqnr_p) buffer_clear(&incoming_packet); buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), buffer_len(&compression_buffer)); - DBG(debug("input: len after de-compress %d", buffer_len(&incoming_packet))); + DBG(debug("input: len after de-compress %d", + buffer_len(&incoming_packet))); } /* * get packet type, implies consume. @@ -996,7 +1019,7 @@ packet_read_poll2(u_int32_t *seqnr_p) int packet_read_poll_seqnr(u_int32_t *seqnr_p) { - int reason, seqnr; + u_int reason, seqnr; u_char type; char *msg; @@ -1019,14 +1042,15 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) case SSH2_MSG_DISCONNECT: reason = packet_get_int(); msg = packet_get_string(NULL); - log("Received disconnect from %s: %d: %.400s", get_remote_ipaddr(), - reason, msg); + log("Received disconnect from %s: %u: %.400s", + get_remote_ipaddr(), reason, msg); xfree(msg); fatal_cleanup(); break; case SSH2_MSG_UNIMPLEMENTED: seqnr = packet_get_int(); - debug("Received SSH2_MSG_UNIMPLEMENTED for %d", seqnr); + debug("Received SSH2_MSG_UNIMPLEMENTED for %u", + seqnr); break; default: return type; @@ -1044,8 +1068,8 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) break; case SSH_MSG_DISCONNECT: msg = packet_get_string(NULL); - log("Received disconnect from %s: %.400s", get_remote_ipaddr(), - msg); + log("Received disconnect from %s: %.400s", + get_remote_ipaddr(), msg); fatal_cleanup(); xfree(msg); break; @@ -1082,6 +1106,7 @@ u_int packet_get_char(void) { char ch; + buffer_get(&incoming_packet, &ch, 1); return (u_char) ch; } @@ -1115,6 +1140,7 @@ void * packet_get_raw(int *length_ptr) { int bytes = buffer_len(&incoming_packet); + if (length_ptr != NULL) *length_ptr = bytes; return buffer_ptr(&incoming_packet); @@ -1187,6 +1213,7 @@ packet_disconnect(const char *fmt,...) char buf[1024]; va_list args; static int disconnecting = 0; + if (disconnecting) /* Guard against recursive invocations. */ fatal("packet_disconnect called recursively."); disconnecting = 1; @@ -1199,6 +1226,9 @@ packet_disconnect(const char *fmt,...) vsnprintf(buf, sizeof(buf), fmt, args); va_end(args); + /* Display the error locally */ + log("Disconnecting: %.100s", buf); + /* Send the disconnect message to the other side, and wait for it to get sent. */ if (compat20) { packet_start(SSH2_MSG_DISCONNECT); @@ -1218,8 +1248,6 @@ packet_disconnect(const char *fmt,...) /* Close the connection. */ packet_close(); - /* Display the error locally and exit. */ - log("Disconnecting: %.100s", buf); fatal_cleanup(); } @@ -1229,6 +1257,7 @@ void packet_write_poll(void) { int len = buffer_len(&output); + if (len > 0) { len = write(connection_out, buffer_ptr(&output), len); if (len <= 0) { @@ -1348,6 +1377,7 @@ int packet_set_maxsize(int s) { static int called = 0; + if (called) { log("packet_set_maxsize: called twice: old %d new %d", max_packet_size, s);