version 1.233, 2016/07/18 06:08:01 |
version 1.234, 2016/07/18 11:35:33 |
|
|
|
|
/* XXX discard incoming data after MAC error */ |
/* XXX discard incoming data after MAC error */ |
u_int packet_discard; |
u_int packet_discard; |
|
size_t packet_discard_mac_already; |
struct sshmac *packet_discard_mac; |
struct sshmac *packet_discard_mac; |
|
|
/* Used in packet_read_poll2() */ |
/* Used in packet_read_poll2() */ |
|
|
|
|
if (state->packet_discard_mac) { |
if (state->packet_discard_mac) { |
char buf[1024]; |
char buf[1024]; |
|
size_t dlen = PACKET_MAX_SIZE; |
|
|
|
if (dlen > state->packet_discard_mac_already) |
|
dlen -= state->packet_discard_mac_already; |
memset(buf, 'a', sizeof(buf)); |
memset(buf, 'a', sizeof(buf)); |
while (sshbuf_len(state->incoming_packet) < |
while (sshbuf_len(state->incoming_packet) < dlen) |
PACKET_MAX_SIZE) |
|
if ((r = sshbuf_put(state->incoming_packet, buf, |
if ((r = sshbuf_put(state->incoming_packet, buf, |
sizeof(buf))) != 0) |
sizeof(buf))) != 0) |
return r; |
return r; |
(void) mac_compute(state->packet_discard_mac, |
(void) mac_compute(state->packet_discard_mac, |
state->p_read.seqnr, |
state->p_read.seqnr, |
sshbuf_ptr(state->incoming_packet), PACKET_MAX_SIZE, |
sshbuf_ptr(state->incoming_packet), dlen, |
NULL, 0); |
NULL, 0); |
} |
} |
logit("Finished discarding for %.200s port %d", |
logit("Finished discarding for %.200s port %d", |
|
|
|
|
static int |
static int |
ssh_packet_start_discard(struct ssh *ssh, struct sshenc *enc, |
ssh_packet_start_discard(struct ssh *ssh, struct sshenc *enc, |
struct sshmac *mac, u_int packet_length, u_int discard) |
struct sshmac *mac, size_t mac_already, u_int discard) |
{ |
{ |
struct session_state *state = ssh->state; |
struct session_state *state = ssh->state; |
int r; |
int r; |
|
|
return r; |
return r; |
return SSH_ERR_MAC_INVALID; |
return SSH_ERR_MAC_INVALID; |
} |
} |
if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled) |
/* |
|
* Record number of bytes over which the mac has already |
|
* been computed in order to minimize timing attacks. |
|
*/ |
|
if (mac && mac->enabled) { |
state->packet_discard_mac = mac; |
state->packet_discard_mac = mac; |
if (sshbuf_len(state->input) >= discard && |
state->packet_discard_mac_already = mac_already; |
(r = ssh_packet_stop_discard(ssh)) != 0) |
} |
return r; |
if (sshbuf_len(state->input) >= discard) |
|
return ssh_packet_stop_discard(ssh); |
state->packet_discard = discard - sshbuf_len(state->input); |
state->packet_discard = discard - sshbuf_len(state->input); |
return 0; |
return 0; |
} |
} |
|
|
sshbuf_dump(state->incoming_packet, stderr); |
sshbuf_dump(state->incoming_packet, stderr); |
#endif |
#endif |
logit("Bad packet length %u.", state->packlen); |
logit("Bad packet length %u.", state->packlen); |
return ssh_packet_start_discard(ssh, enc, mac, |
return ssh_packet_start_discard(ssh, enc, mac, 0, |
state->packlen, PACKET_MAX_SIZE); |
PACKET_MAX_SIZE); |
} |
} |
if ((r = sshbuf_consume(state->input, block_size)) != 0) |
if ((r = sshbuf_consume(state->input, block_size)) != 0) |
goto out; |
goto out; |
|
|
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); |
return ssh_packet_start_discard(ssh, enc, mac, |
return ssh_packet_start_discard(ssh, enc, mac, 0, |
state->packlen, PACKET_MAX_SIZE - block_size); |
PACKET_MAX_SIZE - block_size); |
} |
} |
/* |
/* |
* check if the entire packet has been received and |
* check if the entire packet has been received and |
|
|
if (need > PACKET_MAX_SIZE) |
if (need > PACKET_MAX_SIZE) |
return SSH_ERR_INTERNAL_ERROR; |
return SSH_ERR_INTERNAL_ERROR; |
return ssh_packet_start_discard(ssh, enc, mac, |
return ssh_packet_start_discard(ssh, enc, mac, |
state->packlen, PACKET_MAX_SIZE - need); |
sshbuf_len(state->incoming_packet), |
|
PACKET_MAX_SIZE - need); |
} |
} |
/* Remove MAC from input buffer */ |
/* Remove MAC from input buffer */ |
DBG(debug("MAC #%d ok", state->p_read.seqnr)); |
DBG(debug("MAC #%d ok", state->p_read.seqnr)); |