components/openssh/patches/023-gsskex.patch
branchs11u3-sru
changeset 7320 edeb951aa980
parent 6076 0d5715bee554
child 7594 022a611ded2d
--- a/components/openssh/patches/023-gsskex.patch	Wed Nov 16 12:04:24 2016 -0800
+++ b/components/openssh/patches/023-gsskex.patch	Wed Nov 16 12:17:49 2016 -0800
@@ -6,12 +6,24 @@
 # Default value for GSSAPIKeyExchange changed to yes to match SunSSH behavior.
 # New files kexgssc.c and kexgsss.c moved to ../sources/ and made cstyle clean.
 #
+# Update Sep 5, 2016:
+# Upstream renamed and moved canohost.c`get_canonical_hostname to sshd-specific
+# auth.c`auth_get_canonical_hostname. In Solaris specific GSS-API key exchange
+# code we need this functionality on the client side too, for canonicalizing
+# server hostbased service principal. We have moved remote_hostname back to
+# canohost.c.
+#
+# TODO:
+# When we upgrade Kerberos in Solaris to future version 1.15, we will use
+# krb5_expand_hostname for hostname canonicalization instead.
+#
 # Upstream rejected GSS-API key exchange several times before.
 #
-diff -pur old/Makefile.in new/Makefile.in
---- old/Makefile.in
-+++ new/Makefile.in
-@@ -86,5 +86,6 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
+diff -rupN old/Makefile.in new/Makefile.in
+--- old/Makefile.in	2016-09-21 19:40:34.495262333 -0700
++++ new/Makefile.in	2016-09-21 20:20:17.560532505 -0700
+@@ -85,6 +85,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
+ 	atomicio.o key.o dispatch.o mac.o uidswap.o uuencode.o misc.o utf8.o \
  	monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
  	msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o umac128.o \
 +	kexgssc.o \
@@ -25,11 +37,114 @@
 -	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 md5crypt.o \
- 	sftp-server.o sftp-common.o sftp_provider.o \
+ 	sftp-server.o sftp-common.o \
  	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
-diff -pur old/auth2-gss.c new/auth2-gss.c
---- old/auth2-gss.c
-+++ new/auth2-gss.c
+diff -rupN old/auth.c new/auth.c
+--- old/auth.c	2016-09-21 19:40:20.287164940 -0700
++++ new/auth.c	2016-09-21 19:25:47.928961550 -0700
+@@ -786,99 +786,6 @@ fakepw(void)
+ }
+ 
+ /*
+- * 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.
+- * XXX is RhostsRSAAuthentication vulnerable to these?
+- * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?)
+- */
+-
+-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) < 0) {
+-		debug("getpeername failed: %.100s", strerror(errno));
+-		return strdup(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 strdup(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 strdup(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 strdup(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 strdup(ntop);
+-	}
+-	return strdup(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
+  * several times.
+diff -rupN old/auth2-gss.c new/auth2-gss.c
+--- old/auth2-gss.c	2016-09-21 19:40:20.290128383 -0700
++++ new/auth2-gss.c	2016-09-21 19:25:47.855250807 -0700
 @@ -1,7 +1,7 @@
  /* $OpenBSD: auth2-gss.c,v 1.22 2015/01/19 20:07:45 markus Exp $ */
  
@@ -92,9 +207,9 @@
  Authmethod method_gssapi = {
  	"gssapi-with-mic",
  	userauth_gssapi,
-diff -pur old/auth2.c new/auth2.c
---- old/auth2.c
-+++ new/auth2.c
+diff -rupN old/auth2.c new/auth2.c
+--- old/auth2.c	2016-09-21 19:40:20.293020496 -0700
++++ new/auth2.c	2016-09-21 19:25:47.497355321 -0700
 @@ -70,6 +70,7 @@ extern Authmethod method_passwd;
  extern Authmethod method_kbdint;
  extern Authmethod method_hostbased;
@@ -111,9 +226,123 @@
  	&method_gssapi,
  #endif
  	&method_passwd,
-diff -pur old/gss-genr.c new/gss-genr.c
---- old/gss-genr.c
-+++ new/gss-genr.c
+diff -rupN old/canohost.c new/canohost.c
+--- old/canohost.c	2016-09-21 19:40:20.295936952 -0700
++++ new/canohost.c	2016-09-21 19:25:47.908930173 -0700
+@@ -202,3 +202,97 @@ get_local_port(int sock)
+ {
+ 	return get_sock_port(sock, 1);
+ }
++
++/*
++ * 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.
++ * XXX is RhostsRSAAuthentication vulnerable to these?
++ * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?)
++ */
++
++/* Oracle Solaris - moved out of auth.c for use in GSSKEX in sshconnect2.c */
++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) < 0) {
++		debug("getpeername failed: %.100s", strerror(errno));
++		return strdup(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 strdup(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 strdup(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 strdup(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 strdup(ntop);
++	}
++	return strdup(name);
++}
+diff -rupN old/canohost.h new/canohost.h
+--- old/canohost.h	2016-09-21 19:40:20.298804941 -0700
++++ new/canohost.h	2016-09-21 19:25:47.335129267 -0700
+@@ -21,6 +21,9 @@ char		*get_local_ipaddr(int);
+ char		*get_local_name(int);
+ int		get_local_port(int);
+ 
++#include "packet.h"
++char		*remote_hostname(struct ssh *);
++
+ #endif /* _CANOHOST_H */
+ 
+ void		 ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
+diff -rupN old/gss-genr.c new/gss-genr.c
+--- old/gss-genr.c	2016-09-21 19:40:20.301650203 -0700
++++ new/gss-genr.c	2016-09-21 19:25:47.301737088 -0700
 @@ -1,7 +1,7 @@
  /* $OpenBSD: gss-genr.c,v 1.23 2015/01/20 23:14:00 deraadt Exp $ */
  
@@ -341,9 +570,9 @@
  		ssh_gssapi_delete_ctx(ctx);
  
  	return (!GSS_ERROR(major));
-diff -pur old/gss-serv.c new/gss-serv.c
---- old/gss-serv.c
-+++ new/gss-serv.c
+diff -rupN old/gss-serv.c new/gss-serv.c
+--- old/gss-serv.c	2016-09-21 19:40:20.304525100 -0700
++++ new/gss-serv.c	2016-09-21 19:25:47.229908522 -0700
 @@ -1,7 +1,7 @@
  /* $OpenBSD: gss-serv.c,v 1.29 2015/05/22 03:50:02 djm Exp $ */
  
@@ -416,10 +645,10 @@
 -}
 -
  #endif
-diff -pur old/kex.c new/kex.c
---- old/kex.c
-+++ new/kex.c
-@@ -54,6 +54,10 @@
+diff -rupN old/kex.c new/kex.c
+--- old/kex.c	2016-09-21 19:40:20.307412118 -0700
++++ new/kex.c	2016-09-21 19:25:47.559276736 -0700
+@@ -55,6 +55,10 @@
  #include "sshbuf.h"
  #include "digest.h"
  
@@ -430,7 +659,7 @@
  #if OPENSSL_VERSION_NUMBER >= 0x00907000L
  # if defined(HAVE_EVP_SHA256)
  # define evp_ssh_sha256 EVP_sha256
-@@ -107,6 +111,11 @@ static const struct kexalg kexalgs[] = {
+@@ -111,6 +115,11 @@ static const struct kexalg kexalgs[] = {
  #if defined(HAVE_EVP_SHA256) || !defined(WITH_OPENSSL)
  	{ KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
  #endif /* HAVE_EVP_SHA256 || !WITH_OPENSSL */
@@ -442,7 +671,7 @@
  	{ NULL, -1, -1, -1},
  };
  
-@@ -138,7 +147,7 @@ kex_alg_by_name(const char *name)
+@@ -142,7 +151,7 @@ kex_alg_by_name(const char *name)
  	const struct kexalg *k;
  
  	for (k = kexalgs; k->name != NULL; k++) {
@@ -451,10 +680,10 @@
  			return k;
  	}
  	return NULL;
-diff -pur old/kex.h new/kex.h
---- old/kex.h
-+++ new/kex.h
-@@ -92,6 +92,9 @@ enum kex_exchange {
+diff -rupN old/kex.h new/kex.h
+--- old/kex.h	2016-09-21 19:40:20.310245128 -0700
++++ new/kex.h	2016-09-21 19:25:47.142516186 -0700
+@@ -98,6 +98,9 @@ enum kex_exchange {
  	KEX_DH_GEX_SHA256,
  	KEX_ECDH_SHA2,
  	KEX_C25519_SHA256,
@@ -464,7 +693,7 @@
  	KEX_MAX
  };
  
-@@ -140,6 +143,10 @@ struct kex {
+@@ -146,6 +149,10 @@ struct kex {
  	u_int	flags;
  	int	hash_alg;
  	int	ec_nid;
@@ -475,7 +704,7 @@
  	char	*client_version_string;
  	char	*server_version_string;
  	char	*failed_choice;
-@@ -189,6 +196,10 @@ int	 kexecdh_client(struct ssh *);
+@@ -195,6 +202,10 @@ int	 kexecdh_client(struct ssh *);
  int	 kexecdh_server(struct ssh *);
  int	 kexc25519_client(struct ssh *);
  int	 kexc25519_server(struct ssh *);
@@ -484,12 +713,12 @@
 +int	 kexgss_server(struct ssh *);
 +#endif
  
- int	 kex_dh_hash(const char *, const char *,
+ int	 kex_dh_hash(int, const char *, const char *,
      const u_char *, size_t, const u_char *, size_t, const u_char *, size_t,
-diff -pur old/monitor.c new/monitor.c
---- old/monitor.c
-+++ new/monitor.c
-@@ -159,6 +159,7 @@ int mm_answer_gss_setup_ctx(int, Buffer
+diff -rupN old/monitor.c new/monitor.c
+--- old/monitor.c	2016-09-21 19:40:20.313190151 -0700
++++ new/monitor.c	2016-09-21 19:25:47.525137447 -0700
+@@ -161,6 +161,7 @@ int mm_answer_gss_setup_ctx(int, Buffer 
  int mm_answer_gss_accept_ctx(int, Buffer *);
  int mm_answer_gss_userok(int, Buffer *);
  int mm_answer_gss_checkmic(int, Buffer *);
@@ -497,7 +726,7 @@
  #endif
  
  #ifdef SSH_AUDIT_EVENTS
-@@ -243,11 +244,17 @@ struct mon_table mon_dispatch_proto20[]
+@@ -245,11 +246,17 @@ struct mon_table mon_dispatch_proto20[] 
      {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
      {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
      {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
@@ -515,7 +744,7 @@
  #ifdef WITH_OPENSSL
      {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
  #endif
-@@ -362,6 +369,10 @@ monitor_child_preauth(Authctxt *_authctx
+@@ -364,6 +371,10 @@ monitor_child_preauth(Authctxt *_authctx
  		/* Permit requests for moduli and signatures */
  		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
  		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
@@ -526,7 +755,7 @@
  	} else {
  		mon_dispatch = mon_dispatch_proto15;
  
-@@ -501,6 +512,10 @@ monitor_child_postauth(struct monitor *p
+@@ -503,6 +514,10 @@ monitor_child_postauth(struct monitor *p
  		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
  		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
  		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
@@ -537,7 +766,7 @@
  	} else {
  		mon_dispatch = mon_dispatch_postauth15;
  		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
-@@ -1924,6 +1939,13 @@ monitor_apply_keystate(struct monitor *p
+@@ -1939,6 +1954,13 @@ monitor_apply_keystate(struct monitor *p
  # endif
  #endif /* WITH_OPENSSL */
  		kex->kex[KEX_C25519_SHA256] = kexc25519_server;
@@ -551,7 +780,7 @@
  		kex->load_host_public_key=&get_hostkey_public_by_type;
  		kex->load_host_private_key=&get_hostkey_private_by_type;
  		kex->host_key_index=&get_hostkey_index;
-@@ -2023,6 +2045,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer
+@@ -2038,6 +2060,9 @@ mm_answer_gss_setup_ctx(int sock, Buffer
  	OM_uint32 major;
  	u_int len;
  
@@ -561,7 +790,7 @@
  	goid.elements = buffer_get_string(m, &len);
  	goid.length = len;
  
-@@ -2050,6 +2075,9 @@ mm_answer_gss_accept_ctx(int sock, Buffe
+@@ -2065,6 +2090,9 @@ mm_answer_gss_accept_ctx(int sock, Buffe
  	OM_uint32 flags = 0; /* GSI needs this */
  	u_int len;
  
@@ -571,7 +800,7 @@
  	in.value = buffer_get_string(m, &len);
  	in.length = len;
  	major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
-@@ -2067,6 +2095,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe
+@@ -2082,6 +2110,7 @@ mm_answer_gss_accept_ctx(int sock, Buffe
  		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
  		monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
  		monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
@@ -579,7 +808,7 @@
  	}
  	return (0);
  }
-@@ -2078,6 +2107,9 @@ mm_answer_gss_checkmic(int sock, Buffer
+@@ -2093,6 +2122,9 @@ mm_answer_gss_checkmic(int sock, Buffer 
  	OM_uint32 ret;
  	u_int len;
  
@@ -589,7 +818,7 @@
  	gssbuf.value = buffer_get_string(m, &len);
  	gssbuf.length = len;
  	mic.value = buffer_get_string(m, &len);
-@@ -2104,6 +2136,9 @@ mm_answer_gss_userok(int sock, Buffer *m
+@@ -2119,6 +2151,9 @@ mm_answer_gss_userok(int sock, Buffer *m
  {
  	int authenticated;
  
@@ -599,7 +828,7 @@
  	authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
  
  	buffer_clear(m);
-@@ -2117,5 +2152,47 @@ mm_answer_gss_userok(int sock, Buffer *m
+@@ -2132,5 +2167,47 @@ mm_answer_gss_userok(int sock, Buffer *m
  	/* Monitor loop will terminate if authenticated */
  	return (authenticated);
  }
@@ -647,9 +876,9 @@
 +
  #endif /* GSSAPI */
  
-diff -pur old/monitor.h new/monitor.h
---- old/monitor.h
-+++ new/monitor.h
+diff -rupN old/monitor.h new/monitor.h
+--- old/monitor.h	2016-09-21 19:40:20.316049455 -0700
++++ new/monitor.h	2016-09-21 19:25:47.113344203 -0700
 @@ -68,6 +68,9 @@ enum monitor_reqtype {
  #ifdef PAM_ENHANCEMENT
          MONITOR_REQ_AUTHMETHOD = 114,
@@ -660,10 +889,10 @@
  };
  
  struct mm_master;
-diff -pur old/monitor_wrap.c new/monitor_wrap.c
---- old/monitor_wrap.c
-+++ new/monitor_wrap.c
-@@ -1103,5 +1103,28 @@ mm_ssh_gssapi_userok(char *user)
+diff -rupN old/monitor_wrap.c new/monitor_wrap.c
+--- old/monitor_wrap.c	2016-09-21 19:40:20.318913737 -0700
++++ new/monitor_wrap.c	2016-09-21 19:25:47.668505812 -0700
+@@ -1108,5 +1108,28 @@ mm_ssh_gssapi_userok(char *user)
  	debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
  	return (authenticated);
  }
@@ -692,10 +921,10 @@
 +
  #endif /* GSSAPI */
  
-diff -pur old/monitor_wrap.h new/monitor_wrap.h
---- old/monitor_wrap.h
-+++ new/monitor_wrap.h
-@@ -60,6 +60,7 @@ OM_uint32 mm_ssh_gssapi_accept_ctx(Gssct
+diff -rupN old/monitor_wrap.h new/monitor_wrap.h
+--- old/monitor_wrap.h	2016-09-21 19:40:20.321783476 -0700
++++ new/monitor_wrap.h	2016-09-21 19:25:47.026452744 -0700
+@@ -62,6 +62,7 @@ OM_uint32 mm_ssh_gssapi_accept_ctx(Gssct
     gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
  int mm_ssh_gssapi_userok(char *user);
  OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
@@ -703,10 +932,10 @@
  #endif
  
  #ifdef USE_PAM
-diff -pur old/readconf.c new/readconf.c
---- old/readconf.c
-+++ new/readconf.c
-@@ -148,6 +148,7 @@ typedef enum {
+diff -rupN old/readconf.c new/readconf.c
+--- old/readconf.c	2016-09-21 19:40:20.324827120 -0700
++++ new/readconf.c	2016-09-21 19:25:47.885753634 -0700
+@@ -160,6 +160,7 @@ typedef enum {
  	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
  	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
  	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
@@ -714,7 +943,7 @@
  	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
  	oSendEnv, oControlPath, oControlMaster, oControlPersist,
  	oHashKnownHosts,
-@@ -199,11 +200,15 @@ static struct {
+@@ -211,11 +212,15 @@ static struct {
  	{ "gssauthentication", oGssAuthentication },                /* alias */
  	{ "gssapidelegatecredentials", oGssDelegateCreds },
  	{ "gssdelegatecreds", oGssDelegateCreds },                  /* alias */
@@ -730,7 +959,7 @@
  #endif
  	{ "fallbacktorsh", oDeprecated },
  	{ "usersh", oDeprecated },
-@@ -965,6 +970,10 @@ parse_time:
+@@ -1002,6 +1007,10 @@ parse_time:
  		intptr = &options->gss_authentication;
  		goto parse_flag;
  
@@ -741,7 +970,7 @@
  	case oGssDelegateCreds:
  		intptr = &options->gss_deleg_creds;
  		goto parse_flag;
-@@ -1694,6 +1703,7 @@ initialize_options(Options * options)
+@@ -1824,6 +1833,7 @@ initialize_options(Options * options)
  	options->pubkey_authentication = -1;
  	options->challenge_response_authentication = -1;
  	options->gss_authentication = -1;
@@ -749,7 +978,7 @@
  	options->gss_deleg_creds = -1;
  	options->password_authentication = -1;
  	options->kbd_interactive_authentication = -1;
-@@ -1834,6 +1844,12 @@ fill_default_options(Options * options)
+@@ -1979,6 +1989,12 @@ fill_default_options(Options * options)
  #else
  		options->gss_authentication = 0;
  #endif
@@ -762,9 +991,9 @@
  	if (options->gss_deleg_creds == -1)
  		options->gss_deleg_creds = 0;
  	if (options->password_authentication == -1)
-diff -pur old/readconf.h new/readconf.h
---- old/readconf.h
-+++ new/readconf.h
+diff -rupN old/readconf.h new/readconf.h
+--- old/readconf.h	2016-09-21 19:40:20.327689956 -0700
++++ new/readconf.h	2016-09-21 19:25:47.449284716 -0700
 @@ -45,6 +45,7 @@ typedef struct {
  	int     challenge_response_authentication;
  					/* Try S/Key or TIS, authentication. */
@@ -773,10 +1002,10 @@
  	int     gss_deleg_creds;	/* Delegate GSS credentials */
  	int     password_authentication;	/* Try password
  						 * authentication. */
-diff -pur old/servconf.c new/servconf.c
---- old/servconf.c
-+++ new/servconf.c
-@@ -117,6 +117,7 @@ initialize_server_options(ServerOptions
+diff -rupN old/servconf.c new/servconf.c
+--- old/servconf.c	2016-09-21 19:40:20.330699306 -0700
++++ new/servconf.c	2016-09-21 19:25:47.054209571 -0700
+@@ -117,6 +117,7 @@ initialize_server_options(ServerOptions 
  	options->kerberos_ticket_cleanup = -1;
  	options->kerberos_get_afs_token = -1;
  	options->gss_authentication=-1;
@@ -797,7 +1026,7 @@
  	if (options->gss_cleanup_creds == -1)
  		options->gss_cleanup_creds = 1;
  	if (options->gss_strict_acceptor == -1)
-@@ -449,6 +456,7 @@ typedef enum {
+@@ -457,6 +464,7 @@ typedef enum {
  	sHostbasedUsesNameFromPacketOnly, sHostbasedAcceptedKeyTypes,
  	sHostKeyAlgorithms,
  	sClientAliveInterval, sClientAliveCountMax, sAuthorizedKeysFile,
@@ -805,7 +1034,7 @@
  	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
  	sAcceptEnv, sPermitTunnel,
  	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
-@@ -526,6 +534,8 @@ static struct {
+@@ -534,6 +542,8 @@ static struct {
  #ifdef GSSAPI
  	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
  	{ "gssauthentication", sGssAuthentication, SSHCFG_ALL },   /* alias */
@@ -814,7 +1043,7 @@
  #ifdef USE_GSS_STORE_CRED
  	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
  #else /* USE_GSS_STORE_CRED */
-@@ -535,6 +545,8 @@ static struct {
+@@ -543,6 +553,8 @@ static struct {
  #else
  	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
  	{ "gssauthentication", sUnsupported, SSHCFG_ALL },          /* alias */
@@ -823,7 +1052,7 @@
  	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
  	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
  #endif
-@@ -1319,6 +1331,10 @@ process_server_config_line(ServerOptions
+@@ -1328,6 +1340,10 @@ process_server_config_line(ServerOptions
  		intptr = &options->gss_authentication;
  		goto parse_flag;
  
@@ -834,7 +1063,7 @@
  	case sGssCleanupCreds:
  		intptr = &options->gss_cleanup_creds;
  		goto parse_flag;
-@@ -2373,6 +2389,7 @@ dump_config(ServerOptions *o)
+@@ -2416,6 +2432,7 @@ dump_config(ServerOptions *o)
  #endif
  #ifdef GSSAPI
  	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
@@ -842,9 +1071,9 @@
  #ifndef USE_GSS_STORE_CRED
  	dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
  #endif /* !USE_GSS_STORE_CRED */
-diff -pur old/servconf.h new/servconf.h
---- old/servconf.h
-+++ new/servconf.h
+diff -rupN old/servconf.h new/servconf.h
+--- old/servconf.h	2016-09-21 19:40:20.333544958 -0700
++++ new/servconf.h	2016-09-21 19:25:47.739063955 -0700
 @@ -122,6 +122,7 @@ typedef struct {
  	int     kerberos_get_afs_token;		/* If true, try to get AFS token if
  						 * authenticated with Kerberos. */
@@ -853,9 +1082,9 @@
  	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
  	int     gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */
  	int     password_authentication;	/* If true, permit password
-diff -pur old/ssh-gss.h new/ssh-gss.h
---- old/ssh-gss.h
-+++ new/ssh-gss.h
+diff -rupN old/ssh-gss.h new/ssh-gss.h
+--- old/ssh-gss.h	2016-09-21 19:40:20.336386442 -0700
++++ new/ssh-gss.h	2016-09-21 19:25:47.600702960 -0700
 @@ -61,6 +61,17 @@
  
  #define SSH_GSS_OIDTYPE 0x06
@@ -903,9 +1132,9 @@
  #endif /* GSSAPI */
  
  #endif /* _SSH_GSS_H */
-diff -pur old/ssh_config.5 new/ssh_config.5
---- old/ssh_config.5
-+++ new/ssh_config.5
+diff -rupN old/ssh_config.5 new/ssh_config.5
+--- old/ssh_config.5	2016-09-21 19:40:20.339307715 -0700
++++ new/ssh_config.5	2016-09-21 19:25:47.188814608 -0700
 @@ -834,6 +834,12 @@ The default is
  Specifies whether user authentication based on GSSAPI is allowed.
  The default on Solaris is
@@ -919,10 +1148,10 @@
  .It Cm GSSAPIDelegateCredentials
  Forward (delegate) credentials to the server.
  The default is
-diff -pur old/sshconnect2.c new/sshconnect2.c
---- old/sshconnect2.c
-+++ new/sshconnect2.c
-@@ -164,11 +164,35 @@ ssh_kex2(char *host, struct sockaddr *ho
+diff -rupN old/sshconnect2.c new/sshconnect2.c
+--- old/sshconnect2.c	2016-09-21 19:40:20.342249196 -0700
++++ new/sshconnect2.c	2016-09-21 19:25:47.810679787 -0700
+@@ -165,11 +165,35 @@ ssh_kex2(char *host, struct sockaddr *ho
  	char *s;
  	struct kex *kex;
  	int r;
@@ -944,7 +1173,7 @@
 +		 * client to the key exchange algorithm proposal */
 +		orig = myproposal[PROPOSAL_KEX_ALGS];
 +
-+		gss_host = (char *)get_canonical_hostname(1);
++		gss_host = (char *)remote_hostname(active_state);
 +
 +		gss = ssh_gssapi_client_mechanisms(gss_host);
 +		if (gss) {
@@ -959,7 +1188,7 @@
  		fatal("%s: kex_names_cat", __func__);
  	myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(s);
  	myproposal[PROPOSAL_ENC_ALGS_CTOS] =
-@@ -199,6 +223,17 @@ ssh_kex2(char *host, struct sockaddr *ho
+@@ -196,6 +220,17 @@ ssh_kex2(char *host, struct sockaddr *ho
  		    order_hostkeyalgs(host, hostaddr, port));
  	}
  
@@ -1020,7 +1249,7 @@
  	{"gssapi-with-mic",
  		userauth_gssapi,
  		NULL,
-@@ -678,7 +732,10 @@ userauth_gssapi(Authctxt *authctxt)
+@@ -672,7 +726,10 @@ userauth_gssapi(Authctxt *authctxt)
  	 * once. */
  
  	if (gss_supported == NULL)
@@ -1032,7 +1261,7 @@
  
  	/* Check to see if the mechanism is usable before we offer it */
  	while (mech < gss_supported->count && !ok) {
-@@ -782,8 +839,8 @@ input_gssapi_response(int type, u_int32_
+@@ -776,8 +833,8 @@ input_gssapi_response(int type, u_int32_
  {
  	Authctxt *authctxt = ctxt;
  	Gssctxt *gssctxt;
@@ -1043,7 +1272,7 @@
  
  	if (authctxt == NULL)
  		fatal("input_gssapi_response: no authentication context");
-@@ -896,6 +953,48 @@ input_gssapi_error(int type, u_int32_t p
+@@ -890,6 +947,48 @@ input_gssapi_error(int type, u_int32_t p
  	free(lang);
  	return 0;
  }
@@ -1092,10 +1321,10 @@
  #endif /* GSSAPI */
  
  int
-diff -pur old/sshd.c new/sshd.c
---- old/sshd.c
-+++ new/sshd.c
-@@ -1833,10 +1833,13 @@ main(int ac, char **av)
+diff -rupN old/sshd.c new/sshd.c
+--- old/sshd.c	2016-09-21 19:40:20.345291027 -0700
++++ new/sshd.c	2016-09-21 19:25:47.376369649 -0700
+@@ -1892,10 +1892,13 @@ main(int ac, char **av)
  		logit("Disabling protocol version 1. Could not load host key");
  		options.protocol &= ~SSH_PROTO_1;
  	}
@@ -1109,7 +1338,7 @@
  	if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
  		logit("sshd: no hostkeys available -- exiting.");
  		exit(1);
-@@ -2596,6 +2599,48 @@ do_ssh2_kex(void)
+@@ -2656,6 +2659,48 @@ do_ssh2_kex(void)
  	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
  	    list_hostkey_types());
  
@@ -1158,7 +1387,7 @@
  	/* start key exchange */
  	if ((r = kex_setup(active_state, myproposal)) != 0)
  		fatal("kex_setup: %s", ssh_err(r));
-@@ -2610,6 +2655,13 @@ do_ssh2_kex(void)
+@@ -2673,6 +2718,13 @@ do_ssh2_kex(void)
  # endif
  #endif
  	kex->kex[KEX_C25519_SHA256] = kexc25519_server;
@@ -1172,10 +1401,10 @@
  	kex->server = 1;
  	kex->client_version_string=client_version_string;
  	kex->server_version_string=server_version_string;
-diff -pur old/sshd_config.5 new/sshd_config.5
---- old/sshd_config.5
-+++ new/sshd_config.5
-@@ -623,6 +623,11 @@ The default is
+diff -rupN old/sshd_config.5 new/sshd_config.5
+--- old/sshd_config.5	2016-09-21 19:40:20.348225013 -0700
++++ new/sshd_config.5	2016-09-21 19:25:47.433470021 -0700
+@@ -632,6 +632,11 @@ The default is
  Specifies whether user authentication based on GSSAPI is allowed.
  The default on Solaris is
  .Dq yes .
@@ -1187,9 +1416,9 @@
  .It Cm GSSAPICleanupCredentials
  Specifies whether to automatically destroy the user's credentials cache
  on logout.
-diff -pur old/sshkey.c new/sshkey.c
---- old/sshkey.c
-+++ new/sshkey.c
+diff -rupN old/sshkey.c new/sshkey.c
+--- old/sshkey.c	2016-09-21 19:40:20.351243462 -0700
++++ new/sshkey.c	2016-09-21 19:25:47.271519675 -0700
 @@ -115,6 +115,7 @@ static const struct keytype keytypes[] =
  #  endif /* OPENSSL_HAS_NISTP521 */
  # endif /* OPENSSL_HAS_ECC */
@@ -1198,9 +1427,9 @@
  	{ NULL, NULL, -1, -1, 0, 0 }
  };
  
-diff -pur old/sshkey.h new/sshkey.h
---- old/sshkey.h
-+++ new/sshkey.h
+diff -rupN old/sshkey.h new/sshkey.h
+--- old/sshkey.h	2016-09-21 19:40:20.354147713 -0700
++++ new/sshkey.h	2016-09-21 19:25:47.934179627 -0700
 @@ -62,6 +62,7 @@ enum sshkey_types {
  	KEY_DSA_CERT,
  	KEY_ECDSA_CERT,