diff options
Diffstat (limited to '')
-rw-r--r-- | debian/patches/gssapi.patch | 604 |
1 files changed, 206 insertions, 398 deletions
diff --git a/debian/patches/gssapi.patch b/debian/patches/gssapi.patch index 7c3ba4a..5f5f9ce 100644 --- a/debian/patches/gssapi.patch +++ b/debian/patches/gssapi.patch @@ -1,4 +1,4 @@ -From 4431708c5c325cdbcf802e5d86ea1f4da78c1b50 Mon Sep 17 00:00:00 2001 +From 19f6afb4e07135a843c2f5caaa663a1d3f3db6f1 Mon Sep 17 00:00:00 2001 From: Simon Wilkinson <simon@sxw.org.uk> Date: Sun, 9 Feb 2014 16:09:48 +0000 Subject: GSSAPI key exchange support @@ -21,23 +21,23 @@ Author: Colin Watson <cjwatson@debian.org> Author: Jakub Jelen <jjelen@redhat.com> Origin: other, https://github.com/openssh-gsskex/openssh-gsskex/pull/23 Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1242 -Last-Updated: 2024-03-14 +Last-Updated: 2024-07-31 Patch-Name: gssapi.patch --- Makefile.in | 5 +- README.md | 36 +++ - auth.c | 94 +------- - auth2-gss.c | 57 ++++- + auth.c | 3 +- + auth2-gss.c | 54 ++++- + auth2-methods.c | 6 + auth2.c | 2 + - canohost.c | 91 ++++++++ - canohost.h | 3 + clientloop.c | 13 ++ configure.ac | 24 ++ gss-genr.c | 297 +++++++++++++++++++++++- gss-serv-krb5.c | 87 ++++++- - gss-serv.c | 205 +++++++++++++++-- - kex.c | 66 +++++- + gss-serv.c | 200 ++++++++++++++-- + kex-names.c | 62 ++++- + kex.c | 4 + kex.h | 29 +++ kexdh.c | 10 + kexgen.c | 2 +- @@ -58,22 +58,23 @@ Patch-Name: gssapi.patch ssh.c | 6 +- ssh_config | 2 + ssh_config.5 | 57 +++++ - sshconnect2.c | 146 +++++++++++- - sshd.c | 62 ++++- + sshconnect2.c | 144 +++++++++++- + sshd-session.c | 59 ++++- + sshd.c | 3 +- sshd_config | 2 + sshd_config.5 | 30 +++ sshkey.c | 8 +- sshkey.h | 1 + - 39 files changed, 2763 insertions(+), 164 deletions(-) + 40 files changed, 2667 insertions(+), 71 deletions(-) create mode 100644 kexgssc.c create mode 100644 kexgsss.c create mode 100644 ssh-null.c diff --git a/Makefile.in b/Makefile.in -index 1efe11f6f..f9488099a 100644 +index e1b77ebc6..6635b5518 100644 --- a/Makefile.in +++ b/Makefile.in -@@ -101,7 +101,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ +@@ -103,7 +103,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \ atomicio.o dispatch.o mac.o misc.o utf8.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \ @@ -82,22 +83,22 @@ index 1efe11f6f..f9488099a 100644 msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \ ssh-pkcs11.o smult_curve25519_ref.o \ poly1305.o chacha.o cipher-chachapoly.o cipher-chachapoly-libcrypto.o \ -@@ -110,6 +110,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ - kex.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ +@@ -112,6 +112,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \ + kex.o kex-names.o kexdh.o kexgex.o kexecdh.o kexc25519.o \ kexgexc.o kexgexs.o \ kexsntrup761x25519.o sntrup761.o kexgen.o \ + kexgssc.o \ sftp-realpath.o platform-pledge.o platform-tracing.o platform-misc.o \ sshbuf-io.o -@@ -126,7 +127,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o \ +@@ -134,7 +135,7 @@ SSHD_SESSION_OBJS=sshd-session.o auth-rhosts.o auth-passwd.o \ auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-pubkeyfile.o \ monitor.o monitor_wrap.o auth-krb5.o \ - auth2-gss.o gss-serv.o gss-serv-krb5.o \ + auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o \ loginrec.o auth-pam.o auth-shadow.o auth-sia.o \ - srclimit.o sftp-server.o sftp-common.o \ + sftp-server.o sftp-common.o \ sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \ diff --git a/README.md b/README.md index 9431b0ffd..e5051828c 100644 @@ -144,10 +145,10 @@ index 9431b0ffd..e5051828c 100644 [![C/C++ CI](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml/badge.svg)](https://github.com/openssh/openssh-portable/actions/workflows/c-cpp.yml) diff --git a/auth.c b/auth.c -index 3b380d9bb..8ccf06370 100644 +index 2e4cbef07..407b32e78 100644 --- a/auth.c +++ b/auth.c -@@ -357,7 +357,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) +@@ -356,7 +356,8 @@ auth_root_allowed(struct ssh *ssh, const char *method) case PERMIT_NO_PASSWD: if (strcmp(method, "publickey") == 0 || strcmp(method, "hostbased") == 0 || @@ -157,110 +158,12 @@ index 3b380d9bb..8ccf06370 100644 return 1; break; case PERMIT_FORCED_ONLY: -@@ -637,97 +638,6 @@ fakepw(void) - return (&fake); - } - --/* -- * Returns the remote DNS hostname as a string. The returned string must not -- * be freed. NB. this will usually trigger a DNS query the first time it is -- * called. -- * This function does additional checks on the hostname to mitigate some -- * attacks on based on conflation of hostnames and IP addresses. -- */ -- --static char * --remote_hostname(struct ssh *ssh) --{ -- struct sockaddr_storage from; -- socklen_t fromlen; -- struct addrinfo hints, *ai, *aitop; -- char name[NI_MAXHOST], ntop2[NI_MAXHOST]; -- const char *ntop = ssh_remote_ipaddr(ssh); -- -- /* Get IP address of client. */ -- fromlen = sizeof(from); -- memset(&from, 0, sizeof(from)); -- if (getpeername(ssh_packet_get_connection_in(ssh), -- (struct sockaddr *)&from, &fromlen) == -1) { -- debug("getpeername failed: %.100s", strerror(errno)); -- return xstrdup(ntop); -- } -- -- ipv64_normalise_mapped(&from, &fromlen); -- if (from.ss_family == AF_INET6) -- fromlen = sizeof(struct sockaddr_in6); -- -- debug3("Trying to reverse map address %.100s.", ntop); -- /* Map the IP address to a host name. */ -- if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), -- NULL, 0, NI_NAMEREQD) != 0) { -- /* Host name not found. Use ip address. */ -- return xstrdup(ntop); -- } -- -- /* -- * if reverse lookup result looks like a numeric hostname, -- * someone is trying to trick us by PTR record like following: -- * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 -- */ -- memset(&hints, 0, sizeof(hints)); -- hints.ai_socktype = SOCK_DGRAM; /*dummy*/ -- hints.ai_flags = AI_NUMERICHOST; -- if (getaddrinfo(name, NULL, &hints, &ai) == 0) { -- logit("Nasty PTR record \"%s\" is set up for %s, ignoring", -- name, ntop); -- freeaddrinfo(ai); -- return xstrdup(ntop); -- } -- -- /* Names are stored in lowercase. */ -- lowercase(name); -- -- /* -- * Map it back to an IP address and check that the given -- * address actually is an address of this host. This is -- * necessary because anyone with access to a name server can -- * define arbitrary names for an IP address. Mapping from -- * name to IP address can be trusted better (but can still be -- * fooled if the intruder has access to the name server of -- * the domain). -- */ -- memset(&hints, 0, sizeof(hints)); -- hints.ai_family = from.ss_family; -- hints.ai_socktype = SOCK_STREAM; -- if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { -- logit("reverse mapping checking getaddrinfo for %.700s " -- "[%s] failed.", name, ntop); -- return xstrdup(ntop); -- } -- /* Look for the address from the list of addresses. */ -- for (ai = aitop; ai; ai = ai->ai_next) { -- if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, -- sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && -- (strcmp(ntop, ntop2) == 0)) -- break; -- } -- freeaddrinfo(aitop); -- /* If we reached the end of the list, the address was not there. */ -- if (ai == NULL) { -- /* Address not found for the host name. */ -- logit("Address %.100s maps to %.600s, but this does not " -- "map back to the address.", ntop, name); -- return xstrdup(ntop); -- } -- return xstrdup(name); --} -- - /* - * Return the canonical name of the host in the other side of the current - * connection. The host name is cached, so it is efficient to call this diff --git a/auth2-gss.c b/auth2-gss.c -index f72a38998..052c7b80f 100644 +index 75eb4e3a3..3e7d18fd2 100644 --- a/auth2-gss.c +++ b/auth2-gss.c @@ -1,7 +1,7 @@ - /* $OpenBSD: auth2-gss.c,v 1.34 2023/03/31 04:22:27 djm Exp $ */ + /* $OpenBSD: auth2-gss.c,v 1.36 2024/05/17 04:42:13 djm Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. @@ -268,7 +171,15 @@ index f72a38998..052c7b80f 100644 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions -@@ -57,6 +57,48 @@ static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh); +@@ -51,6 +51,7 @@ + #define SSH_GSSAPI_MAX_MECHS 2048 + + extern ServerOptions options; ++extern struct authmethod_cfg methodcfg_gsskeyex; + extern struct authmethod_cfg methodcfg_gssapi; + + static int input_gssapi_token(int type, u_int32_t plen, struct ssh *ssh); +@@ -58,6 +59,47 @@ static int input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh); static int input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh); static int input_gssapi_errtok(int, u_int32_t, struct ssh *); @@ -303,10 +214,9 @@ index f72a38998..052c7b80f 100644 + gssbuf.length = sshbuf_len(b); + + /* gss_kex_context is NULL with privsep, so we can't check it here */ -+ if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, -+ &gssbuf, &mic)))) -+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 1)); ++ if (!GSS_ERROR(mm_ssh_gssapi_checkmic(gss_kex_context, &gssbuf, &mic))) ++ authenticated = mm_ssh_gssapi_userok(authctxt->user, ++ authctxt->pw, 1); + + sshbuf_free(b); + free(mic.value); @@ -317,42 +227,63 @@ index f72a38998..052c7b80f 100644 /* * We only support those mechanisms that we know about (ie ones that we know * how to check local user kuserok and the like) -@@ -267,7 +309,8 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) +@@ -267,7 +309,7 @@ input_gssapi_exchange_complete(int type, u_int32_t plen, struct ssh *ssh) if ((r = sshpkt_get_end(ssh)) != 0) fatal_fr(r, "parse packet"); -- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); -+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 1)); +- authenticated = mm_ssh_gssapi_userok(authctxt->user); ++ authenticated = mm_ssh_gssapi_userok(authctxt->user, authctxt->pw, 1); - if ((!use_privsep || mm_is_monitor()) && - (displayname = ssh_gssapi_displayname()) != NULL) -@@ -313,7 +356,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) + authctxt->postponed = 0; + ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); +@@ -308,7 +350,8 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) gssbuf.length = sshbuf_len(b); - if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic)))) -- authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user)); -+ authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user, -+ authctxt->pw, 0)); + if (!GSS_ERROR(mm_ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))) +- authenticated = mm_ssh_gssapi_userok(authctxt->user); ++ authenticated = mm_ssh_gssapi_userok(authctxt->user, ++ authctxt->pw, 0); else logit("GSSAPI MIC check failed"); -@@ -333,6 +377,13 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) +@@ -324,6 +367,11 @@ input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh) return 0; } +Authmethod method_gsskeyex = { -+ "gssapi-keyex", -+ NULL, ++ &methodcfg_gsskeyex, + userauth_gsskeyex, -+ &options.gss_authentication +}; + Authmethod method_gssapi = { + &methodcfg_gssapi, + userauth_gssapi, +diff --git a/auth2-methods.c b/auth2-methods.c +index 99637a89b..a05908cf3 100644 +--- a/auth2-methods.c ++++ b/auth2-methods.c +@@ -50,6 +50,11 @@ struct authmethod_cfg methodcfg_pubkey = { + &options.pubkey_authentication + }; + #ifdef GSSAPI ++struct authmethod_cfg methodcfg_gsskeyex = { ++ "gssapi-keyex", ++ NULL, ++ &options.gss_authentication ++}; + struct authmethod_cfg methodcfg_gssapi = { "gssapi-with-mic", NULL, +@@ -76,6 +81,7 @@ static struct authmethod_cfg *authmethod_cfgs[] = { + &methodcfg_none, + &methodcfg_pubkey, + #ifdef GSSAPI ++ &methodcfg_gsskeyex, + &methodcfg_gssapi, + #endif + &methodcfg_passwd, diff --git a/auth2.c b/auth2.c -index 271789a77..514a697ca 100644 +index 67dec88c3..f75f1d20d 100644 --- a/auth2.c +++ b/auth2.c @@ -71,6 +71,7 @@ extern Authmethod method_passwd; @@ -371,124 +302,8 @@ index 271789a77..514a697ca 100644 &method_gssapi, #endif &method_passwd, -diff --git a/canohost.c b/canohost.c -index 28f086e5a..33213ab05 100644 ---- a/canohost.c -+++ b/canohost.c -@@ -35,6 +35,97 @@ - #include "canohost.h" - #include "misc.h" - -+/* -+ * Returns the remote DNS hostname as a string. The returned string must not -+ * be freed. NB. this will usually trigger a DNS query the first time it is -+ * called. -+ * This function does additional checks on the hostname to mitigate some -+ * attacks on legacy rhosts-style authentication. -+ */ -+ -+char * -+remote_hostname(struct ssh *ssh) -+{ -+ struct sockaddr_storage from; -+ socklen_t fromlen; -+ struct addrinfo hints, *ai, *aitop; -+ char name[NI_MAXHOST], ntop2[NI_MAXHOST]; -+ const char *ntop = ssh_remote_ipaddr(ssh); -+ -+ /* Get IP address of client. */ -+ fromlen = sizeof(from); -+ memset(&from, 0, sizeof(from)); -+ if (getpeername(ssh_packet_get_connection_in(ssh), -+ (struct sockaddr *)&from, &fromlen) == -1) { -+ debug("getpeername failed: %.100s", strerror(errno)); -+ return xstrdup(ntop); -+ } -+ -+ ipv64_normalise_mapped(&from, &fromlen); -+ if (from.ss_family == AF_INET6) -+ fromlen = sizeof(struct sockaddr_in6); -+ -+ debug3("Trying to reverse map address %.100s.", ntop); -+ /* Map the IP address to a host name. */ -+ if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), -+ NULL, 0, NI_NAMEREQD) != 0) { -+ /* Host name not found. Use ip address. */ -+ return xstrdup(ntop); -+ } -+ -+ /* -+ * if reverse lookup result looks like a numeric hostname, -+ * someone is trying to trick us by PTR record like following: -+ * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 -+ */ -+ memset(&hints, 0, sizeof(hints)); -+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/ -+ hints.ai_flags = AI_NUMERICHOST; -+ if (getaddrinfo(name, NULL, &hints, &ai) == 0) { -+ logit("Nasty PTR record \"%s\" is set up for %s, ignoring", -+ name, ntop); -+ freeaddrinfo(ai); -+ return xstrdup(ntop); -+ } -+ -+ /* Names are stored in lowercase. */ -+ lowercase(name); -+ -+ /* -+ * Map it back to an IP address and check that the given -+ * address actually is an address of this host. This is -+ * necessary because anyone with access to a name server can -+ * define arbitrary names for an IP address. Mapping from -+ * name to IP address can be trusted better (but can still be -+ * fooled if the intruder has access to the name server of -+ * the domain). -+ */ -+ memset(&hints, 0, sizeof(hints)); -+ hints.ai_family = from.ss_family; -+ hints.ai_socktype = SOCK_STREAM; -+ if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { -+ logit("reverse mapping checking getaddrinfo for %.700s " -+ "[%s] failed.", name, ntop); -+ return xstrdup(ntop); -+ } -+ /* Look for the address from the list of addresses. */ -+ for (ai = aitop; ai; ai = ai->ai_next) { -+ if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, -+ sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && -+ (strcmp(ntop, ntop2) == 0)) -+ break; -+ } -+ freeaddrinfo(aitop); -+ /* If we reached the end of the list, the address was not there. */ -+ if (ai == NULL) { -+ /* Address not found for the host name. */ -+ logit("Address %.100s maps to %.600s, but this does not " -+ "map back to the address.", ntop, name); -+ return xstrdup(ntop); -+ } -+ return xstrdup(name); -+} -+ - void - ipv64_normalise_mapped(struct sockaddr_storage *addr, socklen_t *len) - { -diff --git a/canohost.h b/canohost.h -index 26d62855a..0cadc9f18 100644 ---- a/canohost.h -+++ b/canohost.h -@@ -15,6 +15,9 @@ - #ifndef _CANOHOST_H - #define _CANOHOST_H - -+struct ssh; -+ -+char *remote_hostname(struct ssh *); - char *get_peer_ipaddr(int); - int get_peer_port(int); - char *get_local_ipaddr(int); diff --git a/clientloop.c b/clientloop.c -index 8ec36af94..a1f94a85a 100644 +index 8ed8b1c34..6d57339a1 100644 --- a/clientloop.c +++ b/clientloop.c @@ -115,6 +115,10 @@ @@ -502,7 +317,7 @@ index 8ec36af94..a1f94a85a 100644 /* Permitted RSA signature algorithms for UpdateHostkeys proofs */ #define HOSTKEY_PROOF_RSA_ALGS "rsa-sha2-512,rsa-sha2-256" -@@ -1594,6 +1598,15 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, +@@ -1590,6 +1594,15 @@ client_loop(struct ssh *ssh, int have_pty, int escape_char_arg, /* Do channel operations. */ channel_after_poll(ssh, pfd, npfd_active); @@ -519,7 +334,7 @@ index 8ec36af94..a1f94a85a 100644 if (conn_in_ready) client_process_net_input(ssh); diff --git a/configure.ac b/configure.ac -index 82e8bb7c1..bb3e644fe 100644 +index 5a865f8e1..dc274329f 100644 --- a/configure.ac +++ b/configure.ac @@ -774,6 +774,30 @@ int main(void) { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) @@ -1061,7 +876,7 @@ index a151bc1e4..ef20401ec 100644 #endif /* KRB5 */ diff --git a/gss-serv.c b/gss-serv.c -index 00e3d118b..162fec447 100644 +index 00e3d118b..b761d12aa 100644 --- a/gss-serv.c +++ b/gss-serv.c @@ -1,7 +1,7 @@ @@ -1117,7 +932,7 @@ index 00e3d118b..162fec447 100644 + Gssctxt *ctx = NULL; + int res; + -+ res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid))); ++ res = !GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctx, oid)); + ssh_gssapi_delete_ctx(&ctx); + + return (res); @@ -1152,15 +967,15 @@ index 00e3d118b..162fec447 100644 + debug("Rekeyed credentials have different mechanism"); + return GSS_S_COMPLETE; + } -+ + +- gss_buffer_desc ename; + if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, + ctx->client_creds, ctx->oid, &new_name, + NULL, NULL, NULL))) { + ssh_gssapi_error(ctx); + return (ctx->major); + } - -- gss_buffer_desc ename; ++ + ctx->major = gss_compare_name(&ctx->minor, client->name, + new_name, &equal); + @@ -1263,7 +1078,7 @@ index 00e3d118b..162fec447 100644 /* Destroy delegated credentials if userok fails */ gss_release_buffer(&lmin, &gssapi_client.displayname); gss_release_buffer(&lmin, &gssapi_client.exportedname); -@@ -382,14 +471,90 @@ ssh_gssapi_userok(char *user) +@@ -382,14 +471,85 @@ ssh_gssapi_userok(char *user) return (0); } @@ -1306,7 +1121,7 @@ index 00e3d118b..162fec447 100644 + gssapi_client.store.envvar == NULL) + return; + -+ ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store)); ++ ok = mm_ssh_gssapi_update_creds(&gssapi_client.store); + + if (!ok) + return; @@ -1318,11 +1133,6 @@ index 00e3d118b..162fec447 100644 + * for rekeying. So, use our own :) + */ +#ifdef USE_PAM -+ if (!use_privsep) { -+ debug("Not even going to try and do PAM with privsep disabled"); -+ return; -+ } -+ + ret = pam_start("sshd-rekey", gssapi_client.store.owner->pw_name, + &pamconv, &pamh); + if (ret) @@ -1360,29 +1170,22 @@ index 00e3d118b..162fec447 100644 } /* Privileged */ -diff --git a/kex.c b/kex.c -index 8a0f16513..e4a2362bd 100644 ---- a/kex.c -+++ b/kex.c -@@ -58,12 +58,17 @@ - #include "dispatch.h" - #include "monitor.h" - #include "myproposal.h" -+#include "xmalloc.h" - +diff --git a/kex-names.c b/kex-names.c +index 339eb1c23..f077520bb 100644 +--- a/kex-names.c ++++ b/kex-names.c +@@ -45,6 +45,10 @@ #include "ssherr.h" - #include "sshbuf.h" - #include "digest.h" #include "xmalloc.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif + - /* prototype */ - static int kex_choose_conf(struct ssh *, uint32_t seq); - static int kex_input_newkeys(int, u_int32_t, struct ssh *); -@@ -119,15 +124,28 @@ static const struct kexalg kexalgs[] = { + struct kexalg { + char *name; + u_int type; +@@ -83,15 +87,28 @@ static const struct kexalg kexalgs[] = { #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */ { NULL, 0, -1, -1}, }; @@ -1414,7 +1217,7 @@ index 8a0f16513..e4a2362bd 100644 if (ret != NULL) ret[rlen++] = sep; nlen = strlen(k->name); -@@ -142,6 +160,18 @@ kex_alg_list(char sep) +@@ -106,6 +123,18 @@ kex_alg_list(char sep) return ret; } @@ -1433,7 +1236,7 @@ index 8a0f16513..e4a2362bd 100644 static const struct kexalg * kex_alg_by_name(const char *name) { -@@ -151,6 +181,10 @@ kex_alg_by_name(const char *name) +@@ -115,6 +144,10 @@ kex_alg_by_name(const char *name) if (strcmp(k->name, name) == 0) return k; } @@ -1444,8 +1247,8 @@ index 8a0f16513..e4a2362bd 100644 return NULL; } -@@ -393,6 +427,29 @@ kex_proposal_free_entries(char *prop[PROPOSAL_MAX]) - free(prop[i]); +@@ -177,6 +210,29 @@ kex_names_valid(const char *names) + return 1; } +/* Validate GSS KEX method name list */ @@ -1471,10 +1274,22 @@ index 8a0f16513..e4a2362bd 100644 + return 1; +} + - /* put algorithm proposal into buffer */ + /* returns non-zero if proposal contains any algorithm from algs */ int - kex_prop2buf(struct sshbuf *b, char *proposal[PROPOSAL_MAX]) -@@ -987,6 +1044,9 @@ kex_free(struct kex *kex) + kex_has_any_alg(const char *proposal, const char *algs) +diff --git a/kex.c b/kex.c +index 63aae5d71..fd018021e 100644 +--- a/kex.c ++++ b/kex.c +@@ -58,6 +58,7 @@ + #include "dispatch.h" + #include "monitor.h" + #include "myproposal.h" ++#include "xmalloc.h" + + #include "ssherr.h" + #include "sshbuf.h" +@@ -739,6 +740,9 @@ kex_free(struct kex *kex) sshbuf_free(kex->session_id); sshbuf_free(kex->initial_sig); sshkey_free(kex->initial_hostkey); @@ -1485,7 +1300,7 @@ index 8a0f16513..e4a2362bd 100644 free(kex->hostkey_alg); free(kex->name); diff --git a/kex.h b/kex.h -index 0caf42b50..32da837f8 100644 +index 34665eb20..d3c57a329 100644 --- a/kex.h +++ b/kex.h @@ -102,6 +102,15 @@ enum kex_exchange { @@ -1517,21 +1332,17 @@ index 0caf42b50..32da837f8 100644 char *failed_choice; int (*verify_host_key)(struct sshkey *, struct ssh *); struct sshkey *(*load_host_public_key)(int, int, struct ssh *); -@@ -185,11 +200,13 @@ struct kex { - +@@ -188,7 +203,9 @@ u_int kex_type_from_name(const char *); + int kex_hash_from_name(const char *); + int kex_nid_from_name(const char *); int kex_names_valid(const char *); ++int kex_gss_names_valid(const char *); char *kex_alg_list(char); +char *kex_gss_alg_list(char); char *kex_names_cat(const char *, const char *); + int kex_has_any_alg(const char *, const char *); int kex_assemble_names(char **, const char *, const char *); - void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX], - const char *, const char *, const char *, const char *, const char *); - void kex_proposal_free_entries(char *prop[PROPOSAL_MAX]); -+int kex_gss_names_valid(const char *); - - int kex_exchange_identification(struct ssh *, int, const char *); - -@@ -219,6 +236,12 @@ int kexgex_client(struct ssh *); +@@ -224,6 +241,12 @@ int kexgex_client(struct ssh *); int kexgex_server(struct ssh *); int kex_gen_client(struct ssh *); int kex_gen_server(struct ssh *); @@ -1544,7 +1355,7 @@ index 0caf42b50..32da837f8 100644 int kex_dh_keypair(struct kex *); int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, -@@ -251,6 +274,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, +@@ -256,6 +279,12 @@ int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, const BIGNUM *, const u_char *, size_t, u_char *, size_t *); @@ -2208,7 +2019,7 @@ index 000000000..2da431428 +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --git a/kexgsss.c b/kexgsss.c new file mode 100644 -index 000000000..40d184170 +index 000000000..1fd1d1e48 --- /dev/null +++ b/kexgsss.c @@ -0,0 +1,478 @@ @@ -2310,7 +2121,7 @@ index 000000000..40d184170 + + debug2_f("Acquiring credentials"); + -+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) ++ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, oid))) + fatal("Unable to acquire credentials for the server"); + + do { @@ -2362,8 +2173,8 @@ index 000000000..40d184170 + type); + } + -+ maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, -+ &send_tok, &ret_flags)); ++ maj_status = mm_ssh_gssapi_accept_ctx(ctxt, &recv_tok, ++ &send_tok, &ret_flags); + + gss_release_buffer(&min_status, &recv_tok); + @@ -2416,7 +2227,7 @@ index 000000000..40d184170 + gssbuf.value = hash; + gssbuf.length = hashlen; + -+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok)))) ++ if (GSS_ERROR(mm_ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))) + fatal("Couldn't get MIC"); + + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || @@ -2506,7 +2317,7 @@ index 000000000..40d184170 + + debug2_f("Acquiring credentials"); + -+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) ++ if (GSS_ERROR(mm_ssh_gssapi_server_ctx(&ctxt, oid))) + fatal("Unable to acquire credentials for the server"); + + /* 5. S generates an ephemeral key pair (do the allocations early) */ @@ -2532,7 +2343,7 @@ index 000000000..40d184170 + if (max < min || nbits < min || max < nbits) + fatal("GSS_GEX, bad parameters: %d !< %d !< %d", + min, nbits, max); -+ kex->dh = PRIVSEP(choose_dh(min, nbits, max)); ++ kex->dh = mm_choose_dh(min, nbits, max); + if (kex->dh == NULL) { + sshpkt_disconnect(ssh, "Protocol error: no matching group found"); + fatal("Protocol error: no matching group found"); @@ -2579,8 +2390,8 @@ index 000000000..40d184170 + type); + } + -+ maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, -+ &send_tok, &ret_flags)); ++ maj_status = mm_ssh_gssapi_accept_ctx(ctxt, &recv_tok, ++ &send_tok, &ret_flags); + + gss_release_buffer(&min_status, &recv_tok); + @@ -2645,7 +2456,7 @@ index 000000000..40d184170 + gssbuf.value = hash; + gssbuf.length = hashlen; + -+ if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok)))) ++ if (GSS_ERROR(mm_ssh_gssapi_sign(ctxt, &gssbuf, &msg_tok))) + fatal("Couldn't get MIC"); + + if ((r = sshpkt_start(ssh, SSH2_MSG_KEXGSS_COMPLETE)) != 0 || @@ -2691,10 +2502,10 @@ index 000000000..40d184170 +} +#endif /* defined(GSSAPI) && defined(WITH_OPENSSL) */ diff --git a/monitor.c b/monitor.c -index b3ed515ed..2bc152468 100644 +index 9e0e03ea2..92e2ca107 100644 --- a/monitor.c +++ b/monitor.c -@@ -142,6 +142,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); +@@ -140,6 +140,8 @@ int mm_answer_gss_setup_ctx(struct ssh *, int, struct sshbuf *); int mm_answer_gss_accept_ctx(struct ssh *, int, struct sshbuf *); int mm_answer_gss_userok(struct ssh *, int, struct sshbuf *); int mm_answer_gss_checkmic(struct ssh *, int, struct sshbuf *); @@ -2703,7 +2514,7 @@ index b3ed515ed..2bc152468 100644 #endif #ifdef SSH_AUDIT_EVENTS -@@ -214,11 +216,18 @@ struct mon_table mon_dispatch_proto20[] = { +@@ -213,11 +215,18 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic}, @@ -2722,7 +2533,7 @@ index b3ed515ed..2bc152468 100644 #ifdef WITH_OPENSSL {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, #endif -@@ -287,6 +296,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -286,6 +295,10 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor) /* Permit requests for moduli and signatures */ monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); @@ -2733,7 +2544,7 @@ index b3ed515ed..2bc152468 100644 /* The first few requests do not require asynchronous access */ while (!authenticated) { -@@ -403,6 +416,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) +@@ -407,6 +420,10 @@ monitor_child_postauth(struct ssh *ssh, struct monitor *pmonitor) monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); @@ -2744,7 +2555,7 @@ index b3ed515ed..2bc152468 100644 if (auth_opts->permit_pty_flag) { monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); -@@ -1745,6 +1762,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) +@@ -1760,6 +1777,17 @@ monitor_apply_keystate(struct ssh *ssh, struct monitor *pmonitor) # ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; # endif @@ -2762,7 +2573,7 @@ index b3ed515ed..2bc152468 100644 #endif /* WITH_OPENSSL */ kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; -@@ -1837,8 +1865,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1852,8 +1880,8 @@ mm_answer_gss_setup_ctx(struct ssh *ssh, int sock, struct sshbuf *m) u_char *p; int r; @@ -2773,7 +2584,7 @@ index b3ed515ed..2bc152468 100644 if ((r = sshbuf_get_string(m, &p, &len)) != 0) fatal_fr(r, "parse"); -@@ -1870,8 +1898,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1885,8 +1913,8 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 flags = 0; /* GSI needs this */ int r; @@ -2784,7 +2595,7 @@ index b3ed515ed..2bc152468 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &in)) != 0) fatal_fr(r, "ssh_gssapi_get_buffer_desc"); -@@ -1891,6 +1919,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1906,6 +1934,7 @@ mm_answer_gss_accept_ctx(struct ssh *ssh, int sock, struct sshbuf *m) monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0); monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1); monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1); @@ -2792,7 +2603,7 @@ index b3ed515ed..2bc152468 100644 } return (0); } -@@ -1902,8 +1931,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1917,8 +1946,8 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) OM_uint32 ret; int r; @@ -2803,7 +2614,7 @@ index b3ed515ed..2bc152468 100644 if ((r = ssh_gssapi_get_buffer_desc(m, &gssbuf)) != 0 || (r = ssh_gssapi_get_buffer_desc(m, &mic)) != 0) -@@ -1929,13 +1958,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1944,13 +1973,17 @@ mm_answer_gss_checkmic(struct ssh *ssh, int sock, struct sshbuf *m) int mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) { @@ -2825,7 +2636,7 @@ index b3ed515ed..2bc152468 100644 sshbuf_reset(m); if ((r = sshbuf_put_u32(m, authenticated)) != 0) -@@ -1944,7 +1977,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1959,7 +1992,11 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) debug3_f("sending result %d", authenticated); mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m); @@ -2838,7 +2649,7 @@ index b3ed515ed..2bc152468 100644 if ((displayname = ssh_gssapi_displayname()) != NULL) auth2_record_info(authctxt, "%s", displayname); -@@ -1952,5 +1989,83 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) +@@ -1967,5 +2004,83 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m) /* Monitor loop will terminate if authenticated */ return (authenticated); } @@ -2924,7 +2735,7 @@ index b3ed515ed..2bc152468 100644 + +#endif /* GSSAPI */ diff --git a/monitor.h b/monitor.h -index 683e5e071..2b1a2d590 100644 +index fa48fc69b..7d8f3c6fa 100644 --- a/monitor.h +++ b/monitor.h @@ -63,6 +63,8 @@ enum monitor_reqtype { @@ -2937,10 +2748,10 @@ index 683e5e071..2b1a2d590 100644 struct ssh; diff --git a/monitor_wrap.c b/monitor_wrap.c -index 6270d1398..189467037 100644 +index 5358c77a1..cb3261b4d 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c -@@ -998,13 +998,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) +@@ -1054,13 +1054,15 @@ mm_ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic) } int @@ -2957,7 +2768,7 @@ index 6270d1398..189467037 100644 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, m); mm_request_receive_expect(pmonitor->m_recvfd, -@@ -1017,4 +1019,57 @@ mm_ssh_gssapi_userok(char *user) +@@ -1073,6 +1075,59 @@ mm_ssh_gssapi_userok(char *user) debug3_f("user %sauthenticated", authenticated ? "" : "not "); return (authenticated); } @@ -3015,11 +2826,13 @@ index 6270d1398..189467037 100644 +} + #endif /* GSSAPI */ + + /* diff --git a/monitor_wrap.h b/monitor_wrap.h -index 0df49c25b..830fdb308 100644 +index e768036ed..09b0ccaaa 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h -@@ -65,8 +65,10 @@ int mm_sshkey_verify(const struct sshkey *, const u_char *, size_t, +@@ -64,8 +64,10 @@ void mm_decode_activate_server_options(struct ssh *ssh, struct sshbuf *m); OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID); OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *, gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *); @@ -3032,7 +2845,7 @@ index 0df49c25b..830fdb308 100644 #ifdef USE_PAM diff --git a/readconf.c b/readconf.c -index 3a64a0441..91d3c0aa0 100644 +index 4e3791cb7..8bdeb9d08 100644 --- a/readconf.c +++ b/readconf.c @@ -70,6 +70,7 @@ @@ -3189,7 +3002,7 @@ index 9447d5d6e..f039c11bd 100644 * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ diff --git a/servconf.c b/servconf.c -index 4b434909a..961cf9e45 100644 +index 5b32f0bfc..c1bfca258 100644 --- a/servconf.c +++ b/servconf.c @@ -68,6 +68,7 @@ @@ -3198,9 +3011,9 @@ index 4b434909a..961cf9e45 100644 #include "digest.h" +#include "ssh-gss.h" - static void add_listen_addr(ServerOptions *, const char *, - const char *, int); -@@ -134,8 +135,11 @@ initialize_server_options(ServerOptions *options) + #if !defined(SSHD_PAM_SERVICE) + # define SSHD_PAM_SERVICE "sshd" +@@ -137,8 +138,11 @@ initialize_server_options(ServerOptions *options) options->kerberos_ticket_cleanup = -1; options->kerberos_get_afs_token = -1; options->gss_authentication=-1; @@ -3212,7 +3025,7 @@ index 4b434909a..961cf9e45 100644 options->password_authentication = -1; options->kbd_interactive_authentication = -1; options->permit_empty_passwd = -1; -@@ -358,10 +362,18 @@ fill_default_server_options(ServerOptions *options) +@@ -376,10 +380,18 @@ fill_default_server_options(ServerOptions *options) options->kerberos_get_afs_token = 0; if (options->gss_authentication == -1) options->gss_authentication = 0; @@ -3231,15 +3044,15 @@ index 4b434909a..961cf9e45 100644 if (options->password_authentication == -1) options->password_authentication = 1; if (options->kbd_interactive_authentication == -1) -@@ -518,6 +530,7 @@ typedef enum { - sHostKeyAlgorithms, sPerSourceMaxStartups, sPerSourceNetBlockSize, +@@ -558,6 +570,7 @@ typedef enum { + sPerSourcePenalties, sPerSourcePenaltyExemptList, sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile, sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor, + sGssKeyEx, sGssKexAlgorithms, sGssStoreRekey, sAcceptEnv, sSetEnv, sPermitTunnel, sMatch, sPermitOpen, sPermitListen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, -@@ -600,12 +613,22 @@ static struct { +@@ -643,12 +656,22 @@ static struct { #ifdef GSSAPI { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL }, { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL }, @@ -3262,7 +3075,7 @@ index 4b434909a..961cf9e45 100644 { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL }, { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */ -@@ -1618,6 +1641,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1585,6 +1608,10 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_authentication; goto parse_flag; @@ -3273,7 +3086,7 @@ index 4b434909a..961cf9e45 100644 case sGssCleanupCreds: intptr = &options->gss_cleanup_creds; goto parse_flag; -@@ -1626,6 +1653,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, +@@ -1593,6 +1620,22 @@ process_server_config_line_depth(ServerOptions *options, char *line, intptr = &options->gss_strict_acceptor; goto parse_flag; @@ -3296,7 +3109,7 @@ index 4b434909a..961cf9e45 100644 case sPasswordAuthentication: intptr = &options->password_authentication; goto parse_flag; -@@ -3112,6 +3155,10 @@ dump_config(ServerOptions *o) +@@ -3178,6 +3221,10 @@ dump_config(ServerOptions *o) #ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); @@ -3308,10 +3121,10 @@ index 4b434909a..961cf9e45 100644 dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, diff --git a/servconf.h b/servconf.h -index ed7b72e8e..2ce4ae0ad 100644 +index 22b158d10..c1e2751ee 100644 --- a/servconf.h +++ b/servconf.h -@@ -139,8 +139,11 @@ typedef struct { +@@ -149,8 +149,11 @@ typedef struct { int kerberos_get_afs_token; /* If true, try to get AFS token if * authenticated with Kerberos. */ int gss_authentication; /* If true, permit GSSAPI authentication */ @@ -3324,10 +3137,10 @@ index ed7b72e8e..2ce4ae0ad 100644 * authentication. */ int kbd_interactive_authentication; /* If true, permit */ diff --git a/session.c b/session.c -index c821dcd44..cbb4edac5 100644 +index c9415114d..3d9a16b1e 100644 --- a/session.c +++ b/session.c -@@ -2687,13 +2687,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) +@@ -2672,13 +2672,19 @@ do_cleanup(struct ssh *ssh, Authctxt *authctxt) #ifdef KRB5 if (options.kerberos_ticket_cleanup && @@ -3350,11 +3163,11 @@ index c821dcd44..cbb4edac5 100644 /* remove agent socket */ diff --git a/ssh-gss.h b/ssh-gss.h -index a8af117d2..6303ce185 100644 +index 7b14e74a8..0fd77cd45 100644 --- a/ssh-gss.h +++ b/ssh-gss.h @@ -1,6 +1,6 @@ - /* $OpenBSD: ssh-gss.h,v 1.15 2021/01/27 10:05:28 djm Exp $ */ + /* $OpenBSD: ssh-gss.h,v 1.16 2024/05/17 06:42:04 jsg Exp $ */ /* - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved. + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved. @@ -3429,7 +3242,7 @@ index a8af117d2..6303ce185 100644 int ssh_gssapi_check_oid(Gssctxt *, void *, size_t); void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t); -@@ -109,6 +138,7 @@ OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *); +@@ -108,6 +137,7 @@ OM_uint32 ssh_gssapi_test_oid_supported(OM_uint32 *, gss_OID, int *); struct sshbuf; int ssh_gssapi_get_buffer_desc(struct sshbuf *, gss_buffer_desc *); @@ -3437,7 +3250,7 @@ index a8af117d2..6303ce185 100644 OM_uint32 ssh_gssapi_import_name(Gssctxt *, const char *); OM_uint32 ssh_gssapi_init_ctx(Gssctxt *, int, -@@ -123,17 +153,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); +@@ -122,17 +152,33 @@ void ssh_gssapi_delete_ctx(Gssctxt **); OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t); void ssh_gssapi_buildmic(struct sshbuf *, const char *, const char *, const char *, const struct sshbuf *); @@ -3588,7 +3401,7 @@ index 000000000..a934bda77 + +#endif /* GSSAPI */ diff --git a/ssh.1 b/ssh.1 -index 936c995ba..877c3bc64 100644 +index f871ff4e4..dc382cd49 100644 --- a/ssh.1 +++ b/ssh.1 @@ -536,7 +536,13 @@ For full details of the options listed below, and their possible values, see @@ -3652,7 +3465,7 @@ index cc5663562..16197d15d 100644 # CheckHostIP no # AddressFamily any diff --git a/ssh_config.5 b/ssh_config.5 -index 2931d807e..8e8aeb640 100644 +index 2e1902283..255577462 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -938,10 +938,67 @@ The default is @@ -3724,19 +3537,10 @@ index 2931d807e..8e8aeb640 100644 Indicates that .Xr ssh 1 diff --git a/sshconnect2.c b/sshconnect2.c -index 745c2a051..b7c376116 100644 +index e63bb5ec6..e27139adf 100644 --- a/sshconnect2.c +++ b/sshconnect2.c -@@ -80,8 +80,6 @@ - #endif - - /* import */ --extern char *client_version_string; --extern char *server_version_string; - extern Options options; - - /* -@@ -224,6 +222,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, +@@ -222,6 +222,11 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, char *all_key, *hkalgs = NULL; int r, use_known_hosts_order = 0; @@ -3748,7 +3552,7 @@ index 745c2a051..b7c376116 100644 xxx_host = host; xxx_hostaddr = hostaddr; xxx_conn_info = cinfo; -@@ -259,6 +262,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, +@@ -257,6 +262,42 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, free(hkalgs); @@ -3761,7 +3565,7 @@ index 745c2a051..b7c376116 100644 + if (options.gss_server_identity) { + gss_host = xstrdup(options.gss_server_identity); + } else if (options.gss_trust_dns) { -+ gss_host = remote_hostname(ssh); ++ gss_host = ssh_remote_hostname(ssh); + /* Fall back to specified host if we are using proxy command + * and can not use DNS on that socket */ + if (strcmp(gss_host, "UNKNOWN") == 0) { @@ -3791,7 +3595,7 @@ index 745c2a051..b7c376116 100644 /* start key exchange */ if ((r = kex_setup(ssh, myproposal)) != 0) fatal_r(r, "kex_setup"); -@@ -273,11 +312,31 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, +@@ -271,11 +312,31 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port, # ifdef OPENSSL_HAS_ECC ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client; # endif @@ -3824,7 +3628,7 @@ index 745c2a051..b7c376116 100644 ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &ssh->kex->done); kex_proposal_free_entries(myproposal); -@@ -370,6 +429,7 @@ static int input_gssapi_response(int type, u_int32_t, struct ssh *); +@@ -368,6 +429,7 @@ static int input_gssapi_response(int type, u_int32_t, struct ssh *); static int input_gssapi_token(int type, u_int32_t, struct ssh *); static int input_gssapi_error(int, u_int32_t, struct ssh *); static int input_gssapi_errtok(int, u_int32_t, struct ssh *); @@ -3832,7 +3636,7 @@ index 745c2a051..b7c376116 100644 #endif void userauth(struct ssh *, char *); -@@ -386,6 +446,11 @@ static char *authmethods_get(void); +@@ -384,6 +446,11 @@ static char *authmethods_get(void); Authmethod authmethods[] = { #ifdef GSSAPI @@ -3844,7 +3648,7 @@ index 745c2a051..b7c376116 100644 {"gssapi-with-mic", userauth_gssapi, userauth_gssapi_cleanup, -@@ -757,12 +822,32 @@ userauth_gssapi(struct ssh *ssh) +@@ -755,12 +822,32 @@ userauth_gssapi(struct ssh *ssh) OM_uint32 min; int r, ok = 0; gss_OID mech = NULL; @@ -3853,7 +3657,7 @@ index 745c2a051..b7c376116 100644 + if (options.gss_server_identity) { + gss_host = xstrdup(options.gss_server_identity); + } else if (options.gss_trust_dns) { -+ gss_host = remote_hostname(ssh); ++ gss_host = ssh_remote_hostname(ssh); + /* Fall back to specified host if we are using proxy command + * and can not use DNS on that socket */ + if (strcmp(gss_host, "UNKNOWN") == 0) { @@ -3878,7 +3682,7 @@ index 745c2a051..b7c376116 100644 /* Check to see whether the mechanism is usable before we offer it */ while (authctxt->mech_tried < authctxt->gss_supported_mechs->count && -@@ -771,13 +856,15 @@ userauth_gssapi(struct ssh *ssh) +@@ -769,13 +856,15 @@ userauth_gssapi(struct ssh *ssh) elements[authctxt->mech_tried]; /* My DER encoding requires length<128 */ if (mech->length < 128 && ssh_gssapi_check_mechanism(&gssctxt, @@ -3895,7 +3699,7 @@ index 745c2a051..b7c376116 100644 if (!ok || mech == NULL) return 0; -@@ -1011,6 +1098,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) +@@ -1009,6 +1098,55 @@ input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh) free(lang); return r; } @@ -3951,11 +3755,11 @@ index 745c2a051..b7c376116 100644 #endif /* GSSAPI */ static int -diff --git a/sshd.c b/sshd.c -index b4f2b9742..d5c3dfe57 100644 ---- a/sshd.c -+++ b/sshd.c -@@ -798,8 +798,8 @@ notify_hostkeys(struct ssh *ssh) +diff --git a/sshd-session.c b/sshd-session.c +index fe6ae7f32..ab88db7c5 100644 +--- a/sshd-session.c ++++ b/sshd-session.c +@@ -656,8 +656,8 @@ notify_hostkeys(struct ssh *ssh) } debug3_f("sent %u hostkeys", nkeys); if (nkeys == 0) @@ -3966,17 +3770,7 @@ index b4f2b9742..d5c3dfe57 100644 sshpkt_fatal(ssh, r, "%s: send", __func__); sshbuf_free(buf); } -@@ -1930,7 +1930,8 @@ main(int ac, char **av) - free(fp); - } - accumulate_host_timing_secret(cfg, NULL); -- if (!sensitive_data.have_ssh2_key) { -+ /* The GSSAPI key exchange can run without a host key */ -+ if (!sensitive_data.have_ssh2_key && !options.gss_keyex) { - logit("sshd: no hostkeys available -- exiting."); - exit(1); - } -@@ -2402,6 +2403,48 @@ do_ssh2_kex(struct ssh *ssh) +@@ -1431,6 +1431,48 @@ do_ssh2_kex(struct ssh *ssh) free(hkalgs); @@ -4025,10 +3819,10 @@ index b4f2b9742..d5c3dfe57 100644 /* start key exchange */ if ((r = kex_setup(ssh, myproposal)) != 0) fatal_r(r, "kex_setup"); -@@ -2419,7 +2462,18 @@ do_ssh2_kex(struct ssh *ssh) - # ifdef OPENSSL_HAS_ECC +@@ -1448,7 +1490,18 @@ do_ssh2_kex(struct ssh *ssh) + #ifdef OPENSSL_HAS_ECC kex->kex[KEX_ECDH_SHA2] = kex_gen_server; - # endif + #endif -#endif +# ifdef GSSAPI + if (options.gss_keyex) { @@ -4045,6 +3839,20 @@ index b4f2b9742..d5c3dfe57 100644 kex->kex[KEX_C25519_SHA256] = kex_gen_server; kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server; kex->load_host_public_key=&get_hostkey_public_by_type; +diff --git a/sshd.c b/sshd.c +index ed54fc6d6..54c65dfe6 100644 +--- a/sshd.c ++++ b/sshd.c +@@ -1551,7 +1551,8 @@ main(int ac, char **av) + free(fp); + } + accumulate_host_timing_secret(cfg, NULL); +- if (!sensitive_data.have_ssh2_key) { ++ /* The GSSAPI key exchange can run without a host key */ ++ if (!sensitive_data.have_ssh2_key && !options.gss_keyex) { + logit("sshd: no hostkeys available -- exiting."); + exit(1); + } diff --git a/sshd_config b/sshd_config index 36894ace5..ecfe8d026 100644 --- a/sshd_config @@ -4059,7 +3867,7 @@ index 36894ace5..ecfe8d026 100644 # Set this to 'yes' to enable PAM authentication, account processing, # and session processing. If this is enabled, PAM authentication will diff --git a/sshd_config.5 b/sshd_config.5 -index a0f16874f..c0c1b0d9a 100644 +index 1ab0f41d9..5e41f0478 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -739,6 +739,11 @@ Specifies whether to automatically destroy the user's credentials cache @@ -4140,7 +3948,7 @@ index d4356e72c..c7abbe298 100644 if (!include_sigonly && impl->sigonly) continue; diff --git a/sshkey.h b/sshkey.h -index 708f2da86..dddb40fe2 100644 +index 32933bbbd..dc5d3051b 100644 --- a/sshkey.h +++ b/sshkey.h @@ -71,6 +71,7 @@ enum sshkey_types { |