Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fscheiner/ec430514b28e4dad24516c66939a8945 to your computer and use it in GitHub Desktop.
Save fscheiner/ec430514b28e4dad24516c66939a8945 to your computer and use it in GitHub Desktop.
This fix unbreaks GSS KEX for GSI-OpenSSH 8.0p1-6.el8
diff -Nur openssh-8.0p1.orig/kexgssc.c openssh-8.0p1/kexgssc.c
--- openssh-8.0p1.orig/kexgssc.c 2021-03-03 12:35:48.356269671 +0100
+++ openssh-8.0p1/kexgssc.c 2021-03-03 13:39:31.000000000 +0100
@@ -162,11 +162,16 @@
do {
type = ssh_packet_read(ssh);
if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
+ char *tmp = NULL;
+ size_t tmp_len = 0;
+
debug("Received KEXGSS_HOSTKEY");
if (server_host_key_blob)
fatal("Server host key received more than once");
- if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0)
+ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0)
fatal("Failed to read server host key: %s", ssh_err(r));
+ if ((server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL)
+ fatal("sshbuf_from failed");
}
} while (type == SSH2_MSG_KEXGSS_HOSTKEY);
@@ -448,11 +453,16 @@
do {
type = ssh_packet_read(ssh);
if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
+ char *tmp = NULL;
+ size_t tmp_len = 0;
+
debug("Received KEXGSS_HOSTKEY");
if (server_host_key_blob)
fatal("Server host key received more than once");
- if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0)
+ if ((r = sshpkt_get_string(ssh, &tmp, &tmp_len)) != 0)
fatal("sshpkt failed: %s", ssh_err(r));
+ if ((server_host_key_blob = sshbuf_from(tmp, tmp_len)) == NULL)
+ fatal("sshbuf_from failed");
}
} while (type == SSH2_MSG_KEXGSS_HOSTKEY);
diff -Nur openssh-8.0p1.orig/kexgsss.c openssh-8.0p1/kexgsss.c
--- openssh-8.0p1.orig/kexgsss.c 2021-03-03 12:35:48.517268025 +0100
+++ openssh-8.0p1/kexgsss.c 2021-03-03 13:35:53.545558691 +0100
@@ -65,7 +65,7 @@
*/
OM_uint32 ret_flags = 0;
- gss_buffer_desc gssbuf, recv_tok, msg_tok;
+ gss_buffer_desc gssbuf = {0, NULL}, recv_tok, msg_tok;
gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
Gssctxt *ctxt = NULL;
struct sshbuf *shared_secret = NULL;
@@ -107,7 +107,7 @@
type = ssh_packet_read(ssh);
switch(type) {
case SSH2_MSG_KEXGSS_INIT:
- if (client_pubkey != NULL)
+ if (gssbuf.value != NULL)
fatal("Received KEXGSS_INIT after initialising");
if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
&recv_tok)) != 0 ||
@@ -138,6 +138,31 @@
goto out;
/* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
+
+ /* Calculate the hash early so we can free the
+ * client_pubkey, which has reference to the parent
+ * buffer state->incoming_packet
+ */
+ hashlen = sizeof(hash);
+ if ((r = kex_gen_hash(
+ kex->hash_alg,
+ kex->client_version,
+ kex->server_version,
+ kex->peer,
+ kex->my,
+ empty,
+ client_pubkey,
+ server_pubkey,
+ shared_secret,
+ hash, &hashlen)) != 0)
+ goto out;
+
+ gssbuf.value = hash;
+ gssbuf.length = hashlen;
+
+ sshbuf_free(client_pubkey);
+ client_pubkey = NULL;
+
break;
case SSH2_MSG_KEXGSS_CONTINUE:
if ((r = ssh_gssapi_sshpkt_get_buffer_desc(ssh,
@@ -159,7 +184,7 @@
if (maj_status != GSS_S_COMPLETE && send_tok.length == 0)
fatal("Zero length token output when incomplete");
- if (client_pubkey == NULL)
+ if (gssbuf.value == NULL)
fatal("No client public key");
if (maj_status & GSS_S_CONTINUE_NEEDED) {
@@ -189,23 +214,6 @@
if (!(ret_flags & GSS_C_INTEG_FLAG))
fatal("Integrity flag wasn't set");
- hashlen = sizeof(hash);
- if ((r = kex_gen_hash(
- kex->hash_alg,
- kex->client_version,
- kex->server_version,
- kex->peer,
- kex->my,
- empty,
- client_pubkey,
- server_pubkey,
- shared_secret,
- hash, &hashlen)) != 0)
- goto out;
-
- gssbuf.value = hash;
- gssbuf.length = hashlen;
-
if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))))
fatal("Couldn't get MIC");
@fscheiner
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment