*/
#include "includes.h"
-RCSID("$OpenBSD: packet.c,v 1.115 2004/06/21 17:36:31 avsm Exp $");
+RCSID("$OpenBSD: packet.c,v 1.120 2005/10/30 08:52:17 djm Exp $");
#include "openbsd-compat/sys-queue.h"
/* Set to true if the connection is interactive. */
static int interactive_mode = 0;
+/* Set to true if we are the server side. */
+static int server_side = 0;
+
+/* Set to true if we are authenticated. */
+static int after_authentication = 0;
+
/* Session key information for Encryption and MAC */
Newkeys *newkeys[MODE_MAX];
static struct packet_state {
buffer_clear(&outgoing_packet);
/*
- * Note that the packet is now only buffered in output. It won\'t be
+ * Note that the packet is now only buffered in output. It won't be
* actually sent until packet_write_wait or packet_write_poll is
* called.
*/
/* Deleting the keys does not gain extra security */
/* memset(enc->iv, 0, enc->block_size);
memset(enc->key, 0, enc->key_len); */
- if (comp->type != 0 && comp->enabled == 0) {
+ if ((comp->type == COMP_ZLIB ||
+ (comp->type == COMP_DELAYED && after_authentication)) &&
+ comp->enabled == 0) {
packet_init_compression();
if (mode == MODE_OUT)
buffer_compress_init_send(6);
*max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size);
}
+/*
+ * Delayed compression for SSH2 is enabled after authentication:
+ * This happans on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent,
+ * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received.
+ */
+static void
+packet_enable_delayed_compress(void)
+{
+ Comp *comp = NULL;
+ int mode;
+
+ /*
+ * Remember that we are past the authentication step, so rekeying
+ * with COMP_DELAYED will turn on compression immediately.
+ */
+ after_authentication = 1;
+ for (mode = 0; mode < MODE_MAX; mode++) {
+ comp = &newkeys[mode]->comp;
+ if (comp && !comp->enabled && comp->type == COMP_DELAYED) {
+ packet_init_compression();
+ if (mode == MODE_OUT)
+ buffer_compress_init_send(6);
+ else
+ buffer_compress_init_recv();
+ comp->enabled = 1;
+ }
+ }
+}
+
/*
* Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
*/
if (type == SSH2_MSG_NEWKEYS)
set_newkeys(MODE_OUT);
+ else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side)
+ packet_enable_delayed_compress();
}
static void
buffer_len(&compression_buffer));
}
type = buffer_get_char(&incoming_packet);
+ if (type < SSH_MSG_MIN || type > SSH_MSG_MAX)
+ packet_disconnect("Invalid ssh1 packet type: %d", type);
return type;
}
static u_int packet_length = 0;
u_int padlen, need;
u_char *macbuf, *cp, type;
- int maclen, block_size;
+ u_int maclen, block_size;
Enc *enc = NULL;
Mac *mac = NULL;
Comp *comp = NULL;
* return length of payload (without type field)
*/
type = buffer_get_char(&incoming_packet);
+ if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN)
+ packet_disconnect("Invalid ssh2 packet type: %d", type);
if (type == SSH2_MSG_NEWKEYS)
set_newkeys(MODE_IN);
+ else if (type == SSH2_MSG_USERAUTH_SUCCESS && !server_side)
+ packet_enable_delayed_compress();
#ifdef PACKET_DEBUG
fprintf(stderr, "read/plain[%d]:\r\n", type);
buffer_dump(&incoming_packet);
}
void *
-packet_get_raw(int *length_ptr)
+packet_get_raw(u_int *length_ptr)
{
- int bytes = buffer_len(&incoming_packet);
+ u_int bytes = buffer_len(&incoming_packet);
if (length_ptr != NULL)
*length_ptr = bytes;
rnd >>= 8;
}
}
+int rekey_requested = 0;
+
+void
+packet_request_rekeying(void)
+{
+ rekey_requested = 1;
+}
#define MAX_PACKETS (1U<<31)
int
{
if (datafellows & SSH_BUG_NOREKEY)
return 0;
+ if (rekey_requested == 1)
+ {
+ rekey_requested = 0;
+ return 1;
+ }
return
(p_send.packets > MAX_PACKETS) ||
(p_read.packets > MAX_PACKETS) ||
{
rekey_limit = bytes;
}
+
+void
+packet_set_server(void)
+{
+ server_side = 1;
+}
+
+void
+packet_set_authenticated(void)
+{
+ after_authentication = 1;
+}