version 1.158, 2008/11/21 15:47:38 |
version 1.159, 2009/01/26 09:58:15 |
|
|
#define DBG(x) |
#define DBG(x) |
#endif |
#endif |
|
|
|
#define PACKET_MAX_SIZE (256 * 1024) |
|
|
/* |
/* |
* This variable contains the file descriptors used for communicating with |
* This variable contains the file descriptors used for communicating with |
* the other side. connection_in is used for reading; connection_out for |
* the other side. connection_in is used for reading; connection_out for |
|
|
/* roundup current message to extra_pad bytes */ |
/* roundup current message to extra_pad bytes */ |
static u_char extra_pad = 0; |
static u_char extra_pad = 0; |
|
|
|
/* XXX discard incoming data after MAC error */ |
|
static u_int packet_discard = 0; |
|
static Mac *packet_discard_mac = NULL; |
|
|
struct packet { |
struct packet { |
TAILQ_ENTRY(packet) next; |
TAILQ_ENTRY(packet) next; |
u_char type; |
u_char type; |
|
|
packet_timeout_ms = timeout * count * 1000; |
packet_timeout_ms = timeout * count * 1000; |
} |
} |
|
|
|
static void |
|
packet_stop_discard(void) |
|
{ |
|
if (packet_discard_mac) { |
|
char buf[1024]; |
|
|
|
memset(buf, 'a', sizeof(buf)); |
|
while (buffer_len(&incoming_packet) < PACKET_MAX_SIZE) |
|
buffer_append(&incoming_packet, buf, sizeof(buf)); |
|
(void) mac_compute(packet_discard_mac, |
|
p_read.seqnr, |
|
buffer_ptr(&incoming_packet), |
|
PACKET_MAX_SIZE); |
|
} |
|
logit("Finished discarding for %.200s", get_remote_ipaddr()); |
|
cleanup_exit(255); |
|
} |
|
|
|
static void |
|
packet_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard) |
|
{ |
|
if (!cipher_is_cbc(enc->cipher)) |
|
packet_disconnect("Packet corrupt"); |
|
if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled) |
|
packet_discard_mac = mac; |
|
if (buffer_len(&input) >= discard) |
|
packet_stop_discard(); |
|
packet_discard = discard - buffer_len(&input); |
|
} |
|
|
/* Returns 1 if remote host is connected via socket, 0 if not. */ |
/* Returns 1 if remote host is connected via socket, 0 if not. */ |
|
|
int |
int |
|
|
Mac *mac = NULL; |
Mac *mac = NULL; |
Comp *comp = NULL; |
Comp *comp = NULL; |
|
|
|
if (packet_discard) |
|
return SSH_MSG_NONE; |
|
|
if (newkeys[MODE_IN] != NULL) { |
if (newkeys[MODE_IN] != NULL) { |
enc = &newkeys[MODE_IN]->enc; |
enc = &newkeys[MODE_IN]->enc; |
mac = &newkeys[MODE_IN]->mac; |
mac = &newkeys[MODE_IN]->mac; |
|
|
block_size); |
block_size); |
cp = buffer_ptr(&incoming_packet); |
cp = buffer_ptr(&incoming_packet); |
packet_length = get_u32(cp); |
packet_length = get_u32(cp); |
if (packet_length < 1 + 4 || packet_length > 256 * 1024) { |
if (packet_length < 1 + 4 || packet_length > PACKET_MAX_SIZE) { |
#ifdef PACKET_DEBUG |
#ifdef PACKET_DEBUG |
buffer_dump(&incoming_packet); |
buffer_dump(&incoming_packet); |
#endif |
#endif |
packet_disconnect("Bad packet length %-10u", |
logit("Bad packet length %u.", packet_length); |
packet_length); |
packet_start_discard(enc, mac, packet_length, |
|
PACKET_MAX_SIZE); |
|
return SSH_MSG_NONE; |
} |
} |
DBG(debug("input: packet len %u", packet_length+4)); |
DBG(debug("input: packet len %u", packet_length+4)); |
buffer_consume(&input, block_size); |
buffer_consume(&input, block_size); |
|
|
if (need % block_size != 0) { |
if (need % block_size != 0) { |
logit("padding error: need %d block %d mod %d", |
logit("padding error: need %d block %d mod %d", |
need, block_size, need % block_size); |
need, block_size, need % block_size); |
packet_disconnect("Bad packet length %-10u", packet_length); |
packet_start_discard(enc, mac, packet_length, |
|
PACKET_MAX_SIZE - block_size); |
|
return SSH_MSG_NONE; |
} |
} |
/* |
/* |
* check if the entire packet has been received and |
* check if the entire packet has been received and |
|
|
macbuf = mac_compute(mac, p_read.seqnr, |
macbuf = mac_compute(mac, p_read.seqnr, |
buffer_ptr(&incoming_packet), |
buffer_ptr(&incoming_packet), |
buffer_len(&incoming_packet)); |
buffer_len(&incoming_packet)); |
if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) |
if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) { |
packet_disconnect("Corrupted MAC on input."); |
logit("Corrupted MAC on input."); |
|
if (need > PACKET_MAX_SIZE) |
|
fatal("internal error need %d", need); |
|
packet_start_discard(enc, mac, packet_length, |
|
PACKET_MAX_SIZE - need); |
|
return SSH_MSG_NONE; |
|
} |
|
|
DBG(debug("MAC #%d ok", p_read.seqnr)); |
DBG(debug("MAC #%d ok", p_read.seqnr)); |
buffer_consume(&input, mac->mac_len); |
buffer_consume(&input, mac->mac_len); |
} |
} |
|
/* XXX now it's safe to use fatal/packet_disconnect */ |
if (seqnr_p != NULL) |
if (seqnr_p != NULL) |
*seqnr_p = p_read.seqnr; |
*seqnr_p = p_read.seqnr; |
if (++p_read.seqnr == 0) |
if (++p_read.seqnr == 0) |
|
|
void |
void |
packet_process_incoming(const char *buf, u_int len) |
packet_process_incoming(const char *buf, u_int len) |
{ |
{ |
|
if (packet_discard) { |
|
keep_alive_timeouts = 0; /* ?? */ |
|
if (len >= packet_discard) |
|
packet_stop_discard(); |
|
packet_discard -= len; |
|
return; |
|
} |
buffer_append(&input, buf, len); |
buffer_append(&input, buf, len); |
} |
} |
|
|