diff options
Diffstat (limited to 'packet.c')
-rw-r--r-- | packet.c | 74 |
1 files changed, 51 insertions, 23 deletions
@@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.182 2013/04/11 02:27:50 djm Exp $ */ +/* $OpenBSD: packet.c,v 1.188 2013/07/12 00:19:58 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -58,6 +58,7 @@ #include <string.h> #include <unistd.h> #include <signal.h> +#include <time.h> #include "xmalloc.h" #include "buffer.h" @@ -165,9 +166,14 @@ struct session_state { Newkeys *newkeys[MODE_MAX]; struct packet_state p_read, p_send; + /* Volume-based rekeying */ u_int64_t max_blocks_in, max_blocks_out; u_int32_t rekey_limit; + /* Time-based rekeying */ + time_t rekey_interval; /* how often in seconds */ + time_t rekey_time; /* time of last rekeying */ + /* Session key for protocol v1 */ u_char ssh1_key[SSH_SESSION_KEY_LENGTH]; u_int ssh1_keylen; @@ -215,7 +221,7 @@ alloc_session_state(void) void packet_set_connection(int fd_in, int fd_out) { - Cipher *none = cipher_by_name("none"); + const Cipher *none = cipher_by_name("none"); if (none == NULL) fatal("packet_set_connection: cannot load cipher 'none'"); @@ -545,7 +551,7 @@ packet_start_compression(int level) void packet_set_encryption_key(const u_char *key, u_int keylen, int number) { - Cipher *cipher = cipher_by_number(number); + const Cipher *cipher = cipher_by_number(number); if (cipher == NULL) fatal("packet_set_encryption_key: unknown cipher number %d", number); @@ -760,13 +766,13 @@ set_newkeys(int mode) memset(enc->iv, 0, enc->iv_len); memset(enc->key, 0, enc->key_len); memset(mac->key, 0, mac->key_len); - xfree(enc->name); - xfree(enc->iv); - xfree(enc->key); - xfree(mac->name); - xfree(mac->key); - xfree(comp->name); - xfree(active_state->newkeys[mode]); + free(enc->name); + free(enc->iv); + free(enc->key); + free(mac->name); + free(mac->key); + free(comp->name); + free(active_state->newkeys[mode]); } active_state->newkeys[mode] = kex_get_newkeys(mode); if (active_state->newkeys[mode] == NULL) @@ -1009,6 +1015,7 @@ packet_send2(void) /* after a NEWKEYS message we can send the complete queue */ if (type == SSH2_MSG_NEWKEYS) { active_state->rekeying = 0; + active_state->rekey_time = monotime(); while ((p = TAILQ_FIRST(&active_state->outgoing))) { type = p->type; debug("dequeue packet: %u", type); @@ -1016,7 +1023,7 @@ packet_send2(void) memcpy(&active_state->outgoing_packet, &p->payload, sizeof(Buffer)); TAILQ_REMOVE(&active_state->outgoing, p, next); - xfree(p); + free(p); packet_send2_wrapped(); } } @@ -1041,7 +1048,7 @@ packet_send(void) int packet_read_seqnr(u_int32_t *seqnr_p) { - int type, len, ret, ms_remain, cont; + int type, len, ret, cont, ms_remain = 0; fd_set *setp; char buf[8192]; struct timeval timeout, start, *timeoutp = NULL; @@ -1066,7 +1073,7 @@ packet_read_seqnr(u_int32_t *seqnr_p) packet_check_eom(); /* If we got a packet, return it. */ if (type != SSH_MSG_NONE) { - xfree(setp); + free(setp); return type; } /* @@ -1453,9 +1460,9 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) packet_get_char(); msg = packet_get_string(NULL); debug("Remote: %.900s", msg); - xfree(msg); + free(msg); msg = packet_get_string(NULL); - xfree(msg); + free(msg); break; case SSH2_MSG_DISCONNECT: reason = packet_get_int(); @@ -1466,7 +1473,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, "Received disconnect from %s: %u: %.400s", get_remote_ipaddr(), reason, msg); - xfree(msg); + free(msg); cleanup_exit(255); break; case SSH2_MSG_UNIMPLEMENTED: @@ -1480,12 +1487,14 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) } else { type = packet_read_poll1(); switch (type) { + case SSH_MSG_NONE: + return SSH_MSG_NONE; case SSH_MSG_IGNORE: break; case SSH_MSG_DEBUG: msg = packet_get_string(NULL); debug("Remote: %.900s", msg); - xfree(msg); + free(msg); break; case SSH_MSG_DISCONNECT: msg = packet_get_string(NULL); @@ -1494,8 +1503,7 @@ packet_read_poll_seqnr(u_int32_t *seqnr_p) cleanup_exit(255); break; default: - if (type) - DBG(debug("received packet type %d", type)); + DBG(debug("received packet type %d", type)); return type; } } @@ -1732,7 +1740,7 @@ void packet_write_wait(void) { fd_set *setp; - int ret, ms_remain; + int ret, ms_remain = 0; struct timeval start, timeout, *timeoutp = NULL; setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1, @@ -1773,7 +1781,7 @@ packet_write_wait(void) } packet_write_poll(); } - xfree(setp); + free(setp); } /* Returns true if there is buffered data to write to the connection. */ @@ -1933,13 +1941,33 @@ packet_need_rekeying(void) (active_state->max_blocks_out && (active_state->p_send.blocks > active_state->max_blocks_out)) || (active_state->max_blocks_in && - (active_state->p_read.blocks > active_state->max_blocks_in)); + (active_state->p_read.blocks > active_state->max_blocks_in)) || + (active_state->rekey_interval != 0 && active_state->rekey_time + + active_state->rekey_interval <= monotime()); } void -packet_set_rekey_limit(u_int32_t bytes) +packet_set_rekey_limits(u_int32_t bytes, time_t seconds) { + debug3("rekey after %lld bytes, %d seconds", (long long)bytes, + (int)seconds); active_state->rekey_limit = bytes; + active_state->rekey_interval = seconds; + /* + * We set the time here so that in post-auth privsep slave we count + * from the completion of the authentication. + */ + active_state->rekey_time = monotime(); +} + +time_t +packet_get_rekey_timeout(void) +{ + time_t seconds; + + seconds = active_state->rekey_time + active_state->rekey_interval - + monotime(); + return (seconds <= 0 ? 1 : seconds); } void |