aboutsummaryrefslogtreecommitdiff
path: root/kex.c
diff options
context:
space:
mode:
Diffstat (limited to 'kex.c')
-rw-r--r--kex.c57
1 files changed, 39 insertions, 18 deletions
diff --git a/kex.c b/kex.c
index b4e2ab75f541..8ff92f2a2d5e 100644
--- a/kex.c
+++ b/kex.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kex.c,v 1.178 2023/03/12 10:40:39 dtucker Exp $ */
+/* $OpenBSD: kex.c,v 1.181 2023/08/28 03:28:43 djm Exp $ */
/*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
*
@@ -492,12 +492,14 @@ kex_send_ext_info(struct ssh *ssh)
return SSH_ERR_ALLOC_FAIL;
/* XXX filter algs list by allowed pubkey/hostbased types */
if ((r = sshpkt_start(ssh, SSH2_MSG_EXT_INFO)) != 0 ||
- (r = sshpkt_put_u32(ssh, 2)) != 0 ||
+ (r = sshpkt_put_u32(ssh, 3)) != 0 ||
(r = sshpkt_put_cstring(ssh, "server-sig-algs")) != 0 ||
(r = sshpkt_put_cstring(ssh, algs)) != 0 ||
(r = sshpkt_put_cstring(ssh,
"publickey-hostbound@openssh.com")) != 0 ||
(r = sshpkt_put_cstring(ssh, "0")) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "ping@openssh.com")) != 0 ||
+ (r = sshpkt_put_cstring(ssh, "0")) != 0 ||
(r = sshpkt_send(ssh)) != 0) {
error_fr(r, "compose");
goto out;
@@ -527,6 +529,23 @@ kex_send_newkeys(struct ssh *ssh)
return 0;
}
+/* Check whether an ext_info value contains the expected version string */
+static int
+kex_ext_info_check_ver(struct kex *kex, const char *name,
+ const u_char *val, size_t len, const char *want_ver, u_int flag)
+{
+ if (memchr(val, '\0', len) != NULL) {
+ error("SSH2_MSG_EXT_INFO: %s value contains nul byte", name);
+ return SSH_ERR_INVALID_FORMAT;
+ }
+ debug_f("%s=<%s>", name, val);
+ if (strcmp(val, want_ver) == 0)
+ kex->flags |= flag;
+ else
+ debug_f("unsupported version of %s extension", name);
+ return 0;
+}
+
int
kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
{
@@ -557,6 +576,8 @@ kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
/* Ensure no \0 lurking in value */
if (memchr(val, '\0', vlen) != NULL) {
error_f("nul byte in %s", name);
+ free(name);
+ free(val);
return SSH_ERR_INVALID_FORMAT;
}
debug_f("%s=<%s>", name, val);
@@ -564,18 +585,18 @@ kex_input_ext_info(int type, u_int32_t seq, struct ssh *ssh)
val = NULL;
} else if (strcmp(name,
"publickey-hostbound@openssh.com") == 0) {
- /* XXX refactor */
- /* Ensure no \0 lurking in value */
- if (memchr(val, '\0', vlen) != NULL) {
- error_f("nul byte in %s", name);
- return SSH_ERR_INVALID_FORMAT;
+ if ((r = kex_ext_info_check_ver(kex, name, val, vlen,
+ "0", KEX_HAS_PUBKEY_HOSTBOUND)) != 0) {
+ free(name);
+ free(val);
+ return r;
}
- debug_f("%s=<%s>", name, val);
- if (strcmp(val, "0") == 0)
- kex->flags |= KEX_HAS_PUBKEY_HOSTBOUND;
- else {
- debug_f("unsupported version of %s extension",
- name);
+ } else if (strcmp(name, "ping@openssh.com") == 0) {
+ if ((r = kex_ext_info_check_ver(kex, name, val, vlen,
+ "0", KEX_HAS_PING)) != 0) {
+ free(name);
+ free(val);
+ return r;
}
} else
debug_f("%s (unrecognised)", name);
@@ -1334,7 +1355,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
for (;;) {
if (timeout_ms > 0) {
r = waitrfd(ssh_packet_get_connection_in(ssh),
- &timeout_ms);
+ &timeout_ms, NULL);
if (r == -1 && errno == ETIMEDOUT) {
send_error(ssh, "Timed out waiting "
"for SSH identification string.");
@@ -1353,7 +1374,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
len = atomicio(read, ssh_packet_get_connection_in(ssh),
&c, 1);
if (len != 1 && errno == EPIPE) {
- error_f("Connection closed by remote host");
+ verbose_f("Connection closed by remote host");
r = SSH_ERR_CONN_CLOSED;
goto out;
} else if (len != 1) {
@@ -1369,7 +1390,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
if (c == '\n')
break;
if (c == '\0' || expect_nl) {
- error_f("banner line contains invalid "
+ verbose_f("banner line contains invalid "
"characters");
goto invalid;
}
@@ -1379,7 +1400,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
goto out;
}
if (sshbuf_len(peer_version) > SSH_MAX_BANNER_LEN) {
- error_f("banner line too long");
+ verbose_f("banner line too long");
goto invalid;
}
}
@@ -1395,7 +1416,7 @@ kex_exchange_identification(struct ssh *ssh, int timeout_ms,
}
/* Do not accept lines before the SSH ident from a client */
if (ssh->kex->server) {
- error_f("client sent invalid protocol identifier "
+ verbose_f("client sent invalid protocol identifier "
"\"%.256s\"", cp);
free(cp);
goto invalid;