version 1.296, 2020/07/05 23:59:45 |
version 1.297, 2020/10/18 11:32:01 |
|
|
int r; |
int r; |
|
|
if (none == NULL) { |
if (none == NULL) { |
error("%s: cannot load cipher 'none'", __func__); |
error_f("cannot load cipher 'none'"); |
return NULL; |
return NULL; |
} |
} |
if (ssh == NULL) |
if (ssh == NULL) |
ssh = ssh_alloc_session_state(); |
ssh = ssh_alloc_session_state(); |
if (ssh == NULL) { |
if (ssh == NULL) { |
error("%s: could not allocate state", __func__); |
error_f("could not allocate state"); |
return NULL; |
return NULL; |
} |
} |
state = ssh->state; |
state = ssh->state; |
|
|
(const u_char *)"", 0, NULL, 0, CIPHER_ENCRYPT)) != 0 || |
(const u_char *)"", 0, NULL, 0, CIPHER_ENCRYPT)) != 0 || |
(r = cipher_init(&state->receive_context, none, |
(r = cipher_init(&state->receive_context, none, |
(const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0) { |
(const u_char *)"", 0, NULL, 0, CIPHER_DECRYPT)) != 0) { |
error("%s: cipher_init failed: %s", __func__, ssh_err(r)); |
error_fr(r, "cipher_init failed"); |
free(ssh); /* XXX need ssh_free_session_state? */ |
free(ssh); /* XXX need ssh_free_session_state? */ |
return NULL; |
return NULL; |
} |
} |
|
|
max_blocks = &state->max_blocks_in; |
max_blocks = &state->max_blocks_in; |
} |
} |
if (state->newkeys[mode] != NULL) { |
if (state->newkeys[mode] != NULL) { |
debug("%s: rekeying %s, input %llu bytes %llu blocks, " |
debug_f("rekeying %s, input %llu bytes %llu blocks, " |
"output %llu bytes %llu blocks", __func__, dir, |
"output %llu bytes %llu blocks", dir, |
(unsigned long long)state->p_read.bytes, |
(unsigned long long)state->p_read.bytes, |
(unsigned long long)state->p_read.blocks, |
(unsigned long long)state->p_read.blocks, |
(unsigned long long)state->p_send.bytes, |
(unsigned long long)state->p_send.bytes, |
|
|
return r; |
return r; |
} |
} |
mac->enabled = 1; |
mac->enabled = 1; |
DBG(debug("%s: cipher_init_context: %s", __func__, dir)); |
DBG(debug_f("cipher_init_context: %s", dir)); |
cipher_free(*ccp); |
cipher_free(*ccp); |
*ccp = NULL; |
*ccp = NULL; |
if ((r = cipher_init(ccp, enc->cipher, enc->key, enc->key_len, |
if ((r = cipher_init(ccp, enc->cipher, enc->key, enc->key_len, |
|
|
if (tmp > state->extra_pad) |
if (tmp > state->extra_pad) |
return SSH_ERR_INVALID_ARGUMENT; |
return SSH_ERR_INVALID_ARGUMENT; |
pad = state->extra_pad - tmp; |
pad = state->extra_pad - tmp; |
DBG(debug3("%s: adding %d (len %d padlen %d extra_pad %d)", |
DBG(debug3_f("adding %d (len %d padlen %d extra_pad %d)", |
__func__, pad, len, padlen, state->extra_pad)); |
pad, len, padlen, state->extra_pad)); |
tmp = padlen; |
tmp = padlen; |
padlen += pad; |
padlen += pad; |
/* Check whether padlen calculation overflowed */ |
/* Check whether padlen calculation overflowed */ |
|
|
*/ |
*/ |
if ((need_rekey || state->rekeying) && !ssh_packet_type_is_kex(type)) { |
if ((need_rekey || state->rekeying) && !ssh_packet_type_is_kex(type)) { |
if (need_rekey) |
if (need_rekey) |
debug3("%s: rekex triggered", __func__); |
debug3_f("rekex triggered"); |
debug("enqueue packet: %u", type); |
debug("enqueue packet: %u", type); |
p = calloc(1, sizeof(*p)); |
p = calloc(1, sizeof(*p)); |
if (p == NULL) |
if (p == NULL) |
|
|
*/ |
*/ |
if (ssh_packet_need_rekeying(ssh, |
if (ssh_packet_need_rekeying(ssh, |
sshbuf_len(p->payload))) { |
sshbuf_len(p->payload))) { |
debug3("%s: queued packet triggered rekex", |
debug3_f("queued packet triggered rekex"); |
__func__); |
|
return kex_start_rekex(ssh); |
return kex_start_rekex(ssh); |
} |
} |
debug("dequeue packet: %u", type); |
debug("dequeue packet: %u", type); |
|
|
int r; |
int r; |
|
|
if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) |
if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0) |
fatal("%s: %s", __func__, ssh_err(r)); |
fatal_fr(r, "read"); |
return type; |
return type; |
} |
} |
|
|
|
|
(r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) |
(r = sshbuf_get_u8(state->incoming_packet, typep)) != 0) |
return r; |
return r; |
if (ssh_packet_log_type(*typep)) |
if (ssh_packet_log_type(*typep)) |
debug3("%s: type %u", __func__, *typep); |
debug3_f("type %u", *typep); |
/* sshbuf_dump(state->incoming_packet, stderr); */ |
/* sshbuf_dump(state->incoming_packet, stderr); */ |
/* reset for next packet */ |
/* reset for next packet */ |
state->packlen = 0; |
state->packlen = 0; |
|
|
|
|
/* do we need to rekey? */ |
/* do we need to rekey? */ |
if (ssh_packet_need_rekeying(ssh, 0)) { |
if (ssh_packet_need_rekeying(ssh, 0)) { |
debug3("%s: rekex triggered", __func__); |
debug3_f("rekex triggered"); |
if ((r = kex_start_rekex(ssh)) != 0) |
if ((r = kex_start_rekex(ssh)) != 0) |
return r; |
return r; |
} |
} |
|
|
(r = sshpkt_put_cstring(ssh, "")) != 0 || |
(r = sshpkt_put_cstring(ssh, "")) != 0 || |
(r = sshpkt_send(ssh)) != 0 || |
(r = sshpkt_send(ssh)) != 0 || |
(r = ssh_packet_write_wait(ssh)) != 0) |
(r = ssh_packet_write_wait(ssh)) != 0) |
fatal("%s: %s", __func__, ssh_err(r)); |
fatal_fr(r, "send DEBUG"); |
} |
} |
|
|
void |
void |
|
|
default: |
default: |
if (vasprintf(&tag, fmt, ap) == -1) { |
if (vasprintf(&tag, fmt, ap) == -1) { |
ssh_packet_clear_keys(ssh); |
ssh_packet_clear_keys(ssh); |
logdie("%s: could not allocate failure message", |
logdie_f("could not allocate failure message"); |
__func__); |
|
} |
} |
ssh_packet_clear_keys(ssh); |
ssh_packet_clear_keys(ssh); |
errno = oerrno; |
errno = oerrno; |
logdie("%s%sConnection %s %s: %s", |
logdie_r(r, "%s%sConnection %s %s", |
tag != NULL ? tag : "", tag != NULL ? ": " : "", |
tag != NULL ? tag : "", tag != NULL ? ": " : "", |
ssh->state->server_side ? "from" : "to", |
ssh->state->server_side ? "from" : "to", remote_id); |
remote_id, ssh_err(r)); |
|
} |
} |
} |
} |
|
|
|
|
sshpkt_vfatal(ssh, r, fmt, ap); |
sshpkt_vfatal(ssh, r, fmt, ap); |
/* NOTREACHED */ |
/* NOTREACHED */ |
va_end(ap); |
va_end(ap); |
logdie("%s: should have exited", __func__); |
logdie_f("should have exited"); |
} |
} |
|
|
/* |
/* |
|
|
return; |
return; |
switch (ssh_packet_connection_af(ssh)) { |
switch (ssh_packet_connection_af(ssh)) { |
case AF_INET: |
case AF_INET: |
debug3("%s: set IP_TOS 0x%02x", __func__, tos); |
debug3_f("set IP_TOS 0x%02x", tos); |
if (setsockopt(ssh->state->connection_in, |
if (setsockopt(ssh->state->connection_in, |
IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) == -1) |
IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) == -1) |
error("setsockopt IP_TOS %d: %.100s:", |
error("setsockopt IP_TOS %d: %.100s:", |
tos, strerror(errno)); |
tos, strerror(errno)); |
break; |
break; |
case AF_INET6: |
case AF_INET6: |
debug3("%s: set IPV6_TCLASS 0x%02x", __func__, tos); |
debug3_f("set IPV6_TCLASS 0x%02x", tos); |
if (setsockopt(ssh->state->connection_in, |
if (setsockopt(ssh->state->connection_in, |
IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) == -1) |
IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) == -1) |
error("setsockopt IPV6_TCLASS %d: %.100s:", |
error("setsockopt IPV6_TCLASS %d: %.100s:", |
|
|
{ |
{ |
int r; |
int r; |
|
|
debug("%s: called", __func__); |
debug_f("called"); |
/* This was set in net child, but is not visible in user child */ |
/* This was set in net child, but is not visible in user child */ |
ssh->state->after_authentication = 1; |
ssh->state->after_authentication = 1; |
ssh->state->rekeying = 0; |
ssh->state->rekeying = 0; |
|
|
|
|
if (sshbuf_len(m)) |
if (sshbuf_len(m)) |
return SSH_ERR_INVALID_FORMAT; |
return SSH_ERR_INVALID_FORMAT; |
debug3("%s: done", __func__); |
debug3_f("done"); |
return 0; |
return 0; |
} |
} |
|
|
|
|
cp = sshbuf_mutable_ptr(state->outgoing_packet); |
cp = sshbuf_mutable_ptr(state->outgoing_packet); |
type = cp[5]; |
type = cp[5]; |
if (ssh_packet_log_type(type)) |
if (ssh_packet_log_type(type)) |
debug3("%s: type %u", __func__, type); |
debug3_f("type %u", type); |
/* drop everything, but the connection protocol */ |
/* drop everything, but the connection protocol */ |
if (type >= SSH2_MSG_CONNECTION_MIN && |
if (type >= SSH2_MSG_CONNECTION_MIN && |
type <= SSH2_MSG_CONNECTION_MAX) { |
type <= SSH2_MSG_CONNECTION_MAX) { |