[gsi-openssh/el6] Based on openssh-5.3p1-81.el6

Mattias Ellert ellert at fedoraproject.org
Tue Aug 14 07:28:06 UTC 2012


commit 34d8c1d226037806dfad2245ccee31ffc0bb6d43
Author: Mattias Ellert <mattias.ellert at fysast.uu.se>
Date:   Tue Aug 14 09:27:34 2012 +0200

    Based on openssh-5.3p1-81.el6

 gsi-openssh.spec                                   |   30 +-
 gsisshd.init                                       |   10 +-
 openssh-4.3p2-no-v6only.patch                      |   11 -
 openssh-5.3p1-gsissh.patch                         |  254 +++---
 openssh-5.3p1-linux-oomkiller.patch                |  164 ++++
 openssh-5.3p1-noslash.patch                        |   21 +
 ...3p1-prevent-post-auth-resource-exhaustion.patch |   13 +
 openssh-5.3p1-required-authentications.patch       |  832 ++++++++++++++++++++
 openssh-5.3p1-selabel.patch                        |    8 +-
 openssh-5.3p1-selinux-privsep.patch                |   50 ++
 openssh-5.3p1-sftp-chroot.patch                    |   21 +-
 openssh-5.3p1-v6only.patch                         |   18 +
 12 files changed, 1275 insertions(+), 157 deletions(-)
---
diff --git a/gsi-openssh.spec b/gsi-openssh.spec
index 1ab3e56..4cb4cdd 100644
--- a/gsi-openssh.spec
+++ b/gsi-openssh.spec
@@ -37,7 +37,7 @@
 Summary: An implementation of the SSH protocol with GSI authentication
 Name: gsi-openssh
 Version: 5.3p1
-Release: 5%{?dist}
+Release: 6%{?dist}
 Provides: gsissh = %{version}-%{release}
 Obsoletes: gsissh < 5.3p1-3
 URL: http://www.openssh.com/portable.html
@@ -66,7 +66,6 @@ Patch27: openssh-5.1p1-log-in-chroot.patch
 Patch30: openssh-4.0p1-exit-deadlock.patch
 Patch35: openssh-5.1p1-askpass-progress.patch
 Patch38: openssh-4.3p2-askpass-grab-info.patch
-Patch39: openssh-4.3p2-no-v6only.patch
 Patch44: openssh-5.2p1-allow-ip-opts.patch
 Patch49: openssh-4.3p2-gssapi-canohost.patch
 Patch51: openssh-5.3p1-nss-keys.patch
@@ -97,10 +96,22 @@ Patch91: openssh-5.3p1-manerr.patch
 Patch92: openssh-5.3p1-askpass-ld.patch
 # make aes-ctr ciphers use EVP engines such as AES-NI from OpenSSL
 Patch93: openssh-5.3p1-ctr-evp-fast.patch
+# adjust Linux out-of-memory killer (#744236)
+Patch94: openssh-5.3p1-linux-oomkiller.patch
+# add RequiredAuthentications (#657378)
+Patch95: openssh-5.3p1-required-authentications.patch
+# run privsep slave process as the users SELinux context (#798241)
+Patch96: openssh-5.3p1-selinux-privsep.patch
+# don't escape backslah in a banner (#809619)
+Patch97: openssh-5.3p1-noslash.patch
+# prevent post-auth resource exhaustion (#809938)
+Patch98: openssh-5.3p1-prevent-post-auth-resource-exhaustion.patch
+# use IPV6_V6ONLY also for channels (#732955)
+Patch99: openssh-5.3p1-v6only.patch
 
 # This is the patch that adds GSI support
 # Based on http://grid.ncsa.illinois.edu/ssh/dl/patch/openssh-5.3p1.patch
-Patch98: openssh-5.3p1-gsissh.patch
+Patch200: openssh-5.3p1-gsissh.patch
 
 License: BSD
 Group: Applications/Internet
@@ -219,7 +230,6 @@ This version of OpenSSH has been modified to support GSI authentication.
 %patch30 -p1 -b .exit-deadlock
 %patch35 -p1 -b .progress
 %patch38 -p1 -b .grab-info
-%patch39 -p1 -b .no-v6only
 %patch44 -p1 -b .ip-opts
 %patch49 -p1 -b .canohost
 %patch51 -p1 -b .nss-keys
@@ -251,7 +261,14 @@ This version of OpenSSH has been modified to support GSI authentication.
 %patch91 -p1 -b .manerr
 %patch92 -p1 -b .askpass-ld
 %patch93 -p1 -b .evp-ctr
-%patch98 -p1 -b .gsi
+%patch94 -p1 -b .oom-killer
+%patch95 -p1 -b .required-authentication
+%patch96 -p1 -b .privsep
+%patch97 -p1 -b .noslash
+%patch98 -p1 -b .postauth-exhaustion
+%patch99 -p1 -b .v6only
+
+%patch200 -p1 -b .gsi
 
 sed 's/sshd.pid/gsisshd.pid/' -i pathnames.h
 sed 's!$(piddir)/sshd.pid!$(piddir)/gsisshd.pid!' -i Makefile.in
@@ -454,6 +471,9 @@ fi
 %attr(0640,root,root) %config(noreplace) /etc/sysconfig/gsisshd
 
 %changelog
+* Tue Aug 14 2012 Mattias Ellert <mattias.ellert at fysast.uu.se> - 5.3p1-6
+- Based on openssh-5.3p1-81.el6
+
 * Wed Feb 08 2012 Mattias Ellert <mattias.ellert at fysast.uu.se> - 5.3p1-5
 - Based on openssh-5.3p1-70.el6_2.2
 
diff --git a/gsisshd.init b/gsisshd.init
index 9c3d5df..887ca53 100755
--- a/gsisshd.init
+++ b/gsisshd.init
@@ -45,8 +45,16 @@ PID_FILE=/var/run/gsisshd.pid
 
 runlevel=$(set -- $(runlevel); eval "echo \$$#" )
 
+fips_enabled() {
+	if [ -r /proc/sys/crypto/fips_enabled ]; then
+		cat /proc/sys/crypto/fips_enabled
+	else
+		echo 0
+	fi
+}
+
 do_rsa1_keygen() {
-	if [ ! -s $RSA1_KEY ]; then
+	if [ ! -s $RSA1_KEY -a `fips_enabled` -eq 0 ]; then
 		echo -n $"Generating SSH1 RSA host key: "
 		rm -f $RSA1_KEY
 		if test ! -f $RSA1_KEY && $KEYGEN -q -t rsa1 -f $RSA1_KEY -C '' -N '' >&/dev/null; then
diff --git a/openssh-5.3p1-gsissh.patch b/openssh-5.3p1-gsissh.patch
index 298fe8c..5c0d689 100644
--- a/openssh-5.3p1-gsissh.patch
+++ b/openssh-5.3p1-gsissh.patch
@@ -1,6 +1,6 @@
 diff -Nur openssh-5.3p1.orig/auth2.c openssh-5.3p1/auth2.c
---- openssh-5.3p1.orig/auth2.c	2011-08-12 08:52:47.301701689 +0200
-+++ openssh-5.3p1/auth2.c	2011-08-12 08:53:52.205703508 +0200
+--- openssh-5.3p1.orig/auth2.c	2012-08-14 08:39:57.180580380 +0200
++++ openssh-5.3p1/auth2.c	2012-08-14 08:41:07.411697289 +0200
 @@ -229,7 +229,27 @@
  	user = packet_get_string(NULL);
  	service = packet_get_string(NULL);
@@ -97,8 +97,8 @@ diff -Nur openssh-5.3p1.orig/auth2.c openssh-5.3p1/auth2.c
  		    authctxt->user, authctxt->service, user, service);
  	}
 diff -Nur openssh-5.3p1.orig/auth2-gss.c openssh-5.3p1/auth2-gss.c
---- openssh-5.3p1.orig/auth2-gss.c	2011-08-12 08:52:47.223701687 +0200
-+++ openssh-5.3p1/auth2-gss.c	2011-08-12 08:53:52.205703508 +0200
+--- openssh-5.3p1.orig/auth2-gss.c	2012-08-14 08:39:57.181580368 +0200
++++ openssh-5.3p1/auth2-gss.c	2012-08-14 08:41:07.412697277 +0200
 @@ -47,6 +47,7 @@
  
  extern ServerOptions options;
@@ -256,7 +256,7 @@ diff -Nur openssh-5.3p1.orig/auth2-gss.c openssh-5.3p1/auth2-gss.c
  		logit("GSSAPI MIC check failed");
  
 @@ -339,6 +398,23 @@
- 	userauth_finish(authctxt, authenticated, "gssapi-with-mic");
+ 	userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
  }
  
 +static void ssh_gssapi_userauth_error(Gssctxt *ctxt) {
@@ -280,8 +280,8 @@ diff -Nur openssh-5.3p1.orig/auth2-gss.c openssh-5.3p1/auth2-gss.c
  	"gssapi-keyex",
  	userauth_gsskeyex,
 diff -Nur openssh-5.3p1.orig/auth.c openssh-5.3p1/auth.c
---- openssh-5.3p1.orig/auth.c	2008-11-05 06:12:54.000000000 +0100
-+++ openssh-5.3p1/auth.c	2011-08-12 08:53:52.251703501 +0200
+--- openssh-5.3p1.orig/auth.c	2012-08-14 08:39:57.182580356 +0200
++++ openssh-5.3p1/auth.c	2012-08-14 08:41:07.436696971 +0200
 @@ -71,6 +71,9 @@
  #endif
  #include "monitor_wrap.h"
@@ -292,9 +292,9 @@ diff -Nur openssh-5.3p1.orig/auth.c openssh-5.3p1/auth.c
  /* import */
  extern ServerOptions options;
  extern int use_privsep;
-@@ -269,7 +272,8 @@
- 	    authmsg,
+@@ -271,7 +274,8 @@
  	    method,
+ 	    submethod == NULL ? "" : "/", submethod == NULL ? "" : submethod,
  	    authctxt->valid ? "" : "invalid user ",
 -	    authctxt->user,
 +	    (authctxt->user && authctxt->user[0]) ?
@@ -302,7 +302,7 @@ diff -Nur openssh-5.3p1.orig/auth.c openssh-5.3p1/auth.c
  	    get_remote_ipaddr(),
  	    get_remote_port(),
  	    info);
-@@ -291,6 +295,21 @@
+@@ -293,6 +297,21 @@
  	if (authenticated == 0 && !authctxt->postponed)
  		audit_event(audit_classify_auth(method));
  #endif
@@ -324,7 +324,7 @@ diff -Nur openssh-5.3p1.orig/auth.c openssh-5.3p1/auth.c
  }
  
  /*
-@@ -325,7 +344,7 @@
+@@ -327,7 +346,7 @@
   *
   * This returns a buffer allocated by xmalloc.
   */
@@ -333,7 +333,7 @@ diff -Nur openssh-5.3p1.orig/auth.c openssh-5.3p1/auth.c
  expand_authorized_keys(const char *filename, struct passwd *pw)
  {
  	char *file, ret[MAXPATHLEN];
-@@ -526,9 +545,14 @@
+@@ -528,9 +547,14 @@
  	    get_canonical_hostname(options.use_dns), get_remote_ipaddr());
  
  	pw = getpwnam(user);
@@ -350,19 +350,19 @@ diff -Nur openssh-5.3p1.orig/auth.c openssh-5.3p1/auth.c
  		record_failed_login(user,
  		    get_canonical_hostname(options.use_dns), "ssh");
 diff -Nur openssh-5.3p1.orig/auth.h openssh-5.3p1/auth.h
---- openssh-5.3p1.orig/auth.h	2011-08-12 08:52:47.303701689 +0200
-+++ openssh-5.3p1/auth.h	2011-08-12 08:53:52.251703501 +0200
-@@ -149,6 +149,7 @@
- void	userauth_finish(Authctxt *, int, char *);
- void	userauth_send_banner(const char *);
- int	auth_root_allowed(char *);
+--- openssh-5.3p1.orig/auth.h	2012-08-14 08:39:57.182580356 +0200
++++ openssh-5.3p1/auth.h	2012-08-14 08:46:39.092526709 +0200
+@@ -148,6 +148,7 @@
+ void	auth_log(Authctxt *, int, const char *, const char *, const char *);
+ void	userauth_finish(Authctxt *, int, const char *, const char *);
+ int	auth_root_allowed(const char *);
 +char	*expand_authorized_keys(const char *filename, struct passwd *pw);
  
- char	*auth2_read_banner(void);
+ void	userauth_send_banner(const char *);
  
 diff -Nur openssh-5.3p1.orig/auth-pam.c openssh-5.3p1/auth-pam.c
---- openssh-5.3p1.orig/auth-pam.c	2011-08-12 08:52:47.099701683 +0200
-+++ openssh-5.3p1/auth-pam.c	2011-08-12 08:53:52.252703501 +0200
+--- openssh-5.3p1.orig/auth-pam.c	2012-08-14 08:39:56.995582706 +0200
++++ openssh-5.3p1/auth-pam.c	2012-08-14 08:41:07.478696447 +0200
 @@ -122,6 +122,10 @@
   */
  typedef pthread_t sp_pthread_t;
@@ -493,8 +493,8 @@ diff -Nur openssh-5.3p1.orig/auth-pam.c openssh-5.3p1/auth-pam.c
  	if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
  		debug("PAM: password authentication accepted for %.100s",
 diff -Nur openssh-5.3p1.orig/auth-pam.h openssh-5.3p1/auth-pam.h
---- openssh-5.3p1.orig/auth-pam.h	2011-08-12 08:52:47.098701683 +0200
-+++ openssh-5.3p1/auth-pam.h	2011-08-12 08:53:52.252703501 +0200
+--- openssh-5.3p1.orig/auth-pam.h	2012-08-14 08:39:56.994582718 +0200
++++ openssh-5.3p1/auth-pam.h	2012-08-14 08:41:07.478696447 +0200
 @@ -46,5 +46,6 @@
  void sshpam_cleanup(void);
  int sshpam_auth_passwd(Authctxt *, const char *);
@@ -503,8 +503,8 @@ diff -Nur openssh-5.3p1.orig/auth-pam.h openssh-5.3p1/auth-pam.h
  
  #endif /* USE_PAM */
 diff -Nur openssh-5.3p1.orig/canohost.c openssh-5.3p1/canohost.c
---- openssh-5.3p1.orig/canohost.c	2011-08-12 08:52:47.143701685 +0200
-+++ openssh-5.3p1/canohost.c	2011-08-12 08:53:52.253703501 +0200
+--- openssh-5.3p1.orig/canohost.c	2012-08-14 08:39:57.019582404 +0200
++++ openssh-5.3p1/canohost.c	2012-08-14 08:41:07.479696435 +0200
 @@ -16,6 +16,7 @@
  
  #include <sys/types.h>
@@ -549,7 +549,7 @@ diff -Nur openssh-5.3p1.orig/canohost.c openssh-5.3p1/canohost.c
 +}
 diff -Nur openssh-5.3p1.orig/canohost.h openssh-5.3p1/canohost.h
 --- openssh-5.3p1.orig/canohost.h	2009-06-21 11:50:08.000000000 +0200
-+++ openssh-5.3p1/canohost.h	2011-08-12 08:53:52.253703501 +0200
++++ openssh-5.3p1/canohost.h	2012-08-14 08:41:07.479696435 +0200
 @@ -26,4 +26,6 @@
  int		 get_sock_port(int, int);
  void		 clear_cached_addr(void);
@@ -558,9 +558,9 @@ diff -Nur openssh-5.3p1.orig/canohost.h openssh-5.3p1/canohost.h
 +
  void		 ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
 diff -Nur openssh-5.3p1.orig/configure.ac openssh-5.3p1/configure.ac
---- openssh-5.3p1.orig/configure.ac	2011-08-12 08:52:47.361701691 +0200
-+++ openssh-5.3p1/configure.ac	2011-08-12 08:53:52.254703501 +0200
-@@ -3642,6 +3642,14 @@
+--- openssh-5.3p1.orig/configure.ac	2012-08-14 08:39:57.175580443 +0200
++++ openssh-5.3p1/configure.ac	2012-08-14 08:41:07.480696423 +0200
+@@ -3643,6 +3643,14 @@
  			AC_CHECK_HEADER(gssapi_krb5.h, ,
  					[ CPPFLAGS="$oldCPP" ])
  
@@ -575,7 +575,7 @@ diff -Nur openssh-5.3p1.orig/configure.ac openssh-5.3p1/configure.ac
  		fi
  		if test ! -z "$need_dash_r" ; then
  			LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib"
-@@ -3661,6 +3669,50 @@
+@@ -3662,6 +3670,50 @@
  	]
  )
  
@@ -626,7 +626,7 @@ diff -Nur openssh-5.3p1.orig/configure.ac openssh-5.3p1/configure.ac
  # Check whether user wants NSS support
  LIBNSS_MSG="no"
  AC_ARG_WITH(nss,
-@@ -3670,7 +3722,7 @@
+@@ -3671,7 +3723,7 @@
  		LIBNSS_MSG="yes"
  		CPPFLAGS="$CPPFLAGS -I/usr/include/nss3 -I/usr/include/nspr4"
  		AC_CHECK_HEADERS(pk11pub.h)
@@ -636,8 +636,8 @@ diff -Nur openssh-5.3p1.orig/configure.ac openssh-5.3p1/configure.ac
  	fi
  	])
 diff -Nur openssh-5.3p1.orig/gss-genr.c openssh-5.3p1/gss-genr.c
---- openssh-5.3p1.orig/gss-genr.c	2011-08-12 08:52:47.231701687 +0200
-+++ openssh-5.3p1/gss-genr.c	2011-08-12 08:53:52.256703501 +0200
+--- openssh-5.3p1.orig/gss-genr.c	2012-08-14 08:39:57.068581789 +0200
++++ openssh-5.3p1/gss-genr.c	2012-08-14 08:41:07.481696410 +0200
 @@ -38,6 +38,7 @@
  #include "xmalloc.h"
  #include "buffer.h"
@@ -675,8 +675,8 @@ diff -Nur openssh-5.3p1.orig/gss-genr.c openssh-5.3p1/gss-genr.c
  	return (ctx->major);
  }
 diff -Nur openssh-5.3p1.orig/gss-serv.c openssh-5.3p1/gss-serv.c
---- openssh-5.3p1.orig/gss-serv.c	2011-08-12 08:52:47.232701687 +0200
-+++ openssh-5.3p1/gss-serv.c	2011-08-12 08:53:52.257703501 +0200
+--- openssh-5.3p1.orig/gss-serv.c	2012-08-14 08:39:57.191580243 +0200
++++ openssh-5.3p1/gss-serv.c	2012-08-14 08:41:07.482696397 +0200
 @@ -52,6 +52,7 @@
  #include "monitor_wrap.h"
  
@@ -748,7 +748,7 @@ diff -Nur openssh-5.3p1.orig/gss-serv.c openssh-5.3p1/gss-serv.c
  	/*
  	 * Check that ename is long enough for all of the fixed length
  	 * header, and that the initial ID bytes are correct
-@@ -296,8 +322,11 @@
+@@ -298,8 +324,11 @@
  			return GSS_S_COMPLETE;
  		}
  
@@ -762,7 +762,7 @@ diff -Nur openssh-5.3p1.orig/gss-serv.c openssh-5.3p1/gss-serv.c
  		    NULL, NULL, NULL))) {
  			ssh_gssapi_error(ctx);
  			return (ctx->major);
-@@ -340,9 +369,12 @@
+@@ -342,9 +371,12 @@
  	if (client->mech == NULL)
  		return GSS_S_FAILURE;
  
@@ -777,7 +777,7 @@ diff -Nur openssh-5.3p1.orig/gss-serv.c openssh-5.3p1/gss-serv.c
  		ssh_gssapi_error(ctx);
  		return (ctx->major);
  	}
-@@ -369,6 +401,10 @@
+@@ -371,6 +403,10 @@
  	/* We can't copy this structure, so we just move the pointer to it */
  	client->creds = ctx->client_creds;
  	ctx->client_creds = GSS_C_NO_CREDENTIAL;
@@ -788,7 +788,7 @@ diff -Nur openssh-5.3p1.orig/gss-serv.c openssh-5.3p1/gss-serv.c
  	return (ctx->major);
  }
  
-@@ -389,6 +425,11 @@
+@@ -391,6 +427,11 @@
  ssh_gssapi_storecreds(void)
  {
  	if (gssapi_client.mech && gssapi_client.mech->storecreds) {
@@ -800,7 +800,7 @@ diff -Nur openssh-5.3p1.orig/gss-serv.c openssh-5.3p1/gss-serv.c
  		(*gssapi_client.mech->storecreds)(&gssapi_client);
  	} else
  		debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
-@@ -413,7 +454,7 @@
+@@ -415,7 +456,7 @@
  
  /* Privileged */
  int
@@ -809,7 +809,7 @@ diff -Nur openssh-5.3p1.orig/gss-serv.c openssh-5.3p1/gss-serv.c
  {
  	OM_uint32 lmin;
  
-@@ -422,6 +463,12 @@
+@@ -424,6 +465,12 @@
  		debug("No suitable client data");
  		return 0;
  	}
@@ -822,7 +822,7 @@ diff -Nur openssh-5.3p1.orig/gss-serv.c openssh-5.3p1/gss-serv.c
  	if (gssapi_client.mech && gssapi_client.mech->userok)
  		if ((*gssapi_client.mech->userok)(&gssapi_client, user)) {
  			gssapi_client.used = 1;
-@@ -440,6 +487,24 @@
+@@ -442,6 +489,24 @@
  	return (0);
  }
  
@@ -847,7 +847,7 @@ diff -Nur openssh-5.3p1.orig/gss-serv.c openssh-5.3p1/gss-serv.c
  /* These bits are only used for rekeying. The unpriviledged child is running 
   * as the user, the monitor is root.
   *
-@@ -466,6 +531,7 @@
+@@ -468,6 +533,7 @@
  	pam_handle_t *pamh = NULL;
  	struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL};
  	char *envstr;
@@ -855,7 +855,7 @@ diff -Nur openssh-5.3p1.orig/gss-serv.c openssh-5.3p1/gss-serv.c
  #endif
  
  	if (gssapi_client.store.filename == NULL && 
-@@ -495,6 +561,18 @@
+@@ -497,6 +563,18 @@
  	if (ret)
  		return;
  
@@ -874,7 +874,7 @@ diff -Nur openssh-5.3p1.orig/gss-serv.c openssh-5.3p1/gss-serv.c
  	xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, 
  	    gssapi_client.store.envval);
  
-@@ -526,4 +604,12 @@
+@@ -528,4 +606,12 @@
  	return ok;
  }
  
@@ -889,7 +889,7 @@ diff -Nur openssh-5.3p1.orig/gss-serv.c openssh-5.3p1/gss-serv.c
  #endif
 diff -Nur openssh-5.3p1.orig/gss-serv-gsi.c openssh-5.3p1/gss-serv-gsi.c
 --- openssh-5.3p1.orig/gss-serv-gsi.c	1970-01-01 01:00:00.000000000 +0100
-+++ openssh-5.3p1/gss-serv-gsi.c	2011-08-12 08:53:52.257703501 +0200
++++ openssh-5.3p1/gss-serv-gsi.c	2012-08-14 08:41:07.482696397 +0200
 @@ -0,0 +1,238 @@
 +/*
 + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
@@ -1130,8 +1130,8 @@ diff -Nur openssh-5.3p1.orig/gss-serv-gsi.c openssh-5.3p1/gss-serv-gsi.c
 +#endif /* GSI */
 +#endif /* GSSAPI */
 diff -Nur openssh-5.3p1.orig/gss-serv-krb5.c openssh-5.3p1/gss-serv-krb5.c
---- openssh-5.3p1.orig/gss-serv-krb5.c	2011-08-12 08:52:47.340701691 +0200
-+++ openssh-5.3p1/gss-serv-krb5.c	2011-08-12 08:53:52.258703501 +0200
+--- openssh-5.3p1.orig/gss-serv-krb5.c	2012-08-14 08:39:57.126581059 +0200
++++ openssh-5.3p1/gss-serv-krb5.c	2012-08-14 08:41:07.483696384 +0200
 @@ -109,7 +109,35 @@
  	return retval;
  }
@@ -1187,8 +1187,8 @@ diff -Nur openssh-5.3p1.orig/gss-serv-krb5.c openssh-5.3p1/gss-serv-krb5.c
  	&ssh_gssapi_krb5_updatecreds
  };
 diff -Nur openssh-5.3p1.orig/kexgsss.c openssh-5.3p1/kexgsss.c
---- openssh-5.3p1.orig/kexgsss.c	2011-08-12 08:52:47.236701687 +0200
-+++ openssh-5.3p1/kexgsss.c	2011-08-12 08:53:52.259703501 +0200
+--- openssh-5.3p1.orig/kexgsss.c	2012-08-14 08:39:57.071581750 +0200
++++ openssh-5.3p1/kexgsss.c	2012-08-14 08:41:07.483696384 +0200
 @@ -44,6 +44,7 @@
  #include "monitor_wrap.h"
  #include "servconf.h"
@@ -1250,7 +1250,7 @@ diff -Nur openssh-5.3p1.orig/kexgsss.c openssh-5.3p1/kexgsss.c
  #endif /* GSSAPI */
 diff -Nur openssh-5.3p1.orig/LICENSE.globus_usage openssh-5.3p1/LICENSE.globus_usage
 --- openssh-5.3p1.orig/LICENSE.globus_usage	1970-01-01 01:00:00.000000000 +0100
-+++ openssh-5.3p1/LICENSE.globus_usage	2011-08-12 08:53:52.260703501 +0200
++++ openssh-5.3p1/LICENSE.globus_usage	2012-08-14 08:41:07.483696384 +0200
 @@ -0,0 +1,18 @@
 +/*
 + * Portions of the Usage Metrics suport code are derived from the
@@ -1271,8 +1271,8 @@ diff -Nur openssh-5.3p1.orig/LICENSE.globus_usage openssh-5.3p1/LICENSE.globus_u
 + * limitations under the License.
 + */
 diff -Nur openssh-5.3p1.orig/Makefile.in openssh-5.3p1/Makefile.in
---- openssh-5.3p1.orig/Makefile.in	2011-08-12 08:52:47.381701691 +0200
-+++ openssh-5.3p1/Makefile.in	2011-08-12 08:53:52.262703501 +0200
+--- openssh-5.3p1.orig/Makefile.in	2012-08-14 08:39:57.199580142 +0200
++++ openssh-5.3p1/Makefile.in	2012-08-14 08:41:07.484696371 +0200
 @@ -91,8 +91,10 @@
  	monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \
  	auth-krb5.o audit-linux.o \
@@ -1285,8 +1285,8 @@ diff -Nur openssh-5.3p1.orig/Makefile.in openssh-5.3p1/Makefile.in
  
  MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out ssh-ldap-helper.8.out sshd_config.5.out ssh_config.5.out ssh-ldap.conf.5.out
 diff -Nur openssh-5.3p1.orig/misc.c openssh-5.3p1/misc.c
---- openssh-5.3p1.orig/misc.c	2011-08-12 08:52:47.089701683 +0200
-+++ openssh-5.3p1/misc.c	2011-08-12 08:53:52.263703501 +0200
+--- openssh-5.3p1.orig/misc.c	2012-08-14 08:39:56.989582782 +0200
++++ openssh-5.3p1/misc.c	2012-08-14 08:41:07.484696371 +0200
 @@ -155,11 +155,14 @@
  #define WHITESPACE " \t\r\n"
  #define QUOTE	"\""
@@ -1348,7 +1348,7 @@ diff -Nur openssh-5.3p1.orig/misc.c openssh-5.3p1/misc.c
   * Port must be >=0 and <=65535.
 diff -Nur openssh-5.3p1.orig/misc.h openssh-5.3p1/misc.h
 --- openssh-5.3p1.orig/misc.h	2008-06-12 22:42:45.000000000 +0200
-+++ openssh-5.3p1/misc.h	2011-08-12 08:53:52.263703501 +0200
++++ openssh-5.3p1/misc.h	2012-08-14 08:41:07.485696359 +0200
 @@ -37,6 +37,7 @@
  void	 ms_to_timeval(struct timeval *, int);
  
@@ -1358,8 +1358,8 @@ diff -Nur openssh-5.3p1.orig/misc.h openssh-5.3p1/misc.h
  
  typedef struct arglist arglist;
 diff -Nur openssh-5.3p1.orig/monitor.c openssh-5.3p1/monitor.c
---- openssh-5.3p1.orig/monitor.c	2011-08-12 08:52:47.320701689 +0200
-+++ openssh-5.3p1/monitor.c	2011-08-12 08:53:52.266703501 +0200
+--- openssh-5.3p1.orig/monitor.c	2012-08-14 08:39:57.183580343 +0200
++++ openssh-5.3p1/monitor.c	2012-08-14 08:53:21.123477167 +0200
 @@ -179,6 +179,9 @@
  int mm_answer_gss_userok(int, Buffer *);
  int mm_answer_gss_checkmic(int, Buffer *);
@@ -1370,7 +1370,7 @@ diff -Nur openssh-5.3p1.orig/monitor.c openssh-5.3p1/monitor.c
  int mm_answer_gss_updatecreds(int, Buffer *);
  #endif
  
-@@ -224,7 +227,7 @@
+@@ -225,7 +228,7 @@
  struct mon_table mon_dispatch_proto20[] = {
      {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli},
      {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
@@ -1379,7 +1379,7 @@ diff -Nur openssh-5.3p1.orig/monitor.c openssh-5.3p1/monitor.c
      {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
  #ifdef WITH_SELINUX
      {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
-@@ -232,7 +235,7 @@
+@@ -233,7 +236,7 @@
      {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
      {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
  #ifdef USE_PAM
@@ -1388,7 +1388,7 @@ diff -Nur openssh-5.3p1.orig/monitor.c openssh-5.3p1/monitor.c
      {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
      {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
      {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
-@@ -262,6 +265,9 @@
+@@ -263,6 +266,9 @@
      {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
      {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic},
      {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
@@ -1398,7 +1398,7 @@ diff -Nur openssh-5.3p1.orig/monitor.c openssh-5.3p1/monitor.c
  #endif
  #ifdef JPAKE
      {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
-@@ -278,6 +284,8 @@
+@@ -279,6 +285,8 @@
      {MONITOR_REQ_GSSSETUP, 0, mm_answer_gss_setup_ctx},
      {MONITOR_REQ_GSSSTEP, 0, mm_answer_gss_accept_ctx},
      {MONITOR_REQ_GSSSIGN, 0, mm_answer_gss_sign},
@@ -1407,7 +1407,7 @@ diff -Nur openssh-5.3p1.orig/monitor.c openssh-5.3p1/monitor.c
      {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
  #endif
      {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
-@@ -315,7 +323,7 @@
+@@ -316,7 +324,7 @@
      {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
  #endif
  #ifdef USE_PAM
@@ -1416,7 +1416,7 @@ diff -Nur openssh-5.3p1.orig/monitor.c openssh-5.3p1/monitor.c
      {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account},
      {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx},
      {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query},
-@@ -401,6 +409,8 @@
+@@ -404,6 +412,8 @@
  #ifdef GSSAPI
  		/* and for the GSSAPI key exchange */
  		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
@@ -1425,7 +1425,7 @@ diff -Nur openssh-5.3p1.orig/monitor.c openssh-5.3p1/monitor.c
  #endif
  	} else {
  		mon_dispatch = mon_dispatch_proto15;
-@@ -491,6 +501,8 @@
+@@ -507,6 +517,8 @@
  #ifdef GSSAPI
  		/* and for the GSSAPI key exchange */
  		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
@@ -1434,7 +1434,7 @@ diff -Nur openssh-5.3p1.orig/monitor.c openssh-5.3p1/monitor.c
  #endif		
  	} else {
  		mon_dispatch = mon_dispatch_postauth15;
-@@ -684,14 +696,17 @@
+@@ -700,14 +712,17 @@
  
  	debug3("%s", __func__);
  
@@ -1455,7 +1455,7 @@ diff -Nur openssh-5.3p1.orig/monitor.c openssh-5.3p1/monitor.c
  	setproctitle("%s [priv]", pwent ? username : "unknown");
  	xfree(username);
  
-@@ -2150,12 +2165,15 @@
+@@ -2179,12 +2194,15 @@
  mm_answer_gss_userok(int sock, Buffer *m)
  {
  	int authenticated;
@@ -1472,7 +1472,7 @@ diff -Nur openssh-5.3p1.orig/monitor.c openssh-5.3p1/monitor.c
  
  	buffer_clear(m);
  	buffer_put_int(m, authenticated);
-@@ -2163,12 +2181,77 @@
+@@ -2192,13 +2210,78 @@
  	debug3("%s: sending result %d", __func__, authenticated);
  	mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m);
  
@@ -1481,6 +1481,7 @@ diff -Nur openssh-5.3p1.orig/monitor.c openssh-5.3p1/monitor.c
 +		auth_method = "gssapi-keyex";
 +	else
 +		auth_method = "gssapi-with-mic";
+ 	auth_submethod = NULL;
  
  	/* Monitor loop will terminate if authenticated */
  	return (authenticated);
@@ -1552,8 +1553,8 @@ diff -Nur openssh-5.3p1.orig/monitor.c openssh-5.3p1/monitor.c
  mm_answer_gss_sign(int socket, Buffer *m)
  {
 diff -Nur openssh-5.3p1.orig/monitor.h openssh-5.3p1/monitor.h
---- openssh-5.3p1.orig/monitor.h	2011-08-12 08:52:47.321701689 +0200
-+++ openssh-5.3p1/monitor.h	2011-08-12 08:53:52.267703501 +0200
+--- openssh-5.3p1.orig/monitor.h	2012-08-14 08:39:57.114581209 +0200
++++ openssh-5.3p1/monitor.h	2012-08-14 08:41:07.487696335 +0200
 @@ -55,6 +55,9 @@
  	MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP,
  	MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
@@ -1565,8 +1566,8 @@ diff -Nur openssh-5.3p1.orig/monitor.h openssh-5.3p1/monitor.h
  	MONITOR_REQ_GSSSIGN, MONITOR_ANS_GSSSIGN,
  	MONITOR_REQ_GSSUPCREDS, MONITOR_ANS_GSSUPCREDS,
 diff -Nur openssh-5.3p1.orig/monitor_wrap.c openssh-5.3p1/monitor_wrap.c
---- openssh-5.3p1.orig/monitor_wrap.c	2011-08-12 08:52:47.322701689 +0200
-+++ openssh-5.3p1/monitor_wrap.c	2011-08-12 08:53:52.268703501 +0200
+--- openssh-5.3p1.orig/monitor_wrap.c	2012-08-14 08:39:57.115581197 +0200
++++ openssh-5.3p1/monitor_wrap.c	2012-08-14 08:41:07.487696335 +0200
 @@ -1340,12 +1340,13 @@
  }
  
@@ -1667,8 +1668,8 @@ diff -Nur openssh-5.3p1.orig/monitor_wrap.c openssh-5.3p1/monitor_wrap.c
  mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash)
  {
 diff -Nur openssh-5.3p1.orig/monitor_wrap.h openssh-5.3p1/monitor_wrap.h
---- openssh-5.3p1.orig/monitor_wrap.h	2011-08-12 08:52:47.323701689 +0200
-+++ openssh-5.3p1/monitor_wrap.h	2011-08-12 08:53:52.268703501 +0200
+--- openssh-5.3p1.orig/monitor_wrap.h	2012-08-14 08:39:57.115581197 +0200
++++ openssh-5.3p1/monitor_wrap.h	2012-08-14 08:41:07.488696322 +0200
 @@ -61,9 +61,13 @@
  OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
  OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *,
@@ -1685,8 +1686,8 @@ diff -Nur openssh-5.3p1.orig/monitor_wrap.h openssh-5.3p1/monitor_wrap.h
  #endif
  
 diff -Nur openssh-5.3p1.orig/readconf.c openssh-5.3p1/readconf.c
---- openssh-5.3p1.orig/readconf.c	2011-08-12 08:52:47.244701687 +0200
-+++ openssh-5.3p1/readconf.c	2011-08-12 08:53:52.269703501 +0200
+--- openssh-5.3p1.orig/readconf.c	2012-08-14 08:39:57.075581701 +0200
++++ openssh-5.3p1/readconf.c	2012-08-14 08:41:07.488696322 +0200
 @@ -1168,13 +1168,13 @@
  	if (options->challenge_response_authentication == -1)
  		options->challenge_response_authentication = 1;
@@ -1706,8 +1707,8 @@ diff -Nur openssh-5.3p1.orig/readconf.c openssh-5.3p1/readconf.c
  		options->gss_renewal_rekey = 0;
  	if (options->password_authentication == -1)
 diff -Nur openssh-5.3p1.orig/readconf.h openssh-5.3p1/readconf.h
---- openssh-5.3p1.orig/readconf.h	2011-08-12 08:52:47.245701687 +0200
-+++ openssh-5.3p1/readconf.h	2011-08-12 08:53:52.269703501 +0200
+--- openssh-5.3p1.orig/readconf.h	2012-08-14 08:39:57.075581701 +0200
++++ openssh-5.3p1/readconf.h	2012-08-14 08:41:07.489696309 +0200
 @@ -80,6 +80,8 @@
  	char   *host_key_alias;	/* hostname alias for .ssh/known_hosts */
  	char   *proxy_command;	/* Proxy command for connecting the host. */
@@ -1718,9 +1719,9 @@ diff -Nur openssh-5.3p1.orig/readconf.h openssh-5.3p1/readconf.h
  
  	char   *system_hostfile;/* Path for /etc/ssh/ssh_known_hosts. */
 diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
---- openssh-5.3p1.orig/servconf.c	2011-08-12 08:52:47.341701691 +0200
-+++ openssh-5.3p1/servconf.c	2011-08-12 08:53:52.271703501 +0200
-@@ -58,6 +58,7 @@
+--- openssh-5.3p1.orig/servconf.c	2012-08-14 08:39:57.184580330 +0200
++++ openssh-5.3p1/servconf.c	2012-08-14 08:47:45.684690246 +0200
+@@ -60,6 +60,7 @@
  
  	/* Portable-specific options */
  	options->use_pam = -1;
@@ -1728,7 +1729,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  
  	/* Standard Options */
  	options->num_ports = 0;
-@@ -92,9 +93,11 @@
+@@ -94,9 +95,11 @@
  	options->kerberos_ticket_cleanup = -1;
  	options->kerberos_get_afs_token = -1;
  	options->gss_authentication=-1;
@@ -1740,7 +1741,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  	options->gss_store_rekey = -1;
  	options->password_authentication = -1;
  	options->kbd_interactive_authentication = -1;
-@@ -135,6 +138,8 @@
+@@ -139,6 +142,8 @@
  	options->authorized_keys_command_runas = NULL;
  	options->zero_knowledge_password_authentication = -1;
  	options->use_kuserok = -1;
@@ -1749,7 +1750,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  }
  
  void
-@@ -143,6 +148,8 @@
+@@ -147,6 +152,8 @@
  	/* Portable-specific options */
  	if (options->use_pam == -1)
  		options->use_pam = 0;
@@ -1758,7 +1759,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  
  	/* Standard Options */
  	if (options->protocol == SSH_PROTO_UNKNOWN)
-@@ -216,13 +223,17 @@
+@@ -220,13 +227,17 @@
  	if (options->kerberos_get_afs_token == -1)
  		options->kerberos_get_afs_token = 0;
  	if (options->gss_authentication == -1)
@@ -1778,7 +1779,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  	if (options->gss_store_rekey == -1)
  		options->gss_store_rekey = 0;
  	if (options->password_authentication == -1)
-@@ -299,7 +310,7 @@
+@@ -303,7 +314,7 @@
  typedef enum {
  	sBadOption,		/* == unknown option */
  	/* Portable-specific options */
@@ -1787,7 +1788,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  	/* Standard Options */
  	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
  	sPermitRootLogin, sLogFacility, sLogLevel,
-@@ -320,11 +331,15 @@
+@@ -324,12 +335,16 @@
  	sBanner, sShowPatchLevel, sUseDNS, sHostbasedAuthentication,
  	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
  	sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
@@ -1797,13 +1798,14 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
  	sGssKeyEx, sGssStoreRekey,
  	sAcceptEnv, sPermitTunnel,
+ 	sRequiredAuthentications1, sRequiredAuthentications2,
  	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
  	sUsePrivilegeSeparation, sAllowAgentForwarding,
 +	sDisUsageStats, sUsageStatsTarg,
  	sZeroKnowledgePasswordAuthentication,
  	sAuthorizedKeysCommand, sAuthorizedKeysCommandRunAs,
  	sDeprecated, sUnsupported
-@@ -343,8 +358,10 @@
+@@ -348,8 +363,10 @@
  	/* Portable-specific options */
  #ifdef USE_PAM
  	{ "usepam", sUsePAM, SSHCFG_GLOBAL },
@@ -1814,7 +1816,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  #endif
  	{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
  	/* Standard Options */
-@@ -386,13 +403,23 @@
+@@ -391,13 +408,23 @@
  	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
  #ifdef GSSAPI
  	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
@@ -1838,7 +1840,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
  	{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
  	{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
-@@ -454,6 +481,8 @@
+@@ -459,6 +486,8 @@
  	{ "permitopen", sPermitOpen, SSHCFG_ALL },
  	{ "forcecommand", sForceCommand, SSHCFG_ALL },
  	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
@@ -1847,7 +1849,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  #ifdef WITH_AUTHORIZED_KEYS_COMMAND
  	{ "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
  	{ "authorizedkeyscommandrunas", sAuthorizedKeysCommandRunAs, SSHCFG_ALL },
-@@ -718,6 +747,10 @@
+@@ -725,6 +754,10 @@
  		intptr = &options->use_pam;
  		goto parse_flag;
  
@@ -1858,7 +1860,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  	/* Standard Options */
  	case sBadOption:
  		return -1;
-@@ -928,6 +961,10 @@
+@@ -935,6 +968,10 @@
  		intptr = &options->gss_authentication;
  		goto parse_flag;
  
@@ -1869,7 +1871,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  	case sGssKeyEx:
  		intptr = &options->gss_keyex;
  		goto parse_flag;
-@@ -936,6 +973,10 @@
+@@ -943,6 +980,10 @@
  		intptr = &options->gss_cleanup_creds;
  		goto parse_flag;
  
@@ -1880,7 +1882,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  	case sGssStrictAcceptor:
  		intptr = &options->gss_strict_acceptor;
  		goto parse_flag;
-@@ -944,6 +985,12 @@
+@@ -951,6 +992,12 @@
  		intptr = &options->gss_store_rekey;
  		goto parse_flag;
  
@@ -1893,7 +1895,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  	case sPasswordAuthentication:
  		intptr = &options->password_authentication;
  		goto parse_flag;
-@@ -1361,6 +1408,18 @@
+@@ -1395,6 +1442,18 @@
  			*charptr = xstrdup(arg);
  		break;
  
@@ -1912,7 +1914,7 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  	case sAuthorizedKeysCommand:
  		len = strspn(cp, WHITESPACE);
  		if (*activep && options->authorized_keys_command == NULL)
-@@ -1466,6 +1525,7 @@
+@@ -1500,6 +1559,7 @@
  {
  	M_CP_INTOPT(password_authentication);
  	M_CP_INTOPT(gss_authentication);
@@ -1921,8 +1923,8 @@ diff -Nur openssh-5.3p1.orig/servconf.c openssh-5.3p1/servconf.c
  	M_CP_INTOPT(pubkey_authentication);
  	M_CP_STROPT(authorized_keys_command);
 diff -Nur openssh-5.3p1.orig/servconf.h openssh-5.3p1/servconf.h
---- openssh-5.3p1.orig/servconf.h	2011-08-12 08:52:47.344701691 +0200
-+++ openssh-5.3p1/servconf.h	2011-08-12 08:53:52.272703501 +0200
+--- openssh-5.3p1.orig/servconf.h	2012-08-14 08:39:57.184580330 +0200
++++ openssh-5.3p1/servconf.h	2012-08-14 08:41:07.491696283 +0200
 @@ -90,9 +90,12 @@
  						 * file on logout. */
  	int     kerberos_get_afs_token;		/* If true, try to get AFS token if
@@ -1936,7 +1938,7 @@ diff -Nur openssh-5.3p1.orig/servconf.h openssh-5.3p1/servconf.h
  	int 	gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */
  	int 	gss_store_rekey;
  	int     password_authentication;	/* If true, permit password
-@@ -149,6 +152,7 @@
+@@ -152,6 +155,7 @@
  	char   *adm_forced_command;
  
  	int	use_pam;		/* Enable auth via PAM */
@@ -1944,7 +1946,7 @@ diff -Nur openssh-5.3p1.orig/servconf.h openssh-5.3p1/servconf.h
  
  	int	permit_tun;
  
-@@ -156,6 +160,10 @@
+@@ -159,6 +163,10 @@
  	int	use_kuserok;
  
  	char   *chroot_directory;
@@ -1956,8 +1958,8 @@ diff -Nur openssh-5.3p1.orig/servconf.h openssh-5.3p1/servconf.h
  	char   *authorized_keys_command_runas;
  }       ServerOptions;
 diff -Nur openssh-5.3p1.orig/ssh.1 openssh-5.3p1/ssh.1
---- openssh-5.3p1.orig/ssh.1	2011-08-12 08:52:47.405701693 +0200
-+++ openssh-5.3p1/ssh.1	2011-08-12 08:53:52.273703501 +0200
+--- openssh-5.3p1.orig/ssh.1	2012-08-14 08:39:57.166580557 +0200
++++ openssh-5.3p1/ssh.1	2012-08-14 08:41:07.492696271 +0200
 @@ -1238,6 +1238,18 @@
  on to new connections).
  .It Ev USER
@@ -1978,8 +1980,8 @@ diff -Nur openssh-5.3p1.orig/ssh.1 openssh-5.3p1/ssh.1
  .Pp
  Additionally,
 diff -Nur openssh-5.3p1.orig/ssh.c openssh-5.3p1/ssh.c
---- openssh-5.3p1.orig/ssh.c	2011-08-12 08:52:47.213701687 +0200
-+++ openssh-5.3p1/ssh.c	2011-08-12 08:53:52.274703501 +0200
+--- openssh-5.3p1.orig/ssh.c	2012-08-14 08:39:57.057581927 +0200
++++ openssh-5.3p1/ssh.c	2012-08-14 08:41:07.493696259 +0200
 @@ -627,6 +627,32 @@
  			fatal("Can't open user config file %.100s: "
  			    "%.100s", config, strerror(errno));
@@ -2028,8 +2030,8 @@ diff -Nur openssh-5.3p1.orig/ssh.c openssh-5.3p1/ssh.c
  	/* Get default port if port has not been set. */
  	if (options.port == 0) {
 diff -Nur openssh-5.3p1.orig/ssh_config openssh-5.3p1/ssh_config
---- openssh-5.3p1.orig/ssh_config	2011-08-12 08:52:47.251701687 +0200
-+++ openssh-5.3p1/ssh_config	2011-08-12 08:53:52.275703501 +0200
+--- openssh-5.3p1.orig/ssh_config	2012-08-14 08:39:57.077581676 +0200
++++ openssh-5.3p1/ssh_config	2012-08-14 08:41:07.493696259 +0200
 @@ -24,10 +24,10 @@
  #   RSAAuthentication yes
  #   PasswordAuthentication yes
@@ -2046,8 +2048,8 @@ diff -Nur openssh-5.3p1.orig/ssh_config openssh-5.3p1/ssh_config
  #   CheckHostIP yes
  #   AddressFamily any
 diff -Nur openssh-5.3p1.orig/ssh_config.5 openssh-5.3p1/ssh_config.5
---- openssh-5.3p1.orig/ssh_config.5	2011-08-12 08:52:47.250701687 +0200
-+++ openssh-5.3p1/ssh_config.5	2011-08-12 08:53:52.275703501 +0200
+--- openssh-5.3p1.orig/ssh_config.5	2012-08-14 08:39:57.077581676 +0200
++++ openssh-5.3p1/ssh_config.5	2012-08-14 08:41:07.494696247 +0200
 @@ -56,6 +56,12 @@
  user's configuration file
  .Pq Pa ~/.ssh/config
@@ -2062,8 +2064,8 @@ diff -Nur openssh-5.3p1.orig/ssh_config.5 openssh-5.3p1/ssh_config.5
  .Pq Pa /etc/ssh/ssh_config
  .El
 diff -Nur openssh-5.3p1.orig/sshconnect2.c openssh-5.3p1/sshconnect2.c
---- openssh-5.3p1.orig/sshconnect2.c	2011-08-12 08:52:47.253701687 +0200
-+++ openssh-5.3p1/sshconnect2.c	2011-08-12 08:53:52.277703501 +0200
+--- openssh-5.3p1.orig/sshconnect2.c	2012-08-14 08:39:57.190580255 +0200
++++ openssh-5.3p1/sshconnect2.c	2012-08-14 08:41:07.495696234 +0200
 @@ -615,6 +615,11 @@
  	const char* canonicalhost = get_canonical_hostname(1);
  	const char *gss_host;
@@ -2126,8 +2128,8 @@ diff -Nur openssh-5.3p1.orig/sshconnect2.c openssh-5.3p1/sshconnect2.c
  	packet_put_cstring(authctxt->method->name);
  	packet_put_string(mic.value, mic.length);
 diff -Nur openssh-5.3p1.orig/sshd.8 openssh-5.3p1/sshd.8
---- openssh-5.3p1.orig/sshd.8	2011-08-12 08:52:47.407701693 +0200
-+++ openssh-5.3p1/sshd.8	2011-08-12 08:53:52.278703501 +0200
+--- openssh-5.3p1.orig/sshd.8	2012-08-14 08:39:57.166580557 +0200
++++ openssh-5.3p1/sshd.8	2012-08-14 08:41:07.495696234 +0200
 @@ -682,6 +682,43 @@
  |1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa
  AAAA1234.....=
@@ -2173,8 +2175,8 @@ diff -Nur openssh-5.3p1.orig/sshd.8 openssh-5.3p1/sshd.8
  .Bl -tag -width Ds -compact
  .It ~/.hushlogin
 diff -Nur openssh-5.3p1.orig/sshd.c openssh-5.3p1/sshd.c
---- openssh-5.3p1.orig/sshd.c	2011-08-12 08:52:47.414701693 +0200
-+++ openssh-5.3p1/sshd.c	2011-08-12 08:53:52.281703501 +0200
+--- openssh-5.3p1.orig/sshd.c	2012-08-14 08:39:57.177580417 +0200
++++ openssh-5.3p1/sshd.c	2012-08-14 08:41:07.496696221 +0200
 @@ -122,6 +122,7 @@
  #include "roaming.h"
  #include "audit.h"
@@ -2197,7 +2199,7 @@ diff -Nur openssh-5.3p1.orig/sshd.c openssh-5.3p1/sshd.c
  	/* challenge-response is implemented via keyboard interactive */
  	if (options.challenge_response_authentication)
  		options.kbd_interactive_authentication = 1;
-@@ -2032,7 +2040,7 @@
+@@ -2033,7 +2041,7 @@
  #endif
  
  #ifdef GSSAPI
@@ -2207,8 +2209,8 @@ diff -Nur openssh-5.3p1.orig/sshd.c openssh-5.3p1/sshd.c
  		ssh_gssapi_storecreds();
  		restore_uid();
 diff -Nur openssh-5.3p1.orig/sshd_config openssh-5.3p1/sshd_config
---- openssh-5.3p1.orig/sshd_config	2011-08-12 08:52:47.346701691 +0200
-+++ openssh-5.3p1/sshd_config	2011-08-12 08:53:52.281703501 +0200
+--- openssh-5.3p1.orig/sshd_config	2012-08-14 08:39:57.128581033 +0200
++++ openssh-5.3p1/sshd_config	2012-08-14 08:41:07.497696208 +0200
 @@ -77,12 +77,11 @@
  #KerberosUseKuserok yes
  
@@ -2245,8 +2247,8 @@ diff -Nur openssh-5.3p1.orig/sshd_config openssh-5.3p1/sshd_config
 +#UsageStatsTargets usage-stats.cilogon.org:4810
 +#DisableUsageStats no
 diff -Nur openssh-5.3p1.orig/sshd_config.5 openssh-5.3p1/sshd_config.5
---- openssh-5.3p1.orig/sshd_config.5	2011-08-12 08:52:47.345701691 +0200
-+++ openssh-5.3p1/sshd_config.5	2011-08-12 08:53:52.283703501 +0200
+--- openssh-5.3p1.orig/sshd_config.5	2012-08-14 08:39:57.185580317 +0200
++++ openssh-5.3p1/sshd_config.5	2012-08-14 08:41:07.498696195 +0200
 @@ -335,6 +335,15 @@
  in
  .Xr ssh_config 5
@@ -2297,7 +2299,7 @@ diff -Nur openssh-5.3p1.orig/sshd_config.5 openssh-5.3p1/sshd_config.5
  .It Cm GSSAPIStrictAcceptorCheck
  Determines whether to be strict about the identity of the GSSAPI acceptor 
  a client authenticates against. If
-@@ -935,6 +964,121 @@
+@@ -953,6 +982,121 @@
  .Pp
  To disable TCP keepalive messages, the value should be set to
  .Dq no .
@@ -2419,7 +2421,7 @@ diff -Nur openssh-5.3p1.orig/sshd_config.5 openssh-5.3p1/sshd_config.5
  .It Cm UseDNS
  Specifies whether
  .Xr sshd 8
-@@ -986,6 +1130,12 @@
+@@ -1004,6 +1148,12 @@
  as a non-root user.
  The default is
  .Dq no .
@@ -2434,7 +2436,7 @@ diff -Nur openssh-5.3p1.orig/sshd_config.5 openssh-5.3p1/sshd_config.5
  .Xr sshd 8
 diff -Nur openssh-5.3p1.orig/ssh-globus-usage.c openssh-5.3p1/ssh-globus-usage.c
 --- openssh-5.3p1.orig/ssh-globus-usage.c	1970-01-01 01:00:00.000000000 +0100
-+++ openssh-5.3p1/ssh-globus-usage.c	2011-08-12 08:53:52.284703501 +0200
++++ openssh-5.3p1/ssh-globus-usage.c	2012-08-14 08:41:07.498696195 +0200
 @@ -0,0 +1,389 @@
 +/*
 + * Copyright 2009 The Board of Trustees of the University
@@ -2827,7 +2829,7 @@ diff -Nur openssh-5.3p1.orig/ssh-globus-usage.c openssh-5.3p1/ssh-globus-usage.c
 +}
 diff -Nur openssh-5.3p1.orig/ssh-globus-usage.h openssh-5.3p1/ssh-globus-usage.h
 --- openssh-5.3p1.orig/ssh-globus-usage.h	1970-01-01 01:00:00.000000000 +0100
-+++ openssh-5.3p1/ssh-globus-usage.h	2011-08-12 08:53:52.284703501 +0200
++++ openssh-5.3p1/ssh-globus-usage.h	2012-08-14 08:41:07.499696183 +0200
 @@ -0,0 +1,46 @@
 +/*
 + * Copyright 2009 The Board of Trustees of the University
@@ -2876,8 +2878,8 @@ diff -Nur openssh-5.3p1.orig/ssh-globus-usage.h openssh-5.3p1/ssh-globus-usage.h
 +
 +#endif /* __SSH_GLOBUS_USAGE_H */
 diff -Nur openssh-5.3p1.orig/ssh-gss.h openssh-5.3p1/ssh-gss.h
---- openssh-5.3p1.orig/ssh-gss.h	2011-08-12 08:52:47.258701687 +0200
-+++ openssh-5.3p1/ssh-gss.h	2011-08-12 08:53:52.285703501 +0200
+--- openssh-5.3p1.orig/ssh-gss.h	2012-08-14 08:39:57.081581624 +0200
++++ openssh-5.3p1/ssh-gss.h	2012-08-14 08:41:07.499696183 +0200
 @@ -86,6 +86,7 @@
  	gss_name_t name;
  	struct ssh_gssapi_mech_struct *mech;
@@ -2924,7 +2926,7 @@ diff -Nur openssh-5.3p1.orig/ssh-gss.h openssh-5.3p1/ssh-gss.h
  #endif /* _SSH_GSS_H */
 diff -Nur openssh-5.3p1.orig/version.h openssh-5.3p1/version.h
 --- openssh-5.3p1.orig/version.h	2009-07-05 23:13:04.000000000 +0200
-+++ openssh-5.3p1/version.h	2011-08-12 08:53:52.285703501 +0200
++++ openssh-5.3p1/version.h	2012-08-14 08:41:07.499696183 +0200
 @@ -1,6 +1,21 @@
  /* $OpenBSD: version.h,v 1.56 2009/06/30 14:54:40 markus Exp $ */
  
diff --git a/openssh-5.3p1-linux-oomkiller.patch b/openssh-5.3p1-linux-oomkiller.patch
new file mode 100644
index 0000000..cafdad3
--- /dev/null
+++ b/openssh-5.3p1-linux-oomkiller.patch
@@ -0,0 +1,164 @@
+--- a/configure.ac	
++++ a/configure.ac	
+@@ -613,6 +613,7 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
+ 		if it doesn't return EOPNOTSUPP.])
+ 	AC_DEFINE(_PATH_BTMP, "/var/log/btmp", [log for bad login attempts])
+ 	AC_DEFINE(USE_BTMP)
++	AC_DEFINE(LINUX_OOM_ADJUST, 1, [Adjust Linux out-of-memory killer])
+ 	inet6_default_4in6=yes
+ 	case `uname -r` in
+ 	1.*|2.0.*)
+--- a/openbsd-compat/port-linux.c	
++++ a/openbsd-compat/port-linux.c	
+@@ -27,8 +27,15 @@ 
+ #include <stdarg.h>
+ #include <string.h>
+ 
+-#ifdef WITH_SELINUX
++#if defined(LINUX_OOM_ADJUST) || defined(WITH_SELINUX)
+ #include "log.h"
++#endif
++
++#ifdef LINUX_OOM_ADJUST
++#include <stdio.h>
++#endif
++
++#ifdef WITH_SELINUX
+ #include "port-linux.h"
+ #include "key.h"
+ #include "hostfile.h"
+@@ -537,3 +544,76 @@ ssh_selinux_copy_context(void)
+ 	xfree(ctx);
+ }
+ #endif /* WITH_SELINUX */
++
++#ifdef LINUX_OOM_ADJUST
++/*
++ * The magic "don't kill me" values, old and new, as documented in eg:
++ * http://lxr.linux.no/#linux+v2.6.36/Documentation/filesystems/proc.txt
++ */
++
++static int oom_adj_save = INT_MIN;
++static char *oom_adj_path = NULL;
++struct {
++       char *path;
++       int value;
++} oom_adjust[] = {
++       {"/proc/self/oom_score_adj", -1000},    /* kernels >= 2.6.36 */
++       {"/proc/self/oom_adj", -17},            /* kernels <= 2.6.35 */
++       {NULL, 0},
++};
++
++
++/*
++ * Tell the kernel's out-of-memory killer to avoid sshd.
++ * Returns the previous oom_adj value or zero.
++ */
++void
++oom_adjust_setup(void)
++{
++	int i, value;
++	FILE *fp;
++
++	debug3("%s", __func__);
++	for (i = 0; oom_adjust[i].path != NULL; i++) {
++	       oom_adj_path = oom_adjust[i].path;
++	       value = oom_adjust[i].value;
++	       if ((fp = fopen(oom_adj_path, "r+")) != NULL) {
++		       if (fscanf(fp, "%d", &oom_adj_save) != 1)
++			       verbose("error reading %s: %s", oom_adj_path,
++				   strerror(errno));
++		       else {
++			       rewind(fp);
++			       if (fprintf(fp, "%d\n", value) <= 0)
++				       verbose("error writing %s: %s",
++					  oom_adj_path, strerror(errno));
++			       else
++				       verbose("Set %s from %d to %d",
++					  oom_adj_path, oom_adj_save, value);
++		       }
++		       fclose(fp);
++		       return;
++		}
++	}
++	oom_adj_path = NULL;
++}
++
++/* Restore the saved OOM adjustment */
++void
++oom_adjust_restore(void)
++{
++	FILE *fp;
++
++	debug3("%s", __func__);
++	if (oom_adj_save == INT_MIN || oom_adj_path == NULL ||
++	    (fp = fopen(oom_adj_path, "w")) == NULL)
++		return;
++
++	if (fprintf(fp, "%d\n", oom_adj_save) <= 0)
++		verbose("error writing %s: %s", oom_adj_path, strerror(errno));
++	else
++		verbose("Set %s to %d", oom_adj_path, oom_adj_save);
++
++	fclose(fp);
++	return;
++}
++#endif
+--- a/openbsd-compat/port-linux.h	
++++ a/openbsd-compat/port-linux.h	
+@@ -27,4 +27,9 @@ void ssh_selinux_change_context(const char *);
+ void ssh_selinux_chopy_context(void);
+ #endif
+ 
++#ifdef LINUX_OOM_ADJUST
++void oom_adjust_restore(void);
++void oom_adjust_setup(void);
++#endif
++
+ #endif /* ! _PORT_LINUX_H */
+--- a/platform.c	
++++ a/platform.c	
+@@ -22,6 +22,15 @@ 
+ #include "openbsd-compat/openbsd-compat.h"
+ 
+ void
++platform_pre_listen(void)
++{
++#ifdef LINUX_OOM_ADJUST
++	/* Adjust out-of-memory killer so listening process is not killed */
++	oom_adjust_setup();
++#endif
++}
++
++void
+ platform_pre_fork(void)
+ {
+ #ifdef USE_SOLARIS_PROCESS_CONTRACTS
+@@ -43,4 +52,7 @@ platform_post_fork_child(void)
+ #ifdef USE_SOLARIS_PROCESS_CONTRACTS
+ 	solaris_contract_post_fork_child();
+ #endif
++#ifdef LINUX_OOM_ADJUST
++	oom_adjust_restore();
++#endif
+ }
+--- a/platform.h	
++++ a/platform.h	
+@@ -18,6 +18,7 @@ 
+ 
+ #include <sys/types.h>
+ 
++void platform_pre_listen(void);
+ void platform_pre_fork(void);
+ void platform_post_fork_parent(pid_t child_pid);
+ void platform_post_fork_child(void);
+--- a/sshd.c	
++++ a/sshd.c	
+@@ -1746,6 +1746,7 @@ main(int ac, char **av)
+ 	if (inetd_flag) {
+ 		server_accept_inetd(&sock_in, &sock_out);
+ 	} else {
++		platform_pre_listen();
+ 		server_listen();
+ 
+ 		if (options.protocol & SSH_PROTO_1)
diff --git a/openssh-5.3p1-noslash.patch b/openssh-5.3p1-noslash.patch
new file mode 100644
index 0000000..3370e6c
--- /dev/null
+++ b/openssh-5.3p1-noslash.patch
@@ -0,0 +1,21 @@
+commit 4927f76786f0db9cb2d7c9f49c3f58344fd234da
+Author: Jeffrey Bastian <jbastian at redhat.com>
+Date:   Tue Apr 3 14:19:40 2012 -0500
+
+    don't double up backslash in banner
+
+    http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/sshconnect2.c.diff?r1=1.176;r2=1.177
+
+diff --git a/sshconnect2.c b/sshconnect2.c
+index 9d56120..8510367 100644
+--- a/sshconnect2.c
++++ b/sshconnect2.c
+@@ -483,7 +483,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt)
+ 		if (len > 65536)
+ 			len = 65536;
+ 		msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */
+-		strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL);
++		strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL|VIS_NOSLASH);
+ 		fprintf(stderr, "%s", msg);
+ 		xfree(msg);
+ 	}
diff --git a/openssh-5.3p1-prevent-post-auth-resource-exhaustion.patch b/openssh-5.3p1-prevent-post-auth-resource-exhaustion.patch
new file mode 100644
index 0000000..e059150
--- /dev/null
+++ b/openssh-5.3p1-prevent-post-auth-resource-exhaustion.patch
@@ -0,0 +1,13 @@
+diff --git a/gss-serv.c b/gss-serv.c
+index 365e48d..998fd1e 100644
+--- a/gss-serv.c
++++ b/gss-serv.c
+@@ -266,6 +266,8 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
+ 	name->length = get_u32(tok+offset);
+ 	offset += 4;
+ 
++	if (UINT_MAX - offset < name->length)
++		return GSS_S_FAILURE;
+ 	if (ename->length < offset+name->length)
+ 		return GSS_S_FAILURE;
+ 
diff --git a/openssh-5.3p1-required-authentications.patch b/openssh-5.3p1-required-authentications.patch
new file mode 100644
index 0000000..9d6ea46
--- /dev/null
+++ b/openssh-5.3p1-required-authentications.patch
@@ -0,0 +1,832 @@
+diff -up openssh-5.3p1/auth1.c.required-authentication openssh-5.3p1/auth1.c
+--- openssh-5.3p1/auth1.c.required-authentication	2012-05-10 16:41:36.583004891 +0200
++++ openssh-5.3p1/auth1.c	2012-05-10 16:50:31.741985981 +0200
+@@ -98,6 +98,55 @@ static const struct AuthMethod1
+ 	return (NULL);
+ }
+ 
++static const struct AuthMethod1 *
++lookup_authmethod1_by_name(const char *name)
++{
++	int i;
++
++	for (i = 0; auth1_methods[i].name != NULL; i++)
++		if (strcmp(auth1_methods[i].name, name) == 0)
++			return (&(auth1_methods[i]));
++
++	return NULL;
++}
++
++#define	DELIM	","
++int
++auth1_check_required(const char *list)
++{
++	char *orig_methods, *methods, *cp;
++	static const struct AuthMethod1 *m;
++	int ret = 0;
++
++	orig_methods = methods = xstrdup(list);
++	for(;;) { /* XXX maybe: while ((cp = ...) != NULL) ? */
++		if ((cp = strsep(&methods, DELIM)) == NULL)
++			break;
++		debug2("auth1_check_required: method \"%s\"", cp);
++		if (*cp == '\0') {
++			debug("auth1_check_required: empty method");
++			ret = -1;
++		}
++		if ((m = lookup_authmethod1_by_name(cp)) == NULL) {
++			debug("auth1_check_required: unknown method "
++			    "\"%s\"", cp);
++			ret = -1;
++			break;
++		}
++		if (*(m->enabled) == 0) {
++			debug("auth1_check_required: method %s explicitly "
++			    "disabled", cp);
++			ret = -1;
++		}
++		/* Activate method if it isn't already */
++		if (*(m->enabled) == -1)
++			*(m->enabled) = 1;
++        }
++	xfree(orig_methods);
++	return (ret);
++}
++
++
+ static char *
+ get_authname(int type)
+ {
+@@ -237,6 +286,7 @@ do_authloop(Authctxt *authctxt)
+ {
+ 	int authenticated = 0;
+ 	char info[1024];
++	const char *meth_name;
+ 	int prev = 0, type = 0;
+ 	const struct AuthMethod1 *meth;
+ 
+@@ -244,7 +294,7 @@ do_authloop(Authctxt *authctxt)
+ 	    authctxt->valid ? "" : "invalid user ", authctxt->user);
+ 
+ 	/* If the user has no password, accept authentication immediately. */
+-	if (options.permit_empty_passwd && options.password_authentication &&
++	if (options.permit_empty_passwd && options.password_authentication && options.password_authentication &&
+ #ifdef KRB5
+ 	    (!options.kerberos_authentication || options.kerberos_or_local_passwd) &&
+ #endif
+@@ -253,7 +303,7 @@ do_authloop(Authctxt *authctxt)
+ 		if (options.use_pam && (PRIVSEP(do_pam_account())))
+ #endif
+ 		{
+-			auth_log(authctxt, 1, "without authentication", "");
++			auth_log(authctxt, 1, "without authentication", NULL, "");
+ 			return;
+ 		}
+ 	}
+@@ -272,6 +322,7 @@ do_authloop(Authctxt *authctxt)
+ 		/* Get a packet from the client. */
+ 		prev = type;
+ 		type = packet_read();
++		meth_name = get_authname(type);
+ 
+ 		/*
+ 		 * If we started challenge-response authentication but the
+@@ -287,8 +338,8 @@ do_authloop(Authctxt *authctxt)
+ 		if (authctxt->failures >= options.max_authtries)
+ 			goto skip;
+ 		if ((meth = lookup_authmethod1(type)) == NULL) {
+-			logit("Unknown message during authentication: "
+-			    "type %d", type);
++			logit("Unknown message during authentication: type %d",
++			    type);
+ 			goto skip;
+ 		}
+ 
+@@ -297,6 +348,17 @@ do_authloop(Authctxt *authctxt)
+ 			goto skip;
+ 		}
+ 
++		/*
++		 * Skip methods not in required list, until all the required
++		 * ones are done
++		 */
++		if (options.required_auth1 != NULL &&
++		    !auth_method_in_list(options.required_auth1, meth_name)) {
++			debug("Skipping method \"%s\" until required "
++			    "authentication completed", meth_name);
++			goto skip;
++		}
++
+ 		authenticated = meth->method(authctxt, info, sizeof(info));
+ 		if (authenticated == -1)
+ 			continue; /* "postponed" */
+@@ -352,7 +414,29 @@ do_authloop(Authctxt *authctxt)
+ 
+  skip:
+ 		/* Log before sending the reply */
+-		auth_log(authctxt, authenticated, get_authname(type), info);
++		auth_log(authctxt, authenticated, meth_name, NULL, info);
++
++		/* Loop until the required authmethods are done */
++		if (authenticated && options.required_auth1 != NULL) {
++			if (auth_remove_from_list(&options.required_auth1,
++			    meth_name) == 0)
++				fatal("INTERNAL ERROR: authenticated method "
++				    "\"%s\" not in required list \"%s\"",
++				    meth_name, options.required_auth1);
++			debug2("do_authloop: required list now: %s",
++			    options.required_auth1 == NULL ?
++			    "DONE" : options.required_auth1);
++			if (options.required_auth1 == NULL)
++				return;
++			authenticated = 0;
++			/*
++			 * Disable method so client can't authenticate with it
++			 * after the required authentications are complete.
++			 */
++			*(meth->enabled) = 0;
++			packet_send_debug("Further authentication required");
++			goto send_fail;
++		}
+ 
+ 		if (client_user != NULL) {
+ 			xfree(client_user);
+@@ -368,6 +452,7 @@ do_authloop(Authctxt *authctxt)
+ #endif
+ 			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
+ 		}
++ send_fail:
+ 
+ 		packet_start(SSH_SMSG_FAILURE);
+ 		packet_send();
+diff -up openssh-5.3p1/auth2-chall.c.required-authentication openssh-5.3p1/auth2-chall.c
+--- openssh-5.3p1/auth2-chall.c.required-authentication	2009-01-28 06:13:39.000000000 +0100
++++ openssh-5.3p1/auth2-chall.c	2012-05-10 16:41:36.818692159 +0200
+@@ -341,7 +341,8 @@ input_userauth_info_response(int type, u
+ 			auth2_challenge_start(authctxt);
+ 		}
+ 	}
+-	userauth_finish(authctxt, authenticated, method);
++	userauth_finish(authctxt, authenticated, "keyboard-interactive",
++	    authctxt->kbdintctxt != NULL ? kbdintctxt->device->name : NULL);
+ 	xfree(method);
+ }
+ 
+diff -up openssh-5.3p1/auth2.c.required-authentication openssh-5.3p1/auth2.c
+--- openssh-5.3p1/auth2.c.required-authentication	2012-05-10 16:41:36.738692295 +0200
++++ openssh-5.3p1/auth2.c	2012-05-10 16:41:36.819691687 +0200
+@@ -217,7 +217,7 @@ input_userauth_request(int type, u_int32
+ {
+ 	Authctxt *authctxt = ctxt;
+ 	Authmethod *m = NULL;
+-	char *user, *service, *method, *style = NULL;
++	char *user, *service, *method, *active_methods, *style = NULL;
+ #ifdef WITH_SELINUX
+ 	char *role = NULL;
+ #endif
+@@ -291,22 +291,31 @@ input_userauth_request(int type, u_int32
+ 	authctxt->server_caused_failure = 0;
+ 
+ 	/* try to authenticate user */
+-	m = authmethod_lookup(method);
+-	if (m != NULL && authctxt->failures < options.max_authtries) {
+-		debug2("input_userauth_request: try method %s", method);
+-		authenticated =	m->userauth(authctxt);
+-	}
+-	userauth_finish(authctxt, authenticated, method);
++	active_methods = authmethods_get();
++	if (strcmp(method, "none") == 0 || 
++	    auth_method_in_list(active_methods, method)) {
++		m = authmethod_lookup(method);
++		if (m != NULL) {
++			debug2("input_userauth_request: try method %s", method);
++			authenticated =	m->userauth(authctxt);
++		}
+ 
++	}
++	xfree(active_methods);
++	userauth_finish(authctxt, authenticated, method, NULL);
++ 
+ 	xfree(service);
+ 	xfree(user);
+ 	xfree(method);
+ }
+ 
+ void
+-userauth_finish(Authctxt *authctxt, int authenticated, char *method)
++userauth_finish(Authctxt *authctxt, int authenticated, const char *method,
++    const char *submethod)
+ {
+ 	char *methods;
++	Authmethod *m = NULL;
++	u_int partial = 0;
+ 
+ 	if (!authctxt->valid && authenticated)
+ 		fatal("INTERNAL ERROR: authenticated invalid user %s",
+@@ -344,12 +353,42 @@ userauth_finish(Authctxt *authctxt, int 
+ #endif /* _UNICOS */
+ 
+ 	/* Log before sending the reply */
+-	auth_log(authctxt, authenticated, method, " ssh2");
++	auth_log(authctxt, authenticated, method, submethod, " ssh2");
+ 
+ 	if (authctxt->postponed)
+ 		return;
+ 
+-	/* XXX todo: check if multiple auth methods are needed */
++	/* Handle RequiredAuthentications2: loop until required methods done */
++	if (authenticated && options.required_auth2 != NULL) {
++		if ((m = authmethod_lookup(method)) == NULL)
++			fatal("INTERNAL ERROR: authenticated method "
++			    "\"%s\" unknown", method);
++		if (auth_remove_from_list(&options.required_auth2, method) == 0)
++			fatal("INTERNAL ERROR: authenticated method "
++			    "\"%s\" not in required list \"%s\"", 
++			    method, options.required_auth2);
++		debug2("userauth_finish: required list now: %s",
++		    options.required_auth2 == NULL ?
++		    "DONE" : options.required_auth2);
++		/*
++		 * if authenticated and no more required methods 
++		 * then declare success
++		 */
++		if ( authenticated && options.required_auth2 == NULL ) {
++			debug2("userauth_finish: authenticated and no more required methods");
++		} else {
++			/*
++			 * Disable method so client can't authenticate with it after
++			 * the required authentications are complete.
++			 */
++			if (m->enabled != NULL)
++			*(m->enabled) = 0;
++			authenticated = 0;
++			partial = 1;
++			goto send_fail;
++		}
++	}
++
+ 	if (authenticated == 1) {
+ 		/* turn off userauth */
+ 		dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
+@@ -359,7 +398,6 @@ userauth_finish(Authctxt *authctxt, int 
+ 		/* now we can break out */
+ 		authctxt->success = 1;
+ 	} else {
+-
+ 		/* Allow initial try of "none" auth without failure penalty */
+ 		if (!authctxt->server_caused_failure &&
+ 		    (authctxt->attempt > 1 || strcmp(method, "none") != 0))
+@@ -370,10 +408,11 @@ userauth_finish(Authctxt *authctxt, int 
+ #endif
+ 			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
+ 		}
++ send_fail:
+ 		methods = authmethods_get();
+ 		packet_start(SSH2_MSG_USERAUTH_FAILURE);
+ 		packet_put_cstring(methods);
+-		packet_put_char(0);	/* XXX partial success, unused */
++		packet_put_char(partial);
+ 		packet_send();
+ 		packet_write_wait();
+ 		xfree(methods);
+@@ -387,6 +426,9 @@ authmethods_get(void)
+ 	char *list;
+ 	int i;
+ 
++	if (options.required_auth2 != NULL)
++		return xstrdup(options.required_auth2);
++
+ 	buffer_init(&b);
+ 	for (i = 0; authmethods[i] != NULL; i++) {
+ 		if (strcmp(authmethods[i]->name, "none") == 0)
+@@ -421,3 +463,43 @@ authmethod_lookup(const char *name)
+ 	return NULL;
+ }
+ 
++#define DELIM ","
++
++int
++auth2_check_required(const char *list)
++{
++	char *orig_methods, *methods, *cp;
++	struct Authmethod *m;
++	int i, ret = 0;
++
++	orig_methods = methods = xstrdup(list);
++	for(;;) {
++		if ((cp = strsep(&methods, DELIM)) == NULL)
++			break;
++		debug2("auth2_check_required: method \"%s\"", cp);
++		if (*cp == '\0') {
++			debug("auth2_check_required: empty method");
++			ret = -1;
++		}
++		for (i = 0; authmethods[i] != NULL; i++)
++			if (strcmp(cp, authmethods[i]->name) == 0)
++				break;
++		if ((m = authmethods[i]) == NULL) {
++			debug("auth2_check_required: unknown method "
++			    "\"%s\"", cp);
++			ret = -1;
++			break;
++		}
++		if (m->enabled == NULL || *(m->enabled) == 0) {
++			debug("auth2_check_required: method %s explicitly "
++			    "disabled", cp);
++			ret = -1;
++		}
++		/* Activate method if it isn't already */
++		if (m->enabled != NULL && *(m->enabled) == -1)
++			*(m->enabled) = 1;
++	}
++	xfree(orig_methods);
++	return (ret);
++}
++
+diff -up openssh-5.3p1/auth2-gss.c.required-authentication openssh-5.3p1/auth2-gss.c
+--- openssh-5.3p1/auth2-gss.c.required-authentication	2012-05-10 16:41:36.686885848 +0200
++++ openssh-5.3p1/auth2-gss.c	2012-05-10 16:41:36.819691687 +0200
+@@ -197,7 +197,7 @@ input_gssapi_token(int type, u_int32_t p
+ 		}
+ 		authctxt->postponed = 0;
+ 		dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+-		userauth_finish(authctxt, 0, "gssapi-with-mic");
++		userauth_finish(authctxt, 0, "gssapi-with-mic", NULL);
+ 	} else {
+ 		if (send_tok.length != 0) {
+ 			packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
+@@ -286,7 +286,7 @@ input_gssapi_exchange_complete(int type,
+ 	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
+ 	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
+ 	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
+-	userauth_finish(authctxt, authenticated, "gssapi-with-mic");
++	userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
+ }
+ 
+ static void
+@@ -336,7 +336,7 @@ input_gssapi_mic(int type, u_int32_t ple
+ 	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
+ 	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
+ 	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
+-	userauth_finish(authctxt, authenticated, "gssapi-with-mic");
++	userauth_finish(authctxt, authenticated, "gssapi-with-mic", NULL);
+ }
+ 
+ Authmethod method_gsskeyex = {
+diff -up openssh-5.3p1/auth2-none.c.required-authentication openssh-5.3p1/auth2-none.c
+--- openssh-5.3p1/auth2-none.c.required-authentication	2012-05-10 16:41:36.564696355 +0200
++++ openssh-5.3p1/auth2-none.c	2012-05-10 16:41:36.820692160 +0200
+@@ -61,7 +61,7 @@ userauth_none(Authctxt *authctxt)
+ {
+ 	none_enabled = 0;
+ 	packet_check_eom();
+-	if (options.permit_empty_passwd && options.password_authentication)
++	if (options.permit_empty_passwd && options.password_authentication && options.required_auth2 == NULL)
+ 		return (PRIVSEP(auth_password(authctxt, "")));
+ 	return (0);
+ }
+diff -up openssh-5.3p1/auth.c.required-authentication openssh-5.3p1/auth.c
+--- openssh-5.3p1/auth.c.required-authentication	2008-11-05 06:12:54.000000000 +0100
++++ openssh-5.3p1/auth.c	2012-05-10 16:41:36.820692160 +0200
+@@ -245,7 +245,8 @@ allowed_user(struct passwd * pw)
+ }
+ 
+ void
+-auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
++auth_log(Authctxt *authctxt, int authenticated, const char *method,
++    const char *submethod, const char *info)
+ {
+ 	void (*authlog) (const char *fmt,...) = verbose;
+ 	char *authmsg;
+@@ -265,9 +266,10 @@ auth_log(Authctxt *authctxt, int authent
+ 	else
+ 		authmsg = authenticated ? "Accepted" : "Failed";
+ 
+-	authlog("%s %s for %s%.100s from %.200s port %d%s",
++	authlog("%s %s%s%s for %s%.100s from %.200s port %d%s",
+ 	    authmsg,
+ 	    method,
++	    submethod == NULL ? "" : "/", submethod == NULL ? "" : submethod,
+ 	    authctxt->valid ? "" : "invalid user ",
+ 	    authctxt->user,
+ 	    get_remote_ipaddr(),
+@@ -297,7 +299,7 @@ auth_log(Authctxt *authctxt, int authent
+  * Check whether root logins are disallowed.
+  */
+ int
+-auth_root_allowed(char *method)
++auth_root_allowed(const char *method)
+ {
+ 	switch (options.permit_root_login) {
+ 	case PERMIT_YES:
+@@ -620,3 +622,57 @@ fakepw(void)
+ 
+ 	return (&fake);
+ }
++
++int
++auth_method_in_list(const char *list, const char *method)
++{
++	char *cp;
++
++	cp = match_list(method, list, NULL);
++	if (cp != NULL) {
++		xfree(cp);
++		return 1;
++	}
++
++	return 0;
++}
++
++#define	DELIM	","
++int
++auth_remove_from_list(char **list, const char *method)
++{
++	char *oldlist, *cp, *newlist = NULL;
++	u_int len = 0, ret = 0;
++
++	if (list == NULL || *list == NULL)
++		return (0);
++
++	oldlist = *list;
++	len = strlen(oldlist) + 1;
++	newlist = xmalloc(len);
++	memset(newlist, '\0', len);
++
++	/* Remove method from list, if present */
++	for (;;) {
++		if ((cp = strsep(&oldlist, DELIM)) == NULL)
++			break;
++		if (*cp == '\0')
++			continue;
++		if (strcmp(cp, method) != 0) {
++			if (*newlist != '\0')
++				strlcat(newlist, DELIM, len);
++			strlcat(newlist, cp, len);
++		} else
++			ret++;
++	}
++
++	/* Return NULL instead of empty list */
++	if (*newlist == '\0') {
++		xfree(newlist);
++		newlist = NULL;
++	}
++	xfree(*list);
++	*list = newlist;
++	
++	return (ret);
++}
+diff -up openssh-5.3p1/auth.h.required-authentication openssh-5.3p1/auth.h
+--- openssh-5.3p1/auth.h.required-authentication	2012-05-10 16:41:36.740693177 +0200
++++ openssh-5.3p1/auth.h	2012-05-10 16:41:36.821693125 +0200
+@@ -145,10 +145,11 @@ void disable_forwarding(void);
+ void	do_authentication(Authctxt *);
+ void	do_authentication2(Authctxt *);
+ 
+-void	auth_log(Authctxt *, int, char *, char *);
+-void	userauth_finish(Authctxt *, int, char *);
++void	auth_log(Authctxt *, int, const char *, const char *, const char *);
++void	userauth_finish(Authctxt *, int, const char *, const char *);
++int	auth_root_allowed(const char *);
++
+ void	userauth_send_banner(const char *);
+-int	auth_root_allowed(char *);
+ 
+ char	*auth2_read_banner(void);
+ 
+@@ -194,6 +195,11 @@ void	 auth_debug_send(void);
+ void	 auth_debug_reset(void);
+ 
+ struct passwd *fakepw(void);
++int	 auth_method_in_list(const char *, const char *);
++int	 auth_remove_from_list(char **, const char *);
++
++int	 auth1_check_required(const char *);
++int	 auth2_check_required(const char *);
+ 
+ int	 sys_auth_passwd(Authctxt *, const char *);
+ 
+diff -up openssh-5.3p1/monitor.c.required-authentication openssh-5.3p1/monitor.c
+--- openssh-5.3p1/monitor.c.required-authentication	2012-05-10 16:41:36.751692712 +0200
++++ openssh-5.3p1/monitor.c	2012-05-10 16:41:36.822691860 +0200
+@@ -202,6 +202,7 @@ static int key_blobtype = MM_NOKEY;
+ static char *hostbased_cuser = NULL;
+ static char *hostbased_chost = NULL;
+ static char *auth_method = "unknown";
++static char *auth_submethod = NULL;
+ static u_int session_id2_len = 0;
+ static u_char *session_id2 = NULL;
+ static pid_t monitor_child_pid;
+@@ -384,6 +385,7 @@ monitor_child_preauth(Authctxt *_authctx
+ {
+ 	struct mon_table *ent;
+ 	int authenticated = 0;
++	char **req_auth;
+ 
+ 	debug3("preauth child monitor started");
+ 
+@@ -394,6 +396,7 @@ monitor_child_preauth(Authctxt *_authctx
+ 
+ 	if (compat20) {
+ 		mon_dispatch = mon_dispatch_proto20;
++		req_auth = &options.required_auth2;
+ 
+ 		/* Permit requests for moduli and signatures */
+ 		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
+@@ -404,6 +407,7 @@ monitor_child_preauth(Authctxt *_authctx
+ #endif
+ 	} else {
+ 		mon_dispatch = mon_dispatch_proto15;
++		req_auth = &options.required_auth1;
+ 
+ 		monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1);
+ 	}
+@@ -411,6 +415,7 @@ monitor_child_preauth(Authctxt *_authctx
+ 	/* The first few requests do not require asynchronous access */
+ 	while (!authenticated) {
+ 		auth_method = "unknown";
++		auth_submethod = NULL;
+ 		authenticated = (monitor_read(pmonitor, mon_dispatch, &ent) == 1);
+ 		if (authenticated) {
+ 			if (!(ent->flags & MON_AUTHDECIDE))
+@@ -432,10 +437,19 @@ monitor_child_preauth(Authctxt *_authctx
+ 			}
+ #endif
+ 		}
++		/* Loop until the required authmethods are done */
++		if (authenticated && *req_auth != NULL) {
++			if (auth_remove_from_list(req_auth, auth_method) == 0)
++				fatal("INTERNAL ERROR: authenticated method "
++				    "\"%s\" not in required list \"%s\"",
++				    auth_method, *req_auth);
++			debug2("monitor_child_preauth: required list now: %s",
++			    *req_auth == NULL ? "DONE" : *req_auth);
++		}
+ 
+ 		if (ent->flags & (MON_AUTHDECIDE|MON_ALOG)) {
+ 			auth_log(authctxt, authenticated, auth_method,
+-			    compat20 ? " ssh2" : "");
++				 auth_submethod, compat20 ? " ssh2" : "");
+ 			if (!authenticated)
+ 				authctxt->failures++;
+ 		}
+@@ -448,6 +462,8 @@ monitor_child_preauth(Authctxt *_authctx
+ 			}
+ 		}
+ #endif
++		if (*req_auth != NULL)
++			authenticated = 0;
+ 	}
+ 
+ 	if (!authctxt->valid)
+@@ -823,6 +839,7 @@ mm_answer_authpassword(int sock, Buffer 
+ 		auth_method = "none";
+ 	else
+ 		auth_method = "password";
++	auth_submethod = NULL;
+ 
+ 	/* Causes monitor loop to terminate if authenticated */
+ 	return (authenticated);
+@@ -882,6 +899,7 @@ mm_answer_bsdauthrespond(int sock, Buffe
+ 	mm_request_send(sock, MONITOR_ANS_BSDAUTHRESPOND, m);
+ 
+ 	auth_method = "bsdauth";
++	auth_submethod = NULL;
+ 
+ 	return (authok != 0);
+ }
+@@ -931,6 +949,7 @@ mm_answer_skeyrespond(int sock, Buffer *
+ 	mm_request_send(sock, MONITOR_ANS_SKEYRESPOND, m);
+ 
+ 	auth_method = "skey";
++	auth_submethod = NULL;
+ 
+ 	return (authok != 0);
+ }
+@@ -1020,7 +1039,8 @@ mm_answer_pam_query(int sock, Buffer *m)
+ 		xfree(prompts);
+ 	if (echo_on != NULL)
+ 		xfree(echo_on);
+-	auth_method = "keyboard-interactive/pam";
++	auth_method = "keyboard-interactive";
++	auth_submethod = "pam";
+ 	mm_request_send(sock, MONITOR_ANS_PAM_QUERY, m);
+ 	return (0);
+ }
+@@ -1049,7 +1069,8 @@ mm_answer_pam_respond(int sock, Buffer *
+ 	buffer_clear(m);
+ 	buffer_put_int(m, ret);
+ 	mm_request_send(sock, MONITOR_ANS_PAM_RESPOND, m);
+-	auth_method = "keyboard-interactive/pam";
++	auth_method = "keyboard-interactive";
++	auth_submethod = "pam";
+ 	if (ret == 0)
+ 		sshpam_authok = sshpam_ctxt;
+ 	return (0);
+@@ -1063,7 +1084,8 @@ mm_answer_pam_free_ctx(int sock, Buffer 
+ 	(sshpam_device.free_ctx)(sshpam_ctxt);
+ 	buffer_clear(m);
+ 	mm_request_send(sock, MONITOR_ANS_PAM_FREE_CTX, m);
+-	auth_method = "keyboard-interactive/pam";
++	auth_method = "keyboard-interactive";
++	auth_submethod = "pam";
+ 	return (sshpam_authok == sshpam_ctxt);
+ }
+ #endif
+@@ -1110,6 +1132,7 @@ mm_answer_keyallowed(int sock, Buffer *m
+ 			allowed = options.pubkey_authentication &&
+ 			    user_key_allowed(authctxt->pw, key);
+ 			auth_method = "publickey";
++			auth_submethod = NULL;
+ 			if (options.pubkey_authentication && allowed != 1)
+ 				auth_clear_options();
+ 			break;
+@@ -1118,6 +1141,7 @@ mm_answer_keyallowed(int sock, Buffer *m
+ 			    hostbased_key_allowed(authctxt->pw,
+ 			    cuser, chost, key);
+ 			auth_method = "hostbased";
++			auth_submethod = NULL;
+ 			break;
+ 		case MM_RSAHOSTKEY:
+ 			key->type = KEY_RSA1; /* XXX */
+@@ -1127,6 +1151,7 @@ mm_answer_keyallowed(int sock, Buffer *m
+ 			if (options.rhosts_rsa_authentication && allowed != 1)
+ 				auth_clear_options();
+ 			auth_method = "rsa";
++			auth_submethod = NULL;
+ 			break;
+ 		default:
+ 			fatal("%s: unknown key type %d", __func__, type);
+@@ -1148,7 +1173,8 @@ mm_answer_keyallowed(int sock, Buffer *m
+ 		hostbased_chost = chost;
+ 	} else {
+ 		/* Log failed attempt */
+-		auth_log(authctxt, 0, auth_method, compat20 ? " ssh2" : "");
++		auth_log(authctxt, 0, auth_method, auth_submethod,
++		    compat20 ? " ssh2" : "");
+ 		xfree(blob);
+ 		xfree(cuser);
+ 		xfree(chost);
+@@ -1347,6 +1373,7 @@ mm_answer_keyverify(int sock, Buffer *m)
+ 	xfree(data);
+ 
+ 	auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased";
++	auth_submethod = NULL;
+ 
+ 	monitor_reset_key_state();
+ 
+@@ -1542,6 +1569,7 @@ mm_answer_rsa_keyallowed(int sock, Buffe
+ 	debug3("%s entering", __func__);
+ 
+ 	auth_method = "rsa";
++	auth_submethod = NULL;
+ 	if (options.rsa_authentication && authctxt->valid) {
+ 		if ((client_n = BN_new()) == NULL)
+ 			fatal("%s: BN_new", __func__);
+@@ -1649,6 +1677,7 @@ mm_answer_rsa_response(int sock, Buffer 
+ 	xfree(response);
+ 
+ 	auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa";
++	auth_submethod = NULL;
+ 
+ 	/* reset state */
+ 	BN_clear_free(ssh1_challenge);
+@@ -2164,6 +2193,7 @@ mm_answer_gss_userok(int sock, Buffer *m
+ 	mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m);
+ 
+ 	auth_method = "gssapi-with-mic";
++	auth_submethod = NULL;
+ 
+ 	/* Monitor loop will terminate if authenticated */
+ 	return (authenticated);
+@@ -2436,6 +2466,7 @@ mm_answer_jpake_check_confirm(int sock, 
+ 	monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1);
+ 
+ 	auth_method = "jpake-01 at openssh.com";
++	auth_submethod = NULL;
+ 	return authenticated;
+ }
+ 
+diff -up openssh-5.3p1/servconf.c.required-authentication openssh-5.3p1/servconf.c
+--- openssh-5.3p1/servconf.c.required-authentication	2012-05-10 16:41:36.763691825 +0200
++++ openssh-5.3p1/servconf.c	2012-05-10 16:41:36.823691935 +0200
+@@ -38,6 +38,8 @@
+ #include "key.h"
+ #include "kex.h"
+ #include "mac.h"
++#include "hostfile.h"
++#include "auth.h"
+ #include "match.h"
+ #include "channels.h"
+ #include "groupaccess.h"
+@@ -128,6 +130,8 @@ initialize_server_options(ServerOptions 
+ 	options->authorized_keys_file2 = NULL;
+ 	options->num_accept_env = 0;
+ 	options->permit_tun = -1;
++	options->required_auth1 = NULL;
++	options->required_auth2 = NULL;
+ 	options->num_permitted_opens = -1;
+ 	options->adm_forced_command = NULL;
+ 	options->chroot_directory = NULL;
+@@ -323,6 +327,7 @@ typedef enum {
+ 	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
+ 	sGssKeyEx, sGssStoreRekey,
+ 	sAcceptEnv, sPermitTunnel,
++	sRequiredAuthentications1, sRequiredAuthentications2,
+ 	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
+ 	sUsePrivilegeSeparation, sAllowAgentForwarding,
+ 	sZeroKnowledgePasswordAuthentication,
+@@ -461,6 +466,8 @@ static struct {
+ 	{ "authorizedkeyscommand", sUnsupported, SSHCFG_ALL },
+ 	{ "authorizedkeyscommandrunas", sUnsupported, SSHCFG_ALL },
+ #endif
++	{ "requiredauthentications1", sRequiredAuthentications1, SSHCFG_ALL },
++	{ "requiredauthentications2", sRequiredAuthentications2, SSHCFG_ALL },
+ 	{ NULL, sBadOption, 0 }
+ };
+ 
+@@ -1219,6 +1226,33 @@ process_server_config_line(ServerOptions
+ 			options->max_startups = options->max_startups_begin;
+ 		break;
+ 
++
++	case sRequiredAuthentications1:
++		charptr = &options->required_auth1;
++		arg = strdelim(&cp);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.",
++			    filename, linenum);
++		if (auth1_check_required(arg) != 0)
++			fatal("%.200s line %d: Invalid required authentication "
++			    "list", filename, linenum);
++		if (*charptr == NULL)
++			*charptr = xstrdup(arg);
++		break;
++
++	case sRequiredAuthentications2:
++		charptr = &options->required_auth2;
++		arg = strdelim(&cp);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.",
++			    filename, linenum);
++		if (auth2_check_required(arg) != 0)
++			fatal("%.200s line %d: Invalid required authentication "
++			    "list", filename, linenum);
++		if (*charptr == NULL)
++			*charptr = xstrdup(arg);
++		break;
++
+ 	case sMaxAuthTries:
+ 		intptr = &options->max_authtries;
+ 		goto parse_int;
+diff -up openssh-5.3p1/servconf.h.required-authentication openssh-5.3p1/servconf.h
+--- openssh-5.3p1/servconf.h.required-authentication	2012-05-10 16:41:36.764691829 +0200
++++ openssh-5.3p1/servconf.h	2012-05-10 16:41:36.824692044 +0200
+@@ -146,6 +146,9 @@ typedef struct {
+ 	char   *authorized_keys_file;	/* File containing public keys */
+ 	char   *authorized_keys_file2;
+ 
++	char   *required_auth1; /* Required, but not sufficient */
++	char   *required_auth2;
++
+ 	char   *adm_forced_command;
+ 
+ 	int	use_pam;		/* Enable auth via PAM */
+diff -up openssh-5.3p1/sshd_config.5.required-authentication openssh-5.3p1/sshd_config.5
+--- openssh-5.3p1/sshd_config.5.required-authentication	2012-05-10 16:41:36.765694885 +0200
++++ openssh-5.3p1/sshd_config.5	2012-05-10 16:41:36.824692044 +0200
+@@ -650,6 +650,8 @@ Available keywords are
+ .Cm PermitEmptyPasswords ,
+ .Cm PermitOpen ,
+ .Cm PermitRootLogin ,
++.Cm RequiredAuthentications1,
++.Cm RequiredAuthentications2,
+ .Cm RhostsRSAAuthentication ,
+ .Cm RSAAuthentication ,
+ .Cm X11DisplayOffset ,
+@@ -854,7 +856,23 @@ only with PubkeyAuthentication turned on
+ .It Cm AuthorizedKeysCommandRunAs
+ Specifies the user under whose account the AuthorizedKeysCommand is run. Empty
+ string (the default value) means the user being authorized is used.
+-.Dq 
++.It Cm RequiredAuthentications[12]
++Specifies required methods of authentications that has to succeed before authorizing the connection.
++(RequiredAuthentication1 for Protocol version 1, and RequiredAuthentication2 for v2)
++.Bd -literal -offset 3n
++ RequiredAuthentications1 method[,method...] 
++ RequiredAuthentications2 method[,method...]
++.Ed
++.Pp
++Example 1:
++.Bd -literal -offset 3n
++ RequiredAuthentications2 password,hostbased
++.Ed
++.Pp
++Example 2:
++.Bd -literal -offset 3n
++ RequiredAuthentications2 publickey,password
++.Ed
+ .It Cm RhostsRSAAuthentication
+ Specifies whether rhosts or /etc/hosts.equiv authentication together
+ with successful RSA host authentication is allowed.
diff --git a/openssh-5.3p1-selabel.patch b/openssh-5.3p1-selabel.patch
index 29e2984..6e5d6bd 100644
--- a/openssh-5.3p1-selabel.patch
+++ b/openssh-5.3p1-selabel.patch
@@ -33,7 +33,7 @@ diff -up openssh-5.3p1/ssh.c.selabel openssh-5.3p1/ssh.c
  #include "openbsd-compat/openssl-compat.h"
  #include "openbsd-compat/sys-queue.h"
  
-@@ -792,10 +793,17 @@ main(int ac, char **av)
+@@ -792,10 +793,15 @@ main(int ac, char **av)
  	 */
  	r = snprintf(buf, sizeof buf, "%s%s%s", pw->pw_dir,
  	    strcmp(pw->pw_dir, "/") ? "/" : "", _PATH_SSH_USER_DIR);
@@ -41,10 +41,8 @@ diff -up openssh-5.3p1/ssh.c.selabel openssh-5.3p1/ssh.c
 +	if (r > 0 && (size_t)r < sizeof(buf) && stat(buf, &st) < 0) {
 +		char *scon;
 +
-+		if (matchpathcon(buf, 0700, &scon) != -1) {
-+			setfscreatecon(scon);
-+			matchpathcon_fini();
-+		}
++		matchpathcon(buf, 0700, &scon);
++		setfscreatecon(scon);
  		if (mkdir(buf, 0700) < 0)
  			error("Could not create directory '%.200s'.", buf);
 -
diff --git a/openssh-5.3p1-selinux-privsep.patch b/openssh-5.3p1-selinux-privsep.patch
new file mode 100644
index 0000000..33416ee
--- /dev/null
+++ b/openssh-5.3p1-selinux-privsep.patch
@@ -0,0 +1,50 @@
+diff -up openssh-5.3p1/session.c.privsep openssh-5.3p1/session.c
+--- openssh-5.3p1/session.c.privsep	2012-04-23 14:23:03.747701150 +0200
++++ openssh-5.3p1/session.c	2012-04-23 14:24:59.097013562 +0200
+@@ -1565,6 +1565,13 @@ do_setusercontext(struct passwd *pw)
+ #endif
+ 	}
+ 
++#ifdef WITH_SELINUX
++	if (options.chroot_directory == NULL ||
++	    strcasecmp(options.chroot_directory, "none") == 0) {
++		ssh_selinux_copy_context();
++	}
++#endif
++
+ 	if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
+ 		fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
+ }
+@@ -1577,6 +1584,9 @@ do_pwchange(Session *s)
+ 	if (s->ttyfd != -1) {
+ 		fprintf(stderr,
+ 		    "You must change your password now and login again!\n");
++#ifdef WITH_SELINUX
++		setexeccon(NULL);
++#endif
+ #ifdef PASSWD_NEEDS_USERNAME
+ 		execl(_PATH_PASSWD_PROG, "passwd", s->pw->pw_name,
+ 		    (char *)NULL);
+@@ -1698,7 +1708,9 @@ do_child(Session *s, const char *command
+ 		/* When PAM is enabled we rely on it to do the nologin check */
+ 		if (!options.use_pam)
+ 			do_nologin(pw);
+-		do_setusercontext(pw);
++		/* We are already separated */
++		if (!use_privsep)
++			do_setusercontext(pw);
+ 		/*
+ 		 * PAM session modules in do_setusercontext may have
+ 		 * generated messages, so if this in an interactive
+@@ -1806,8 +1818,9 @@ do_child(Session *s, const char *command
+ 		char *p, *args;
+ 
+ #ifdef WITH_SELINUX
+-		if (options.chroot_directory == NULL ||
+-		    strcasecmp(options.chroot_directory, "none") == 0) {
++		if (!use_privsep &&
++		    (options.chroot_directory == NULL ||
++		    strcasecmp(options.chroot_directory, "none") == 0)) {
+ 			ssh_selinux_copy_context();
+ 		}
+ #endif
diff --git a/openssh-5.3p1-sftp-chroot.patch b/openssh-5.3p1-sftp-chroot.patch
index d71a150..551705a 100644
--- a/openssh-5.3p1-sftp-chroot.patch
+++ b/openssh-5.3p1-sftp-chroot.patch
@@ -1,6 +1,6 @@
 diff -up openssh-5.3p1/channels.c.sftp-chroot openssh-5.3p1/channels.c
---- openssh-5.3p1/channels.c.sftp-chroot	2011-08-25 22:56:05.097081555 +0200
-+++ openssh-5.3p1/channels.c	2011-08-25 22:56:17.284027242 +0200
+--- openssh-5.3p1/channels.c.sftp-chroot	2012-05-14 15:07:37.162692861 +0200
++++ openssh-5.3p1/channels.c	2012-05-14 15:07:37.223697550 +0200
 @@ -839,8 +839,9 @@ channel_pre_open(Channel *c, fd_set *rea
  		if (c->extended_usage == CHAN_EXTENDED_WRITE &&
  		    buffer_len(&c->extended) > 0)
@@ -40,9 +40,9 @@ diff -up openssh-5.3p1/channels.c.sftp-chroot openssh-5.3p1/channels.c
  		}
  	}
 diff -up openssh-5.3p1/openbsd-compat/port-linux.c.sftp-chroot openssh-5.3p1/openbsd-compat/port-linux.c
---- openssh-5.3p1/openbsd-compat/port-linux.c.sftp-chroot	2011-08-25 22:56:16.941023541 +0200
-+++ openssh-5.3p1/openbsd-compat/port-linux.c	2011-08-25 22:56:17.445026125 +0200
-@@ -519,4 +519,21 @@ ssh_selinux_change_context(const char *n
+--- openssh-5.3p1/openbsd-compat/port-linux.c.sftp-chroot	2012-05-14 15:07:37.220691904 +0200
++++ openssh-5.3p1/openbsd-compat/port-linux.c	2012-05-14 15:09:21.246692262 +0200
+@@ -519,4 +519,24 @@ ssh_selinux_change_context(const char *n
  	xfree(oldctx);
  	xfree(newctx);
  }
@@ -59,14 +59,17 @@ diff -up openssh-5.3p1/openbsd-compat/port-linux.c.sftp-chroot openssh-5.3p1/ope
 +		logit("%s: getcon failed with %s", __func__, strerror (errno));
 +		return;
 +	}
++	if (ctx == NULL)
++		return;
++
 +	if (setcon(ctx) < 0)
 +		logit("%s: setcon failed with %s", __func__, strerror (errno));
 +	xfree(ctx);
 +}
  #endif /* WITH_SELINUX */
 diff -up openssh-5.3p1/openbsd-compat/port-linux.h.sftp-chroot openssh-5.3p1/openbsd-compat/port-linux.h
---- openssh-5.3p1/openbsd-compat/port-linux.h.sftp-chroot	2011-08-25 22:55:48.496222543 +0200
-+++ openssh-5.3p1/openbsd-compat/port-linux.h	2011-08-25 22:56:17.603031980 +0200
+--- openssh-5.3p1/openbsd-compat/port-linux.h.sftp-chroot	2012-05-14 15:07:37.072823237 +0200
++++ openssh-5.3p1/openbsd-compat/port-linux.h	2012-05-14 15:07:37.224698177 +0200
 @@ -24,6 +24,7 @@ int ssh_selinux_enabled(void);
  void ssh_selinux_setup_pty(char *, const char *);
  void ssh_selinux_setup_exec_context(char *);
@@ -76,8 +79,8 @@ diff -up openssh-5.3p1/openbsd-compat/port-linux.h.sftp-chroot openssh-5.3p1/ope
  
  #endif /* ! _PORT_LINUX_H */
 diff -up openssh-5.3p1/session.c.sftp-chroot openssh-5.3p1/session.c
---- openssh-5.3p1/session.c.sftp-chroot	2011-08-25 22:56:11.262030419 +0200
-+++ openssh-5.3p1/session.c	2011-08-26 10:01:26.419149592 +0200
+--- openssh-5.3p1/session.c.sftp-chroot	2012-05-14 15:07:37.192692480 +0200
++++ openssh-5.3p1/session.c	2012-05-14 15:07:37.225697525 +0200
 @@ -105,7 +105,7 @@
  /* func */
  
diff --git a/openssh-5.3p1-v6only.patch b/openssh-5.3p1-v6only.patch
new file mode 100644
index 0000000..5869d72
--- /dev/null
+++ b/openssh-5.3p1-v6only.patch
@@ -0,0 +1,18 @@
+diff -up openssh-5.3p1/channels.c.v6only openssh-5.3p1/channels.c
+--- openssh-5.3p1/channels.c.v6only	2012-04-26 11:12:22.306701457 +0200
++++ openssh-5.3p1/channels.c	2012-04-26 11:13:40.962041896 +0200
+@@ -2599,7 +2599,13 @@ channel_setup_fwd_listener(int type, con
+ 			verbose("socket: %.100s", strerror(errno));
+ 			continue;
+ 		}
+-
++#ifdef IPV6_V6ONLY
++		if (ai->ai_family == AF_INET6) {
++			int on = 1;
++			if (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0)
++				error("setsockopt IPV6_V6ONLY: %.100s", strerror(errno));
++		}
++#endif
+ 		channel_set_reuseaddr(sock);
+ 
+ 		debug("Local forwarding listening on %s port %s.",


More information about the scm-commits mailing list