sync with OpenBSD -current
This commit is contained in:
parent
da785accdf
commit
659ea2942e
39 changed files with 1318 additions and 384 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $OpenBSD: packet.c,v 1.312 2023/08/28 03:31:16 djm Exp $ */
|
||||
/* $OpenBSD: packet.c,v 1.313 2023/12/18 14:45:17 djm Exp $ */
|
||||
/*
|
||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||
|
@ -1187,8 +1187,13 @@ ssh_packet_send2_wrapped(struct ssh *ssh)
|
|||
sshbuf_dump(state->output, stderr);
|
||||
#endif
|
||||
/* increment sequence number for outgoing packets */
|
||||
if (++state->p_send.seqnr == 0)
|
||||
if (++state->p_send.seqnr == 0) {
|
||||
if ((ssh->kex->flags & KEX_INITIAL) != 0) {
|
||||
ssh_packet_disconnect(ssh, "outgoing sequence number "
|
||||
"wrapped during initial key exchange");
|
||||
}
|
||||
logit("outgoing seqnr wraps around");
|
||||
}
|
||||
if (++state->p_send.packets == 0)
|
||||
if (!(ssh->compat & SSH_BUG_NOREKEY))
|
||||
return SSH_ERR_NEED_REKEY;
|
||||
|
@ -1196,6 +1201,11 @@ ssh_packet_send2_wrapped(struct ssh *ssh)
|
|||
state->p_send.bytes += len;
|
||||
sshbuf_reset(state->outgoing_packet);
|
||||
|
||||
if (type == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) {
|
||||
debug_f("resetting send seqnr %u", state->p_send.seqnr);
|
||||
state->p_send.seqnr = 0;
|
||||
}
|
||||
|
||||
if (type == SSH2_MSG_NEWKEYS)
|
||||
r = ssh_set_newkeys(ssh, MODE_OUT);
|
||||
else if (type == SSH2_MSG_USERAUTH_SUCCESS && state->server_side)
|
||||
|
@ -1324,8 +1334,7 @@ ssh_packet_read_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
|||
/* Stay in the loop until we have received a complete packet. */
|
||||
for (;;) {
|
||||
/* Try to read a packet from the buffer. */
|
||||
r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p);
|
||||
if (r != 0)
|
||||
if ((r = ssh_packet_read_poll_seqnr(ssh, typep, seqnr_p)) != 0)
|
||||
break;
|
||||
/* If we got a packet, return it. */
|
||||
if (*typep != SSH_MSG_NONE)
|
||||
|
@ -1395,29 +1404,6 @@ ssh_packet_read(struct ssh *ssh)
|
|||
return type;
|
||||
}
|
||||
|
||||
/*
|
||||
* Waits until a packet has been received, verifies that its type matches
|
||||
* that given, and gives a fatal error and exits if there is a mismatch.
|
||||
*/
|
||||
|
||||
int
|
||||
ssh_packet_read_expect(struct ssh *ssh, u_int expected_type)
|
||||
{
|
||||
int r;
|
||||
u_char type;
|
||||
|
||||
if ((r = ssh_packet_read_seqnr(ssh, &type, NULL)) != 0)
|
||||
return r;
|
||||
if (type != expected_type) {
|
||||
if ((r = sshpkt_disconnect(ssh,
|
||||
"Protocol error: expected packet type %d, got %d",
|
||||
expected_type, type)) != 0)
|
||||
return r;
|
||||
return SSH_ERR_PROTOCOL_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ssh_packet_read_poll2_mux(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
||||
{
|
||||
|
@ -1608,10 +1594,16 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
|||
if ((r = sshbuf_consume(state->input, mac->mac_len)) != 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (seqnr_p != NULL)
|
||||
*seqnr_p = state->p_read.seqnr;
|
||||
if (++state->p_read.seqnr == 0)
|
||||
if (++state->p_read.seqnr == 0) {
|
||||
if ((ssh->kex->flags & KEX_INITIAL) != 0) {
|
||||
ssh_packet_disconnect(ssh, "incoming sequence number "
|
||||
"wrapped during initial key exchange");
|
||||
}
|
||||
logit("incoming seqnr wraps around");
|
||||
}
|
||||
if (++state->p_read.packets == 0)
|
||||
if (!(ssh->compat & SSH_BUG_NOREKEY))
|
||||
return SSH_ERR_NEED_REKEY;
|
||||
|
@ -1677,6 +1669,10 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
|||
#endif
|
||||
/* reset for next packet */
|
||||
state->packlen = 0;
|
||||
if (*typep == SSH2_MSG_NEWKEYS && ssh->kex->kex_strict) {
|
||||
debug_f("resetting read seqnr %u", state->p_read.seqnr);
|
||||
state->p_read.seqnr = 0;
|
||||
}
|
||||
|
||||
if ((r = ssh_packet_check_rekey(ssh)) != 0)
|
||||
return r;
|
||||
|
@ -1699,10 +1695,39 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
|||
r = ssh_packet_read_poll2(ssh, typep, seqnr_p);
|
||||
if (r != 0)
|
||||
return r;
|
||||
if (*typep) {
|
||||
state->keep_alive_timeouts = 0;
|
||||
DBG(debug("received packet type %d", *typep));
|
||||
if (*typep == 0) {
|
||||
/* no message ready */
|
||||
return 0;
|
||||
}
|
||||
state->keep_alive_timeouts = 0;
|
||||
DBG(debug("received packet type %d", *typep));
|
||||
|
||||
/* Always process disconnect messages */
|
||||
if (*typep == SSH2_MSG_DISCONNECT) {
|
||||
if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
|
||||
(r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
|
||||
return r;
|
||||
/* Ignore normal client exit notifications */
|
||||
do_log2(ssh->state->server_side &&
|
||||
reason == SSH2_DISCONNECT_BY_APPLICATION ?
|
||||
SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
|
||||
"Received disconnect from %s port %d:"
|
||||
"%u: %.400s", ssh_remote_ipaddr(ssh),
|
||||
ssh_remote_port(ssh), reason, msg);
|
||||
free(msg);
|
||||
return SSH_ERR_DISCONNECTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Do not implicitly handle any messages here during initial
|
||||
* KEX when in strict mode. They will be need to be allowed
|
||||
* explicitly by the KEX dispatch table or they will generate
|
||||
* protocol errors.
|
||||
*/
|
||||
if (ssh->kex != NULL &&
|
||||
(ssh->kex->flags & KEX_INITIAL) && ssh->kex->kex_strict)
|
||||
return 0;
|
||||
/* Implicitly handle transport-level messages */
|
||||
switch (*typep) {
|
||||
case SSH2_MSG_IGNORE:
|
||||
debug3("Received SSH2_MSG_IGNORE");
|
||||
|
@ -1717,19 +1742,6 @@ ssh_packet_read_poll_seqnr(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p)
|
|||
debug("Remote: %.900s", msg);
|
||||
free(msg);
|
||||
break;
|
||||
case SSH2_MSG_DISCONNECT:
|
||||
if ((r = sshpkt_get_u32(ssh, &reason)) != 0 ||
|
||||
(r = sshpkt_get_string(ssh, &msg, NULL)) != 0)
|
||||
return r;
|
||||
/* Ignore normal client exit notifications */
|
||||
do_log2(ssh->state->server_side &&
|
||||
reason == SSH2_DISCONNECT_BY_APPLICATION ?
|
||||
SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
|
||||
"Received disconnect from %s port %d:"
|
||||
"%u: %.400s", ssh_remote_ipaddr(ssh),
|
||||
ssh_remote_port(ssh), reason, msg);
|
||||
free(msg);
|
||||
return SSH_ERR_DISCONNECTED;
|
||||
case SSH2_MSG_UNIMPLEMENTED:
|
||||
if ((r = sshpkt_get_u32(ssh, &seqnr)) != 0)
|
||||
return r;
|
||||
|
@ -2219,6 +2231,7 @@ kex_to_blob(struct sshbuf *m, struct kex *kex)
|
|||
(r = sshbuf_put_u32(m, kex->hostkey_type)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, kex->hostkey_nid)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, kex->kex_type)) != 0 ||
|
||||
(r = sshbuf_put_u32(m, kex->kex_strict)) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, kex->my)) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, kex->peer)) != 0 ||
|
||||
(r = sshbuf_put_stringb(m, kex->client_version)) != 0 ||
|
||||
|
@ -2381,6 +2394,7 @@ kex_from_blob(struct sshbuf *m, struct kex **kexp)
|
|||
(r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_type)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, (u_int *)&kex->hostkey_nid)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, &kex->kex_type)) != 0 ||
|
||||
(r = sshbuf_get_u32(m, &kex->kex_strict)) != 0 ||
|
||||
(r = sshbuf_get_stringb(m, kex->my)) != 0 ||
|
||||
(r = sshbuf_get_stringb(m, kex->peer)) != 0 ||
|
||||
(r = sshbuf_get_stringb(m, kex->client_version)) != 0 ||
|
||||
|
@ -2705,6 +2719,7 @@ sshpkt_disconnect(struct ssh *ssh, const char *fmt,...)
|
|||
vsnprintf(buf, sizeof(buf), fmt, args);
|
||||
va_end(args);
|
||||
|
||||
debug2_f("sending SSH2_MSG_DISCONNECT: %s", buf);
|
||||
if ((r = sshpkt_start(ssh, SSH2_MSG_DISCONNECT)) != 0 ||
|
||||
(r = sshpkt_put_u32(ssh, SSH2_DISCONNECT_PROTOCOL_ERROR)) != 0 ||
|
||||
(r = sshpkt_put_cstring(ssh, buf)) != 0 ||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue