version 1.70.2.2, 2002/03/07 17:37:46 |
version 1.70.2.3, 2002/05/17 00:03:23 |
|
|
static CipherContext send_context; |
static CipherContext send_context; |
|
|
/* Buffer for raw input data from the socket. */ |
/* Buffer for raw input data from the socket. */ |
static Buffer input; |
Buffer input; |
|
|
/* Buffer for raw output data going to the socket. */ |
/* Buffer for raw output data going to the socket. */ |
static Buffer output; |
Buffer output; |
|
|
/* Buffer for the partial outgoing packet being constructed. */ |
/* Buffer for the partial outgoing packet being constructed. */ |
static Buffer outgoing_packet; |
static Buffer outgoing_packet; |
|
|
|
|
/* Session key information for Encryption and MAC */ |
/* Session key information for Encryption and MAC */ |
Newkeys *newkeys[MODE_MAX]; |
Newkeys *newkeys[MODE_MAX]; |
|
static u_int32_t read_seqnr = 0; |
|
static u_int32_t send_seqnr = 0; |
|
|
/* 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; |
|
|
return 1; |
return 1; |
} |
} |
|
|
|
/* |
|
* Exports an IV from the CipherContext required to export the key |
|
* state back from the unprivileged child to the privileged parent |
|
* process. |
|
*/ |
|
|
|
void |
|
packet_get_keyiv(int mode, u_char *iv, u_int len) |
|
{ |
|
CipherContext *cc; |
|
|
|
if (mode == MODE_OUT) |
|
cc = &send_context; |
|
else |
|
cc = &receive_context; |
|
|
|
cipher_get_keyiv(cc, iv, len); |
|
} |
|
|
|
int |
|
packet_get_keycontext(int mode, u_char *dat) |
|
{ |
|
CipherContext *cc; |
|
|
|
if (mode == MODE_OUT) |
|
cc = &send_context; |
|
else |
|
cc = &receive_context; |
|
|
|
return (cipher_get_keycontext(cc, dat)); |
|
} |
|
|
|
void |
|
packet_set_keycontext(int mode, u_char *dat) |
|
{ |
|
CipherContext *cc; |
|
|
|
if (mode == MODE_OUT) |
|
cc = &send_context; |
|
else |
|
cc = &receive_context; |
|
|
|
cipher_set_keycontext(cc, dat); |
|
} |
|
|
|
int |
|
packet_get_keyiv_len(int mode) |
|
{ |
|
CipherContext *cc; |
|
|
|
if (mode == MODE_OUT) |
|
cc = &send_context; |
|
else |
|
cc = &receive_context; |
|
|
|
return (cipher_get_keyiv_len(cc)); |
|
} |
|
void |
|
packet_set_iv(int mode, u_char *dat) |
|
{ |
|
CipherContext *cc; |
|
|
|
if (mode == MODE_OUT) |
|
cc = &send_context; |
|
else |
|
cc = &receive_context; |
|
|
|
cipher_set_keyiv(cc, dat); |
|
} |
|
int |
|
packet_get_ssh1_cipher() |
|
{ |
|
return (cipher_get_number(receive_context.cipher)); |
|
} |
|
|
|
|
|
u_int32_t |
|
packet_get_seqnr(int mode) |
|
{ |
|
return (mode == MODE_IN ? read_seqnr : send_seqnr); |
|
} |
|
|
|
void |
|
packet_set_seqnr(int mode, u_int32_t seqnr) |
|
{ |
|
if (mode == MODE_IN) |
|
read_seqnr = seqnr; |
|
else if (mode == MODE_OUT) |
|
send_seqnr = seqnr; |
|
else |
|
fatal("%s: bad mode %d", __FUNCTION__, mode); |
|
} |
|
|
/* returns 1 if connection is via ipv4 */ |
/* returns 1 if connection is via ipv4 */ |
|
|
int |
int |
|
|
*/ |
*/ |
} |
} |
|
|
static void |
void |
set_newkeys(int mode) |
set_newkeys(int mode) |
{ |
{ |
Enc *enc; |
Enc *enc; |
|
|
DBG(debug("cipher_init_context: %d", mode)); |
DBG(debug("cipher_init_context: %d", mode)); |
cipher_init(cc, enc->cipher, enc->key, enc->key_len, |
cipher_init(cc, enc->cipher, enc->key, enc->key_len, |
enc->iv, enc->block_size, encrypt); |
enc->iv, enc->block_size, encrypt); |
memset(enc->iv, 0, enc->block_size); |
/* Deleting the keys does not gain extra security */ |
memset(enc->key, 0, enc->key_len); |
/* memset(enc->iv, 0, enc->block_size); |
|
memset(enc->key, 0, enc->key_len); */ |
if (comp->type != 0 && comp->enabled == 0) { |
if (comp->type != 0 && comp->enabled == 0) { |
packet_init_compression(); |
packet_init_compression(); |
if (mode == MODE_OUT) |
if (mode == MODE_OUT) |
|
|
static void |
static void |
packet_send2(void) |
packet_send2(void) |
{ |
{ |
static u_int32_t seqnr = 0; |
|
u_char type, *cp, *macbuf = NULL; |
u_char type, *cp, *macbuf = NULL; |
u_char padlen, pad; |
u_char padlen, pad; |
u_int packet_length = 0; |
u_int packet_length = 0; |
|
|
/* will wrap if extra_pad+padlen > 255 */ |
/* will wrap if extra_pad+padlen > 255 */ |
extra_pad = roundup(extra_pad, block_size); |
extra_pad = roundup(extra_pad, block_size); |
pad = extra_pad - ((len + padlen) % extra_pad); |
pad = extra_pad - ((len + padlen) % extra_pad); |
debug("packet_send2: adding %d (len %d padlen %d extra_pad %d)", |
debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)", |
pad, len, padlen, extra_pad); |
pad, len, padlen, extra_pad); |
padlen += pad; |
padlen += pad; |
extra_pad = 0; |
extra_pad = 0; |
|
|
|
|
/* compute MAC over seqnr and packet(length fields, payload, padding) */ |
/* compute MAC over seqnr and packet(length fields, payload, padding) */ |
if (mac && mac->enabled) { |
if (mac && mac->enabled) { |
macbuf = mac_compute(mac, seqnr, |
macbuf = mac_compute(mac, send_seqnr, |
buffer_ptr(&outgoing_packet), |
buffer_ptr(&outgoing_packet), |
buffer_len(&outgoing_packet)); |
buffer_len(&outgoing_packet)); |
DBG(debug("done calc MAC out #%d", seqnr)); |
DBG(debug("done calc MAC out #%d", send_seqnr)); |
} |
} |
/* encrypt packet and append to output buffer. */ |
/* encrypt packet and append to output buffer. */ |
cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); |
cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); |
|
|
buffer_dump(&output); |
buffer_dump(&output); |
#endif |
#endif |
/* increment sequence number for outgoing packets */ |
/* increment sequence number for outgoing packets */ |
if (++seqnr == 0) |
if (++send_seqnr == 0) |
log("outgoing seqnr wraps around"); |
log("outgoing seqnr wraps around"); |
buffer_clear(&outgoing_packet); |
buffer_clear(&outgoing_packet); |
|
|
|
|
static int |
static int |
packet_read_poll2(u_int32_t *seqnr_p) |
packet_read_poll2(u_int32_t *seqnr_p) |
{ |
{ |
static u_int32_t seqnr = 0; |
|
static u_int packet_length = 0; |
static u_int packet_length = 0; |
u_int padlen, need; |
u_int padlen, need; |
u_char *macbuf, *cp, type; |
u_char *macbuf, *cp, type; |
|
|
* increment sequence number for incoming packet |
* increment sequence number for incoming packet |
*/ |
*/ |
if (mac && mac->enabled) { |
if (mac && mac->enabled) { |
macbuf = mac_compute(mac, seqnr, |
macbuf = mac_compute(mac, 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."); |
packet_disconnect("Corrupted MAC on input."); |
DBG(debug("MAC #%d ok", seqnr)); |
DBG(debug("MAC #%d ok", read_seqnr)); |
buffer_consume(&input, mac->mac_len); |
buffer_consume(&input, mac->mac_len); |
} |
} |
if (seqnr_p != NULL) |
if (seqnr_p != NULL) |
*seqnr_p = seqnr; |
*seqnr_p = read_seqnr; |
if (++seqnr == 0) |
if (++read_seqnr == 0) |
log("incoming seqnr wraps around"); |
log("incoming seqnr wraps around"); |
|
|
/* get padlen */ |
/* get padlen */ |