File openssh-6.0p1-gsissh-SuSE.patch.patch of Package gsi-openssh

1,16c1,24
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/ChangeLog.gssapi openssh-6.0p1/ChangeLog.gssapi
< --- openssh-6.0p1.orig/ChangeLog.gssapi	1969-12-31 18:00:00.000000000 -0600
< +++ openssh-6.0p1/ChangeLog.gssapi	2012-05-27 17:50:01.000000000 -0500
< @@ -0,0 +1,113 @@
< +20110101
< +  - Finally update for OpenSSH 5.6p1
< +  - Add GSSAPIServerIdentity option from Jim Basney
< + 
< +20100308
< +  - [ Makefile.in, key.c, key.h ]
< +    Updates for OpenSSH 5.4p1
< +  - [ servconf.c ]
< +    Include GSSAPI options in the sshd -T configuration dump, and flag
< +    some older configuration options as being unsupported. Thanks to Colin 
< +    Watson.
< +  -
---
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/auth2.c openssh-6.0p1/auth2.c
> --- openssh-6.0p1.orig/auth2.c	2012-07-12 17:00:49.006194713 +0200
> +++ openssh-6.0p1/auth2.c	2012-07-12 17:05:00.459115081 +0200
> @@ -49,6 +49,7 @@
>  #include "dispatch.h"
>  #include "pathnames.h"
>  #include "buffer.h"
> +#include "canohost.h"
>  
>  #ifdef GSSAPI
>  #include "ssh-gss.h"
> @@ -69,6 +70,7 @@
>  extern Authmethod method_kbdint;
>  extern Authmethod method_hostbased;
>  #ifdef GSSAPI
> +extern Authmethod method_gsskeyex;
>  extern Authmethod method_gssapi;
>  extern Authmethod method_gssapi_old;
>  #endif
> @@ -76,10 +78,14 @@
>  extern Authmethod method_jpake;
>  #endif
>  
> +static int log_flag = 0;
18,21d25
< +20100124
< +  - [ sshconnect2.c ]
< +    Adapt to deal with additional element in Authmethod structure. Thanks to
< +    Colin Watson
23,35c27,45
< +20090615
< +  - [ gss-genr.c gss-serv.c kexgssc.c kexgsss.c monitor.c sshconnect2.c
< +      sshd.c ]
< +    Fix issues identified by Greg Hudson following a code review
< +	Check return value of gss_indicate_mechs
< +	Protect GSSAPI calls in monitor, so they can only be used if enabled
< +	Check return values of bignum functions in key exchange
< +	Use BN_clear_free to clear other side's DH value
< +	Make ssh_gssapi_id_kex more robust
< +	Only configure kex table pointers if GSSAPI is enabled
< +	Don't leak mechanism list, or gss mechanism list
< +	Cast data.length before printing
< +	If serverkey isn't provided, use an empty string, rather than NULL
---
>  Authmethod *authmethods[] = {
>  	&method_none,
>  	&method_pubkey,
>  #ifdef GSSAPI
> + 	&method_gsskeyex,
>  	&method_gssapi,
>  	&method_gssapi_old,
>  #endif
> @@ -223,20 +229,67 @@
>  	if (authctxt == NULL)
>  		fatal("input_userauth_request: no authctxt");
>  
> -	user = packet_get_cstring(NULL);
> -	service = packet_get_cstring(NULL);
> -	method = packet_get_cstring(NULL);
> -	debug("userauth-request for user %s service %s method %s", user, service, method);
> +	user = packet_get_string(NULL);
> +	service = packet_get_string(NULL);
> +	method = packet_get_string(NULL);
37,41c47,63
< +20090201
< +  - [ gss-genr.c gss-serv.c kex.h kexgssc.c readconf.c readconf.h ssh-gss.h
< +      ssh_config.5 sshconnet2.c ]
< +    Add support for the GSSAPIClientIdentity option, which allows the user
< +    to specify which GSSAPI identity to use to contact a given server
---
> +#ifdef GSSAPI
> +	if (user[0] == '\0') {
> +	    debug("received empty username for %s", method);
> +	    if (strcmp(method, "gssapi-keyex") == 0) {
> +		char *lname = NULL;
> +		PRIVSEP(ssh_gssapi_localname(&lname));
> +		if (lname && lname[0] != '\0') {
> +		    xfree(user);
> +		    user = lname;
> +		    debug("set username to %s from gssapi context", user);
> +		} else {
> +		    debug("failed to set username from gssapi context");
> +		    packet_send_debug("failed to set username from gssapi context");
> +		}
> +	    }
> +	}
> +#endif
43,47c65,181
< +20080404
< +  - [ gss-serv.c ]
< +    Add code to actually implement GSSAPIStrictAcceptCheck, which had somehow
< +    been omitted from a previous version of this patch. Reported by Borislav
< +    Stoichkov
---
> +	debug("userauth-request for user %s service %s method %s",
> +	      user[0] ? user : "<implicit>", service, method);
> +	if (!log_flag) {
> +		logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", 
> +		      get_remote_ipaddr(), get_remote_port(),
> +              user[0] ? user : "<implicit>");
> +		log_flag = 1;
> +	}
>  	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
>  
>  	if ((style = strchr(user, ':')) != NULL)
>  		*style++ = 0;
>  
> -	if (authctxt->attempt++ == 0) {
> -		/* setup auth context */
> +	/* If first time or username changed or empty username,
> +	   setup/reset authentication context. */
> +	if ((authctxt->attempt++ == 0) ||
> +	    (strcmp(user, authctxt->user) != 0) ||
> +	    (strcmp(user, "") == 0)) {
> +		if (authctxt->user) {
> +		    xfree(authctxt->user);
> +		    authctxt->user = NULL;
> +		}
> +		authctxt->valid = 0;
> +        authctxt->user = xstrdup(user);
> +        if (strcmp(service, "ssh-connection") != 0) {
> +            packet_disconnect("Unsupported service %s", service);
> +        }
> +#ifdef GSSAPI
> +		/* If we're going to set the username based on the
> +		   GSSAPI context later, then wait until then to
> +		   verify it. Just put in placeholders for now. */
> +		if ((strcmp(user, "") == 0) &&
> +		    ((strcmp(method, "gssapi") == 0) ||
> +		     (strcmp(method, "gssapi-with-mic") == 0))) {
> +			authctxt->pw = fakepw();
> +		} else {
> +#endif
>  		authctxt->pw = PRIVSEP(getpwnamallow(user));
> -		authctxt->user = xstrdup(user);
> -		if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
> +		if (authctxt->pw) {
>  			authctxt->valid = 1;
>  			debug2("input_userauth_request: setting up authctxt for %s", user);
>  		} else {
> @@ -246,20 +299,25 @@
>  			PRIVSEP(audit_event(SSH_INVALID_USER));
>  #endif
>  		}
> +#ifdef GSSAPI
> +		} /* endif for setting username based on GSSAPI context */
> +#endif
>  #ifdef USE_PAM
>  		if (options.use_pam)
>  			PRIVSEP(start_pam(authctxt));
>  #endif
>  		setproctitle("%s%s", authctxt->valid ? user : "unknown",
>  		    use_privsep ? " [net]" : "");
> -		authctxt->service = xstrdup(service);
> -		authctxt->style = style ? xstrdup(style) : NULL;
> -		if (use_privsep)
> -			mm_inform_authserv(service, style);
> -		userauth_banner();
> -	} else if (strcmp(user, authctxt->user) != 0 ||
> -	    strcmp(service, authctxt->service) != 0) {
> -		packet_disconnect("Change of username or service not allowed: "
> +		if (authctxt->attempt == 1) {
> +            authctxt->service = xstrdup(service);
> +            authctxt->style = style ? xstrdup(style) : NULL;
> +            if (use_privsep)
> +                mm_inform_authserv(service, style);
> +            userauth_banner();
> +		}
> +	}
> +	if (strcmp(service, authctxt->service) != 0) {
> +		packet_disconnect("Change of service not allowed: "
>  		    "(%s,%s) -> (%s,%s)",
>  		    authctxt->user, authctxt->service, user, service);
>  	}
> @@ -347,7 +405,7 @@
>  		/* now we can break out */
>  		authctxt->success = 1;
>  	} else {
> -
> +		/* Dont count server configuration issues against the client */
>  		/* Allow initial try of "none" auth without failure penalty */
>  		if (!authctxt->server_caused_failure &&
>  		    (authctxt->attempt > 1 || strcmp(method, "none") != 0))
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/auth2.c.orig openssh-6.0p1/auth2.c.orig
> --- openssh-6.0p1.orig/auth2.c.orig	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/auth2.c.orig	2012-07-12 16:59:34.316733314 +0200
> @@ -0,0 +1,411 @@
> +/* $OpenBSD: auth2.c,v 1.124 2011/12/07 05:44:38 djm Exp $ */
> +/*
> + * Copyright (c) 2000 Markus Friedl.  All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
> + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
> + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
> + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
49,52c183
< +20070317
< +  - [ gss-serv-krb5.c ]
< +    Remove C99ism, where new_ccname was being declared in the middle of a 
< +    function
---
> +#include "includes.h"
54,57c185,187
< +20061220
< +  - [ servconf.c ]
< +    Make default for GSSAPIStrictAcceptorCheck be Yes, to match previous, and 
< +    documented, behaviour. Reported by Dan Watson.
---
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <sys/uio.h>
59,72c189,193
< +20060910
< +  - [ gss-genr.c kexgssc.c kexgsss.c kex.h monitor.c sshconnect2.c sshd.c
< +      ssh-gss.h ]
< +    add support for gss-group14-sha1 key exchange mechanisms
< +  - [ gss-serv.c servconf.c servconf.h sshd_config sshd_config.5 ]
< +    Add GSSAPIStrictAcceptorCheck option to allow the disabling of
< +    acceptor principal checking on multi-homed machines.
< +    <Bugzilla #928>
< +  - [ sshd_config ssh_config ]
< +    Add settings for GSSAPIKeyExchange and GSSAPITrustDNS to the sample
< +    configuration files
< +  - [ kexgss.c kegsss.c sshconnect2.c sshd.c ]
< +    Code cleanup. Replace strlen/xmalloc/snprintf sequences with xasprintf()
< +    Limit length of error messages displayed by client
---
> +#include <fcntl.h>
> +#include <pwd.h>
> +#include <stdarg.h>
> +#include <string.h>
> +#include <unistd.h>
74,78c195,208
< +20060909
< +  - [ gss-genr.c gss-serv.c ]
< +    move ssh_gssapi_acquire_cred() and ssh_gssapi_server_ctx to be server
< +    only, where they belong 
< +    <Bugzilla #1225>
---
> +#include "atomicio.h"
> +#include "xmalloc.h"
> +#include "ssh2.h"
> +#include "packet.h"
> +#include "log.h"
> +#include "buffer.h"
> +#include "servconf.h"
> +#include "compat.h"
> +#include "key.h"
> +#include "hostfile.h"
> +#include "auth.h"
> +#include "dispatch.h"
> +#include "pathnames.h"
> +#include "buffer.h"
80,83c210,213
< +20060829
< +  - [ gss-serv-krb5.c ]
< +    Fix CCAPI credentials cache name when creating KRB5CCNAME environment 
< +    variable
---
> +#ifdef GSSAPI
> +#include "ssh-gss.h"
> +#endif
> +#include "monitor_wrap.h"
85,88c215,234
< +20060828
< +  - [ gss-genr.c ]
< +    Avoid Heimdal context freeing problem
< +    <Fixed upstream 20060829>
---
> +/* import */
> +extern ServerOptions options;
> +extern u_char *session_id2;
> +extern u_int session_id2_len;
> +extern Buffer loginmsg;
> +
> +/* methods */
> +
> +extern Authmethod method_none;
> +extern Authmethod method_pubkey;
> +extern Authmethod method_passwd;
> +extern Authmethod method_kbdint;
> +extern Authmethod method_hostbased;
> +#ifdef GSSAPI
> +extern Authmethod method_gssapi;
> +extern Authmethod method_gssapi_old;
> +#endif
> +#ifdef JPAKE
> +extern Authmethod method_jpake;
> +#endif
90,93c236,250
< +20060818
< +  - [ gss-genr.c ssh-gss.h sshconnect2.c ]
< +    Make sure that SPENGO is disabled 
< +    <Bugzilla #1218 - Fixed upstream 20060818>
---
> +Authmethod *authmethods[] = {
> +	&method_none,
> +	&method_pubkey,
> +#ifdef GSSAPI
> +	&method_gssapi,
> +	&method_gssapi_old,
> +#endif
> +#ifdef JPAKE
> +	&method_jpake,
> +#endif
> +	&method_passwd,
> +	&method_kbdint,
> +	&method_hostbased,
> +	NULL
> +};
95,122c252
< +20060421
< +  - [ gssgenr.c, sshconnect2.c ]
< +    a few type changes (signed versus unsigned, int versus size_t) to
< +    fix compiler errors/warnings 
< +    (from jbasney AT ncsa.uiuc.edu)
< +  - [ kexgssc.c, sshconnect2.c ]
< +    fix uninitialized variable warnings
< +    (from jbasney AT ncsa.uiuc.edu)
< +  - [ gssgenr.c ]
< +    pass oid to gss_display_status (helpful when using GSSAPI mechglue)
< +    (from jbasney AT ncsa.uiuc.edu)
< +    <Bugzilla #1220 >
< +  - [ gss-serv-krb5.c ]
< +    #ifdef HAVE_GSSAPI_KRB5 should be #ifdef HAVE_GSSAPI_KRB5_H
< +    (from jbasney AT ncsa.uiuc.edu)
< +    <Fixed upstream 20060304>
< +  - [ readconf.c, readconf.h, ssh_config.5, sshconnect2.c 
< +    add client-side GssapiKeyExchange option
< +    (from jbasney AT ncsa.uiuc.edu)
< +  - [ sshconnect2.c ]
< +    add support for GssapiTrustDns option for gssapi-with-mic
< +    (from jbasney AT ncsa.uiuc.edu)
< +    <gssapi-with-mic support is Bugzilla #1008>
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/HPN-README openssh-6.0p1/HPN-README
< --- openssh-6.0p1.orig/HPN-README	1969-12-31 18:00:00.000000000 -0600
< +++ openssh-6.0p1/HPN-README	2012-05-27 17:50:01.000000000 -0500
< @@ -0,0 +1,128 @@
< +Notes:
---
> +/* protocol */
124,136c254,255
< +MULTI-THREADED CIPHER:
< +The AES cipher in CTR mode has been multithreaded (MTR-AES-CTR). This will allow ssh installations
< +on hosts with multiple cores to use more than one processing core during encryption. 
< +Tests have show significant throughput performance increases when using MTR-AES-CTR up 
< +to and including a full gigabit per second on quad core systems. It should be possible to 
< +achieve full line rate on dual core systems but OS and data management overhead makes this
< +more difficult to achieve. The cipher stream from MTR-AES-CTR is entirely compatible with single 
< +thread AES-CTR (ST-AES-CTR) implementations and should be 100% backward compatible. Optimal 
< +performance requires the MTR-AES-CTR mode be enabled on both ends of the connection. 
< +The MTR-AES-CTR replaces ST-AES-CTR and is used in exactly the same way with the same
< +nomenclature. 
< +Use examples: 	ssh -caes128-ctr you@host.com
< +		scp -oCipher=aes256-ctr file you@host.com:~/file
---
> +static void input_service_request(int, u_int32_t, void *);
> +static void input_userauth_request(int, u_int32_t, void *);
138,143c257,259
< +NONE CIPHER:
< +To use the NONE option you must have the NoneEnabled switch set on the server and
< +you *must* have *both* NoneEnabled and NoneSwitch set to yes on the client. The NONE
< +feature works with ALL ssh subsystems (as far as we can tell) *AS LONG AS* a tty is not 
< +spawned. If a user uses the -T switch to prevent a tty being created the NONE cipher will
< +be disabled. 
---
> +/* helper */
> +static Authmethod *authmethod_lookup(const char *);
> +static char *authmethods_get(void);
145,148c261,267
< +The performance increase will only be as good as the network and TCP stack tuning
< +on the reciever side of the connection allows. As a rule of thumb a user will need 
< +at least 10Mb/s connection with a 100ms RTT to see a doubling of performance. The
< +HPN-SSH home page describes this in greater detail. 
---
> +char *
> +auth2_read_banner(void)
> +{
> +	struct stat st;
> +	char *banner = NULL;
> +	size_t len, n;
> +	int fd;
150c269,278
< +http://www.psc.edu/networking/projects/hpn-ssh
---
> +	if ((fd = open(options.banner, O_RDONLY)) == -1)
> +		return (NULL);
> +	if (fstat(fd, &st) == -1) {
> +		close(fd);
> +		return (NULL);
> +	}
> +	if (st.st_size <= 0 || st.st_size > 1*1024*1024) {
> +		close(fd);
> +		return (NULL);
> +	}
152c280,283
< +BUFFER SIZES:
---
> +	len = (size_t)st.st_size;		/* truncate */
> +	banner = xmalloc(len + 1);
> +	n = atomicio(read, fd, banner, len);
> +	close(fd);
154,155c285,289
< +If HPN is disabled the receive buffer size will be set to the 
< +OpenSSH default of 64K.
---
> +	if (n != len) {
> +		xfree(banner);
> +		return (NULL);
> +	}
> +	banner[n] = '\0';
157,158c291,292
< +If an HPN system connects to a nonHPN system the receive buffer will
< +be set to the HPNBufferSize value. The default is 2MB but user adjustable.
---
> +	return (banner);
> +}
160,161c294,298
< +If an HPN to HPN connection is established a number of different things might
< +happen based on the user options and conditions. 
---
> +void
> +userauth_send_banner(const char *msg)
> +{
> +	if (datafellows & SSH_BUG_BANNER)
> +		return;
163,167c300,305
< +Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set 
< +HPN Buffer Size = up to 64MB 
< +This is the default state. The HPN buffer size will grow to a maximum of 64MB 
< +as the TCP receive buffer grows. The maximum HPN Buffer size of 64MB is 
< +geared towards 10GigE transcontinental connections. 
---
> +	packet_start(SSH2_MSG_USERAUTH_BANNER);
> +	packet_put_cstring(msg);
> +	packet_put_cstring("");		/* language, unused */
> +	packet_send();
> +	debug("%s: sent", __func__);
> +}
169,172c307,310
< +Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
< +HPN Buffer Size = TCP receive buffer value. 
< +Users on non-autotuning systesm should disable TCPRcvBufPoll in the 
< +ssh_cofig and sshd_config
---
> +static void
> +userauth_banner(void)
> +{
> +	char *banner = NULL;
174,176c312,315
< +Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
< +HPN Buffer Size = minmum of TCP receive buffer and HPNBufferSize. 
< +This would be the system defined TCP receive buffer (RWIN).
---
> +	if (options.banner == NULL ||
> +	    strcasecmp(options.banner, "none") == 0 ||
> +	    (datafellows & SSH_BUG_BANNER) != 0)
> +		return;
178,180c317,324
< +Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf SET
< +HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. 
< +Generally there is no need to set both.
---
> +	if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
> +		goto done;
> +	userauth_send_banner(banner);
> +
> +done:
> +	if (banner)
> +		xfree(banner);
> +}
182,184c326,335
< +Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set
< +HPN Buffer Size = grows to HPNBufferSize
< +The buffer will grow up to the maximum size specified here. 
---
> +/*
> + * loop until authctxt->success == TRUE
> + */
> +void
> +do_authentication2(Authctxt *authctxt)
> +{
> +	dispatch_init(&dispatch_protocol_error);
> +	dispatch_set(SSH2_MSG_SERVICE_REQUEST, &input_service_request);
> +	dispatch_run(DISPATCH_BLOCK, &authctxt->success, authctxt);
> +}
186,190c337,345
< +Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf SET
< +HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. 
< +Generally there is no need to set both of these, especially on autotuning 
< +systems. However, if the users wishes to override the autotuning this would be 
< +one way to do it.
---
> +/*ARGSUSED*/
> +static void
> +input_service_request(int type, u_int32_t seq, void *ctxt)
> +{
> +	Authctxt *authctxt = ctxt;
> +	u_int len;
> +	int acceptit = 0;
> +	char *service = packet_get_cstring(&len);
> +	packet_check_eom();
192,195c347,348
< +Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf SET
< +HPN Buffer Size = TCPRcvBuf. 
< +This will override autotuning and set the TCP recieve buffer to the user defined 
< +value.
---
> +	if (authctxt == NULL)
> +		fatal("input_service_request: no authctxt");
196a350,357
> +	if (strcmp(service, "ssh-userauth") == 0) {
> +		if (!authctxt->success) {
> +			acceptit = 1;
> +			/* now we can handle user-auth requests */
> +			dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &input_userauth_request);
> +		}
> +	}
> +	/* XXX all other service requests are denied */
198c359,369
< +HPN Specific Configuration options
---
> +	if (acceptit) {
> +		packet_start(SSH2_MSG_SERVICE_ACCEPT);
> +		packet_put_cstring(service);
> +		packet_send();
> +		packet_write_wait();
> +	} else {
> +		debug("bad service request %s", service);
> +		packet_disconnect("bad service request %s", service);
> +	}
> +	xfree(service);
> +}
200,207c371,378
< +TcpRcvBuf=[int]KB client
< +      set the TCP socket receive buffer to n Kilobytes. It can be set up to the 
< +maximum socket size allowed by the system. This is useful in situations where 
< +the tcp receive window is set low but the maximum buffer size is set 
< +higher (as is typical). This works on a per TCP connection basis. You can also 
< +use this to artifically limit the transfer rate of the connection. In these 
< +cases the throughput will be no more than n/RTT. The minimum buffer size is 1KB. 
< +Default is the current system wide tcp receive buffer size.
---
> +/*ARGSUSED*/
> +static void
> +input_userauth_request(int type, u_int32_t seq, void *ctxt)
> +{
> +	Authctxt *authctxt = ctxt;
> +	Authmethod *m = NULL;
> +	char *user, *service, *method, *style = NULL;
> +	int authenticated = 0;
209,213c380,381
< +TcpRcvBufPoll=[yes/no] client/server
< +      enable of disable the polling of the tcp receive buffer through the life 
< +of the connection. You would want to make sure that this option is enabled 
< +for systems making use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista) 
< +default is yes.
---
> +	if (authctxt == NULL)
> +		fatal("input_userauth_request: no authctxt");
215,219c383,427
< +NoneEnabled=[yes/no] client/server
< +      enable or disable the use of the None cipher. Care must always be used 
< +when enabling this as it will allow users to send data in the clear. However, 
< +it is important to note that authentication information remains encrypted 
< +even if this option is enabled. Set to no by default.
---
> +	user = packet_get_cstring(NULL);
> +	service = packet_get_cstring(NULL);
> +	method = packet_get_cstring(NULL);
> +	debug("userauth-request for user %s service %s method %s", user, service, method);
> +	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
> +
> +	if ((style = strchr(user, ':')) != NULL)
> +		*style++ = 0;
> +
> +	if (authctxt->attempt++ == 0) {
> +		/* setup auth context */
> +		authctxt->pw = PRIVSEP(getpwnamallow(user));
> +		authctxt->user = xstrdup(user);
> +		if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
> +			authctxt->valid = 1;
> +			debug2("input_userauth_request: setting up authctxt for %s", user);
> +		} else {
> +			logit("input_userauth_request: invalid user %s", user);
> +			authctxt->pw = fakepw();
> +#ifdef SSH_AUDIT_EVENTS
> +			PRIVSEP(audit_event(SSH_INVALID_USER));
> +#endif
> +		}
> +#ifdef USE_PAM
> +		if (options.use_pam)
> +			PRIVSEP(start_pam(authctxt));
> +#endif
> +		setproctitle("%s%s", authctxt->valid ? user : "unknown",
> +		    use_privsep ? " [net]" : "");
> +		authctxt->service = xstrdup(service);
> +		authctxt->style = style ? xstrdup(style) : NULL;
> +		if (use_privsep)
> +			mm_inform_authserv(service, style);
> +		userauth_banner();
> +	} else if (strcmp(user, authctxt->user) != 0 ||
> +	    strcmp(service, authctxt->service) != 0) {
> +		packet_disconnect("Change of username or service not allowed: "
> +		    "(%s,%s) -> (%s,%s)",
> +		    authctxt->user, authctxt->service, user, service);
> +	}
> +	/* reset state */
> +	auth2_challenge_stop(authctxt);
> +#ifdef JPAKE
> +	auth2_jpake_stop(authctxt);
> +#endif
221,228c429,433
< +NoneSwitch=[yes/no] client
< +     Switch the encryption cipher being used to the None cipher after
< +authentication takes place. NoneEnabled must be enabled on both the client
< +and server side of the connection. When the connection switches to the NONE
< +cipher a warning is sent to STDERR. The connection attempt will fail with an
< +error if a client requests a NoneSwitch from the server that does not explicitly
< +have NoneEnabled set to yes. Note: The NONE cipher cannot be used in
< +interactive (shell) sessions and it will fail silently. Set to no by default.
---
> +#ifdef GSSAPI
> +	/* XXX move to auth2_gssapi_stop() */
> +	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
> +	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
> +#endif
230,233c435,436
< +HPNDisabled=[yes/no] client/server
< +     In some situations, such as transfers on a local area network, the impact 
< +of the HPN code produces a net decrease in performance. In these cases it is 
< +helpful to disable the HPN functionality. By default HPNDisabled is set to no. 
---
> +	authctxt->postponed = 0;
> +	authctxt->server_caused_failure = 0;
235,241c438,444
< +HPNBufferSize=[int]KB client/server
< +     This is the default buffer size the HPN functionality uses when interacting
< +with nonHPN SSH installations. Conceptually this is similar to the TcpRcvBuf
< +option as applied to the internal SSH flow control. This value can range from 
< +1KB to 64MB (1-65536). Use of oversized or undersized buffers can cause performance
< +problems depending on the length of the network path. The default size of this buffer
< +is 2MB.
---
> +	/* 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);
242a446,449
> +	xfree(service);
> +	xfree(user);
> +	xfree(method);
> +}
244,279c451,454
< +Credits: This patch was conceived, designed, and led by Chris Rapier (rapier@psc.edu)
< +         The majority of the actual coding for versions up to HPN12v1 was performed
< +         by Michael Stevens (mstevens@andrew.cmu.edu). The MT-AES-CTR cipher was 
< +	 implemented by Ben Bennet (ben@psc.edu). This work was financed, in part,
< +         by Cisco System, Inc., the National Library of Medicine, 
< +	 and the National Science Foundation. 
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/LICENSE.globus_usage openssh-6.0p1/LICENSE.globus_usage
< --- openssh-6.0p1.orig/LICENSE.globus_usage	1969-12-31 18:00:00.000000000 -0600
< +++ openssh-6.0p1/LICENSE.globus_usage	2012-05-27 17:50:01.000000000 -0500
< @@ -0,0 +1,18 @@
< +/*
< + * Portions of the Usage Metrics suport code are derived from the
< + * Globus project's GridFTP subject to the following license.
< + *
< + * Copyright 2010 University of Chicago
< + *
< + * Licensed under the Apache License, Version 2.0 (the "License");
< + * you may not use this file except in compliance with the License.
< + * You may obtain a copy of the License at
< + *
< + * http://www.apache.org/licenses/LICENSE-2.0
< + *
< + * Unless required by applicable law or agreed to in writing, software
< + * distributed under the License is distributed on an "AS IS" BASIS,
< + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
< + * See the License for the specific language governing permissions and
< + * limitations under the License.
< + */
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/Makefile.in openssh-6.0p1/Makefile.in
< --- openssh-6.0p1.orig/Makefile.in	2012-04-03 20:27:57.000000000 -0500
< +++ openssh-6.0p1/Makefile.in	2012-05-27 17:50:01.000000000 -0500
< @@ -59,6 +59,8 @@
<  EXEEXT=@EXEEXT@
<  MANFMT=@MANFMT@
<  
< +INSTALL_GSISSH=@INSTALL_GSISSH@
---
> +void
> +userauth_finish(Authctxt *authctxt, int authenticated, char *method)
> +{
> +	char *methods;
281,290c456,617
<  TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT)
<  
<  LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
< @@ -70,6 +72,7 @@
<  	atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
<  	monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
<  	kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \
< +	kexgssc.o \
<  	msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o jpake.o \
<  	schnorr.o ssh-pkcs11.o
---
> +	if (!authctxt->valid && authenticated)
> +		fatal("INTERNAL ERROR: authenticated invalid user %s",
> +		    authctxt->user);
> +
> +	/* Special handling for root */
> +	if (authenticated && authctxt->pw->pw_uid == 0 &&
> +	    !auth_root_allowed(method)) {
> +		authenticated = 0;
> +#ifdef SSH_AUDIT_EVENTS
> +		PRIVSEP(audit_event(SSH_LOGIN_ROOT_DENIED));
> +#endif
> +	}
> +
> +#ifdef USE_PAM
> +	if (options.use_pam && authenticated) {
> +		if (!PRIVSEP(do_pam_account())) {
> +			/* if PAM returned a message, send it to the user */
> +			if (buffer_len(&loginmsg) > 0) {
> +				buffer_append(&loginmsg, "\0", 1);
> +				userauth_send_banner(buffer_ptr(&loginmsg));
> +				packet_write_wait();
> +			}
> +			fatal("Access denied for user %s by PAM account "
> +			    "configuration", authctxt->user);
> +		}
> +	}
> +#endif
> +
> +#ifdef _UNICOS
> +	if (authenticated && cray_access_denied(authctxt->user)) {
> +		authenticated = 0;
> +		fatal("Access denied for user %s.",authctxt->user);
> +	}
> +#endif /* _UNICOS */
> +
> +	/* Log before sending the reply */
> +	auth_log(authctxt, authenticated, method, " ssh2");
> +
> +	if (authctxt->postponed)
> +		return;
> +
> +	/* XXX todo: check if multiple auth methods are needed */
> +	if (authenticated == 1) {
> +		/* turn off userauth */
> +		dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &dispatch_protocol_ignore);
> +		packet_start(SSH2_MSG_USERAUTH_SUCCESS);
> +		packet_send();
> +		packet_write_wait();
> +		/* 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))
> +			authctxt->failures++;
> +		if (authctxt->failures >= options.max_authtries) {
> +#ifdef SSH_AUDIT_EVENTS
> +			PRIVSEP(audit_event(SSH_LOGIN_EXCEED_MAXTRIES));
> +#endif
> +			packet_disconnect(AUTH_FAIL_MSG, authctxt->user);
> +		}
> +		methods = authmethods_get();
> +		packet_start(SSH2_MSG_USERAUTH_FAILURE);
> +		packet_put_cstring(methods);
> +		packet_put_char(0);	/* XXX partial success, unused */
> +		packet_send();
> +		packet_write_wait();
> +		xfree(methods);
> +	}
> +}
> +
> +static char *
> +authmethods_get(void)
> +{
> +	Buffer b;
> +	char *list;
> +	int i;
> +
> +	buffer_init(&b);
> +	for (i = 0; authmethods[i] != NULL; i++) {
> +		if (strcmp(authmethods[i]->name, "none") == 0)
> +			continue;
> +		if (authmethods[i]->enabled != NULL &&
> +		    *(authmethods[i]->enabled) != 0) {
> +			if (buffer_len(&b) > 0)
> +				buffer_append(&b, ",", 1);
> +			buffer_append(&b, authmethods[i]->name,
> +			    strlen(authmethods[i]->name));
> +		}
> +	}
> +	buffer_append(&b, "\0", 1);
> +	list = xstrdup(buffer_ptr(&b));
> +	buffer_free(&b);
> +	return list;
> +}
> +
> +static Authmethod *
> +authmethod_lookup(const char *name)
> +{
> +	int i;
> +
> +	if (name != NULL)
> +		for (i = 0; authmethods[i] != NULL; i++)
> +			if (authmethods[i]->enabled != NULL &&
> +			    *(authmethods[i]->enabled) != 0 &&
> +			    strcmp(name, authmethods[i]->name) == 0)
> +				return authmethods[i];
> +	debug2("Unrecognized authentication method name: %s",
> +	    name ? name : "NULL");
> +	return NULL;
> +}
> +
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/auth2.c.rej openssh-6.0p1/auth2.c.rej
> --- openssh-6.0p1.orig/auth2.c.rej	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/auth2.c.rej	2012-07-12 17:01:14.078685297 +0200
> @@ -0,0 +1,40 @@
> +***************
> +*** 69,84 ****
> +  extern Authmethod method_kbdint;
> +  extern Authmethod method_hostbased;
> +  #ifdef GSSAPI
> +  extern Authmethod method_gssapi;
> +  #endif
> +  #ifdef JPAKE
> +  extern Authmethod method_jpake;
> +  #endif
> +  
> +  Authmethod *authmethods[] = {
> +  	&method_none,
> +  	&method_pubkey,
> +  #ifdef GSSAPI
> +  	&method_gssapi,
> +  #endif
> +  #ifdef JPAKE
> +--- 70,90 ----
> +  extern Authmethod method_kbdint;
> +  extern Authmethod method_hostbased;
> +  #ifdef GSSAPI
> ++ extern Authmethod method_gsskeyex;
> +  extern Authmethod method_gssapi;
> +  #endif
> +  #ifdef JPAKE
> +  extern Authmethod method_jpake;
> +  #endif
> +  
> ++ static int log_flag = 0;
> ++ 
> ++ 
> +  Authmethod *authmethods[] = {
> +  	&method_none,
> +  	&method_pubkey,
> +  #ifdef GSSAPI
> ++ 	&method_gsskeyex,
> +  	&method_gssapi,
> +  #endif
> +  #ifdef JPAKE
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/auth2-gss.c openssh-6.0p1/auth2-gss.c
> --- openssh-6.0p1.orig/auth2-gss.c	2012-07-12 17:00:48.970194008 +0200
> +++ openssh-6.0p1/auth2-gss.c	2012-07-12 17:01:14.058684906 +0200
> @@ -1,7 +1,7 @@
>  /* $OpenBSD: auth2-gss.c,v 1.17 2011/03/10 02:52:57 djm Exp $ */
292,404d618
< @@ -86,9 +89,11 @@
<  	auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \
<  	monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \
<  	auth-krb5.o \
< -	auth2-gss.o gss-serv.o gss-serv-krb5.o \
< +	auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o\
< +	gss-serv-gsi.o \
<  	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
<  	sftp-server.o sftp-common.o \
< +	ssh-globus-usage.o \
<  	roaming_common.o roaming_serv.o \
<  	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
<  	sandbox-seccomp-filter.o
< @@ -277,6 +282,20 @@
<  	ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
<  	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
<  	ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
< +	if [ ! -z "$(INSTALL_GSISSH)" ]; then \
< +		rm -f $(DESTDIR)$(bindir)/gsissh; \
< +		ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/gsissh; \
< +		rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsissh.1; \
< +		ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/gsissh.1; \
< +		rm -f $(DESTDIR)$(bindir)/gsiscp; \
< +		ln -s ./scp$(EXEEXT) $(DESTDIR)$(bindir)/gsiscp; \
< +		rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsiscp.1; \
< +		ln -s ./scp.1 $(DESTDIR)$(mandir)/$(mansubdir)1/gsiscp.1; \
< +		rm -f $(DESTDIR)$(bindir)/gsisftp; \
< +		ln -s ./sftp$(EXEEXT) $(DESTDIR)$(bindir)/gsisftp; \
< +		rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsisftp.1; \
< +		ln -s ./sftp.1 $(DESTDIR)$(mandir)/$(mansubdir)1/gsisftp.1; \
< +	fi
<  
<  install-sysconf:
<  	if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \
< @@ -348,6 +367,11 @@
<  
<  uninstall:
<  	-rm -f $(DESTDIR)$(bindir)/slogin
< +	if [ ! -z "$(INSTALL_GSISSH)" ]; then \
< +		rm -f $(DESTDIR)$(bindir)/gsiscp; \
< +		rm -f $(DESTDIR)$(bindir)/gsissh; \
< +		rm -f $(DESTDIR)$(bindir)/gsisftp; \
< +	fi
<  	-rm -f $(DESTDIR)$(bindir)/ssh$(EXEEXT)
<  	-rm -f $(DESTDIR)$(bindir)/scp$(EXEEXT)
<  	-rm -f $(DESTDIR)$(bindir)/ssh-add$(EXEEXT)
< @@ -361,6 +385,11 @@
<  	-rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
<  	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
<  	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
< +	if [ ! -z "$(INSTALL_GSISSH)" ]; then \
< +		rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsissh.1; \
< +		rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsiscp.1; \
< +		rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsisftp.1; \
< +	fi
<  	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
<  	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1
<  	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/auth-krb5.c openssh-6.0p1/auth-krb5.c
< --- openssh-6.0p1.orig/auth-krb5.c	2009-12-20 17:49:22.000000000 -0600
< +++ openssh-6.0p1/auth-krb5.c	2012-05-27 17:50:01.000000000 -0500
< @@ -170,8 +170,13 @@
<  
<  	len = strlen(authctxt->krb5_ticket_file) + 6;
<  	authctxt->krb5_ccname = xmalloc(len);
< +#ifdef USE_CCAPI
< +	snprintf(authctxt->krb5_ccname, len, "API:%s",
< +	    authctxt->krb5_ticket_file);
< +#else
<  	snprintf(authctxt->krb5_ccname, len, "FILE:%s",
<  	    authctxt->krb5_ticket_file);
< +#endif
<  
<  #ifdef USE_PAM
<  	if (options.use_pam)
< @@ -226,15 +231,22 @@
<  #ifndef HEIMDAL
<  krb5_error_code
<  ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
< -	int tmpfd, ret;
< +	int ret;
<  	char ccname[40];
<  	mode_t old_umask;
< +#ifdef USE_CCAPI
< +	char cctemplate[] = "API:krb5cc_%d";
< +#else
< +	char cctemplate[] = "FILE:/tmp/krb5cc_%d_XXXXXXXXXX";
< +	int tmpfd;
< +#endif
<  
<  	ret = snprintf(ccname, sizeof(ccname),
< -	    "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
< +	    cctemplate, geteuid());
<  	if (ret < 0 || (size_t)ret >= sizeof(ccname))
<  		return ENOMEM;
<  
< +#ifndef USE_CCAPI
<  	old_umask = umask(0177);
<  	tmpfd = mkstemp(ccname + strlen("FILE:"));
<  	umask(old_umask);
< @@ -249,6 +261,7 @@
<  		return errno;
<  	}
<  	close(tmpfd);
< +#endif
<  
<  	return (krb5_cc_resolve(ctx, ccname, ccache));
<  }
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/auth-pam.c openssh-6.0p1/auth-pam.c
< --- openssh-6.0p1.orig/auth-pam.c	2009-07-12 07:07:21.000000000 -0500
< +++ openssh-6.0p1/auth-pam.c	2012-05-27 17:50:01.000000000 -0500
< @@ -30,7 +30,7 @@
<   */
406,408c620,621
<   * Copyright (c) 2003,2004 Damien Miller <djm@mindrot.org>
< - * Copyright (c) 2003,2004 Darren Tucker <dtucker@zip.com.au>
< + * Copyright (c) 2003,2004,2006 Darren Tucker <dtucker@zip.com.au>
---
> - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
> + * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
410,421c623,625
<   * Permission to use, copy, modify, and distribute this software for any
<   * purpose with or without fee is hereby granted, provided that the above
< @@ -122,6 +122,10 @@
<   */
<  typedef pthread_t sp_pthread_t;
<  #else
< +#define pthread_create openssh_pthread_create
< +#define pthread_exit openssh_pthread_exit
< +#define pthread_cancel openssh_pthread_cancel
< +#define pthread_join openssh_pthread_join
<  typedef pid_t sp_pthread_t;
<  #endif
---
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions
> @@ -47,11 +47,60 @@
423,425c627
< @@ -272,6 +276,49 @@
<  # define pam_chauthtok(a,b)	(sshpam_chauthtok_ruid((a), (b)))
<  #endif
---
>  extern ServerOptions options;
427,428c629,639
< +struct passwd *
< +sshpam_getpw(const char *user)
---
> +static void ssh_gssapi_userauth_error(Gssctxt *ctxt);
>  static void input_gssapi_token(int type, u_int32_t plen, void *ctxt);
>  static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt);
>  static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
>  static void input_gssapi_errtok(int, u_int32_t, void *);
>  
> +/* 
> + * The 'gssapi_keyex' userauth mechanism.
> + */
> +static int
> +userauth_gsskeyex(Authctxt *authctxt)
430c641,644
< +	struct passwd *pw;
---
> +	int authenticated = 0;
> +	Buffer b, b2;
> +	gss_buffer_desc mic, gssbuf, gssbuf2;
> +	u_int len;
432,433c646,647
< +	if ((pw = getpwnam(user)) != NULL)
< +		return(pw);
---
> +	mic.value = packet_get_string(&len);
> +	mic.length = len;
435,442c649
< +	debug("PAM: faking passwd struct for user '%.100s'", user);
< +	if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL)
< +		return NULL;
< +	pw->pw_name = xstrdup(user);	/* XXX leak */
< +	pw->pw_shell = "/bin/true";
< +	pw->pw_gecos = "sshd fake PAM user";
< +	return (pw);
< +}
---
> +	packet_check_eom();
444,449c651,652
< +void
< +sshpam_check_userchanged(void)
< +{
< +	int sshpam_err;
< +	struct passwd *pw;
< +	const char *user;
---
> +	ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
> +	    "gssapi-keyex");
451,466c654,673
< +	debug("sshpam_check_userchanged");
< +	sshpam_err = pam_get_item(sshpam_handle, PAM_USER, &user);
< +	if (sshpam_err != PAM_SUCCESS)
< +		fatal("PAM: could not get PAM_USER: %s",
< +		    pam_strerror(sshpam_handle, sshpam_err));
< +	if (strcmp(user, sshpam_authctxt->pw->pw_name) != 0) {
< +		debug("PAM: user mapped from '%.100s' to '%.100s'",
< +		    sshpam_authctxt->pw->pw_name, user);
< +		if ((pw = getpwnam(user)) == NULL)
< +			fatal("PAM: could not get passwd entry for user "
< +			    "'%.100s' provided by PAM_USER", user);
< +		pwfree(sshpam_authctxt->pw);
< +		sshpam_authctxt->pw = pw;
< +		sshpam_authctxt->valid = allowed_user(pw);
< +		debug("PAM: user '%.100s' now %svalid", user,
< +		    sshpam_authctxt->valid ? "" : "in");
---
> +	gssbuf.value = buffer_ptr(&b);
> +	gssbuf.length = buffer_len(&b);
> +
> +	/* client may have used empty username to determine target
> +	   name from GSSAPI context */
> +	ssh_gssapi_buildmic(&b2, "", authctxt->service, "gssapi-keyex");
> +
> +	gssbuf2.value = buffer_ptr(&b2);
> +	gssbuf2.length = buffer_len(&b2);
> +
> +	/* gss_kex_context is NULL with privsep, so we can't check it here */
> +	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, 
> +						   &gssbuf, &mic))) ||
> +	    !GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, 
> +						   &gssbuf2, &mic)))) {
> +	    if (authctxt->valid && authctxt->user && authctxt->user[0]) {
> +            authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
> +                                                      authctxt->pw,
> +                                                      1 /* gssapi-keyex */));
> +	    }
467a675,680
> +	
> +	buffer_free(&b);
> +	buffer_free(&b2);
> +	xfree(mic.value);
> +
> +	return (authenticated);
470,480c683,688
<  void
<  sshpam_password_change_required(int reqd)
<  {
< @@ -294,7 +341,7 @@
<  static void
<  import_environments(Buffer *b)
<  {
< -	char *env;
< +	char *env, *user;
<  	u_int i, num_env;
<  	int err;
---
>  /*
>   * We only support those mechanisms that we know about (ie ones that we know
>   * how to check local user kuserok and the like)
> @@ -68,7 +117,10 @@
>  	u_int len;
>  	u_char *doid = NULL;
482,494c690,695
< @@ -304,6 +351,15 @@
<  	/* Import variables set by do_pam_account */
<  	sshpam_account_status = buffer_get_int(b);
<  	sshpam_password_change_required(buffer_get_int(b));
< +	if (options.permit_pam_user_change) {
< +        user = buffer_get_string(b, NULL);
< +        debug("PAM: got username '%.100s' from thread", user);
< +        if ((err = pam_set_item(sshpam_handle, PAM_USER, user)) != PAM_SUCCESS)
< +            fatal("PAM: failed to set PAM_USER: %s",
< +                  pam_strerror(sshpam_handle, err));
< +        pwfree(sshpam_authctxt->pw);
< +        sshpam_authctxt->pw = pwcopy(sshpam_getpw(user));
< +    }
---
> -	if (!authctxt->valid || authctxt->user == NULL)
> +	/* authctxt->valid may be 0 if we haven't yet determined
> +	   username from gssapi context. */
> +
> +	if (authctxt->user == NULL)
>  		return (0);
496,739c697,704
<  	/* Import environment from subprocess */
<  	num_env = buffer_get_int(b);
< @@ -469,6 +525,9 @@
<  	if (sshpam_err != PAM_SUCCESS)
<  		goto auth_fail;
<  
< +	if (options.permit_pam_user_change) {
< +        sshpam_check_userchanged();
< +    }
<  	if (compat20) {
<  		if (!do_pam_account()) {
<  			sshpam_err = PAM_ACCT_EXPIRED;
< @@ -489,6 +548,9 @@
<  	/* Export variables set by do_pam_account */
<  	buffer_put_int(&buffer, sshpam_account_status);
<  	buffer_put_int(&buffer, sshpam_authctxt->force_pwchange);
< +	if (options.permit_pam_user_change) {
< +        buffer_put_cstring(&buffer, sshpam_authctxt->pw->pw_name);
< +    }
<  
<  	/* Export any environment strings set in child */
<  	for(i = 0; environ[i] != NULL; i++)
< @@ -907,6 +969,12 @@
<  	debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err,
<  	    pam_strerror(sshpam_handle, sshpam_err));
<  
< +	if (options.permit_pam_user_change) {
< +        sshpam_check_userchanged();
< +        if (getpwnam(sshpam_authctxt->pw->pw_name) == NULL)
< +            fatal("PAM: completed authentication but PAM account invalid");
< +    }
< +
<  	if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
<  		sshpam_account_status = 0;
<  		return (sshpam_account_status);
< @@ -1206,6 +1274,9 @@
<  		    pam_strerror(sshpam_handle, sshpam_err));
<  
<  	sshpam_err = pam_authenticate(sshpam_handle, flags);
< +	if (options.permit_pam_user_change) {
< +        sshpam_check_userchanged();
< +    }
<  	sshpam_password = NULL;
<  	if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
<  		debug("PAM: password authentication accepted for %.100s",
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/auth-pam.h openssh-6.0p1/auth-pam.h
< --- openssh-6.0p1.orig/auth-pam.h	2004-09-11 07:17:26.000000000 -0500
< +++ openssh-6.0p1/auth-pam.h	2012-05-27 17:50:01.000000000 -0500
< @@ -46,5 +46,6 @@
<  void sshpam_cleanup(void);
<  int sshpam_auth_passwd(Authctxt *, const char *);
<  int is_pam_session_open(void);
< +struct passwd *sshpam_getpw(const char *);
<  
<  #endif /* USE_PAM */
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/auth.c openssh-6.0p1/auth.c
< --- openssh-6.0p1.orig/auth.c	2011-05-29 06:40:42.000000000 -0500
< +++ openssh-6.0p1/auth.c	2012-05-27 17:50:01.000000000 -0500
< @@ -72,6 +72,9 @@
<  #include "authfile.h"
<  #include "monitor_wrap.h"
<  
< +#include "version.h"
< +#include "ssh-globus-usage.h"
< +
<  /* import */
<  extern ServerOptions options;
<  extern int use_privsep;
< @@ -275,7 +278,8 @@
<  	    authmsg,
<  	    method,
<  	    authctxt->valid ? "" : "invalid user ",
< -	    authctxt->user,
< +	    (authctxt->user && authctxt->user[0]) ?
< +		authctxt->user : "unknown",
<  	    get_remote_ipaddr(),
<  	    get_remote_port(),
<  	    info);
< @@ -297,6 +301,21 @@
<  	if (authenticated == 0 && !authctxt->postponed)
<  		audit_event(audit_classify_auth(method));
<  #endif
< +	if (authenticated) {
< +		char *userdn = NULL;
< +		char *mech_name = NULL;
< +		ssh_gssapi_get_client_info(&userdn, &mech_name);
< +		debug("REPORTING (%s) (%s) (%s) (%s) (%s) (%s) (%s)",
< +			 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION),
< +			 method, mech_name?mech_name:"NULL", get_remote_ipaddr(),
< +			 (authctxt->user && authctxt->user[0])?
< +				authctxt->user : "unknown",
< +			userdn?userdn:"NULL");
< +		ssh_globus_send_usage_metrics(SSH_RELEASE,
< +					SSLeay_version(SSLEAY_VERSION),
< +					method, mech_name, get_remote_ipaddr(),
< +					authctxt->user, userdn);
< +	}
<  }
<  
<  /*
< @@ -553,6 +572,10 @@
<  #endif
<  
<  	pw = getpwnam(user);
< +#ifdef USE_PAM
< +	if (options.use_pam && options.permit_pam_user_change && pw == NULL)
< +		pw = sshpam_getpw(user);
< +#endif
<  
<  #if defined(_AIX) && defined(HAVE_SETAUTHDB)
<  	aix_restoreauthdb();
< @@ -572,7 +595,8 @@
<  #endif
<  	if (pw == NULL) {
<  		logit("Invalid user %.100s from %.100s",
< -		    user, get_remote_ipaddr());
< +		      (user && user[0]) ? user : "unknown",
< +		      get_remote_ipaddr());
<  #ifdef CUSTOM_FAILED_LOGIN
<  		record_failed_login(user,
<  		    get_canonical_hostname(options.use_dns), "ssh");
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/auth.h openssh-6.0p1/auth.h
< --- openssh-6.0p1.orig/auth.h	2011-05-29 06:39:38.000000000 -0500
< +++ openssh-6.0p1/auth.h	2012-05-27 17:50:01.000000000 -0500
< @@ -41,6 +41,9 @@
<  #ifdef KRB5
<  #include <krb5.h>
<  #endif
< +#ifdef AFS_KRB5
< +#include <krbafs.h>
< +#endif
<  
<  typedef struct Authctxt Authctxt;
<  typedef struct Authmethod Authmethod;
< @@ -71,6 +74,9 @@
<  	char		*krb5_ticket_file;
<  	char		*krb5_ccname;
<  #endif
< +#ifdef SESSION_HOOKS
< +        char            *session_env_file;
< +#endif
<  	Buffer		*loginmsg;
<  	void		*methoddata;
<  };
< @@ -146,6 +152,7 @@
<  void	userauth_finish(Authctxt *, int, char *);
<  void	userauth_send_banner(const char *);
<  int	auth_root_allowed(char *);
< +char *expand_authorized_keys(const char *filename, struct passwd *pw);
<  
<  char	*auth2_read_banner(void);
<  
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/auth2-gss.c openssh-6.0p1/auth2-gss.c
< --- openssh-6.0p1.orig/auth2-gss.c	2011-05-04 23:04:11.000000000 -0500
< +++ openssh-6.0p1/auth2-gss.c	2012-05-27 17:50:01.000000000 -0500
< @@ -1,7 +1,7 @@
<  /* $OpenBSD: auth2-gss.c,v 1.17 2011/03/10 02:52:57 djm Exp $ */
<  
<  /*
< - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
< + * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
<   *
<   * Redistribution and use in source and binary forms, with or without
<   * modification, are permitted provided that the following conditions
< @@ -47,11 +47,60 @@
<  
<  extern ServerOptions options;
<  
< +static void ssh_gssapi_userauth_error(Gssctxt *ctxt);
<  static void input_gssapi_token(int type, u_int32_t plen, void *ctxt);
<  static void input_gssapi_mic(int type, u_int32_t plen, void *ctxt);
<  static void input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt);
<  static void input_gssapi_errtok(int, u_int32_t, void *);
<  
< +/* 
< + * The 'gssapi_keyex' userauth mechanism.
< + */
< +static int
< +userauth_gsskeyex(Authctxt *authctxt)
< +{
< +	int authenticated = 0;
< +	Buffer b, b2;
< +	gss_buffer_desc mic, gssbuf, gssbuf2;
< +	u_int len;
< +
< +	mic.value = packet_get_string(&len);
< +	mic.length = len;
< +
< +	packet_check_eom();
< +
< +	ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
< +	    "gssapi-keyex");
< +
< +	gssbuf.value = buffer_ptr(&b);
< +	gssbuf.length = buffer_len(&b);
< +
< +	/* client may have used empty username to determine target
< +	   name from GSSAPI context */
< +	ssh_gssapi_buildmic(&b2, "", authctxt->service, "gssapi-keyex");
< +
< +	gssbuf2.value = buffer_ptr(&b2);
< +	gssbuf2.length = buffer_len(&b2);
< +
< +	/* gss_kex_context is NULL with privsep, so we can't check it here */
< +	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, 
< +						   &gssbuf, &mic))) ||
< +	    !GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gss_kex_context, 
< +						   &gssbuf2, &mic)))) {
< +	    if (authctxt->valid && authctxt->user && authctxt->user[0]) {
< +            authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user,
< +                                                      authctxt->pw,
< +                                                      1 /* gssapi-keyex */));
< +	    }
< +	}
< +	
< +	buffer_free(&b);
< +	buffer_free(&b2);
< +	xfree(mic.value);
< +
< +	return (authenticated);
< +}
< +
<  /*
<   * We only support those mechanisms that we know about (ie ones that we know
<   * how to check local user kuserok and the like)
< @@ -68,7 +117,10 @@
<  	u_int len;
<  	u_char *doid = NULL;
<  
< -	if (!authctxt->valid || authctxt->user == NULL)
< +	/* authctxt->valid may be 0 if we haven't yet determined
< +	   username from gssapi context. */
< +
< +	if (authctxt->user == NULL)
<  		return (0);
<  
<  	mechs = packet_get_int();
< @@ -138,7 +190,7 @@
<  	Gssctxt *gssctxt;
<  	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
<  	gss_buffer_desc recv_tok;
< -	OM_uint32 maj_status, min_status, flags;
< +	OM_uint32 maj_status, min_status, flags=0;
<  	u_int len;
---
>  	mechs = packet_get_int();
> @@ -138,7 +190,7 @@
>  	Gssctxt *gssctxt;
>  	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
>  	gss_buffer_desc recv_tok;
> -	OM_uint32 maj_status, min_status, flags;
> +	OM_uint32 maj_status, min_status, flags=0;
>  	u_int len;
750c715
< @@ -219,6 +272,32 @@
---
> @@ -228,6 +281,32 @@
783c748
< @@ -235,6 +314,8 @@
---
> @@ -244,6 +323,8 @@
792c757
< @@ -244,7 +325,13 @@
---
> @@ -253,7 +334,13 @@
807c772
< @@ -278,8 +365,16 @@
---
> @@ -287,8 +374,16 @@
825c790
< @@ -294,6 +389,29 @@
---
> @@ -303,6 +398,29 @@
855,862c820,837
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/auth2.c openssh-6.0p1/auth2.c
< --- openssh-6.0p1.orig/auth2.c	2011-12-18 17:52:51.000000000 -0600
< +++ openssh-6.0p1/auth2.c	2012-05-27 17:50:01.000000000 -0500
< @@ -49,6 +49,7 @@
<  #include "dispatch.h"
<  #include "pathnames.h"
<  #include "buffer.h"
< +#include "canohost.h"
---
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/auth2-gss.c.orig openssh-6.0p1/auth2-gss.c.orig
> --- openssh-6.0p1.orig/auth2-gss.c.orig	2012-07-12 17:00:51.322240030 +0200
> +++ openssh-6.0p1/auth2-gss.c.orig	2012-07-12 16:59:34.276732528 +0200
> @@ -179,6 +179,15 @@
>  				dispatch_set(
>  				    SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
>  				    &input_gssapi_exchange_complete);
> +
> +			/*
> +			 * Old style 'gssapi' didn't have the GSSAPI_MIC
> +			 * and went straight to sending exchange_complete
> +			 */
> +			if (options.gss_enable_mitm)
> +				dispatch_set(
> +				    SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
> +				    &input_gssapi_exchange_complete);
>  		}
>  	}
864,875c839,841
<  #ifdef GSSAPI
<  #include "ssh-gss.h"
< @@ -69,16 +70,21 @@
<  extern Authmethod method_kbdint;
<  extern Authmethod method_hostbased;
<  #ifdef GSSAPI
< +extern Authmethod method_gsskeyex;
<  extern Authmethod method_gssapi;
<  #endif
<  #ifdef JPAKE
<  extern Authmethod method_jpake;
<  #endif
---
> @@ -300,4 +309,10 @@
>  	&options.gss_authentication
>  };
877,878c843,847
< +static int log_flag = 0;
< +
---
> +Authmethod method_gssapi_old = {
> +	"gssapi",
> +	userauth_gssapi,
> +	&options.gss_enable_mitm
> +};
880,890c849,855
<  Authmethod *authmethods[] = {
<  	&method_none,
<  	&method_pubkey,
<  #ifdef GSSAPI
< +	&method_gsskeyex,
<  	&method_gssapi,
<  #endif
<  #ifdef JPAKE
< @@ -221,20 +227,67 @@
<  	if (authctxt == NULL)
<  		fatal("input_userauth_request: no authctxt");
---
>  #endif /* GSSAPI */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/auth.c openssh-6.0p1/auth.c
> --- openssh-6.0p1.orig/auth.c	2012-07-12 17:00:48.950193617 +0200
> +++ openssh-6.0p1/auth.c	2012-07-12 17:01:14.030684358 +0200
> @@ -72,6 +72,9 @@
>  #include "authfile.h"
>  #include "monitor_wrap.h"
892,916c857,858
< -	user = packet_get_cstring(NULL);
< -	service = packet_get_cstring(NULL);
< -	method = packet_get_cstring(NULL);
< -	debug("userauth-request for user %s service %s method %s", user, service, method);
< +	user = packet_get_string(NULL);
< +	service = packet_get_string(NULL);
< +	method = packet_get_string(NULL);
< +
< +#ifdef GSSAPI
< +	if (user[0] == '\0') {
< +	    debug("received empty username for %s", method);
< +	    if (strcmp(method, "gssapi-keyex") == 0) {
< +		char *lname = NULL;
< +		PRIVSEP(ssh_gssapi_localname(&lname));
< +		if (lname && lname[0] != '\0') {
< +		    xfree(user);
< +		    user = lname;
< +		    debug("set username to %s from gssapi context", user);
< +		} else {
< +		    debug("failed to set username from gssapi context");
< +		    packet_send_debug("failed to set username from gssapi context");
< +		}
< +	    }
< +	}
< +#endif
---
> +#include "version.h"
> +#include "ssh-globus-usage.h"
918,924c860,890
< +	debug("userauth-request for user %s service %s method %s",
< +	      user[0] ? user : "<implicit>", service, method);
< +	if (!log_flag) {
< +		logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", 
< +		      get_remote_ipaddr(), get_remote_port(),
< +              user[0] ? user : "<implicit>");
< +		log_flag = 1;
---
>  /* import */
>  extern ServerOptions options;
>  extern int use_privsep;
> @@ -275,7 +278,8 @@
>  	    authmsg,
>  	    method,
>  	    authctxt->valid ? "" : "invalid user ",
> -	    authctxt->user,
> +	    (authctxt->user && authctxt->user[0]) ?
> +		authctxt->user : "unknown",
>  	    get_remote_ipaddr(),
>  	    get_remote_port(),
>  	    info);
> @@ -303,6 +307,21 @@
>  	if (authenticated == 0 && !authctxt->postponed)
>  		audit_event(audit_classify_auth(method));
>  #endif
> +	if (authenticated) {
> +		char *userdn = NULL;
> +		char *mech_name = NULL;
> +		ssh_gssapi_get_client_info(&userdn, &mech_name);
> +		debug("REPORTING (%s) (%s) (%s) (%s) (%s) (%s) (%s)",
> +			 SSH_RELEASE, SSLeay_version(SSLEAY_VERSION),
> +			 method, mech_name?mech_name:"NULL", get_remote_ipaddr(),
> +			 (authctxt->user && authctxt->user[0])?
> +				authctxt->user : "unknown",
> +			userdn?userdn:"NULL");
> +		ssh_globus_send_usage_metrics(SSH_RELEASE,
> +					SSLeay_version(SSLEAY_VERSION),
> +					method, mech_name, get_remote_ipaddr(),
> +					authctxt->user, userdn);
926c892
<  	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
---
>  }
928,929c894,896
<  	if ((style = strchr(user, ':')) != NULL)
<  		*style++ = 0;
---
>  /*
> @@ -559,6 +578,10 @@
>  #endif
931,955c898,901
< -	if (authctxt->attempt++ == 0) {
< -		/* setup auth context */
< +	/* If first time or username changed or empty username,
< +	   setup/reset authentication context. */
< +	if ((authctxt->attempt++ == 0) ||
< +	    (strcmp(user, authctxt->user) != 0) ||
< +	    (strcmp(user, "") == 0)) {
< +		if (authctxt->user) {
< +		    xfree(authctxt->user);
< +		    authctxt->user = NULL;
< +		}
< +		authctxt->valid = 0;
< +        authctxt->user = xstrdup(user);
< +        if (strcmp(service, "ssh-connection") != 0) {
< +            packet_disconnect("Unsupported service %s", service);
< +        }
< +#ifdef GSSAPI
< +		/* If we're going to set the username based on the
< +		   GSSAPI context later, then wait until then to
< +		   verify it. Just put in placeholders for now. */
< +		if ((strcmp(user, "") == 0) &&
< +		    ((strcmp(method, "gssapi") == 0) ||
< +		     (strcmp(method, "gssapi-with-mic") == 0))) {
< +			authctxt->pw = fakepw();
< +		} else {
---
>  	pw = getpwnam(user);
> +#ifdef USE_PAM
> +	if (options.use_pam && options.permit_pam_user_change && pw == NULL)
> +		pw = sshpam_getpw(user);
957,965c903,906
<  		authctxt->pw = PRIVSEP(getpwnamallow(user));
< -		authctxt->user = xstrdup(user);
< -		if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
< +		if (authctxt->pw) {
<  			authctxt->valid = 1;
<  			debug2("input_userauth_request: setting up authctxt for %s", user);
<  		} else {
< @@ -244,20 +297,25 @@
<  			PRIVSEP(audit_event(SSH_INVALID_USER));
---
>  
>  #if defined(_AIX) && defined(HAVE_SETAUTHDB)
>  	aix_restoreauthdb();
> @@ -578,7 +601,8 @@
967,973c908,921
<  		}
< +#ifdef GSSAPI
< +		} /* endif for setting username based on GSSAPI context */
< +#endif
<  #ifdef USE_PAM
<  		if (options.use_pam)
<  			PRIVSEP(start_pam(authctxt));
---
>  	if (pw == NULL) {
>  		logit("Invalid user %.100s from %.100s",
> -		    user, get_remote_ipaddr());
> +		      (user && user[0]) ? user : "unknown",
> +		      get_remote_ipaddr());
>  #ifdef CUSTOM_FAILED_LOGIN
>  		record_failed_login(user,
>  		    get_canonical_hostname(options.use_dns), "ssh");
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/auth.c.orig openssh-6.0p1/auth.c.orig
> --- openssh-6.0p1.orig/auth.c.orig	2012-07-12 17:00:51.490243317 +0200
> +++ openssh-6.0p1/auth.c.orig	2012-07-12 16:59:34.256732139 +0200
> @@ -293,6 +293,12 @@
>  		    get_canonical_hostname(options.use_dns), "ssh", &loginmsg);
>  # endif
975,991c923,926
<  		setproctitle("%s%s", authctxt->valid ? user : "unknown",
<  		    use_privsep ? " [net]" : "");
< -		authctxt->service = xstrdup(service);
< -		authctxt->style = style ? xstrdup(style) : NULL;
< -		if (use_privsep)
< -			mm_inform_authserv(service, style);
< -		userauth_banner();
< -	} else if (strcmp(user, authctxt->user) != 0 ||
< -	    strcmp(service, authctxt->service) != 0) {
< -		packet_disconnect("Change of username or service not allowed: "
< +		if (authctxt->attempt == 1) {
< +            authctxt->service = xstrdup(service);
< +            authctxt->style = style ? xstrdup(style) : NULL;
< +            if (use_privsep)
< +                mm_inform_authserv(service, style);
< +            userauth_banner();
< +		}
---
> +#if HAVE_LINUX_AUDIT
> +	if (authenticated == 0 && !authctxt->postponed) {
> +		linux_audit_record_event(-1, authctxt->user, NULL,
> +			get_remote_ipaddr(), "sshd", 0);
993,1024c928,952
< +	if (strcmp(service, authctxt->service) != 0) {
< +		packet_disconnect("Change of service not allowed: "
<  		    "(%s,%s) -> (%s,%s)",
<  		    authctxt->user, authctxt->service, user, service);
<  	}
< @@ -345,7 +403,7 @@
<  		/* now we can break out */
<  		authctxt->success = 1;
<  	} else {
< -
< +		/* Dont count server configuration issues against the client */
<  		/* Allow initial try of "none" auth without failure penalty */
<  		if (!authctxt->server_caused_failure &&
<  		    (authctxt->attempt > 1 || strcmp(method, "none") != 0))
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/buffer.c openssh-6.0p1/buffer.c
< --- openssh-6.0p1.orig/buffer.c	2010-02-11 16:23:40.000000000 -0600
< +++ openssh-6.0p1/buffer.c	2012-05-27 17:50:01.000000000 -0500
< @@ -127,7 +127,7 @@
<  
<  	/* Increase the size of the buffer and retry. */
<  	newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ);
< -	if (newlen > BUFFER_MAX_LEN)
< +	if (newlen > BUFFER_MAX_LEN_HPN)
<  		fatal("buffer_append_space: alloc %u not supported",
<  		    newlen);
<  	buffer->buf = xrealloc(buffer->buf, 1, newlen);
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/buffer.h openssh-6.0p1/buffer.h
< --- openssh-6.0p1.orig/buffer.h	2010-09-09 20:39:27.000000000 -0500
< +++ openssh-6.0p1/buffer.h	2012-05-27 17:50:01.000000000 -0500
< @@ -16,6 +16,9 @@
<  #ifndef BUFFER_H
<  #define BUFFER_H
---
> +#endif
>  #ifdef SSH_AUDIT_EVENTS
>  	if (authenticated == 0 && !authctxt->postponed)
>  		audit_event(audit_classify_auth(method));
> @@ -577,6 +583,10 @@
>  		record_failed_login(user,
>  		    get_canonical_hostname(options.use_dns), "ssh");
>  #endif
> +#ifdef HAVE_LINUX_AUDIT
> +		linux_audit_record_event(-1, user, NULL, get_remote_ipaddr(),
> +			"sshd", 0);
> +#endif
>  #ifdef SSH_AUDIT_EVENTS
>  		audit_event(SSH_INVALID_USER);
>  #endif /* SSH_AUDIT_EVENTS */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/auth.h openssh-6.0p1/auth.h
> --- openssh-6.0p1.orig/auth.h	2012-07-12 17:00:48.954193695 +0200
> +++ openssh-6.0p1/auth.h	2012-07-12 17:01:14.038684514 +0200
> @@ -41,6 +41,9 @@
>  #ifdef KRB5
>  #include <krb5.h>
>  #endif
> +#ifdef AFS_KRB5
> +#include <krbafs.h>
> +#endif
1026,1035c954,970
< +/* move the following to a more appropriate place and name */
< +#define BUFFER_MAX_LEN_HPN          0x4000000  /* 64MB */
< +
<  typedef struct {
<  	u_char	*buf;		/* Buffer for data. */
<  	u_int	 alloc;		/* Number of bytes allocated for data. */
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/canohost.c openssh-6.0p1/canohost.c
< --- openssh-6.0p1.orig/canohost.c	2010-10-11 21:28:12.000000000 -0500
< +++ openssh-6.0p1/canohost.c	2012-05-27 17:50:01.000000000 -0500
< @@ -16,6 +16,7 @@
---
>  typedef struct Authctxt Authctxt;
>  typedef struct Authmethod Authmethod;
> @@ -71,6 +74,9 @@
>  	char		*krb5_ticket_file;
>  	char		*krb5_ccname;
>  #endif
> +#ifdef SESSION_HOOKS
> +        char            *session_env_file;
> +#endif
>  	Buffer		*loginmsg;
>  	void		*methoddata;
>  };
> @@ -146,6 +152,7 @@
>  void	userauth_finish(Authctxt *, int, char *);
>  void	userauth_send_banner(const char *);
>  int	auth_root_allowed(char *);
> +char *expand_authorized_keys(const char *filename, struct passwd *pw);
1037,1039c972
<  #include <sys/types.h>
<  #include <sys/socket.h>
< +#include <sys/param.h>          /* for MAXHOSTNAMELEN */
---
>  char	*auth2_read_banner(void);
1041,1082c974,977
<  #include <netinet/in.h>
<  #include <arpa/inet.h>
< @@ -438,3 +439,33 @@
<  {
<  	return get_port(1);
<  }
< +
< +void
< +resolve_localhost(char **host)
< +{
< +    struct hostent *hostinfo;
< +
< +    hostinfo = gethostbyname(*host);
< +    if (hostinfo == NULL || hostinfo->h_name == NULL) {
< +	debug("gethostbyname(%s) failed", *host);
< +	return;
< +    }
< +    if (hostinfo->h_addrtype == AF_INET) {
< +	struct in_addr addr;
< +	addr = *(struct in_addr *)(hostinfo->h_addr);
< +	if (ntohl(addr.s_addr) == INADDR_LOOPBACK) {
< +	    char buf[MAXHOSTNAMELEN];
< +	    if (gethostname(buf, sizeof(buf)) < 0) {
< +		debug("gethostname() failed");
< +		return;
< +	    }
< +	    hostinfo = gethostbyname(buf);
< +	    xfree(*host);
< +	    if (hostinfo == NULL || hostinfo->h_name == NULL) {
< +		*host = xstrdup(buf);
< +	    } else {
< +		*host = xstrdup(hostinfo->h_name);
< +	    }
< +	}
< +    }
< +}
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/canohost.h openssh-6.0p1/canohost.h
< --- openssh-6.0p1.orig/canohost.h	2009-06-21 04:50:08.000000000 -0500
< +++ openssh-6.0p1/canohost.h	2012-05-27 17:50:01.000000000 -0500
< @@ -26,4 +26,6 @@
<  int		 get_sock_port(int, int);
<  void		 clear_cached_addr(void);
---
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/auth-krb5.c openssh-6.0p1/auth-krb5.c
> --- openssh-6.0p1.orig/auth-krb5.c	2012-07-12 17:00:48.882192286 +0200
> +++ openssh-6.0p1/auth-krb5.c	2012-07-12 17:01:13.942682637 +0200
> @@ -170,8 +170,13 @@
1084,1092c979,987
< +void		 resolve_localhost(char **host);
< +
<  void		 ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/channels.c openssh-6.0p1/channels.c
< --- openssh-6.0p1.orig/channels.c	2011-10-02 02:59:03.000000000 -0500
< +++ openssh-6.0p1/channels.c	2012-05-27 17:50:01.000000000 -0500
< @@ -173,8 +173,14 @@
<  static int connect_next(struct channel_connect *);
<  static void channel_connect_ctx_free(struct channel_connect *);
---
>  	len = strlen(authctxt->krb5_ticket_file) + 6;
>  	authctxt->krb5_ccname = xmalloc(len);
> +#ifdef USE_CCAPI
> +	snprintf(authctxt->krb5_ccname, len, "API:%s",
> +	    authctxt->krb5_ticket_file);
> +#else
>  	snprintf(authctxt->krb5_ccname, len, "FILE:%s",
>  	    authctxt->krb5_ticket_file);
> +#endif
1094,1098c989,1004
< +
< +static int hpn_disabled = 0;
< +static int hpn_buffer_size = 2 * 1024 * 1024;
< +
<  /* -- channel core */
---
>  #ifdef USE_PAM
>  	if (options.use_pam)
> @@ -226,15 +231,22 @@
>  #ifndef HEIMDAL
>  krb5_error_code
>  ssh_krb5_cc_gen(krb5_context ctx, krb5_ccache *ccache) {
> -	int tmpfd, ret;
> +	int ret;
>  	char ccname[40];
>  	mode_t old_umask;
> +#ifdef USE_CCAPI
> +	char cctemplate[] = "API:krb5cc_%d";
> +#else
> +	char cctemplate[] = "FILE:/tmp/krb5cc_%d_XXXXXXXXXX";
> +	int tmpfd;
> +#endif
1100,1114c1006,1022
< +
< +
<  Channel *
<  channel_by_id(int id)
<  {
< @@ -318,6 +324,7 @@
<  	c->local_window_max = window;
<  	c->local_consumed = 0;
<  	c->local_maxpacket = maxpack;
< +	c->dynamic_window = 0;
<  	c->remote_id = -1;
<  	c->remote_name = xstrdup(remote_name);
<  	c->remote_window = 0;
< @@ -817,11 +824,37 @@
<  		FD_SET(c->sock, writeset);
---
>  	ret = snprintf(ccname, sizeof(ccname),
> -	    "FILE:/tmp/krb5cc_%d_XXXXXXXXXX", geteuid());
> +	    cctemplate, geteuid());
>  	if (ret < 0 || (size_t)ret >= sizeof(ccname))
>  		return ENOMEM;
>  
> +#ifndef USE_CCAPI
>  	old_umask = umask(0177);
>  	tmpfd = mkstemp(ccname + strlen("FILE:"));
>  	umask(old_umask);
> @@ -249,6 +261,7 @@
>  		return errno;
>  	}
>  	close(tmpfd);
> +#endif
>  
>  	return (krb5_cc_resolve(ctx, ccname, ccache));
1115a1024,1045
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/auth-pam.c openssh-6.0p1/auth-pam.c
> --- openssh-6.0p1.orig/auth-pam.c	2012-07-12 17:00:48.894192521 +0200
> +++ openssh-6.0p1/auth-pam.c	2012-07-12 17:01:14.002683810 +0200
> @@ -30,7 +30,7 @@
>   */
>  /*
>   * Copyright (c) 2003,2004 Damien Miller <djm@mindrot.org>
> - * Copyright (c) 2003,2004 Darren Tucker <dtucker@zip.com.au>
> + * Copyright (c) 2003,2004,2006 Darren Tucker <dtucker@zip.com.au>
>   *
>   * Permission to use, copy, modify, and distribute this software for any
>   * purpose with or without fee is hereby granted, provided that the above
> @@ -122,6 +122,10 @@
>   */
>  typedef pthread_t sp_pthread_t;
>  #else
> +#define pthread_create openssh_pthread_create
> +#define pthread_exit openssh_pthread_exit
> +#define pthread_cancel openssh_pthread_cancel
> +#define pthread_join openssh_pthread_join
>  typedef pid_t sp_pthread_t;
>  #endif
1117,1120c1047,1054
< +int channel_tcpwinsz () {
< +        u_int32_t tcpwinsz = 0;
< +        socklen_t optsz = sizeof(tcpwinsz);
< +	int ret = -1;
---
> @@ -272,6 +276,49 @@
>  # define pam_chauthtok(a,b)	(sshpam_chauthtok_ruid((a), (b)))
>  #endif
>  
> +struct passwd *
> +sshpam_getpw(const char *user)
> +{
> +	struct passwd *pw;
1122,1134c1056,1091
< +	/* if we aren't on a socket return 128KB*/
< +	if(!packet_connection_is_on_socket()) 
< +	    return(128*1024);
< +	ret = getsockopt(packet_get_connection_in(),
< +			 SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
< +	/* return no more than 64MB */
< +	if ((ret == 0) && tcpwinsz > BUFFER_MAX_LEN_HPN)
< +	    tcpwinsz = BUFFER_MAX_LEN_HPN;
< +#if 0 /* too verbose */
< +	debug2("tcpwinsz: %d for connection: %d", tcpwinsz, 
< +	       packet_get_connection_in());
< +#endif
< +	return(tcpwinsz);
---
> +	if ((pw = getpwnam(user)) != NULL)
> +		return(pw);
> +
> +	debug("PAM: faking passwd struct for user '%.100s'", user);
> +	if ((pw = getpwnam(SSH_PRIVSEP_USER)) == NULL)
> +		return NULL;
> +	pw->pw_name = xstrdup(user);	/* XXX leak */
> +	pw->pw_shell = "/bin/true";
> +	pw->pw_gecos = "sshd fake PAM user";
> +	return (pw);
> +}
> +
> +void
> +sshpam_check_userchanged(void)
> +{
> +	int sshpam_err;
> +	struct passwd *pw;
> +	const char *user;
> +
> +	debug("sshpam_check_userchanged");
> +	sshpam_err = pam_get_item(sshpam_handle, PAM_USER, &user);
> +	if (sshpam_err != PAM_SUCCESS)
> +		fatal("PAM: could not get PAM_USER: %s",
> +		    pam_strerror(sshpam_handle, sshpam_err));
> +	if (strcmp(user, sshpam_authctxt->pw->pw_name) != 0) {
> +		debug("PAM: user mapped from '%.100s' to '%.100s'",
> +		    sshpam_authctxt->pw->pw_name, user);
> +		if ((pw = getpwnam(user)) == NULL)
> +			fatal("PAM: could not get passwd entry for user "
> +			    "'%.100s' provided by PAM_USER", user);
> +		pwfree(sshpam_authctxt->pw);
> +		sshpam_authctxt->pw = pw;
> +		sshpam_authctxt->valid = allowed_user(pw);
> +		debug("PAM: user '%.100s' now %svalid", user,
> +		    sshpam_authctxt->valid ? "" : "in");
> +	}
1136a1094,1097
>  void
>  sshpam_password_change_required(int reqd)
>  {
> @@ -294,7 +341,7 @@
1138c1099
<  channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
---
>  import_environments(Buffer *b)
1140c1101,1104
<  	u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
---
> -	char *env;
> +	char *env, *user;
>  	u_int i, num_env;
>  	int err;
1142,1175c1106,1118
< +        /* check buffer limits */
< +	if ((!c->tcpwinsz) || (c->dynamic_window > 0))
< +    	    c->tcpwinsz = channel_tcpwinsz();
< +	
< +	limit = MIN(limit, 2 * c->tcpwinsz);
< +	
<  	if (c->istate == CHAN_INPUT_OPEN &&
<  	    limit > 0 &&
<  	    buffer_len(&c->input) < limit &&
< @@ -1798,14 +1831,21 @@
<  	    c->local_maxpacket*3) ||
<  	    c->local_window < c->local_window_max/2) &&
<  	    c->local_consumed > 0) {
< +		u_int addition = 0;
< +		/* adjust max window size if we are in a dynamic environment */
< +		if (c->dynamic_window && (c->tcpwinsz > c->local_window_max)) {
< +			/* grow the window somewhat aggressively to maintain pressure */
< +			addition = 1.5*(c->tcpwinsz - c->local_window_max);
< +			c->local_window_max += addition;
< +		}
<  		packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
<  		packet_put_int(c->remote_id);
< -		packet_put_int(c->local_consumed);
< +		packet_put_int(c->local_consumed + addition);
<  		packet_send();
<  		debug2("channel %d: window %d sent adjust %d",
<  		    c->self, c->local_window,
<  		    c->local_consumed);
< -		c->local_window += c->local_consumed;
< +		c->local_window += c->local_consumed + addition;
<  		c->local_consumed = 0;
<  	}
<  	return 1;
< @@ -2137,11 +2177,12 @@
---
> @@ -304,6 +351,15 @@
>  	/* Import variables set by do_pam_account */
>  	sshpam_account_status = buffer_get_int(b);
>  	sshpam_password_change_required(buffer_get_int(b));
> +	if (options.permit_pam_user_change) {
> +        user = buffer_get_string(b, NULL);
> +        debug("PAM: got username '%.100s' from thread", user);
> +        if ((err = pam_set_item(sshpam_handle, PAM_USER, user)) != PAM_SUCCESS)
> +            fatal("PAM: failed to set PAM_USER: %s",
> +                  pam_strerror(sshpam_handle, err));
> +        pwfree(sshpam_authctxt->pw);
> +        sshpam_authctxt->pw = pwcopy(sshpam_getpw(user));
> +    }
1176a1120,1124
>  	/* Import environment from subprocess */
>  	num_env = buffer_get_int(b);
> @@ -469,6 +525,9 @@
>  	if (sshpam_err != PAM_SUCCESS)
>  		goto auth_fail;
1178,1185c1126,1138
<  /* If there is data to send to the connection, enqueue some of it now. */
< -void
< +int
<  channel_output_poll(void)
<  {
<  	Channel *c;
<  	u_int i, len;
< +	int packet_length = 0;
---
> +	if (options.permit_pam_user_change) {
> +        sshpam_check_userchanged();
> +    }
>  	if (compat20) {
>  		if (!do_pam_account()) {
>  			sshpam_err = PAM_ACCT_EXPIRED;
> @@ -489,6 +548,9 @@
>  	/* Export variables set by do_pam_account */
>  	buffer_put_int(&buffer, sshpam_account_status);
>  	buffer_put_int(&buffer, sshpam_authctxt->force_pwchange);
> +	if (options.permit_pam_user_change) {
> +        buffer_put_cstring(&buffer, sshpam_authctxt->pw->pw_name);
> +    }
1187,1282c1140,1144
<  	for (i = 0; i < channels_alloc; i++) {
<  		c = channels[i];
< @@ -2189,7 +2230,7 @@
<  					packet_start(SSH2_MSG_CHANNEL_DATA);
<  					packet_put_int(c->remote_id);
<  					packet_put_string(data, dlen);
< -					packet_send();
< +					packet_length = packet_send();
<  					c->remote_window -= dlen + 4;
<  					xfree(data);
<  				}
< @@ -2219,7 +2260,7 @@
<  				    SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
<  				packet_put_int(c->remote_id);
<  				packet_put_string(buffer_ptr(&c->input), len);
< -				packet_send();
< +				packet_length = packet_send();
<  				buffer_consume(&c->input, len);
<  				c->remote_window -= len;
<  			}
< @@ -2254,12 +2295,13 @@
<  			packet_put_int(c->remote_id);
<  			packet_put_int(SSH2_EXTENDED_DATA_STDERR);
<  			packet_put_string(buffer_ptr(&c->extended), len);
< -			packet_send();
< +			packet_length = packet_send();
<  			buffer_consume(&c->extended, len);
<  			c->remote_window -= len;
<  			debug2("channel %d: sent ext data %d", c->self, len);
<  		}
<  	}
< +	return (packet_length);
<  }
<  
<  
< @@ -2643,6 +2685,13 @@
<  	IPv4or6 = af;
<  }
<  
< +void 
< +channel_set_hpn(int external_hpn_disabled, int external_hpn_buffer_size)
< +{
< +      	hpn_disabled = external_hpn_disabled;
< +	hpn_buffer_size = external_hpn_buffer_size;
< +	debug("HPN Disabled: %d, HPN Buffer Size: %d", hpn_disabled, hpn_buffer_size);
< +}
<  
<  /*
<   * Determine whether or not a port forward listens to loopback, the
< @@ -2809,9 +2858,15 @@
<  		}
<  
<  		/* Allocate a channel number for the socket. */
< +		/* explicitly test for hpn disabled option. if true use smaller window size */
< +		if (hpn_disabled)
<  		c = channel_new("port listener", type, sock, sock, -1,
<  		    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
<  		    0, "port listener", 1);
< + 		else
< + 			c = channel_new("port listener", type, sock, sock, -1,
< + 		    	  hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
< + 		    	  0, "port listener", 1); 
<  		c->path = xstrdup(host);
<  		c->host_port = port_to_connect;
<  		c->listening_addr = addr == NULL ? NULL : xstrdup(addr);
< @@ -3456,10 +3511,17 @@
<  	*chanids = xcalloc(num_socks + 1, sizeof(**chanids));
<  	for (n = 0; n < num_socks; n++) {
<  		sock = socks[n];
< +		/* Is this really necassary? */
< +		if (hpn_disabled) 
<  		nc = channel_new("x11 listener",
<  		    SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
<  		    CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
<  		    0, "X11 inet listener", 1);
< +		else 
< +			nc = channel_new("x11 listener",
< +			    SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
< +			    hpn_buffer_size, CHAN_X11_PACKET_DEFAULT,
< +			    0, "X11 inet listener", 1);
<  		nc->single_connection = single_connection;
<  		(*chanids)[n] = nc->self;
<  	}
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/channels.h openssh-6.0p1/channels.h
< --- openssh-6.0p1.orig/channels.h	2011-10-02 02:59:03.000000000 -0500
< +++ openssh-6.0p1/channels.h	2012-05-27 17:50:01.000000000 -0500
< @@ -128,8 +128,10 @@
<  	u_int	local_window_max;
<  	u_int	local_consumed;
<  	u_int	local_maxpacket;
< +	int	dynamic_window;
<  	int     extended_usage;
<  	int	single_connection;
< +	u_int 	tcpwinsz;	
<  
<  	char   *ctype;		/* type */
---
>  	/* Export any environment strings set in child */
>  	for(i = 0; environ[i] != NULL; i++)
> @@ -909,6 +971,12 @@
>  	debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err,
>  	    pam_strerror(sshpam_handle, sshpam_err));
1284c1146,1156
< @@ -164,9 +166,11 @@
---
> +	if (options.permit_pam_user_change) {
> +        sshpam_check_userchanged();
> +        if (getpwnam(sshpam_authctxt->pw->pw_name) == NULL)
> +            fatal("PAM: completed authentication but PAM account invalid");
> +    }
> +
>  	if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
>  		sshpam_account_status = 0;
>  		return (sshpam_account_status);
> @@ -1208,6 +1276,9 @@
>  		    pam_strerror(sshpam_handle, sshpam_err));
1286,1289c1158,1214
<  /* default window/packet sizes for tcp/x11-fwd-channel */
<  #define CHAN_SES_PACKET_DEFAULT	(32*1024)
< -#define CHAN_SES_WINDOW_DEFAULT	(64*CHAN_SES_PACKET_DEFAULT)
< +#define CHAN_SES_WINDOW_DEFAULT	(4*CHAN_SES_PACKET_DEFAULT)
---
>  	sshpam_err = pam_authenticate(sshpam_handle, flags);
> +	if (options.permit_pam_user_change) {
> +        sshpam_check_userchanged();
> +    }
>  	sshpam_password = NULL;
>  	if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
>  		debug("PAM: password authentication accepted for %.100s",
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/auth-pam.c.orig openssh-6.0p1/auth-pam.c.orig
> --- openssh-6.0p1.orig/auth-pam.c.orig	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/auth-pam.c.orig	2012-07-12 16:59:34.184730731 +0200
> @@ -0,0 +1,1223 @@
> +/*-
> + * Copyright (c) 2002 Networks Associates Technology, Inc.
> + * All rights reserved.
> + *
> + * This software was developed for the FreeBSD Project by ThinkSec AS and
> + * NAI Labs, the Security Research Division of Network Associates, Inc.
> + * under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the
> + * DARPA CHATS research program.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
> + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
> + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> + * SUCH DAMAGE.
> + */
> +/*
> + * Copyright (c) 2003,2004 Damien Miller <djm@mindrot.org>
> + * Copyright (c) 2003,2004 Darren Tucker <dtucker@zip.com.au>
> + *
> + * Permission to use, copy, modify, and distribute this software for any
> + * purpose with or without fee is hereby granted, provided that the above
> + * copyright notice and this permission notice appear in all copies.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
> + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
> + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
> + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
> + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
> + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
> + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
1291,1293c1216,1217
<  #define CHAN_TCP_PACKET_DEFAULT	(32*1024)
< -#define CHAN_TCP_WINDOW_DEFAULT	(64*CHAN_TCP_PACKET_DEFAULT)
< +#define CHAN_TCP_WINDOW_DEFAULT	(4*CHAN_TCP_PACKET_DEFAULT)
---
> +/* Based on $FreeBSD: src/crypto/openssh/auth2-pam-freebsd.c,v 1.11 2003/03/31 13:48:18 des Exp $ */
> +#include "includes.h"
1295,1312c1219,1221
<  #define CHAN_X11_PACKET_DEFAULT	(16*1024)
<  #define CHAN_X11_WINDOW_DEFAULT	(4*CHAN_X11_PACKET_DEFAULT)
<  
< @@ -240,7 +244,7 @@
<  
<  void	 channel_prepare_select(fd_set **, fd_set **, int *, u_int*, int);
<  void     channel_after_select(fd_set *, fd_set *);
< -void     channel_output_poll(void);
< +int      channel_output_poll(void);
<  
<  int      channel_not_very_much_buffered_data(void);
<  void     channel_close_all(void);
< @@ -300,4 +304,7 @@
<  void	 chan_write_failed(Channel *);
<  void	 chan_obuf_empty(Channel *);
<  
< +/* hpn handler */
< +void     channel_set_hpn(int, int);
---
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <sys/wait.h>
1314,1350c1223,1263
<  #endif
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/cipher.c openssh-6.0p1/cipher.c
< --- openssh-6.0p1.orig/cipher.c	2009-01-27 23:38:41.000000000 -0600
< +++ openssh-6.0p1/cipher.c	2012-05-27 17:50:01.000000000 -0500
< @@ -163,7 +163,8 @@
<  	for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
<  	    (p = strsep(&cp, CIPHER_SEP))) {
<  		c = cipher_by_name(p);
< -		if (c == NULL || c->number != SSH_CIPHER_SSH2) {
< +		if (c == NULL || (c->number != SSH_CIPHER_SSH2 &&
< +				  c->number != SSH_CIPHER_NONE)) {
<  			debug("bad cipher %s [%s]", p, names);
<  			xfree(cipher_list);
<  			return 0;
< @@ -337,6 +338,7 @@
<  	int evplen;
<  
<  	switch (c->number) {
< +	case SSH_CIPHER_NONE:
<  	case SSH_CIPHER_SSH2:
<  	case SSH_CIPHER_DES:
<  	case SSH_CIPHER_BLOWFISH:
< @@ -371,6 +373,7 @@
<  	int evplen = 0;
<  
<  	switch (c->number) {
< +	case SSH_CIPHER_NONE:
<  	case SSH_CIPHER_SSH2:
<  	case SSH_CIPHER_DES:
<  	case SSH_CIPHER_BLOWFISH:
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/clientloop.c openssh-6.0p1/clientloop.c
< --- openssh-6.0p1.orig/clientloop.c	2012-02-10 15:18:17.000000000 -0600
< +++ openssh-6.0p1/clientloop.c	2012-05-27 17:50:01.000000000 -0500
< @@ -111,6 +111,10 @@
<  #include "msg.h"
<  #include "roaming.h"
<  
---
> +#include <errno.h>
> +#include <signal.h>
> +#include <stdarg.h>
> +#include <string.h>
> +#include <unistd.h>
> +
> +#ifdef USE_PAM
> +#if defined(HAVE_SECURITY_PAM_APPL_H)
> +#include <security/pam_appl.h>
> +#elif defined (HAVE_PAM_PAM_APPL_H)
> +#include <pam/pam_appl.h>
> +#endif
> +
> +/* OpenGroup RFC86.0 and XSSO specify no "const" on arguments */
> +#ifdef PAM_SUN_CODEBASE
> +# define sshpam_const		/* Solaris, HP-UX, AIX */
> +#else
> +# define sshpam_const	const	/* LinuxPAM, OpenPAM */
> +#endif
> +
> +/* Ambiguity in spec: is it an array of pointers or a pointer to an array? */
> +#ifdef PAM_SUN_CODEBASE
> +# define PAM_MSG_MEMBER(msg, n, member) ((*(msg))[(n)].member)
> +#else
> +# define PAM_MSG_MEMBER(msg, n, member) ((msg)[(n)]->member)
> +#endif
> +
> +#include "xmalloc.h"
> +#include "buffer.h"
> +#include "key.h"
> +#include "hostfile.h"
> +#include "auth.h"
> +#include "auth-pam.h"
> +#include "canohost.h"
> +#include "log.h"
> +#include "msg.h"
> +#include "packet.h"
> +#include "misc.h"
> +#include "servconf.h"
> +#include "ssh2.h"
> +#include "auth-options.h"
1353a1267
> +#include "monitor_wrap.h"
1355,1361c1269,1277
<  /* import options */
<  extern Options options;
<  
< @@ -1540,6 +1544,15 @@
<  		/* Do channel operations unless rekeying in progress. */
<  		if (!rekeying) {
<  			channel_after_select(readset, writeset);
---
> +extern ServerOptions options;
> +extern Buffer loginmsg;
> +extern int compat20;
> +extern u_int utmp_len;
> +
> +/* so we don't silently change behaviour */
> +#ifdef USE_POSIX_THREADS
> +# error "USE_POSIX_THREADS replaced by UNSUPPORTED_POSIX_THREADS_HACK"
> +#endif
1363,1368c1279,1293
< +#ifdef GSSAPI
< +			if (options.gss_renewal_rekey &&
< +			    ssh_gssapi_credentials_updated((Gssctxt *)GSS_C_NO_CONTEXT)) {
< +				debug("credentials updated - forcing rekey");
< +				need_rekeying = 1;
< +			}
---
> +/*
> + * Formerly known as USE_POSIX_THREADS, using this is completely unsupported
> + * and generally a bad idea.  Use at own risk and do not expect support if
> + * this breaks.
> + */
> +#ifdef UNSUPPORTED_POSIX_THREADS_HACK
> +#include <pthread.h>
> +/*
> + * Avoid namespace clash when *not* using pthreads for systems *with*
> + * pthreads, which unconditionally define pthread_t via sys/types.h
> + * (e.g. Linux)
> + */
> +typedef pthread_t sp_pthread_t;
> +#else
> +typedef pid_t sp_pthread_t;
1371,1421c1296,1301
<  			if (need_rekeying || packet_need_rekeying()) {
<  				debug("need rekeying");
<  				xxx_kex->done = 0;
< @@ -1825,9 +1838,15 @@
<  	sock = x11_connect_display();
<  	if (sock < 0)
<  		return NULL;
< +	/* again is this really necessary for X11? */
< +	if (options.hpn_disabled) 
<  	c = channel_new("x11",
<  	    SSH_CHANNEL_X11_OPEN, sock, sock, -1,
<  	    CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
< +	else 
< +		c = channel_new("x11",
< +		    SSH_CHANNEL_X11_OPEN, sock, sock, -1,
< +		    options.hpn_buffer_size, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
<  	c->force_drain = 1;
<  	return c;
<  }
< @@ -1847,9 +1866,15 @@
<  	sock = ssh_get_authentication_socket();
<  	if (sock < 0)
<  		return NULL;
< +	if (options.hpn_disabled) 
<  	c = channel_new("authentication agent connection",
<  	    SSH_CHANNEL_OPEN, sock, sock, -1,
< -	    CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
< +		    CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
< +		    "authentication agent connection", 1);
< +       else
< +	c = channel_new("authentication agent connection",
< +	    SSH_CHANNEL_OPEN, sock, sock, -1,
< +                   options.hpn_buffer_size, options.hpn_buffer_size, 0,
<  	    "authentication agent connection", 1);
<  	c->force_drain = 1;
<  	return c;
< @@ -1877,10 +1902,18 @@
<  		return -1;
<  	}
<  
< +	if(options.hpn_disabled)
< +	c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
< +				CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
< +				0, "tun", 1);
< +	else
<  	c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
< -	    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
< +				options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
< +				0, "tun", 1);
<  	c->datagram = 1;
<  
---
> +struct pam_ctxt {
> +	sp_pthread_t	 pam_thread;
> +	int		 pam_psock;
> +	int		 pam_csock;
> +	int		 pam_done;
> +};
1422a1303,1304
> +static void sshpam_free_ctx(void *);
> +static struct pam_ctxt *cleanup_ctxt;
1424,1465c1306,1309
<  #if defined(SSH_TUN_FILTER)
<  	if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
<  		channel_register_filter(c->self, sys_tun_infilter,
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/compat.c openssh-6.0p1/compat.c
< --- openssh-6.0p1.orig/compat.c	2011-10-02 02:59:03.000000000 -0500
< +++ openssh-6.0p1/compat.c	2012-05-27 17:50:01.000000000 -0500
< @@ -171,6 +171,15 @@
<  		    strlen(check[i].pat), 0) == 1) {
<  			debug("match: %s pat %s", version, check[i].pat);
<  			datafellows = check[i].bugs;
< +			/* Check to see if the remote side is OpenSSH and not HPN */
< +			if(strstr(version,"OpenSSH") != NULL)
< +			{
< +				if (strstr(version,"hpn") == NULL)
< +				{
< +					datafellows |= SSH_BUG_LARGEWINDOW;
< +					debug("Remote is NON-HPN aware");
< +				}
< +			}
<  			return;
<  		}
<  	}
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/compat.h openssh-6.0p1/compat.h
< --- openssh-6.0p1.orig/compat.h	2011-10-02 02:59:03.000000000 -0500
< +++ openssh-6.0p1/compat.h	2012-05-27 17:50:01.000000000 -0500
< @@ -59,6 +59,7 @@
<  #define SSH_BUG_RFWD_ADDR	0x02000000
<  #define SSH_NEW_OPENSSH		0x04000000
<  #define SSH_BUG_DYNAMIC_RPORT	0x08000000
< +#define SSH_BUG_LARGEWINDOW     0x80000000
<  
<  void     enable_compat13(void);
<  void     enable_compat20(void);
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/config.h.in openssh-6.0p1/config.h.in
< --- openssh-6.0p1.orig/config.h.in	2012-04-20 00:03:32.000000000 -0500
< +++ openssh-6.0p1/config.h.in	2012-05-27 17:50:03.000000000 -0500
< @@ -3,6 +3,9 @@
<  /* Define if building universal (internal helper macro) */
<  #undef AC_APPLE_UNIVERSAL_BUILD
<  
< +/* Define this if you want to use AFS/Kerberos 5 option, which runs aklog. */
< +#undef AFS_KRB5
---
> +#ifndef UNSUPPORTED_POSIX_THREADS_HACK
> +/*
> + * Simulate threads with processes.
> + */
1467,1475c1311,1312
<  /* Define if you have a getaddrinfo that fails for the all-zeros IPv6 address
<     */
<  #undef AIX_GETNAMEINFO_HACK
< @@ -10,6 +13,9 @@
<  /* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */
<  #undef AIX_LOGINFAILED_4ARG
<  
< +/* Define this if you want to use AFS/Kerberos 5 option, which runs aklog. */
< +#undef AKLOG_PATH
---
> +static int sshpam_thread_status = -1;
> +static mysig_t sshpam_oldsig;
1477,1494c1314,1335
<  /* System only supports IPv4 audit records */
<  #undef AU_IPv4
<  
< @@ -22,7 +28,7 @@
<  /* Define if cmsg_type is not passed correctly */
<  #undef BROKEN_CMSG_TYPE
<  
< -/* getaddrinfo is broken (if present) */
< +/* assume getaddrinfo is broken) */
<  #undef BROKEN_GETADDRINFO
<  
<  /* getgroups(0,NULL) will return -1 */
< @@ -152,6 +158,9 @@
<  /* Define if your system glob() function has gl_statv options in glob_t */
<  #undef GLOB_HAS_GL_STATV
<  
< +/* Define if you want GSI/Globus authentication support. */
< +#undef GSI
---
> +static void
> +sshpam_sigchld_handler(int sig)
> +{
> +	signal(SIGCHLD, SIG_DFL);
> +	if (cleanup_ctxt == NULL)
> +		return;	/* handler called after PAM cleanup, shouldn't happen */
> +	if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, WNOHANG)
> +	    <= 0) {
> +		/* PAM thread has not exitted, privsep slave must have */
> +		kill(cleanup_ctxt->pam_thread, SIGTERM);
> +		if (waitpid(cleanup_ctxt->pam_thread, &sshpam_thread_status, 0)
> +		    <= 0)
> +			return; /* could not wait */
> +	}
> +	if (WIFSIGNALED(sshpam_thread_status) &&
> +	    WTERMSIG(sshpam_thread_status) == SIGTERM)
> +		return;	/* terminated by pthread_cancel */
> +	if (!WIFEXITED(sshpam_thread_status))
> +		sigdie("PAM: authentication thread exited unexpectedly");
> +	if (WEXITSTATUS(sshpam_thread_status) != 0)
> +		sigdie("PAM: authentication thread exited uncleanly");
> +}
1496,1505c1337,1342
<  /* Define this if you want GSSAPI support in the version 2 protocol */
<  #undef GSSAPI
<  
< @@ -476,6 +485,16 @@
<  /* Define to 1 if you have the `glob' function. */
<  #undef HAVE_GLOB
<  
< +/* Define to 1 if you have the `globus_gss_assist_map_and_authorize' function.
< +   */
< +#undef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
---
> +/* ARGSUSED */
> +static void
> +pthread_exit(void *value)
> +{
> +	_exit(0);
> +}
1507,1508c1344,1350
< +/* Have Globus Usage */
< +#undef HAVE_GLOBUS_USAGE
---
> +/* ARGSUSED */
> +static int
> +pthread_create(sp_pthread_t *thread, const void *attr,
> +    void *(*thread_start)(void *), void *arg)
> +{
> +	pid_t pid;
> +	struct pam_ctxt *ctx = arg;
1510,1511c1352,1369
< +/* Have Globus Usage send_array */
< +#undef HAVE_GLOBUS_USAGE_SEND_ARRAY
---
> +	sshpam_thread_status = -1;
> +	switch ((pid = fork())) {
> +	case -1:
> +		error("fork(): %s", strerror(errno));
> +		return (-1);
> +	case 0:
> +		close(ctx->pam_psock);
> +		ctx->pam_psock = -1;
> +		thread_start(arg);
> +		_exit(1);
> +	default:
> +		*thread = pid;
> +		close(ctx->pam_csock);
> +		ctx->pam_csock = -1;
> +		sshpam_oldsig = signal(SIGCHLD, sshpam_sigchld_handler);
> +		return (0);
> +	}
> +}
1513,1521c1371,1376
<  /* Define to 1 if you have the <glob.h> header file. */
<  #undef HAVE_GLOB_H
<  
< @@ -1292,6 +1311,9 @@
<  /* Set this to your mail directory if you do not have _PATH_MAILDIR */
<  #undef MAIL_DIRECTORY
<  
< +/* Define this if you're building with GSSAPI MechGlue. */
< +#undef MECHGLUE
---
> +static int
> +pthread_cancel(sp_pthread_t thread)
> +{
> +	signal(SIGCHLD, sshpam_oldsig);
> +	return (kill(thread, SIGTERM));
> +}
1523,1531c1378,1382
<  /* Define on *nto-qnx systems */
<  #undef MISSING_FD_MASK
<  
< @@ -1380,6 +1402,9 @@
<  /* Specify the system call convention in use */
<  #undef SECCOMP_AUDIT_ARCH
<  
< +/* Define this if you want support for startup/shutdown hooks */
< +#undef SESSION_HOOKS
---
> +/* ARGSUSED */
> +static int
> +pthread_join(sp_pthread_t thread, void **value)
> +{
> +	int status;
1533,1541c1384,1390
<  /* Define if your platform breaks doing a seteuid before a setuid */
<  #undef SETEUID_BREAKS_SETUID
<  
< @@ -1465,6 +1490,9 @@
<  /* Use btmp to log bad logins */
<  #undef USE_BTMP
<  
< +/* platform uses an in-memory credentials cache */
< +#undef USE_CCAPI
---
> +	if (sshpam_thread_status != -1)
> +		return (sshpam_thread_status);
> +	signal(SIGCHLD, sshpam_oldsig);
> +	waitpid(thread, &status, 0);
> +	return (status);
> +}
> +#endif
1543,1551d1391
<  /* Use libedit for sftp */
<  #undef USE_LIBEDIT
<  
< @@ -1480,6 +1508,9 @@
<  /* Use PIPES instead of a socketpair() */
<  #undef USE_PIPES
<  
< +/* platform has the Security Authorization Session API */
< +#undef USE_SECURITY_SESSION_API
1553,1616c1393,1416
<  /* Define if you have Solaris process contracts */
<  #undef USE_SOLARIS_PROCESS_CONTRACTS
<  
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/configure openssh-6.0p1/configure
< --- openssh-6.0p1.orig/configure	2012-04-20 00:03:38.000000000 -0500
< +++ openssh-6.0p1/configure	2012-05-27 17:50:04.000000000 -0500
< @@ -615,6 +615,7 @@
<  xauth_path
<  PRIVSEP_PATH
<  KRB5CONF
< +INSTALL_GSISSH
<  SSHDLIBS
<  SSHLIBS
<  SSH_PRIVSEP_USER
< @@ -707,6 +708,10 @@
<  ac_subst_files=''
<  ac_user_opts='
<  enable_option_checking
< +with_gsi
< +with_globus
< +with_globus_static
< +with_globus_flavor
<  enable_largefile
<  with_stackprotect
<  with_rpath
< @@ -734,7 +739,10 @@
<  with_privsep_user
<  with_sandbox
<  with_selinux
< +with_mechglue
<  with_kerberos5
< +with_afs_krb5
< +with_session_hooks
<  with_privsep_path
<  with_xauth
<  enable_strip
< @@ -1398,6 +1406,10 @@
<  Optional Packages:
<    --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
<    --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
< +  --with-gsi              Enable Globus GSI authentication support
< +  --with-globus           Enable Globus GSI authentication support
< +  --with-globus-static    Link statically with Globus GSI libraries
< +  --with-globus-flavor=TYPE  Specify Globus flavor type (ex: gcc32dbg)
<    --without-stackprotect  Don't use compiler's stack protection
<    --without-rpath         Disable auto-added -R linker paths
<    --with-cflags           Specify additional flags to pass to compiler
< @@ -1424,7 +1436,10 @@
<    --with-privsep-user=user Specify non-privileged user for privilege separation
<    --with-sandbox=style    Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter)
<    --with-selinux          Enable SELinux support
< +  --with-mechglue=PATH    Build with GSSAPI mechglue library
<    --with-kerberos5=PATH   Enable Kerberos 5 support
< +  --with-afs-krb5[=AKLOG_PATH]  Enable aklog to get token (default=/usr/bin/aklog).
< +  --with-session-hooks    Enable hooks for executing external commands                                       before/after a session
<    --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty)
<    --with-xauth=PATH       Specify path to xauth program
<    --with-maildir=/path/to/mail    Specify your system mail directory
< @@ -2576,6 +2591,175 @@
<  ac_compiler_gnu=$ac_cv_c_compiler_gnu
<  
<  
< +# Handle Globus configuration right away, because the Globus flavor
< +# determines our compiler options.
---
> +static pam_handle_t *sshpam_handle = NULL;
> +static int sshpam_err = 0;
> +static int sshpam_authenticated = 0;
> +static int sshpam_session_open = 0;
> +static int sshpam_cred_established = 0;
> +static int sshpam_account_status = -1;
> +static char **sshpam_env = NULL;
> +static Authctxt *sshpam_authctxt = NULL;
> +static const char *sshpam_password = NULL;
> +static char badpw[] = "\b\n\r\177INCORRECT";
> +
> +/* Some PAM implementations don't implement this */
> +#ifndef HAVE_PAM_GETENVLIST
> +static char **
> +pam_getenvlist(pam_handle_t *pamh)
> +{
> +	/*
> +	 * XXX - If necessary, we can still support envrionment passing
> +	 * for platforms without pam_getenvlist by searching for known
> +	 * env vars (e.g. KRB5CCNAME) from the PAM environment.
> +	 */
> +	 return NULL;
> +}
> +#endif
1618,1619c1418,1429
< +# Check whether the user wants GSI (Globus) support
< +gsi_path="no"
---
> +/*
> + * Some platforms, notably Solaris, do not enforce password complexity
> + * rules during pam_chauthtok() if the real uid of the calling process
> + * is 0, on the assumption that it's being called by "passwd" run by root.
> + * This wraps pam_chauthtok and sets/restore the real uid so PAM will do
> + * the right thing.
> + */
> +#ifdef SSHPAM_CHAUTHTOK_NEEDS_RUID
> +static int
> +sshpam_chauthtok_ruid(pam_handle_t *pamh, int flags)
> +{
> +	int result;
1621,1624c1431,1441
< +# Check whether --with-gsi was given.
< +if test "${with_gsi+set}" = set; then :
< +  withval=$with_gsi;
< +		gsi_path="$withval"
---
> +	if (sshpam_authctxt == NULL)
> +		fatal("PAM: sshpam_authctxt not initialized");
> +	if (setreuid(sshpam_authctxt->pw->pw_uid, -1) == -1)
> +		fatal("%s: setreuid failed: %s", __func__, strerror(errno));
> +	result = pam_chauthtok(pamh, flags);
> +	if (setreuid(0, -1) == -1)
> +		fatal("%s: setreuid failed: %s", __func__, strerror(errno));
> +	return result;
> +}
> +# define pam_chauthtok(a,b)	(sshpam_chauthtok_ruid((a), (b)))
> +#endif
1625a1443,1459
> +void
> +sshpam_password_change_required(int reqd)
> +{
> +	debug3("%s %d", __func__, reqd);
> +	if (sshpam_authctxt == NULL)
> +		fatal("%s: PAM authctxt not initialized", __func__);
> +	sshpam_authctxt->force_pwchange = reqd;
> +	if (reqd) {
> +		no_port_forwarding_flag |= 2;
> +		no_agent_forwarding_flag |= 2;
> +		no_x11_forwarding_flag |= 2;
> +	} else {
> +		no_port_forwarding_flag &= ~2;
> +		no_agent_forwarding_flag &= ~2;
> +		no_x11_forwarding_flag &= ~2;
> +	}
> +}
1627c1461,1503
< +fi
---
> +/* Import regular and PAM environment from subprocess */
> +static void
> +import_environments(Buffer *b)
> +{
> +	char *env;
> +	u_int i, num_env;
> +	int err;
> +
> +	debug3("PAM: %s entering", __func__);
> +
> +#ifndef UNSUPPORTED_POSIX_THREADS_HACK
> +	/* Import variables set by do_pam_account */
> +	sshpam_account_status = buffer_get_int(b);
> +	sshpam_password_change_required(buffer_get_int(b));
> +
> +	/* Import environment from subprocess */
> +	num_env = buffer_get_int(b);
> +	if (num_env > 1024)
> +		fatal("%s: received %u environment variables, expected <= 1024",
> +		    __func__, num_env);
> +	sshpam_env = xcalloc(num_env + 1, sizeof(*sshpam_env));
> +	debug3("PAM: num env strings %d", num_env);
> +	for(i = 0; i < num_env; i++)
> +		sshpam_env[i] = buffer_get_string(b, NULL);
> +
> +	sshpam_env[num_env] = NULL;
> +
> +	/* Import PAM environment from subprocess */
> +	num_env = buffer_get_int(b);
> +	debug("PAM: num PAM env strings %d", num_env);
> +	for(i = 0; i < num_env; i++) {
> +		env = buffer_get_string(b, NULL);
> +
> +#ifdef HAVE_PAM_PUTENV
> +		/* Errors are not fatal here */
> +		if ((err = pam_putenv(sshpam_handle, env)) != PAM_SUCCESS) {
> +			error("PAM: pam_putenv: %s",
> +			    pam_strerror(sshpam_handle, sshpam_err));
> +		}
> +#endif
> +	}
> +#endif
> +}
1628a1505,1589
> +/*
> + * Conversation function for authentication thread.
> + */
> +static int
> +sshpam_thread_conv(int n, sshpam_const struct pam_message **msg,
> +    struct pam_response **resp, void *data)
> +{
> +	Buffer buffer;
> +	struct pam_ctxt *ctxt;
> +	struct pam_response *reply;
> +	int i;
> +
> +	debug3("PAM: %s entering, %d messages", __func__, n);
> +	*resp = NULL;
> +
> +	if (data == NULL) {
> +		error("PAM: conversation function passed a null context");
> +		return (PAM_CONV_ERR);
> +	}
> +	ctxt = data;
> +	if (n <= 0 || n > PAM_MAX_NUM_MSG)
> +		return (PAM_CONV_ERR);
> +
> +	if ((reply = calloc(n, sizeof(*reply))) == NULL)
> +		return (PAM_CONV_ERR);
> +
> +	buffer_init(&buffer);
> +	for (i = 0; i < n; ++i) {
> +		switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
> +		case PAM_PROMPT_ECHO_OFF:
> +			buffer_put_cstring(&buffer,
> +			    PAM_MSG_MEMBER(msg, i, msg));
> +			if (ssh_msg_send(ctxt->pam_csock,
> +			    PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
> +				goto fail;
> +			if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1)
> +				goto fail;
> +			if (buffer_get_char(&buffer) != PAM_AUTHTOK)
> +				goto fail;
> +			reply[i].resp = buffer_get_string(&buffer, NULL);
> +			break;
> +		case PAM_PROMPT_ECHO_ON:
> +			buffer_put_cstring(&buffer,
> +			    PAM_MSG_MEMBER(msg, i, msg));
> +			if (ssh_msg_send(ctxt->pam_csock,
> +			    PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
> +				goto fail;
> +			if (ssh_msg_recv(ctxt->pam_csock, &buffer) == -1)
> +				goto fail;
> +			if (buffer_get_char(&buffer) != PAM_AUTHTOK)
> +				goto fail;
> +			reply[i].resp = buffer_get_string(&buffer, NULL);
> +			break;
> +		case PAM_ERROR_MSG:
> +			buffer_put_cstring(&buffer,
> +			    PAM_MSG_MEMBER(msg, i, msg));
> +			if (ssh_msg_send(ctxt->pam_csock,
> +			    PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
> +				goto fail;
> +			break;
> +		case PAM_TEXT_INFO:
> +			buffer_put_cstring(&buffer,
> +			    PAM_MSG_MEMBER(msg, i, msg));
> +			if (ssh_msg_send(ctxt->pam_csock,
> +			    PAM_MSG_MEMBER(msg, i, msg_style), &buffer) == -1)
> +				goto fail;
> +			break;
> +		default:
> +			goto fail;
> +		}
> +		buffer_clear(&buffer);
> +	}
> +	buffer_free(&buffer);
> +	*resp = reply;
> +	return (PAM_SUCCESS);
> +
> + fail:
> +	for(i = 0; i < n; i++) {
> +		if (reply[i].resp != NULL)
> +			xfree(reply[i].resp);
> +	}
> +	xfree(reply);
> +	buffer_free(&buffer);
> +	return (PAM_CONV_ERR);
> +}
1629a1591,1623
> +/*
> + * Authentication thread.
> + */
> +static void *
> +sshpam_thread(void *ctxtp)
> +{
> +	struct pam_ctxt *ctxt = ctxtp;
> +	Buffer buffer;
> +	struct pam_conv sshpam_conv;
> +	int flags = (options.permit_empty_passwd == 0 ?
> +	    PAM_DISALLOW_NULL_AUTHTOK : 0);
> +#ifndef UNSUPPORTED_POSIX_THREADS_HACK
> +	extern char **environ;
> +	char **env_from_pam;
> +	u_int i;
> +	const char *pam_user;
> +	const char **ptr_pam_user = &pam_user;
> +	char *tz = getenv("TZ");
> +
> +	pam_get_item(sshpam_handle, PAM_USER,
> +	    (sshpam_const void **)ptr_pam_user);
> +
> +	environ[0] = NULL;
> +	if (tz != NULL)
> +		if (setenv("TZ", tz, 1) == -1)
> +			error("PAM: could not set TZ environment: %s",
> +			    strerror(errno));
> +
> +	if (sshpam_authctxt != NULL) {
> +		setproctitle("%s [pam]",
> +		    sshpam_authctxt->valid ? pam_user : "unknown");
> +	}
> +#endif
1631,1634c1625,1638
< +# Check whether --with-globus was given.
< +if test "${with_globus+set}" = set; then :
< +  withval=$with_globus;
< +		gsi_path="$withval"
---
> +	sshpam_conv.conv = sshpam_thread_conv;
> +	sshpam_conv.appdata_ptr = ctxt;
> +
> +	if (sshpam_authctxt == NULL)
> +		fatal("%s: PAM authctxt not initialized", __func__);
> +
> +	buffer_init(&buffer);
> +	sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
> +	    (const void *)&sshpam_conv);
> +	if (sshpam_err != PAM_SUCCESS)
> +		goto auth_fail;
> +	sshpam_err = pam_authenticate(sshpam_handle, flags);
> +	if (sshpam_err != PAM_SUCCESS)
> +		goto auth_fail;
1635a1640,1652
> +	if (compat20) {
> +		if (!do_pam_account()) {
> +			sshpam_err = PAM_ACCT_EXPIRED;
> +			goto auth_fail;
> +		}
> +		if (sshpam_authctxt->force_pwchange) {
> +			sshpam_err = pam_chauthtok(sshpam_handle,
> +			    PAM_CHANGE_EXPIRED_AUTHTOK);
> +			if (sshpam_err != PAM_SUCCESS)
> +				goto auth_fail;
> +			sshpam_password_change_required(0);
> +		}
> +	}
1637c1654
< +fi
---
> +	buffer_put_cstring(&buffer, "OK");
1638a1656,1691
> +#ifndef UNSUPPORTED_POSIX_THREADS_HACK
> +	/* Export variables set by do_pam_account */
> +	buffer_put_int(&buffer, sshpam_account_status);
> +	buffer_put_int(&buffer, sshpam_authctxt->force_pwchange);
> +
> +	/* Export any environment strings set in child */
> +	for(i = 0; environ[i] != NULL; i++)
> +		; /* Count */
> +	buffer_put_int(&buffer, i);
> +	for(i = 0; environ[i] != NULL; i++)
> +		buffer_put_cstring(&buffer, environ[i]);
> +
> +	/* Export any environment strings set by PAM in child */
> +	env_from_pam = pam_getenvlist(sshpam_handle);
> +	for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++)
> +		; /* Count */
> +	buffer_put_int(&buffer, i);
> +	for(i = 0; env_from_pam != NULL && env_from_pam[i] != NULL; i++)
> +		buffer_put_cstring(&buffer, env_from_pam[i]);
> +#endif /* UNSUPPORTED_POSIX_THREADS_HACK */
> +
> +	/* XXX - can't do much about an error here */
> +	ssh_msg_send(ctxt->pam_csock, sshpam_err, &buffer);
> +	buffer_free(&buffer);
> +	pthread_exit(NULL);
> +
> + auth_fail:
> +	buffer_put_cstring(&buffer,
> +	    pam_strerror(sshpam_handle, sshpam_err));
> +	/* XXX - can't do much about an error here */
> +	if (sshpam_err == PAM_ACCT_EXPIRED)
> +		ssh_msg_send(ctxt->pam_csock, PAM_ACCT_EXPIRED, &buffer);
> +	else
> +		ssh_msg_send(ctxt->pam_csock, PAM_AUTH_ERR, &buffer);
> +	buffer_free(&buffer);
> +	pthread_exit(NULL);
1639a1693,1694
> +	return (NULL); /* Avoid warning for non-pthread case */
> +}
1641,1647c1696,1699
< +# Check whether --with-globus-static was given.
< +if test "${with_globus_static+set}" = set; then :
< +  withval=$with_globus_static;
< +		gsi_static="-static"
< +		if test "x$gsi_path" = "xno" ; then
< +			gsi_path="$withval"
< +		fi
---
> +void
> +sshpam_thread_cleanup(void)
> +{
> +	struct pam_ctxt *ctxt = cleanup_ctxt;
1648a1701,1710
> +	debug3("PAM: %s entering", __func__);
> +	if (ctxt != NULL && ctxt->pam_thread != 0) {
> +		pthread_cancel(ctxt->pam_thread);
> +		pthread_join(ctxt->pam_thread, NULL);
> +		close(ctxt->pam_psock);
> +		close(ctxt->pam_csock);
> +		memset(ctxt, 0, sizeof(*ctxt));
> +		cleanup_ctxt = NULL;
> +	}
> +}
1650c1712,1718
< +fi
---
> +static int
> +sshpam_null_conv(int n, sshpam_const struct pam_message **msg,
> +    struct pam_response **resp, void *data)
> +{
> +	debug3("PAM: %s entering, %d messages", __func__, n);
> +	return (PAM_CONV_ERR);
> +}
1651a1720
> +static struct pam_conv null_conv = { sshpam_null_conv, NULL };
1653,1654c1722,1753
< +# Check whether the user has a Globus flavor type
< +globus_flavor_type="no"
---
> +static int
> +sshpam_store_conv(int n, sshpam_const struct pam_message **msg,
> +    struct pam_response **resp, void *data)
> +{
> +	struct pam_response *reply;
> +	int i;
> +	size_t len;
> +
> +	debug3("PAM: %s called with %d messages", __func__, n);
> +	*resp = NULL;
> +
> +	if (n <= 0 || n > PAM_MAX_NUM_MSG)
> +		return (PAM_CONV_ERR);
> +
> +	if ((reply = calloc(n, sizeof(*reply))) == NULL)
> +		return (PAM_CONV_ERR);
> +
> +	for (i = 0; i < n; ++i) {
> +		switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
> +		case PAM_ERROR_MSG:
> +		case PAM_TEXT_INFO:
> +			len = strlen(PAM_MSG_MEMBER(msg, i, msg));
> +			buffer_append(&loginmsg, PAM_MSG_MEMBER(msg, i, msg), len);
> +			buffer_append(&loginmsg, "\n", 1 );
> +			reply[i].resp_retcode = PAM_SUCCESS;
> +			break;
> +		default:
> +			goto fail;
> +		}
> +	}
> +	*resp = reply;
> +	return (PAM_SUCCESS);
1656,1662c1755,1762
< +# Check whether --with-globus-flavor was given.
< +if test "${with_globus_flavor+set}" = set; then :
< +  withval=$with_globus_flavor;
< +		globus_flavor_type="$withval"
< +		if test "x$gsi_path" = "xno" ; then
< +			gsi_path="yes"
< +		fi
---
> + fail:
> +	for(i = 0; i < n; i++) {
> +		if (reply[i].resp != NULL)
> +			xfree(reply[i].resp);
> +	}
> +	xfree(reply);
> +	return (PAM_CONV_ERR);
> +}
1663a1764
> +static struct pam_conv store_conv = { sshpam_store_conv, NULL };
1665c1766,1786
< +fi
---
> +void
> +sshpam_cleanup(void)
> +{
> +	if (sshpam_handle == NULL || (use_privsep && !mm_is_monitor()))
> +		return;
> +	debug("PAM: cleanup");
> +	pam_set_item(sshpam_handle, PAM_CONV, (const void *)&null_conv);
> +	if (sshpam_session_open) {
> +		debug("PAM: closing session");
> +		pam_close_session(sshpam_handle, PAM_SILENT);
> +		sshpam_session_open = 0;
> +	}
> +	if (sshpam_cred_established) {
> +		debug("PAM: deleting credentials");
> +		pam_setcred(sshpam_handle, PAM_DELETE_CRED);
> +		sshpam_cred_established = 0;
> +	}
> +	sshpam_authenticated = 0;
> +	pam_end(sshpam_handle, sshpam_err);
> +	sshpam_handle = NULL;
> +}
1666a1788,1837
> +static int
> +sshpam_init(Authctxt *authctxt)
> +{
> +	extern char *__progname;
> +	const char *pam_rhost, *pam_user, *user = authctxt->user;
> +	const char **ptr_pam_user = &pam_user;
> +
> +	if (sshpam_handle != NULL) {
> +		/* We already have a PAM context; check if the user matches */
> +		sshpam_err = pam_get_item(sshpam_handle,
> +		    PAM_USER, (sshpam_const void **)ptr_pam_user);
> +		if (sshpam_err == PAM_SUCCESS && strcmp(user, pam_user) == 0)
> +			return (0);
> +		pam_end(sshpam_handle, sshpam_err);
> +		sshpam_handle = NULL;
> +	}
> +	debug("PAM: initializing for \"%s\"", user);
> +	sshpam_err =
> +	    pam_start(SSHD_PAM_SERVICE, user, &store_conv, &sshpam_handle);
> +	sshpam_authctxt = authctxt;
> +
> +	if (sshpam_err != PAM_SUCCESS) {
> +		pam_end(sshpam_handle, sshpam_err);
> +		sshpam_handle = NULL;
> +		return (-1);
> +	}
> +	pam_rhost = get_remote_name_or_ip(utmp_len, options.use_dns);
> +	debug("PAM: setting PAM_RHOST to \"%s\"", pam_rhost);
> +	sshpam_err = pam_set_item(sshpam_handle, PAM_RHOST, pam_rhost);
> +	if (sshpam_err != PAM_SUCCESS) {
> +		pam_end(sshpam_handle, sshpam_err);
> +		sshpam_handle = NULL;
> +		return (-1);
> +	}
> +#ifdef PAM_TTY_KLUDGE
> +	/*
> +	 * Some silly PAM modules (e.g. pam_time) require a TTY to operate.
> +	 * sshd doesn't set the tty until too late in the auth process and
> +	 * may not even set one (for tty-less connections)
> +	 */
> +	debug("PAM: setting PAM_TTY to \"ssh\"");
> +	sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, "ssh");
> +	if (sshpam_err != PAM_SUCCESS) {
> +		pam_end(sshpam_handle, sshpam_err);
> +		sshpam_handle = NULL;
> +		return (-1);
> +	}
> +#endif
> +	return (0);
> +}
1668,1671c1839,1843
< +if test "x$gsi_path" != "xno" ; then
< +	# Globus GSSAPI configuration
< +	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Globus GSI" >&5
< +$as_echo_n "checking for Globus GSI... " >&6; }
---
> +static void *
> +sshpam_init_ctx(Authctxt *authctxt)
> +{
> +	struct pam_ctxt *ctxt;
> +	int socks[2];
1673c1845,1851
< +$as_echo "#define GSI 1" >>confdefs.h
---
> +	debug3("PAM: %s entering", __func__);
> +	/*
> +	 * Refuse to start if we don't have PAM enabled or do_pam_account
> +	 * has previously failed.
> +	 */
> +	if (!options.use_pam || sshpam_account_status == 0)
> +		return NULL;
1674a1853,1879
> +	/* Initialize PAM */
> +	if (sshpam_init(authctxt) == -1) {
> +		error("PAM: initialization failed");
> +		return (NULL);
> +	}
> +
> +	ctxt = xcalloc(1, sizeof *ctxt);
> +
> +	/* Start the authentication thread */
> +	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, socks) == -1) {
> +		error("PAM: failed create sockets: %s", strerror(errno));
> +		xfree(ctxt);
> +		return (NULL);
> +	}
> +	ctxt->pam_psock = socks[0];
> +	ctxt->pam_csock = socks[1];
> +	if (pthread_create(&ctxt->pam_thread, NULL, sshpam_thread, ctxt) == -1) {
> +		error("PAM: failed to start authentication thread: %s",
> +		    strerror(errno));
> +		close(socks[0]);
> +		close(socks[1]);
> +		xfree(ctxt);
> +		return (NULL);
> +	}
> +	cleanup_ctxt = ctxt;
> +	return (ctxt);
> +}
1676,1680c1881,1890
< +	if test "$GSSAPI" -a "$GSSAPI" != "mechglue"; then
< +		as_fn_error $? "Previously configured GSSAPI library conflicts with Globus GSI." "$LINENO" 5
< +	fi
< +	if test -z "$GSSAPI"; then
< +		$as_echo "#define GSSAPI 1" >>confdefs.h
---
> +static int
> +sshpam_query(void *ctx, char **name, char **info,
> +    u_int *num, char ***prompts, u_int **echo_on)
> +{
> +	Buffer buffer;
> +	struct pam_ctxt *ctxt = ctx;
> +	size_t plen;
> +	u_char type;
> +	char *msg;
> +	size_t len, mlen;
1682,1683c1892,1980
< +		GSSAPI="GSI"
< +	fi
---
> +	debug3("PAM: %s entering", __func__);
> +	buffer_init(&buffer);
> +	*name = xstrdup("");
> +	*info = xstrdup("");
> +	*prompts = xmalloc(sizeof(char *));
> +	**prompts = NULL;
> +	plen = 0;
> +	*echo_on = xmalloc(sizeof(u_int));
> +	while (ssh_msg_recv(ctxt->pam_psock, &buffer) == 0) {
> +		type = buffer_get_char(&buffer);
> +		msg = buffer_get_string(&buffer, NULL);
> +		mlen = strlen(msg);
> +		switch (type) {
> +		case PAM_PROMPT_ECHO_ON:
> +		case PAM_PROMPT_ECHO_OFF:
> +			*num = 1;
> +			len = plen + mlen + 1;
> +			**prompts = xrealloc(**prompts, 1, len);
> +			strlcpy(**prompts + plen, msg, len - plen);
> +			plen += mlen;
> +			**echo_on = (type == PAM_PROMPT_ECHO_ON);
> +			xfree(msg);
> +			return (0);
> +		case PAM_ERROR_MSG:
> +		case PAM_TEXT_INFO:
> +			/* accumulate messages */
> +			len = plen + mlen + 2;
> +			**prompts = xrealloc(**prompts, 1, len);
> +			strlcpy(**prompts + plen, msg, len - plen);
> +			plen += mlen;
> +			strlcat(**prompts + plen, "\n", len - plen);
> +			plen++;
> +			xfree(msg);
> +			break;
> +		case PAM_ACCT_EXPIRED:
> +			sshpam_account_status = 0;
> +			/* FALLTHROUGH */
> +		case PAM_AUTH_ERR:
> +			debug3("PAM: %s", pam_strerror(sshpam_handle, type));
> +			if (**prompts != NULL && strlen(**prompts) != 0) {
> +				*info = **prompts;
> +				**prompts = NULL;
> +				*num = 0;
> +				**echo_on = 0;
> +				ctxt->pam_done = -1;
> +				xfree(msg);
> +				return 0;
> +			}
> +			/* FALLTHROUGH */
> +		case PAM_SUCCESS:
> +			if (**prompts != NULL) {
> +				/* drain any accumulated messages */
> +				debug("PAM: %s", **prompts);
> +				buffer_append(&loginmsg, **prompts,
> +				    strlen(**prompts));
> +				xfree(**prompts);
> +				**prompts = NULL;
> +			}
> +			if (type == PAM_SUCCESS) {
> +				if (!sshpam_authctxt->valid ||
> +				    (sshpam_authctxt->pw->pw_uid == 0 &&
> +				    options.permit_root_login != PERMIT_YES))
> +					fatal("Internal error: PAM auth "
> +					    "succeeded when it should have "
> +					    "failed");
> +#ifndef USE_POSIX_THREADS
> +                import_environments(&buffer);
> +#endif
> +				*num = 0;
> +				**echo_on = 0;
> +				ctxt->pam_done = 1;
> +				xfree(msg);
> +				return (0);
> +			}
> +			error("PAM: %s for %s%.100s from %.100s", msg,
> +			    sshpam_authctxt->valid ? "" : "illegal user ",
> +			    sshpam_authctxt->user,
> +			    get_remote_name_or_ip(utmp_len, options.use_dns));
> +			/* FALLTHROUGH */
> +		default:
> +			*num = 0;
> +			**echo_on = 0;
> +			xfree(msg);
> +			ctxt->pam_done = -1;
> +			return (-1);
> +		}
> +	}
> +	return (-1);
> +}
1685,1698c1982,1987
< +	if test "x$gsi_path" = "xyes" ; then
< +		if test -z "$GLOBUS_LOCATION" ; then
< +			as_fn_error $? "GLOBUS_LOCATION environment variable must be set." "$LINENO" 5
< +		else
< +			gsi_path="$GLOBUS_LOCATION"
< +		fi
< +	fi
< +	GLOBUS_LOCATION="$gsi_path"
< +	export GLOBUS_LOCATION
< +    LD_LIBRARY_PATH="${gsi_path}/lib:$LD_LIBRARY_PATH"
< +    export LD_LIBRARY_PATH
< +	if test ! -d "$GLOBUS_LOCATION" ; then
< +		as_fn_error $? "Cannot find Globus installation.  Set GLOBUS_LOCATION environment variable." "$LINENO" 5
< +	fi
---
> +/* XXX - see also comment in auth-chall.c:verify_response */
> +static int
> +sshpam_respond(void *ctx, u_int num, char **resp)
> +{
> +	Buffer buffer;
> +	struct pam_ctxt *ctxt = ctx;
1700,1707c1989,2016
< +        if test "x$globus_flavor_type" = "xno" ; then
< +                as_fn_error $? "--with-globus-flavor=TYPE must be specified" "$LINENO" 5
< +	fi
< +        if test "x$globus_flavor_type" = "xyes" ; then
< +                as_fn_error $? "--with-globus-flavor=TYPE must specify a flavor type" "$LINENO" 5
< +	fi
< +    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GLOBUS_LOCATION" >&5
< +$as_echo "$GLOBUS_LOCATION" >&6; }
---
> +	debug2("PAM: %s entering, %u responses", __func__, num);
> +	switch (ctxt->pam_done) {
> +	case 1:
> +		sshpam_authenticated = 1;
> +		return (0);
> +	case 0:
> +		break;
> +	default:
> +		return (-1);
> +	}
> +	if (num != 1) {
> +		error("PAM: expected one response, got %u", num);
> +		return (-1);
> +	}
> +	buffer_init(&buffer);
> +	if (sshpam_authctxt->valid &&
> +	    (sshpam_authctxt->pw->pw_uid != 0 ||
> +	    options.permit_root_login == PERMIT_YES))
> +		buffer_put_cstring(&buffer, *resp);
> +	else
> +		buffer_put_cstring(&buffer, badpw);
> +	if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, &buffer) == -1) {
> +		buffer_free(&buffer);
> +		return (-1);
> +	}
> +	buffer_free(&buffer);
> +	return (1);
> +}
1709,1720c2018,2021
< +	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Globus include path" >&5
< +$as_echo_n "checking for Globus include path... " >&6; }
< +  if test -d "${gsi_path}/include/${globus_flavor_type}" ; then
< +	    GLOBUS_INCLUDE="${gsi_path}/include/${globus_flavor_type}"
< +  elif test -d "${gsi_path}/include/globus" ; then
< +      GLOBUS_INCLUDE="${gsi_path}/include/globus"
< +  else
< +		as_fn_error $? "Cannot find Globus include directory in ${gsi_path}/include" "$LINENO" 5
< +	fi
< +	GSI_CPPFLAGS="-I${GLOBUS_INCLUDE}"
< +	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
< +$as_echo "yes" >&6; }
---
> +static void
> +sshpam_free_ctx(void *ctxtp)
> +{
> +	struct pam_ctxt *ctxt = ctxtp;
1722,1759c2023,2032
< +	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for globus-makefile-header" >&5
< +$as_echo_n "checking for globus-makefile-header... " >&6; }
< +	if test -x ${gsi_path}/bin/globus-makefile-header ; then
< +		${gsi_path}/bin/globus-makefile-header --flavor=${globus_flavor_type} ${gsi_static} globus_gss_assist globus_usage 2>/dev/null | sed 's/ = \(.*\)/="\1"/' > ./gpt_build_tmp.sh
< +	elif test -x ${gsi_path}/sbin/globus-makefile-header ; then
< +		${gsi_path}/sbin/globus-makefile-header --flavor=${globus_flavor_type} ${gsi_static} globus_gss_assist globus_usage 2>/dev/null | sed 's/ = \(.*\)/="\1"/' > ./gpt_build_tmp.sh
< +	fi
< +    if test -f ./gpt_build_tmp.sh ; then
< +    	. ./gpt_build_tmp.sh
< +    fi
< +	if test -z "$GLOBUS_PKG_LIBS" ; then
< +    	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
< +$as_echo "no" >&6; }
< +        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gpt_build_config" >&5
< +$as_echo_n "checking for gpt_build_config... " >&6; }
< +        # globus-makefile-header failed so try gpt_build_config
< +        # likely this is because gpt-postinstall hasn't been run yet
< +        # (i.e., this is a fresh Globus Toolkit install)
< +        if test -x $GPT_LOCATION/sbin/gpt_build_config ; then
< +        	gpt_linkline_helper="$GPT_LOCATION/sbin/gpt_build_config"
< +        elif test -x ${gsi_path}/sbin/gpt_build_config ; then
< +        	gpt_linkline_helper="${gsi_path}/sbin/gpt_build_config"
< +        else
< +            as_fn_error $? "Cannot find gpt_build_config: GPT installation is incomplete" "$LINENO" 5
< +        fi
< +        if test -n "${gsi_static}"; then
< +           ${gpt_linkline_helper} -f ${globus_flavor_type} -link static -src pkg_data_src.gpt
< +        else
< +        	${gpt_linkline_helper} -f ${globus_flavor_type} -link shared -src pkg_data_src.gpt
< +        fi
< +        . ./gpt_build_temp.sh
< +        if test -z "$GPT_CONFIG_PGM_LINKS" ; then
< +        	as_fn_error $? "gpt_build_config failed" "$LINENO" 5
< +        fi
< +       	GSI_LDFLAGS="-L${gsi_path}/lib"
< +    fi
< +   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
< +$as_echo "yes" >&6; }
---
> +	debug3("PAM: %s entering", __func__);
> +	sshpam_thread_cleanup();
> +	xfree(ctxt);
> +	/*
> +	 * We don't call sshpam_cleanup() here because we may need the PAM
> +	 * handle at a later stage, e.g. when setting up a session.  It's
> +	 * still on the cleanup list, so pam_end() *will* be called before
> +	 * the server process terminates.
> +	 */
> +}
1761c2034,2040
< +	$as_echo "#define HAVE_GSSAPI_H 1" >>confdefs.h
---
> +KbdintDevice sshpam_device = {
> +	"pam",
> +	sshpam_init_ctx,
> +	sshpam_query,
> +	sshpam_respond,
> +	sshpam_free_ctx
> +};
1762a2042,2048
> +KbdintDevice mm_sshpam_device = {
> +	"pam",
> +	mm_sshpam_init_ctx,
> +	mm_sshpam_query,
> +	mm_sshpam_respond,
> +	mm_sshpam_free_ctx
> +};
1764,1776c2050,2057
< +    if test -n "$GLOBUS_CC" ; then
< +        CC="$GLOBUS_CC"
< +    fi
< +    CFLAGS="$CFLAGS $GLOBUS_CFLAGS $GPT_CONFIG_CFLAGS"
< +    if test -n "$GLOBUS_CPP" ; then
< +        CPP="$GLOBUS_CPP"
< +    fi
< +	CPPFLAGS="$CPPFLAGS $GLOBUS_CPPFLAGS $GLOBUS_INCLUDES $GSI_CPPFLAGS $GPT_CONFIG_INCLUDES"
< +	LIBS="$LIBS $GLOBUS_LIBS $GLOBUS_PKG_LIBS $GPT_CONFIG_LIBS $GPT_CONFIG_PGM_LINKS"
< +    if test -n "$GLOBUS_LD" ; then
< +        LD="$GLOBUS_LD"
< +    fi
< +	LDFLAGS="$LDFLAGS $GLOBUS_LDFLAGS $GSI_LDFLAGS"
---
> +/*
> + * This replaces auth-pam.c
> + */
> +void
> +start_pam(Authctxt *authctxt)
> +{
> +	if (!options.use_pam)
> +		fatal("PAM: initialisation requested when UsePAM=no");
1778,1782c2059,2061
< +	INSTALL_GSISSH="yes"
< +else
< +	INSTALL_GSISSH=""
< +fi
< +# End Globus/GSI section
---
> +	if (sshpam_init(authctxt) == -1)
> +		fatal("PAM: initialisation failed");
> +}
1784,1867c2063,2064
<  ac_config_headers="$ac_config_headers config.h"
<  
<  ac_ext=c
< @@ -5700,29 +5884,8 @@
<  fi
<  rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
<  }
< -	{
< -	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wuninitialized" >&5
< -$as_echo_n "checking if $CC supports -Wuninitialized... " >&6; }
< -	saved_CFLAGS="$CFLAGS"
< -	CFLAGS="$CFLAGS -Wuninitialized"
< -	_define_flag=""
< -	test "x$_define_flag" = "x" && _define_flag="-Wuninitialized"
< -	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
< -/* end confdefs.h.  */
< -int main(void) { return 0; }
< -_ACEOF
< -if ac_fn_c_try_compile "$LINENO"; then :
< -   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
< -$as_echo "yes" >&6; }
< -		  CFLAGS="$saved_CFLAGS $_define_flag"
< -else
< -   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
< -$as_echo "no" >&6; }
< -		  CFLAGS="$saved_CFLAGS"
< -
< -fi
< -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
< -}
< +#	cc1: warning: -Wuninitialized is not supported without -O
< +#	OSSH_CHECK_CFLAG_COMPILE([-Wuninitialized])
<  	{
<  	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wsign-compare" >&5
<  $as_echo_n "checking if $CC supports -Wsign-compare... " >&6; }
< @@ -6554,37 +6717,9 @@
<  
<  	;;
<  *-*-darwin*)
< -	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have working getaddrinfo" >&5
< -$as_echo_n "checking if we have working getaddrinfo... " >&6; }
< -	if test "$cross_compiling" = yes; then :
< -  { $as_echo "$as_me:${as_lineno-$LINENO}: result: assume it is working" >&5
< -$as_echo "assume it is working" >&6; }
< -else
< -  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
< -/* end confdefs.h.  */
< - #include <mach-o/dyld.h>
< -main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
< -		exit(0);
< -	else
< -		exit(1);
< -}
< -
< -_ACEOF
< -if ac_fn_c_try_run "$LINENO"; then :
< -  { $as_echo "$as_me:${as_lineno-$LINENO}: result: working" >&5
< -$as_echo "working" >&6; }
< -else
< -  { $as_echo "$as_me:${as_lineno-$LINENO}: result: buggy" >&5
< -$as_echo "buggy" >&6; }
<  
<  $as_echo "#define BROKEN_GETADDRINFO 1" >>confdefs.h
<  
< -
< -fi
< -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
< -  conftest.$ac_objext conftest.beam conftest.$ac_ext
< -fi
< -
<  	$as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h
<  
<  	$as_echo "#define BROKEN_SETREUID 1" >>confdefs.h
< @@ -6608,6 +6743,63 @@
<  
<  $as_echo "#define SSH_TUN_PREPEND_AF 1" >>confdefs.h
<  
< +	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have the Security Authorization Session API" >&5
< +$as_echo_n "checking if we have the Security Authorization Session API... " >&6; }
< +	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
< +/* end confdefs.h.  */
< +#include <Security/AuthSession.h>
< +int
< +main ()
---
> +void
> +finish_pam(void)
1869,1871c2066
< +SessionCreate(0, 0);
< +  ;
< +  return 0;
---
> +	sshpam_cleanup();
1873,1877d2067
< +_ACEOF
< +if ac_fn_c_try_compile "$LINENO"; then :
< +  ac_cv_use_security_session_api="yes"
< +
< +$as_echo "#define USE_SECURITY_SESSION_API 1" >>confdefs.h
1879,1894c2069,2070
< +		 LIBS="$LIBS -framework Security"
< +		 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
< +$as_echo "yes" >&6; }
< +else
< +  ac_cv_use_security_session_api="no"
< +		 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
< +$as_echo "no" >&6; }
< +fi
< +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
< +	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have an in-memory credentials cache" >&5
< +$as_echo_n "checking if we have an in-memory credentials cache... " >&6; }
< +	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
< +/* end confdefs.h.  */
< +#include <Kerberos/Kerberos.h>
< +int
< +main ()
---
> +u_int
> +do_pam_account(void)
1896,1902c2072,2074
< +cc_context_t c;
< +		 (void) cc_initialize (&c, 0, NULL, NULL);
< +  ;
< +  return 0;
< +}
< +_ACEOF
< +if ac_fn_c_try_compile "$LINENO"; then :
---
> +	debug("%s: called", __func__);
> +	if (sshpam_account_status != -1)
> +		return (sshpam_account_status);
1904c2076,2078
< +$as_echo "#define USE_CCAPI 1" >>confdefs.h
---
> +	sshpam_err = pam_acct_mgmt(sshpam_handle, 0);
> +	debug3("PAM: %s pam_acct_mgmt = %d (%s)", __func__, sshpam_err,
> +	    pam_strerror(sshpam_handle, sshpam_err));
1906,1914c2080,2083
< +		 LIBS="$LIBS -framework Security"
< +		 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
< +$as_echo "yes" >&6; }
< +		 if test "x$ac_cv_use_security_session_api" = "xno"; then
< +			as_fn_error $? "*** Need a security framework to use the credentials cache API ***" "$LINENO" 5
< +		fi
< +else
< +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
< +$as_echo "no" >&6; }
---
> +	if (sshpam_err != PAM_SUCCESS && sshpam_err != PAM_NEW_AUTHTOK_REQD) {
> +		sshpam_account_status = 0;
> +		return (sshpam_account_status);
> +	}
1916,1937c2085,2086
< +fi
< +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
<  
<  	ac_fn_c_check_decl "$LINENO" "AU_IPv4" "ac_cv_have_decl_AU_IPv4" "$ac_includes_default"
<  if test "x$ac_cv_have_decl_AU_IPv4" = xyes; then :
< @@ -14945,6 +15137,151 @@
<  
<  
<  
< +# Finish configuring Globus GSSAPI
< +if test "x$gsi_path" != "xno" ; then
< +	if test ! -z "$need_dash_r" ; then
< +		LDFLAGS="$LDFLAGS -R${gsi_path}/lib"
< +	fi
< +	if test ! -z "$blibpath" ; then
< +		blibpath="$blibpath:${gsi_path}/lib"
< +	fi
< +	# test that we got the libraries OK
< +	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Globus linkline" >&5
< +$as_echo_n "checking Globus linkline... " >&6; }
< +	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
< +/* end confdefs.h.  */
---
> +	if (sshpam_err == PAM_NEW_AUTHTOK_REQD)
> +		sshpam_password_change_required(1);
1939,1941c2088,2090
< +int
< +main ()
< +{
---
> +	sshpam_account_status = 1;
> +	return (sshpam_account_status);
> +}
1943,1944c2092,2101
< +  ;
< +  return 0;
---
> +void
> +do_pam_set_tty(const char *tty)
> +{
> +	if (tty != NULL) {
> +		debug("PAM: setting PAM_TTY to \"%s\"", tty);
> +		sshpam_err = pam_set_item(sshpam_handle, PAM_TTY, tty);
> +		if (sshpam_err != PAM_SUCCESS)
> +			fatal("PAM: failed to set PAM_TTY: %s",
> +			    pam_strerror(sshpam_handle, sshpam_err));
> +	}
1946,1947d2102
< +_ACEOF
< +if ac_fn_c_try_link "$LINENO"; then :
1949,1950c2104,2129
< +			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
< +$as_echo "yes" >&6; }
---
> +void
> +do_pam_setcred(int init)
> +{
> +	sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
> +	    (const void *)&store_conv);
> +	if (sshpam_err != PAM_SUCCESS)
> +		fatal("PAM: failed to set PAM_CONV: %s",
> +		    pam_strerror(sshpam_handle, sshpam_err));
> +	if (init) {
> +		debug("PAM: establishing credentials");
> +		sshpam_err = pam_setcred(sshpam_handle, PAM_ESTABLISH_CRED);
> +	} else {
> +		debug("PAM: reinitializing credentials");
> +		sshpam_err = pam_setcred(sshpam_handle, PAM_REINITIALIZE_CRED);
> +	}
> +	if (sshpam_err == PAM_SUCCESS) {
> +		sshpam_cred_established = 1;
> +		return;
> +	}
> +	if (sshpam_authenticated)
> +		fatal("PAM: pam_setcred(): %s",
> +		    pam_strerror(sshpam_handle, sshpam_err));
> +	else
> +		debug("PAM: pam_setcred(): %s",
> +		    pam_strerror(sshpam_handle, sshpam_err));
> +}
1952c2131,2175
< +else
---
> +static int
> +sshpam_tty_conv(int n, sshpam_const struct pam_message **msg,
> +    struct pam_response **resp, void *data)
> +{
> +	char input[PAM_MAX_MSG_SIZE];
> +	struct pam_response *reply;
> +	int i;
> +
> +	debug3("PAM: %s called with %d messages", __func__, n);
> +
> +	*resp = NULL;
> +
> +	if (n <= 0 || n > PAM_MAX_NUM_MSG || !isatty(STDIN_FILENO))
> +		return (PAM_CONV_ERR);
> +
> +	if ((reply = calloc(n, sizeof(*reply))) == NULL)
> +		return (PAM_CONV_ERR);
> +
> +	for (i = 0; i < n; ++i) {
> +		switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
> +		case PAM_PROMPT_ECHO_OFF:
> +			reply[i].resp =
> +			    read_passphrase(PAM_MSG_MEMBER(msg, i, msg),
> +			    RP_ALLOW_STDIN);
> +			reply[i].resp_retcode = PAM_SUCCESS;
> +			break;
> +		case PAM_PROMPT_ECHO_ON:
> +			fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg));
> +			if (fgets(input, sizeof input, stdin) == NULL)
> +				input[0] = '\0';
> +			if ((reply[i].resp = strdup(input)) == NULL)
> +				goto fail;
> +			reply[i].resp_retcode = PAM_SUCCESS;
> +			break;
> +		case PAM_ERROR_MSG:
> +		case PAM_TEXT_INFO:
> +			fprintf(stderr, "%s\n", PAM_MSG_MEMBER(msg, i, msg));
> +			reply[i].resp_retcode = PAM_SUCCESS;
> +			break;
> +		default:
> +			goto fail;
> +		}
> +	}
> +	*resp = reply;
> +	return (PAM_SUCCESS);
1954c2177,2184
< +			as_fn_error $? "link with Globus libraries failed" "$LINENO" 5
---
> + fail:
> +	for(i = 0; i < n; i++) {
> +		if (reply[i].resp != NULL)
> +			xfree(reply[i].resp);
> +	}
> +	xfree(reply);
> +	return (PAM_CONV_ERR);
> +}
1955a2186
> +static struct pam_conv tty_conv = { sshpam_tty_conv, NULL };
1957,1966c2188,2207
< +fi
< +rm -f core conftest.err conftest.$ac_objext \
< +    conftest$ac_exeext conftest.$ac_ext
< +    for ac_func in globus_gss_assist_map_and_authorize
< +do :
< +  ac_fn_c_check_func "$LINENO" "globus_gss_assist_map_and_authorize" "ac_cv_func_globus_gss_assist_map_and_authorize"
< +if test "x$ac_cv_func_globus_gss_assist_map_and_authorize" = xyes; then :
< +  cat >>confdefs.h <<_ACEOF
< +#define HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE 1
< +_ACEOF
---
> +/*
> + * XXX this should be done in the authentication phase, but ssh1 doesn't
> + * support that
> + */
> +void
> +do_pam_chauthtok(void)
> +{
> +	if (use_privsep)
> +		fatal("Password expired (unable to change with privsep)");
> +	sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
> +	    (const void *)&tty_conv);
> +	if (sshpam_err != PAM_SUCCESS)
> +		fatal("PAM: failed to set PAM_CONV: %s",
> +		    pam_strerror(sshpam_handle, sshpam_err));
> +	debug("PAM: changing password");
> +	sshpam_err = pam_chauthtok(sshpam_handle, PAM_CHANGE_EXPIRED_AUTHTOK);
> +	if (sshpam_err != PAM_SUCCESS)
> +		fatal("PAM: pam_chauthtok(): %s",
> +		    pam_strerror(sshpam_handle, sshpam_err));
> +}
1968,1969c2209,2226
< +fi
< +done
---
> +void
> +do_pam_session(void)
> +{
> +	debug3("PAM: opening session");
> +	sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
> +	    (const void *)&store_conv);
> +	if (sshpam_err != PAM_SUCCESS)
> +		fatal("PAM: failed to set PAM_CONV: %s",
> +		    pam_strerror(sshpam_handle, sshpam_err));
> +	sshpam_err = pam_open_session(sshpam_handle, 0);
> +	if (sshpam_err == PAM_SUCCESS)
> +		sshpam_session_open = 1;
> +	else {
> +		sshpam_session_open = 0;
> +		disable_forwarding();
> +		error("PAM: pam_open_session(): %s",
> +		    pam_strerror(sshpam_handle, sshpam_err));
> +	}
1971c2228
< +fi
---
> +}
1972a2230,2234
> +int
> +is_pam_session_open(void)
> +{
> +	return sshpam_session_open;
> +}
1974,1975c2236,2247
< +ac_fn_c_check_func "$LINENO" "globus_usage_stats_send" "ac_cv_func_globus_usage_stats_send"
< +if test "x$ac_cv_func_globus_usage_stats_send" = xyes; then :
---
> +/*
> + * Set a PAM environment string. We need to do this so that the session
> + * modules can handle things like Kerberos/GSI credentials that appear
> + * during the ssh authentication process.
> + */
> +int
> +do_pam_putenv(char *name, char *value)
> +{
> +	int ret = 1;
> +#ifdef HAVE_PAM_PUTENV
> +	char *compound;
> +	size_t len;
1977c2249,2250
< +$as_echo "#define HAVE_GLOBUS_USAGE 1" >>confdefs.h
---
> +	len = strlen(name) + strlen(value) + 2;
> +	compound = xmalloc(len);
1979c2252,2255
< +fi
---
> +	snprintf(compound, len, "%s=%s", name, value);
> +	ret = pam_putenv(sshpam_handle, compound);
> +	xfree(compound);
> +#endif
1980a2257,2258
> +	return (ret);
> +}
1982,1983c2260,2264
< +ac_fn_c_check_func "$LINENO" "globus_usage_stats_send_array" "ac_cv_func_globus_usage_stats_send_array"
< +if test "x$ac_cv_func_globus_usage_stats_send_array" = xyes; then :
---
> +char **
> +fetch_pam_child_environment(void)
> +{
> +	return sshpam_env;
> +}
1985c2266,2270
< +$as_echo "#define HAVE_GLOBUS_USAGE_SEND_ARRAY 1" >>confdefs.h
---
> +char **
> +fetch_pam_environment(void)
> +{
> +	return (pam_getenvlist(sshpam_handle));
> +}
1987c2272,2275
< +fi
---
> +void
> +free_pam_environment(char **env)
> +{
> +	char **envp;
1988a2277,2278
> +	if (env == NULL)
> +		return;
1990c2280,2283
< +# Check whether the user wants GSSAPI mechglue support
---
> +	for (envp = env; *envp; envp++)
> +		xfree(*envp);
> +	xfree(env);
> +}
1992,1996c2285,2334
< +# Check whether --with-mechglue was given.
< +if test "${with_mechglue+set}" = set; then :
< +  withval=$with_mechglue;
< +		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mechglue library" >&5
< +$as_echo_n "checking for mechglue library... " >&6; }
---
> +/*
> + * "Blind" conversation function for password authentication.  Assumes that
> + * echo-off prompts are for the password and stores messages for later
> + * display.
> + */
> +static int
> +sshpam_passwd_conv(int n, sshpam_const struct pam_message **msg,
> +    struct pam_response **resp, void *data)
> +{
> +	struct pam_response *reply;
> +	int i;
> +	size_t len;
> +
> +	debug3("PAM: %s called with %d messages", __func__, n);
> +
> +	*resp = NULL;
> +
> +	if (n <= 0 || n > PAM_MAX_NUM_MSG)
> +		return (PAM_CONV_ERR);
> +
> +	if ((reply = calloc(n, sizeof(*reply))) == NULL)
> +		return (PAM_CONV_ERR);
> +
> +	for (i = 0; i < n; ++i) {
> +		switch (PAM_MSG_MEMBER(msg, i, msg_style)) {
> +		case PAM_PROMPT_ECHO_OFF:
> +			if (sshpam_password == NULL)
> +				goto fail;
> +			if ((reply[i].resp = strdup(sshpam_password)) == NULL)
> +				goto fail;
> +			reply[i].resp_retcode = PAM_SUCCESS;
> +			break;
> +		case PAM_ERROR_MSG:
> +		case PAM_TEXT_INFO:
> +			len = strlen(PAM_MSG_MEMBER(msg, i, msg));
> +			if (len > 0) {
> +				buffer_append(&loginmsg,
> +				    PAM_MSG_MEMBER(msg, i, msg), len);
> +				buffer_append(&loginmsg, "\n", 1);
> +			}
> +			if ((reply[i].resp = strdup("")) == NULL)
> +				goto fail;
> +			reply[i].resp_retcode = PAM_SUCCESS;
> +			break;
> +		default:
> +			goto fail;
> +		}
> +	}
> +	*resp = reply;
> +	return (PAM_SUCCESS);
1998,2007c2336,2343
< +		if test -e ${withval}/libgssapi.a ; then
< +		    mechglue_lib=${withval}/libgssapi.a
< +		elif test -e ${withval}/lib/libgssapi.a ; then
< +		    mechglue_lib=${withval}/lib/libgssapi.a
< +		else
< +		    as_fn_error $? "\"Can't find libgssapi in ${withval}\"" "$LINENO" 5;
< +		fi
< +		LIBS="${mechglue_lib} $LIBS"
< +		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${mechglue_lib}" >&5
< +$as_echo "${mechglue_lib}" >&6; }
---
> + fail:
> +	for(i = 0; i < n; i++) {
> +		if (reply[i].resp != NULL)
> +			xfree(reply[i].resp);
> +	}
> +	xfree(reply);
> +	return (PAM_CONV_ERR);
> +}
2009,2017c2345
< +		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
< +$as_echo_n "checking for dlopen in -ldl... " >&6; }
< +if ${ac_cv_lib_dl_dlopen+:} false; then :
< +  $as_echo_n "(cached) " >&6
< +else
< +  ac_check_lib_save_LIBS=$LIBS
< +LIBS="-ldl  $LIBS"
< +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
< +/* end confdefs.h.  */
---
> +static struct pam_conv passwd_conv = { sshpam_passwd_conv, NULL };
2019,2025c2347,2349
< +/* Override any GCC internal prototype to avoid an error.
< +   Use char because int might match the return type of a GCC
< +   builtin and then its argument prototype would still apply.  */
< +#ifdef __cplusplus
< +extern "C"
< +#endif
< +char dlopen ();
---
> +/*
> + * Attempt password authentication via PAM
> + */
2027c2351
< +main ()
---
> +sshpam_auth_passwd(Authctxt *authctxt, const char *password)
2029,2050c2353,2354
< +return dlopen ();
< +  ;
< +  return 0;
< +}
< +_ACEOF
< +if ac_fn_c_try_link "$LINENO"; then :
< +  ac_cv_lib_dl_dlopen=yes
< +else
< +  ac_cv_lib_dl_dlopen=no
< +fi
< +rm -f core conftest.err conftest.$ac_objext \
< +    conftest$ac_exeext conftest.$ac_ext
< +LIBS=$ac_check_lib_save_LIBS
< +fi
< +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
< +$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
< +if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
< +  cat >>confdefs.h <<_ACEOF
< +#define HAVE_LIBDL 1
< +_ACEOF
< +
< +  LIBS="-ldl $LIBS"
---
> +	int flags = (options.permit_empty_passwd == 0 ?
> +	    PAM_DISALLOW_NULL_AUTHTOK : 0);
2052c2356,2358
< +fi
---
> +	if (!options.use_pam || sshpam_handle == NULL)
> +		fatal("PAM: %s called when PAM disabled or failed to "
> +		    "initialise.", __func__);
2054,2056c2360,2361
< +		if test $ac_cv_lib_dl_dlopen = yes; then
< +		   LDFLAGS="$LDFLAGS -ldl -Wl,-Bsymbolic"
< +		fi
---
> +	sshpam_password = password;
> +	sshpam_authctxt = authctxt;
2058c2363,2370
< +		$as_echo "#define GSSAPI 1" >>confdefs.h
---
> +	/*
> +	 * If the user logging in is invalid, or is root but is not permitted
> +	 * by PermitRootLogin, use an invalid password to prevent leaking
> +	 * information via timing (eg if the PAM config has a delay on fail).
> +	 */
> +	if (!authctxt->valid || (authctxt->pw->pw_uid == 0 &&
> +	    options.permit_root_login != PERMIT_YES))
> +		sshpam_password = badpw;
2059a2372,2376
> +	sshpam_err = pam_set_item(sshpam_handle, PAM_CONV,
> +	    (const void *)&passwd_conv);
> +	if (sshpam_err != PAM_SUCCESS)
> +		fatal("PAM: %s: failed to set PAM_CONV: %s", __func__,
> +		    pam_strerror(sshpam_handle, sshpam_err));
2061,2073c2378,2399
< +$as_echo "#define MECHGLUE 1" >>confdefs.h
< +
< +		GSSAPI="mechglue"
< +
< +
< +fi
< +
< +
< +
<  # Check whether user wants Kerberos 5 support
<  KRB5_MSG="no"
<  
< @@ -15348,7 +15685,27 @@
---
> +	sshpam_err = pam_authenticate(sshpam_handle, flags);
> +	sshpam_password = NULL;
> +	if (sshpam_err == PAM_SUCCESS && authctxt->valid) {
> +		debug("PAM: password authentication accepted for %.100s",
> +		    authctxt->user);
> +		return 1;
> +	} else {
> +		debug("PAM: password authentication failed for %.100s: %s",
> +		    authctxt->valid ? authctxt->user : "an illegal user",
> +		    pam_strerror(sshpam_handle, sshpam_err));
> +		return 0;
> +	}
> +}
> +#endif /* USE_PAM */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/auth-pam.h openssh-6.0p1/auth-pam.h
> --- openssh-6.0p1.orig/auth-pam.h	2012-07-12 17:00:48.902192678 +0200
> +++ openssh-6.0p1/auth-pam.h	2012-07-12 17:01:14.010683967 +0200
> @@ -46,5 +46,6 @@
>  void sshpam_cleanup(void);
>  int sshpam_auth_passwd(Authctxt *, const char *);
>  int is_pam_session_open(void);
> +struct passwd *sshpam_getpw(const char *);
2074a2401,2405
>  #endif /* USE_PAM */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/buffer.c openssh-6.0p1/buffer.c
> --- openssh-6.0p1.orig/buffer.c	2012-07-12 17:00:49.046195495 +0200
> +++ openssh-6.0p1/buffer.c	2012-07-12 17:01:14.086685454 +0200
> @@ -127,7 +127,7 @@
2075a2407,2419
>  	/* Increase the size of the buffer and retry. */
>  	newlen = roundup(buffer->alloc + len, BUFFER_ALLOCSZ);
> -	if (newlen > BUFFER_MAX_LEN)
> +	if (newlen > BUFFER_MAX_LEN_HPN)
>  		fatal("buffer_append_space: alloc %u not supported",
>  		    newlen);
>  	buffer->buf = xrealloc(buffer->buf, 1, newlen);
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/buffer.h openssh-6.0p1/buffer.h
> --- openssh-6.0p1.orig/buffer.h	2012-07-12 17:00:49.050195573 +0200
> +++ openssh-6.0p1/buffer.h	2012-07-12 17:01:14.090685532 +0200
> @@ -16,6 +16,9 @@
>  #ifndef BUFFER_H
>  #define BUFFER_H
2077,2096c2421,2422
< -		fi
< +			# If we're using some other GSSAPI
< +			if test "$GSSAPI" -a "$GSSAPI" != "mechglue"; then
< +				as_fn_error $? "$GSSAPI GSSAPI library conflicts with Kerberos support.  Use mechglue instead." "$LINENO" 5
< +			fi
< +
< +			if test -z "$GSSAPI"; then
< +				GSSAPI="KRB5";
< +			fi
< +
< +			oldCPP="$CPPFLAGS"
< +			CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
< +			ac_fn_c_check_header_mongrel "$LINENO" "gssapi_krb5.h" "ac_cv_header_gssapi_krb5_h" "$ac_includes_default"
< +if test "x$ac_cv_header_gssapi_krb5_h" = xyes; then :
< +
< +else
< +   CPPFLAGS="$oldCPP"
< +fi
< +
< +
---
> +/* move the following to a more appropriate place and name */
> +#define BUFFER_MAX_LEN_HPN          0x4000000  /* 64MB */
2098,2103c2424,2430
< +                fi
<  		if test ! -z "$need_dash_r" ; then
<  			LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib"
<  		fi
< @@ -15461,6 +15818,57 @@
<  fi
---
>  typedef struct {
>  	u_char	*buf;		/* Buffer for data. */
>  	u_int	 alloc;		/* Number of bytes allocated for data. */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/canohost.c openssh-6.0p1/canohost.c
> --- openssh-6.0p1.orig/canohost.c	2012-07-12 17:00:49.062195808 +0200
> +++ openssh-6.0p1/canohost.c	2012-07-12 17:01:14.098685689 +0200
> @@ -16,6 +16,7 @@
2104a2432,2434
>  #include <sys/types.h>
>  #include <sys/socket.h>
> +#include <sys/param.h>          /* for MAXHOSTNAMELEN */
2106,2107c2436,2441
< +# Check whether user wants AFS_KRB5 support
< +AFS_KRB5_MSG="no"
---
>  #include <netinet/in.h>
>  #include <arpa/inet.h>
> @@ -438,3 +439,33 @@
>  {
>  	return get_port(1);
>  }
2109,2112c2443,2446
< +# Check whether --with-afs-krb5 was given.
< +if test "${with_afs_krb5+set}" = set; then :
< +  withval=$with_afs_krb5;
< +		if test "x$withval" != "xno" ; then
---
> +void
> +resolve_localhost(char **host)
> +{
> +    struct hostent *hostinfo;
2114c2448,2479
< +			if test "x$withval" != "xyes" ; then
---
> +    hostinfo = gethostbyname(*host);
> +    if (hostinfo == NULL || hostinfo->h_name == NULL) {
> +	debug("gethostbyname(%s) failed", *host);
> +	return;
> +    }
> +    if (hostinfo->h_addrtype == AF_INET) {
> +	struct in_addr addr;
> +	addr = *(struct in_addr *)(hostinfo->h_addr);
> +	if (ntohl(addr.s_addr) == INADDR_LOOPBACK) {
> +	    char buf[MAXHOSTNAMELEN];
> +	    if (gethostname(buf, sizeof(buf)) < 0) {
> +		debug("gethostname() failed");
> +		return;
> +	    }
> +	    hostinfo = gethostbyname(buf);
> +	    xfree(*host);
> +	    if (hostinfo == NULL || hostinfo->h_name == NULL) {
> +		*host = xstrdup(buf);
> +	    } else {
> +		*host = xstrdup(hostinfo->h_name);
> +	    }
> +	}
> +    }
> +}
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/canohost.h openssh-6.0p1/canohost.h
> --- openssh-6.0p1.orig/canohost.h	2012-07-12 17:00:49.066195887 +0200
> +++ openssh-6.0p1/canohost.h	2012-07-12 17:01:14.106685845 +0200
> @@ -26,4 +26,6 @@
>  int		 get_sock_port(int, int);
>  void		 clear_cached_addr(void);
>  
> +void		 resolve_localhost(char **host);
2116,2118c2481,2497
< +cat >>confdefs.h <<_ACEOF
< +#define AKLOG_PATH "$withval"
< +_ACEOF
---
>  void		 ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *);
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/ChangeLog.gssapi openssh-6.0p1/ChangeLog.gssapi
> --- openssh-6.0p1.orig/ChangeLog.gssapi	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/ChangeLog.gssapi	2012-07-12 17:01:13.862681212 +0200
> @@ -0,0 +1,113 @@
> +20110101
> +  - Finally update for OpenSSH 5.6p1
> +  - Add GSSAPIServerIdentity option from Jim Basney
> + 
> +20100308
> +  - [ Makefile.in, key.c, key.h ]
> +    Updates for OpenSSH 5.4p1
> +  - [ servconf.c ]
> +    Include GSSAPI options in the sshd -T configuration dump, and flag
> +    some older configuration options as being unsupported. Thanks to Colin 
> +    Watson.
> +  -
2120c2499,2502
< +			else
---
> +20100124
> +  - [ sshconnect2.c ]
> +    Adapt to deal with additional element in Authmethod structure. Thanks to
> +    Colin Watson
2122,2124c2504,2516
< +cat >>confdefs.h <<_ACEOF
< +#define AKLOG_PATH "/usr/bin/aklog"
< +_ACEOF
---
> +20090615
> +  - [ gss-genr.c gss-serv.c kexgssc.c kexgsss.c monitor.c sshconnect2.c
> +      sshd.c ]
> +    Fix issues identified by Greg Hudson following a code review
> +	Check return value of gss_indicate_mechs
> +	Protect GSSAPI calls in monitor, so they can only be used if enabled
> +	Check return values of bignum functions in key exchange
> +	Use BN_clear_free to clear other side's DH value
> +	Make ssh_gssapi_id_kex more robust
> +	Only configure kex table pointers if GSSAPI is enabled
> +	Don't leak mechanism list, or gss mechanism list
> +	Cast data.length before printing
> +	If serverkey isn't provided, use an empty string, rather than NULL
2126c2518,2522
< +			fi
---
> +20090201
> +  - [ gss-genr.c gss-serv.c kex.h kexgssc.c readconf.c readconf.h ssh-gss.h
> +      ssh_config.5 sshconnet2.c ]
> +    Add support for the GSSAPIClientIdentity option, which allows the user
> +    to specify which GSSAPI identity to use to contact a given server
2128,2131c2524,2528
< +			if test -z "$KRB5ROOT" ; then
< +				{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: AFS_KRB5 requires Kerberos 5 support, build may fail" >&5
< +$as_echo "$as_me: WARNING: AFS_KRB5 requires Kerberos 5 support, build may fail" >&2;}
< +			fi
---
> +20080404
> +  - [ gss-serv.c ]
> +    Add code to actually implement GSSAPIStrictAcceptCheck, which had somehow
> +    been omitted from a previous version of this patch. Reported by Borislav
> +    Stoichkov
2133,2136c2530,2533
< +			LIBS="-lkrbafs -lkrb4 $LIBS"
< +			if test ! -z "$AFS_LIBS" ; then
< +				LIBS="$LIBS $AFS_LIBS"
< +			fi
---
> +20070317
> +  - [ gss-serv-krb5.c ]
> +    Remove C99ism, where new_ccname was being declared in the middle of a 
> +    function
2138c2535,2538
< +$as_echo "#define AFS_KRB5 1" >>confdefs.h
---
> +20061220
> +  - [ servconf.c ]
> +    Make default for GSSAPIStrictAcceptorCheck be Yes, to match previous, and 
> +    documented, behaviour. Reported by Dan Watson.
2140,2141c2540,2553
< +			AFS_KRB5_MSG="yes"
< +		fi
---
> +20060910
> +  - [ gss-genr.c kexgssc.c kexgsss.c kex.h monitor.c sshconnect2.c sshd.c
> +      ssh-gss.h ]
> +    add support for gss-group14-sha1 key exchange mechanisms
> +  - [ gss-serv.c servconf.c servconf.h sshd_config sshd_config.5 ]
> +    Add GSSAPIStrictAcceptorCheck option to allow the disabling of
> +    acceptor principal checking on multi-homed machines.
> +    <Bugzilla #928>
> +  - [ sshd_config ssh_config ]
> +    Add settings for GSSAPIKeyExchange and GSSAPITrustDNS to the sample
> +    configuration files
> +  - [ kexgss.c kegsss.c sshconnect2.c sshd.c ]
> +    Code cleanup. Replace strlen/xmalloc/snprintf sequences with xasprintf()
> +    Limit length of error messages displayed by client
2142a2555,2559
> +20060909
> +  - [ gss-genr.c gss-serv.c ]
> +    move ssh_gssapi_acquire_cred() and ssh_gssapi_server_ctx to be server
> +    only, where they belong 
> +    <Bugzilla #1225>
2144c2561,2564
< +fi
---
> +20060829
> +  - [ gss-serv-krb5.c ]
> +    Fix CCAPI credentials cache name when creating KRB5CCNAME environment 
> +    variable
2145a2566,2569
> +20060828
> +  - [ gss-genr.c ]
> +    Avoid Heimdal context freeing problem
> +    <Fixed upstream 20060829>
2146a2571,2574
> +20060818
> +  - [ gss-genr.c ssh-gss.h sshconnect2.c ]
> +    Make sure that SPENGO is disabled 
> +    <Bugzilla #1218 - Fixed upstream 20060818>
2148,2151c2576,2605
< +# Check whether --with-session-hooks was given.
< +if test "${with_session_hooks+set}" = set; then :
< +  withval=$with_session_hooks;
< +$as_echo "#define SESSION_HOOKS 1" >>confdefs.h
---
> +20060421
> +  - [ gssgenr.c, sshconnect2.c ]
> +    a few type changes (signed versus unsigned, int versus size_t) to
> +    fix compiler errors/warnings 
> +    (from jbasney AT ncsa.uiuc.edu)
> +  - [ kexgssc.c, sshconnect2.c ]
> +    fix uninitialized variable warnings
> +    (from jbasney AT ncsa.uiuc.edu)
> +  - [ gssgenr.c ]
> +    pass oid to gss_display_status (helpful when using GSSAPI mechglue)
> +    (from jbasney AT ncsa.uiuc.edu)
> +    <Bugzilla #1220 >
> +  - [ gss-serv-krb5.c ]
> +    #ifdef HAVE_GSSAPI_KRB5 should be #ifdef HAVE_GSSAPI_KRB5_H
> +    (from jbasney AT ncsa.uiuc.edu)
> +    <Fixed upstream 20060304>
> +  - [ readconf.c, readconf.h, ssh_config.5, sshconnect2.c 
> +    add client-side GssapiKeyExchange option
> +    (from jbasney AT ncsa.uiuc.edu)
> +  - [ sshconnect2.c ]
> +    add support for GssapiTrustDns option for gssapi-with-mic
> +    (from jbasney AT ncsa.uiuc.edu)
> +    <gssapi-with-mic support is Bugzilla #1008>
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/channels.c openssh-6.0p1/channels.c
> --- openssh-6.0p1.orig/channels.c	2012-07-12 17:00:49.074196043 +0200
> +++ openssh-6.0p1/channels.c	2012-07-12 17:01:14.114686002 +0200
> @@ -173,8 +173,14 @@
>  static int connect_next(struct channel_connect *);
>  static void channel_connect_ctx_free(struct channel_connect *);
>  
2152a2607,2608
> +static int hpn_disabled = 0;
> +static int hpn_buffer_size = 2 * 1024 * 1024;
2154c2610,2611
< +fi
---
>  /* -- channel core */
>  
2157,2176c2614,2627
<  # Looking for programs, paths and files
<  
<  PRIVSEP_PATH=/var/empty
< @@ -15542,7 +15950,10 @@
<  fi
<  
<  
< +# strip causes problems with GSI libraries...
< +if test -z "$GLOBUS_LDFLAGS" ; then
<  STRIP_OPT=-s
< +fi
<  # Check whether --enable-strip was given.
<  if test "${enable_strip+set}" = set; then :
<    enableval=$enable_strip;
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/configure.ac openssh-6.0p1/configure.ac
< --- openssh-6.0p1.orig/configure.ac	2012-04-19 06:46:38.000000000 -0500
< +++ openssh-6.0p1/configure.ac	2012-05-27 17:50:01.000000000 -0500
< @@ -19,6 +19,151 @@
<  AC_CONFIG_SRCDIR([ssh.c])
<  AC_LANG([C])
---
>  Channel *
>  channel_by_id(int id)
>  {
> @@ -318,6 +324,7 @@
>  	c->local_window_max = window;
>  	c->local_consumed = 0;
>  	c->local_maxpacket = maxpack;
> +	c->dynamic_window = 0;
>  	c->remote_id = -1;
>  	c->remote_name = xstrdup(remote_name);
>  	c->remote_window = 0;
> @@ -817,11 +824,37 @@
>  		FD_SET(c->sock, writeset);
>  }
2178,2179c2629,2632
< +# Handle Globus configuration right away, because the Globus flavor
< +# determines our compiler options.
---
> +int channel_tcpwinsz () {
> +        u_int32_t tcpwinsz = 0;
> +        socklen_t optsz = sizeof(tcpwinsz);
> +	int ret = -1;
2181,2188c2634,2647
< +# Check whether the user wants GSI (Globus) support
< +gsi_path="no"
< +AC_ARG_WITH(gsi,
< +	[  --with-gsi              Enable Globus GSI authentication support],
< +	[
< +		gsi_path="$withval"
< +	]
< +)
---
> +	/* if we aren't on a socket return 128KB*/
> +	if(!packet_connection_is_on_socket()) 
> +	    return(128*1024);
> +	ret = getsockopt(packet_get_connection_in(),
> +			 SOL_SOCKET, SO_RCVBUF, &tcpwinsz, &optsz);
> +	/* return no more than 64MB */
> +	if ((ret == 0) && tcpwinsz > BUFFER_MAX_LEN_HPN)
> +	    tcpwinsz = BUFFER_MAX_LEN_HPN;
> +#if 0 /* too verbose */
> +	debug2("tcpwinsz: %d for connection: %d", tcpwinsz, 
> +	       packet_get_connection_in());
> +#endif
> +	return(tcpwinsz);
> +}
2190,2195c2649,2801
< +AC_ARG_WITH(globus,
< +	[  --with-globus           Enable Globus GSI authentication support],
< +	[
< +		gsi_path="$withval"
< +	]
< +)
---
>  static void
>  channel_pre_open(Channel *c, fd_set *readset, fd_set *writeset)
>  {
>  	u_int limit = compat20 ? c->remote_window : packet_get_maxsize();
>  
> +        /* check buffer limits */
> +	if ((!c->tcpwinsz) || (c->dynamic_window > 0))
> +    	    c->tcpwinsz = channel_tcpwinsz();
> +	
> +	limit = MIN(limit, 2 * c->tcpwinsz);
> +	
>  	if (c->istate == CHAN_INPUT_OPEN &&
>  	    limit > 0 &&
>  	    buffer_len(&c->input) < limit &&
> @@ -1798,14 +1831,21 @@
>  	    c->local_maxpacket*3) ||
>  	    c->local_window < c->local_window_max/2) &&
>  	    c->local_consumed > 0) {
> +		u_int addition = 0;
> +		/* adjust max window size if we are in a dynamic environment */
> +		if (c->dynamic_window && (c->tcpwinsz > c->local_window_max)) {
> +			/* grow the window somewhat aggressively to maintain pressure */
> +			addition = 1.5*(c->tcpwinsz - c->local_window_max);
> +			c->local_window_max += addition;
> +		}
>  		packet_start(SSH2_MSG_CHANNEL_WINDOW_ADJUST);
>  		packet_put_int(c->remote_id);
> -		packet_put_int(c->local_consumed);
> +		packet_put_int(c->local_consumed + addition);
>  		packet_send();
>  		debug2("channel %d: window %d sent adjust %d",
>  		    c->self, c->local_window,
>  		    c->local_consumed);
> -		c->local_window += c->local_consumed;
> +		c->local_window += c->local_consumed + addition;
>  		c->local_consumed = 0;
>  	}
>  	return 1;
> @@ -2137,11 +2177,12 @@
>  
>  
>  /* If there is data to send to the connection, enqueue some of it now. */
> -void
> +int
>  channel_output_poll(void)
>  {
>  	Channel *c;
>  	u_int i, len;
> +	int packet_length = 0;
>  
>  	for (i = 0; i < channels_alloc; i++) {
>  		c = channels[i];
> @@ -2189,7 +2230,7 @@
>  					packet_start(SSH2_MSG_CHANNEL_DATA);
>  					packet_put_int(c->remote_id);
>  					packet_put_string(data, dlen);
> -					packet_send();
> +					packet_length = packet_send();
>  					c->remote_window -= dlen + 4;
>  					xfree(data);
>  				}
> @@ -2219,7 +2260,7 @@
>  				    SSH2_MSG_CHANNEL_DATA : SSH_MSG_CHANNEL_DATA);
>  				packet_put_int(c->remote_id);
>  				packet_put_string(buffer_ptr(&c->input), len);
> -				packet_send();
> +				packet_length = packet_send();
>  				buffer_consume(&c->input, len);
>  				c->remote_window -= len;
>  			}
> @@ -2254,12 +2295,13 @@
>  			packet_put_int(c->remote_id);
>  			packet_put_int(SSH2_EXTENDED_DATA_STDERR);
>  			packet_put_string(buffer_ptr(&c->extended), len);
> -			packet_send();
> +			packet_length = packet_send();
>  			buffer_consume(&c->extended, len);
>  			c->remote_window -= len;
>  			debug2("channel %d: sent ext data %d", c->self, len);
>  		}
>  	}
> +	return (packet_length);
>  }
>  
>  
> @@ -2643,6 +2685,13 @@
>  	IPv4or6 = af;
>  }
>  
> +void 
> +channel_set_hpn(int external_hpn_disabled, int external_hpn_buffer_size)
> +{
> +      	hpn_disabled = external_hpn_disabled;
> +	hpn_buffer_size = external_hpn_buffer_size;
> +	debug("HPN Disabled: %d, HPN Buffer Size: %d", hpn_disabled, hpn_buffer_size);
> +}
>  
>  /*
>   * Determine whether or not a port forward listens to loopback, the
> @@ -2809,9 +2858,15 @@
>  		}
>  
>  		/* Allocate a channel number for the socket. */
> +		/* explicitly test for hpn disabled option. if true use smaller window size */
> +		if (hpn_disabled)
>  		c = channel_new("port listener", type, sock, sock, -1,
>  		    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
>  		    0, "port listener", 1);
> + 		else
> + 			c = channel_new("port listener", type, sock, sock, -1,
> + 		    	  hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
> + 		    	  0, "port listener", 1); 
>  		c->path = xstrdup(host);
>  		c->host_port = port_to_connect;
>  		c->listening_addr = addr == NULL ? NULL : xstrdup(addr);
> @@ -3456,10 +3511,17 @@
>  	*chanids = xcalloc(num_socks + 1, sizeof(**chanids));
>  	for (n = 0; n < num_socks; n++) {
>  		sock = socks[n];
> +		/* Is this really necassary? */
> +		if (hpn_disabled) 
>  		nc = channel_new("x11 listener",
>  		    SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
>  		    CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
>  		    0, "X11 inet listener", 1);
> +		else 
> +			nc = channel_new("x11 listener",
> +			    SSH_CHANNEL_X11_LISTENER, sock, sock, -1,
> +			    hpn_buffer_size, CHAN_X11_PACKET_DEFAULT,
> +			    0, "X11 inet listener", 1);
>  		nc->single_connection = single_connection;
>  		(*chanids)[n] = nc->self;
>  	}
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/channels.h openssh-6.0p1/channels.h
> --- openssh-6.0p1.orig/channels.h	2012-07-12 17:00:49.082196200 +0200
> +++ openssh-6.0p1/channels.h	2012-07-12 17:01:14.122686158 +0200
> @@ -128,8 +128,10 @@
>  	u_int	local_window_max;
>  	u_int	local_consumed;
>  	u_int	local_maxpacket;
> +	int	dynamic_window;
>  	int     extended_usage;
>  	int	single_connection;
> +	u_int 	tcpwinsz;	
>  
>  	char   *ctype;		/* type */
>  
> @@ -164,9 +166,11 @@
>  
>  /* default window/packet sizes for tcp/x11-fwd-channel */
>  #define CHAN_SES_PACKET_DEFAULT	(32*1024)
> -#define CHAN_SES_WINDOW_DEFAULT	(64*CHAN_SES_PACKET_DEFAULT)
> +#define CHAN_SES_WINDOW_DEFAULT	(4*CHAN_SES_PACKET_DEFAULT)
2197,2205c2803,2805
< +AC_ARG_WITH(globus-static,
< +	[  --with-globus-static    Link statically with Globus GSI libraries],
< +	[
< +		gsi_static="-static"
< +		if test "x$gsi_path" = "xno" ; then
< +			gsi_path="$withval"
< +		fi
< +	]
< +)
---
>  #define CHAN_TCP_PACKET_DEFAULT	(32*1024)
> -#define CHAN_TCP_WINDOW_DEFAULT	(64*CHAN_TCP_PACKET_DEFAULT)
> +#define CHAN_TCP_WINDOW_DEFAULT	(4*CHAN_TCP_PACKET_DEFAULT)
2207,2217c2807,2824
< +# Check whether the user has a Globus flavor type
< +globus_flavor_type="no"
< +AC_ARG_WITH(globus-flavor,
< +	[  --with-globus-flavor=TYPE  Specify Globus flavor type (ex: gcc32dbg)],
< +	[
< +		globus_flavor_type="$withval"
< +		if test "x$gsi_path" = "xno" ; then
< +			gsi_path="yes"
< +		fi
< +	]
< +)
---
>  #define CHAN_X11_PACKET_DEFAULT	(16*1024)
>  #define CHAN_X11_WINDOW_DEFAULT	(4*CHAN_X11_PACKET_DEFAULT)
>  
> @@ -240,7 +244,7 @@
>  
>  void	 channel_prepare_select(fd_set **, fd_set **, int *, u_int*, int);
>  void     channel_after_select(fd_set *, fd_set *);
> -void     channel_output_poll(void);
> +int      channel_output_poll(void);
>  
>  int      channel_not_very_much_buffered_data(void);
>  void     channel_close_all(void);
> @@ -300,4 +304,7 @@
>  void	 chan_write_failed(Channel *);
>  void	 chan_obuf_empty(Channel *);
>  
> +/* hpn handler */
> +void     channel_set_hpn(int, int);
2219,2222c2826,2865
< +if test "x$gsi_path" != "xno" ; then
< +	# Globus GSSAPI configuration
< +	AC_MSG_CHECKING(for Globus GSI)
< +	AC_DEFINE(GSI, 1, [Define if you want GSI/Globus authentication support.])
---
>  #endif
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/cipher.c openssh-6.0p1/cipher.c
> --- openssh-6.0p1.orig/cipher.c	2012-07-12 17:00:49.110196747 +0200
> +++ openssh-6.0p1/cipher.c	2012-07-12 17:01:14.130686315 +0200
> @@ -163,7 +163,8 @@
>  	for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
>  	    (p = strsep(&cp, CIPHER_SEP))) {
>  		c = cipher_by_name(p);
> -		if (c == NULL || c->number != SSH_CIPHER_SSH2) {
> +		if (c == NULL || (c->number != SSH_CIPHER_SSH2 &&
> +				  c->number != SSH_CIPHER_NONE)) {
>  			debug("bad cipher %s [%s]", p, names);
>  			xfree(cipher_list);
>  			return 0;
> @@ -337,6 +338,7 @@
>  	int evplen;
>  
>  	switch (c->number) {
> +	case SSH_CIPHER_NONE:
>  	case SSH_CIPHER_SSH2:
>  	case SSH_CIPHER_DES:
>  	case SSH_CIPHER_BLOWFISH:
> @@ -371,6 +373,7 @@
>  	int evplen = 0;
>  
>  	switch (c->number) {
> +	case SSH_CIPHER_NONE:
>  	case SSH_CIPHER_SSH2:
>  	case SSH_CIPHER_DES:
>  	case SSH_CIPHER_BLOWFISH:
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/clientloop.c openssh-6.0p1/clientloop.c
> --- openssh-6.0p1.orig/clientloop.c	2012-07-12 17:00:49.130197139 +0200
> +++ openssh-6.0p1/clientloop.c	2012-07-12 17:01:14.138686471 +0200
> @@ -111,6 +111,10 @@
>  #include "msg.h"
>  #include "roaming.h"
>  
> +#ifdef GSSAPI
> +#include "ssh-gss.h"
> +#endif
2224,2230c2867,2873
< +	if test "$GSSAPI" -a "$GSSAPI" != "mechglue"; then
< +		AC_MSG_ERROR([Previously configured GSSAPI library conflicts with Globus GSI.])
< +	fi
< +	if test -z "$GSSAPI"; then
< +		AC_DEFINE(GSSAPI)
< +		GSSAPI="GSI"
< +	fi
---
>  /* import options */
>  extern Options options;
>  
> @@ -1540,6 +1544,15 @@
>  		/* Do channel operations unless rekeying in progress. */
>  		if (!rekeying) {
>  			channel_after_select(readset, writeset);
2232,2245c2875,2881
< +	if test "x$gsi_path" = "xyes" ; then
< +		if test -z "$GLOBUS_LOCATION" ; then
< +			AC_MSG_ERROR(GLOBUS_LOCATION environment variable must be set.)
< +		else
< +			gsi_path="$GLOBUS_LOCATION"
< +		fi
< +	fi
< +	GLOBUS_LOCATION="$gsi_path"
< +	export GLOBUS_LOCATION
< +    LD_LIBRARY_PATH="${gsi_path}/lib:$LD_LIBRARY_PATH"
< +    export LD_LIBRARY_PATH
< +	if test ! -d "$GLOBUS_LOCATION" ; then
< +		AC_MSG_ERROR(Cannot find Globus installation.  Set GLOBUS_LOCATION environment variable.)
< +	fi
---
> +#ifdef GSSAPI
> +			if (options.gss_renewal_rekey &&
> +			    ssh_gssapi_credentials_updated((Gssctxt *)GSS_C_NO_CONTEXT)) {
> +				debug("credentials updated - forcing rekey");
> +				need_rekeying = 1;
> +			}
> +#endif
2247,2253c2883,2933
< +        if test "x$globus_flavor_type" = "xno" ; then
< +                AC_MSG_ERROR(--with-globus-flavor=TYPE must be specified)
< +	fi
< +        if test "x$globus_flavor_type" = "xyes" ; then
< +                AC_MSG_ERROR(--with-globus-flavor=TYPE must specify a flavor type)
< +	fi
< +    AC_MSG_RESULT($GLOBUS_LOCATION)
---
>  			if (need_rekeying || packet_need_rekeying()) {
>  				debug("need rekeying");
>  				xxx_kex->done = 0;
> @@ -1825,9 +1838,15 @@
>  	sock = x11_connect_display();
>  	if (sock < 0)
>  		return NULL;
> +	/* again is this really necessary for X11? */
> +	if (options.hpn_disabled) 
>  	c = channel_new("x11",
>  	    SSH_CHANNEL_X11_OPEN, sock, sock, -1,
>  	    CHAN_TCP_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
> +	else 
> +		c = channel_new("x11",
> +		    SSH_CHANNEL_X11_OPEN, sock, sock, -1,
> +		    options.hpn_buffer_size, CHAN_X11_PACKET_DEFAULT, 0, "x11", 1);
>  	c->force_drain = 1;
>  	return c;
>  }
> @@ -1847,9 +1866,15 @@
>  	sock = ssh_get_authentication_socket();
>  	if (sock < 0)
>  		return NULL;
> +	if (options.hpn_disabled) 
>  	c = channel_new("authentication agent connection",
>  	    SSH_CHANNEL_OPEN, sock, sock, -1,
> -	    CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0,
> +		    CHAN_X11_WINDOW_DEFAULT, CHAN_TCP_WINDOW_DEFAULT, 0,
> +		    "authentication agent connection", 1);
> +       else
> +	c = channel_new("authentication agent connection",
> +	    SSH_CHANNEL_OPEN, sock, sock, -1,
> +                   options.hpn_buffer_size, options.hpn_buffer_size, 0,
>  	    "authentication agent connection", 1);
>  	c->force_drain = 1;
>  	return c;
> @@ -1877,10 +1902,18 @@
>  		return -1;
>  	}
>  
> +	if(options.hpn_disabled)
> +	c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
> +				CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT,
> +				0, "tun", 1);
> +	else
>  	c = channel_new("tun", SSH_CHANNEL_OPENING, fd, fd, -1,
> -	    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
> +				options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT,
> +				0, "tun", 1);
>  	c->datagram = 1;
>  
2255,2299d2934
< +	AC_MSG_CHECKING(for Globus include path)
< +  if test -d "${gsi_path}/include/${globus_flavor_type}" ; then
< +	    GLOBUS_INCLUDE="${gsi_path}/include/${globus_flavor_type}"
< +  elif test -d "${gsi_path}/include/globus" ; then
< +      GLOBUS_INCLUDE="${gsi_path}/include/globus"
< +  else
< +		AC_MSG_ERROR(Cannot find Globus include directory in ${gsi_path}/include)
< +	fi
< +	GSI_CPPFLAGS="-I${GLOBUS_INCLUDE}"
< +	AC_MSG_RESULT(yes)
< +	
< +	AC_MSG_CHECKING(for globus-makefile-header)
< +	if test -x ${gsi_path}/bin/globus-makefile-header ; then
< +		${gsi_path}/bin/globus-makefile-header --flavor=${globus_flavor_type} ${gsi_static} globus_gss_assist globus_usage 2>/dev/null | sed 's/ = \(.*\)/="\1"/' > ./gpt_build_tmp.sh
< +	elif test -x ${gsi_path}/sbin/globus-makefile-header ; then
< +		${gsi_path}/sbin/globus-makefile-header --flavor=${globus_flavor_type} ${gsi_static} globus_gss_assist globus_usage 2>/dev/null | sed 's/ = \(.*\)/="\1"/' > ./gpt_build_tmp.sh
< +	fi
< +    if test -f ./gpt_build_tmp.sh ; then
< +    	. ./gpt_build_tmp.sh
< +    fi
< +	if test -z "$GLOBUS_PKG_LIBS" ; then
< +    	AC_MSG_RESULT(no)
< +        AC_MSG_CHECKING(for gpt_build_config)
< +        # globus-makefile-header failed so try gpt_build_config
< +        # likely this is because gpt-postinstall hasn't been run yet
< +        # (i.e., this is a fresh Globus Toolkit install)
< +        if test -x $GPT_LOCATION/sbin/gpt_build_config ; then
< +        	gpt_linkline_helper="$GPT_LOCATION/sbin/gpt_build_config"
< +        elif test -x ${gsi_path}/sbin/gpt_build_config ; then
< +        	gpt_linkline_helper="${gsi_path}/sbin/gpt_build_config"
< +        else
< +            AC_MSG_ERROR(Cannot find gpt_build_config: GPT installation is incomplete)
< +        fi
< +        if test -n "${gsi_static}"; then
< +           ${gpt_linkline_helper} -f ${globus_flavor_type} -link static -src pkg_data_src.gpt
< +        else
< +        	${gpt_linkline_helper} -f ${globus_flavor_type} -link shared -src pkg_data_src.gpt
< +        fi
< +        . ./gpt_build_temp.sh
< +        if test -z "$GPT_CONFIG_PGM_LINKS" ; then
< +        	AC_MSG_ERROR(gpt_build_config failed)
< +        fi
< +       	GSI_LDFLAGS="-L${gsi_path}/lib"
< +    fi
< +   	AC_MSG_RESULT(yes)
2301c2936,2977
< +	AC_DEFINE(HAVE_GSSAPI_H)
---
>  #if defined(SSH_TUN_FILTER)
>  	if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
>  		channel_register_filter(c->self, sys_tun_infilter,
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/compat.c openssh-6.0p1/compat.c
> --- openssh-6.0p1.orig/compat.c	2012-07-12 17:00:49.142197374 +0200
> +++ openssh-6.0p1/compat.c	2012-07-12 17:01:14.146686628 +0200
> @@ -171,6 +171,15 @@
>  		    strlen(check[i].pat), 0) == 1) {
>  			debug("match: %s pat %s", version, check[i].pat);
>  			datafellows = check[i].bugs;
> +			/* Check to see if the remote side is OpenSSH and not HPN */
> +			if(strstr(version,"OpenSSH") != NULL)
> +			{
> +				if (strstr(version,"hpn") == NULL)
> +				{
> +					datafellows |= SSH_BUG_LARGEWINDOW;
> +					debug("Remote is NON-HPN aware");
> +				}
> +			}
>  			return;
>  		}
>  	}
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/compat.h openssh-6.0p1/compat.h
> --- openssh-6.0p1.orig/compat.h	2012-07-12 17:00:49.146197452 +0200
> +++ openssh-6.0p1/compat.h	2012-07-12 17:01:14.154686784 +0200
> @@ -59,6 +59,7 @@
>  #define SSH_BUG_RFWD_ADDR	0x02000000
>  #define SSH_NEW_OPENSSH		0x04000000
>  #define SSH_BUG_DYNAMIC_RPORT	0x08000000
> +#define SSH_BUG_LARGEWINDOW     0x80000000
>  
>  void     enable_compat13(void);
>  void     enable_compat20(void);
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/config.h.in openssh-6.0p1/config.h.in
> --- openssh-6.0p1.orig/config.h.in	2012-07-12 17:00:51.498243473 +0200
> +++ openssh-6.0p1/config.h.in	2012-07-12 17:01:14.162686941 +0200
> @@ -3,6 +3,9 @@
>  /* Define if building universal (internal helper macro) */
>  #undef AC_APPLE_UNIVERSAL_BUILD
>  
> +/* Define this if you want to use AFS/Kerberos 5 option, which runs aklog. */
> +#undef AFS_KRB5
2303,2315c2979,2987
< +    if test -n "$GLOBUS_CC" ; then
< +        CC="$GLOBUS_CC"
< +    fi
< +    CFLAGS="$CFLAGS $GLOBUS_CFLAGS $GPT_CONFIG_CFLAGS"
< +    if test -n "$GLOBUS_CPP" ; then
< +        CPP="$GLOBUS_CPP"
< +    fi
< +	CPPFLAGS="$CPPFLAGS $GLOBUS_CPPFLAGS $GLOBUS_INCLUDES $GSI_CPPFLAGS $GPT_CONFIG_INCLUDES"
< +	LIBS="$LIBS $GLOBUS_LIBS $GLOBUS_PKG_LIBS $GPT_CONFIG_LIBS $GPT_CONFIG_PGM_LINKS"
< +    if test -n "$GLOBUS_LD" ; then
< +        LD="$GLOBUS_LD"
< +    fi
< +	LDFLAGS="$LDFLAGS $GLOBUS_LDFLAGS $GSI_LDFLAGS"
---
>  /* Define if you have a getaddrinfo that fails for the all-zeros IPv6 address
>     */
>  #undef AIX_GETNAMEINFO_HACK
> @@ -10,6 +13,9 @@
>  /* Define if your AIX loginfailed() function takes 4 arguments (AIX >= 5.2) */
>  #undef AIX_LOGINFAILED_4ARG
>  
> +/* Define this if you want to use AFS/Kerberos 5 option, which runs aklog. */
> +#undef AKLOG_PATH
2317,2321c2989,3006
< +	INSTALL_GSISSH="yes"
< +else
< +	INSTALL_GSISSH=""
< +fi
< +# End Globus/GSI section
---
>  /* System only supports IPv4 audit records */
>  #undef AU_IPv4
>  
> @@ -22,7 +28,7 @@
>  /* Define if cmsg_type is not passed correctly */
>  #undef BROKEN_CMSG_TYPE
>  
> -/* getaddrinfo is broken (if present) */
> +/* assume getaddrinfo is broken) */
>  #undef BROKEN_GETADDRINFO
>  
>  /* getgroups(0,NULL) will return -1 */
> @@ -152,6 +158,9 @@
>  /* Define if your system glob() function has gl_statv options in glob_t */
>  #undef GLOB_HAS_GL_STATV
>  
> +/* Define if you want GSI/Globus authentication support. */
> +#undef GSI
2323,2391c3008,3009
<  AC_CONFIG_HEADER([config.h])
<  AC_PROG_CC
<  AC_CANONICAL_HOST
< @@ -157,7 +302,8 @@
<  if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
<  	OSSH_CHECK_CFLAG_COMPILE([-Wall])
<  	OSSH_CHECK_CFLAG_COMPILE([-Wpointer-arith])
< -	OSSH_CHECK_CFLAG_COMPILE([-Wuninitialized])
< +#	cc1: warning: -Wuninitialized is not supported without -O
< +#	OSSH_CHECK_CFLAG_COMPILE([-Wuninitialized])
<  	OSSH_CHECK_CFLAG_COMPILE([-Wsign-compare])
<  	OSSH_CHECK_CFLAG_COMPILE([-Wformat-security])
<  	OSSH_CHECK_CFLAG_COMPILE([-Wpointer-sign], [-Wno-pointer-sign])
< @@ -520,20 +666,7 @@
<  	AC_DEFINE([BROKEN_SETREGID])
<  	;;
<  *-*-darwin*)
< -	AC_MSG_CHECKING([if we have working getaddrinfo])
< -	AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include <mach-o/dyld.h>
< -main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
< -		exit(0);
< -	else
< -		exit(1);
< -}
< -			]])],
< -	[AC_MSG_RESULT([working])],
< -	[AC_MSG_RESULT([buggy])
< -	AC_DEFINE([BROKEN_GETADDRINFO], [1],
< -		[getaddrinfo is broken (if present)])
< -	],
< -	[AC_MSG_RESULT([assume it is working])])
< +	AC_DEFINE(BROKEN_GETADDRINFO, 1, [assume getaddrinfo is broken)])
<  	AC_DEFINE([SETEUID_BREAKS_SETUID])
<  	AC_DEFINE([BROKEN_SETREUID])
<  	AC_DEFINE([BROKEN_SETREGID])
< @@ -545,6 +678,30 @@
<  	    [Use tunnel device compatibility to OpenBSD])
<  	AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
<  	    [Prepend the address family to IP tunnel traffic])
< +	AC_MSG_CHECKING(if we have the Security Authorization Session API)
< +	AC_TRY_COMPILE([#include <Security/AuthSession.h>],
< +		[SessionCreate(0, 0);],
< +		[ac_cv_use_security_session_api="yes"
< +		 AC_DEFINE(USE_SECURITY_SESSION_API, 1, 
< +			[platform has the Security Authorization Session API])
< +		 LIBS="$LIBS -framework Security"
< +		 AC_MSG_RESULT(yes)],
< +		[ac_cv_use_security_session_api="no"
< +		 AC_MSG_RESULT(no)])
< +	AC_MSG_CHECKING(if we have an in-memory credentials cache)
< +	AC_TRY_COMPILE(
< +		[#include <Kerberos/Kerberos.h>],
< +		[cc_context_t c;
< +		 (void) cc_initialize (&c, 0, NULL, NULL);],
< +		[AC_DEFINE(USE_CCAPI, 1, 
< +			[platform uses an in-memory credentials cache])
< +		 LIBS="$LIBS -framework Security"
< +		 AC_MSG_RESULT(yes)
< +		 if test "x$ac_cv_use_security_session_api" = "xno"; then
< +			AC_MSG_ERROR(*** Need a security framework to use the credentials cache API ***)
< +		fi],
< +		[AC_MSG_RESULT(no)]
< +	)
<  	m4_pattern_allow([AU_IPv])
<  	AC_CHECK_DECL([AU_IPv4], [], 
<  	    AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records])
< @@ -3479,6 +3636,71 @@
<  AC_SUBST([SSHLIBS])
<  AC_SUBST([SSHDLIBS])
---
>  /* Define this if you want GSSAPI support in the version 2 protocol */
>  #undef GSSAPI
2393,2463c3011,3013
< +# Finish configuring Globus GSSAPI
< +if test "x$gsi_path" != "xno" ; then
< +	if test ! -z "$need_dash_r" ; then
< +		LDFLAGS="$LDFLAGS -R${gsi_path}/lib"
< +	fi
< +	if test ! -z "$blibpath" ; then
< +		blibpath="$blibpath:${gsi_path}/lib"
< +	fi
< +	# test that we got the libraries OK
< +	AC_MSG_CHECKING(Globus linkline)
< +	AC_TRY_LINK(
< +		[],
< +		[],
< +		[
< +			AC_MSG_RESULT(yes)
< +		],
< +		[
< +			AC_MSG_ERROR(link with Globus libraries failed)
< +		]
< +	)
< +    AC_CHECK_FUNCS(globus_gss_assist_map_and_authorize)
< +fi
< +AC_SUBST(INSTALL_GSISSH)
< +
< +dnl
< +dnl Check for globus_usage_stats_send
< +dnl
< +AC_CHECK_FUNC(globus_usage_stats_send,
< +              AC_DEFINE([HAVE_GLOBUS_USAGE], 1, [Have Globus Usage]))
< +
< +dnl
< +dnl Check for globus_usage_stats_send_array
< +dnl
< +AC_CHECK_FUNC(globus_usage_stats_send_array,
< +              AC_DEFINE([HAVE_GLOBUS_USAGE_SEND_ARRAY], 1,
< +                        [Have Globus Usage send_array]))
< +
< +# Check whether the user wants GSSAPI mechglue support
< +AC_ARG_WITH(mechglue,
< +	[  --with-mechglue=PATH    Build with GSSAPI mechglue library],
< +	[
< +		AC_MSG_CHECKING(for mechglue library)
< +
< +		if test -e ${withval}/libgssapi.a ; then
< +		    mechglue_lib=${withval}/libgssapi.a
< +		elif test -e ${withval}/lib/libgssapi.a ; then
< +		    mechglue_lib=${withval}/lib/libgssapi.a
< +		else
< +		    AC_MSG_ERROR("Can't find libgssapi in ${withval}");
< +		fi
< +		LIBS="${mechglue_lib} $LIBS"
< +		AC_MSG_RESULT(${mechglue_lib})
< +
< +		AC_CHECK_LIB(dl, dlopen, , )
< +		if test $ac_cv_lib_dl_dlopen = yes; then
< +		   LDFLAGS="$LDFLAGS -ldl -Wl,-Bsymbolic"
< +		fi
< +
< +		AC_DEFINE(GSSAPI)
< +		AC_DEFINE(MECHGLUE, 1, [Define this if you're building with GSSAPI MechGlue.])
< +		GSSAPI="mechglue"
< +	]
< +)
< +
< +
<  # Check whether user wants Kerberos 5 support
<  KRB5_MSG="no"
<  AC_ARG_WITH([kerberos5],
< @@ -3566,7 +3788,21 @@
<  			AC_CHECK_HEADER([gssapi_krb5.h], ,
<  					[ CPPFLAGS="$oldCPP" ])
---
> @@ -476,6 +485,16 @@
>  /* Define to 1 if you have the `glob' function. */
>  #undef HAVE_GLOB
2465,2469c3015,3017
< -		fi
< +			# If we're using some other GSSAPI
< +			if test "$GSSAPI" -a "$GSSAPI" != "mechglue"; then
< +				AC_MSG_ERROR([$GSSAPI GSSAPI library conflicts with Kerberos support.  Use mechglue instead.])
< +			fi
---
> +/* Define to 1 if you have the `globus_gss_assist_map_and_authorize' function.
> +   */
> +#undef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
2471,2473c3019,3020
< +			if test -z "$GSSAPI"; then
< +				GSSAPI="KRB5";
< +			fi
---
> +/* Have Globus Usage */
> +#undef HAVE_GLOBUS_USAGE
2475,2478c3022,3023
< +			oldCPP="$CPPFLAGS"
< +			CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
< +			AC_CHECK_HEADER(gssapi_krb5.h, ,
< +					[ CPPFLAGS="$oldCPP" ])
---
> +/* Have Globus Usage send_array */
> +#undef HAVE_GLOBUS_USAGE_SEND_ARRAY
2480,2486c3025,3026
< +                fi
<  		if test ! -z "$need_dash_r" ; then
<  			LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib"
<  		fi
< @@ -3585,6 +3821,42 @@
<  	]
<  )
---
>  /* Define to 1 if you have the <glob.h> header file. */
>  #undef HAVE_GLOB_H
2488,2522c3028,3033
< +# Check whether user wants AFS_KRB5 support
< +AFS_KRB5_MSG="no"
< +AC_ARG_WITH(afs-krb5,
< +	[  --with-afs-krb5[[=AKLOG_PATH]]  Enable aklog to get token (default=/usr/bin/aklog).],
< +	[
< +		if test "x$withval" != "xno" ; then
< +
< +			if test "x$withval" != "xyes" ; then
< +				AC_DEFINE_UNQUOTED(AKLOG_PATH, "$withval",
< +					[Define this if you want to use AFS/Kerberos 5 option, which runs aklog.])
< +			else
< +				AC_DEFINE_UNQUOTED(AKLOG_PATH,
< +					"/usr/bin/aklog",
< +					[Define this if you want to use AFS/Kerberos 5 option, which runs aklog.])
< +			fi
< +
< +			if test -z "$KRB5ROOT" ; then
< +				AC_MSG_WARN([AFS_KRB5 requires Kerberos 5 support, build may fail])
< +			fi
< +
< +			LIBS="-lkrbafs -lkrb4 $LIBS"
< +			if test ! -z "$AFS_LIBS" ; then
< +				LIBS="$LIBS $AFS_LIBS"
< +			fi
< +			AC_DEFINE(AFS_KRB5, 1,
< +				[Define this if you want to use AFS/Kerberos 5 option, which runs aklog.])
< +			AFS_KRB5_MSG="yes"
< +		fi
< +	]
< +)
< +
< +AC_ARG_WITH(session-hooks,
< +        [  --with-session-hooks    Enable hooks for executing external commands                                       before/after a session],
< +        [ AC_DEFINE(SESSION_HOOKS, 1, [Define this if you want support for startup/shutdown hooks]) ]
< +)
---
> @@ -1292,6 +1311,9 @@
>  /* Set this to your mail directory if you do not have _PATH_MAILDIR */
>  #undef MAIL_DIRECTORY
>  
> +/* Define this if you're building with GSSAPI MechGlue. */
> +#undef MECHGLUE
2524c3035,3036
<  # Looking for programs, paths and files
---
>  /* Define on *nto-qnx systems */
>  #undef MISSING_FD_MASK
2526,2529c3038,3040
<  PRIVSEP_PATH=/var/empty
< @@ -3620,7 +3892,10 @@
<  	]
<  )
---
> @@ -1380,6 +1402,9 @@
>  /* Specify the system call convention in use */
>  #undef SECCOMP_AUDIT_ARCH
2531,2542c3042,3046
< +# strip causes problems with GSI libraries...
< +if test -z "$GLOBUS_LDFLAGS" ; then
<  STRIP_OPT=-s
< +fi
<  AC_ARG_ENABLE([strip],
<  	[  --disable-strip         Disable calling strip(1) on install],
<  	[
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/gss-genr.c openssh-6.0p1/gss-genr.c
< --- openssh-6.0p1.orig/gss-genr.c	2009-06-22 01:11:07.000000000 -0500
< +++ openssh-6.0p1/gss-genr.c	2012-05-27 17:50:01.000000000 -0500
< @@ -1,7 +1,7 @@
<  /* $OpenBSD: gss-genr.c,v 1.20 2009/06/22 05:39:28 dtucker Exp $ */
---
> +/* Define this if you want support for startup/shutdown hooks */
> +#undef SESSION_HOOKS
> +
>  /* Define if your platform breaks doing a seteuid before a setuid */
>  #undef SETEUID_BREAKS_SETUID
2544,2559c3048,3050
<  /*
< - * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
< + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
<   *
<   * Redistribution and use in source and binary forms, with or without
<   * modification, are permitted provided that the following conditions
< @@ -38,13 +38,169 @@
<  #include "xmalloc.h"
<  #include "buffer.h"
<  #include "log.h"
< +#include "canohost.h"
<  #include "ssh2.h"
< +#include "cipher.h"
< +#include "key.h"
< +#include "kex.h"
< +#include <openssl/evp.h>
---
> @@ -1465,6 +1490,9 @@
>  /* Use btmp to log bad logins */
>  #undef USE_BTMP
2561c3052,3056
<  #include "ssh-gss.h"
---
> +/* platform uses an in-memory credentials cache */
> +#undef USE_CCAPI
> +
>  /* Use libedit for sftp */
>  #undef USE_LIBEDIT
2563,2564c3058,3060
<  extern u_char *session_id2;
<  extern u_int session_id2_len;
---
> @@ -1480,6 +1508,9 @@
>  /* Use PIPES instead of a socketpair() */
>  #undef USE_PIPES
2566,2569c3062,3063
< +typedef struct {
< +	char *encoded;
< +	gss_OID oid;
< +} ssh_gss_kex_mapping;
---
> +/* platform has the Security Authorization Session API */
> +#undef USE_SECURITY_SESSION_API
2571,2574c3065,3128
< +/*
< + * XXX - It would be nice to find a more elegant way of handling the
< + * XXX   passing of the key exchange context to the userauth routines
< + */
---
>  /* Define if you have Solaris process contracts */
>  #undef USE_SOLARIS_PROCESS_CONTRACTS
>  
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/configure openssh-6.0p1/configure
> --- openssh-6.0p1.orig/configure	2012-07-12 17:00:51.226238151 +0200
> +++ openssh-6.0p1/configure	2012-07-12 17:01:14.182687332 +0200
> @@ -615,6 +615,7 @@
>  xauth_path
>  PRIVSEP_PATH
>  KRB5CONF
> +INSTALL_GSISSH
>  SSHDLIBS
>  SSHLIBS
>  SSH_PRIVSEP_USER
> @@ -707,6 +708,10 @@
>  ac_subst_files=''
>  ac_user_opts='
>  enable_option_checking
> +with_gsi
> +with_globus
> +with_globus_static
> +with_globus_flavor
>  enable_largefile
>  with_stackprotect
>  with_rpath
> @@ -734,7 +739,10 @@
>  with_privsep_user
>  with_sandbox
>  with_selinux
> +with_mechglue
>  with_kerberos5
> +with_afs_krb5
> +with_session_hooks
>  with_privsep_path
>  with_xauth
>  enable_strip
> @@ -1398,6 +1406,10 @@
>  Optional Packages:
>    --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
>    --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
> +  --with-gsi              Enable Globus GSI authentication support
> +  --with-globus           Enable Globus GSI authentication support
> +  --with-globus-static    Link statically with Globus GSI libraries
> +  --with-globus-flavor=TYPE  Specify Globus flavor type (ex: gcc32dbg)
>    --without-stackprotect  Don't use compiler's stack protection
>    --without-rpath         Disable auto-added -R linker paths
>    --with-cflags           Specify additional flags to pass to compiler
> @@ -1424,7 +1436,10 @@
>    --with-privsep-user=user Specify non-privileged user for privilege separation
>    --with-sandbox=style    Specify privilege separation sandbox (no, darwin, rlimit, systrace, seccomp_filter)
>    --with-selinux          Enable SELinux support
> +  --with-mechglue=PATH    Build with GSSAPI mechglue library
>    --with-kerberos5=PATH   Enable Kerberos 5 support
> +  --with-afs-krb5[=AKLOG_PATH]  Enable aklog to get token (default=/usr/bin/aklog).
> +  --with-session-hooks    Enable hooks for executing external commands                                       before/after a session
>    --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty)
>    --with-xauth=PATH       Specify path to xauth program
>    --with-maildir=/path/to/mail    Specify your system mail directory
> @@ -2576,6 +2591,175 @@
>  ac_compiler_gnu=$ac_cv_c_compiler_gnu
>  
>  
> +# Handle Globus configuration right away, because the Globus flavor
> +# determines our compiler options.
2576c3130,3131
< +Gssctxt *gss_kex_context = NULL;
---
> +# Check whether the user wants GSI (Globus) support
> +gsi_path="no"
2578c3133,3136
< +static ssh_gss_kex_mapping *gss_enc2oid = NULL;
---
> +# Check whether --with-gsi was given.
> +if test "${with_gsi+set}" = set; then :
> +  withval=$with_gsi;
> +		gsi_path="$withval"
2580,2583d3137
< +int 
< +ssh_gssapi_oid_table_ok() {
< +	return (gss_enc2oid != NULL);
< +}
2585,2590c3139
< +/*
< + * Return a list of the gss-group1-sha1 mechanisms supported by this program
< + *
< + * We test mechanisms to ensure that we can use them, to avoid starting
< + * a key exchange with a bad mechanism
< + */
---
> +fi
2592,2595d3140
< +char *
< +ssh_gssapi_client_mechanisms(const char *host, const char *client) {
< +	gss_OID_set gss_supported;
< +	OM_uint32 min_status;
2597,2598d3141
< +	if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported)))
< +		return NULL;
2600,2602c3143,3146
< +	return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism,
< +	    host, client));
< +}
---
> +# Check whether --with-globus was given.
> +if test "${with_globus+set}" = set; then :
> +  withval=$with_globus;
> +		gsi_path="$withval"
2604,2614d3147
< +char *
< +ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
< +    const char *host, const char *client) {
< +	Buffer buf;
< +	size_t i;
< +	int oidpos, enclen;
< +	char *mechs, *encoded;
< +	u_char digest[EVP_MAX_MD_SIZE];
< +	char deroid[2];
< +	const EVP_MD *evp_md = EVP_md5();
< +	EVP_MD_CTX md;
2616,2620c3149
< +	if (gss_enc2oid != NULL) {
< +		for (i = 0; gss_enc2oid[i].encoded != NULL; i++)
< +			xfree(gss_enc2oid[i].encoded);
< +		xfree(gss_enc2oid);
< +	}
---
> +fi
2622,2623d3150
< +	gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) *
< +	    (gss_supported->count + 1));
2625d3151
< +	buffer_init(&buf);
2627,2630c3153,3159
< +	oidpos = 0;
< +	for (i = 0; i < gss_supported->count; i++) {
< +		if (gss_supported->elements[i].length < 128 &&
< +		    (*check)(NULL, &(gss_supported->elements[i]), host, client)) {
---
> +# Check whether --with-globus-static was given.
> +if test "${with_globus_static+set}" = set; then :
> +  withval=$with_globus_static;
> +		gsi_static="-static"
> +		if test "x$gsi_path" = "xno" ; then
> +			gsi_path="$withval"
> +		fi
2632,2633d3160
< +			deroid[0] = SSH_GSS_OIDTYPE;
< +			deroid[1] = gss_supported->elements[i].length;
2635,2640c3162
< +			EVP_DigestInit(&md, evp_md);
< +			EVP_DigestUpdate(&md, deroid, 2);
< +			EVP_DigestUpdate(&md,
< +			    gss_supported->elements[i].elements,
< +			    gss_supported->elements[i].length);
< +			EVP_DigestFinal(&md, digest, NULL);
---
> +fi
2642,2644d3163
< +			encoded = xmalloc(EVP_MD_size(evp_md) * 2);
< +			enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
< +			    encoded, EVP_MD_size(evp_md) * 2);
2646,2647c3165,3166
< +			if (oidpos != 0)
< +				buffer_put_char(&buf, ',');
---
> +# Check whether the user has a Globus flavor type
> +globus_flavor_type="no"
2649,2659c3168,3174
< +			buffer_append(&buf, KEX_GSS_GEX_SHA1_ID,
< +			    sizeof(KEX_GSS_GEX_SHA1_ID) - 1);
< +			buffer_append(&buf, encoded, enclen);
< +			buffer_put_char(&buf, ',');
< +			buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, 
< +			    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1);
< +			buffer_append(&buf, encoded, enclen);
< +			buffer_put_char(&buf, ',');
< +			buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID,
< +			    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1);
< +			buffer_append(&buf, encoded, enclen);
---
> +# Check whether --with-globus-flavor was given.
> +if test "${with_globus_flavor+set}" = set; then :
> +  withval=$with_globus_flavor;
> +		globus_flavor_type="$withval"
> +		if test "x$gsi_path" = "xno" ; then
> +			gsi_path="yes"
> +		fi
2661,2667d3175
< +			gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
< +			gss_enc2oid[oidpos].encoded = encoded;
< +			oidpos++;
< +		}
< +	}
< +	gss_enc2oid[oidpos].oid = NULL;
< +	gss_enc2oid[oidpos].encoded = NULL;
2669c3177
< +	buffer_put_char(&buf, '\0');
---
> +fi
2671,2673d3178
< +	mechs = xmalloc(buffer_len(&buf));
< +	buffer_get(&buf, mechs, buffer_len(&buf));
< +	buffer_free(&buf);
2675,2681c3180,3183
< +	if (strlen(mechs) == 0) {
< +		xfree(mechs);
< +		mechs = NULL;
< +	}
< +	
< +	return (mechs);
< +}
---
> +if test "x$gsi_path" != "xno" ; then
> +	# Globus GSSAPI configuration
> +	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Globus GSI" >&5
> +$as_echo_n "checking for Globus GSI... " >&6; }
2683,2705c3185
< +gss_OID
< +ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) {
< +	int i = 0;
< +	
< +	switch (kex_type) {
< +	case KEX_GSS_GRP1_SHA1:
< +		if (strlen(name) < sizeof(KEX_GSS_GRP1_SHA1_ID))
< +			return GSS_C_NO_OID;
< +		name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1;
< +		break;
< +	case KEX_GSS_GRP14_SHA1:
< +		if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA1_ID))
< +			return GSS_C_NO_OID;
< +		name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1;
< +		break;
< +	case KEX_GSS_GEX_SHA1:
< +		if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID))
< +			return GSS_C_NO_OID;
< +		name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1;
< +		break;
< +	default:
< +		return GSS_C_NO_OID;
< +	}
---
> +$as_echo "#define GSI 1" >>confdefs.h
2707,2709d3186
< +	while (gss_enc2oid[i].encoded != NULL &&
< +	    strcmp(name, gss_enc2oid[i].encoded) != 0)
< +		i++;
2711,2712c3188,3192
< +	if (gss_enc2oid[i].oid != NULL && ctx != NULL)
< +		ssh_gssapi_set_oid(ctx, gss_enc2oid[i].oid);
---
> +	if test "$GSSAPI" -a "$GSSAPI" != "mechglue"; then
> +		as_fn_error $? "Previously configured GSSAPI library conflicts with Globus GSI." "$LINENO" 5
> +	fi
> +	if test -z "$GSSAPI"; then
> +		$as_echo "#define GSSAPI 1" >>confdefs.h
2714,2715c3194,3195
< +	return gss_enc2oid[i].oid;
< +}
---
> +		GSSAPI="GSI"
> +	fi
2717,2789c3197,3210
<  /* Check that the OID in a data stream matches that in the context */
<  int
<  ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len)
< @@ -155,10 +311,13 @@
<  void
<  ssh_gssapi_delete_ctx(Gssctxt **ctx)
<  {
< +#if !defined(MECHGLUE)
<  	OM_uint32 ms;
< +#endif
<  
<  	if ((*ctx) == NULL)
<  		return;
< +#if !defined(MECHGLUE) /* mechglue has some memory management issues */
<  	if ((*ctx)->context != GSS_C_NO_CONTEXT)
<  		gss_delete_sec_context(&ms, &(*ctx)->context, GSS_C_NO_BUFFER);
<  	if ((*ctx)->name != GSS_C_NO_NAME)
< @@ -174,6 +333,7 @@
<  		gss_release_name(&ms, &(*ctx)->client);
<  	if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL)
<  		gss_release_cred(&ms, &(*ctx)->client_creds);
< +#endif
<  
<  	xfree(*ctx);
<  	*ctx = NULL;
< @@ -197,7 +357,7 @@
<  	}
<  
<  	ctx->major = gss_init_sec_context(&ctx->minor,
< -	    GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid,
< +	    ctx->client_creds, &ctx->context, ctx->name, ctx->oid,
<  	    GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag,
<  	    0, NULL, recv_tok, NULL, send_tok, flags, NULL);
<  
< @@ -212,9 +372,18 @@
<  ssh_gssapi_import_name(Gssctxt *ctx, const char *host)
<  {
<  	gss_buffer_desc gssbuf;
< +	char *xhost;
<  	char *val;
<  
< -	xasprintf(&val, "host@%s", host);
< +	/* Make a copy of the host name, in case it was returned by a
< +	 * previous call to gethostbyname(). */	
< +	xhost = xstrdup(host);
< +
< +	/* Make sure we have the FQDN. Some GSSAPI implementations don't do
< +	 * this for us themselves */
< +	resolve_localhost(&xhost);
< +	
< +	xasprintf(&val, "host@%s", xhost);
<  	gssbuf.value = val;
<  	gssbuf.length = strlen(gssbuf.value);
<  
< @@ -222,13 +391,48 @@
<  	    &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name)))
<  		ssh_gssapi_error(ctx);
<  
< +	xfree(xhost);
<  	xfree(gssbuf.value);
<  	return (ctx->major);
<  }
<  
<  OM_uint32
< +ssh_gssapi_client_identity(Gssctxt *ctx, const char *name)
< +{
< +	gss_buffer_desc gssbuf;
< +	gss_name_t gssname;
< +	OM_uint32 status;
< +	gss_OID_set oidset;
< +
< +	gssbuf.value = (void *) name;
< +	gssbuf.length = strlen(gssbuf.value);
---
> +	if test "x$gsi_path" = "xyes" ; then
> +		if test -z "$GLOBUS_LOCATION" ; then
> +			as_fn_error $? "GLOBUS_LOCATION environment variable must be set." "$LINENO" 5
> +		else
> +			gsi_path="$GLOBUS_LOCATION"
> +		fi
> +	fi
> +	GLOBUS_LOCATION="$gsi_path"
> +	export GLOBUS_LOCATION
> +    LD_LIBRARY_PATH="${gsi_path}/lib:$LD_LIBRARY_PATH"
> +    export LD_LIBRARY_PATH
> +	if test ! -d "$GLOBUS_LOCATION" ; then
> +		as_fn_error $? "Cannot find Globus installation.  Set GLOBUS_LOCATION environment variable." "$LINENO" 5
> +	fi
2791,2792c3212,3219
< +	gss_create_empty_oid_set(&status, &oidset);
< +	gss_add_oid_set_member(&status, ctx->oid, &oidset);
---
> +        if test "x$globus_flavor_type" = "xno" ; then
> +                as_fn_error $? "--with-globus-flavor=TYPE must be specified" "$LINENO" 5
> +	fi
> +        if test "x$globus_flavor_type" = "xyes" ; then
> +                as_fn_error $? "--with-globus-flavor=TYPE must specify a flavor type" "$LINENO" 5
> +	fi
> +    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GLOBUS_LOCATION" >&5
> +$as_echo "$GLOBUS_LOCATION" >&6; }
2794,2795c3221,3232
< +	ctx->major = gss_import_name(&ctx->minor, &gssbuf,
< +	    GSS_C_NT_USER_NAME, &gssname);
---
> +	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Globus include path" >&5
> +$as_echo_n "checking for Globus include path... " >&6; }
> +  if test -d "${gsi_path}/include/${globus_flavor_type}" ; then
> +	    GLOBUS_INCLUDE="${gsi_path}/include/${globus_flavor_type}"
> +  elif test -d "${gsi_path}/include/globus" ; then
> +      GLOBUS_INCLUDE="${gsi_path}/include/globus"
> +  else
> +		as_fn_error $? "Cannot find Globus include directory in ${gsi_path}/include" "$LINENO" 5
> +	fi
> +	GSI_CPPFLAGS="-I${GLOBUS_INCLUDE}"
> +	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
> +$as_echo "yes" >&6; }
2797,2800c3234,3271
< +	if (!ctx->major)
< +		ctx->major = gss_acquire_cred(&ctx->minor, 
< +		    gssname, 0, oidset, GSS_C_INITIATE, 
< +		    &ctx->client_creds, NULL, NULL);
---
> +	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for globus-makefile-header" >&5
> +$as_echo_n "checking for globus-makefile-header... " >&6; }
> +	if test -x ${gsi_path}/bin/globus-makefile-header ; then
> +		${gsi_path}/bin/globus-makefile-header --flavor=${globus_flavor_type} ${gsi_static} globus_gss_assist globus_usage 2>/dev/null | sed 's/ = \(.*\)/="\1"/' > ./gpt_build_tmp.sh
> +	elif test -x ${gsi_path}/sbin/globus-makefile-header ; then
> +		${gsi_path}/sbin/globus-makefile-header --flavor=${globus_flavor_type} ${gsi_static} globus_gss_assist globus_usage 2>/dev/null | sed 's/ = \(.*\)/="\1"/' > ./gpt_build_tmp.sh
> +	fi
> +    if test -f ./gpt_build_tmp.sh ; then
> +    	. ./gpt_build_tmp.sh
> +    fi
> +	if test -z "$GLOBUS_PKG_LIBS" ; then
> +    	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
> +        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gpt_build_config" >&5
> +$as_echo_n "checking for gpt_build_config... " >&6; }
> +        # globus-makefile-header failed so try gpt_build_config
> +        # likely this is because gpt-postinstall hasn't been run yet
> +        # (i.e., this is a fresh Globus Toolkit install)
> +        if test -x $GPT_LOCATION/sbin/gpt_build_config ; then
> +        	gpt_linkline_helper="$GPT_LOCATION/sbin/gpt_build_config"
> +        elif test -x ${gsi_path}/sbin/gpt_build_config ; then
> +        	gpt_linkline_helper="${gsi_path}/sbin/gpt_build_config"
> +        else
> +            as_fn_error $? "Cannot find gpt_build_config: GPT installation is incomplete" "$LINENO" 5
> +        fi
> +        if test -n "${gsi_static}"; then
> +           ${gpt_linkline_helper} -f ${globus_flavor_type} -link static -src pkg_data_src.gpt
> +        else
> +        	${gpt_linkline_helper} -f ${globus_flavor_type} -link shared -src pkg_data_src.gpt
> +        fi
> +        . ./gpt_build_temp.sh
> +        if test -z "$GPT_CONFIG_PGM_LINKS" ; then
> +        	as_fn_error $? "gpt_build_config failed" "$LINENO" 5
> +        fi
> +       	GSI_LDFLAGS="-L${gsi_path}/lib"
> +    fi
> +   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
> +$as_echo "yes" >&6; }
2802,2803c3273
< +	gss_release_name(&status, &gssname);
< +	gss_release_oid_set(&status, &oidset);
---
> +	$as_echo "#define HAVE_GSSAPI_H 1" >>confdefs.h
2805,2806d3274
< +	if (ctx->major)
< +		ssh_gssapi_error(ctx);
2808,2809c3276,3288
< +	return(ctx->major);
< +}
---
> +    if test -n "$GLOBUS_CC" ; then
> +        CC="$GLOBUS_CC"
> +    fi
> +    CFLAGS="$CFLAGS $GLOBUS_CFLAGS $GPT_CONFIG_CFLAGS"
> +    if test -n "$GLOBUS_CPP" ; then
> +        CPP="$GLOBUS_CPP"
> +    fi
> +	CPPFLAGS="$CPPFLAGS $GLOBUS_CPPFLAGS $GLOBUS_INCLUDES $GSI_CPPFLAGS $GPT_CONFIG_INCLUDES"
> +	LIBS="$LIBS $GLOBUS_LIBS $GLOBUS_PKG_LIBS $GPT_CONFIG_LIBS $GPT_CONFIG_PGM_LINKS"
> +    if test -n "$GLOBUS_LD" ; then
> +        LD="$GLOBUS_LD"
> +    fi
> +	LDFLAGS="$LDFLAGS $GLOBUS_LDFLAGS $GSI_LDFLAGS"
2811,2815c3290,3294
< +OM_uint32
<  ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
<  {
< +	if (ctx == NULL) 
< +		return -1;
---
> +	INSTALL_GSISSH="yes"
> +else
> +	INSTALL_GSISSH=""
> +fi
> +# End Globus/GSI section
2817,2822c3296
<  	if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
<  	    GSS_C_QOP_DEFAULT, buffer, hash)))
<  		ssh_gssapi_error(ctx);
< @@ -236,6 +440,19 @@
<  	return (ctx->major);
<  }
---
>  ac_config_headers="$ac_config_headers config.h"
2824,2840c3298,3301
< +/* Priviledged when used by server */
< +OM_uint32
< +ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
< +{
< +	if (ctx == NULL)
< +		return -1;
< +
< +	ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
< +	    gssbuf, gssmic, NULL);
< +
< +	return (ctx->major);
< +}
< +
<  void
<  ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service,
<      const char *context)
< @@ -249,11 +466,16 @@
---
>  ac_ext=c
> @@ -5700,29 +5884,8 @@
>  fi
>  rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
2841a3303,3331
> -	{
> -	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wuninitialized" >&5
> -$as_echo_n "checking if $CC supports -Wuninitialized... " >&6; }
> -	saved_CFLAGS="$CFLAGS"
> -	CFLAGS="$CFLAGS -Wuninitialized"
> -	_define_flag=""
> -	test "x$_define_flag" = "x" && _define_flag="-Wuninitialized"
> -	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> -/* end confdefs.h.  */
> -int main(void) { return 0; }
> -_ACEOF
> -if ac_fn_c_try_compile "$LINENO"; then :
> -   { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
> -$as_echo "yes" >&6; }
> -		  CFLAGS="$saved_CFLAGS $_define_flag"
> -else
> -   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> -$as_echo "no" >&6; }
> -		  CFLAGS="$saved_CFLAGS"
> -
> -fi
> -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
> -}
> +#	cc1: warning: -Wuninitialized is not supported without -O
> +#	OSSH_CHECK_CFLAG_COMPILE([-Wuninitialized])
>  	{
>  	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC supports -Wsign-compare" >&5
>  $as_echo_n "checking if $CC supports -Wsign-compare... " >&6; }
> @@ -6554,37 +6717,9 @@
2843,2854c3333,3356
<  int
< -ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host)
< +ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host, 
< +    const char *client)
<  {
<  	gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
<  	OM_uint32 major, minor;
<  	gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"};
< +	Gssctxt *intctx = NULL;
< +
< +	if (ctx == NULL)
< +		ctx = &intctx;
---
>  	;;
>  *-*-darwin*)
> -	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have working getaddrinfo" >&5
> -$as_echo_n "checking if we have working getaddrinfo... " >&6; }
> -	if test "$cross_compiling" = yes; then :
> -  { $as_echo "$as_me:${as_lineno-$LINENO}: result: assume it is working" >&5
> -$as_echo "assume it is working" >&6; }
> -else
> -  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> -/* end confdefs.h.  */
> - #include <mach-o/dyld.h>
> -main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
> -		exit(0);
> -	else
> -		exit(1);
> -}
> -
> -_ACEOF
> -if ac_fn_c_try_run "$LINENO"; then :
> -  { $as_echo "$as_me:${as_lineno-$LINENO}: result: working" >&5
> -$as_echo "working" >&6; }
> -else
> -  { $as_echo "$as_me:${as_lineno-$LINENO}: result: buggy" >&5
> -$as_echo "buggy" >&6; }
2856,2871c3358
<  	/* RFC 4462 says we MUST NOT do SPNEGO */
<  	if (oid->length == spnego_oid.length && 
< @@ -263,6 +485,10 @@
<  	ssh_gssapi_build_ctx(ctx);
<  	ssh_gssapi_set_oid(*ctx, oid);
<  	major = ssh_gssapi_import_name(*ctx, host);
< +
< +	if (!GSS_ERROR(major) && client)
< +		major = ssh_gssapi_client_identity(*ctx, client);
< +
<  	if (!GSS_ERROR(major)) {
<  		major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, 
<  		    NULL);
< @@ -272,10 +498,66 @@
<  			    GSS_C_NO_BUFFER);
<  	}
---
>  $as_echo "#define BROKEN_GETADDRINFO 1" >>confdefs.h
2873,2875c3360,3366
< -	if (GSS_ERROR(major)) 
< +	if (GSS_ERROR(major) || intctx != NULL) 
<  		ssh_gssapi_delete_ctx(ctx);
---
> -
> -fi
> -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
> -  conftest.$ac_objext conftest.beam conftest.$ac_ext
> -fi
> -
>  	$as_echo "#define SETEUID_BREAKS_SETUID 1" >>confdefs.h
2877,2878c3368,3369
<  	return (!GSS_ERROR(major));
<  }
---
>  	$as_echo "#define BROKEN_SETREUID 1" >>confdefs.h
> @@ -6608,6 +6743,63 @@
2879a3371,3377
>  $as_echo "#define SSH_TUN_PREPEND_AF 1" >>confdefs.h
>  
> +	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have the Security Authorization Session API" >&5
> +$as_echo_n "checking if we have the Security Authorization Session API... " >&6; }
> +	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h.  */
> +#include <Security/AuthSession.h>
2881,2890c3379,3387
< +ssh_gssapi_credentials_updated(Gssctxt *ctxt) {
< +	static gss_name_t saved_name = GSS_C_NO_NAME;
< +	static OM_uint32 saved_lifetime = 0;
< +	static gss_OID saved_mech = GSS_C_NO_OID;
< +	static gss_name_t name;
< +	static OM_uint32 last_call = 0;
< +	OM_uint32 lifetime, now, major, minor;
< +	int equal;
< +	
< +	now = time(NULL);
---
> +main ()
> +{
> +SessionCreate(0, 0);
> +  ;
> +  return 0;
> +}
> +_ACEOF
> +if ac_fn_c_try_compile "$LINENO"; then :
> +  ac_cv_use_security_session_api="yes"
2892,2893c3389
< +	if (ctxt) {
< +		debug("Rekey has happened - updating saved versions");
---
> +$as_echo "#define USE_SECURITY_SESSION_API 1" >>confdefs.h
2895,2896c3391,3414
< +		if (saved_name != GSS_C_NO_NAME)
< +			gss_release_name(&minor, &saved_name);
---
> +		 LIBS="$LIBS -framework Security"
> +		 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
> +$as_echo "yes" >&6; }
> +else
> +  ac_cv_use_security_session_api="no"
> +		 { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
> +fi
> +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
> +	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if we have an in-memory credentials cache" >&5
> +$as_echo_n "checking if we have an in-memory credentials cache... " >&6; }
> +	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h.  */
> +#include <Kerberos/Kerberos.h>
> +int
> +main ()
> +{
> +cc_context_t c;
> +		 (void) cc_initialize (&c, 0, NULL, NULL);
> +  ;
> +  return 0;
> +}
> +_ACEOF
> +if ac_fn_c_try_compile "$LINENO"; then :
2898,2899c3416
< +		major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL,
< +		    &saved_name, &saved_lifetime, NULL, NULL);
---
> +$as_echo "#define USE_CCAPI 1" >>confdefs.h
2901,2908c3418,3426
< +		if (!GSS_ERROR(major)) {
< +			saved_mech = ctxt->oid;
< +		        saved_lifetime+= now;
< +		} else {
< +			/* Handle the error */
< +		}
< +		return 0;
< +	}
---
> +		 LIBS="$LIBS -framework Security"
> +		 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
> +$as_echo "yes" >&6; }
> +		 if test "x$ac_cv_use_security_session_api" = "xno"; then
> +			as_fn_error $? "*** Need a security framework to use the credentials cache API ***" "$LINENO" 5
> +		fi
> +else
> +  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
> +$as_echo "no" >&6; }
2910,2911c3428,3449
< +	if (now - last_call < 10)
< +		return 0;
---
> +fi
> +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
>  
>  	ac_fn_c_check_decl "$LINENO" "AU_IPv4" "ac_cv_have_decl_AU_IPv4" "$ac_includes_default"
>  if test "x$ac_cv_have_decl_AU_IPv4" = xyes; then :
> @@ -14945,6 +15137,151 @@
>  
>  
>  
> +# Finish configuring Globus GSSAPI
> +if test "x$gsi_path" != "xno" ; then
> +	if test ! -z "$need_dash_r" ; then
> +		LDFLAGS="$LDFLAGS -R${gsi_path}/lib"
> +	fi
> +	if test ! -z "$blibpath" ; then
> +		blibpath="$blibpath:${gsi_path}/lib"
> +	fi
> +	# test that we got the libraries OK
> +	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Globus linkline" >&5
> +$as_echo_n "checking Globus linkline... " >&6; }
> +	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h.  */
2913c3451,3453
< +	last_call = now;
---
> +int
> +main ()
> +{
2915,2923c3455,3459
< +	if (saved_mech == GSS_C_NO_OID)
< +		return 0;
< +	
< +	major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, 
< +	    &name, &lifetime, NULL, NULL);
< +	if (major == GSS_S_CREDENTIALS_EXPIRED)
< +		return 0;
< +	else if (GSS_ERROR(major))
< +		return 0;
---
> +  ;
> +  return 0;
> +}
> +_ACEOF
> +if ac_fn_c_try_link "$LINENO"; then :
2925,2928c3461,3462
< +	major = gss_compare_name(&minor, saved_name, name, &equal);
< +	gss_release_name(&minor, &name);
< +	if (GSS_ERROR(major))
< +		return 0;
---
> +			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
> +$as_echo "yes" >&6; }
2930,2931c3464
< +	if (equal && (saved_lifetime < lifetime + now - 10))
< +		return 1;
---
> +else
2933,2934c3466
< +	return 0;
< +}
---
> +			as_fn_error $? "link with Globus libraries failed" "$LINENO" 5
2936,2963d3467
<  #endif /* GSSAPI */
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/gss-serv-gsi.c openssh-6.0p1/gss-serv-gsi.c
< --- openssh-6.0p1.orig/gss-serv-gsi.c	1969-12-31 18:00:00.000000000 -0600
< +++ openssh-6.0p1/gss-serv-gsi.c	2012-05-27 17:50:01.000000000 -0500
< @@ -0,0 +1,238 @@
< +/*
< + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
< + *
< + * Redistribution and use in source and binary forms, with or without
< + * modification, are permitted provided that the following conditions
< + * are met:
< + * 1. Redistributions of source code must retain the above copyright
< + *    notice, this list of conditions and the following disclaimer.
< + * 2. Redistributions in binary form must reproduce the above copyright
< + *    notice, this list of conditions and the following disclaimer in the
< + *    documentation and/or other materials provided with the distribution.
< + *
< + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
< + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
< + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
< + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
< + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
< + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
< + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
< + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
< + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
< + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
< + */
2965c3469,3478
< +#include "includes.h"
---
> +fi
> +rm -f core conftest.err conftest.$ac_objext \
> +    conftest$ac_exeext conftest.$ac_ext
> +    for ac_func in globus_gss_assist_map_and_authorize
> +do :
> +  ac_fn_c_check_func "$LINENO" "globus_gss_assist_map_and_authorize" "ac_cv_func_globus_gss_assist_map_and_authorize"
> +if test "x$ac_cv_func_globus_gss_assist_map_and_authorize" = xyes; then :
> +  cat >>confdefs.h <<_ACEOF
> +#define HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE 1
> +_ACEOF
2967,2968c3480,3481
< +#ifdef GSSAPI
< +#ifdef GSI
---
> +fi
> +done
2970c3483
< +#include <sys/types.h>
---
> +fi
2972,2973d3484
< +#include <stdarg.h>
< +#include <string.h>
2975,2980c3486,3487
< +#include "xmalloc.h"
< +#include "key.h"
< +#include "hostfile.h"
< +#include "auth.h"
< +#include "log.h"
< +#include "servconf.h"
---
> +ac_fn_c_check_func "$LINENO" "globus_usage_stats_send" "ac_cv_func_globus_usage_stats_send"
> +if test "x$ac_cv_func_globus_usage_stats_send" = xyes; then :
2982,2983c3489
< +#include "buffer.h"
< +#include "ssh-gss.h"
---
> +$as_echo "#define HAVE_GLOBUS_USAGE 1" >>confdefs.h
2985c3491
< +extern ServerOptions options;
---
> +fi
2987d3492
< +#include <globus_gss_assist.h>
2989,2993c3494,3495
< +static int ssh_gssapi_gsi_userok(ssh_gssapi_client *client, char *name);
< +static int ssh_gssapi_gsi_localname(ssh_gssapi_client *client, char **user);
< +static void ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client);
< +static int ssh_gssapi_gsi_updatecreds(ssh_gssapi_ccache *store,
< +				       ssh_gssapi_client *client);
---
> +ac_fn_c_check_func "$LINENO" "globus_usage_stats_send_array" "ac_cv_func_globus_usage_stats_send_array"
> +if test "x$ac_cv_func_globus_usage_stats_send_array" = xyes; then :
2995,3004c3497
< +ssh_gssapi_mech gssapi_gsi_mech = {
< +	"dZuIebMjgUqaxvbF7hDbAw==",
< +	"GSI",
< +	{9, "\x2B\x06\x01\x04\x01\x9B\x50\x01\x01"},
< +	NULL,
< +	&ssh_gssapi_gsi_userok,
< +	&ssh_gssapi_gsi_localname,
< +	&ssh_gssapi_gsi_storecreds,
< +	&ssh_gssapi_gsi_updatecreds
< +};
---
> +$as_echo "#define HAVE_GLOBUS_USAGE_SEND_ARRAY 1" >>confdefs.h
3006,3026c3499
< +/*
< + * Check if this user is OK to login under GSI. User has been authenticated
< + * as identity in global 'client_name.value' and is trying to log in as passed
< + * username in 'name'.
< + *
< + * Returns non-zero if user is authorized, 0 otherwise.
< + */
< +static int
< +ssh_gssapi_gsi_userok(ssh_gssapi_client *client, char *name)
< +{
< +    int authorized = 0;
< +    globus_result_t res;
< +#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
< +    char lname[256] = "";
< +#endif
< +    
< +#ifdef GLOBUS_GSI_GSS_ASSIST_MODULE
< +    if (globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE) != 0) {
< +	return 0;
< +    }
< +#endif
---
> +fi
3028,3055d3500
< +/* use new globus_gss_assist_map_and_authorize() interface if available */
< +#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
< +    debug("calling globus_gss_assist_map_and_authorize()");
< +    if (GLOBUS_SUCCESS !=
< +        (res = globus_gss_assist_map_and_authorize(client->context, "ssh",
< +                                                   name, lname, 256))) {
< +        debug("%s", globus_error_print_chain(globus_error_get(res)));
< +    } else if (lname[0] && strcmp(name, lname) != 0) {
< +        debug("GSI user maps to %s, not %s", lname, name);
< +    } else {
< +        authorized = 1;
< +    }
< +#else
< +    debug("calling globus_gss_assist_userok()");
< +    if (GLOBUS_SUCCESS !=
< +        (res = (globus_gss_assist_userok(client->displayname.value,
< +                                         name)))) {
< +        debug("%s", globus_error_print_chain(globus_error_get(res)));
< +    } else {
< +        authorized = 1;
< +    }
< +#endif
< +    
< +    logit("GSI user %s is%s authorized as target user %s",
< +	(char *) client->displayname.value, (authorized ? "" : " not"), name);
< +    
< +    return authorized;
< +}
3057,3059c3502,3537
< +/*
< + * Return the local username associated with the GSI credentials.
< + */
---
> +# Check whether the user wants GSSAPI mechglue support
> +
> +# Check whether --with-mechglue was given.
> +if test "${with_mechglue+set}" = set; then :
> +  withval=$with_mechglue;
> +		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mechglue library" >&5
> +$as_echo_n "checking for mechglue library... " >&6; }
> +
> +		if test -e ${withval}/libgssapi.a ; then
> +		    mechglue_lib=${withval}/libgssapi.a
> +		elif test -e ${withval}/lib/libgssapi.a ; then
> +		    mechglue_lib=${withval}/lib/libgssapi.a
> +		else
> +		    as_fn_error $? "\"Can't find libgssapi in ${withval}\"" "$LINENO" 5;
> +		fi
> +		LIBS="${mechglue_lib} $LIBS"
> +		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${mechglue_lib}" >&5
> +$as_echo "${mechglue_lib}" >&6; }
> +
> +		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
> +$as_echo_n "checking for dlopen in -ldl... " >&6; }
> +if ${ac_cv_lib_dl_dlopen+:} false; then :
> +  $as_echo_n "(cached) " >&6
> +else
> +  ac_check_lib_save_LIBS=$LIBS
> +LIBS="-ldl  $LIBS"
> +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
> +/* end confdefs.h.  */
> +
> +/* Override any GCC internal prototype to avoid an error.
> +   Use char because int might match the return type of a GCC
> +   builtin and then its argument prototype would still apply.  */
> +#ifdef __cplusplus
> +extern "C"
> +#endif
> +char dlopen ();
3061c3539
< +ssh_gssapi_gsi_localname(ssh_gssapi_client *client, char **user)
---
> +main ()
3063,3066c3541,3560
< +    globus_result_t res;
< +#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
< +    char lname[256] = "";
< +#endif
---
> +return dlopen ();
> +  ;
> +  return 0;
> +}
> +_ACEOF
> +if ac_fn_c_try_link "$LINENO"; then :
> +  ac_cv_lib_dl_dlopen=yes
> +else
> +  ac_cv_lib_dl_dlopen=no
> +fi
> +rm -f core conftest.err conftest.$ac_objext \
> +    conftest$ac_exeext conftest.$ac_ext
> +LIBS=$ac_check_lib_save_LIBS
> +fi
> +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
> +$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
> +if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
> +  cat >>confdefs.h <<_ACEOF
> +#define HAVE_LIBDL 1
> +_ACEOF
3068,3072c3562
< +#ifdef GLOBUS_GSI_GSS_ASSIST_MODULE
< +    if (globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE) != 0) {
< +	return 0;
< +    }
< +#endif
---
> +  LIBS="-ldl $LIBS"
3074,3093c3564
< +/* use new globus_gss_assist_map_and_authorize() interface if available */
< +#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
< +    debug("calling globus_gss_assist_map_and_authorize()");
< +    if (GLOBUS_SUCCESS !=
< +        (res = globus_gss_assist_map_and_authorize(client->context, "ssh",
< +                                                   NULL, lname, 256))) {
< +        debug("%s", globus_error_print_chain(globus_error_get(res)));
< +        logit("failed to map GSI user %s", (char *)client->displayname.value);
< +        return 0;
< +    }
< +    *user = strdup(lname);
< +#else
< +    debug("calling globus_gss_assist_gridmap()");
< +    if (GLOBUS_SUCCESS !=
< +        (res = globus_gss_assist_gridmap(client->displayname.value, user))) {
< +        debug("%s", globus_error_print_chain(globus_error_get(res)));
< +        logit("failed to map GSI user %s", (char *)client->displayname.value);
< +        return 0;
< +    }
< +#endif
---
> +fi
3095,3096c3566,3568
< +    logit("GSI user %s mapped to target user %s",
< +          (char *) client->displayname.value, *user);
---
> +		if test $ac_cv_lib_dl_dlopen = yes; then
> +		   LDFLAGS="$LDFLAGS -ldl -Wl,-Bsymbolic"
> +		fi
3098,3099c3570
< +    return 1;
< +}
---
> +		$as_echo "#define GSSAPI 1" >>confdefs.h
3101,3114d3571
< +/*
< + * Export GSI credentials to disk.
< + */
< +static void
< +ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client)
< +{
< +	OM_uint32	major_status;
< +	OM_uint32	minor_status;
< +	gss_buffer_desc	export_cred = GSS_C_EMPTY_BUFFER;
< +	char *		p;
< +	
< +	if (!client || !client->creds) {
< +	    return;
< +	}
3116,3165c3573
< +	major_status = gss_export_cred(&minor_status,
< +				       client->creds,
< +				       GSS_C_NO_OID,
< +				       1,
< +				       &export_cred);
< +	if (GSS_ERROR(major_status) && major_status != GSS_S_UNAVAILABLE) {
< +	    Gssctxt *ctx;
< +	    ssh_gssapi_build_ctx(&ctx);
< +	    ctx->major = major_status;
< +	    ctx->minor = minor_status;
< +	    ssh_gssapi_set_oid(ctx, &gssapi_gsi_mech.oid);
< +	    ssh_gssapi_error(ctx);
< +	    ssh_gssapi_delete_ctx(&ctx);
< +	    return;
< +	}
< +	
< +	p = strchr((char *) export_cred.value, '=');
< +	if (p == NULL) {
< +	    logit("Failed to parse exported credentials string '%.100s'",
< +		(char *)export_cred.value);
< +	    gss_release_buffer(&minor_status, &export_cred);
< +	    return;
< +	}
< +	*p++ = '\0';
< +	if (strcmp((char *)export_cred.value,"X509_USER_DELEG_PROXY") == 0) {
< +	    client->store.envvar = strdup("X509_USER_PROXY");
< +	} else {
< +	    client->store.envvar = strdup((char *)export_cred.value);
< +	}
< +	if (access(p, R_OK) == 0) {
< +        if (client->store.filename) {
< +            if (rename(p, client->store.filename) < 0) {
< +                logit("Failed to rename %s to %s: %s", p,
< +                      client->store.filename, strerror(errno));
< +                xfree(client->store.filename);
< +                client->store.filename = strdup(p);
< +            } else {
< +                p = client->store.filename;
< +            }
< +        } else {
< +            client->store.filename = strdup(p);
< +        }
< +	}
< +	client->store.envval = strdup(p);
< +#ifdef USE_PAM
< +	if (options.use_pam)
< +	    do_pam_putenv(client->store.envvar, client->store.envval);
< +#endif
< +	gss_release_buffer(&minor_status, &export_cred);
< +}
---
> +$as_echo "#define MECHGLUE 1" >>confdefs.h
3167,3175c3575
< +/*
< + * Export updated GSI credentials to disk.
< + */
< +static int
< +ssh_gssapi_gsi_updatecreds(ssh_gssapi_ccache *store,ssh_gssapi_client *client)
< +{
< +	ssh_gssapi_gsi_storecreds(client);
< +	return 1;
< +}
---
> +		GSSAPI="mechglue"
3177,3209d3576
< +#endif /* GSI */
< +#endif /* GSSAPI */
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/gss-serv-krb5.c openssh-6.0p1/gss-serv-krb5.c
< --- openssh-6.0p1.orig/gss-serv-krb5.c	2006-09-01 00:38:36.000000000 -0500
< +++ openssh-6.0p1/gss-serv-krb5.c	2012-05-27 17:50:01.000000000 -0500
< @@ -1,7 +1,7 @@
<  /* $OpenBSD: gss-serv-krb5.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */
<  
<  /*
< - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
< + * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
<   *
<   * Redistribution and use in source and binary forms, with or without
<   * modification, are permitted provided that the following conditions
< @@ -48,7 +48,7 @@
<  
<  #ifdef HEIMDAL
<  # include <krb5.h>
< -#else
< +#elif !defined(MECHGLUE)
<  # ifdef HAVE_GSSAPI_KRB5_H
<  #  include <gssapi_krb5.h>
<  # elif HAVE_GSSAPI_GSSAPI_KRB5_H
< @@ -57,6 +57,23 @@
<  #endif
<  
<  static krb5_context krb_context = NULL;
< +static int ssh_gssapi_krb5_init();
< +static int ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name);
< +static int ssh_gssapi_krb5_localname(ssh_gssapi_client *client, char **user);
< +static void ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client);
< +static int ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store,
< +                                       ssh_gssapi_client *client);
3211,3220c3578,3583
< +ssh_gssapi_mech gssapi_kerberos_mech = {
< +	"toWM5Slw5Ew8Mqkay+al2g==",
< +	"Kerberos",
< +	{9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"},
< +	NULL,
< +	&ssh_gssapi_krb5_userok,
< +	&ssh_gssapi_krb5_localname,
< +	&ssh_gssapi_krb5_storecreds,
< +	&ssh_gssapi_krb5_updatecreds
< +};
---
> +fi
> +
> +
> +
>  # Check whether user wants Kerberos 5 support
>  KRB5_MSG="no"
3222c3585
<  /* Initialise the krb5 library, for the stuff that GSSAPI won't do */
---
> @@ -15348,7 +15685,27 @@
3224,3225d3586
< @@ -109,6 +126,35 @@
<  }
3228,3237c3589,3593
< +/* Retrieve the local username associated with a set of Kerberos 
< + * credentials. Hopefully we can use this for the 'empty' username
< + * logins discussed in the draft  */
< +static int
< +ssh_gssapi_krb5_localname(ssh_gssapi_client *client, char **user) {
< +	krb5_principal princ;
< +	int retval;
< +	
< +	if (ssh_gssapi_krb5_init() == 0)
< +		return 0;
---
> -		fi
> +			# If we're using some other GSSAPI
> +			if test "$GSSAPI" -a "$GSSAPI" != "mechglue"; then
> +				as_fn_error $? "$GSSAPI GSSAPI library conflicts with Kerberos support.  Use mechglue instead." "$LINENO" 5
> +			fi
3239,3282c3595,3597
< +	if ((retval=krb5_parse_name(krb_context, client->displayname.value, 
< +				    &princ))) {
< +		logit("krb5_parse_name(): %.100s", 
< +			krb5_get_err_text(krb_context,retval));
< +		return 0;
< +	}
< +	
< +	/* We've got to return a malloc'd string */
< +	*user = (char *)xmalloc(256);
< +	if (krb5_aname_to_localname(krb_context, princ, 256, *user)) {
< +		xfree(*user);
< +		*user = NULL;
< +		return(0);
< +	}
< +	
< +	return(1);
< +}
< +	
<  /* This writes out any forwarded credentials from the structure populated
<   * during userauth. Called after we have setuid to the user */
<  
< @@ -119,7 +165,9 @@
<  	krb5_error_code problem;
<  	krb5_principal princ;
<  	OM_uint32 maj_status, min_status;
< +	gss_cred_id_t krb5_cred_handle;
<  	int len;
< +	const char *new_ccname;
<  
<  	if (client->creds == NULL) {
<  		debug("No credentials stored");
< @@ -161,18 +209,31 @@
<  
<  	krb5_free_principal(krb_context, princ);
<  
< -	if ((maj_status = gss_krb5_copy_ccache(&min_status,
< -	    client->creds, ccache))) {
< +#ifdef MECHGLUE
< +	krb5_cred_handle =
< +	    __gss_get_mechanism_cred(client->creds,
< +				     &(gssapi_kerberos_mech.oid));
< +#else
< +	krb5_cred_handle = client->creds;
< +#endif
---
> +			if test -z "$GSSAPI"; then
> +				GSSAPI="KRB5";
> +			fi
3284,3292c3599,3602
< +	if ((maj_status = gss_krb5_copy_ccache(&min_status, 
< +	    krb5_cred_handle, ccache))) {
<  		logit("gss_krb5_copy_ccache() failed");
<  		krb5_cc_destroy(krb_context, ccache);
<  		return;
<  	}
<  
< -	client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache));
< +	new_ccname = krb5_cc_get_name(krb_context, ccache);
---
> +			oldCPP="$CPPFLAGS"
> +			CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
> +			ac_fn_c_check_header_mongrel "$LINENO" "gssapi_krb5.h" "ac_cv_header_gssapi_krb5_h" "$ac_includes_default"
> +if test "x$ac_cv_header_gssapi_krb5_h" = xyes; then :
3294,3304c3604,3615
<  	client->store.envvar = "KRB5CCNAME";
< -	len = strlen(client->store.filename) + 6;
< -	client->store.envval = xmalloc(len);
< -	snprintf(client->store.envval, len, "FILE:%s", client->store.filename);
< +#ifdef USE_CCAPI
< +	xasprintf(&client->store.envval, "API:%s", new_ccname);
< +	client->store.filename = NULL;
< +#else
< +	xasprintf(&client->store.envval, "FILE:%s", new_ccname);
< +	client->store.filename = xstrdup(new_ccname);
< +#endif
---
> +else
> +   CPPFLAGS="$oldCPP"
> +fi
> +
> +
> +
> +                fi
>  		if test ! -z "$need_dash_r" ; then
>  			LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib"
>  		fi
> @@ -15461,6 +15818,57 @@
>  fi
3306,3310d3616
<  #ifdef USE_PAM
<  	if (options.use_pam)
< @@ -184,15 +245,70 @@
<  	return;
<  }
3312,3329c3618,3619
< -ssh_gssapi_mech gssapi_kerberos_mech = {
< -	"toWM5Slw5Ew8Mqkay+al2g==",
< -	"Kerberos",
< -	{9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"},
< -	NULL,
< -	&ssh_gssapi_krb5_userok,
< -	NULL,
< -	&ssh_gssapi_krb5_storecreds
< -};
< +static int
< +ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, 
< +    ssh_gssapi_client *client)
< +{
< +	krb5_ccache ccache = NULL;
< +	krb5_principal principal = NULL;
< +	char *name = NULL;
< +	krb5_error_code problem;
< +	OM_uint32 maj_status, min_status;
---
> +# Check whether user wants AFS_KRB5 support
> +AFS_KRB5_MSG="no"
3331,3344c3621,3624
< +   	if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) {
< +                logit("krb5_cc_resolve(): %.100s",
< +                    krb5_get_err_text(krb_context, problem));
< +                return 0;
< +       	}
< +	
< +	/* Find out who the principal in this cache is */
< +	if ((problem = krb5_cc_get_principal(krb_context, ccache, 
< +	    &principal))) {
< +		logit("krb5_cc_get_principal(): %.100s",
< +		    krb5_get_err_text(krb_context, problem));
< +		krb5_cc_close(krb_context, ccache);
< +		return 0;
< +	}
---
> +# Check whether --with-afs-krb5 was given.
> +if test "${with_afs_krb5+set}" = set; then :
> +  withval=$with_afs_krb5;
> +		if test "x$withval" != "xno" ; then
3346,3352c3626
< +	if ((problem = krb5_unparse_name(krb_context, principal, &name))) {
< +		logit("krb5_unparse_name(): %.100s",
< +		    krb5_get_err_text(krb_context, problem));
< +		krb5_free_principal(krb_context, principal);
< +		krb5_cc_close(krb_context, ccache);
< +		return 0;
< +	}
---
> +			if test "x$withval" != "xyes" ; then
3353a3628,3630
> +cat >>confdefs.h <<_ACEOF
> +#define AKLOG_PATH "$withval"
> +_ACEOF
3355,3362c3632
< +	if (strcmp(name,client->exportedname.value)!=0) {
< +		debug("Name in local credentials cache differs. Not storing");
< +		krb5_free_principal(krb_context, principal);
< +		krb5_cc_close(krb_context, ccache);
< +		krb5_free_unparsed_name(krb_context, name);
< +		return 0;
< +	}
< +	krb5_free_unparsed_name(krb_context, name);
---
> +			else
3364c3634,3636
< +	/* Name matches, so lets get on with it! */
---
> +cat >>confdefs.h <<_ACEOF
> +#define AKLOG_PATH "/usr/bin/aklog"
> +_ACEOF
3366,3372c3638
< +	if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) {
< +		logit("krb5_cc_initialize(): %.100s",
< +		    krb5_get_err_text(krb_context, problem));
< +		krb5_free_principal(krb_context, principal);
< +		krb5_cc_close(krb_context, ccache);
< +		return 0;
< +	}
---
> +			fi
3374c3640,3643
< +	krb5_free_principal(krb_context, principal);
---
> +			if test -z "$KRB5ROOT" ; then
> +				{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: AFS_KRB5 requires Kerberos 5 support, build may fail" >&5
> +$as_echo "$as_me: WARNING: AFS_KRB5 requires Kerberos 5 support, build may fail" >&2;}
> +			fi
3376,3381c3645,3648
< +	if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds,
< +	    ccache))) {
< +		logit("gss_krb5_copy_ccache() failed. Sorry!");
< +		krb5_cc_close(krb_context, ccache);
< +		return 0;
< +	}
---
> +			LIBS="-lkrbafs -lkrb4 $LIBS"
> +			if test ! -z "$AFS_LIBS" ; then
> +				LIBS="$LIBS $AFS_LIBS"
> +			fi
3383,3409c3650
< +	return 1;
< +}
<  
<  #endif /* KRB5 */
<  
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/gss-serv.c openssh-6.0p1/gss-serv.c
< --- openssh-6.0p1.orig/gss-serv.c	2011-08-05 15:16:46.000000000 -0500
< +++ openssh-6.0p1/gss-serv.c	2012-05-27 17:50:01.000000000 -0500
< @@ -1,7 +1,7 @@
<  /* $OpenBSD: gss-serv.c,v 1.23 2011/08/01 19:18:15 markus Exp $ */
<  
<  /*
< - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
< + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
<   *
<   * Redistribution and use in source and binary forms, with or without
<   * modification, are permitted provided that the following conditions
< @@ -45,27 +45,43 @@
<  #include "channels.h"
<  #include "session.h"
<  #include "misc.h"
< +#include "servconf.h"
< +#include "uidswap.h"
<  
< +#include "xmalloc.h"
<  #include "ssh-gss.h"
< +#include "monitor_wrap.h"
---
> +$as_echo "#define AFS_KRB5 1" >>confdefs.h
3411,3412c3652,3669
< +extern ServerOptions options;
< +extern Authctxt *the_authctxt;
---
> +			AFS_KRB5_MSG="yes"
> +		fi
> +
> +
> +fi
> +
> +
> +
> +# Check whether --with-session-hooks was given.
> +if test "${with_session_hooks+set}" = set; then :
> +  withval=$with_session_hooks;
> +$as_echo "#define SESSION_HOOKS 1" >>confdefs.h
> +
> +
> +fi
> +
> +
>  # Looking for programs, paths and files
3414,3417c3671,3673
<  static ssh_gssapi_client gssapi_client =
<      { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER,
< -    GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL}};
< +    GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,  NULL, {NULL, NULL, NULL}, 0, 0};
---
>  PRIVSEP_PATH=/var/empty
> @@ -15542,7 +15950,10 @@
>  fi
3419,3421d3674
<  ssh_gssapi_mech gssapi_null_mech =
< -    { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL};
< +    { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL};
3423,3428c3676,3688
<  #ifdef KRB5
<  extern ssh_gssapi_mech gssapi_kerberos_mech;
<  #endif
< +#ifdef GSI
< +extern ssh_gssapi_mech gssapi_gsi_mech;
< +#endif
---
> +# strip causes problems with GSI libraries...
> +if test -z "$GLOBUS_LDFLAGS" ; then
>  STRIP_OPT=-s
> +fi
>  # Check whether --enable-strip was given.
>  if test "${enable_strip+set}" = set; then :
>    enableval=$enable_strip;
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/configure.ac openssh-6.0p1/configure.ac
> --- openssh-6.0p1.orig/configure.ac	2012-07-12 17:00:49.174198000 +0200
> +++ openssh-6.0p1/configure.ac	2012-07-12 17:01:14.214687958 +0200
> @@ -19,6 +19,151 @@
>  AC_CONFIG_SRCDIR([ssh.c])
>  AC_LANG([C])
3430,3454c3690,3691
<  ssh_gssapi_mech* supported_mechs[]= {
<  #ifdef KRB5
<  	&gssapi_kerberos_mech,
<  #endif
< +#ifdef GSI
< +	&gssapi_gsi_mech,
< +#endif
<  	&gssapi_null_mech,
<  };
<  
< +#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG
< +static int limited = 0;
< +#endif
<  
<  /*
<   * Acquire credentials for a server running on the current host.
< @@ -81,25 +97,32 @@
<  	char lname[MAXHOSTNAMELEN];
<  	gss_OID_set oidset;
<  
< -	gss_create_empty_oid_set(&status, &oidset);
< -	gss_add_oid_set_member(&status, ctx->oid, &oidset);
< +	if (options.gss_strict_acceptor) {
< +		gss_create_empty_oid_set(&status, &oidset);
< +		gss_add_oid_set_member(&status, ctx->oid, &oidset);
---
> +# Handle Globus configuration right away, because the Globus flavor
> +# determines our compiler options.
3456,3468c3693,3700
< +		if (gethostname(lname, MAXHOSTNAMELEN)) {
< +			gss_release_oid_set(&status, &oidset);
< +			return (-1);
< +		}
<  
< -	if (gethostname(lname, MAXHOSTNAMELEN)) {
< -		gss_release_oid_set(&status, &oidset);
< -		return (-1);
< -	}
< +		if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
< +			gss_release_oid_set(&status, &oidset);
< +			return (ctx->major);
< +		}
---
> +# Check whether the user wants GSI (Globus) support
> +gsi_path="no"
> +AC_ARG_WITH(gsi,
> +	[  --with-gsi              Enable Globus GSI authentication support],
> +	[
> +		gsi_path="$withval"
> +	]
> +)
3470,3499c3702,3707
< +		if ((ctx->major = gss_acquire_cred(&ctx->minor,
< +		    ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, 
< +		    NULL, NULL)))
< +			ssh_gssapi_error(ctx);
<  
< -	if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
<  		gss_release_oid_set(&status, &oidset);
<  		return (ctx->major);
< +	} else {
< +		ctx->name = GSS_C_NO_NAME;
< +		ctx->creds = GSS_C_NO_CREDENTIAL;
<  	}
< -
< -	if ((ctx->major = gss_acquire_cred(&ctx->minor,
< -	    ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL)))
< -		ssh_gssapi_error(ctx);
< -
< -	gss_release_oid_set(&status, &oidset);
< -	return (ctx->major);
< +	return GSS_S_COMPLETE;
<  }
<  
<  /* Privileged */
< @@ -114,6 +137,29 @@
<  }
<  
<  /* Unprivileged */
< +char *
< +ssh_gssapi_server_mechanisms() {
< +	gss_OID_set	supported;
---
> +AC_ARG_WITH(globus,
> +	[  --with-globus           Enable Globus GSI authentication support],
> +	[
> +		gsi_path="$withval"
> +	]
> +)
3501,3504c3709,3717
< +	ssh_gssapi_supported_oids(&supported);
< +	return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech,
< +	    NULL, NULL));
< +}
---
> +AC_ARG_WITH(globus-static,
> +	[  --with-globus-static    Link statically with Globus GSI libraries],
> +	[
> +		gsi_static="-static"
> +		if test "x$gsi_path" = "xno" ; then
> +			gsi_path="$withval"
> +		fi
> +	]
> +)
3506,3514c3719,3729
< +/* Unprivileged */
< +int
< +ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data,
< +    const char *dummy) {
< +	Gssctxt *ctx = NULL;
< +	int res;
< + 
< +	res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid)));
< +	ssh_gssapi_delete_ctx(&ctx);
---
> +# Check whether the user has a Globus flavor type
> +globus_flavor_type="no"
> +AC_ARG_WITH(globus-flavor,
> +	[  --with-globus-flavor=TYPE  Specify Globus flavor type (ex: gcc32dbg)],
> +	[
> +		globus_flavor_type="$withval"
> +		if test "x$gsi_path" = "xno" ; then
> +			gsi_path="yes"
> +		fi
> +	]
> +)
3516,3517c3731,3734
< +	return (res);
< +}
---
> +if test "x$gsi_path" != "xno" ; then
> +	# Globus GSSAPI configuration
> +	AC_MSG_CHECKING(for Globus GSI)
> +	AC_DEFINE(GSI, 1, [Define if you want GSI/Globus authentication support.])
3519,3527c3736,3742
< +/* Unprivileged */
<  void
<  ssh_gssapi_supported_oids(gss_OID_set *oidset)
<  {
< @@ -123,7 +169,10 @@
<  	gss_OID_set supported;
<  
<  	gss_create_empty_oid_set(&min_status, oidset);
< -	gss_indicate_mechs(&min_status, &supported);
---
> +	if test "$GSSAPI" -a "$GSSAPI" != "mechglue"; then
> +		AC_MSG_ERROR([Previously configured GSSAPI library conflicts with Globus GSI.])
> +	fi
> +	if test -z "$GSSAPI"; then
> +		AC_DEFINE(GSSAPI)
> +		GSSAPI="GSI"
> +	fi
3529,3559c3744,3757
< +	/* Ask privileged process what mechanisms it supports. */
< +	if (GSS_ERROR(PRIVSEP(gss_indicate_mechs(&min_status, &supported))))
< +		return;
<  
<  	while (supported_mechs[i]->name != NULL) {
<  		if (GSS_ERROR(gss_test_oid_set_member(&min_status,
< @@ -175,6 +224,10 @@
<  	    (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) {
<  		if (ssh_gssapi_getclient(ctx, &gssapi_client))
<  			fatal("Couldn't convert client name");
< +#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG
< +		if (flags && (*flags & GSS_C_GLOBUS_LIMITED_PROXY_FLAG))
< +			limited=1;
< +#endif
<  	}
<  
<  	return (status);
< @@ -194,6 +247,17 @@
<  
<  	tok = ename->value;
<  
< +#ifdef GSI /* GSI gss_export_name() is broken. */
< +	if ((ctx->oid->length == gssapi_gsi_mech.oid.length) &&
< +	    (memcmp(ctx->oid->elements, gssapi_gsi_mech.oid.elements,
< +		    gssapi_gsi_mech.oid.length) == 0)) {
< +	    name->length = ename->length;
< +	    name->value = xmalloc(ename->length+1);
< +	    memcpy(name->value, ename->value, ename->length);
< +	    return GSS_S_COMPLETE;
< +	}
< +#endif
---
> +	if test "x$gsi_path" = "xyes" ; then
> +		if test -z "$GLOBUS_LOCATION" ; then
> +			AC_MSG_ERROR(GLOBUS_LOCATION environment variable must be set.)
> +		else
> +			gsi_path="$GLOBUS_LOCATION"
> +		fi
> +	fi
> +	GLOBUS_LOCATION="$gsi_path"
> +	export GLOBUS_LOCATION
> +    LD_LIBRARY_PATH="${gsi_path}/lib:$LD_LIBRARY_PATH"
> +    export LD_LIBRARY_PATH
> +	if test ! -d "$GLOBUS_LOCATION" ; then
> +		AC_MSG_ERROR(Cannot find Globus installation.  Set GLOBUS_LOCATION environment variable.)
> +	fi
3561,3570c3759,3765
<  	/*
<  	 * Check that ename is long enough for all of the fixed length
<  	 * header, and that the initial ID bytes are correct
< @@ -249,8 +313,51 @@
<  ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
<  {
<  	int i = 0;
< +	int equal = 0;
< +	gss_name_t new_name = GSS_C_NO_NAME;
< +	gss_buffer_desc ename = GSS_C_EMPTY_BUFFER;
---
> +        if test "x$globus_flavor_type" = "xno" ; then
> +                AC_MSG_ERROR(--with-globus-flavor=TYPE must be specified)
> +	fi
> +        if test "x$globus_flavor_type" = "xyes" ; then
> +                AC_MSG_ERROR(--with-globus-flavor=TYPE must specify a flavor type)
> +	fi
> +    AC_MSG_RESULT($GLOBUS_LOCATION)
3572,3578c3767,3811
< +	if (options.gss_store_rekey && client->used && ctx->client_creds) {
< +		if (client->mech->oid.length != ctx->oid->length ||
< +		    (memcmp(client->mech->oid.elements,
< +		     ctx->oid->elements, ctx->oid->length) !=0)) {
< +			debug("Rekeyed credentials have different mechanism");
< +			return GSS_S_COMPLETE;
< +		}
---
> +	AC_MSG_CHECKING(for Globus include path)
> +  if test -d "${gsi_path}/include/${globus_flavor_type}" ; then
> +	    GLOBUS_INCLUDE="${gsi_path}/include/${globus_flavor_type}"
> +  elif test -d "${gsi_path}/include/globus" ; then
> +      GLOBUS_INCLUDE="${gsi_path}/include/globus"
> +  else
> +		AC_MSG_ERROR(Cannot find Globus include directory in ${gsi_path}/include)
> +	fi
> +	GSI_CPPFLAGS="-I${GLOBUS_INCLUDE}"
> +	AC_MSG_RESULT(yes)
> +	
> +	AC_MSG_CHECKING(for globus-makefile-header)
> +	if test -x ${gsi_path}/bin/globus-makefile-header ; then
> +		${gsi_path}/bin/globus-makefile-header --flavor=${globus_flavor_type} ${gsi_static} globus_gss_assist globus_usage 2>/dev/null | sed 's/ = \(.*\)/="\1"/' > ./gpt_build_tmp.sh
> +	elif test -x ${gsi_path}/sbin/globus-makefile-header ; then
> +		${gsi_path}/sbin/globus-makefile-header --flavor=${globus_flavor_type} ${gsi_static} globus_gss_assist globus_usage 2>/dev/null | sed 's/ = \(.*\)/="\1"/' > ./gpt_build_tmp.sh
> +	fi
> +    if test -f ./gpt_build_tmp.sh ; then
> +    	. ./gpt_build_tmp.sh
> +    fi
> +	if test -z "$GLOBUS_PKG_LIBS" ; then
> +    	AC_MSG_RESULT(no)
> +        AC_MSG_CHECKING(for gpt_build_config)
> +        # globus-makefile-header failed so try gpt_build_config
> +        # likely this is because gpt-postinstall hasn't been run yet
> +        # (i.e., this is a fresh Globus Toolkit install)
> +        if test -x $GPT_LOCATION/sbin/gpt_build_config ; then
> +        	gpt_linkline_helper="$GPT_LOCATION/sbin/gpt_build_config"
> +        elif test -x ${gsi_path}/sbin/gpt_build_config ; then
> +        	gpt_linkline_helper="${gsi_path}/sbin/gpt_build_config"
> +        else
> +            AC_MSG_ERROR(Cannot find gpt_build_config: GPT installation is incomplete)
> +        fi
> +        if test -n "${gsi_static}"; then
> +           ${gpt_linkline_helper} -f ${globus_flavor_type} -link static -src pkg_data_src.gpt
> +        else
> +        	${gpt_linkline_helper} -f ${globus_flavor_type} -link shared -src pkg_data_src.gpt
> +        fi
> +        . ./gpt_build_temp.sh
> +        if test -z "$GPT_CONFIG_PGM_LINKS" ; then
> +        	AC_MSG_ERROR(gpt_build_config failed)
> +        fi
> +       	GSI_LDFLAGS="-L${gsi_path}/lib"
> +    fi
> +   	AC_MSG_RESULT(yes)
3580,3581c3813
< +        /* Call gss_inquire_cred rather than gss_inquire_cred_by_mech
< +           because GSI doesn't support the latter. -jbasney */
---
> +	AC_DEFINE(HAVE_GSSAPI_H)
3583,3588c3815,3827
< +		if ((ctx->major = gss_inquire_cred(&ctx->minor, 
< +		    ctx->client_creds, &new_name, 
< +		    NULL, NULL, NULL))) {
< +			ssh_gssapi_error(ctx);
< +			return (ctx->major);
< +		}
---
> +    if test -n "$GLOBUS_CC" ; then
> +        CC="$GLOBUS_CC"
> +    fi
> +    CFLAGS="$CFLAGS $GLOBUS_CFLAGS $GPT_CONFIG_CFLAGS"
> +    if test -n "$GLOBUS_CPP" ; then
> +        CPP="$GLOBUS_CPP"
> +    fi
> +	CPPFLAGS="$CPPFLAGS $GLOBUS_CPPFLAGS $GLOBUS_INCLUDES $GSI_CPPFLAGS $GPT_CONFIG_INCLUDES"
> +	LIBS="$LIBS $GLOBUS_LIBS $GLOBUS_PKG_LIBS $GPT_CONFIG_LIBS $GPT_CONFIG_PGM_LINKS"
> +    if test -n "$GLOBUS_LD" ; then
> +        LD="$GLOBUS_LD"
> +    fi
> +	LDFLAGS="$LDFLAGS $GLOBUS_LDFLAGS $GSI_LDFLAGS"
3590,3591c3829,3903
< +		ctx->major = gss_compare_name(&ctx->minor, client->name, 
< +		    new_name, &equal);
---
> +	INSTALL_GSISSH="yes"
> +else
> +	INSTALL_GSISSH=""
> +fi
> +# End Globus/GSI section
> +
>  AC_CONFIG_HEADER([config.h])
>  AC_PROG_CC
>  AC_CANONICAL_HOST
> @@ -157,7 +302,8 @@
>  if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
>  	OSSH_CHECK_CFLAG_COMPILE([-Wall])
>  	OSSH_CHECK_CFLAG_COMPILE([-Wpointer-arith])
> -	OSSH_CHECK_CFLAG_COMPILE([-Wuninitialized])
> +#	cc1: warning: -Wuninitialized is not supported without -O
> +#	OSSH_CHECK_CFLAG_COMPILE([-Wuninitialized])
>  	OSSH_CHECK_CFLAG_COMPILE([-Wsign-compare])
>  	OSSH_CHECK_CFLAG_COMPILE([-Wformat-security])
>  	OSSH_CHECK_CFLAG_COMPILE([-Wpointer-sign], [-Wno-pointer-sign])
> @@ -520,20 +666,7 @@
>  	AC_DEFINE([BROKEN_SETREGID])
>  	;;
>  *-*-darwin*)
> -	AC_MSG_CHECKING([if we have working getaddrinfo])
> -	AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include <mach-o/dyld.h>
> -main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
> -		exit(0);
> -	else
> -		exit(1);
> -}
> -			]])],
> -	[AC_MSG_RESULT([working])],
> -	[AC_MSG_RESULT([buggy])
> -	AC_DEFINE([BROKEN_GETADDRINFO], [1],
> -		[getaddrinfo is broken (if present)])
> -	],
> -	[AC_MSG_RESULT([assume it is working])])
> +	AC_DEFINE(BROKEN_GETADDRINFO, 1, [assume getaddrinfo is broken)])
>  	AC_DEFINE([SETEUID_BREAKS_SETUID])
>  	AC_DEFINE([BROKEN_SETREUID])
>  	AC_DEFINE([BROKEN_SETREGID])
> @@ -545,6 +678,30 @@
>  	    [Use tunnel device compatibility to OpenBSD])
>  	AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
>  	    [Prepend the address family to IP tunnel traffic])
> +	AC_MSG_CHECKING(if we have the Security Authorization Session API)
> +	AC_TRY_COMPILE([#include <Security/AuthSession.h>],
> +		[SessionCreate(0, 0);],
> +		[ac_cv_use_security_session_api="yes"
> +		 AC_DEFINE(USE_SECURITY_SESSION_API, 1, 
> +			[platform has the Security Authorization Session API])
> +		 LIBS="$LIBS -framework Security"
> +		 AC_MSG_RESULT(yes)],
> +		[ac_cv_use_security_session_api="no"
> +		 AC_MSG_RESULT(no)])
> +	AC_MSG_CHECKING(if we have an in-memory credentials cache)
> +	AC_TRY_COMPILE(
> +		[#include <Kerberos/Kerberos.h>],
> +		[cc_context_t c;
> +		 (void) cc_initialize (&c, 0, NULL, NULL);],
> +		[AC_DEFINE(USE_CCAPI, 1, 
> +			[platform uses an in-memory credentials cache])
> +		 LIBS="$LIBS -framework Security"
> +		 AC_MSG_RESULT(yes)
> +		 if test "x$ac_cv_use_security_session_api" = "xno"; then
> +			AC_MSG_ERROR(*** Need a security framework to use the credentials cache API ***)
> +		fi],
> +		[AC_MSG_RESULT(no)]
> +	)
>  	m4_pattern_allow([AU_IPv])
>  	AC_CHECK_DECL([AU_IPv4], [], 
>  	    AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records])
> @@ -3493,6 +3650,71 @@
>  	])
>  AC_SUBST([LIBAUDIT])
3593,3602c3905,3927
< -	gss_buffer_desc ename;
< +		if (GSS_ERROR(ctx->major)) {
< +			ssh_gssapi_error(ctx);
< +			return (ctx->major);
< +		}
< + 
< +		if (!equal) {
< +			debug("Rekeyed credentials have different name");
< +			return GSS_S_COMPLETE;
< +		}
---
> +# Finish configuring Globus GSSAPI
> +if test "x$gsi_path" != "xno" ; then
> +	if test ! -z "$need_dash_r" ; then
> +		LDFLAGS="$LDFLAGS -R${gsi_path}/lib"
> +	fi
> +	if test ! -z "$blibpath" ; then
> +		blibpath="$blibpath:${gsi_path}/lib"
> +	fi
> +	# test that we got the libraries OK
> +	AC_MSG_CHECKING(Globus linkline)
> +	AC_TRY_LINK(
> +		[],
> +		[],
> +		[
> +			AC_MSG_RESULT(yes)
> +		],
> +		[
> +			AC_MSG_ERROR(link with Globus libraries failed)
> +		]
> +	)
> +    AC_CHECK_FUNCS(globus_gss_assist_map_and_authorize)
> +fi
> +AC_SUBST(INSTALL_GSISSH)
3604c3929,3933
< +		debug("Marking rekeyed credentials for export");
---
> +dnl
> +dnl Check for globus_usage_stats_send
> +dnl
> +AC_CHECK_FUNC(globus_usage_stats_send,
> +              AC_DEFINE([HAVE_GLOBUS_USAGE], 1, [Have Globus Usage]))
3606,3622c3935,3940
< +		gss_release_name(&ctx->minor, &client->name);
< +		gss_release_cred(&ctx->minor, &client->creds);
< +		client->name = new_name;
< +		client->creds = ctx->client_creds;
< +        	ctx->client_creds = GSS_C_NO_CREDENTIAL;
< +		client->updated = 1;
< +		return GSS_S_COMPLETE;
< +	}
<  
<  	client->mech = NULL;
<  
< @@ -265,6 +372,16 @@
<  	if (client->mech == NULL)
<  		return GSS_S_FAILURE;
<  
< +    /* Call gss_inquire_cred rather than gss_inquire_cred_by_mech
< +       because GSI doesn't support the latter. -jbasney */
---
> +dnl
> +dnl Check for globus_usage_stats_send_array
> +dnl
> +AC_CHECK_FUNC(globus_usage_stats_send_array,
> +              AC_DEFINE([HAVE_GLOBUS_USAGE_SEND_ARRAY], 1,
> +                        [Have Globus Usage send_array]))
3624,3629c3942,3946
< +	if (ctx->client_creds &&
< +	    (ctx->major = gss_inquire_cred(&ctx->minor,
< +	     ctx->client_creds, &client->name, NULL, NULL, NULL))) {
< +		ssh_gssapi_error(ctx);
< +		return (ctx->major);
< +	}
---
> +# Check whether the user wants GSSAPI mechglue support
> +AC_ARG_WITH(mechglue,
> +	[  --with-mechglue=PATH    Build with GSSAPI mechglue library],
> +	[
> +		AC_MSG_CHECKING(for mechglue library)
3631,3638c3948,3956
<  	if ((ctx->major = gss_display_name(&ctx->minor, ctx->client,
<  	    &client->displayname, NULL))) {
<  		ssh_gssapi_error(ctx);
< @@ -282,9 +399,15 @@
<  		return (ctx->major);
<  	}
<  
< +	gss_release_buffer(&ctx->minor, &ename);
---
> +		if test -e ${withval}/libgssapi.a ; then
> +		    mechglue_lib=${withval}/libgssapi.a
> +		elif test -e ${withval}/lib/libgssapi.a ; then
> +		    mechglue_lib=${withval}/lib/libgssapi.a
> +		else
> +		    AC_MSG_ERROR("Can't find libgssapi in ${withval}");
> +		fi
> +		LIBS="${mechglue_lib} $LIBS"
> +		AC_MSG_RESULT(${mechglue_lib})
3640,3642c3958,3961
<  	/* 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;
---
> +		AC_CHECK_LIB(dl, dlopen, , )
> +		if test $ac_cv_lib_dl_dlopen = yes; then
> +		   LDFLAGS="$LDFLAGS -ldl -Wl,-Bsymbolic"
> +		fi
3644,3645c3963,3967
< +    /* needed for globus_gss_assist_map_and_authorize() */
< +    client->context = ctx->context;
---
> +		AC_DEFINE(GSSAPI)
> +		AC_DEFINE(MECHGLUE, 1, [Define this if you're building with GSSAPI MechGlue.])
> +		GSSAPI="mechglue"
> +	]
> +)
3647,3663c3969,3975
<  	return (ctx->major);
<  }
<  
< @@ -305,6 +428,11 @@
<  ssh_gssapi_storecreds(void)
<  {
<  	if (gssapi_client.mech && gssapi_client.mech->storecreds) {
< +        if (options.gss_creds_path) {
< +            gssapi_client.store.filename =
< +                expand_authorized_keys(options.gss_creds_path,
< +                                       the_authctxt->pw);
< +        }
<  		(*gssapi_client.mech->storecreds)(&gssapi_client);
<  	} else
<  		debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
< @@ -328,8 +456,9 @@
<  }
---
> +
>  # Check whether user wants Kerberos 5 support
>  KRB5_MSG="no"
>  AC_ARG_WITH([kerberos5],
> @@ -3580,7 +3802,21 @@
>  			AC_CHECK_HEADER([gssapi_krb5.h], ,
>  					[ CPPFLAGS="$oldCPP" ])
3665,3671c3977,3998
<  /* Privileged */
< +/* gssapi_keyex arg added for Globus usage */
<  int
< -ssh_gssapi_userok(char *user)
< +ssh_gssapi_userok(char *user, struct passwd *pw, int gssapi_keyex)
<  {
<  	OM_uint32 lmin;
---
> -		fi
> +			# If we're using some other GSSAPI
> +			if test "$GSSAPI" -a "$GSSAPI" != "mechglue"; then
> +				AC_MSG_ERROR([$GSSAPI GSSAPI library conflicts with Kerberos support.  Use mechglue instead.])
> +			fi
> +
> +			if test -z "$GSSAPI"; then
> +				GSSAPI="KRB5";
> +			fi
> +
> +			oldCPP="$CPPFLAGS"
> +			CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
> +			AC_CHECK_HEADER(gssapi_krb5.h, ,
> +					[ CPPFLAGS="$oldCPP" ])
> +
> +                fi
>  		if test ! -z "$need_dash_r" ; then
>  			LDFLAGS="$LDFLAGS -R${KRB5ROOT}/lib"
>  		fi
> @@ -3599,6 +3835,42 @@
>  	]
>  )
3673,3702c4000,4005
< @@ -338,10 +467,18 @@
<  		debug("No suitable client data");
<  		return 0;
<  	}
< +#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG
< +	if (limited && options.gsi_allow_limited_proxy != 1) {
< +		debug("limited proxy not acceptable for remote login");
< +		return 0;
< +	}
< +#endif
<  	if (gssapi_client.mech && gssapi_client.mech->userok)
< -		if ((*gssapi_client.mech->userok)(&gssapi_client, user))
< +		if ((*gssapi_client.mech->userok)(&gssapi_client, user)) {
< +			gssapi_client.used = 1;
< +			gssapi_client.store.owner = pw;
<  			return 1;
< -		else {
< +		} else {
<  			/* Destroy delegated credentials if userok fails */
<  			gss_release_buffer(&lmin, &gssapi_client.displayname);
<  			gss_release_buffer(&lmin, &gssapi_client.exportedname);
< @@ -354,14 +491,133 @@
<  	return (0);
<  }
<  
< -/* Privileged */
< -OM_uint32
< -ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
< +/* ssh_gssapi_checkmic() moved to gss-genr.c so it can be called by
< +   kexgss_client(). */
---
> +# Check whether user wants AFS_KRB5 support
> +AFS_KRB5_MSG="no"
> +AC_ARG_WITH(afs-krb5,
> +	[  --with-afs-krb5[[=AKLOG_PATH]]  Enable aklog to get token (default=/usr/bin/aklog).],
> +	[
> +		if test "x$withval" != "xno" ; then
3704,3720c4007,4014
< +/* Priviledged */
< +int
< +ssh_gssapi_localname(char **user)
< +{
< +    	*user = NULL;
< +	if (gssapi_client.displayname.length==0 || 
< +	    gssapi_client.displayname.value==NULL) {
< +		debug("No suitable client data");
< +		return(0);;
< +	}
< +	if (gssapi_client.mech && gssapi_client.mech->localname) {
< +		return((*gssapi_client.mech->localname)(&gssapi_client,user));
< +	} else {
< +		debug("Unknown client authentication type");
< +	}
< +	return(0);
< +}
---
> +			if test "x$withval" != "xyes" ; then
> +				AC_DEFINE_UNQUOTED(AKLOG_PATH, "$withval",
> +					[Define this if you want to use AFS/Kerberos 5 option, which runs aklog.])
> +			else
> +				AC_DEFINE_UNQUOTED(AKLOG_PATH,
> +					"/usr/bin/aklog",
> +					[Define this if you want to use AFS/Kerberos 5 option, which runs aklog.])
> +			fi
3722,3728c4016,4018
< +/* These bits are only used for rekeying. The unpriviledged child is running 
< + * as the user, the monitor is root.
< + *
< + * In the child, we want to :
< + *    *) Ask the monitor to store our credentials into the store we specify
< + *    *) If it succeeds, maybe do a PAM update
< + */
---
> +			if test -z "$KRB5ROOT" ; then
> +				AC_MSG_WARN([AFS_KRB5 requires Kerberos 5 support, build may fail])
> +			fi
3730c4020,4029
< +/* Stuff for PAM */
---
> +			LIBS="-lkrbafs -lkrb4 $LIBS"
> +			if test ! -z "$AFS_LIBS" ; then
> +				LIBS="$LIBS $AFS_LIBS"
> +			fi
> +			AC_DEFINE(AFS_KRB5, 1,
> +				[Define this if you want to use AFS/Kerberos 5 option, which runs aklog.])
> +			AFS_KRB5_MSG="yes"
> +		fi
> +	]
> +)
3732,3740c4031,4036
< +#ifdef USE_PAM
< +static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, 
< +    struct pam_response **resp, void *data)
<  {
< -	ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
< -	    gssbuf, gssmic, NULL);
< +	return (PAM_CONV_ERR);
< +}
< +#endif
---
> +AC_ARG_WITH(session-hooks,
> +        [  --with-session-hooks    Enable hooks for executing external commands                                       before/after a session],
> +        [ AC_DEFINE(SESSION_HOOKS, 1, [Define this if you want support for startup/shutdown hooks]) ]
> +)
> +
>  # Looking for programs, paths and files
3742,3752c4038,4069
< -	return (ctx->major);
< +void
< +ssh_gssapi_rekey_creds() {
< +	int ok;
< +#ifdef USE_PAM
< +	int ret;
< +	pam_handle_t *pamh = NULL;
< +	struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL};
< +	char *envstr;
< +	char **p;char **pw;
< +#endif
---
>  PRIVSEP_PATH=/var/empty
> @@ -3634,7 +3906,10 @@
>  	]
>  )
>  
> +# strip causes problems with GSI libraries...
> +if test -z "$GLOBUS_LDFLAGS" ; then
>  STRIP_OPT=-s
> +fi
>  AC_ARG_ENABLE([strip],
>  	[  --disable-strip         Disable calling strip(1) on install],
>  	[
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/configure.ac.orig openssh-6.0p1/configure.ac.orig
> --- openssh-6.0p1.orig/configure.ac.orig	2012-07-12 17:00:51.510243708 +0200
> +++ openssh-6.0p1/configure.ac.orig	2012-07-12 16:59:34.500736911 +0200
> @@ -3479,6 +3479,20 @@
>  AC_SUBST([SSHLIBS])
>  AC_SUBST([SSHDLIBS])
>  
> +# Check whether user wants Linux audit support
> +LINUX_AUDIT_MSG="no"
> +LIBAUDIT=""
> +AC_ARG_WITH([linux-audit],
> +	[  --with-linux-audit   Enable Linux audit support],
> +	[ if test "x$withval" != "xno" ; then
> +		AC_DEFINE([HAVE_LINUX_AUDIT],[1],[Define if you want Linux audit support.])
> +		LINUX_AUDIT_MSG="yes"
> +		AC_CHECK_HEADERS([libaudit.h])
> +		LIBAUDIT="-laudit"
> +	fi
> +	])
> +AC_SUBST([LIBAUDIT])
3754,3759c4071,4113
< +	if (gssapi_client.store.filename == NULL && 
< +	    gssapi_client.store.envval == NULL &&
< +	    gssapi_client.store.envvar == NULL)
< +		return;
< + 
< +	ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store));
---
>  # Check whether user wants Kerberos 5 support
>  KRB5_MSG="no"
>  AC_ARG_WITH([kerberos5],
> @@ -4338,6 +4352,7 @@
>  echo "                   OSF SIA support: $SIA_MSG"
>  echo "                 KerberosV support: $KRB5_MSG"
>  echo "                   SELinux support: $SELINUX_MSG"
> +echo "               Linux audit support: $LINUX_AUDIT_MSG"
>  echo "                 Smartcard support: $SCARD_MSG"
>  echo "                     S/KEY support: $SKEY_MSG"
>  echo "              TCP Wrappers support: $TCPW_MSG"
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/gss-genr.c openssh-6.0p1/gss-genr.c
> --- openssh-6.0p1.orig/gss-genr.c	2012-07-12 17:00:49.270199878 +0200
> +++ openssh-6.0p1/gss-genr.c	2012-07-12 17:01:14.226688193 +0200
> @@ -1,7 +1,7 @@
>  /* $OpenBSD: gss-genr.c,v 1.20 2009/06/22 05:39:28 dtucker Exp $ */
>  
>  /*
> - * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
> + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
>   *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions
> @@ -38,13 +38,169 @@
>  #include "xmalloc.h"
>  #include "buffer.h"
>  #include "log.h"
> +#include "canohost.h"
>  #include "ssh2.h"
> +#include "cipher.h"
> +#include "key.h"
> +#include "kex.h"
> +#include <openssl/evp.h>
>  
>  #include "ssh-gss.h"
>  
>  extern u_char *session_id2;
>  extern u_int session_id2_len;
>  
> +typedef struct {
> +	char *encoded;
> +	gss_OID oid;
> +} ssh_gss_kex_mapping;
3761,3762c4115,4118
< +	if (!ok)
< +		return;
---
> +/*
> + * XXX - It would be nice to find a more elegant way of handling the
> + * XXX   passing of the key exchange context to the userauth routines
> + */
3764c4120
< +	debug("Rekeyed credentials stored successfully");
---
> +Gssctxt *gss_kex_context = NULL;
3766,3774c4122
< +	/* Actually managing to play with the ssh pam stack from here will
< +	 * be next to impossible. In any case, we may want different options
< +	 * for rekeying. So, use our own :)
< +	 */
< +#ifdef USE_PAM	
< +	if (!use_privsep) {
< +		debug("Not even going to try and do PAM with privsep disabled");
< +		return;
< +	}
---
> +static ssh_gss_kex_mapping *gss_enc2oid = NULL;
3776,3779c4124,4127
< +	ret = pam_start("sshd-rekey", gssapi_client.store.owner->pw_name,
< + 	    &pamconv, &pamh);
< +	if (ret)
< +		return;
---
> +int 
> +ssh_gssapi_oid_table_ok() {
> +	return (gss_enc2oid != NULL);
> +}
3781,3791c4129,4134
< +	/* Put ssh pam stack env variables in this new pam stack env 
< +	 * Using pam-pkinit, KRB5CCNAME is set during do_pam_session
< +	 * this addition enables pam-pkinit to access KRB5CCNAME if used 
< +	 * in sshd-rekey stack too
< +	 */
< +	pw = p = fetch_pam_environment();
< +	while ( *pw != NULL ) {
< +	        pam_putenv(pamh,*pw);
< +		pw++;
< +	}
< +	free_pam_environment(p);
---
> +/*
> + * Return a list of the gss-group1-sha1 mechanisms supported by this program
> + *
> + * We test mechanisms to ensure that we can use them, to avoid starting
> + * a key exchange with a bad mechanism
> + */
3793,3794c4136,4139
< +	xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, 
< +	    gssapi_client.store.envval);
---
> +char *
> +ssh_gssapi_client_mechanisms(const char *host, const char *client) {
> +	gss_OID_set gss_supported;
> +	OM_uint32 min_status;
3796,3801c4141,4142
< +	ret = pam_putenv(pamh, envstr);
< +	if (!ret)
< +		pam_setcred(pamh, PAM_REINITIALIZE_CRED);
< +	pam_end(pamh, PAM_SUCCESS);
< +#endif
< +}
---
> +	if (GSS_ERROR(gss_indicate_mechs(&min_status, &gss_supported)))
> +		return NULL;
3803,3805c4144,4146
< +int 
< +ssh_gssapi_update_creds(ssh_gssapi_ccache *store) {
< +	int ok = 0;
---
> +	return(ssh_gssapi_kex_mechs(gss_supported, ssh_gssapi_check_mechanism,
> +	    host, client));
> +}
3807,3809c4148,4158
< +	/* Check we've got credentials to store */
< +	if (!gssapi_client.updated)
< +		return 0;
---
> +char *
> +ssh_gssapi_kex_mechs(gss_OID_set gss_supported, ssh_gssapi_check_fn *check,
> +    const char *host, const char *client) {
> +	Buffer buf;
> +	size_t i;
> +	int oidpos, enclen;
> +	char *mechs, *encoded;
> +	u_char digest[EVP_MAX_MD_SIZE];
> +	char deroid[2];
> +	const EVP_MD *evp_md = EVP_md5();
> +	EVP_MD_CTX md;
3811c4160,4164
< +	gssapi_client.updated = 0;
---
> +	if (gss_enc2oid != NULL) {
> +		for (i = 0; gss_enc2oid[i].encoded != NULL; i++)
> +			xfree(gss_enc2oid[i].encoded);
> +		xfree(gss_enc2oid);
> +	}
3813,3817c4166,4167
< +	temporarily_use_uid(gssapi_client.store.owner);
< +	if (gssapi_client.mech && gssapi_client.mech->updatecreds)
< +		ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client);
< +	else
< +		debug("No update function for this mechanism");
---
> +	gss_enc2oid = xmalloc(sizeof(ssh_gss_kex_mapping) *
> +	    (gss_supported->count + 1));
3819c4169
< +	restore_uid();
---
> +	buffer_init(&buf);
3821,3822c4171,4174
< +	return ok;
< +}
---
> +	oidpos = 0;
> +	for (i = 0; i < gss_supported->count; i++) {
> +		if (gss_supported->elements[i].length < 128 &&
> +		    (*check)(NULL, &(gss_supported->elements[i]), host, client)) {
3824,3827c4176,4177
< +/* added for Globus usage */
< +void
< +ssh_gssapi_get_client_info(char **userdn, char **mech) {
< +	*userdn = gssapi_client.displayname.value;
---
> +			deroid[0] = SSH_GSS_OIDTYPE;
> +			deroid[1] = gss_supported->elements[i].length;
3829,3841c4179,4184
< +	if (gssapi_client.mech)
< +		*mech = gssapi_client.mech->name;
<  }
<  
<  #endif
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/kex.c openssh-6.0p1/kex.c
< --- openssh-6.0p1.orig/kex.c	2010-09-24 07:11:14.000000000 -0500
< +++ openssh-6.0p1/kex.c	2012-05-27 17:50:01.000000000 -0500
< @@ -49,6 +49,11 @@
<  #include "dispatch.h"
<  #include "monitor.h"
<  #include "roaming.h"
< +#include "canohost.h"
---
> +			EVP_DigestInit(&md, evp_md);
> +			EVP_DigestUpdate(&md, deroid, 2);
> +			EVP_DigestUpdate(&md,
> +			    gss_supported->elements[i].elements,
> +			    gss_supported->elements[i].length);
> +			EVP_DigestFinal(&md, digest, NULL);
3843,3884c4186,4188
< +#ifdef GSSAPI
< +#include "ssh-gss.h"
< +#endif
<  
<  #if OPENSSL_VERSION_NUMBER >= 0x00907000L
<  # if defined(HAVE_EVP_SHA256)
< @@ -91,7 +96,8 @@
<  }
<  
<  /* put algorithm proposal into buffer */
< -static void
< +/* used in sshconnect.c as well as kex.c */
< +void
<  kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
<  {
<  	u_int i;
< @@ -358,6 +364,20 @@
<   		k->kex_type = KEX_ECDH_SHA2;
<  		k->evp_md = kex_ecdh_name_to_evpmd(k->name);
<  #endif
< +#ifdef GSSAPI
< +	} else if (strncmp(k->name, KEX_GSS_GEX_SHA1_ID,
< +	    sizeof(KEX_GSS_GEX_SHA1_ID) - 1) == 0) {
< +		k->kex_type = KEX_GSS_GEX_SHA1;
< +		k->evp_md = EVP_sha1();
< +	} else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID,
< +	    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1) == 0) {
< +		k->kex_type = KEX_GSS_GRP1_SHA1;
< +		k->evp_md = EVP_sha1();
< +	} else if (strncmp(k->name, KEX_GSS_GRP14_SHA1_ID,
< +	    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1) == 0) {
< +		k->kex_type = KEX_GSS_GRP14_SHA1;
< +		k->evp_md = EVP_sha1();
< +#endif
<  	} else
<  		fatal("bad kex alg %s", k->name);
<  }
< @@ -407,6 +427,13 @@
<  	int nenc, nmac, ncomp;
<  	u_int mode, ctos, need;
<  	int first_kex_follows, type;
< +	int log_flag = 0;
---
> +			encoded = xmalloc(EVP_MD_size(evp_md) * 2);
> +			enclen = __b64_ntop(digest, EVP_MD_size(evp_md),
> +			    encoded, EVP_MD_size(evp_md) * 2);
3886c4190,4191
< +	int auth_flag;
---
> +			if (oidpos != 0)
> +				buffer_put_char(&buf, ',');
3888c4193,4203
< +	auth_flag = packet_authentication_state();
---
> +			buffer_append(&buf, KEX_GSS_GEX_SHA1_ID,
> +			    sizeof(KEX_GSS_GEX_SHA1_ID) - 1);
> +			buffer_append(&buf, encoded, enclen);
> +			buffer_put_char(&buf, ',');
> +			buffer_append(&buf, KEX_GSS_GRP1_SHA1_ID, 
> +			    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1);
> +			buffer_append(&buf, encoded, enclen);
> +			buffer_put_char(&buf, ',');
> +			buffer_append(&buf, KEX_GSS_GRP14_SHA1_ID,
> +			    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1);
> +			buffer_append(&buf, encoded, enclen);
3890,3923c4205,4207
< +	debug ("AUTH STATE IS %d", auth_flag);
<  
<  	my   = kex_buf2prop(&kex->my, NULL);
<  	peer = kex_buf2prop(&kex->peer, &first_kex_follows);
< @@ -441,11 +468,34 @@
<  		choose_enc (&newkeys->enc,  cprop[nenc],  sprop[nenc]);
<  		choose_mac (&newkeys->mac,  cprop[nmac],  sprop[nmac]);
<  		choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]);
< +		debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name);
< +		if (strcmp(newkeys->enc.name, "none") == 0) {
< +				debug("Requesting NONE. Authflag is %d", auth_flag);			
< +			if (auth_flag == 1) {
< +				debug("None requested post authentication.");
< +			} else {
< +				fatal("Pre-authentication none cipher requests are not allowed.");
< +			}
< +		} 
<  		debug("kex: %s %s %s %s",
<  		    ctos ? "client->server" : "server->client",
<  		    newkeys->enc.name,
<  		    newkeys->mac.name,
<  		    newkeys->comp.name);
< +		/* client starts withctos = 0 && log flag = 0 and no log*/
< +		/* 2nd client pass ctos=1 and flag = 1 so no log*/
< +		/* server starts with ctos =1 && log_flag = 0 so log */
< +		/* 2nd sever pass ctos = 1 && log flag = 1 so no log*/
< +		/* -cjr*/
< +		if (ctos && !log_flag) {
< +			logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s",
< +			      get_remote_ipaddr(),
< +			      get_remote_port(),
< +			      newkeys->enc.name,
< +			      newkeys->mac.name,
< +			      newkeys->comp.name);
---
> +			gss_enc2oid[oidpos].oid = &(gss_supported->elements[i]);
> +			gss_enc2oid[oidpos].encoded = encoded;
> +			oidpos++;
3925,4007c4209,4211
< +		log_flag = 1;
<  	}
<  	choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
<  	choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/kex.h openssh-6.0p1/kex.h
< --- openssh-6.0p1.orig/kex.h	2010-09-24 07:11:14.000000000 -0500
< +++ openssh-6.0p1/kex.h	2012-05-27 17:50:01.000000000 -0500
< @@ -73,6 +73,9 @@
<  	KEX_DH_GEX_SHA1,
<  	KEX_DH_GEX_SHA256,
<  	KEX_ECDH_SHA2,
< +	KEX_GSS_GRP1_SHA1,
< +	KEX_GSS_GRP14_SHA1,
< +	KEX_GSS_GEX_SHA1,
<  	KEX_MAX
<  };
<  
< @@ -129,6 +132,12 @@
<  	sig_atomic_t done;
<  	int	flags;
<  	const EVP_MD *evp_md;
< +#ifdef GSSAPI
< +	int	gss_deleg_creds;
< +	int	gss_trust_dns;
< +	char    *gss_host;
< +	char	*gss_client;
< +#endif
<  	char	*client_version_string;
<  	char	*server_version_string;
<  	int	(*verify_host_key)(Key *);
< @@ -140,6 +149,8 @@
<  
<  int	 kex_names_valid(const char *);
<  
< +void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]);
< +
<  Kex	*kex_setup(char *[PROPOSAL_MAX]);
<  void	 kex_finish(Kex *);
<  
< @@ -156,6 +167,16 @@
<  void	 kexecdh_client(Kex *);
<  void	 kexecdh_server(Kex *);
<  
< +#ifdef GSSAPI
< +void	kexgss_client(Kex *);
< +void	kexgss_server(Kex *);
< +#endif
< +
< +#ifdef GSSAPI
< +void	kexgss_client(Kex *);
< +void	kexgss_server(Kex *);
< +#endif
< +
<  void
<  kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
<      BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/kexgssc.c openssh-6.0p1/kexgssc.c
< --- openssh-6.0p1.orig/kexgssc.c	1969-12-31 18:00:00.000000000 -0600
< +++ openssh-6.0p1/kexgssc.c	2012-05-27 17:50:01.000000000 -0500
< @@ -0,0 +1,334 @@
< +/*
< + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
< + *
< + * Redistribution and use in source and binary forms, with or without
< + * modification, are permitted provided that the following conditions
< + * are met:
< + * 1. Redistributions of source code must retain the above copyright
< + *    notice, this list of conditions and the following disclaimer.
< + * 2. Redistributions in binary form must reproduce the above copyright
< + *    notice, this list of conditions and the following disclaimer in the
< + *    documentation and/or other materials provided with the distribution.
< + *
< + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
< + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
< + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
< + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
< + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
< + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
< + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
< + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
< + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
< + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
< + */
---
> +	}
> +	gss_enc2oid[oidpos].oid = NULL;
> +	gss_enc2oid[oidpos].encoded = NULL;
4009c4213
< +#include "includes.h"
---
> +	buffer_put_char(&buf, '\0');
4011c4215,4217
< +#ifdef GSSAPI
---
> +	mechs = xmalloc(buffer_len(&buf));
> +	buffer_get(&buf, mechs, buffer_len(&buf));
> +	buffer_free(&buf);
4013c4219,4225
< +#include "includes.h"
---
> +	if (strlen(mechs) == 0) {
> +		xfree(mechs);
> +		mechs = NULL;
> +	}
> +	
> +	return (mechs);
> +}
4015,4016c4227,4249
< +#include <openssl/crypto.h>
< +#include <openssl/bn.h>
---
> +gss_OID
> +ssh_gssapi_id_kex(Gssctxt *ctx, char *name, int kex_type) {
> +	int i = 0;
> +	
> +	switch (kex_type) {
> +	case KEX_GSS_GRP1_SHA1:
> +		if (strlen(name) < sizeof(KEX_GSS_GRP1_SHA1_ID))
> +			return GSS_C_NO_OID;
> +		name += sizeof(KEX_GSS_GRP1_SHA1_ID) - 1;
> +		break;
> +	case KEX_GSS_GRP14_SHA1:
> +		if (strlen(name) < sizeof(KEX_GSS_GRP14_SHA1_ID))
> +			return GSS_C_NO_OID;
> +		name += sizeof(KEX_GSS_GRP14_SHA1_ID) - 1;
> +		break;
> +	case KEX_GSS_GEX_SHA1:
> +		if (strlen(name) < sizeof(KEX_GSS_GEX_SHA1_ID))
> +			return GSS_C_NO_OID;
> +		name += sizeof(KEX_GSS_GEX_SHA1_ID) - 1;
> +		break;
> +	default:
> +		return GSS_C_NO_OID;
> +	}
4018c4251,4253
< +#include <string.h>
---
> +	while (gss_enc2oid[i].encoded != NULL &&
> +	    strcmp(name, gss_enc2oid[i].encoded) != 0)
> +		i++;
4020,4028c4255,4256
< +#include "xmalloc.h"
< +#include "buffer.h"
< +#include "ssh2.h"
< +#include "key.h"
< +#include "cipher.h"
< +#include "kex.h"
< +#include "log.h"
< +#include "packet.h"
< +#include "dh.h"
---
> +	if (gss_enc2oid[i].oid != NULL && ctx != NULL)
> +		ssh_gssapi_set_oid(ctx, gss_enc2oid[i].oid);
4030c4258,4259
< +#include "ssh-gss.h"
---
> +	return gss_enc2oid[i].oid;
> +}
4032,4060c4261,4305
< +void
< +kexgss_client(Kex *kex) {
< +	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
< +	gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr;
< +	Gssctxt *ctxt;
< +	OM_uint32 maj_status, min_status, ret_flags;
< +	u_int klen, kout, slen = 0, hashlen, strlen;
< +	DH *dh; 
< +	BIGNUM *dh_server_pub = NULL;
< +	BIGNUM *shared_secret = NULL;
< +	BIGNUM *p = NULL;
< +	BIGNUM *g = NULL;	
< +	u_char *kbuf, *hash;
< +	u_char *serverhostkey = NULL;
< +	u_char *empty = "";
< +	char *msg;
< +	char *lang;
< +	int type = 0;
< +	int first = 1;
< +	int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX;
< +
< +	/* Initialise our GSSAPI world */	
< +	ssh_gssapi_build_ctx(&ctxt);
< +	if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) 
< +	    == GSS_C_NO_OID)
< +		fatal("Couldn't identify host exchange");
< +
< +	if (ssh_gssapi_import_name(ctxt, kex->gss_host))
< +		fatal("Couldn't import hostname");
---
>  /* Check that the OID in a data stream matches that in the context */
>  int
>  ssh_gssapi_check_oid(Gssctxt *ctx, void *data, size_t len)
> @@ -155,10 +311,13 @@
>  void
>  ssh_gssapi_delete_ctx(Gssctxt **ctx)
>  {
> +#if !defined(MECHGLUE)
>  	OM_uint32 ms;
> +#endif
>  
>  	if ((*ctx) == NULL)
>  		return;
> +#if !defined(MECHGLUE) /* mechglue has some memory management issues */
>  	if ((*ctx)->context != GSS_C_NO_CONTEXT)
>  		gss_delete_sec_context(&ms, &(*ctx)->context, GSS_C_NO_BUFFER);
>  	if ((*ctx)->name != GSS_C_NO_NAME)
> @@ -174,6 +333,7 @@
>  		gss_release_name(&ms, &(*ctx)->client);
>  	if ((*ctx)->client_creds != GSS_C_NO_CREDENTIAL)
>  		gss_release_cred(&ms, &(*ctx)->client_creds);
> +#endif
>  
>  	xfree(*ctx);
>  	*ctx = NULL;
> @@ -197,7 +357,7 @@
>  	}
>  
>  	ctx->major = gss_init_sec_context(&ctx->minor,
> -	    GSS_C_NO_CREDENTIAL, &ctx->context, ctx->name, ctx->oid,
> +	    ctx->client_creds, &ctx->context, ctx->name, ctx->oid,
>  	    GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG | deleg_flag,
>  	    0, NULL, recv_tok, NULL, send_tok, flags, NULL);
>  
> @@ -212,9 +372,18 @@
>  ssh_gssapi_import_name(Gssctxt *ctx, const char *host)
>  {
>  	gss_buffer_desc gssbuf;
> +	char *xhost;
>  	char *val;
>  
> -	xasprintf(&val, "host@%s", host);
> +	/* Make a copy of the host name, in case it was returned by a
> +	 * previous call to gethostbyname(). */	
> +	xhost = xstrdup(host);
4062,4064c4307,4330
< +	if (kex->gss_client && 
< +	    ssh_gssapi_client_identity(ctxt, kex->gss_client))
< +		fatal("Couldn't acquire client credentials");
---
> +	/* Make sure we have the FQDN. Some GSSAPI implementations don't do
> +	 * this for us themselves */
> +	resolve_localhost(&xhost);
> +	
> +	xasprintf(&val, "host@%s", xhost);
>  	gssbuf.value = val;
>  	gssbuf.length = strlen(gssbuf.value);
>  
> @@ -222,13 +391,48 @@
>  	    &gssbuf, GSS_C_NT_HOSTBASED_SERVICE, &ctx->name)))
>  		ssh_gssapi_error(ctx);
>  
> +	xfree(xhost);
>  	xfree(gssbuf.value);
>  	return (ctx->major);
>  }
>  
>  OM_uint32
> +ssh_gssapi_client_identity(Gssctxt *ctx, const char *name)
> +{
> +	gss_buffer_desc gssbuf;
> +	gss_name_t gssname;
> +	OM_uint32 status;
> +	gss_OID_set oidset;
4066,4079c4332,4333
< +	switch (kex->kex_type) {
< +	case KEX_GSS_GRP1_SHA1:
< +		dh = dh_new_group1();
< +		break;
< +	case KEX_GSS_GRP14_SHA1:
< +		dh = dh_new_group14();
< +		break;
< +	case KEX_GSS_GEX_SHA1:
< +		debug("Doing group exchange\n");
< +		nbits = dh_estimate(kex->we_need * 8);
< +		packet_start(SSH2_MSG_KEXGSS_GROUPREQ);
< +		packet_put_int(min);
< +		packet_put_int(nbits);
< +		packet_put_int(max);
---
> +	gssbuf.value = (void *) name;
> +	gssbuf.length = strlen(gssbuf.value);
4081c4335,4336
< +		packet_send();
---
> +	gss_create_empty_oid_set(&status, &oidset);
> +	gss_add_oid_set_member(&status, ctx->oid, &oidset);
4083c4338,4339
< +		packet_read_expect(SSH2_MSG_KEXGSS_GROUP);
---
> +	ctx->major = gss_import_name(&ctx->minor, &gssbuf,
> +	    GSS_C_NT_USER_NAME, &gssname);
4085,4091c4341,4344
< +		if ((p = BN_new()) == NULL)
< +			fatal("BN_new() failed");
< +		packet_get_bignum2(p);
< +		if ((g = BN_new()) == NULL)
< +			fatal("BN_new() failed");
< +		packet_get_bignum2(g);
< +		packet_check_eom();
---
> +	if (!ctx->major)
> +		ctx->major = gss_acquire_cred(&ctx->minor, 
> +		    gssname, 0, oidset, GSS_C_INITIATE, 
> +		    &ctx->client_creds, NULL, NULL);
4093,4095c4346,4347
< +		if (BN_num_bits(p) < min || BN_num_bits(p) > max)
< +			fatal("GSSGRP_GEX group out of range: %d !< %d !< %d",
< +			    min, BN_num_bits(p), max);
---
> +	gss_release_name(&status, &gssname);
> +	gss_release_oid_set(&status, &oidset);
4097,4104c4349,4350
< +		dh = dh_new_group(g, p);
< +		break;
< +	default:
< +		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
< +	}
< +	
< +	/* Step 1 - e is dh->pub_key */
< +	dh_gen_key(dh, kex->we_need * 8);
---
> +	if (ctx->major)
> +		ssh_gssapi_error(ctx);
4106,4109c4352,4353
< +	/* This is f, we initialise it now to make life easier */
< +	dh_server_pub = BN_new();
< +	if (dh_server_pub == NULL)
< +		fatal("dh_server_pub == NULL");
---
> +	return(ctx->major);
> +}
4111,4118c4355,4359
< +	token_ptr = GSS_C_NO_BUFFER;
< +			 
< +	do {
< +		debug("Calling gss_init_sec_context");
< +		
< +		maj_status = ssh_gssapi_init_ctx(ctxt,
< +		    kex->gss_deleg_creds, token_ptr, &send_tok,
< +		    &ret_flags);
---
> +OM_uint32
>  ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_t buffer, gss_buffer_t hash)
>  {
> +	if (ctx == NULL) 
> +		return -1;
4120,4127c4361,4373
< +		if (GSS_ERROR(maj_status)) {
< +			if (send_tok.length != 0) {
< +				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
< +				packet_put_string(send_tok.value,
< +				    send_tok.length);
< +			}
< +			fatal("gss_init_context failed");
< +		}
---
>  	if ((ctx->major = gss_get_mic(&ctx->minor, ctx->context,
>  	    GSS_C_QOP_DEFAULT, buffer, hash)))
>  		ssh_gssapi_error(ctx);
> @@ -236,6 +440,19 @@
>  	return (ctx->major);
>  }
>  
> +/* Priviledged when used by server */
> +OM_uint32
> +ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
> +{
> +	if (ctx == NULL)
> +		return -1;
4129,4131c4375,4376
< +		/* If we've got an old receive buffer get rid of it */
< +		if (token_ptr != GSS_C_NO_BUFFER)
< +			xfree(recv_tok.value);
---
> +	ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
> +	    gssbuf, gssmic, NULL);
4133,4136c4378,4379
< +		if (maj_status == GSS_S_COMPLETE) {
< +			/* If mutual state flag is not true, kex fails */
< +			if (!(ret_flags & GSS_C_MUTUAL_FLAG))
< +				fatal("Mutual authentication failed");
---
> +	return (ctx->major);
> +}
4138,4141c4381,4395
< +			/* If integ avail flag is not true kex fails */
< +			if (!(ret_flags & GSS_C_INTEG_FLAG))
< +				fatal("Integrity check failed");
< +		}
---
>  void
>  ssh_gssapi_buildmic(Buffer *b, const char *user, const char *service,
>      const char *context)
> @@ -249,11 +466,16 @@
>  }
>  
>  int
> -ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host)
> +ssh_gssapi_check_mechanism(Gssctxt **ctx, gss_OID oid, const char *host, 
> +    const char *client)
>  {
>  	gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
>  	OM_uint32 major, minor;
>  	gss_OID_desc spnego_oid = {6, (void *)"\x2B\x06\x01\x05\x05\x02"};
> +	Gssctxt *intctx = NULL;
4143,4160c4397,4405
< +		/* 
< +		 * If we have data to send, then the last message that we
< +		 * received cannot have been a 'complete'. 
< +		 */
< +		if (send_tok.length != 0) {
< +			if (first) {
< +				packet_start(SSH2_MSG_KEXGSS_INIT);
< +				packet_put_string(send_tok.value,
< +				    send_tok.length);
< +				packet_put_bignum2(dh->pub_key);
< +				first = 0;
< +			} else {
< +				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
< +				packet_put_string(send_tok.value,
< +				    send_tok.length);
< +			}
< +			packet_send();
< +			gss_release_buffer(&min_status, &send_tok);
---
> +	if (ctx == NULL)
> +		ctx = &intctx;
>  
>  	/* RFC 4462 says we MUST NOT do SPNEGO */
>  	if (oid->length == spnego_oid.length && 
> @@ -263,6 +485,10 @@
>  	ssh_gssapi_build_ctx(ctx);
>  	ssh_gssapi_set_oid(*ctx, oid);
>  	major = ssh_gssapi_import_name(*ctx, host);
4162,4172c4407,4408
< +			/* If we've sent them data, they should reply */
< +			do {	
< +				type = packet_read();
< +				if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
< +					debug("Received KEXGSS_HOSTKEY");
< +					if (serverhostkey)
< +						fatal("Server host key received more than once");
< +					serverhostkey = 
< +					    packet_get_string(&slen);
< +				}
< +			} while (type == SSH2_MSG_KEXGSS_HOSTKEY);
---
> +	if (!GSS_ERROR(major) && client)
> +		major = ssh_gssapi_client_identity(*ctx, client);
4174,4238c4410,4434
< +			switch (type) {
< +			case SSH2_MSG_KEXGSS_CONTINUE:
< +				debug("Received GSSAPI_CONTINUE");
< +				if (maj_status == GSS_S_COMPLETE) 
< +					fatal("GSSAPI Continue received from server when complete");
< +				recv_tok.value = packet_get_string(&strlen);
< +				recv_tok.length = strlen; 
< +				break;
< +			case SSH2_MSG_KEXGSS_COMPLETE:
< +				debug("Received GSSAPI_COMPLETE");
< +				packet_get_bignum2(dh_server_pub);
< +				msg_tok.value =  packet_get_string(&strlen);
< +				msg_tok.length = strlen; 
< +
< +				/* Is there a token included? */
< +				if (packet_get_char()) {
< +					recv_tok.value=
< +					    packet_get_string(&strlen);
< +					recv_tok.length = strlen;
< +					/* If we're already complete - protocol error */
< +					if (maj_status == GSS_S_COMPLETE)
< +						packet_disconnect("Protocol error: received token when complete");
< +					} else {
< +						/* No token included */
< +						if (maj_status != GSS_S_COMPLETE)
< +							packet_disconnect("Protocol error: did not receive final token");
< +				}
< +				break;
< +			case SSH2_MSG_KEXGSS_ERROR:
< +				debug("Received Error");
< +				maj_status = packet_get_int();
< +				min_status = packet_get_int();
< +				msg = packet_get_string(NULL);
< +				lang = packet_get_string(NULL);
< +				fatal("GSSAPI Error: \n%.400s",msg);
< +			default:
< +				packet_disconnect("Protocol error: didn't expect packet type %d",
< +		    		type);
< +			}
< +			token_ptr = &recv_tok;
< +		} else {
< +			/* No data, and not complete */
< +			if (maj_status != GSS_S_COMPLETE)
< +				fatal("Not complete, and no token output");
< +		}
< +	} while (maj_status & GSS_S_CONTINUE_NEEDED);
< +
< +	/* 
< +	 * We _must_ have received a COMPLETE message in reply from the 
< +	 * server, which will have set dh_server_pub and msg_tok 
< +	 */
< +
< +	if (type != SSH2_MSG_KEXGSS_COMPLETE)
< +		fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it");
< +
< +	/* Check f in range [1, p-1] */
< +	if (!dh_pub_is_valid(dh, dh_server_pub))
< +		packet_disconnect("bad server public DH value");
< +
< +	/* compute K=f^x mod p */
< +	klen = DH_size(dh);
< +	kbuf = xmalloc(klen);
< +	kout = DH_compute_key(kbuf, dh_server_pub, dh);
< +	if (kout < 0)
< +		fatal("DH_compute_key: failed");
---
>  	if (!GSS_ERROR(major)) {
>  		major = ssh_gssapi_init_ctx(*ctx, 0, GSS_C_NO_BUFFER, &token, 
>  		    NULL);
> @@ -272,10 +498,66 @@
>  			    GSS_C_NO_BUFFER);
>  	}
>  
> -	if (GSS_ERROR(major)) 
> +	if (GSS_ERROR(major) || intctx != NULL) 
>  		ssh_gssapi_delete_ctx(ctx);
>  
>  	return (!GSS_ERROR(major));
>  }
>  
> +int
> +ssh_gssapi_credentials_updated(Gssctxt *ctxt) {
> +	static gss_name_t saved_name = GSS_C_NO_NAME;
> +	static OM_uint32 saved_lifetime = 0;
> +	static gss_OID saved_mech = GSS_C_NO_OID;
> +	static gss_name_t name;
> +	static OM_uint32 last_call = 0;
> +	OM_uint32 lifetime, now, major, minor;
> +	int equal;
> +	
> +	now = time(NULL);
4240,4242c4436,4437
< +	shared_secret = BN_new();
< +	if (shared_secret == NULL)
< +		fatal("kexgss_client: BN_new failed");
---
> +	if (ctxt) {
> +		debug("Rekey has happened - updating saved versions");
4244,4245c4439,4440
< +	if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
< +		fatal("kexdh_client: BN_bin2bn failed");
---
> +		if (saved_name != GSS_C_NO_NAME)
> +			gss_release_name(&minor, &saved_name);
4247,4248c4442,4443
< +	memset(kbuf, 0, klen);
< +	xfree(kbuf);
---
> +		major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL,
> +		    &saved_name, &saved_lifetime, NULL, NULL);
4250,4281c4445,4451
< +	switch (kex->kex_type) {
< +	case KEX_GSS_GRP1_SHA1:
< +	case KEX_GSS_GRP14_SHA1:
< +		kex_dh_hash( kex->client_version_string, 
< +		    kex->server_version_string,
< +		    buffer_ptr(&kex->my), buffer_len(&kex->my),
< +		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
< +		    (serverhostkey ? serverhostkey : empty), slen,
< +		    dh->pub_key,	/* e */
< +		    dh_server_pub,	/* f */
< +		    shared_secret,	/* K */
< +		    &hash, &hashlen
< +		);
< +		break;
< +	case KEX_GSS_GEX_SHA1:
< +		kexgex_hash(
< +		    kex->evp_md,
< +		    kex->client_version_string,
< +		    kex->server_version_string,
< +		    buffer_ptr(&kex->my), buffer_len(&kex->my),
< +		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
< +		    (serverhostkey ? serverhostkey : empty), slen,
< + 		    min, nbits, max,
< +		    dh->p, dh->g,
< +		    dh->pub_key,
< +		    dh_server_pub,
< +		    shared_secret,
< +		    &hash, &hashlen
< +		);
< +		break;
< +	default:
< +		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
---
> +		if (!GSS_ERROR(major)) {
> +			saved_mech = ctxt->oid;
> +		        saved_lifetime+= now;
> +		} else {
> +			/* Handle the error */
> +		}
> +		return 0;
4284,4291c4454,4455
< +	gssbuf.value = hash;
< +	gssbuf.length = hashlen;
< +
< +	/* Verify that the hash matches the MIC we just got. */
< +	if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok)))
< +		packet_disconnect("Hash's MIC didn't verify");
< +
< +	xfree(msg_tok.value);
---
> +	if (now - last_call < 10)
> +		return 0;
4293,4296c4457
< +	DH_free(dh);
< +	if (serverhostkey)
< +		xfree(serverhostkey);
< +	BN_clear_free(dh_server_pub);
---
> +	last_call = now;
4298,4303c4459,4467
< +	/* save session id */
< +	if (kex->session_id == NULL) {
< +		kex->session_id_len = hashlen;
< +		kex->session_id = xmalloc(kex->session_id_len);
< +		memcpy(kex->session_id, hash, kex->session_id_len);
< +	}
---
> +	if (saved_mech == GSS_C_NO_OID)
> +		return 0;
> +	
> +	major = gss_inquire_cred(&minor, GSS_C_NO_CREDENTIAL, 
> +	    &name, &lifetime, NULL, NULL);
> +	if (major == GSS_S_CREDENTIALS_EXPIRED)
> +		return 0;
> +	else if (GSS_ERROR(major))
> +		return 0;
4305,4306c4469,4472
< +	if (kex->gss_deleg_creds)
< +		ssh_gssapi_credentials_updated(ctxt);
---
> +	major = gss_compare_name(&minor, saved_name, name, &equal);
> +	gss_release_name(&minor, &name);
> +	if (GSS_ERROR(major))
> +		return 0;
4308,4311c4474,4475
< +	if (gss_kex_context == NULL)
< +		gss_kex_context = ctxt;
< +	else
< +		ssh_gssapi_delete_ctx(&ctxt);
---
> +	if (equal && (saved_lifetime < lifetime + now - 10))
> +		return 1;
4313,4315c4477
< +	kex_derive_keys(kex, hash, hashlen, shared_secret);
< +	BN_clear_free(shared_secret);
< +	kex_finish(kex);
---
> +	return 0;
4318,4323c4480,4488
< +#endif /* GSSAPI */
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/kexgsss.c openssh-6.0p1/kexgsss.c
< --- openssh-6.0p1.orig/kexgsss.c	1969-12-31 18:00:00.000000000 -0600
< +++ openssh-6.0p1/kexgsss.c	2012-05-27 17:50:01.000000000 -0500
< @@ -0,0 +1,311 @@
< +/*
---
>  #endif /* GSSAPI */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/gss-serv.c openssh-6.0p1/gss-serv.c
> --- openssh-6.0p1.orig/gss-serv.c	2012-07-12 17:00:49.282200113 +0200
> +++ openssh-6.0p1/gss-serv.c	2012-07-12 17:01:14.250688663 +0200
> @@ -1,7 +1,7 @@
>  /* $OpenBSD: gss-serv.c,v 1.23 2011/08/01 19:18:15 markus Exp $ */
>  
>  /*
> - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
4325,4355c4490,4499
< + *
< + * Redistribution and use in source and binary forms, with or without
< + * modification, are permitted provided that the following conditions
< + * are met:
< + * 1. Redistributions of source code must retain the above copyright
< + *    notice, this list of conditions and the following disclaimer.
< + * 2. Redistributions in binary form must reproduce the above copyright
< + *    notice, this list of conditions and the following disclaimer in the
< + *    documentation and/or other materials provided with the distribution.
< + *
< + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
< + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
< + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
< + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
< + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
< + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
< + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
< + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
< + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
< + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
< + */
< +
< +#include "includes.h"
< +
< +#ifdef GSSAPI
< +
< +#include <string.h>
< +
< +#include <openssl/crypto.h>
< +#include <openssl/bn.h>
< +
---
>   *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions
> @@ -45,27 +45,43 @@
>  #include "channels.h"
>  #include "session.h"
>  #include "misc.h"
> +#include "servconf.h"
> +#include "uidswap.h"
>  
4357,4365c4501
< +#include "buffer.h"
< +#include "ssh2.h"
< +#include "key.h"
< +#include "cipher.h"
< +#include "kex.h"
< +#include "log.h"
< +#include "packet.h"
< +#include "dh.h"
< +#include "ssh-gss.h"
---
>  #include "ssh-gss.h"
4367d4502
< +#include "servconf.h"
4369d4503
< +static void kex_gss_send_error(Gssctxt *ctxt);
4370a4505,4547
> +extern Authctxt *the_authctxt;
>  
>  static ssh_gssapi_client gssapi_client =
>      { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER,
> -    GSS_C_NO_CREDENTIAL, NULL, {NULL, NULL, NULL}};
> +    GSS_C_NO_CREDENTIAL, GSS_C_NO_NAME,  NULL, {NULL, NULL, NULL}, 0, 0};
>  
>  ssh_gssapi_mech gssapi_null_mech =
> -    { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL};
> +    { NULL, NULL, {0, NULL}, NULL, NULL, NULL, NULL, NULL};
>  
>  #ifdef KRB5
>  extern ssh_gssapi_mech gssapi_kerberos_mech;
>  #endif
> +#ifdef GSI
> +extern ssh_gssapi_mech gssapi_gsi_mech;
> +#endif
>  
>  ssh_gssapi_mech* supported_mechs[]= {
>  #ifdef KRB5
>  	&gssapi_kerberos_mech,
>  #endif
> +#ifdef GSI
> +	&gssapi_gsi_mech,
> +#endif
>  	&gssapi_null_mech,
>  };
>  
> +#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG
> +static int limited = 0;
> +#endif
>  
>  /*
>   * Acquire credentials for a server running on the current host.
> @@ -81,25 +97,32 @@
>  	char lname[MAXHOSTNAMELEN];
>  	gss_OID_set oidset;
>  
> -	gss_create_empty_oid_set(&status, &oidset);
> -	gss_add_oid_set_member(&status, ctx->oid, &oidset);
> +	if (options.gss_strict_acceptor) {
> +		gss_create_empty_oid_set(&status, &oidset);
> +		gss_add_oid_set_member(&status, ctx->oid, &oidset);
4372,4406c4549,4561
< +void
< +kexgss_server(Kex *kex)
< +{
< +	OM_uint32 maj_status, min_status;
< +	
< +	/* 
< +	 * Some GSSAPI implementations use the input value of ret_flags (an
< + 	 * output variable) as a means of triggering mechanism specific 
< + 	 * features. Initializing it to zero avoids inadvertently 
< + 	 * activating this non-standard behaviour.
< +	 */
< +
< +	OM_uint32 ret_flags = 0;
< +	gss_buffer_desc gssbuf, recv_tok, msg_tok;
< +	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
< +	Gssctxt *ctxt = NULL;
< +	u_int slen, klen, kout, hashlen;
< +	u_char *kbuf, *hash;
< +	DH *dh;
< +	int min = -1, max = -1, nbits = -1;
< +	BIGNUM *shared_secret = NULL;
< +	BIGNUM *dh_client_pub = NULL;
< +	int type = 0;
< +	gss_OID oid;
< +	char *mechs;
< +
< +	/* Initialise GSSAPI */
< +
< +	/* If we're rekeying, privsep means that some of the private structures
< +	 * in the GSSAPI code are no longer available. This kludges them back
< +	 * into life
< +	 */
< +	if (!ssh_gssapi_oid_table_ok()) 
< +		if ((mechs = ssh_gssapi_server_mechanisms()))
< +			xfree(mechs);
---
> +		if (gethostname(lname, MAXHOSTNAMELEN)) {
> +			gss_release_oid_set(&status, &oidset);
> +			return (-1);
> +		}
>  
> -	if (gethostname(lname, MAXHOSTNAMELEN)) {
> -		gss_release_oid_set(&status, &oidset);
> -		return (-1);
> -	}
> +		if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
> +			gss_release_oid_set(&status, &oidset);
> +			return (ctx->major);
> +		}
4408,4411c4563,4592
< +	debug2("%s: Identifying %s", __func__, kex->name);
< +	oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type);
< +	if (oid == GSS_C_NO_OID)
< +	   fatal("Unknown gssapi mechanism");
---
> +		if ((ctx->major = gss_acquire_cred(&ctx->minor,
> +		    ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, 
> +		    NULL, NULL)))
> +			ssh_gssapi_error(ctx);
>  
> -	if (GSS_ERROR(ssh_gssapi_import_name(ctx, lname))) {
>  		gss_release_oid_set(&status, &oidset);
>  		return (ctx->major);
> +	} else {
> +		ctx->name = GSS_C_NO_NAME;
> +		ctx->creds = GSS_C_NO_CREDENTIAL;
>  	}
> -
> -	if ((ctx->major = gss_acquire_cred(&ctx->minor,
> -	    ctx->name, 0, oidset, GSS_C_ACCEPT, &ctx->creds, NULL, NULL)))
> -		ssh_gssapi_error(ctx);
> -
> -	gss_release_oid_set(&status, &oidset);
> -	return (ctx->major);
> +	return GSS_S_COMPLETE;
>  }
>  
>  /* Privileged */
> @@ -114,6 +137,29 @@
>  }
>  
>  /* Unprivileged */
> +char *
> +ssh_gssapi_server_mechanisms() {
> +	gss_OID_set	supported;
4413c4594,4597
< +	debug2("%s: Acquiring credentials", __func__);
---
> +	ssh_gssapi_supported_oids(&supported);
> +	return (ssh_gssapi_kex_mechs(supported, &ssh_gssapi_server_check_mech,
> +	    NULL, NULL));
> +}
4415,4418c4599,4607
< +	if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) {
< +		kex_gss_send_error(ctxt);
< +		fatal("Unable to acquire credentials for the server");
< +    }
---
> +/* Unprivileged */
> +int
> +ssh_gssapi_server_check_mech(Gssctxt **dum, gss_OID oid, const char *data,
> +    const char *dummy) {
> +	Gssctxt *ctx = NULL;
> +	int res;
> + 
> +	res = !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx, oid)));
> +	ssh_gssapi_delete_ctx(&ctx);
4420,4441c4609,4610
< +	switch (kex->kex_type) {
< +	case KEX_GSS_GRP1_SHA1:
< +		dh = dh_new_group1();
< +		break;
< +	case KEX_GSS_GRP14_SHA1:
< +		dh = dh_new_group14();
< +		break;
< +	case KEX_GSS_GEX_SHA1:
< +		debug("Doing group exchange");
< +		packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ);
< +		min = packet_get_int();
< +		nbits = packet_get_int();
< +		max = packet_get_int();
< +		min = MAX(DH_GRP_MIN, min);
< +		max = MIN(DH_GRP_MAX, max);
< +		packet_check_eom();
< +		if (max < min || nbits < min || max < nbits)
< +			fatal("GSS_GEX, bad parameters: %d !< %d !< %d",
< +			    min, nbits, max);
< +		dh = PRIVSEP(choose_dh(min, nbits, max));
< +		if (dh == NULL)
< +			packet_disconnect("Protocol error: no matching group found");
---
> +	return (res);
> +}
4443,4446c4612,4620
< +		packet_start(SSH2_MSG_KEXGSS_GROUP);
< +		packet_put_bignum2(dh->p);
< +		packet_put_bignum2(dh->g);
< +		packet_send();
---
> +/* Unprivileged */
>  void
>  ssh_gssapi_supported_oids(gss_OID_set *oidset)
>  {
> @@ -123,7 +169,10 @@
>  	gss_OID_set supported;
>  
>  	gss_create_empty_oid_set(&min_status, oidset);
> -	gss_indicate_mechs(&min_status, &supported);
4448,4451c4622,4650
< +		packet_write_wait();
< +		break;
< +	default:
< +		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
---
> +	/* Ask privileged process what mechanisms it supports. */
> +	if (GSS_ERROR(PRIVSEP(gss_indicate_mechs(&min_status, &supported))))
> +		return;
>  
>  	while (supported_mechs[i]->name != NULL) {
>  		if (GSS_ERROR(gss_test_oid_set_member(&min_status,
> @@ -175,6 +224,10 @@
>  	    (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) {
>  		if (ssh_gssapi_getclient(ctx, &gssapi_client))
>  			fatal("Couldn't convert client name");
> +#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG
> +		if (flags && (*flags & GSS_C_GLOBUS_LIMITED_PROXY_FLAG))
> +			limited=1;
> +#endif
>  	}
>  
>  	return (status);
> @@ -194,6 +247,17 @@
>  
>  	tok = ename->value;
>  
> +#ifdef GSI /* GSI gss_export_name() is broken. */
> +	if ((ctx->oid->length == gssapi_gsi_mech.oid.length) &&
> +	    (memcmp(ctx->oid->elements, gssapi_gsi_mech.oid.elements,
> +		    gssapi_gsi_mech.oid.length) == 0)) {
> +	    name->length = ename->length;
> +	    name->value = xmalloc(ename->length+1);
> +	    memcpy(name->value, ename->value, ename->length);
> +	    return GSS_S_COMPLETE;
4452a4652
> +#endif
4454,4464c4654,4663
< +	dh_gen_key(dh, kex->we_need * 8);
< +
< +	do {
< +		debug("Wait SSH2_MSG_GSSAPI_INIT");
< +		type = packet_read();
< +		switch(type) {
< +		case SSH2_MSG_KEXGSS_INIT:
< +			if (dh_client_pub != NULL) 
< +				fatal("Received KEXGSS_INIT after initialising");
< +			recv_tok.value = packet_get_string(&slen);
< +			recv_tok.length = slen; 
---
>  	/*
>  	 * Check that ename is long enough for all of the fixed length
>  	 * header, and that the initial ID bytes are correct
> @@ -249,8 +313,51 @@
>  ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
>  {
>  	int i = 0;
> +	int equal = 0;
> +	gss_name_t new_name = GSS_C_NO_NAME;
> +	gss_buffer_desc ename = GSS_C_EMPTY_BUFFER;
4466,4467c4665,4671
< +			if ((dh_client_pub = BN_new()) == NULL)
< +				fatal("dh_client_pub == NULL");
---
> +	if (options.gss_store_rekey && client->used && ctx->client_creds) {
> +		if (client->mech->oid.length != ctx->oid->length ||
> +		    (memcmp(client->mech->oid.elements,
> +		     ctx->oid->elements, ctx->oid->length) !=0)) {
> +			debug("Rekeyed credentials have different mechanism");
> +			return GSS_S_COMPLETE;
> +		}
4469c4673,4674
< +			packet_get_bignum2(dh_client_pub);
---
> +        /* Call gss_inquire_cred rather than gss_inquire_cred_by_mech
> +           because GSI doesn't support the latter. -jbasney */
4471,4480c4676,4680
< +			/* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
< +			break;
< +		case SSH2_MSG_KEXGSS_CONTINUE:
< +			recv_tok.value = packet_get_string(&slen);
< +			recv_tok.length = slen; 
< +			break;
< +		default:
< +			packet_disconnect(
< +			    "Protocol error: didn't expect packet type %d",
< +			    type);
---
> +		if ((ctx->major = gss_inquire_cred(&ctx->minor, 
> +		    ctx->client_creds, &new_name, 
> +		    NULL, NULL, NULL))) {
> +			ssh_gssapi_error(ctx);
> +			return (ctx->major);
4483,4499c4683,4689
< +		maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, 
< +		    &send_tok, &ret_flags));
< +
< +		xfree(recv_tok.value);
< +
< +		if (maj_status != GSS_S_COMPLETE && send_tok.length == 0)
< +			fatal("Zero length token output when incomplete");
< +
< +		if (dh_client_pub == NULL)
< +			fatal("No client public key");
< +		
< +		if (maj_status & GSS_S_CONTINUE_NEEDED) {
< +			debug("Sending GSSAPI_CONTINUE");
< +			packet_start(SSH2_MSG_KEXGSS_CONTINUE);
< +			packet_put_string((char *)send_tok.value, send_tok.length);
< +			packet_send();
< +			gss_release_buffer(&min_status, &send_tok);
---
> +		ctx->major = gss_compare_name(&ctx->minor, client->name, 
> +		    new_name, &equal);
>  
> -	gss_buffer_desc ename;
> +		if (GSS_ERROR(ctx->major)) {
> +			ssh_gssapi_error(ctx);
> +			return (ctx->major);
4501,4508c4691,4694
< +	} while (maj_status & GSS_S_CONTINUE_NEEDED);
< +
< +	if (GSS_ERROR(maj_status)) {
< +		kex_gss_send_error(ctxt);
< +		if (send_tok.length > 0) {
< +			packet_start(SSH2_MSG_KEXGSS_CONTINUE);
< +			packet_put_string((char *)send_tok.value, send_tok.length);
< +			packet_send();
---
> + 
> +		if (!equal) {
> +			debug("Rekeyed credentials have different name");
> +			return GSS_S_COMPLETE;
4510,4511d4695
< +		packet_disconnect("GSSAPI Key Exchange handshake failed");
< +	}
4513,4514c4697
< +	if (!(ret_flags & GSS_C_MUTUAL_FLAG))
< +		fatal("Mutual Authentication flag wasn't set");
---
> +		debug("Marking rekeyed credentials for export");
4516,4520c4699,4715
< +	if (!(ret_flags & GSS_C_INTEG_FLAG))
< +		fatal("Integrity flag wasn't set");
< +	
< +	if (!dh_pub_is_valid(dh, dh_client_pub))
< +		packet_disconnect("bad client public DH value");
---
> +		gss_release_name(&ctx->minor, &client->name);
> +		gss_release_cred(&ctx->minor, &client->creds);
> +		client->name = new_name;
> +		client->creds = ctx->client_creds;
> +        	ctx->client_creds = GSS_C_NO_CREDENTIAL;
> +		client->updated = 1;
> +		return GSS_S_COMPLETE;
> +	}
>  
>  	client->mech = NULL;
>  
> @@ -265,6 +372,16 @@
>  	if (client->mech == NULL)
>  		return GSS_S_FAILURE;
>  
> +    /* Call gss_inquire_cred rather than gss_inquire_cred_by_mech
> +       because GSI doesn't support the latter. -jbasney */
4522,4526c4717,4722
< +	klen = DH_size(dh);
< +	kbuf = xmalloc(klen); 
< +	kout = DH_compute_key(kbuf, dh_client_pub, dh);
< +	if (kout < 0)
< +		fatal("DH_compute_key: failed");
---
> +	if (ctx->client_creds &&
> +	    (ctx->major = gss_inquire_cred(&ctx->minor,
> +	     ctx->client_creds, &client->name, NULL, NULL, NULL))) {
> +		ssh_gssapi_error(ctx);
> +		return (ctx->major);
> +	}
4528,4530c4724,4731
< +	shared_secret = BN_new();
< +	if (shared_secret == NULL)
< +		fatal("kexgss_server: BN_new failed");
---
>  	if ((ctx->major = gss_display_name(&ctx->minor, ctx->client,
>  	    &client->displayname, NULL))) {
>  		ssh_gssapi_error(ctx);
> @@ -282,9 +399,15 @@
>  		return (ctx->major);
>  	}
>  
> +	gss_release_buffer(&ctx->minor, &ename);
4532,4533c4733,4735
< +	if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
< +		fatal("kexgss_server: BN_bin2bn failed");
---
>  	/* 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;
4535,4536c4737,4738
< +	memset(kbuf, 0, klen);
< +	xfree(kbuf);
---
> +    /* needed for globus_gss_assist_map_and_authorize() */
> +    client->context = ctx->context;
4538,4566c4740,4773
< +	switch (kex->kex_type) {
< +	case KEX_GSS_GRP1_SHA1:
< +	case KEX_GSS_GRP14_SHA1:
< +		kex_dh_hash(
< +		    kex->client_version_string, kex->server_version_string,
< +		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
< +		    buffer_ptr(&kex->my), buffer_len(&kex->my),
< +		    NULL, 0, /* Change this if we start sending host keys */
< +		    dh_client_pub, dh->pub_key, shared_secret,
< +		    &hash, &hashlen
< +		);
< +		break;
< +	case KEX_GSS_GEX_SHA1:
< +		kexgex_hash(
< +		    kex->evp_md,
< +		    kex->client_version_string, kex->server_version_string,
< +		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
< +		    buffer_ptr(&kex->my), buffer_len(&kex->my),
< +		    NULL, 0,
< +		    min, nbits, max,
< +		    dh->p, dh->g,
< +		    dh_client_pub,
< +		    dh->pub_key,
< +		    shared_secret,
< +		    &hash, &hashlen
< +		);
< +		break;
< +	default:
< +		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
---
>  	return (ctx->major);
>  }
>  
> @@ -305,6 +428,11 @@
>  ssh_gssapi_storecreds(void)
>  {
>  	if (gssapi_client.mech && gssapi_client.mech->storecreds) {
> +        if (options.gss_creds_path) {
> +            gssapi_client.store.filename =
> +                expand_authorized_keys(options.gss_creds_path,
> +                                       the_authctxt->pw);
> +        }
>  		(*gssapi_client.mech->storecreds)(&gssapi_client);
>  	} else
>  		debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
> @@ -328,8 +456,9 @@
>  }
>  
>  /* Privileged */
> +/* gssapi_keyex arg added for Globus usage */
>  int
> -ssh_gssapi_userok(char *user)
> +ssh_gssapi_userok(char *user, struct passwd *pw, int gssapi_keyex)
>  {
>  	OM_uint32 lmin;
>  
> @@ -338,10 +467,18 @@
>  		debug("No suitable client data");
>  		return 0;
>  	}
> +#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG
> +	if (limited && options.gsi_allow_limited_proxy != 1) {
> +		debug("limited proxy not acceptable for remote login");
> +		return 0;
4567a4775,4795
> +#endif
>  	if (gssapi_client.mech && gssapi_client.mech->userok)
> -		if ((*gssapi_client.mech->userok)(&gssapi_client, user))
> +		if ((*gssapi_client.mech->userok)(&gssapi_client, user)) {
> +			gssapi_client.used = 1;
> +			gssapi_client.store.owner = pw;
>  			return 1;
> -		else {
> +		} else {
>  			/* Destroy delegated credentials if userok fails */
>  			gss_release_buffer(&lmin, &gssapi_client.displayname);
>  			gss_release_buffer(&lmin, &gssapi_client.exportedname);
> @@ -354,14 +491,133 @@
>  	return (0);
>  }
>  
> -/* Privileged */
> -OM_uint32
> -ssh_gssapi_checkmic(Gssctxt *ctx, gss_buffer_t gssbuf, gss_buffer_t gssmic)
> +/* ssh_gssapi_checkmic() moved to gss-genr.c so it can be called by
> +   kexgss_client(). */
4569,4574c4797,4805
< +	BN_clear_free(dh_client_pub);
< +
< +	if (kex->session_id == NULL) {
< +		kex->session_id_len = hashlen;
< +		kex->session_id = xmalloc(kex->session_id_len);
< +		memcpy(kex->session_id, hash, kex->session_id_len);
---
> +/* Priviledged */
> +int
> +ssh_gssapi_localname(char **user)
> +{
> +    	*user = NULL;
> +	if (gssapi_client.displayname.length==0 || 
> +	    gssapi_client.displayname.value==NULL) {
> +		debug("No suitable client data");
> +		return(0);;
4576,4589c4807,4808
< +
< +	gssbuf.value = hash;
< +	gssbuf.length = hashlen;
< +
< +	if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok))))
< +		fatal("Couldn't get MIC");
< +
< +	packet_start(SSH2_MSG_KEXGSS_COMPLETE);
< +	packet_put_bignum2(dh->pub_key);
< +	packet_put_string((char *)msg_tok.value,msg_tok.length);
< +
< +	if (send_tok.length != 0) {
< +		packet_put_char(1); /* true */
< +		packet_put_string((char *)send_tok.value, send_tok.length);
---
> +	if (gssapi_client.mech && gssapi_client.mech->localname) {
> +		return((*gssapi_client.mech->localname)(&gssapi_client,user));
4591c4810
< +		packet_put_char(0); /* false */
---
> +		debug("Unknown client authentication type");
4593,4601c4812,4813
< +	packet_send();
< +
< +	gss_release_buffer(&min_status, &send_tok);
< +	gss_release_buffer(&min_status, &msg_tok);
< +
< +	if (gss_kex_context == NULL)
< +		gss_kex_context = ctxt;
< +	else 
< +		ssh_gssapi_delete_ctx(&ctxt);
---
> +	return(0);
> +}
4603c4815,4821
< +	DH_free(dh);
---
> +/* These bits are only used for rekeying. The unpriviledged child is running 
> + * as the user, the monitor is root.
> + *
> + * In the child, we want to :
> + *    *) Ask the monitor to store our credentials into the store we specify
> + *    *) If it succeeds, maybe do a PAM update
> + */
4605,4607c4823
< +	kex_derive_keys(kex, hash, hashlen, shared_secret);
< +	BN_clear_free(shared_secret);
< +	kex_finish(kex);
---
> +/* Stuff for PAM */
4609,4612c4825,4831
< +	/* If this was a rekey, then save out any delegated credentials we
< +	 * just exchanged.  */
< +	if (options.gss_store_rekey)
< +		ssh_gssapi_rekey_creds();
---
> +#ifdef USE_PAM
> +static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg, 
> +    struct pam_response **resp, void *data)
>  {
> -	ctx->major = gss_verify_mic(&ctx->minor, ctx->context,
> -	    gssbuf, gssmic, NULL);
> +	return (PAM_CONV_ERR);
4613a4833,4845
> +#endif
>  
> -	return (ctx->major);
> +void
> +ssh_gssapi_rekey_creds() {
> +	int ok;
> +#ifdef USE_PAM
> +	int ret;
> +	pam_handle_t *pamh = NULL;
> +	struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL};
> +	char *envstr;
> +	char **p;char **pw;
> +#endif
4615,4630c4847,4866
< +static void 
< +kex_gss_send_error(Gssctxt *ctxt) {
< +	char *errstr;
< +	OM_uint32 maj,min;
< +		
< +	errstr=PRIVSEP(ssh_gssapi_last_error(ctxt,&maj,&min));
< +	if (errstr) {
< +		packet_start(SSH2_MSG_KEXGSS_ERROR);
< +		packet_put_int(maj);
< +		packet_put_int(min);
< +		packet_put_cstring(errstr);
< +		packet_put_cstring("");
< +		packet_send();
< +		packet_write_wait();
< +		/* XXX - We should probably log the error locally here */
< +		xfree(errstr);
---
> +	if (gssapi_client.store.filename == NULL && 
> +	    gssapi_client.store.envval == NULL &&
> +	    gssapi_client.store.envvar == NULL)
> +		return;
> + 
> +	ok = PRIVSEP(ssh_gssapi_update_creds(&gssapi_client.store));
> +
> +	if (!ok)
> +		return;
> +
> +	debug("Rekeyed credentials stored successfully");
> +
> +	/* Actually managing to play with the ssh pam stack from here will
> +	 * be next to impossible. In any case, we may want different options
> +	 * for rekeying. So, use our own :)
> +	 */
> +#ifdef USE_PAM	
> +	if (!use_privsep) {
> +		debug("Not even going to try and do PAM with privsep disabled");
> +		return;
4632,4674d4867
< +}
< +#endif /* GSSAPI */
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/key.c openssh-6.0p1/key.c
< --- openssh-6.0p1.orig/key.c	2011-10-18 00:06:16.000000000 -0500
< +++ openssh-6.0p1/key.c	2012-05-27 17:50:01.000000000 -0500
< @@ -971,6 +971,8 @@
<  		}
<  		break;
<  #endif /* OPENSSL_HAS_ECC */
< +	case KEY_NULL:
< +		return "null";
<  	}
<  	return "ssh-unknown";
<  }
< @@ -1276,6 +1278,8 @@
<  	    strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) {
<  		return KEY_ECDSA_CERT;
<  #endif
< +	} else if (strcmp(name, "null") == 0) {
< +		return KEY_NULL;
<  	}
<  
<  	debug2("key_type_from_name: unknown key type '%s'", name);
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/key.h openssh-6.0p1/key.h
< --- openssh-6.0p1.orig/key.h	2010-11-04 18:19:49.000000000 -0500
< +++ openssh-6.0p1/key.h	2012-05-27 17:50:01.000000000 -0500
< @@ -44,6 +44,7 @@
<  	KEY_ECDSA_CERT,
<  	KEY_RSA_CERT_V00,
<  	KEY_DSA_CERT_V00,
< +	KEY_NULL,
<  	KEY_UNSPEC
<  };
<  enum fp_type {
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/misc.c openssh-6.0p1/misc.c
< --- openssh-6.0p1.orig/misc.c	2011-09-22 06:34:36.000000000 -0500
< +++ openssh-6.0p1/misc.c	2012-05-27 17:50:01.000000000 -0500
< @@ -158,11 +158,14 @@
<  #define WHITESPACE " \t\r\n"
<  #define QUOTE	"\""
<  
< +/* Characters considered as quotations. */
< +#define QUOTES "'\""
4676,4702c4869,4872
<  /* return next token in configuration line */
<  char *
<  strdelim(char **s)
<  {
< -	char *old;
< +	char *old, *p, *q;
<  	int wspace = 0;
<  
<  	if (*s == NULL)
< @@ -170,6 +173,21 @@
<  
<  	old = *s;
<  
< +        if ((q=strchr(QUOTES, (int) *old)) && *q)
< +        {
< +            /* find next quote character, point old to start of quoted
< +             * string */
< +            for (p = ++old;*p && *p!=*q; p++)
< +                 ;
< +            
< +            /* find start of next token */
< +            *s = (*p) ? p + strspn(p + 1, WHITESPACE) + 1 : NULL;
< +            
< +            /* terminate 'old' token */
< +            *p = '\0';
< +            return (old);
< +        }
---
> +	ret = pam_start("sshd-rekey", gssapi_client.store.owner->pw_name,
> + 	    &pamconv, &pamh);
> +	if (ret)
> +		return;
4704,4718c4874,4892
<  	*s = strpbrk(*s, WHITESPACE QUOTE "=");
<  	if (*s == NULL)
<  		return (old);
< @@ -223,6 +241,20 @@
<  	return copy;
<  }
<  
< +void
< +pwfree(struct passwd *pw)
< +{
< +	xfree(pw->pw_name);
< +	xfree(pw->pw_passwd);
< +	xfree(pw->pw_gecos);
< +#ifdef HAVE_PW_CLASS_IN_PASSWD
< +	xfree(pw->pw_class);
---
> +	/* Put ssh pam stack env variables in this new pam stack env 
> +	 * Using pam-pkinit, KRB5CCNAME is set during do_pam_session
> +	 * this addition enables pam-pkinit to access KRB5CCNAME if used 
> +	 * in sshd-rekey stack too
> +	 */
> +	pw = p = fetch_pam_environment();
> +	while ( *pw != NULL ) {
> +	        pam_putenv(pamh,*pw);
> +		pw++;
> +	}
> +	free_pam_environment(p);
> +
> +	xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, 
> +	    gssapi_client.store.envval);
> +
> +	ret = pam_putenv(pamh, envstr);
> +	if (!ret)
> +		pam_setcred(pamh, PAM_REINITIALIZE_CRED);
> +	pam_end(pamh, PAM_SUCCESS);
4720,4722d4893
< +	xfree(pw->pw_dir);
< +	xfree(pw->pw_shell);
< +	xfree(pw);
4725,4751c4896,4924
<  /*
<   * Convert ASCII string to TCP/IP port number.
<   * Port must be >=0 and <=65535.
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/misc.h openssh-6.0p1/misc.h
< --- openssh-6.0p1.orig/misc.h	2011-05-04 23:14:34.000000000 -0500
< +++ openssh-6.0p1/misc.h	2012-05-27 17:50:01.000000000 -0500
< @@ -38,6 +38,7 @@
<  void	 sock_set_v6only(int);
<  
<  struct passwd *pwcopy(struct passwd *);
< +void	 pwfree(struct passwd *);
<  const char *ssh_gai_strerror(int);
<  
<  typedef struct arglist arglist;
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/monitor.c openssh-6.0p1/monitor.c
< --- openssh-6.0p1.orig/monitor.c	2012-02-10 15:16:09.000000000 -0600
< +++ openssh-6.0p1/monitor.c	2012-05-27 17:50:01.000000000 -0500
< @@ -180,6 +180,11 @@
<  int mm_answer_gss_accept_ctx(int, Buffer *);
<  int mm_answer_gss_userok(int, Buffer *);
<  int mm_answer_gss_checkmic(int, Buffer *);
< +int mm_answer_gss_sign(int, Buffer *);
< +int mm_answer_gss_error(int, Buffer *);
< +int mm_answer_gss_indicate_mechs(int, Buffer *);
< +int mm_answer_gss_localname(int, Buffer *);
< +int mm_answer_gss_updatecreds(int, Buffer *);
<  #endif
---
> +int 
> +ssh_gssapi_update_creds(ssh_gssapi_ccache *store) {
> +	int ok = 0;
> +
> +	/* Check we've got credentials to store */
> +	if (!gssapi_client.updated)
> +		return 0;
> +
> +	gssapi_client.updated = 0;
> +
> +	temporarily_use_uid(gssapi_client.store.owner);
> +	if (gssapi_client.mech && gssapi_client.mech->updatecreds)
> +		ok = (*gssapi_client.mech->updatecreds)(store, &gssapi_client);
> +	else
> +		debug("No update function for this mechanism");
> +
> +	restore_uid();
> +
> +	return ok;
> +}
> +
> +/* added for Globus usage */
> +void
> +ssh_gssapi_get_client_info(char **userdn, char **mech) {
> +	*userdn = gssapi_client.displayname.value;
> +
> +	if (gssapi_client.mech)
> +		*mech = gssapi_client.mech->name;
>  }
4753,4776d4925
<  #ifdef SSH_AUDIT_EVENTS
< @@ -221,12 +226,12 @@
<  struct mon_table mon_dispatch_proto20[] = {
<      {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli},
<      {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
< -    {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
< +    {MONITOR_REQ_PWNAM, MON_AUTH, mm_answer_pwnamallow},
<      {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
<      {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
<      {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
<  #ifdef USE_PAM
< -    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
< +    {MONITOR_REQ_PAM_START, MON_ISAUTH, mm_answer_pam_start},
<      {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},
< @@ -251,6 +256,10 @@
<      {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},
< +    {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
< +    {MONITOR_REQ_GSSERR, MON_ISAUTH | MON_ONCE, mm_answer_gss_error},
< +    {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs},
< +    {MONITOR_REQ_GSSLOCALNAME, MON_ISAUTH, mm_answer_gss_localname},
4778,4783c4927,4956
<  #ifdef JPAKE
<      {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
< @@ -263,6 +272,14 @@
<  };
<  
<  struct mon_table mon_dispatch_postauth20[] = {
---
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/gss-serv-gsi.c openssh-6.0p1/gss-serv-gsi.c
> --- openssh-6.0p1.orig/gss-serv-gsi.c	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/gss-serv-gsi.c	2012-07-12 17:01:14.234688350 +0200
> @@ -0,0 +1,238 @@
> +/*
> + * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
> + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
> + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
> + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
> +
> +#include "includes.h"
> +
4785,4887c4958
< +    {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},
< +    {MONITOR_REQ_GSSERR, 0, mm_answer_gss_error},
< +    {MONITOR_REQ_GSSMECHS, 0, mm_answer_gss_indicate_mechs},
< +    {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
< +#endif
<      {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
<      {MONITOR_REQ_SIGN, 0, mm_answer_sign},
<      {MONITOR_REQ_PTY, 0, mm_answer_pty},
< @@ -292,8 +309,15 @@
<      {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
<      {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
<  #endif
< +#ifdef GSSAPI
< +    {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx},
< +    {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
< +    {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
< +    {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
< +    {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs},
< +#endif
<  #ifdef USE_PAM
< -    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
< +    {MONITOR_REQ_PAM_START, MON_ISAUTH, mm_answer_pam_start},
<      {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},
< @@ -371,6 +395,12 @@
<  		/* Permit requests for moduli and signatures */
<  		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
<  		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
< +#ifdef GSSAPI		
< +		/* and for the GSSAPI key exchange */
< +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
< +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSERR, 1);
< +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS, 1);
< +#endif
<  	} else {
<  		mon_dispatch = mon_dispatch_proto15;
<  
< @@ -468,10 +498,21 @@
<  		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
<  		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
<  		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
< +
< +#ifdef GSSAPI
< +		/* and for the GSSAPI key exchange */
< +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS,1);
< +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP,1);
< +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSERR,1);
< +#endif
< +
<  	} else {
<  		mon_dispatch = mon_dispatch_postauth15;
<  		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
<  	}
< +#ifdef GSSAPI		
< +	monitor_permit(mon_dispatch, MONITOR_REQ_GSSERR, 1);
< +#endif
<  	if (!no_pty_flag) {
<  		monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
<  		monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1);
< @@ -735,14 +776,17 @@
<  
<  	debug3("%s", __func__);
<  
< -	if (authctxt->attempt++ != 0)
< -		fatal("%s: multiple attempts for getpwnam", __func__);
< -
<  	username = buffer_get_string(m, NULL);
<  
<  	pwent = getpwnamallow(username);
<  
< +	if (authctxt->user) xfree(authctxt->user);
<  	authctxt->user = xstrdup(username);
< +#ifdef USE_PAM
< +    if (options.permit_pam_user_change)
< +        setproctitle("%s [priv]", pwent ? "[pam]" : "unknown");
< +    else
< +#endif
<  	setproctitle("%s [priv]", pwent ? username : "unknown");
<  	xfree(username);
<  
< @@ -1803,6 +1847,13 @@
<  	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
<  	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
<  	kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
< +#ifdef GSSAPI
< +	if (options.gss_keyex) {
< +		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
< +		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
< +		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
< +	}
< +#endif
<  	kex->server = 1;
<  	kex->hostkey_type = buffer_get_int(m);
<  	kex->kex_type = buffer_get_int(m);
< @@ -2009,6 +2060,9 @@
<  	OM_uint32 major;
<  	u_int len;
<  
< +	if (!options.gss_authentication && !options.gss_keyex)
< +		fatal("In GSSAPI monitor when GSSAPI is disabled");
---
> +#ifdef GSI
4889,4897c4960
<  	goid.elements = buffer_get_string(m, &len);
<  	goid.length = len;
<  
< @@ -2036,6 +2090,9 @@
<  	OM_uint32 flags = 0; /* GSI needs this */
<  	u_int len;
<  
< +	if (!options.gss_authentication && !options.gss_keyex)
< +		fatal("In GSSAPI monitor when GSSAPI is disabled");
---
> +#include <sys/types.h>
4899,4917c4962,4963
<  	in.value = buffer_get_string(m, &len);
<  	in.length = len;
<  	major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
< @@ -2052,7 +2109,9 @@
<  	if (major == GSS_S_COMPLETE) {
<  		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
<  		monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
< +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
<  		monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
< +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
<  	}
<  	return (0);
<  }
< @@ -2064,6 +2123,9 @@
<  	OM_uint32 ret;
<  	u_int len;
<  
< +	if (!options.gss_authentication && !options.gss_keyex)
< +		fatal("In GSSAPI monitor when GSSAPI is disabled");
---
> +#include <stdarg.h>
> +#include <string.h>
4919,4930c4965,4970
<  	gssbuf.value = buffer_get_string(m, &len);
<  	gssbuf.length = len;
<  	mic.value = buffer_get_string(m, &len);
< @@ -2089,8 +2151,18 @@
<  mm_answer_gss_userok(int sock, Buffer *m)
<  {
<  	int authenticated;
< +	int gssapi_keyex;
<  
< -	authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
< +	if (!options.gss_authentication && !options.gss_keyex)
< +		fatal("In GSSAPI monitor when GSSAPI is disabled");
---
> +#include "xmalloc.h"
> +#include "key.h"
> +#include "hostfile.h"
> +#include "auth.h"
> +#include "log.h"
> +#include "servconf.h"
4932c4972,4973
< +	gssapi_keyex = buffer_get_int(m);
---
> +#include "buffer.h"
> +#include "ssh-gss.h"
4934,4935c4975
< +	if (!options.gss_authentication && !options.gss_keyex)
< +		fatal("In GSSAPI monitor when GSSAPI is disabled");
---
> +extern ServerOptions options;
4937,4954c4977
< +	authenticated = authctxt->valid && 
< +	    ssh_gssapi_userok(authctxt->user, authctxt->pw, gssapi_keyex);
<  
<  	buffer_clear(m);
<  	buffer_put_int(m, authenticated);
< @@ -2098,11 +2170,146 @@
<  	debug3("%s: sending result %d", __func__, authenticated);
<  	mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m);
<  
< -	auth_method = "gssapi-with-mic";
< +	if (gssapi_keyex)
< +		auth_method = "gssapi-keyex";
< +	else
< +		auth_method = "gssapi-with-mic";
<  
<  	/* Monitor loop will terminate if authenticated */
<  	return (authenticated);
<  }
---
> +#include <globus_gss_assist.h>
4956,4959c4979,4983
< +int
< +mm_answer_gss_error(int socket, Buffer *m) {
< +        OM_uint32 major,minor;
< +        char *msg;
---
> +static int ssh_gssapi_gsi_userok(ssh_gssapi_client *client, char *name);
> +static int ssh_gssapi_gsi_localname(ssh_gssapi_client *client, char **user);
> +static void ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client);
> +static int ssh_gssapi_gsi_updatecreds(ssh_gssapi_ccache *store,
> +				       ssh_gssapi_client *client);
4961,4965c4985,4994
< +	msg=ssh_gssapi_last_error(gsscontext,&major,&minor);
< +	buffer_clear(m);
< +	buffer_put_int(m,major);
< +	buffer_put_int(m,minor);
< +	buffer_put_cstring(m,msg);
---
> +ssh_gssapi_mech gssapi_gsi_mech = {
> +	"dZuIebMjgUqaxvbF7hDbAw==",
> +	"GSI",
> +	{9, "\x2B\x06\x01\x04\x01\x9B\x50\x01\x01"},
> +	NULL,
> +	&ssh_gssapi_gsi_userok,
> +	&ssh_gssapi_gsi_localname,
> +	&ssh_gssapi_gsi_storecreds,
> +	&ssh_gssapi_gsi_updatecreds
> +};
4967c4996,5016
< +	mm_request_send(socket,MONITOR_ANS_GSSERR,m);
---
> +/*
> + * Check if this user is OK to login under GSI. User has been authenticated
> + * as identity in global 'client_name.value' and is trying to log in as passed
> + * username in 'name'.
> + *
> + * Returns non-zero if user is authorized, 0 otherwise.
> + */
> +static int
> +ssh_gssapi_gsi_userok(ssh_gssapi_client *client, char *name)
> +{
> +    int authorized = 0;
> +    globus_result_t res;
> +#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
> +    char lname[256] = "";
> +#endif
> +    
> +#ifdef GLOBUS_GSI_GSS_ASSIST_MODULE
> +    if (globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE) != 0) {
> +	return 0;
> +    }
> +#endif
4969,4971c5018,5044
< +	xfree(msg);
< +	
< +        return(0);
---
> +/* use new globus_gss_assist_map_and_authorize() interface if available */
> +#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
> +    debug("calling globus_gss_assist_map_and_authorize()");
> +    if (GLOBUS_SUCCESS !=
> +        (res = globus_gss_assist_map_and_authorize(client->context, "ssh",
> +                                                   name, lname, 256))) {
> +        debug("%s", globus_error_print_chain(globus_error_get(res)));
> +    } else if (lname[0] && strcmp(name, lname) != 0) {
> +        debug("GSI user maps to %s, not %s", lname, name);
> +    } else {
> +        authorized = 1;
> +    }
> +#else
> +    debug("calling globus_gss_assist_userok()");
> +    if (GLOBUS_SUCCESS !=
> +        (res = (globus_gss_assist_userok(client->displayname.value,
> +                                         name)))) {
> +        debug("%s", globus_error_print_chain(globus_error_get(res)));
> +    } else {
> +        authorized = 1;
> +    }
> +#endif
> +    
> +    logit("GSI user %s is%s authorized as target user %s",
> +	(char *) client->displayname.value, (authorized ? "" : " not"), name);
> +    
> +    return authorized;
4973a5047,5049
> +/*
> + * Return the local username associated with the GSI credentials.
> + */
4975,4978c5051,5056
< +mm_answer_gss_indicate_mechs(int socket, Buffer *m) {
< +        OM_uint32 major,minor;
< +	gss_OID_set mech_set;
< +	size_t i;
---
> +ssh_gssapi_gsi_localname(ssh_gssapi_client *client, char **user)
> +{
> +    globus_result_t res;
> +#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
> +    char lname[256] = "";
> +#endif
4980,4991c5058,5061
< +	major=gss_indicate_mechs(&minor, &mech_set);
< +
< +	buffer_clear(m);
< +	buffer_put_int(m, major);
< +	buffer_put_int(m, mech_set->count);
< +	for (i=0; i < mech_set->count; i++) {
< +	    buffer_put_string(m, mech_set->elements[i].elements,
< +			      mech_set->elements[i].length);
< +	}
< +
< +#if !defined(MECHGLUE) /* mechglue memory management bug ??? */
< +	gss_release_oid_set(&minor,&mech_set);
---
> +#ifdef GLOBUS_GSI_GSS_ASSIST_MODULE
> +    if (globus_module_activate(GLOBUS_GSI_GSS_ASSIST_MODULE) != 0) {
> +	return 0;
> +    }
4993,5001d5062
< +	
< +	mm_request_send(socket,MONITOR_ANS_GSSMECHS,m);
< +
< +	return(0);
< +}
< +
< +int
< +mm_answer_gss_localname(int socket, Buffer *m) {
< +	char *name;
5003,5013c5064,5083
< +	ssh_gssapi_localname(&name);
< +
< +        buffer_clear(m);
< +	if (name) {
< +	    buffer_put_cstring(m, name);
< +	    debug3("%s: sending result %s", __func__, name);
< +	    xfree(name);
< +	} else {
< +	    buffer_put_cstring(m, "");
< +	    debug3("%s: sending result \"\"", __func__);
< +	}
---
> +/* use new globus_gss_assist_map_and_authorize() interface if available */
> +#ifdef HAVE_GLOBUS_GSS_ASSIST_MAP_AND_AUTHORIZE
> +    debug("calling globus_gss_assist_map_and_authorize()");
> +    if (GLOBUS_SUCCESS !=
> +        (res = globus_gss_assist_map_and_authorize(client->context, "ssh",
> +                                                   NULL, lname, 256))) {
> +        debug("%s", globus_error_print_chain(globus_error_get(res)));
> +        logit("failed to map GSI user %s", (char *)client->displayname.value);
> +        return 0;
> +    }
> +    *user = strdup(lname);
> +#else
> +    debug("calling globus_gss_assist_gridmap()");
> +    if (GLOBUS_SUCCESS !=
> +        (res = globus_gss_assist_gridmap(client->displayname.value, user))) {
> +        debug("%s", globus_error_print_chain(globus_error_get(res)));
> +        logit("failed to map GSI user %s", (char *)client->displayname.value);
> +        return 0;
> +    }
> +#endif
5015c5085,5086
< +        mm_request_send(socket, MONITOR_ANS_GSSLOCALNAME, m);
---
> +    logit("GSI user %s mapped to target user %s",
> +          (char *) client->displayname.value, *user);
5017c5088
< +        return(0);
---
> +    return 1;
5020,5021c5091,5095
< +int 
< +mm_answer_gss_sign(int socket, Buffer *m)
---
> +/*
> + * Export GSI credentials to disk.
> + */
> +static void
> +ssh_gssapi_gsi_storecreds(ssh_gssapi_client *client)
5023,5041c5097,5103
< +	gss_buffer_desc data;
< +	gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
< +	OM_uint32 major, minor;
< +	u_int len;
< +
< +	if (!options.gss_authentication && !options.gss_keyex)
< +		fatal("In GSSAPI monitor when GSSAPI is disabled");
< +
< +	data.value = buffer_get_string(m, &len);
< +	data.length = len;
< +	if (data.length != 20) 
< +		fatal("%s: data length incorrect: %d", __func__, 
< +		    (int) data.length);
< +
< +	/* Save the session ID on the first time around */
< +	if (session_id2_len == 0) {
< +		session_id2_len = data.length;
< +		session_id2 = xmalloc(session_id2_len);
< +		memcpy(session_id2, data.value, session_id2_len);
---
> +	OM_uint32	major_status;
> +	OM_uint32	minor_status;
> +	gss_buffer_desc	export_cred = GSS_C_EMPTY_BUFFER;
> +	char *		p;
> +	
> +	if (!client || !client->creds) {
> +	    return;
5043,5045d5104
< +	major = ssh_gssapi_sign(gsscontext, &data, &hash);
< +
< +	xfree(data.value);
5047,5056c5106,5120
< +	buffer_clear(m);
< +	buffer_put_int(m, major);
< +	buffer_put_string(m, hash.value, hash.length);
< +
< +	mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
< +
< +	gss_release_buffer(&minor, &hash);
< +
< +	/* Turn on getpwnam permissions */
< +	monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
---
> +	major_status = gss_export_cred(&minor_status,
> +				       client->creds,
> +				       GSS_C_NO_OID,
> +				       1,
> +				       &export_cred);
> +	if (GSS_ERROR(major_status) && major_status != GSS_S_UNAVAILABLE) {
> +	    Gssctxt *ctx;
> +	    ssh_gssapi_build_ctx(&ctx);
> +	    ctx->major = major_status;
> +	    ctx->minor = minor_status;
> +	    ssh_gssapi_set_oid(ctx, &gssapi_gsi_mech.oid);
> +	    ssh_gssapi_error(ctx);
> +	    ssh_gssapi_delete_ctx(&ctx);
> +	    return;
> +	}
5058,5061c5122,5154
< +	/* And credential updating, for when rekeying */
< +	monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
< +
< +	return (0);
---
> +	p = strchr((char *) export_cred.value, '=');
> +	if (p == NULL) {
> +	    logit("Failed to parse exported credentials string '%.100s'",
> +		(char *)export_cred.value);
> +	    gss_release_buffer(&minor_status, &export_cred);
> +	    return;
> +	}
> +	*p++ = '\0';
> +	if (strcmp((char *)export_cred.value,"X509_USER_DELEG_PROXY") == 0) {
> +	    client->store.envvar = strdup("X509_USER_PROXY");
> +	} else {
> +	    client->store.envvar = strdup((char *)export_cred.value);
> +	}
> +	if (access(p, R_OK) == 0) {
> +        if (client->store.filename) {
> +            if (rename(p, client->store.filename) < 0) {
> +                logit("Failed to rename %s to %s: %s", p,
> +                      client->store.filename, strerror(errno));
> +                xfree(client->store.filename);
> +                client->store.filename = strdup(p);
> +            } else {
> +                p = client->store.filename;
> +            }
> +        } else {
> +            client->store.filename = strdup(p);
> +        }
> +	}
> +	client->store.envval = strdup(p);
> +#ifdef USE_PAM
> +	if (options.use_pam)
> +	    do_pam_putenv(client->store.envvar, client->store.envval);
> +#endif
> +	gss_release_buffer(&minor_status, &export_cred);
5064,5084c5157,5164
< +int
< +mm_answer_gss_updatecreds(int socket, Buffer *m) {
< +	ssh_gssapi_ccache store;
< +	int ok;
< +
< +	store.filename = buffer_get_string(m, NULL);
< +	store.envvar   = buffer_get_string(m, NULL);
< +	store.envval   = buffer_get_string(m, NULL);
< +
< +	ok = ssh_gssapi_update_creds(&store);
< +
< +	xfree(store.filename);
< +	xfree(store.envvar);
< +	xfree(store.envval);
< +
< +	buffer_clear(m);
< +	buffer_put_int(m, ok);
< +
< +	mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
< +
< +	return(0);
---
> +/*
> + * Export updated GSI credentials to disk.
> + */
> +static int
> +ssh_gssapi_gsi_updatecreds(ssh_gssapi_ccache *store,ssh_gssapi_client *client)
> +{
> +	ssh_gssapi_gsi_storecreds(client);
> +	return 1;
5087,5119c5167,5173
<  #endif /* GSSAPI */
<  
<  #ifdef JPAKE
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/monitor.h openssh-6.0p1/monitor.h
< --- openssh-6.0p1.orig/monitor.h	2011-06-19 23:42:23.000000000 -0500
< +++ openssh-6.0p1/monitor.h	2012-05-27 17:50:01.000000000 -0500
< @@ -52,7 +52,12 @@
<  	MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP,
<  	MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
<  	MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK,
< +	MONITOR_REQ_GSSMECHS, MONITOR_ANS_GSSMECHS,
< +	MONITOR_REQ_GSSLOCALNAME, MONITOR_ANS_GSSLOCALNAME,
< +	MONITOR_REQ_GSSERR, MONITOR_ANS_GSSERR,
<  	MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC,
< +	MONITOR_REQ_GSSSIGN, MONITOR_ANS_GSSSIGN,
< +	MONITOR_REQ_GSSUPCREDS, MONITOR_ANS_GSSUPCREDS,
<  	MONITOR_REQ_PAM_START,
<  	MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
<  	MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
< @@ -65,7 +70,7 @@
<  	MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA,
<  	MONITOR_REQ_JPAKE_STEP2, MONITOR_ANS_JPAKE_STEP2,
<  	MONITOR_REQ_JPAKE_KEY_CONFIRM, MONITOR_ANS_JPAKE_KEY_CONFIRM,
< -	MONITOR_REQ_JPAKE_CHECK_CONFIRM, MONITOR_ANS_JPAKE_CHECK_CONFIRM,
< +	MONITOR_REQ_JPAKE_CHECK_CONFIRM, MONITOR_ANS_JPAKE_CHECK_CONFIRM
<  };
<  
<  struct mm_master;
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/monitor_wrap.c openssh-6.0p1/monitor_wrap.c
< --- openssh-6.0p1.orig/monitor_wrap.c	2011-06-19 23:42:23.000000000 -0500
< +++ openssh-6.0p1/monitor_wrap.c	2012-05-27 17:50:01.000000000 -0500
< @@ -1270,12 +1270,13 @@
<  }
---
> +#endif /* GSI */
> +#endif /* GSSAPI */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/gss-serv-krb5.c openssh-6.0p1/gss-serv-krb5.c
> --- openssh-6.0p1.orig/gss-serv-krb5.c	2012-07-12 17:00:49.274199956 +0200
> +++ openssh-6.0p1/gss-serv-krb5.c	2012-07-12 17:01:14.242688506 +0200
> @@ -1,7 +1,7 @@
>  /* $OpenBSD: gss-serv-krb5.c,v 1.7 2006/08/03 03:34:42 deraadt Exp $ */
5121,5126c5175,5181
<  int
< -mm_ssh_gssapi_userok(char *user)
< +mm_ssh_gssapi_userok(char *user, struct passwd *pw, int gssapi_keyex)
<  {
<  	Buffer m;
<  	int authenticated = 0;
---
>  /*
> - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
> + * Copyright (c) 2001-2007 Simon Wilkinson. All rights reserved.
>   *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions
> @@ -48,7 +48,7 @@
5128,5129c5183,5191
<  	buffer_init(&m);
< +	buffer_put_int(&m, gssapi_keyex);
---
>  #ifdef HEIMDAL
>  # include <krb5.h>
> -#else
> +#elif !defined(MECHGLUE)
>  # ifdef HAVE_GSSAPI_KRB5_H
>  #  include <gssapi_krb5.h>
>  # elif HAVE_GSSAPI_GSSAPI_KRB5_H
> @@ -57,6 +57,23 @@
>  #endif
5131,5136c5193,5199
<  	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
<  	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
< @@ -1287,6 +1288,128 @@
<  	debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
<  	return (authenticated);
<  }
---
>  static krb5_context krb_context = NULL;
> +static int ssh_gssapi_krb5_init();
> +static int ssh_gssapi_krb5_userok(ssh_gssapi_client *client, char *name);
> +static int ssh_gssapi_krb5_localname(ssh_gssapi_client *client, char **user);
> +static void ssh_gssapi_krb5_storecreds(ssh_gssapi_client *client);
> +static int ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store,
> +                                       ssh_gssapi_client *client);
5138,5157c5201,5224
< +char *
< +mm_ssh_gssapi_last_error(Gssctxt *ctx, OM_uint32 *major, OM_uint32 *minor) {
< +	Buffer m;
< +	OM_uint32 maj,min;
< +	char *errstr;
< +	
< +	buffer_init(&m);
< +
< +	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSERR, &m);
< +	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSERR, &m);
< +
< +	maj = buffer_get_int(&m);
< +	min = buffer_get_int(&m);
< +
< +	if (major) *major=maj;
< +	if (minor) *minor=min;
< +	
< +	errstr=buffer_get_string(&m,NULL);
< +
< +	buffer_free(&m);
---
> +ssh_gssapi_mech gssapi_kerberos_mech = {
> +	"toWM5Slw5Ew8Mqkay+al2g==",
> +	"Kerberos",
> +	{9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"},
> +	NULL,
> +	&ssh_gssapi_krb5_userok,
> +	&ssh_gssapi_krb5_localname,
> +	&ssh_gssapi_krb5_storecreds,
> +	&ssh_gssapi_krb5_updatecreds
> +};
>  
>  /* Initialise the krb5 library, for the stuff that GSSAPI won't do */
>  
> @@ -109,6 +126,35 @@
>  }
>  
>  
> +/* Retrieve the local username associated with a set of Kerberos 
> + * credentials. Hopefully we can use this for the 'empty' username
> + * logins discussed in the draft  */
> +static int
> +ssh_gssapi_krb5_localname(ssh_gssapi_client *client, char **user) {
> +	krb5_principal princ;
> +	int retval;
5159,5171c5226,5227
< +	return(errstr);
< +}	
< +
< +OM_uint32
< +mm_gss_indicate_mechs(OM_uint32 *minor_status, gss_OID_set *mech_set)
< +{
< +        Buffer m;
< +	OM_uint32 major,minor;
< +	int count;
< +	gss_OID_desc oid;
< +        u_int length;
< +
< +	buffer_init(&m);
---
> +	if (ssh_gssapi_krb5_init() == 0)
> +		return 0;
5173,5177c5229,5234
< +	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSMECHS, &m);
< +        mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSMECHS,
< +				  &m);
< +        major=buffer_get_int(&m);
< +	count=buffer_get_int(&m);
---
> +	if ((retval=krb5_parse_name(krb_context, client->displayname.value, 
> +				    &princ))) {
> +		logit("krb5_parse_name(): %.100s", 
> +			krb5_get_err_text(krb_context,retval));
> +		return 0;
> +	}
5179,5183c5236,5241
< +        gss_create_empty_oid_set(&minor,mech_set);
< +	while(count-->0) {
< +	    oid.elements=buffer_get_string(&m,&length);
< +	    oid.length=length;
< +	    gss_add_oid_set_member(&minor,&oid,mech_set);
---
> +	/* We've got to return a malloc'd string */
> +	*user = (char *)xmalloc(256);
> +	if (krb5_aname_to_localname(krb_context, princ, 256, *user)) {
> +		xfree(*user);
> +		*user = NULL;
> +		return(0);
5185,5186d5242
< +
< +	buffer_free(&m);
5188c5244
< +        return(major);
---
> +	return(1);
5189a5246,5272
> +	
>  /* This writes out any forwarded credentials from the structure populated
>   * during userauth. Called after we have setuid to the user */
>  
> @@ -119,7 +165,9 @@
>  	krb5_error_code problem;
>  	krb5_principal princ;
>  	OM_uint32 maj_status, min_status;
> +	gss_cred_id_t krb5_cred_handle;
>  	int len;
> +	const char *new_ccname;
>  
>  	if (client->creds == NULL) {
>  		debug("No credentials stored");
> @@ -161,18 +209,31 @@
>  
>  	krb5_free_principal(krb_context, princ);
>  
> -	if ((maj_status = gss_krb5_copy_ccache(&min_status,
> -	    client->creds, ccache))) {
> +#ifdef MECHGLUE
> +	krb5_cred_handle =
> +	    __gss_get_mechanism_cred(client->creds,
> +				     &(gssapi_kerberos_mech.oid));
> +#else
> +	krb5_cred_handle = client->creds;
> +#endif
5191,5192c5274,5313
< +int
< +mm_ssh_gssapi_localname(char **lname)
---
> +	if ((maj_status = gss_krb5_copy_ccache(&min_status, 
> +	    krb5_cred_handle, ccache))) {
>  		logit("gss_krb5_copy_ccache() failed");
>  		krb5_cc_destroy(krb_context, ccache);
>  		return;
>  	}
>  
> -	client->store.filename = xstrdup(krb5_cc_get_name(krb_context, ccache));
> +	new_ccname = krb5_cc_get_name(krb_context, ccache);
> +
>  	client->store.envvar = "KRB5CCNAME";
> -	len = strlen(client->store.filename) + 6;
> -	client->store.envval = xmalloc(len);
> -	snprintf(client->store.envval, len, "FILE:%s", client->store.filename);
> +#ifdef USE_CCAPI
> +	xasprintf(&client->store.envval, "API:%s", new_ccname);
> +	client->store.filename = NULL;
> +#else
> +	xasprintf(&client->store.envval, "FILE:%s", new_ccname);
> +	client->store.filename = xstrdup(new_ccname);
> +#endif
>  
>  #ifdef USE_PAM
>  	if (options.use_pam)
> @@ -184,15 +245,70 @@
>  	return;
>  }
>  
> -ssh_gssapi_mech gssapi_kerberos_mech = {
> -	"toWM5Slw5Ew8Mqkay+al2g==",
> -	"Kerberos",
> -	{9, "\x2A\x86\x48\x86\xF7\x12\x01\x02\x02"},
> -	NULL,
> -	&ssh_gssapi_krb5_userok,
> -	NULL,
> -	&ssh_gssapi_krb5_storecreds
> -};
> +static int
> +ssh_gssapi_krb5_updatecreds(ssh_gssapi_ccache *store, 
> +    ssh_gssapi_client *client)
5194c5315,5319
< +        Buffer m;
---
> +	krb5_ccache ccache = NULL;
> +	krb5_principal principal = NULL;
> +	char *name = NULL;
> +	krb5_error_code problem;
> +	OM_uint32 maj_status, min_status;
5196,5197c5321,5334
< +	buffer_init(&m);
< +        mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSLOCALNAME, &m);
---
> +   	if ((problem = krb5_cc_resolve(krb_context, store->envval, &ccache))) {
> +                logit("krb5_cc_resolve(): %.100s",
> +                    krb5_get_err_text(krb_context, problem));
> +                return 0;
> +       	}
> +	
> +	/* Find out who the principal in this cache is */
> +	if ((problem = krb5_cc_get_principal(krb_context, ccache, 
> +	    &principal))) {
> +		logit("krb5_cc_get_principal(): %.100s",
> +		    krb5_get_err_text(krb_context, problem));
> +		krb5_cc_close(krb_context, ccache);
> +		return 0;
> +	}
5199,5201c5336,5342
< +        debug3("%s: waiting for MONITOR_ANS_GSSLOCALNAME", __func__);
< +        mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSLOCALNAME,
< +                                  &m);
---
> +	if ((problem = krb5_unparse_name(krb_context, principal, &name))) {
> +		logit("krb5_unparse_name(): %.100s",
> +		    krb5_get_err_text(krb_context, problem));
> +		krb5_free_principal(krb_context, principal);
> +		krb5_cc_close(krb_context, ccache);
> +		return 0;
> +	}
5203d5343
< +	*lname = buffer_get_string(&m, NULL);
5205,5209c5345,5350
< +        buffer_free(&m);
< +	if (lname[0] == '\0') {
< +	    debug3("%s: gssapi identity mapping failed", __func__);
< +	} else {
< +	    debug3("%s: gssapi identity mapped to %s", __func__, *lname);
---
> +	if (strcmp(name,client->exportedname.value)!=0) {
> +		debug("Name in local credentials cache differs. Not storing");
> +		krb5_free_principal(krb_context, principal);
> +		krb5_cc_close(krb_context, ccache);
> +		krb5_free_unparsed_name(krb_context, name);
> +		return 0;
5211,5220c5352
< +	
< +        return(0);
< +}	
< +
< +OM_uint32
< +mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash)
< +{
< +	Buffer m;
< +	OM_uint32 major;
< +	u_int len;
---
> +	krb5_free_unparsed_name(krb_context, name);
5222,5223c5354
< +	buffer_init(&m);
< +	buffer_put_string(&m, data->value, data->length);
---
> +	/* Name matches, so lets get on with it! */
5225,5226c5356,5362
< +	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, &m);
< +	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, &m);
---
> +	if ((problem = krb5_cc_initialize(krb_context, ccache, principal))) {
> +		logit("krb5_cc_initialize(): %.100s",
> +		    krb5_get_err_text(krb_context, problem));
> +		krb5_free_principal(krb_context, principal);
> +		krb5_cc_close(krb_context, ccache);
> +		return 0;
> +	}
5228,5230c5364
< +	major = buffer_get_int(&m);
< +	hash->value = buffer_get_string(&m, &len);
< +	hash->length = len;
---
> +	krb5_free_principal(krb_context, principal);
5232c5366,5371
< +	buffer_free(&m);
---
> +	if ((maj_status = gss_krb5_copy_ccache(&min_status, client->creds,
> +	    ccache))) {
> +		logit("gss_krb5_copy_ccache() failed. Sorry!");
> +		krb5_cc_close(krb_context, ccache);
> +		return 0;
> +	}
5234c5373
< +	return(major);
---
> +	return 1;
5235a5375,5382
>  
>  #endif /* KRB5 */
>  
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/HPN-README openssh-6.0p1/HPN-README
> --- openssh-6.0p1.orig/HPN-README	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/HPN-README	2012-07-12 17:01:13.886681551 +0200
> @@ -0,0 +1,128 @@
> +Notes:
5237,5241c5384,5396
< +int
< +mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store)
< +{
< +	Buffer m;
< +	int ok;
---
> +MULTI-THREADED CIPHER:
> +The AES cipher in CTR mode has been multithreaded (MTR-AES-CTR). This will allow ssh installations
> +on hosts with multiple cores to use more than one processing core during encryption. 
> +Tests have show significant throughput performance increases when using MTR-AES-CTR up 
> +to and including a full gigabit per second on quad core systems. It should be possible to 
> +achieve full line rate on dual core systems but OS and data management overhead makes this
> +more difficult to achieve. The cipher stream from MTR-AES-CTR is entirely compatible with single 
> +thread AES-CTR (ST-AES-CTR) implementations and should be 100% backward compatible. Optimal 
> +performance requires the MTR-AES-CTR mode be enabled on both ends of the connection. 
> +The MTR-AES-CTR replaces ST-AES-CTR and is used in exactly the same way with the same
> +nomenclature. 
> +Use examples: 	ssh -caes128-ctr you@host.com
> +		scp -oCipher=aes256-ctr file you@host.com:~/file
5243c5398,5403
< +	buffer_init(&m);
---
> +NONE CIPHER:
> +To use the NONE option you must have the NoneEnabled switch set on the server and
> +you *must* have *both* NoneEnabled and NoneSwitch set to yes on the client. The NONE
> +feature works with ALL ssh subsystems (as far as we can tell) *AS LONG AS* a tty is not 
> +spawned. If a user uses the -T switch to prevent a tty being created the NONE cipher will
> +be disabled. 
5245,5250c5405,5408
< +	buffer_put_cstring(&m, store->filename ? store->filename : "");
< +	buffer_put_cstring(&m, store->envvar ? store->envvar : "");
< +	buffer_put_cstring(&m, store->envval ? store->envval : "");
< +	
< +	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, &m);
< +	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, &m);
---
> +The performance increase will only be as good as the network and TCP stack tuning
> +on the reciever side of the connection allows. As a rule of thumb a user will need 
> +at least 10Mb/s connection with a 100ms RTT to see a doubling of performance. The
> +HPN-SSH home page describes this in greater detail. 
5252c5410
< +	ok = buffer_get_int(&m);
---
> +http://www.psc.edu/networking/projects/hpn-ssh
5254,5257c5412
< +	buffer_free(&m);
< +	
< +	return (ok);
< +}
---
> +BUFFER SIZES:
5259,5287c5414,5415
<  #endif /* GSSAPI */
<  
<  #ifdef JPAKE
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/monitor_wrap.h openssh-6.0p1/monitor_wrap.h
< --- openssh-6.0p1.orig/monitor_wrap.h	2011-06-19 23:42:23.000000000 -0500
< +++ openssh-6.0p1/monitor_wrap.h	2012-05-27 17:50:01.000000000 -0500
< @@ -58,8 +58,14 @@
<  OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
<  OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *,
<     gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
< -int mm_ssh_gssapi_userok(char *user);
< +int mm_ssh_gssapi_userok(char *user, struct passwd *, int gssapi_keyex);
<  OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
< +OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
< +int mm_ssh_gssapi_localname(char **user);
< +OM_uint32 mm_gss_indicate_mechs(OM_uint32 *minor_status,
< +				gss_OID_set *mech_set);
< +char *mm_ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min);
< +int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *);
<  #endif
<  
<  #ifdef USE_PAM
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/mux.c openssh-6.0p1/mux.c
< --- openssh-6.0p1.orig/mux.c	2012-02-10 15:16:29.000000000 -0600
< +++ openssh-6.0p1/mux.c	2012-05-27 17:50:01.000000000 -0500
< @@ -441,6 +441,7 @@
<  		set_nonblock(new_fd[2]);
<  
<  	window = CHAN_SES_WINDOW_DEFAULT;
---
> +If HPN is disabled the receive buffer size will be set to the 
> +OpenSSH default of 64K.
5289,5398c5417,5418
<  	packetmax = CHAN_SES_PACKET_DEFAULT;
<  	if (cctx->want_tty) {
<  		window >>= 1;
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/myproposal.h openssh-6.0p1/myproposal.h
< --- openssh-6.0p1.orig/myproposal.h	2011-08-16 19:29:03.000000000 -0500
< +++ openssh-6.0p1/myproposal.h	2012-05-27 17:50:01.000000000 -0500
< @@ -75,6 +75,8 @@
<  	"arcfour256,arcfour128," \
<  	"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
<  	"aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se"
< +#define KEX_ENCRYPT_INCLUDE_NONE KEX_DEFAULT_ENCRYPT \
< +	",none"
<  #ifdef HAVE_EVP_SHA256
<  #define	SHA2_HMAC_MODES \
<  	"hmac-sha2-256," \
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/openbsd-compat/port-aix.c openssh-6.0p1/openbsd-compat/port-aix.c
< --- openssh-6.0p1.orig/openbsd-compat/port-aix.c	2009-12-20 17:49:22.000000000 -0600
< +++ openssh-6.0p1/openbsd-compat/port-aix.c	2012-05-27 17:50:01.000000000 -0500
< @@ -50,6 +50,7 @@
<  # include <login.h>
<  # include <userpw.h>
<  # if defined(HAVE_SYS_AUDIT_H) && defined(AIX_LOGINFAILED_4ARG)
< +#  undef T_NULL
<  #  include <sys/audit.h>
<  # endif
<  # include <usersec.h>
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/packet.c openssh-6.0p1/packet.c
< --- openssh-6.0p1.orig/packet.c	2012-03-08 17:28:07.000000000 -0600
< +++ openssh-6.0p1/packet.c	2012-05-27 17:50:01.000000000 -0500
< @@ -838,7 +838,7 @@
<  /*
<   * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
<   */
< -static void
< +static int
<  packet_send2_wrapped(void)
<  {
<  	u_char type, *cp, *macbuf = NULL;
< @@ -957,11 +957,13 @@
<  		set_newkeys(MODE_OUT);
<  	else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side)
<  		packet_enable_delayed_compress();
< +	return(packet_length);
<  }
<  
< -static void
< +static int
<  packet_send2(void)
<  {
< +	static int packet_length = 0;
<  	struct packet *p;
<  	u_char type, *cp;
<  
< @@ -981,7 +983,7 @@
<  			    sizeof(Buffer));
<  			buffer_init(&active_state->outgoing_packet);
<  			TAILQ_INSERT_TAIL(&active_state->outgoing, p, next);
< -			return;
< +			return(sizeof(Buffer));
<  		}
<  	}
<  
< @@ -989,7 +991,7 @@
<  	if (type == SSH2_MSG_KEXINIT)
<  		active_state->rekeying = 1;
<  
< -	packet_send2_wrapped();
< +	packet_length = packet_send2_wrapped();
<  
<  	/* after a NEWKEYS message we can send the complete queue */
<  	if (type == SSH2_MSG_NEWKEYS) {
< @@ -1002,19 +1004,22 @@
<  			    sizeof(Buffer));
<  			TAILQ_REMOVE(&active_state->outgoing, p, next);
<  			xfree(p);
< -			packet_send2_wrapped();
< +			packet_length += packet_send2_wrapped();
<  		}
<  	}
< +	return(packet_length);
<  }
<  
< -void
< +int
<  packet_send(void)
<  {
< +  int packet_len = 0;
<  	if (compat20)
< -		packet_send2();
< +		packet_len = packet_send2();
<  	else
<  		packet_send1();
<  	DBG(debug("packet_send done"));
< +	return(packet_len);
<  }
<  
<  /*
< @@ -1647,12 +1652,14 @@
<  
<  /* Checks if there is any buffered output, and tries to write some of the output. */
<  
< -void
< +int
<  packet_write_poll(void)
<  {
< -	int len = buffer_len(&active_state->output);
< +	int len = 0;
<  	int cont;
<  
< +	len = buffer_len(&active_state->output);
---
> +If an HPN system connects to a nonHPN system the receive buffer will
> +be set to the HPNBufferSize value. The default is 2MB but user adjustable.
5400,5428c5420,5421
<  	if (len > 0) {
<  		cont = 0;
<  		len = roaming_write(active_state->connection_out,
< @@ -1660,13 +1667,14 @@
<  		if (len == -1) {
<  			if (errno == EINTR || errno == EAGAIN ||
<  			    errno == EWOULDBLOCK)
< -				return;
< +				return (0);
<  			fatal("Write failed: %.100s", strerror(errno));
<  		}
<  		if (len == 0 && !cont)
<  			fatal("Write connection closed");
<  		buffer_consume(&active_state->output, len);
<  	}
< +	return(len);
<  }
<  
<  /*
< @@ -1867,12 +1875,24 @@
<  	}
<  }
<  
< +int rekey_requested = 0;
< +void
< +packet_request_rekeying(void)
< +{
< +	rekey_requested = 1;
< +}
---
> +If an HPN to HPN connection is established a number of different things might
> +happen based on the user options and conditions. 
5430,5447c5423,5427
<  #define MAX_PACKETS	(1U<<31)
<  int
<  packet_need_rekeying(void)
<  {
<  	if (datafellows & SSH_BUG_NOREKEY)
<  		return 0;
< +	if (rekey_requested == 1)
< +	{
< +		rekey_requested = 0;
< +		return 1;
< +	}
<  	return
<  	    (active_state->p_send.packets > MAX_PACKETS) ||
<  	    (active_state->p_read.packets > MAX_PACKETS) ||
< @@ -1964,3 +1984,9 @@
<  		add_recv_bytes(len);
<  	}
<  }
---
> +Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set 
> +HPN Buffer Size = up to 64MB 
> +This is the default state. The HPN buffer size will grow to a maximum of 64MB 
> +as the TCP receive buffer grows. The maximum HPN Buffer size of 64MB is 
> +geared towards 10GigE transcontinental connections. 
5449,5462c5429,5432
< +int
< +packet_authentication_state(void)
< +{
< +	return(active_state->after_authentication);
< +}
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/packet.h openssh-6.0p1/packet.h
< --- openssh-6.0p1.orig/packet.h	2012-02-10 15:19:21.000000000 -0600
< +++ openssh-6.0p1/packet.h	2012-05-27 17:50:01.000000000 -0500
< @@ -23,6 +23,12 @@
<  #include <openssl/ec.h>
<  #endif
<  
< +void
< +packet_request_rekeying(void);
---
> +Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
> +HPN Buffer Size = TCP receive buffer value. 
> +Users on non-autotuning systesm should disable TCPRcvBufPoll in the 
> +ssh_cofig and sshd_config
5464,5465c5434,5436
< +void
< +packet_request_rekeying(void);
---
> +Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf NOT Set
> +HPN Buffer Size = minmum of TCP receive buffer and HPNBufferSize. 
> +This would be the system defined TCP receive buffer (RWIN).
5467,5521c5438,5440
<  void     packet_set_connection(int, int);
<  void     packet_set_timeout(int, int);
<  void     packet_set_nonblocking(void);
< @@ -38,6 +44,7 @@
<  int      packet_is_interactive(void);
<  void     packet_set_server(void);
<  void     packet_set_authenticated(void);
< +int	 packet_authentication_state(void);
<  
<  void     packet_start(u_char);
<  void     packet_put_char(int ch);
< @@ -51,7 +58,7 @@
<  void     packet_put_string(const void *buf, u_int len);
<  void     packet_put_cstring(const char *str);
<  void     packet_put_raw(const void *buf, u_int len);
< -void     packet_send(void);
< +int      packet_send(void);
<  
<  int      packet_read(void);
<  void     packet_read_expect(int type);
< @@ -85,7 +92,7 @@
<  void	 packet_set_iv(int, u_char *);
<  void	*packet_get_newkeys(int);
<  
< -void     packet_write_poll(void);
< +int      packet_write_poll(void);
<  void     packet_write_wait(void);
<  int      packet_have_data_to_write(void);
<  int      packet_not_very_much_data_to_write(void);
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/progressmeter.c openssh-6.0p1/progressmeter.c
< --- openssh-6.0p1.orig/progressmeter.c	2006-08-04 21:39:40.000000000 -0500
< +++ openssh-6.0p1/progressmeter.c	2012-05-27 17:50:01.000000000 -0500
< @@ -68,6 +68,8 @@
<  static char *file;		/* name of the file being transferred */
<  static off_t end_pos;		/* ending position of transfer */
<  static off_t cur_pos;		/* transfer position as of last refresh */
< +static off_t last_pos;
< +static off_t max_delta_pos = 0;
<  static volatile off_t *counter;	/* progress counter */
<  static long stalled;		/* how long we have been stalled */
<  static int bytes_per_second;	/* current speed in bytes per second */
< @@ -128,12 +130,17 @@
<  	int hours, minutes, seconds;
<  	int i, len;
<  	int file_len;
< +	off_t delta_pos;
<  
<  	transferred = *counter - cur_pos;
<  	cur_pos = *counter;
<  	now = time(NULL);
<  	bytes_left = end_pos - cur_pos;
<  
< +	delta_pos = cur_pos - last_pos;
< +	if (delta_pos > max_delta_pos) 
< +		max_delta_pos = delta_pos;
---
> +Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf SET
> +HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. 
> +Generally there is no need to set both.
5523,5539c5442,5444
<  	if (bytes_left > 0)
<  		elapsed = now - last_update;
<  	else {
< @@ -158,7 +165,7 @@
<  
<  	/* filename */
<  	buf[0] = '\0';
< -	file_len = win_size - 35;
< +	file_len = win_size - 45;
<  	if (file_len > 0) {
<  		len = snprintf(buf, file_len + 1, "\r%s", file);
<  		if (len < 0)
< @@ -175,7 +182,8 @@
<  		percent = ((float)cur_pos / end_pos) * 100;
<  	else
<  		percent = 100;
< -	snprintf(buf + strlen(buf), win_size - strlen(buf),
---
> +Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf NOT Set
> +HPN Buffer Size = grows to HPNBufferSize
> +The buffer will grow up to the maximum size specified here. 
5541,5556c5446,5450
< +	snprintf(buf + strlen(buf), win_size - strlen(buf-8),
<  	    " %3d%% ", percent);
<  
<  	/* amount transferred */
< @@ -188,6 +196,15 @@
<  	    (off_t)bytes_per_second);
<  	strlcat(buf, "/s ", win_size);
<  
< +	/* instantaneous rate */
< +	if (bytes_left > 0)
< +		format_rate(buf + strlen(buf), win_size - strlen(buf),
< +			    delta_pos);
< +	else
< +		format_rate(buf + strlen(buf), win_size - strlen(buf),
< +			    max_delta_pos);
< +	strlcat(buf, "/s ", win_size);
---
> +Conditions: HPNBufferSize SET, TCPRcvBufPoll enabled, TCPRcvBuf SET
> +HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. 
> +Generally there is no need to set both of these, especially on autotuning 
> +systems. However, if the users wishes to override the autotuning this would be 
> +one way to do it.
5558,5628c5452,5455
<  	/* ETA */
<  	if (!transferred)
<  		stalled += elapsed;
< @@ -224,6 +241,7 @@
<  
<  	atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1);
<  	last_update = now;
< +	last_pos = cur_pos;
<  }
<  
<  /*ARGSUSED*/
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/readconf.c openssh-6.0p1/readconf.c
< --- openssh-6.0p1.orig/readconf.c	2011-10-02 02:59:03.000000000 -0500
< +++ openssh-6.0p1/readconf.c	2012-05-27 17:50:01.000000000 -0500
< @@ -129,12 +129,16 @@
<  	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
<  	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
<  	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
< +	oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey,
< +	oGssServerIdentity, 
<  	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
<  	oSendEnv, oControlPath, oControlMaster, oControlPersist,
<  	oHashKnownHosts,
<  	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
<  	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
<  	oKexAlgorithms, oIPQoS, oRequestTTY,
< +	oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
< +	oHPNBufferSize,
<  	oDeprecated, oUnsupported
<  } OpCodes;
<  
< @@ -169,10 +173,19 @@
<  	{ "afstokenpassing", oUnsupported },
<  #if defined(GSSAPI)
<  	{ "gssapiauthentication", oGssAuthentication },
< +	{ "gssapikeyexchange", oGssKeyEx },
<  	{ "gssapidelegatecredentials", oGssDelegateCreds },
< +	{ "gssapitrustdns", oGssTrustDns },
< +	{ "gssapiclientidentity", oGssClientIdentity },
< +	{ "gssapiserveridentity", oGssServerIdentity },
< +	{ "gssapirenewalforcesrekey", oGssRenewalRekey },
<  #else
<  	{ "gssapiauthentication", oUnsupported },
< +	{ "gssapikeyexchange", oUnsupported },
<  	{ "gssapidelegatecredentials", oUnsupported },
< +	{ "gssapitrustdns", oUnsupported },
< +	{ "gssapiclientidentity", oUnsupported },
< +	{ "gssapirenewalforcesrekey", oUnsupported },
<  #endif
<  	{ "fallbacktorsh", oDeprecated },
<  	{ "usersh", oDeprecated },
< @@ -246,6 +259,12 @@
<  	{ "kexalgorithms", oKexAlgorithms },
<  	{ "ipqos", oIPQoS },
<  	{ "requesttty", oRequestTTY },
< +	{ "noneenabled", oNoneEnabled },
< +	{ "tcprcvbufpoll", oTcpRcvBufPoll },
< +	{ "tcprcvbuf", oTcpRcvBuf },
< +	{ "noneswitch", oNoneSwitch },
< +	{ "hpndisabled", oHPNDisabled },
< +	{ "hpnbuffersize", oHPNBufferSize },
<  
<  	{ NULL, oBadOption }
<  };
< @@ -483,10 +502,30 @@
<  		intptr = &options->gss_authentication;
<  		goto parse_flag;
<  
< +	case oGssKeyEx:
< +		intptr = &options->gss_keyex;
< +		goto parse_flag;
---
> +Conditions: HPNBufferSize NOT Set, TCPRcvBufPoll enabled, TCPRcvBuf SET
> +HPN Buffer Size = TCPRcvBuf. 
> +This will override autotuning and set the TCP recieve buffer to the user defined 
> +value.
5630,5636d5456
<  	case oGssDelegateCreds:
<  		intptr = &options->gss_deleg_creds;
<  		goto parse_flag;
<  
< +	case oGssTrustDns:
< +		intptr = &options->gss_trust_dns;
< +		goto parse_flag;
5638,5644c5458
< +	case oGssClientIdentity:
< +		charptr = &options->gss_client_identity;
< +		goto parse_string;
< +
< +	case oGssServerIdentity:
< +		charptr = &options->gss_server_identity;
< +		goto parse_string;
---
> +HPN Specific Configuration options
5646,5648c5460,5467
< +	case oGssRenewalRekey:
< +		intptr = &options->gss_renewal_rekey;
< +		goto parse_flag;
---
> +TcpRcvBuf=[int]KB client
> +      set the TCP socket receive buffer to n Kilobytes. It can be set up to the 
> +maximum socket size allowed by the system. This is useful in situations where 
> +the tcp receive window is set low but the maximum buffer size is set 
> +higher (as is typical). This works on a per TCP connection basis. You can also 
> +use this to artifically limit the transfer rate of the connection. In these 
> +cases the throughput will be no more than n/RTT. The minimum buffer size is 1KB. 
> +Default is the current system wide tcp receive buffer size.
5650,5674c5469,5473
<  	case oBatchMode:
<  		intptr = &options->batch_mode;
<  		goto parse_flag;
< @@ -495,6 +534,37 @@
<  		intptr = &options->check_host_ip;
<  		goto parse_flag;
<  
< +	case oNoneEnabled:
< +		intptr = &options->none_enabled;
< +		goto parse_flag;
< + 
< +	/* we check to see if the command comes from the */
< +	/* command line or not. If it does then enable it */
< +	/* otherwise fail. NONE should never be a default configuration */
< +	case oNoneSwitch:
< +		if(strcmp(filename,"command-line")==0)
< +		{		
< +		    intptr = &options->none_switch;
< +		    goto parse_flag;
< +		} else {
< +		    error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
< +		    error("Continuing...");
< +		    debug("NoneSwitch directive found in %.200s.", filename);
< +		    return 0;
< +	        }
---
> +TcpRcvBufPoll=[yes/no] client/server
> +      enable of disable the polling of the tcp receive buffer through the life 
> +of the connection. You would want to make sure that this option is enabled 
> +for systems making use of autotuning kernels (linux 2.4.24+, 2.6, MS Vista) 
> +default is yes.
5676,5678c5475,5479
< +	case oHPNDisabled:
< +		intptr = &options->hpn_disabled;
< +		goto parse_flag;
---
> +NoneEnabled=[yes/no] client/server
> +      enable or disable the use of the None cipher. Care must always be used 
> +when enabling this as it will allow users to send data in the clear. However, 
> +it is important to note that authentication information remains encrypted 
> +even if this option is enabled. Set to no by default.
5680,5682c5481,5488
< +	case oHPNBufferSize:
< +		intptr = &options->hpn_buffer_size;
< +		goto parse_int;
---
> +NoneSwitch=[yes/no] client
> +     Switch the encryption cipher being used to the None cipher after
> +authentication takes place. NoneEnabled must be enabled on both the client
> +and server side of the connection. When the connection switches to the NONE
> +cipher a warning is sent to STDERR. The connection attempt will fail with an
> +error if a client requests a NoneSwitch from the server that does not explicitly
> +have NoneEnabled set to yes. Note: The NONE cipher cannot be used in
> +interactive (shell) sessions and it will fail silently. Set to no by default.
5684,5686c5490,5493
< +	case oTcpRcvBufPoll:
< +		intptr = &options->tcp_rcv_buf_poll;
< +		goto parse_flag;
---
> +HPNDisabled=[yes/no] client/server
> +     In some situations, such as transfers on a local area network, the impact 
> +of the HPN code produces a net decrease in performance. In these cases it is 
> +helpful to disable the HPN functionality. By default HPNDisabled is set to no. 
5688,5697c5495,5501
<  	case oVerifyHostKeyDNS:
<  		intptr = &options->verify_host_key_dns;
<  		goto parse_yesnoask;
< @@ -680,6 +750,10 @@
<  		intptr = &options->connection_attempts;
<  		goto parse_int;
<  
< +	case oTcpRcvBuf:
< +		intptr = &options->tcp_rcv_buf;
< +		goto parse_int;
---
> +HPNBufferSize=[int]KB client/server
> +     This is the default buffer size the HPN functionality uses when interacting
> +with nonHPN SSH installations. Conceptually this is similar to the TcpRcvBuf
> +option as applied to the internal SSH flow control. This value can range from 
> +1KB to 64MB (1-65536). Use of oversized or undersized buffers can cause performance
> +problems depending on the length of the network path. The default size of this buffer
> +is 2MB.
5699,5724c5503,5525
<  	case oCipher:
<  		intptr = &options->cipher;
<  		arg = strdelim(&s);
< @@ -1139,7 +1213,12 @@
<  	options->pubkey_authentication = -1;
<  	options->challenge_response_authentication = -1;
<  	options->gss_authentication = -1;
< +	options->gss_keyex = -1;
<  	options->gss_deleg_creds = -1;
< +	options->gss_trust_dns = -1;
< +	options->gss_renewal_rekey = -1;
< +	options->gss_client_identity = NULL;
< +	options->gss_server_identity = NULL;
<  	options->password_authentication = -1;
<  	options->kbd_interactive_authentication = -1;
<  	options->kbd_interactive_devices = NULL;
< @@ -1203,6 +1282,12 @@
<  	options->ip_qos_interactive = -1;
<  	options->ip_qos_bulk = -1;
<  	options->request_tty = -1;
< +	options->none_switch = -1;
< +	options->none_enabled = -1;
< +	options->hpn_disabled = -1;
< +	options->hpn_buffer_size = -1;
< +	options->tcp_rcv_buf_poll = -1;
< +	options->tcp_rcv_buf = -1;
---
> +
> +Credits: This patch was conceived, designed, and led by Chris Rapier (rapier@psc.edu)
> +         The majority of the actual coding for versions up to HPN12v1 was performed
> +         by Michael Stevens (mstevens@andrew.cmu.edu). The MT-AES-CTR cipher was 
> +	 implemented by Ben Bennet (ben@psc.edu). This work was financed, in part,
> +         by Cisco System, Inc., the National Library of Medicine, 
> +	 and the National Science Foundation. 
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/kex.c openssh-6.0p1/kex.c
> --- openssh-6.0p1.orig/kex.c	2012-07-12 17:00:49.314200739 +0200
> +++ openssh-6.0p1/kex.c	2012-07-12 17:01:14.262688898 +0200
> @@ -49,6 +49,11 @@
>  #include "dispatch.h"
>  #include "monitor.h"
>  #include "roaming.h"
> +#include "canohost.h"
> +
> +#ifdef GSSAPI
> +#include "ssh-gss.h"
> +#endif
>  
>  #if OPENSSL_VERSION_NUMBER >= 0x00907000L
>  # if defined(HAVE_EVP_SHA256)
> @@ -91,7 +96,8 @@
5727,5860c5528,5551
<  /*
< @@ -1238,9 +1323,15 @@
<  	if (options->challenge_response_authentication == -1)
<  		options->challenge_response_authentication = 1;
<  	if (options->gss_authentication == -1)
< -		options->gss_authentication = 0;
< +		options->gss_authentication = 1;
< +	if (options->gss_keyex == -1)
< +		options->gss_keyex = 1;
<  	if (options->gss_deleg_creds == -1)
< -		options->gss_deleg_creds = 0;
< +		options->gss_deleg_creds = 1;
< +	if (options->gss_trust_dns == -1)
< +		options->gss_trust_dns = 1;
< +	if (options->gss_renewal_rekey == -1)
< +		options->gss_renewal_rekey = 0;
<  	if (options->password_authentication == -1)
<  		options->password_authentication = 1;
<  	if (options->kbd_interactive_authentication == -1)
< @@ -1339,6 +1430,29 @@
<  		options->server_alive_interval = 0;
<  	if (options->server_alive_count_max == -1)
<  		options->server_alive_count_max = 3;
< +	if (options->none_switch == -1)
< +	        options->none_switch = 0;
< +	if (options->hpn_disabled == -1)
< +	        options->hpn_disabled = 0;
< +	if (options->hpn_buffer_size > -1)
< +	{
< +	  /* if a user tries to set the size to 0 set it to 1KB */
< +		if (options->hpn_buffer_size == 0)
< +		options->hpn_buffer_size = 1024;
< +		/*limit the buffer to 64MB*/
< +		if (options->hpn_buffer_size > 65536)
< +		{
< +			options->hpn_buffer_size = 65536*1024;
< +			debug("User requested buffer larger than 64MB. Request reverted to 64MB");
< +		}
< +		debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
< +	}
< +	if (options->tcp_rcv_buf == 0)
< +		options->tcp_rcv_buf = 1;
< +	if (options->tcp_rcv_buf > -1) 
< +		options->tcp_rcv_buf *=1024;
< +	if (options->tcp_rcv_buf_poll == -1)
< +		options->tcp_rcv_buf_poll = 1;
<  	if (options->control_master == -1)
<  		options->control_master = 0;
<  	if (options->control_persist == -1) {
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/readconf.h openssh-6.0p1/readconf.h
< --- openssh-6.0p1.orig/readconf.h	2011-10-02 02:59:03.000000000 -0500
< +++ openssh-6.0p1/readconf.h	2012-05-27 17:50:01.000000000 -0500
< @@ -48,7 +48,12 @@
<  	int     challenge_response_authentication;
<  					/* Try S/Key or TIS, authentication. */
<  	int     gss_authentication;	/* Try GSS authentication */
< +	int     gss_keyex;		/* Try GSS key exchange */
<  	int     gss_deleg_creds;	/* Delegate GSS credentials */
< +	int	gss_trust_dns;		/* Trust DNS for GSS canonicalization */
< +	int	gss_renewal_rekey;	/* Credential renewal forces rekey */
< +	char    *gss_client_identity;   /* Principal to initiate GSSAPI with */
< +	char    *gss_server_identity;   /* GSSAPI target principal */
<  	int     password_authentication;	/* Try password
<  						 * authentication. */
<  	int     kbd_interactive_authentication; /* Try keyboard-interactive auth. */
< @@ -61,6 +66,10 @@
<  	int     compression_level;	/* Compression level 1 (fast) to 9
<  					 * (best). */
<  	int     tcp_keep_alive;	/* Set SO_KEEPALIVE. */
< +	int     tcp_rcv_buf; /* user switch to set tcp recv buffer */
< +	int     tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */
< +	int     hpn_disabled;    /* Switch to disable HPN buffer management */
< +	int     hpn_buffer_size; /* User definable size for HPN buffer window */
<  	int	ip_qos_interactive;	/* IP ToS/DSCP/class for interactive */
<  	int	ip_qos_bulk;		/* IP ToS/DSCP/class for bulk traffic */
<  	LogLevel log_level;	/* Level for logging. */
< @@ -83,6 +92,8 @@
<  	char   *host_key_alias;	/* hostname alias for .ssh/known_hosts */
<  	char   *proxy_command;	/* Proxy command for connecting the host. */
<  	char   *user;		/* User to log in as. */
< +	int    implicit;	/* Login user was not specified.
< +				   Server may choose based on authctxt. */
<  	int     escape_char;	/* Escape character; -2 = none */
<  
<  	u_int	num_system_hostfiles;	/* Paths for /etc/ssh/ssh_known_hosts */
< @@ -109,6 +120,8 @@
<  
<  	int	enable_ssh_keysign;
<  	int64_t rekey_limit;
< +	int     none_switch;    /* Use none cipher */
< +	int     none_enabled;   /* Allow none to be used */
<  	int	no_host_authentication_for_localhost;
<  	int	identities_only;
<  	int	server_alive_interval;
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/scp.c openssh-6.0p1/scp.c
< --- openssh-6.0p1.orig/scp.c	2011-09-22 06:38:01.000000000 -0500
< +++ openssh-6.0p1/scp.c	2012-05-27 17:50:01.000000000 -0500
< @@ -731,7 +731,7 @@
<  	off_t i, statbytes;
<  	size_t amt;
<  	int fd = -1, haderr, indx;
< -	char *last, *name, buf[2048], encname[MAXPATHLEN];
< +	char *last, *name, buf[16384], encname[MAXPATHLEN];
<  	int len;
<  
<  	for (indx = 0; indx < argc; ++indx) {
< @@ -913,7 +913,7 @@
<  	mode_t mode, omode, mask;
<  	off_t size, statbytes;
<  	int setimes, targisdir, wrerrno = 0;
< -	char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
< +	char ch, *cp, *np, *targ, *why, *vect[1], buf[16384];
<  	struct timeval tv[2];
<  
<  #define	atime	tv[0]
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/servconf.c openssh-6.0p1/servconf.c
< --- openssh-6.0p1.orig/servconf.c	2011-10-02 02:57:38.000000000 -0500
< +++ openssh-6.0p1/servconf.c	2012-05-27 17:50:01.000000000 -0500
< @@ -62,6 +62,7 @@
<  
<  	/* Portable-specific options */
<  	options->use_pam = -1;
< +	options->permit_pam_user_change = -1;
<  
<  	/* Standard Options */
<  	options->num_ports = 0;
< @@ -95,9 +96,19 @@
<  	options->kerberos_authentication = -1;
<  	options->kerberos_or_local_passwd = -1;
<  	options->kerberos_ticket_cleanup = -1;
< +#ifdef  SESSION_HOOKS
< +        options->session_hooks_allow = -1;
< +        options->session_hooks_startup_cmd = NULL;
< +        options->session_hooks_shutdown_cmd = NULL;
---
>  /* put algorithm proposal into buffer */
> -static void
> +/* used in sshconnect.c as well as kex.c */
> +void
>  kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
>  {
>  	u_int i;
> @@ -358,6 +364,20 @@
>   		k->kex_type = KEX_ECDH_SHA2;
>  		k->evp_md = kex_ecdh_name_to_evpmd(k->name);
>  #endif
> +#ifdef GSSAPI
> +	} else if (strncmp(k->name, KEX_GSS_GEX_SHA1_ID,
> +	    sizeof(KEX_GSS_GEX_SHA1_ID) - 1) == 0) {
> +		k->kex_type = KEX_GSS_GEX_SHA1;
> +		k->evp_md = EVP_sha1();
> +	} else if (strncmp(k->name, KEX_GSS_GRP1_SHA1_ID,
> +	    sizeof(KEX_GSS_GRP1_SHA1_ID) - 1) == 0) {
> +		k->kex_type = KEX_GSS_GRP1_SHA1;
> +		k->evp_md = EVP_sha1();
> +	} else if (strncmp(k->name, KEX_GSS_GRP14_SHA1_ID,
> +	    sizeof(KEX_GSS_GRP14_SHA1_ID) - 1) == 0) {
> +		k->kex_type = KEX_GSS_GRP14_SHA1;
> +		k->evp_md = EVP_sha1();
5862,5888c5553,5554
<  	options->kerberos_get_afs_token = -1;
< -	options->gss_authentication=-1;
< +	options->gss_authentication = -1;
< +	options->gss_deleg_creds = -1;
< +	options->gss_keyex = -1;
<  	options->gss_cleanup_creds = -1;
< +	options->gss_strict_acceptor = -1;
< +	options->gsi_allow_limited_proxy = -1;
< +	options->gss_store_rekey = -1;
<  	options->password_authentication = -1;
<  	options->kbd_interactive_authentication = -1;
<  	options->challenge_response_authentication = -1;
< @@ -133,9 +144,15 @@
<  	options->adm_forced_command = NULL;
<  	options->chroot_directory = NULL;
<  	options->zero_knowledge_password_authentication = -1;
< +	options->disable_usage_stats = 0;
< +	options->usage_stats_targets = NULL;
<  	options->revoked_keys_file = NULL;
<  	options->trusted_user_ca_keys = NULL;
<  	options->authorized_principals_file = NULL;
< +	options->none_enabled = -1;
< +	options->tcp_rcv_buf_poll = -1;
< +	options->hpn_disabled = -1;
< +	options->hpn_buffer_size = -1;
<  	options->ip_qos_interactive = -1;
<  	options->ip_qos_bulk = -1;
---
>  	} else
>  		fatal("bad kex alg %s", k->name);
5890,5897c5556,5560
< @@ -143,9 +160,16 @@
<  void
<  fill_default_server_options(ServerOptions *options)
<  {
< +	/* needed for hpn socket tests */
< +	int sock;
< +	int socksize;
< +	int socksizelen = sizeof(int);
---
> @@ -407,6 +427,13 @@
>  	int nenc, nmac, ncomp;
>  	u_int mode, ctos, need;
>  	int first_kex_follows, type;
> +	int log_flag = 0;
5899,5940c5562
<  	/* Portable-specific options */
<  	if (options->use_pam == -1)
<  		options->use_pam = 0;
< +	if (options->permit_pam_user_change == -1)
< +		options->permit_pam_user_change = 0;
<  
<  	/* Standard Options */
<  	if (options->protocol == SSH_PROTO_UNKNOWN)
< @@ -221,12 +245,26 @@
<  		options->kerberos_or_local_passwd = 1;
<  	if (options->kerberos_ticket_cleanup == -1)
<  		options->kerberos_ticket_cleanup = 1;
< +#ifdef  SESSION_HOOKS
< +    if (options->session_hooks_allow == -1)
< +        options->session_hooks_allow = 0;
< +#endif
<  	if (options->kerberos_get_afs_token == -1)
<  		options->kerberos_get_afs_token = 0;
<  	if (options->gss_authentication == -1)
< -		options->gss_authentication = 0;
< +		options->gss_authentication = 1;
< +	if (options->gss_deleg_creds == -1)
< +		options->gss_deleg_creds = 1;
< +	if (options->gss_keyex == -1)
< +		options->gss_keyex = 1;
<  	if (options->gss_cleanup_creds == -1)
<  		options->gss_cleanup_creds = 1;
< +	if (options->gss_strict_acceptor == -1)
< +		options->gss_strict_acceptor = 1;
< +	if (options->gsi_allow_limited_proxy == -1)
< +		options->gsi_allow_limited_proxy = 0;
< +	if (options->gss_store_rekey == -1)
< +		options->gss_store_rekey = 0;
<  	if (options->password_authentication == -1)
<  		options->password_authentication = 1;
<  	if (options->kbd_interactive_authentication == -1)
< @@ -278,6 +316,42 @@
<  	if (options->ip_qos_bulk == -1)
<  		options->ip_qos_bulk = IPTOS_THROUGHPUT;
<  
< +	if (options->hpn_disabled == -1) 
< +		options->hpn_disabled = 0;
---
> +	int auth_flag;
5942,5967c5564,5578
< +	if (options->hpn_buffer_size == -1) {
< +		/* option not explicitly set. Now we have to figure out */
< +		/* what value to use */
< +		if (options->hpn_disabled == 1) {
< +			options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
< +		} else {
< +			/* get the current RCV size and set it to that */
< +			/*create a socket but don't connect it */
< +			/* we use that the get the rcv socket size */
< +			sock = socket(AF_INET, SOCK_STREAM, 0);
< +			getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
< +				   &socksize, &socksizelen);
< +			close(sock);
< +			options->hpn_buffer_size = socksize;
< +			debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
< +			
< +		} 
< +	} else {
< +		/* we have to do this incase the user sets both values in a contradictory */
< +		/* manner. hpn_disabled overrrides hpn_buffer_size*/
< +		if (options->hpn_disabled <= 0) {
< +			if (options->hpn_buffer_size == 0)
< +				options->hpn_buffer_size = 1;
< +			/* limit the maximum buffer to 64MB */
< +			if (options->hpn_buffer_size > 64*1024) {
< +				options->hpn_buffer_size = 64*1024*1024;
---
> +	auth_flag = packet_authentication_state();
> +
> +	debug ("AUTH STATE IS %d", auth_flag);
>  
>  	my   = kex_buf2prop(&kex->my, NULL);
>  	peer = kex_buf2prop(&kex->peer, &first_kex_follows);
> @@ -441,11 +468,34 @@
>  		choose_enc (&newkeys->enc,  cprop[nenc],  sprop[nenc]);
>  		choose_mac (&newkeys->mac,  cprop[nmac],  sprop[nmac]);
>  		choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]);
> +		debug("REQUESTED ENC.NAME is '%s'", newkeys->enc.name);
> +		if (strcmp(newkeys->enc.name, "none") == 0) {
> +				debug("Requesting NONE. Authflag is %d", auth_flag);			
> +			if (auth_flag == 1) {
> +				debug("None requested post authentication.");
5969c5580
< +				options->hpn_buffer_size *= 1024;
---
> +				fatal("Pre-authentication none cipher requests are not allowed.");
5971,5979c5582,5601
< +		} else
< +			options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
< +	}
< +
<  	/* Turn privilege separation on by default */
<  	if (use_privsep == -1)
<  		use_privsep = PRIVSEP_ON;
< @@ -290,14 +364,13 @@
<  		options->compression = 0;
---
> +		} 
>  		debug("kex: %s %s %s %s",
>  		    ctos ? "client->server" : "server->client",
>  		    newkeys->enc.name,
>  		    newkeys->mac.name,
>  		    newkeys->comp.name);
> +		/* client starts withctos = 0 && log flag = 0 and no log*/
> +		/* 2nd client pass ctos=1 and flag = 1 so no log*/
> +		/* server starts with ctos =1 && log_flag = 0 so log */
> +		/* 2nd sever pass ctos = 1 && log flag = 1 so no log*/
> +		/* -cjr*/
> +		if (ctos && !log_flag) {
> +			logit("SSH: Server;Ltype: Kex;Remote: %s-%d;Enc: %s;MAC: %s;Comp: %s",
> +			      get_remote_ipaddr(),
> +			      get_remote_port(),
> +			      newkeys->enc.name,
> +			      newkeys->mac.name,
> +			      newkeys->comp.name);
> +		}
> +		log_flag = 1;
5981,6103c5603,5631
<  #endif
< -
<  }
<  
<  /* Keyword tokens. */
<  typedef enum {
<  	sBadOption,		/* == unknown option */
<  	/* Portable-specific options */
< -	sUsePAM,
< +	sUsePAM, sPermitPAMUserChange,
<  	/* Standard Options */
<  	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
<  	sPermitRootLogin, sLogFacility, sLogLevel,
< @@ -305,6 +378,9 @@
<  	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
<  	sKerberosGetAFSToken,
<  	sKerberosTgtPassing, sChallengeResponseAuthentication,
< +#ifdef SESSION_HOOKS
< +        sAllowSessionHooks, sSessionHookStartupCmd, sSessionHookShutdownCmd,
< +#endif
<  	sPasswordAuthentication, sKbdInteractiveAuthentication,
<  	sListenAddress, sAddressFamily,
<  	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
< @@ -318,11 +394,18 @@
<  	sBanner, sUseDNS, sHostbasedAuthentication,
<  	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
<  	sClientAliveCountMax, sAuthorizedKeysFile,
< -	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
< +    sGssDelegateCreds,
< +    sGssCredsPath,
< +	sGsiAllowLimitedProxy,
< +	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
< +	sGssKeyEx, sGssStoreRekey,
< +	sAcceptEnv, sPermitTunnel,
<  	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
<  	sUsePrivilegeSeparation, sAllowAgentForwarding,
< +	sDisUsageStats, sUsageStatsTarg,
<  	sZeroKnowledgePasswordAuthentication, sHostCertificate,
<  	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
< +	sNoneEnabled, sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize,
<  	sKexAlgorithms, sIPQoS,
<  	sDeprecated, sUnsupported
<  } ServerOpCodes;
< @@ -340,8 +423,10 @@
<  	/* Portable-specific options */
<  #ifdef USE_PAM
<  	{ "usepam", sUsePAM, SSHCFG_GLOBAL },
< +	{ "permitpamuserchange", sPermitPAMUserChange, SSHCFG_GLOBAL },
<  #else
<  	{ "usepam", sUnsupported, SSHCFG_GLOBAL },
< +	{ "permitpamuserchange", sUnsupported, SSHCFG_GLOBAL },
<  #endif
<  	{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
<  	/* Standard Options */
< @@ -381,11 +466,36 @@
<  	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
<  #ifdef GSSAPI
<  	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
< +	{ "gssapidelegatecredentials", sGssDelegateCreds, SSHCFG_ALL },
<  	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
< +	{ "gssapicleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL },
< +	{ "gssapicredentialspath", sGssCredsPath, SSHCFG_GLOBAL },
< +#ifdef GSI
< +	{ "gsiallowlimitedproxy", sGsiAllowLimitedProxy, SSHCFG_GLOBAL },
< +#endif
< +	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
< +	{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
< +	{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
<  #else
<  	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
< +	{ "gssapidelegatecredentials", sUnsupported, SSHCFG_ALL },
<  	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
< +	{ "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL },
< +	{ "gssapicredentialspath", sUnsupported, SSHCFG_GLOBAL },
< +#ifdef GSI
< +	{ "gsiallowlimitedproxy", sUnsupported, SSHCFG_GLOBAL },
< +#endif
< +	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
< +	{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
< +	{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
<  #endif
< +#ifdef SESSION_HOOKS
< +    { "allowsessionhooks", sAllowSessionHooks, SSHCFG_GLOBAL },
< +    { "sessionhookstartupcmd", sSessionHookStartupCmd, SSHCFG_GLOBAL },
< +    { "sessionhookshutdowncmd", sSessionHookShutdownCmd, SSHCFG_GLOBAL },
< +#endif        
< +	{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
< +	{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
<  	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
<  	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
<  	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
< @@ -442,10 +552,16 @@
<  	{ "permitopen", sPermitOpen, SSHCFG_ALL },
<  	{ "forcecommand", sForceCommand, SSHCFG_ALL },
<  	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
< +	{ "disableusagestats", sDisUsageStats, SSHCFG_GLOBAL},
< +	{ "usagestatstargets", sUsageStatsTarg, SSHCFG_GLOBAL},
<  	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
<  	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
<  	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
<  	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
< +	{ "noneenabled", sNoneEnabled, SSHCFG_ALL },
< +	{ "hpndisabled", sHPNDisabled, SSHCFG_ALL },
< +	{ "hpnbuffersize", sHPNBufferSize, SSHCFG_ALL },
< +	{ "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL },
<  	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
<  	{ "ipqos", sIPQoS, SSHCFG_ALL },
<  	{ NULL, sBadOption, 0 }
< @@ -474,6 +590,7 @@
<  
<  	for (i = 0; keywords[i].name; i++)
<  		if (strcasecmp(cp, keywords[i].name) == 0) {
< +		        debug ("Config token is %s", keywords[i].name);
<  			*flags = keywords[i].flags;
<  			return keywords[i].opcode;
<  		}
< @@ -758,6 +875,10 @@
<  		intptr = &options->use_pam;
<  		goto parse_flag;
<  
< +	case sPermitPAMUserChange:
< +		intptr = &options->permit_pam_user_change;
< +		goto parse_flag;
---
>  	choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
>  	choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/kexgssc.c openssh-6.0p1/kexgssc.c
> --- openssh-6.0p1.orig/kexgssc.c	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/kexgssc.c	2012-07-12 17:01:14.278689211 +0200
> @@ -0,0 +1,334 @@
> +/*
> + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
> + *
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
> + *
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
> + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
> + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
> + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> + */
6105,6114c5633
<  	/* Standard Options */
<  	case sBadOption:
<  		return -1;
< @@ -918,6 +1039,22 @@
<  			*intptr = value;
<  		break;
<  
< +	case sNoneEnabled:
< +		intptr = &options->none_enabled;
< +		goto parse_flag;
---
> +#include "includes.h"
6116,6118c5635
< +	case sTcpRcvBufPoll:
< +		intptr = &options->tcp_rcv_buf_poll;
< +		goto parse_flag;
---
> +#ifdef GSSAPI
6120,6122c5637
< +	case sHPNDisabled:
< +		intptr = &options->hpn_disabled;
< +		goto parse_flag;
---
> +#include "includes.h"
6124,6126c5639,5640
< +	case sHPNBufferSize:
< +		intptr = &options->hpn_buffer_size;
< +		goto parse_int;
---
> +#include <openssl/crypto.h>
> +#include <openssl/bn.h>
6128,6137c5642
<  	case sIgnoreUserKnownHosts:
<  		intptr = &options->ignore_user_known_hosts;
<  		goto parse_flag;
< @@ -962,10 +1099,53 @@
<  		intptr = &options->gss_authentication;
<  		goto parse_flag;
<  
< +	case sGssDelegateCreds:
< +		intptr = &options->gss_deleg_creds;
< +		goto parse_flag;
---
> +#include <string.h>
6139,6141c5644,5652
< +	case sGssKeyEx:
< +		intptr = &options->gss_keyex;
< +		goto parse_flag;
---
> +#include "xmalloc.h"
> +#include "buffer.h"
> +#include "ssh2.h"
> +#include "key.h"
> +#include "cipher.h"
> +#include "kex.h"
> +#include "log.h"
> +#include "packet.h"
> +#include "dh.h"
6143,6149c5654
<  	case sGssCleanupCreds:
<  		intptr = &options->gss_cleanup_creds;
<  		goto parse_flag;
<  
< +	case sGssCredsPath:
< +		charptr = &options->gss_creds_path;
< +		goto parse_filename;
---
> +#include "ssh-gss.h"
6151,6153c5656,5675
< +	case sGssStrictAcceptor:
< +		intptr = &options->gss_strict_acceptor;
< +		goto parse_flag;
---
> +void
> +kexgss_client(Kex *kex) {
> +	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
> +	gss_buffer_desc recv_tok, gssbuf, msg_tok, *token_ptr;
> +	Gssctxt *ctxt;
> +	OM_uint32 maj_status, min_status, ret_flags;
> +	u_int klen, kout, slen = 0, hashlen, strlen;
> +	DH *dh; 
> +	BIGNUM *dh_server_pub = NULL;
> +	BIGNUM *shared_secret = NULL;
> +	BIGNUM *p = NULL;
> +	BIGNUM *g = NULL;	
> +	u_char *kbuf, *hash;
> +	u_char *serverhostkey = NULL;
> +	u_char *empty = "";
> +	char *msg;
> +	char *lang;
> +	int type = 0;
> +	int first = 1;
> +	int nbits = 0, min = DH_GRP_MIN, max = DH_GRP_MAX;
6155,6157c5677,5681
< +	case sGssStoreRekey:
< +		intptr = &options->gss_store_rekey;
< +		goto parse_flag;
---
> +	/* Initialise our GSSAPI world */	
> +	ssh_gssapi_build_ctx(&ctxt);
> +	if (ssh_gssapi_id_kex(ctxt, kex->name, kex->kex_type) 
> +	    == GSS_C_NO_OID)
> +		fatal("Couldn't identify host exchange");
6159,6163c5683,5684
< +#ifdef GSI
< +	case sGsiAllowLimitedProxy:
< +		intptr = &options->gsi_allow_limited_proxy;
< +		goto parse_flag;
< +#endif
---
> +	if (ssh_gssapi_import_name(ctxt, kex->gss_host))
> +		fatal("Couldn't import hostname");
6165,6180c5686,5688
< +#ifdef SESSION_HOOKS
< +        case sAllowSessionHooks:
< +                intptr = &options->session_hooks_allow;
< +                goto parse_flag;
< +        case sSessionHookStartupCmd:
< +        case sSessionHookShutdownCmd:
< +                arg = strdelim(&cp);
< +                if (!arg || *arg == '\0')
< +                    fatal("%s line %d: empty session hook command",
< +                          filename, linenum);
< +                if (opcode==sSessionHookStartupCmd)
< +                    options->session_hooks_startup_cmd = strdup(arg);
< +                else
< +                    options->session_hooks_shutdown_cmd = strdup(arg);
< +                break;
< +#endif                  
---
> +	if (kex->gss_client && 
> +	    ssh_gssapi_client_identity(ctxt, kex->gss_client))
> +		fatal("Couldn't acquire client credentials");
6182,6190c5690,5703
<  	case sPasswordAuthentication:
<  		intptr = &options->password_authentication;
<  		goto parse_flag;
< @@ -1370,6 +1550,39 @@
<  			*charptr = xstrdup(arg);
<  		break;
<  
< +	case sDisUsageStats:
< +		charptr = &options->chroot_directory;
---
> +	switch (kex->kex_type) {
> +	case KEX_GSS_GRP1_SHA1:
> +		dh = dh_new_group1();
> +		break;
> +	case KEX_GSS_GRP14_SHA1:
> +		dh = dh_new_group14();
> +		break;
> +	case KEX_GSS_GEX_SHA1:
> +		debug("Doing group exchange\n");
> +		nbits = dh_estimate(kex->we_need * 8);
> +		packet_start(SSH2_MSG_KEXGSS_GROUPREQ);
> +		packet_put_int(min);
> +		packet_put_int(nbits);
> +		packet_put_int(max);
6192,6210c5705
< +		arg = strdelim(&cp);
< +		if (!arg || *arg == '\0')
< +			fatal("%s line %d: missing value.",
< +			    filename, linenum);
< +		if (!strcasecmp(arg, "true") ||
< +		    !strcasecmp(arg, "enabled") ||
< +		    !strcasecmp(arg, "yes") ||
< +		    !strcasecmp(arg, "on") ||
< +		    !strcasecmp(arg, "1"))
< +			options->disable_usage_stats = 1;
< +		else if (!strcasecmp(arg, "false") ||
< +			 !strcasecmp(arg, "disabled") ||
< +			 !strcasecmp(arg, "no") ||
< +			 !strcasecmp(arg, "off") ||
< +			 !strcasecmp(arg, "0"))
< +			options->disable_usage_stats = 0;
< +		else
< +			fatal("Incorrect value for disable_usage_stats");
< +		break;
---
> +		packet_send();
6212,6213c5707
< +	case sUsageStatsTarg:
< +		charptr = &options->chroot_directory;
---
> +		packet_read_expect(SSH2_MSG_KEXGSS_GROUP);
6215,6219c5709,5721
< +		arg = strdelim(&cp);
< +		if (!arg || *arg == '\0')
< +			fatal("%s line %d: missing value.",
< +			    filename, linenum);
< +		options->usage_stats_targets = xstrdup(arg);
---
> +		if ((p = BN_new()) == NULL)
> +			fatal("BN_new() failed");
> +		packet_get_bignum2(p);
> +		if ((g = BN_new()) == NULL)
> +			fatal("BN_new() failed");
> +		packet_get_bignum2(g);
> +		packet_check_eom();
> +
> +		if (BN_num_bits(p) < min || BN_num_bits(p) > max)
> +			fatal("GSSGRP_GEX group out of range: %d !< %d !< %d",
> +			    min, BN_num_bits(p), max);
> +
> +		dh = dh_new_group(g, p);
6220a5723,5728
> +	default:
> +		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
> +	}
> +	
> +	/* Step 1 - e is dh->pub_key */
> +	dh_gen_key(dh, kex->we_need * 8);
6222,6283c5730,5733
<  	case sTrustedUserCAKeys:
<  		charptr = &options->trusted_user_ca_keys;
<  		goto parse_filename;
< @@ -1492,6 +1705,7 @@
<  {
<  	M_CP_INTOPT(password_authentication);
<  	M_CP_INTOPT(gss_authentication);
< +	M_CP_INTOPT(gss_deleg_creds);
<  	M_CP_INTOPT(rsa_authentication);
<  	M_CP_INTOPT(pubkey_authentication);
<  	M_CP_INTOPT(kerberos_authentication);
< @@ -1720,7 +1934,10 @@
<  #endif
<  #ifdef GSSAPI
<  	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
< +	dump_cfg_fmtint(sGssKeyEx, o->gss_keyex);
<  	dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
< +	dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
< +	dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey);
<  #endif
<  #ifdef JPAKE
<  	dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/servconf.h openssh-6.0p1/servconf.h
< --- openssh-6.0p1.orig/servconf.h	2011-06-22 17:30:03.000000000 -0500
< +++ openssh-6.0p1/servconf.h	2012-05-27 17:50:01.000000000 -0500
< @@ -100,10 +100,21 @@
<  						 * /etc/passwd */
<  	int     kerberos_ticket_cleanup;	/* If true, destroy ticket
<  						 * file on logout. */
< +#ifdef SESSION_HOOKS
< +        int     session_hooks_allow;        /* If true, permit user hooks */
< +        char*   session_hooks_startup_cmd;  /* cmd to be executed before */
< +        char*   session_hooks_shutdown_cmd; /* cmd to be executed after */
< +#endif
<  	int     kerberos_get_afs_token;		/* If true, try to get AFS token if
<  						 * authenticated with Kerberos. */
< +	int     gsi_allow_limited_proxy;	/* If true, accept limited proxies */
<  	int     gss_authentication;	/* If true, permit GSSAPI authentication */
< +	int     gss_deleg_creds;	/* If true, store delegated GSSAPI credentials*/
< +	int     gss_keyex;		/* If true, permit GSSAPI key exchange */
<  	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
< +	char*   gss_creds_path;	/* If true, destroy cred cache on logout */
< +	int 	gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */
< +	int 	gss_store_rekey;
<  	int     password_authentication;	/* If true, permit password
<  						 * authentication. */
<  	int     kbd_interactive_authentication;	/* If true, permit */
< @@ -157,12 +168,21 @@
<  	char   *adm_forced_command;
<  
<  	int	use_pam;		/* Enable auth via PAM */
< + 	int	permit_pam_user_change;	/* Allow PAM to change user name */
< +        int     none_enabled;           /* enable NONE cipher switch */
< +        int     tcp_rcv_buf_poll;       /* poll tcp rcv window in autotuning kernels*/
< +	int	hpn_disabled;		/* disable hpn functionality. false by default */
< +	int	hpn_buffer_size;	/* set the hpn buffer size - default 3MB */
<  
<  	int	permit_tun;
<  
<  	int	num_permitted_opens;
<  
<  	char   *chroot_directory;
---
> +	/* This is f, we initialise it now to make life easier */
> +	dh_server_pub = BN_new();
> +	if (dh_server_pub == NULL)
> +		fatal("dh_server_pub == NULL");
6285,6286c5735,5742
< +	int    disable_usage_stats;
< +	char   *usage_stats_targets;
---
> +	token_ptr = GSS_C_NO_BUFFER;
> +			 
> +	do {
> +		debug("Calling gss_init_sec_context");
> +		
> +		maj_status = ssh_gssapi_init_ctx(ctxt,
> +		    kex->gss_deleg_creds, token_ptr, &send_tok,
> +		    &ret_flags);
6288,6315c5744,5751
<  	char   *revoked_keys_file;
<  	char   *trusted_user_ca_keys;
<  	char   *authorized_principals_file;
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/serverloop.c openssh-6.0p1/serverloop.c
< --- openssh-6.0p1.orig/serverloop.c	2011-05-20 04:02:50.000000000 -0500
< +++ openssh-6.0p1/serverloop.c	2012-05-27 17:50:01.000000000 -0500
< @@ -94,10 +94,10 @@
<  static int fdout;		/* Descriptor for stdout (for reading);
<  				   May be same number as fdin. */
<  static int fderr;		/* Descriptor for stderr.  May be -1. */
< -static long stdin_bytes = 0;	/* Number of bytes written to stdin. */
< -static long stdout_bytes = 0;	/* Number of stdout bytes sent to client. */
< -static long stderr_bytes = 0;	/* Number of stderr bytes sent to client. */
< -static long fdout_bytes = 0;	/* Number of stdout bytes read from program. */
< +static u_long stdin_bytes = 0;	/* Number of bytes written to stdin. */
< +static u_long stdout_bytes = 0;	/* Number of stdout bytes sent to client. */
< +static u_long stderr_bytes = 0;	/* Number of stderr bytes sent to client. */
< +static u_long fdout_bytes = 0;	/* Number of stdout bytes read from program. */
<  static int stdin_eof = 0;	/* EOF message received from client. */
<  static int fdout_eof = 0;	/* EOF encountered reading from fdout. */
<  static int fderr_eof = 0;	/* EOF encountered readung from fderr. */
< @@ -122,6 +122,20 @@
<  static void server_init_dispatch(void);
<  
<  /*
< + * Returns current time in seconds from Jan 1, 1970 with the maximum
< + * available resolution.
< + */
---
> +		if (GSS_ERROR(maj_status)) {
> +			if (send_tok.length != 0) {
> +				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
> +				packet_put_string(send_tok.value,
> +				    send_tok.length);
> +			}
> +			fatal("gss_init_context failed");
> +		}
6317,6323c5753,5755
< +static double
< +get_current_time(void)
< +{
< +	struct timeval tv;
< +	gettimeofday(&tv, NULL);
< +	return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
< +}
---
> +		/* If we've got an old receive buffer get rid of it */
> +		if (token_ptr != GSS_C_NO_BUFFER)
> +			xfree(recv_tok.value);
6324a5757,5760
> +		if (maj_status == GSS_S_COMPLETE) {
> +			/* If mutual state flag is not true, kex fails */
> +			if (!(ret_flags & GSS_C_MUTUAL_FLAG))
> +				fatal("Mutual authentication failed");
6326,6410c5762,5765
< +/*
<   * we write to this pipe if a SIGCHLD is caught in order to avoid
<   * the race between select() and child_terminated
<   */
< @@ -414,6 +428,7 @@
<  		} else {
<  			/* Buffer any received data. */
<  			packet_process_incoming(buf, len);
< +			fdout_bytes += len;
<  		}
<  	}
<  	if (compat20)
< @@ -436,6 +451,7 @@
<  		} else {
<  			buffer_append(&stdout_buffer, buf, len);
<  			fdout_bytes += len;
< +			debug ("FD out now: %ld", fdout_bytes);
<  		}
<  	}
<  	/* Read and buffer any available stderr data from the program. */
< @@ -503,7 +519,7 @@
<  	}
<  	/* Send any buffered packet data to the client. */
<  	if (FD_ISSET(connection_out, writeset))
< -		packet_write_poll();
< +		stdin_bytes += packet_write_poll();
<  }
<  
<  /*
< @@ -820,8 +836,10 @@
<  {
<  	fd_set *readset = NULL, *writeset = NULL;
<  	int rekeying = 0, max_fd, nalloc = 0;
< +	double start_time, total_time;
<  
<  	debug("Entering interactive session for SSH2.");
< +	start_time = get_current_time();
<  
<  	mysignal(SIGCHLD, sigchld_handler);
<  	child_terminated = 0;
< @@ -883,6 +901,11 @@
<  
<  	/* free remaining sessions, e.g. remove wtmp entries */
<  	session_destroy_all(NULL);
< +	total_time = get_current_time() - start_time;
< +	logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f",
< +	      get_remote_ipaddr(), get_remote_port(),
< +	      stdin_bytes, fdout_bytes, total_time, stdin_bytes / total_time, 
< +	      fdout_bytes / total_time);
<  }
<  
<  static void
< @@ -998,8 +1021,12 @@
<  	sock = tun_open(tun, mode);
<  	if (sock < 0)
<  		goto done;
< +	if (options.hpn_disabled)
<  	c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
<  	    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
< +	else
< +		c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
< +		    options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
<  	c->datagram = 1;
<  #if defined(SSH_TUN_FILTER)
<  	if (mode == SSH_TUNMODE_POINTOPOINT)
< @@ -1035,6 +1062,8 @@
<  	c = channel_new("session", SSH_CHANNEL_LARVAL,
<  	    -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
<  	    0, "server-session", 1);
< +	if ((options.tcp_rcv_buf_poll) && (!options.hpn_disabled))
< +		c->dynamic_window = 1;
<  	if (session_open(the_authctxt, c->self) != 1) {
<  		debug("session open failed, free channel %d", c->self);
<  		channel_free(c);
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/session.c openssh-6.0p1/session.c
< --- openssh-6.0p1.orig/session.c	2011-11-03 18:55:24.000000000 -0500
< +++ openssh-6.0p1/session.c	2012-05-27 17:50:01.000000000 -0500
< @@ -129,6 +129,11 @@
<  
<  static int session_pty_req(Session *);
<  
< +#ifdef SESSION_HOOKS
< +static void execute_session_hook(char* prog, Authctxt *authctxt,
< +                                 int startup, int save);
< +#endif
---
> +			/* If integ avail flag is not true kex fails */
> +			if (!(ret_flags & GSS_C_INTEG_FLAG))
> +				fatal("Integrity check failed");
> +		}
6412,6433c5767,5784
<  /* import */
<  extern ServerOptions options;
<  extern char *__progname;
< @@ -236,6 +241,7 @@
<  	}
<  
<  	/* Allocate a channel for the authentication agent socket. */
< +	/* this shouldn't matter if its hpn or not - cjr */
<  	nc = channel_new("auth socket",
<  	    SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
<  	    CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
< @@ -283,6 +289,21 @@
<  	else
<  		do_authenticated1(authctxt);
<  
< +#ifdef SESSION_HOOKS
< +        if (options.session_hooks_allow &&
< +            options.session_hooks_shutdown_cmd)
< +        {
< +            execute_session_hook(options.session_hooks_shutdown_cmd,
< +                                 authctxt,
< +                                 /* startup = */ 0, /* save = */ 0);
---
> +		/* 
> +		 * If we have data to send, then the last message that we
> +		 * received cannot have been a 'complete'. 
> +		 */
> +		if (send_tok.length != 0) {
> +			if (first) {
> +				packet_start(SSH2_MSG_KEXGSS_INIT);
> +				packet_put_string(send_tok.value,
> +				    send_tok.length);
> +				packet_put_bignum2(dh->pub_key);
> +				first = 0;
> +			} else {
> +				packet_start(SSH2_MSG_KEXGSS_CONTINUE);
> +				packet_put_string(send_tok.value,
> +				    send_tok.length);
> +			}
> +			packet_send();
> +			gss_release_buffer(&min_status, &send_tok);
6435,6440c5786,5796
< +            if (authctxt->session_env_file)
< +            {
< +                free(authctxt->session_env_file);
< +            }
< +        }
< +#endif
---
> +			/* If we've sent them data, they should reply */
> +			do {	
> +				type = packet_read();
> +				if (type == SSH2_MSG_KEXGSS_HOSTKEY) {
> +					debug("Received KEXGSS_HOSTKEY");
> +					if (serverhostkey)
> +						fatal("Server host key received more than once");
> +					serverhostkey = 
> +					    packet_get_string(&slen);
> +				}
> +			} while (type == SSH2_MSG_KEXGSS_HOSTKEY);
6442,6467c5798,5810
<  	do_cleanup(authctxt);
<  }
<  
< @@ -812,6 +833,26 @@
<  		debug("Forced command (key option) '%.900s'", command);
<  	}
<  
< +#if defined(SESSION_HOOKS)
< +	if (options.session_hooks_allow &&
< +	    (options.session_hooks_startup_cmd ||
< +	     options.session_hooks_shutdown_cmd))
< +	{
< +		char env_file[1000];
< +		struct stat st;
< +		do
< +		{
< +			snprintf(env_file,
< +				 sizeof(env_file),
< +				 "/tmp/ssh_env_%d%d%d",
< +				 getuid(),
< +				 getpid(),
< +				 rand());
< +		} while (stat(env_file, &st)==0);
< +		s->authctxt->session_env_file = strdup(env_file);
< +	}
< +#endif
---
> +			switch (type) {
> +			case SSH2_MSG_KEXGSS_CONTINUE:
> +				debug("Received GSSAPI_CONTINUE");
> +				if (maj_status == GSS_S_COMPLETE) 
> +					fatal("GSSAPI Continue received from server when complete");
> +				recv_tok.value = packet_get_string(&strlen);
> +				recv_tok.length = strlen; 
> +				break;
> +			case SSH2_MSG_KEXGSS_COMPLETE:
> +				debug("Received GSSAPI_COMPLETE");
> +				packet_get_bignum2(dh_server_pub);
> +				msg_tok.value =  packet_get_string(&strlen);
> +				msg_tok.length = strlen; 
6469,6477c5812,5843
<  #ifdef SSH_AUDIT_EVENTS
<  	if (command != NULL)
<  		PRIVSEP(audit_run_command(command));
< @@ -1040,6 +1081,117 @@
<  	fclose(f);
<  }
<  
< +#ifdef SESSION_HOOKS
< +#define SSH_SESSION_ENV_FILE "SSH_SESSION_ENV_FILE"
---
> +				/* Is there a token included? */
> +				if (packet_get_char()) {
> +					recv_tok.value=
> +					    packet_get_string(&strlen);
> +					recv_tok.length = strlen;
> +					/* If we're already complete - protocol error */
> +					if (maj_status == GSS_S_COMPLETE)
> +						packet_disconnect("Protocol error: received token when complete");
> +					} else {
> +						/* No token included */
> +						if (maj_status != GSS_S_COMPLETE)
> +							packet_disconnect("Protocol error: did not receive final token");
> +				}
> +				break;
> +			case SSH2_MSG_KEXGSS_ERROR:
> +				debug("Received Error");
> +				maj_status = packet_get_int();
> +				min_status = packet_get_int();
> +				msg = packet_get_string(NULL);
> +				lang = packet_get_string(NULL);
> +				fatal("GSSAPI Error: \n%.400s",msg);
> +			default:
> +				packet_disconnect("Protocol error: didn't expect packet type %d",
> +		    		type);
> +			}
> +			token_ptr = &recv_tok;
> +		} else {
> +			/* No data, and not complete */
> +			if (maj_status != GSS_S_COMPLETE)
> +				fatal("Not complete, and no token output");
> +		}
> +	} while (maj_status & GSS_S_CONTINUE_NEEDED);
6479,6480c5845,5848
< +typedef enum { no_op, execute, clear_env, restore_env,
< +               read_env, save_or_rm_env } session_action_t;
---
> +	/* 
> +	 * We _must_ have received a COMPLETE message in reply from the 
> +	 * server, which will have set dh_server_pub and msg_tok 
> +	 */
6482,6485c5850,5851
< +static session_action_t action_order[2][5] = {
< +    { clear_env, read_env, execute, save_or_rm_env, restore_env }, /*shutdown*/
< +    { execute, read_env, save_or_rm_env, no_op, no_op }            /*startup */
< +};
---
> +	if (type != SSH2_MSG_KEXGSS_COMPLETE)
> +		fatal("Didn't receive a SSH2_MSG_KEXGSS_COMPLETE when I expected it");
6487,6491c5853,5855
< +static
< +void execute_session_hook(char* prog, Authctxt *authctxt,
< +                          int startup, int save)
< +{
< +    extern char **environ;
---
> +	/* Check f in range [1, p-1] */
> +	if (!dh_pub_is_valid(dh, dh_server_pub))
> +		packet_disconnect("bad server public DH value");
6493,6496c5857,5862
< +    struct stat  st;
< +    char         **saved_env, **tmpenv;
< +    char         *env_file = authctxt->session_env_file;
< +    int          i, status = 0;
---
> +	/* compute K=f^x mod p */
> +	klen = DH_size(dh);
> +	kbuf = xmalloc(klen);
> +	kout = DH_compute_key(kbuf, dh_server_pub, dh);
> +	if (kout < 0)
> +		fatal("DH_compute_key: failed");
6498,6503c5864,5866
< +    for (i=0; i<5; i++)
< +    {
< +        switch (action_order[startup][i])
< +        {
< +          case no_op:
< +            break;
---
> +	shared_secret = BN_new();
> +	if (shared_secret == NULL)
> +		fatal("kexgss_client: BN_new failed");
6505,6508c5868,5869
< +          case execute:
< +            {
< +                FILE* fp;
< +                char  buf[1000];
---
> +	if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
> +		fatal("kexdh_client: BN_bin2bn failed");
6510,6514c5871,5872
< +                snprintf(buf,
< +                         sizeof(buf),
< +                         "%s -c '%s'",
< +                         authctxt->pw->pw_shell,
< +                         prog);
---
> +	memset(kbuf, 0, klen);
> +	xfree(kbuf);
6516,6517c5874,5906
< +                debug("executing session hook: [%s]", buf);
< +                setenv(SSH_SESSION_ENV_FILE, env_file, /* overwrite = */ 1);
---
> +	switch (kex->kex_type) {
> +	case KEX_GSS_GRP1_SHA1:
> +	case KEX_GSS_GRP14_SHA1:
> +		kex_dh_hash( kex->client_version_string, 
> +		    kex->server_version_string,
> +		    buffer_ptr(&kex->my), buffer_len(&kex->my),
> +		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
> +		    (serverhostkey ? serverhostkey : empty), slen,
> +		    dh->pub_key,	/* e */
> +		    dh_server_pub,	/* f */
> +		    shared_secret,	/* K */
> +		    &hash, &hashlen
> +		);
> +		break;
> +	case KEX_GSS_GEX_SHA1:
> +		kexgex_hash(
> +		    kex->evp_md,
> +		    kex->client_version_string,
> +		    kex->server_version_string,
> +		    buffer_ptr(&kex->my), buffer_len(&kex->my),
> +		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
> +		    (serverhostkey ? serverhostkey : empty), slen,
> + 		    min, nbits, max,
> +		    dh->p, dh->g,
> +		    dh->pub_key,
> +		    dh_server_pub,
> +		    shared_secret,
> +		    &hash, &hashlen
> +		);
> +		break;
> +	default:
> +		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
> +	}
6519,6532c5908,5909
< +                /* flusing is recommended in the popen(3) man page, to avoid
< +                   intermingling of output */
< +                fflush(stdout);
< +                fflush(stderr);
< +                if ((fp=popen(buf, "w")) == NULL)
< +                {
< +                    perror("Unable to run session hook");
< +                    return;
< +                }
< +                status = pclose(fp);
< +                debug2("session hook executed, status=%d", status);
< +                unsetenv(SSH_SESSION_ENV_FILE);
< +            }
< +            break;
---
> +	gssbuf.value = hash;
> +	gssbuf.length = hashlen;
6534,6539c5911,5913
< +          case clear_env:
< +            saved_env = environ;
< +            tmpenv = (char**) malloc(sizeof(char*));
< +            tmpenv[0] = NULL;
< +            environ = tmpenv;
< +            break;
---
> +	/* Verify that the hash matches the MIC we just got. */
> +	if (GSS_ERROR(ssh_gssapi_checkmic(ctxt, &gssbuf, &msg_tok)))
> +		packet_disconnect("Hash's MIC didn't verify");
6541,6544c5915
< +          case restore_env:
< +            environ = saved_env;
< +            free(tmpenv);
< +            break;
---
> +	xfree(msg_tok.value);
6546,6549c5917,5920
< +          case read_env:
< +            if (status==0 && stat(env_file, &st)==0)
< +            {
< +                int envsize = 0;
---
> +	DH_free(dh);
> +	if (serverhostkey)
> +		xfree(serverhostkey);
> +	BN_clear_free(dh_server_pub);
6551,6555c5922,5927
< +                debug("reading environment from %s", env_file);
< +                while (environ[envsize++]) ;
< +                read_environment_file(&environ, &envsize, env_file);
< +            }
< +            break;
---
> +	/* save session id */
> +	if (kex->session_id == NULL) {
> +		kex->session_id_len = hashlen;
> +		kex->session_id = xmalloc(kex->session_id_len);
> +		memcpy(kex->session_id, hash, kex->session_id_len);
> +	}
6557,6561c5929,5930
< +          case save_or_rm_env:
< +            if (status==0 && save)
< +            {
< +                FILE* fp;
< +                int    envcount=0;
---
> +	if (kex->gss_deleg_creds)
> +		ssh_gssapi_credentials_updated(ctxt);
6563,6582c5932,5935
< +                debug2("saving environment to %s", env_file);
< +                if ((fp = fopen(env_file, "w")) == NULL) /* hmm: file perms? */
< +                {
< +                    perror("Unable to save session hook info");
< +                }
< +                while (environ[envcount])
< +                {
< +                    fprintf(fp, "%s\n", environ[envcount++]);
< +                }
< +                fflush(fp);
< +                fclose(fp);
< +            }
< +            else if (stat(env_file, &st)==0)
< +            {
< +                debug2("removing environment file %s", env_file);
< +                remove(env_file);
< +            }
< +            break;
< +        }
< +    }
---
> +	if (gss_kex_context == NULL)
> +		gss_kex_context = ctxt;
> +	else
> +		ssh_gssapi_delete_ctx(&ctxt);
6583a5937,5939
> +	kex_derive_keys(kex, hash, hashlen, shared_secret);
> +	BN_clear_free(shared_secret);
> +	kex_finish(kex);
6585,6670d5940
< +#endif
< +
<  #ifdef HAVE_ETC_DEFAULT_LOGIN
<  /*
<   * Return named variable from specified environment, or NULL if not present.
< @@ -1203,6 +1355,23 @@
<  	if (getenv("TZ"))
<  		child_set_env(&env, &envsize, "TZ", getenv("TZ"));
<  
< +#ifdef GSI /* GSI shared libs typically installed in non-system locations. */
< +	{
< +		char *cp;
< +
< +		if ((cp = getenv("LD_LIBRARY_PATH")) != NULL)
< +			child_set_env(&env, &envsize, "LD_LIBRARY_PATH", cp);
< +		if ((cp = getenv("LIBPATH")) != NULL)
< +			child_set_env(&env, &envsize, "LIBPATH", cp);
< +		if ((cp = getenv("SHLIB_PATH")) != NULL)
< +			child_set_env(&env, &envsize, "SHLIB_PATH", cp);
< +		if ((cp = getenv("LD_LIBRARYN32_PATH")) != NULL)
< +			child_set_env(&env, &envsize, "LD_LIBRARYN32_PATH",cp);
< +		if ((cp = getenv("LD_LIBRARY64_PATH")) != NULL)
< +			child_set_env(&env, &envsize, "LD_LIBRARY64_PATH",cp);
< +	}
< +#endif
< +
<  	/* Set custom environment options from RSA authentication. */
<  	if (!options.use_login) {
<  		while (custom_environment) {
< @@ -1620,6 +1789,18 @@
<  	struct passwd *pw = s->pw;
<  	int r = 0;
<  
< +#ifdef AFS_KRB5
< +/* Default place to look for aklog. */
< +#ifdef AKLOG_PATH
< +#define KPROGDIR AKLOG_PATH
< +#else
< +#define KPROGDIR "/usr/bin/aklog"
< +#endif /* AKLOG_PATH */
< +
< +	struct stat st;
< +	char *aklog_path;
< +#endif /* AFS_KRB5 */
< +
<  	/* remove hostkey from the child's memory */
<  	destroy_sensitive_data();
<  
< @@ -1732,6 +1913,41 @@
<  	}
<  #endif
<  
< +#ifdef AFS_KRB5
< +
< +	/* User has authenticated, and if a ticket was going to be
< +	 * passed we would have it.  KRB5CCNAME should already be set.
< +	 * Now try to get an AFS token using aklog.
< +	 */
< +	if (k_hasafs()) {  /* Do we have AFS? */
< +
< +		aklog_path = xstrdup(KPROGDIR);
< +
< +		/*
< +		 * Make sure it exists before we try to run it
< +		 */
< +		if (stat(aklog_path, &st) == 0) {
< +			debug("Running %s to get afs token.",aklog_path);
< +			system(aklog_path);
< +		} else {
< +			debug("%s does not exist.",aklog_path);
< +		}
< +
< +		xfree(aklog_path);
< +	}
< +#endif /* AFS_KRB5 */
< +
< +#ifdef SESSION_HOOKS
< +        if (options.session_hooks_allow &&
< +            options.session_hooks_startup_cmd)
< +        {
< +            execute_session_hook(options.session_hooks_startup_cmd,
< +                                 s->authctxt,
< +                                 /* startup = */ 1,
< +                                 options.session_hooks_shutdown_cmd != NULL);
< +        }
< +#endif
6672,6738c5942,5946
<  	/* Change current directory to the user's home directory. */
<  	if (chdir(pw->pw_dir) < 0) {
<  		/* Suppress missing homedir warning for chroot case */
< @@ -1812,7 +2028,7 @@
<  		/* Execute the shell. */
<  		argv[0] = argv0;
<  		argv[1] = NULL;
< -		execve(shell, argv, env);
< +		execve(shell, argv, environ);
<  
<  		/* Executing the shell failed. */
<  		perror(shell);
< @@ -1826,7 +2042,7 @@
<  	argv[1] = "-c";
<  	argv[2] = (char *) command;
<  	argv[3] = NULL;
< -	execve(shell, argv, env);
< +	execve(shell, argv, environ);
<  	perror(shell);
<  	exit(1);
<  }
< @@ -2278,10 +2494,16 @@
<  	 */
<  	if (s->chanid == -1)
<  		fatal("no channel for session %d", s->self);
< +	if (options.hpn_disabled)
<  	channel_set_fds(s->chanid,
<  	    fdout, fdin, fderr,
<  	    ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
<  	    1, is_tty, CHAN_SES_WINDOW_DEFAULT);
< +	else
< +		channel_set_fds(s->chanid,
< +		    fdout, fdin, fderr,
< +		    ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
< +		    1, is_tty, options.hpn_buffer_size);
<  }
<  
<  /*
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/sftp.1 openssh-6.0p1/sftp.1
< --- openssh-6.0p1.orig/sftp.1	2011-09-22 06:34:15.000000000 -0500
< +++ openssh-6.0p1/sftp.1	2012-05-27 17:50:01.000000000 -0500
< @@ -247,7 +247,8 @@
<  Specify how many requests may be outstanding at any one time.
<  Increasing this may slightly improve file transfer speed
<  but will increase memory usage.
< -The default is 64 outstanding requests.
< +The default is 256 outstanding requests providing for 8MB 
< +of outstanding data with a 32KB buffer.
<  .It Fl r
<  Recursively copy entire directories when uploading and downloading.
<  Note that
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/sftp.c openssh-6.0p1/sftp.c
< --- openssh-6.0p1.orig/sftp.c	2011-11-24 20:53:50.000000000 -0600
< +++ openssh-6.0p1/sftp.c	2012-05-27 17:50:01.000000000 -0500
< @@ -69,7 +69,7 @@
<  #include "sftp-client.h"
<  
<  #define DEFAULT_COPY_BUFLEN	32768	/* Size of buffer for up/download */
< -#define DEFAULT_NUM_REQUESTS	64	/* # concurrent outstanding requests */
< +#define DEFAULT_NUM_REQUESTS	256	/* # concurrent outstanding requests */
<  
<  /* File to read commands from */
<  FILE* infile;
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/ssh-globus-usage.c openssh-6.0p1/ssh-globus-usage.c
< --- openssh-6.0p1.orig/ssh-globus-usage.c	1969-12-31 18:00:00.000000000 -0600
< +++ openssh-6.0p1/ssh-globus-usage.c	2012-05-27 17:50:01.000000000 -0500
< @@ -0,0 +1,396 @@
---
> +#endif /* GSSAPI */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/kexgsss.c openssh-6.0p1/kexgsss.c
> --- openssh-6.0p1.orig/kexgsss.c	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/kexgsss.c	2012-07-12 17:01:14.282689289 +0200
> @@ -0,0 +1,311 @@
6740,6752c5948
< + * Copyright 2009 The Board of Trustees of the University
< + * of Illinois.  See the LICENSE file for detailed license information.
< + *
< + * Portions, specifically log_usage_stats(), ssh_usage_stats_init(),
< + * ssh_usage_stats_close(), ssh_usage_ent_s, ssh_usage_tag_e and
< + * TAG #defines were based on those from Usage Metrics portions of:
< + * gridftp/server/source/globus_i_gfs_log.c
< + *
< + * Copyright 1999-2006 University of Chicago
< + *
< + * Licensed under the Apache License, Version 2.0 (the "License");
< + * you may not use this file except in compliance with the License.
< + * You may obtain a copy of the License at
---
> + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
6754c5950,5957
< + * http://www.apache.org/licenses/LICENSE-2.0
---
> + * Redistribution and use in source and binary forms, with or without
> + * modification, are permitted provided that the following conditions
> + * are met:
> + * 1. Redistributions of source code must retain the above copyright
> + *    notice, this list of conditions and the following disclaimer.
> + * 2. Redistributions in binary form must reproduce the above copyright
> + *    notice, this list of conditions and the following disclaimer in the
> + *    documentation and/or other materials provided with the distribution.
6756,6760c5959,5968
< + * Unless required by applicable law or agreed to in writing, software
< + * distributed under the License is distributed on an "AS IS" BASIS,
< + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
< + * See the License for the specific language governing permissions and
< + * limitations under the License.
---
> + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
> + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
> + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
> + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
> + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
> + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6765,6768c5973
< +#ifdef HAVE_GLOBUS_USAGE
< +
< +#include <stdarg.h>
< +#include <unistd.h> 
---
> +#ifdef GSSAPI
6770,6771c5975
< +#include "log.h"
< +#include "ssh-globus-usage.h"
---
> +#include <string.h>
6773c5977,5978
< +static globus_list_t *usage_handle_list = NULL;
---
> +#include <openssl/crypto.h>
> +#include <openssl/bn.h>
6775,6776c5980,5991
< +#define SSH_GLOBUS_USAGE_ID 12
< +#define SSH_GLOBUS_USAGE_VER 0
---
> +#include "xmalloc.h"
> +#include "buffer.h"
> +#include "ssh2.h"
> +#include "key.h"
> +#include "cipher.h"
> +#include "kex.h"
> +#include "log.h"
> +#include "packet.h"
> +#include "dh.h"
> +#include "ssh-gss.h"
> +#include "monitor_wrap.h"
> +#include "servconf.h"
6778,6780c5993,5994
< +#define SSH_GLOBUS_DEFAULT_TAGLIST "VvMm"
< +#define SSH_GLOBUS_ALL_TAGLIST     "VvMmIuU"
< +#define SSH_GLOBUS_TAGCOUNT 25
---
> +static void kex_gss_send_error(Gssctxt *ctxt);
> +extern ServerOptions options;
6782c5996,5997
< +typedef enum ssh_usage_tag_e
---
> +void
> +kexgss_server(Kex *kex)
6784,6800c5999,6006
< +    SSH_GLOBUS_USAGE_SSH_VER        = 'V',
< +    SSH_GLOBUS_USAGE_SSL_VER        = 'v',
< +    SSH_GLOBUS_USAGE_METHOD         = 'M',
< +    SSH_GLOBUS_USAGE_MECHANISM      = 'm',
< +    SSH_GLOBUS_USAGE_CLIENTIP       = 'I',
< +    SSH_GLOBUS_USAGE_USERNAME       = 'u',
< +    SSH_GLOBUS_USAGE_USERDN         = 'U'
< +    /* !! ADD to ALL_TAGLIST above and to globus_usage_stats_send()
< +          invocation below when adding here */
< +} ssh_usage_tag_t;
< +
< +typedef struct ssh_usage_ent_s
< +{
< +    globus_usage_stats_handle_t         handle;
< +    char *                              target;
< +    char *                              taglist;
< +} ssh_usage_ent_t;
---
> +	OM_uint32 maj_status, min_status;
> +	
> +	/* 
> +	 * Some GSSAPI implementations use the input value of ret_flags (an
> + 	 * output variable) as a means of triggering mechanism specific 
> + 	 * features. Initializing it to zero avoids inadvertently 
> + 	 * activating this non-standard behaviour.
> +	 */
6801a6008,6020
> +	OM_uint32 ret_flags = 0;
> +	gss_buffer_desc gssbuf, recv_tok, msg_tok;
> +	gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
> +	Gssctxt *ctxt = NULL;
> +	u_int slen, klen, kout, hashlen;
> +	u_char *kbuf, *hash;
> +	DH *dh;
> +	int min = -1, max = -1, nbits = -1;
> +	BIGNUM *shared_secret = NULL;
> +	BIGNUM *dh_client_pub = NULL;
> +	int type = 0;
> +	gss_OID oid;
> +	char *mechs;
6803,6812c6022
< +globus_result_t
< +ssh_usage_stats_init(int disable_usage_stats, char *usage_stats_targets)
< +{
< +    globus_result_t                     result;
< +    char *                              target_str = NULL;
< +    char *                              ptr = ptr;
< +    char *                              target = NULL;
< +    char *                              entry = NULL;
< +    globus_list_t *                     list = NULL;
< +    ssh_usage_ent_t *               usage_ent = NULL;
---
> +	/* Initialise GSSAPI */
6814,6815c6024,6030
< +    if (disable_usage_stats)
< +	return GLOBUS_SUCCESS;
---
> +	/* If we're rekeying, privsep means that some of the private structures
> +	 * in the GSSAPI code are no longer available. This kludges them back
> +	 * into life
> +	 */
> +	if (!ssh_gssapi_oid_table_ok()) 
> +		if ((mechs = ssh_gssapi_server_mechanisms()))
> +			xfree(mechs);
6817,6822c6032,6035
< +    result = globus_module_activate(GLOBUS_USAGE_MODULE);
< +    if (result != GLOBUS_SUCCESS)
< +    {
< +        error("ERROR: couldn't activate USAGE STATS module");
< +        return result;
< +    }
---
> +	debug2("%s: Identifying %s", __func__, kex->name);
> +	oid = ssh_gssapi_id_kex(NULL, kex->name, kex->kex_type);
> +	if (oid == GSS_C_NO_OID)
> +	   fatal("Unknown gssapi mechanism");
6824,6828c6037
< +    if (!usage_stats_targets ||
< +        !strcasecmp(usage_stats_targets, "default"))
< +        target_str = strdup(CILOGON_COLLECTOR);
< +    else
< +        target_str = strdup(usage_stats_targets);
---
> +	debug2("%s: Acquiring credentials", __func__);
6830,6833c6039,6041
< +    if (target_str == NULL)
< +    {
< +        error("ERROR: strdup failure for target_str");
< +        goto error;
---
> +	if (GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctxt, oid)))) {
> +		kex_gss_send_error(ctxt);
> +		fatal("Unable to acquire credentials for the server");
6835,6847d6042
< +    debug("Processing usage_stats_target (%s)\n", target_str);
< +
< +    if(target_str && (strchr(target_str, ',') || strchr(target_str, '!')))
< +    {
< +        target = target_str;
< +
< +        do {
< +            usage_ent = (ssh_usage_ent_t *) malloc(sizeof(ssh_usage_ent_t));
< +            if (usage_ent == NULL)
< +            {
< +                error("ERROR: couldn't allocate for ssh_usage_ent_t");
< +                goto error;
< +            }
6849,6850c6044,6065
< +            if ((ptr = strchr(target, ',')) != NULL)
< +                *ptr = '\0';
---
> +	switch (kex->kex_type) {
> +	case KEX_GSS_GRP1_SHA1:
> +		dh = dh_new_group1();
> +		break;
> +	case KEX_GSS_GRP14_SHA1:
> +		dh = dh_new_group14();
> +		break;
> +	case KEX_GSS_GEX_SHA1:
> +		debug("Doing group exchange");
> +		packet_read_expect(SSH2_MSG_KEXGSS_GROUPREQ);
> +		min = packet_get_int();
> +		nbits = packet_get_int();
> +		max = packet_get_int();
> +		min = MAX(DH_GRP_MIN, min);
> +		max = MIN(DH_GRP_MAX, max);
> +		packet_check_eom();
> +		if (max < min || nbits < min || max < nbits)
> +			fatal("GSS_GEX, bad parameters: %d !< %d !< %d",
> +			    min, nbits, max);
> +		dh = PRIVSEP(choose_dh(min, nbits, max));
> +		if (dh == NULL)
> +			packet_disconnect("Protocol error: no matching group found");
6852,6857c6067,6070
< +            entry = strdup(target);
< +            if (entry == NULL)
< +            {
< +                error("ERROR: strdup failure for target");
< +                goto error;
< +            }
---
> +		packet_start(SSH2_MSG_KEXGSS_GROUP);
> +		packet_put_bignum2(dh->p);
> +		packet_put_bignum2(dh->g);
> +		packet_send();
6859,6862c6072,6076
< +            if (ptr)
< +                target = ptr + 1;
< +            else
< +                target = NULL;
---
> +		packet_write_wait();
> +		break;
> +	default:
> +		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
> +	}
6864,6909c6078
< +            if((ptr = strchr(entry, '!')) != NULL)
< +            {
< +                *ptr = '\0';
< +                usage_ent->taglist = strdup(ptr + 1);
< +                if (usage_ent->taglist == NULL)
< +                {
< +                    error("ERROR: strdup failure for taglist");
< +                    goto error;
< +                }
< +                if(strlen(usage_ent->taglist) > SSH_GLOBUS_TAGCOUNT)
< +                {
< +                    usage_ent->taglist[SSH_GLOBUS_TAGCOUNT + 1] = '\0';
< +                }
< +            }
< +            else
< +            {
< +                usage_ent->taglist = strdup(SSH_GLOBUS_DEFAULT_TAGLIST);
< +                if (usage_ent->taglist == NULL)
< +                {
< +                    error("ERROR: couldn't allocate for taglist");
< +                    goto error;
< +                }
< +            }
< +            
< +            if(strcasecmp(usage_ent->taglist, "default") == 0)
< +            {
< +                free(usage_ent->taglist);
< +                usage_ent->taglist = strdup(SSH_GLOBUS_DEFAULT_TAGLIST);
< +                if (usage_ent->taglist == NULL)
< +                {
< +                    error("ERROR: couldn't allocate for taglist");
< +                    goto error;
< +                }
< +            }                
< +            else if(strcasecmp(usage_ent->taglist, "all") == 0)
< +            {
< +                free(usage_ent->taglist);
< +                usage_ent->taglist = strdup(SSH_GLOBUS_ALL_TAGLIST);
< +                if (usage_ent->taglist == NULL)
< +                {
< +                    error("ERROR: couldn't allocate for taglist");
< +                    goto error;
< +                }
< +            }
< +            
< +            usage_ent->target = entry;
---
> +	dh_gen_key(dh, kex->we_need * 8);
6911,6913c6080,6088
< +            globus_list_insert(&usage_handle_list, usage_ent);
< +        }
< +        while(target != NULL);
---
> +	do {
> +		debug("Wait SSH2_MSG_GSSAPI_INIT");
> +		type = packet_read();
> +		switch(type) {
> +		case SSH2_MSG_KEXGSS_INIT:
> +			if (dh_client_pub != NULL) 
> +				fatal("Received KEXGSS_INIT after initialising");
> +			recv_tok.value = packet_get_string(&slen);
> +			recv_tok.length = slen; 
6915,6924c6090,6091
< +        free(target_str);
< +    }
< +    else
< +    {
< +        usage_ent = (ssh_usage_ent_t *) malloc(sizeof(ssh_usage_ent_t));
< +        if (usage_ent == NULL)
< +        {
< +             error("ERROR: couldn't allocate for usage_ent");
< +             goto error;
< +        }
---
> +			if ((dh_client_pub = BN_new()) == NULL)
> +				fatal("dh_client_pub == NULL");
6926,6932c6093
< +        usage_ent->target = target_str;
< +        usage_ent->taglist = strdup(SSH_GLOBUS_DEFAULT_TAGLIST);
< +        if (usage_ent->taglist == NULL)
< +        {
< +             error("ERROR: couldn't allocate for taglist");
< +             goto error;
< +        }
---
> +			packet_get_bignum2(dh_client_pub);
6934,6935c6095,6105
< +        globus_list_insert(&usage_handle_list, usage_ent);
< +    }
---
> +			/* Send SSH_MSG_KEXGSS_HOSTKEY here, if we want */
> +			break;
> +		case SSH2_MSG_KEXGSS_CONTINUE:
> +			recv_tok.value = packet_get_string(&slen);
> +			recv_tok.length = slen; 
> +			break;
> +		default:
> +			packet_disconnect(
> +			    "Protocol error: didn't expect packet type %d",
> +			    type);
> +		}
6937,6942c6107,6108
< +    result = GLOBUS_SUCCESS;
< +    for(list = usage_handle_list;
< +        !globus_list_empty(list);
< +        list = globus_list_rest(list))
< +    {
< +        usage_ent = (ssh_usage_ent_t *) globus_list_first(list);
---
> +		maj_status = PRIVSEP(ssh_gssapi_accept_ctx(ctxt, &recv_tok, 
> +		    &send_tok, &ret_flags));
6944,6957c6110
< +        usage_ent->handle = NULL;
< +        if (globus_usage_stats_handle_init(
< +            &usage_ent->handle,
< +            SSH_GLOBUS_USAGE_ID,
< +            SSH_GLOBUS_USAGE_VER,
< +            usage_ent->target) != GLOBUS_SUCCESS)
< +        {
< +            error("USAGE-STATS: Error initializing (%s) (%s)",
< +                     usage_ent->target?:"NULL",
< +                     usage_ent->taglist?:"NULL");
< +            result = GLOBUS_FAILURE;
< +        } else
< +            debug("USAGE-STATS: Initialized (%s) (%s)", usage_ent->target?:"NULL",
< +                     usage_ent->taglist?:"NULL");
---
> +		xfree(recv_tok.value);
6959c6112,6113
< +    }
---
> +		if (maj_status != GSS_S_COMPLETE && send_tok.length == 0)
> +			fatal("Zero length token output when incomplete");
6961c6115,6125
< +    return result;
---
> +		if (dh_client_pub == NULL)
> +			fatal("No client public key");
> +		
> +		if (maj_status & GSS_S_CONTINUE_NEEDED) {
> +			debug("Sending GSSAPI_CONTINUE");
> +			packet_start(SSH2_MSG_KEXGSS_CONTINUE);
> +			packet_put_string((char *)send_tok.value, send_tok.length);
> +			packet_send();
> +			gss_release_buffer(&min_status, &send_tok);
> +		}
> +	} while (maj_status & GSS_S_CONTINUE_NEEDED);
6963,6975c6127,6135
< +error:
< +    if (target_str)
< +    {
< +        free(target_str); 
< +        target_str = NULL;
< +    }
< +    if (entry)
< +    {
< +        free(target_str); 
< +        target_str = NULL;
< +    }
< +    return GLOBUS_FAILURE;
< +}
---
> +	if (GSS_ERROR(maj_status)) {
> +		kex_gss_send_error(ctxt);
> +		if (send_tok.length > 0) {
> +			packet_start(SSH2_MSG_KEXGSS_CONTINUE);
> +			packet_put_string((char *)send_tok.value, send_tok.length);
> +			packet_send();
> +		}
> +		packet_disconnect("GSSAPI Key Exchange handshake failed");
> +	}
6977,6980c6137,6138
< +void
< +ssh_usage_stats_close(int disable_usage_stats)
< +{
< +    globus_list_t *list;
---
> +	if (!(ret_flags & GSS_C_MUTUAL_FLAG))
> +		fatal("Mutual Authentication flag wasn't set");
6982,6983c6140,6144
< +    if (disable_usage_stats)
< +	return;
---
> +	if (!(ret_flags & GSS_C_INTEG_FLAG))
> +		fatal("Integrity flag wasn't set");
> +	
> +	if (!dh_pub_is_valid(dh, dh_client_pub))
> +		packet_disconnect("bad client public DH value");
6985,7012c6146,6150
< +    list = usage_handle_list;
< +    
< +    while(!globus_list_empty(list))
< +    {
< +        ssh_usage_ent_t *usage_ent;
< +        
< +        usage_ent = (ssh_usage_ent_t *) 
< +            globus_list_remove(&list, list);
< +    
< +        if(usage_ent)
< +        {
< +            if(usage_ent->handle)
< +            {
< +                globus_usage_stats_handle_destroy(usage_ent->handle);
< +            }
< +            if(usage_ent->target)
< +            {
< +                free(usage_ent->target);
< +            }
< +            if(usage_ent->taglist)
< +            {
< +                free(usage_ent->taglist);
< +            }
< +            free(usage_ent);
< +        }
< +    }
< +    usage_handle_list = NULL;
< +}
---
> +	klen = DH_size(dh);
> +	kbuf = xmalloc(klen); 
> +	kout = DH_compute_key(kbuf, dh_client_pub, dh);
> +	if (kout < 0)
> +		fatal("DH_compute_key: failed");
7014,7028c6152,6154
< +static void
< +log_usage_stats(char *ssh_release, const char *ssl_release,
< +                char *method, char *mechanism, const char *clientip,
< +                char *username, char *userdn)
< +{
< +    globus_result_t                     result;
< +    globus_list_t *                     list;
< +    ssh_usage_ent_t *                   usage_ent;
< +    char *                              keys[SSH_GLOBUS_TAGCOUNT];
< +    char *                              values[SSH_GLOBUS_TAGCOUNT];
< +    char *                              ptr;
< +    char *                              key;
< +    char *                              value;
< +    int                                 i = 0;
< +    char *                              save_taglist = NULL;
---
> +	shared_secret = BN_new();
> +	if (shared_secret == NULL)
> +		fatal("kexgss_server: BN_new failed");
7030,7034c6156,6157
< +    for(list = usage_handle_list;
< +        !globus_list_empty(list);
< +        list = globus_list_rest(list))
< +    {
< +        usage_ent = (ssh_usage_ent_t *) globus_list_first(list);
---
> +	if (BN_bin2bn(kbuf, kout, shared_secret) == NULL)
> +		fatal("kexgss_server: BN_bin2bn failed");
7036,7100c6159,6160
< +        if(!usage_ent || usage_ent->handle == NULL)
< +            continue;
< +        
< +        if(save_taglist == NULL || 
< +            strcmp(save_taglist, usage_ent->taglist) != 0)
< +        {
< +            save_taglist = usage_ent->taglist;
< +            
< +            ptr = usage_ent->taglist;
< +            i = 0;
< +            while(ptr && *ptr)
< +            {
< +                switch(*ptr)
< +                {
< +                  case SSH_GLOBUS_USAGE_SSH_VER:
< +                    key = "SSH_VER";
< +                    value = ssh_release;
< +                    break;
< +    
< +                  case SSH_GLOBUS_USAGE_SSL_VER:
< +                    key = "SSL_VER";
< +                    value = (char *) ssl_release;
< +                    break;
< +    
< +                  case SSH_GLOBUS_USAGE_METHOD:
< +                    key = "METHOD";
< +                    value = method;
< +                    break;
< +    
< +                  case SSH_GLOBUS_USAGE_MECHANISM:
< +                    key = "MECH";
< +                    value = mechanism?:"";
< +                    break;
< +    
< +                  case SSH_GLOBUS_USAGE_CLIENTIP:
< +                    key = "CLIENTIP";
< +                    value = (char *) clientip?:"";
< +                    break;
< +    
< +                  case SSH_GLOBUS_USAGE_USERNAME:
< +                    key = "USER";
< +                    value = username?:"";
< +                    break;
< +    
< +                  case SSH_GLOBUS_USAGE_USERDN:
< +                    key = "USERDN";
< +                    value = userdn?:"";
< +                    break;
< +    
< +                  default:
< +                    key = NULL;
< +                    value = NULL;
< +                    break;
< +                }
< +                
< +                if(key != NULL && value != NULL)
< +                {
< +                    keys[i] = key;
< +                    values[i] = value;
< +                    i++;
< +                }
< +                
< +                ptr++;
< +            }
< +        }
---
> +	memset(kbuf, 0, klen);
> +	xfree(kbuf);
7102,7121c6162,6191
< +#ifdef HAVE_GLOBUS_USAGE_SEND_ARRAY
< +        result = globus_usage_stats_send_array(
< +            usage_ent->handle, i, keys, values);
< +#else
< +        if (i)
< +            result = globus_usage_stats_send(
< +                usage_ent->handle, i,
< +                i>0?keys[0]:NULL, i>0?values[0]:NULL,
< +                i>1?keys[1]:NULL, i>1?values[1]:NULL,
< +                i>2?keys[2]:NULL, i>2?values[2]:NULL,
< +                i>3?keys[3]:NULL, i>3?values[3]:NULL,
< +                i>4?keys[4]:NULL, i>4?values[4]:NULL,
< +                i>5?keys[5]:NULL, i>5?values[5]:NULL,
< +                i>6?keys[6]:NULL, i>6?values[6]:NULL);
< +#endif /* HAVE_GLOBUS_USAGE_SEND_ARRAY */
< +    }
< +    
< +    return;
< +}
< +#endif /* HAVE_GLOBUS_USAGE */
---
> +	switch (kex->kex_type) {
> +	case KEX_GSS_GRP1_SHA1:
> +	case KEX_GSS_GRP14_SHA1:
> +		kex_dh_hash(
> +		    kex->client_version_string, kex->server_version_string,
> +		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
> +		    buffer_ptr(&kex->my), buffer_len(&kex->my),
> +		    NULL, 0, /* Change this if we start sending host keys */
> +		    dh_client_pub, dh->pub_key, shared_secret,
> +		    &hash, &hashlen
> +		);
> +		break;
> +	case KEX_GSS_GEX_SHA1:
> +		kexgex_hash(
> +		    kex->evp_md,
> +		    kex->client_version_string, kex->server_version_string,
> +		    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
> +		    buffer_ptr(&kex->my), buffer_len(&kex->my),
> +		    NULL, 0,
> +		    min, nbits, max,
> +		    dh->p, dh->g,
> +		    dh_client_pub,
> +		    dh->pub_key,
> +		    shared_secret,
> +		    &hash, &hashlen
> +		);
> +		break;
> +	default:
> +		fatal("%s: Unexpected KEX type %d", __func__, kex->kex_type);
> +	}
7123,7128c6193
< +void
< +ssh_globus_send_usage_metrics(char *ssh_release, const char *ssl_release,
< +                              char *method, char *mechanism, const char *client_ip,
< +                              char *username, char *userdn)
< +{
< +#ifdef HAVE_GLOBUS_USAGE
---
> +	BN_clear_free(dh_client_pub);
7130,7131c6195,6199
< +    log_usage_stats(ssh_release, ssl_release, method, mechanism,
< +                    client_ip, username, userdn);
---
> +	if (kex->session_id == NULL) {
> +		kex->session_id_len = hashlen;
> +		kex->session_id = xmalloc(kex->session_id_len);
> +		memcpy(kex->session_id, hash, kex->session_id_len);
> +	}
7133,7158c6201,6202
< +#endif /* HAVE_GLOBUS_USAGE */
< +}
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/ssh-globus-usage.h openssh-6.0p1/ssh-globus-usage.h
< --- openssh-6.0p1.orig/ssh-globus-usage.h	1969-12-31 18:00:00.000000000 -0600
< +++ openssh-6.0p1/ssh-globus-usage.h	2012-05-27 17:50:01.000000000 -0500
< @@ -0,0 +1,46 @@
< +/*
< + * Copyright 2009 The Board of Trustees of the University
< + * of Illinois.  See the LICENSE file for detailed license information.
< + *
< + * Portions, specifically ssh_usage_stats_init(), ssh_usage_stats_close()
< + * were based on those from: gridftp/server/source/globus_i_gfs_log.h
< + * Copyright 1999-2006 University of Chicago
< + * 
< + * Licensed under the Apache License, Version 2.0 (the "License");
< + * you may not use this file except in compliance with the License.
< + * You may obtain a copy of the License at
< + * 
< + * http://www.apache.org/licenses/LICENSE-2.0
< + * 
< + * Unless required by applicable law or agreed to in writing, software
< + * distributed under the License is distributed on an "AS IS" BASIS,
< + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
< + * See the License for the specific language governing permissions and
< + * limitations under the License.
< + */
---
> +	gssbuf.value = hash;
> +	gssbuf.length = hashlen;
7160,7161c6204,6205
< +#ifndef __SSH_GLOBUS_USAGE_H
< +#define __SSH_GLOBUS_USAGE_H
---
> +	if (GSS_ERROR(PRIVSEP(ssh_gssapi_sign(ctxt,&gssbuf,&msg_tok))))
> +		fatal("Couldn't get MIC");
7163c6207,6209
< +#include "includes.h"
---
> +	packet_start(SSH2_MSG_KEXGSS_COMPLETE);
> +	packet_put_bignum2(dh->pub_key);
> +	packet_put_string((char *)msg_tok.value,msg_tok.length);
7165,7167c6211,6217
< +#ifdef HAVE_GLOBUS_USAGE
< +
< +#include "globus_usage.h"
---
> +	if (send_tok.length != 0) {
> +		packet_put_char(1); /* true */
> +		packet_put_string((char *)send_tok.value, send_tok.length);
> +	} else {
> +		packet_put_char(0); /* false */
> +	}
> +	packet_send();
7169c6219,6220
< +#define CILOGON_COLLECTOR "usage-stats.cilogon.org:4810"
---
> +	gss_release_buffer(&min_status, &send_tok);
> +	gss_release_buffer(&min_status, &msg_tok);
7171,7172c6222,6225
< +globus_result_t
< +ssh_usage_stats_init(int disable_usage_stats, char *usage_stats_targets);
---
> +	if (gss_kex_context == NULL)
> +		gss_kex_context = ctxt;
> +	else 
> +		ssh_gssapi_delete_ctx(&ctxt);
7174,7175c6227
< +void
< +ssh_usage_stats_close(int disable_usage_stats);
---
> +	DH_free(dh);
7177c6229,6231
< +#endif /* HAVE_GLOBUS_USAGE */
---
> +	kex_derive_keys(kex, hash, hashlen, shared_secret);
> +	BN_clear_free(shared_secret);
> +	kex_finish(kex);
7179,7182c6233,6237
< +void
< +ssh_globus_send_usage_metrics(char *ssh_release, const char *ssl_release,
< +                           char *method, char *mechanism, const char *client_ip,
< +                           char *username, char *userdn);
---
> +	/* If this was a rekey, then save out any delegated credentials we
> +	 * just exchanged.  */
> +	if (options.gss_store_rekey)
> +		ssh_gssapi_rekey_creds();
> +}
7184,7208c6239,6269
< +#endif /* __SSH_GLOBUS_USAGE_H */
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/ssh-gss.h openssh-6.0p1/ssh-gss.h
< --- openssh-6.0p1.orig/ssh-gss.h	2007-06-12 08:40:39.000000000 -0500
< +++ openssh-6.0p1/ssh-gss.h	2012-05-27 17:50:01.000000000 -0500
< @@ -1,6 +1,6 @@
<  /* $OpenBSD: ssh-gss.h,v 1.10 2007/06/12 08:20:00 djm Exp $ */
<  /*
< - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
< + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
<   *
<   * Redistribution and use in source and binary forms, with or without
<   * modification, are permitted provided that the following conditions
< @@ -34,6 +34,7 @@
<  #include <gssapi/gssapi.h>
<  #endif
<  
< +#ifndef MECHGLUE
<  #ifdef KRB5
<  # ifndef HEIMDAL
<  #  ifdef HAVE_GSSAPI_GENERIC_H
< @@ -49,6 +50,7 @@
<  #endif /* GSS_C_NT_... */
<  #endif /* !HEIMDAL */
<  #endif /* KRB5 */
< +#endif /* !MECHGLUE */
---
> +static void 
> +kex_gss_send_error(Gssctxt *ctxt) {
> +	char *errstr;
> +	OM_uint32 maj,min;
> +		
> +	errstr=PRIVSEP(ssh_gssapi_last_error(ctxt,&maj,&min));
> +	if (errstr) {
> +		packet_start(SSH2_MSG_KEXGSS_ERROR);
> +		packet_put_int(maj);
> +		packet_put_int(min);
> +		packet_put_cstring(errstr);
> +		packet_put_cstring("");
> +		packet_send();
> +		packet_write_wait();
> +		/* XXX - We should probably log the error locally here */
> +		xfree(errstr);
> +	}
> +}
> +#endif /* GSSAPI */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/kex.h openssh-6.0p1/kex.h
> --- openssh-6.0p1.orig/kex.h	2012-07-12 17:00:49.318200817 +0200
> +++ openssh-6.0p1/kex.h	2012-07-12 17:01:14.270689054 +0200
> @@ -73,6 +73,9 @@
>  	KEX_DH_GEX_SHA1,
>  	KEX_DH_GEX_SHA256,
>  	KEX_ECDH_SHA2,
> +	KEX_GSS_GRP1_SHA1,
> +	KEX_GSS_GRP14_SHA1,
> +	KEX_GSS_GEX_SHA1,
>  	KEX_MAX
>  };
7210,7212c6271,6284
<  /* draft-ietf-secsh-gsskeyex-06 */
<  #define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE		60
< @@ -60,10 +62,22 @@
---
> @@ -129,6 +132,12 @@
>  	sig_atomic_t done;
>  	int	flags;
>  	const EVP_MD *evp_md;
> +#ifdef GSSAPI
> +	int	gss_deleg_creds;
> +	int	gss_trust_dns;
> +	char    *gss_host;
> +	char	*gss_client;
> +#endif
>  	char	*client_version_string;
>  	char	*server_version_string;
>  	int	(*verify_host_key)(Key *);
> @@ -140,6 +149,8 @@
7214c6286
<  #define SSH_GSS_OIDTYPE 0x06
---
>  int	 kex_names_valid(const char *);
7216,7225c6288
< +#define SSH2_MSG_KEXGSS_INIT                            30
< +#define SSH2_MSG_KEXGSS_CONTINUE                        31
< +#define SSH2_MSG_KEXGSS_COMPLETE                        32
< +#define SSH2_MSG_KEXGSS_HOSTKEY                         33
< +#define SSH2_MSG_KEXGSS_ERROR                           34
< +#define SSH2_MSG_KEXGSS_GROUPREQ			40
< +#define SSH2_MSG_KEXGSS_GROUP				41
< +#define KEX_GSS_GRP1_SHA1_ID				"gss-group1-sha1-"
< +#define KEX_GSS_GRP14_SHA1_ID				"gss-group14-sha1-"
< +#define KEX_GSS_GEX_SHA1_ID				"gss-gex-sha1-"
---
> +void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]);
7227,7245c6290,6291
<  typedef struct {
<  	char *filename;
<  	char *envvar;
<  	char *envval;
< +	struct passwd *owner;
<  	void *data;
<  } ssh_gssapi_ccache;
<  
< @@ -71,8 +85,12 @@
<  	gss_buffer_desc displayname;
<  	gss_buffer_desc exportedname;
<  	gss_cred_id_t creds;
< +	gss_name_t name;
<  	struct ssh_gssapi_mech_struct *mech;
<  	ssh_gssapi_ccache store;
< +    gss_ctx_id_t context; /* needed for globus_gss_assist_map_and_authorize() */
< +	int used;
< +	int updated;
<  } ssh_gssapi_client;
---
>  Kex	*kex_setup(char *[PROPOSAL_MAX]);
>  void	 kex_finish(Kex *);
7247,7253c6293,6295
<  typedef struct ssh_gssapi_mech_struct {
< @@ -83,6 +101,7 @@
<  	int (*userok) (ssh_gssapi_client *, char *);
<  	int (*localname) (ssh_gssapi_client *, char **);
<  	void (*storecreds) (ssh_gssapi_client *);
< +	int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *);
<  } ssh_gssapi_mech;
---
> @@ -156,6 +167,16 @@
>  void	 kexecdh_client(Kex *);
>  void	 kexecdh_server(Kex *);
7255,7266c6297,6328
<  typedef struct {
< @@ -90,13 +109,14 @@
<  	OM_uint32	minor; /* both */
<  	gss_ctx_id_t	context; /* both */
<  	gss_name_t	name; /* both */
< -	gss_OID		oid; /* client */
< +	gss_OID		oid; /* both */
<  	gss_cred_id_t	creds; /* server */
<  	gss_name_t	client; /* server */
< -	gss_cred_id_t	client_creds; /* server */
< +	gss_cred_id_t	client_creds; /* both */
<  } Gssctxt;
---
> +#ifdef GSSAPI
> +void	kexgss_client(Kex *);
> +void	kexgss_server(Kex *);
> +#endif
> +
> +#ifdef GSSAPI
> +void	kexgss_client(Kex *);
> +void	kexgss_server(Kex *);
> +#endif
> +
>  void
>  kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
>      BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/key.c openssh-6.0p1/key.c
> --- openssh-6.0p1.orig/key.c	2012-07-12 17:00:49.370201835 +0200
> +++ openssh-6.0p1/key.c	2012-07-12 17:01:14.294689524 +0200
> @@ -971,6 +971,8 @@
>  		}
>  		break;
>  #endif /* OPENSSL_HAS_ECC */
> +	case KEY_NULL:
> +		return "null";
>  	}
>  	return "ssh-unknown";
>  }
> @@ -1276,6 +1278,8 @@
>  	    strcmp(name, "ecdsa-sha2-nistp521-cert-v01@openssh.com") == 0) {
>  		return KEY_ECDSA_CERT;
>  #endif
> +	} else if (strcmp(name, "null") == 0) {
> +		return KEY_NULL;
>  	}
7268,7269c6330,6369
<  extern ssh_gssapi_mech *supported_mechs[];
< +extern Gssctxt *gss_kex_context;
---
>  	debug2("key_type_from_name: unknown key type '%s'", name);
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/key.h openssh-6.0p1/key.h
> --- openssh-6.0p1.orig/key.h	2012-07-12 17:00:49.382202070 +0200
> +++ openssh-6.0p1/key.h	2012-07-12 17:01:14.302689680 +0200
> @@ -44,6 +44,7 @@
>  	KEY_ECDSA_CERT,
>  	KEY_RSA_CERT_V00,
>  	KEY_DSA_CERT_V00,
> +	KEY_NULL,
>  	KEY_UNSPEC
>  };
>  enum fp_type {
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/LICENSE.globus_usage openssh-6.0p1/LICENSE.globus_usage
> --- openssh-6.0p1.orig/LICENSE.globus_usage	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/LICENSE.globus_usage	2012-07-12 17:01:13.914682089 +0200
> @@ -0,0 +1,18 @@
> +/*
> + * Portions of the Usage Metrics suport code are derived from the
> + * Globus project's GridFTP subject to the following license.
> + *
> + * Copyright 2010 University of Chicago
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/Makefile.in openssh-6.0p1/Makefile.in
> --- openssh-6.0p1.orig/Makefile.in	2012-07-12 17:00:48.754189782 +0200
> +++ openssh-6.0p1/Makefile.in	2012-07-12 17:01:13.934682481 +0200
> @@ -60,6 +60,8 @@
>  EXEEXT=@EXEEXT@
>  MANFMT=@MANFMT@
7271,7280c6371
<  int  ssh_gssapi_check_oid(Gssctxt *, void *, size_t);
<  void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t);
< @@ -116,16 +136,41 @@
<  void ssh_gssapi_delete_ctx(Gssctxt **);
<  OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
<  void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *);
< -int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *);
< +int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *);
< +OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *);
< +int ssh_gssapi_credentials_updated(Gssctxt *);
---
> +INSTALL_GSISSH=@INSTALL_GSISSH@
7282,7283c6373
< +int ssh_gssapi_localname(char **name);
< +void ssh_gssapi_rekey_creds();
---
>  TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT)
7285,7300c6375,6382
<  /* In the server */
< +typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, 
< +    const char *);
< +char *ssh_gssapi_client_mechanisms(const char *, const char *);
< +char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *,
< +    const char *);
< +gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int);
< +int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, 
< +    const char *);
<  OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
< -int ssh_gssapi_userok(char *name);
< +int ssh_gssapi_userok(char *name, struct passwd *, int gssapi_keyex);
<  OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
<  void ssh_gssapi_do_child(char ***, u_int *);
<  void ssh_gssapi_cleanup_creds(void);
<  void ssh_gssapi_storecreds(void);
---
>  LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
> @@ -71,6 +73,7 @@
>  	atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \
>  	monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-rsa.o dh.o \
>  	kexdh.o kexgex.o kexdhc.o kexgexc.o bufec.o kexecdh.o kexecdhc.o \
> +	kexgssc.o \
>  	msg.o progressmeter.o dns.o entropy.o gss-genr.o umac.o jpake.o \
>  	schnorr.o ssh-pkcs11.o
7302,7425c6384,6414
< +#ifdef MECHGLUE
< +gss_cred_id_t __gss_get_mechanism_cred
< +   (gss_cred_id_t,	/* union_cred */
< +    gss_OID		/* mech_type */
< +   );
< +#endif
< +
< +char *ssh_gssapi_server_mechanisms(void);
< +int ssh_gssapi_oid_table_ok();
< +
< +int ssh_gssapi_update_creds(ssh_gssapi_ccache *store);
< +void ssh_gssapi_get_client_info(char **userdn, char **mech);
<  #endif /* GSSAPI */
<  
<  #endif /* _SSH_GSS_H */
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/ssh.1 openssh-6.0p1/ssh.1
< --- openssh-6.0p1.orig/ssh.1	2011-09-22 06:40:46.000000000 -0500
< +++ openssh-6.0p1/ssh.1	2012-05-27 17:50:01.000000000 -0500
< @@ -1195,8 +1195,38 @@
<  explicitly, as that
<  will render the X11 connection insecure (and will require the user to
<  manually copy any required authorization cookies).
< +.It Ev GSSAPI_MECH_CONF
< +Applies to mechglue used to support both GSI and Kerberos GSSAPI mechanisms.
< +Used to specify the location of the mech.conf file that lists the mechanism-
< +specific GSSAPI libraries (both Kerberos and GSI versions). If
< +.Ev GSSAPI_MECH_CONF
< +is not set then /etc/mech.conf is used. This applies to both the clients and
< +the server. The NCSA GSSAPI mechglue distribution includes a sample mech.conf
< +file. You will need to edit the library paths in that file and install it in
< +an appropriate location on your system. If the mech.conf file is not found,
< +the GSSAPI mechglue library will not load any GSSAPI mechanisms and GSI-OpenSSH
< +will simply skip GSSAPI authentication.
<  .It Ev HOME
<  Set to the path of the user's home directory.
< +.It LD_LIBRARY_PATH
< +The ssh client is typically linked dynamically with Globus
< +security libraries, which must be present in the dynamic linker's
< +search path.  This typically requires
< +.Cm $GLOBUS_LOCATION/lib
< +to be included in the list in the
< +.Ev LD_LIBRARY_PATH
< +environment variable, which is set by the
< +.Cm $GLOBUS_LOCATION/libexec/globus-script-initializer
< +script, which should be called from any
< +.Cm ssh
< +invocation script.
< +Alternatively, to set
< +.Ev LD_LIBRARY_PATH
< +appropriately for the Globus libraries in an interactive shell, source
< +.Cm $GLOBUS_LOCATION/etc/globus-user-env.sh
< +(for sh shells) or
< +.Cm $GLOBUS_LOCATION/etc/globus-user.env.csh
< +(for csh shells).
<  .It Ev LOGNAME
<  Synonym for
<  .Ev USER ;
< @@ -1255,6 +1285,18 @@
<  on to new connections).
<  .It Ev USER
<  Set to the name of the user logging in.
< +.It Ev X509_CERT_DIR
< +Used for GSI authentication. Specifies a non-standard location for the
< +CA certificates directory.
< +.It Ev X509_USER_CERT
< +Used for GSI authentication. Specifies a non-standard location for the
< +certificate to be used for authentication to the server.
< +.It Ev X509_USER_KEY
< +Used for GSI authentication. Specifies a non-standard location for the
< +private key to be used for authentication to the server.
< +.It Ev X509_USER_PROXY
< +Used for GSI authentication. Specifies a non-standard location for the
< +proxy credential to be used for authentication to the server.
<  .El
<  .Pp
<  Additionally,
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/ssh.c openssh-6.0p1/ssh.c
< --- openssh-6.0p1.orig/ssh.c	2011-11-03 18:54:22.000000000 -0500
< +++ openssh-6.0p1/ssh.c	2012-05-27 17:50:01.000000000 -0500
< @@ -579,6 +579,10 @@
<  			break;
<  		case 'T':
<  			options.request_tty = REQUEST_TTY_NO;
< +			/* ensure that the user doesn't try to backdoor a */
< +			/* null cipher switch on an interactive session */
< +			/* so explicitly disable it no matter what */
< +			options.none_switch=0;
<  			break;
<  		case 'o':
<  			dummy = 1;
< @@ -703,6 +707,32 @@
<  			fatal("Can't open user config file %.100s: "
<  			    "%.100s", config, strerror(errno));
<  	} else {
< +	    /*
< +	     * Since the config file parsing code aborts if it sees
< +	     * options it doesn't recognize, allow users to put
< +	     * options specific to compile-time add-ons in alternate
< +	     * config files so their primary config file will
< +	     * interoperate SSH versions that don't support those
< +	     * options.
< +	     */
< +#ifdef GSSAPI
< +		r = snprintf(buf, sizeof buf, "%s/%s.gssapi", pw->pw_dir,
< +		    _PATH_SSH_USER_CONFFILE);
< +		if (r > 0 && (size_t)r < sizeof(buf))
< +			(void)read_config_file(buf, host, &options, 1);
< +#ifdef GSI
< +		r = snprintf(buf, sizeof buf, "%s/%s.gsi", pw->pw_dir,
< +		    _PATH_SSH_USER_CONFFILE);
< +		if (r > 0 && (size_t)r < sizeof(buf))
< +			(void)read_config_file(buf, host, &options, 1);
< +#endif
< +#if defined(KRB5)
< +		r = snprintf(buf, sizeof buf, "%s/%s.krb", pw->pw_dir,
< +		    _PATH_SSH_USER_CONFFILE);
< +		if (r > 0 && (size_t)r < sizeof(buf))
< +			(void)read_config_file(buf, host, &options, 1);
< +#endif
< +#endif
<  		r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
<  		    _PATH_SSH_USER_CONFFILE);
<  		if (r > 0 && (size_t)r < sizeof(buf))
< @@ -723,8 +753,11 @@
---
> @@ -87,9 +90,11 @@
>  	auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \
>  	monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o kexecdhs.o \
>  	auth-krb5.o \
> -	auth2-gss.o gss-serv.o gss-serv-krb5.o \
> +	auth2-gss.o gss-serv.o gss-serv-krb5.o kexgsss.o\
> +	gss-serv-gsi.o \
>  	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
>  	sftp-server.o sftp-common.o \
> +	ssh-globus-usage.o \
>  	roaming_common.o roaming_serv.o \
>  	sandbox-null.o sandbox-rlimit.o sandbox-systrace.o sandbox-darwin.o \
>  	sandbox-seccomp-filter.o
> @@ -278,6 +283,20 @@
>  	ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/slogin
>  	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
>  	ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/slogin.1
> +	if [ ! -z "$(INSTALL_GSISSH)" ]; then \
> +		rm -f $(DESTDIR)$(bindir)/gsissh; \
> +		ln -s ./ssh$(EXEEXT) $(DESTDIR)$(bindir)/gsissh; \
> +		rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsissh.1; \
> +		ln -s ./ssh.1 $(DESTDIR)$(mandir)/$(mansubdir)1/gsissh.1; \
> +		rm -f $(DESTDIR)$(bindir)/gsiscp; \
> +		ln -s ./scp$(EXEEXT) $(DESTDIR)$(bindir)/gsiscp; \
> +		rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsiscp.1; \
> +		ln -s ./scp.1 $(DESTDIR)$(mandir)/$(mansubdir)1/gsiscp.1; \
> +		rm -f $(DESTDIR)$(bindir)/gsisftp; \
> +		ln -s ./sftp$(EXEEXT) $(DESTDIR)$(bindir)/gsisftp; \
> +		rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsisftp.1; \
> +		ln -s ./sftp.1 $(DESTDIR)$(mandir)/$(mansubdir)1/gsisftp.1; \
> +	fi
7427c6416,6418
<  	seed_rng();
---
>  install-sysconf:
>  	if [ ! -d $(DESTDIR)$(sysconfdir) ]; then \
> @@ -349,6 +368,11 @@
7429,7434c6420,6467
< -	if (options.user == NULL)
< +	if (options.user == NULL) {
<  		options.user = xstrdup(pw->pw_name);
< +		options.implicit = 1;
< +	}
< +        else options.implicit = 0;
---
>  uninstall:
>  	-rm -f $(DESTDIR)$(bindir)/slogin
> +	if [ ! -z "$(INSTALL_GSISSH)" ]; then \
> +		rm -f $(DESTDIR)$(bindir)/gsiscp; \
> +		rm -f $(DESTDIR)$(bindir)/gsissh; \
> +		rm -f $(DESTDIR)$(bindir)/gsisftp; \
> +	fi
>  	-rm -f $(DESTDIR)$(bindir)/ssh$(EXEEXT)
>  	-rm -f $(DESTDIR)$(bindir)/scp$(EXEEXT)
>  	-rm -f $(DESTDIR)$(bindir)/ssh-add$(EXEEXT)
> @@ -362,6 +386,11 @@
>  	-rm -f $(DESTDIR)$(SSH_PKCS11_HELPER)$(EXEEXT)
>  	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh.1
>  	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/scp.1
> +	if [ ! -z "$(INSTALL_GSISSH)" ]; then \
> +		rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsissh.1; \
> +		rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsiscp.1; \
> +		rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/gsisftp.1; \
> +	fi
>  	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-add.1
>  	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-agent.1
>  	-rm -f $(DESTDIR)$(mandir)/$(mansubdir)1/ssh-keygen.1
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/Makefile.in.orig openssh-6.0p1/Makefile.in.orig
> --- openssh-6.0p1.orig/Makefile.in.orig	2012-07-12 17:00:51.486243239 +0200
> +++ openssh-6.0p1/Makefile.in.orig	2012-07-12 16:59:33.972726582 +0200
> @@ -45,6 +45,7 @@
>  CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
>  LIBS=@LIBS@
>  SSHLIBS=@SSHLIBS@
> +LIBAUDIT=@LIBAUDIT@
>  SSHDLIBS=@SSHDLIBS@
>  LIBEDIT=@LIBEDIT@
>  AR=@AR@
> @@ -142,7 +143,7 @@
>  	$(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHLIBS) $(LIBS)
>  
>  sshd$(EXEEXT): libssh.a	$(LIBCOMPAT) $(SSHDOBJS)
> -	$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS)
> +	$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(LIBAUDIT)
>  
>  scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o
>  	$(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/misc.c openssh-6.0p1/misc.c
> --- openssh-6.0p1.orig/misc.c	2012-07-12 17:00:49.454203479 +0200
> +++ openssh-6.0p1/misc.c	2012-07-12 17:01:14.310689837 +0200
> @@ -158,11 +158,14 @@
>  #define WHITESPACE " \t\r\n"
>  #define QUOTE	"\""
7436,7438c6469,6474
<  	/* Get default port if port has not been set. */
<  	if (options.port == 0) {
< @@ -1369,6 +1402,9 @@
---
> +/* Characters considered as quotations. */
> +#define QUOTES "'\""
> +
>  /* return next token in configuration line */
>  char *
>  strdelim(char **s)
7440,7444c6476,6478
<  	Channel *c;
<  	int window, packetmax, in, out, err;
< +	int sock;
< +	int socksize;
< +	int socksizelen = sizeof(int);
---
> -	char *old;
> +	char *old, *p, *q;
>  	int wspace = 0;
7446,7450c6480,6481
<  	if (stdin_null_flag) {
<  		in = open(_PATH_DEVNULL, O_RDONLY);
< @@ -1389,9 +1425,75 @@
<  	if (!isatty(err))
<  		set_nonblock(err);
---
>  	if (*s == NULL)
> @@ -170,6 +173,21 @@
7452,7458c6483,6498
< -	window = CHAN_SES_WINDOW_DEFAULT;
< +	/* we need to check to see if what they want to do about buffer */
< +	/* sizes here. In a hpn to nonhpn connection we want to limit */
< +	/* the window size to something reasonable in case the far side */
< +	/* has the large window bug. In hpn to hpn connection we want to */
< +	/* use the max window size but allow the user to override it */
< +	/* lastly if they disabled hpn then use the ssh std window size */
---
>  	old = *s;
>  
> +        if ((q=strchr(QUOTES, (int) *old)) && *q)
> +        {
> +            /* find next quote character, point old to start of quoted
> +             * string */
> +            for (p = ++old;*p && *p!=*q; p++)
> +                 ;
> +            
> +            /* find start of next token */
> +            *s = (*p) ? p + strspn(p + 1, WHITESPACE) + 1 : NULL;
> +            
> +            /* terminate 'old' token */
> +            *p = '\0';
> +            return (old);
> +        }
7460,7472c6500,6519
< +	/* so why don't we just do a getsockopt() here and set the */
< +	/* ssh window to that? In the case of a autotuning receive */
< +	/* window the window would get stuck at the initial buffer */
< +	/* size generally less than 96k. Therefore we need to set the */
< +	/* maximum ssh window size to the maximum hpn buffer size */
< +	/* unless the user has specifically set the tcprcvbufpoll */
< +	/* to no. In which case we *can* just set the window to the */
< +	/* minimum of the hpn buffer size and tcp receive buffer size */
< +	
< +	if (tty_flag)
< +		options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
< +	else
< +		options.hpn_buffer_size = 2*1024*1024;
---
>  	*s = strpbrk(*s, WHITESPACE QUOTE "=");
>  	if (*s == NULL)
>  		return (old);
> @@ -223,6 +241,20 @@
>  	return copy;
>  }
>  
> +void
> +pwfree(struct passwd *pw)
> +{
> +	xfree(pw->pw_name);
> +	xfree(pw->pw_passwd);
> +	xfree(pw->pw_gecos);
> +#ifdef HAVE_PW_CLASS_IN_PASSWD
> +	xfree(pw->pw_class);
> +#endif
> +	xfree(pw->pw_dir);
> +	xfree(pw->pw_shell);
> +	xfree(pw);
> +}
7474,7515c6521,6624
< +	if (datafellows & SSH_BUG_LARGEWINDOW) 
< +	{
< +		debug("HPN to Non-HPN Connection");
< +	} 
< +	else 
< +	{
< +		if (options.tcp_rcv_buf_poll <= 0) 
< +		{
< +			sock = socket(AF_INET, SOCK_STREAM, 0);
< +			getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
< +				   &socksize, &socksizelen);
< +			close(sock);
< +			debug("socksize %d", socksize);
< +			options.hpn_buffer_size = socksize;
< +			debug ("HPNBufferSize set to TCP RWIN: %d", options.hpn_buffer_size);
< +		} 
< +		else
< +		{
< +			if (options.tcp_rcv_buf > 0) 
< +			{
< +				/*create a socket but don't connect it */
< +				/* we use that the get the rcv socket size */
< +				sock = socket(AF_INET, SOCK_STREAM, 0);
< +				/* if they are using the tcp_rcv_buf option */
< +				/* attempt to set the buffer size to that */
< +				if (options.tcp_rcv_buf) 
< +					setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&options.tcp_rcv_buf, 
< +						   sizeof(options.tcp_rcv_buf));
< +				getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
< +					   &socksize, &socksizelen);
< +				close(sock);
< +				debug("socksize %d", socksize);
< +				options.hpn_buffer_size = socksize;
< +				debug ("HPNBufferSize set to user TCPRcvBuf: %d", options.hpn_buffer_size);
< +			}
< + 		}
< +		
< +	}
< +
< +	debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
< +
< +	window = options.hpn_buffer_size;
---
>  /*
>   * Convert ASCII string to TCP/IP port number.
>   * Port must be >=0 and <=65535.
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/misc.h openssh-6.0p1/misc.h
> --- openssh-6.0p1.orig/misc.h	2012-07-12 17:00:49.458203557 +0200
> +++ openssh-6.0p1/misc.h	2012-07-12 17:01:14.318689993 +0200
> @@ -38,6 +38,7 @@
>  void	 sock_set_v6only(int);
>  
>  struct passwd *pwcopy(struct passwd *);
> +void	 pwfree(struct passwd *);
>  const char *ssh_gai_strerror(int);
>  
>  typedef struct arglist arglist;
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/monitor.c openssh-6.0p1/monitor.c
> --- openssh-6.0p1.orig/monitor.c	2012-07-12 17:00:49.494204261 +0200
> +++ openssh-6.0p1/monitor.c	2012-07-12 17:01:14.330690228 +0200
> @@ -180,6 +180,11 @@
>  int mm_answer_gss_accept_ctx(int, Buffer *);
>  int mm_answer_gss_userok(int, Buffer *);
>  int mm_answer_gss_checkmic(int, Buffer *);
> +int mm_answer_gss_sign(int, Buffer *);
> +int mm_answer_gss_error(int, Buffer *);
> +int mm_answer_gss_indicate_mechs(int, Buffer *);
> +int mm_answer_gss_localname(int, Buffer *);
> +int mm_answer_gss_updatecreds(int, Buffer *);
>  #endif
>  
>  #ifdef SSH_AUDIT_EVENTS
> @@ -221,12 +226,12 @@
>  struct mon_table mon_dispatch_proto20[] = {
>      {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli},
>      {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
> -    {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
> +    {MONITOR_REQ_PWNAM, MON_AUTH, mm_answer_pwnamallow},
>      {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
>      {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
>      {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
>  #ifdef USE_PAM
> -    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
> +    {MONITOR_REQ_PAM_START, MON_ISAUTH, mm_answer_pam_start},
>      {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},
> @@ -251,6 +256,10 @@
>      {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},
> +    {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
> +    {MONITOR_REQ_GSSERR, MON_ISAUTH | MON_ONCE, mm_answer_gss_error},
> +    {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs},
> +    {MONITOR_REQ_GSSLOCALNAME, MON_ISAUTH, mm_answer_gss_localname},
>  #endif
>  #ifdef JPAKE
>      {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata},
> @@ -263,6 +272,14 @@
>  };
>  
>  struct mon_table mon_dispatch_postauth20[] = {
> +#ifdef GSSAPI
> +    {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},
> +    {MONITOR_REQ_GSSERR, 0, mm_answer_gss_error},
> +    {MONITOR_REQ_GSSMECHS, 0, mm_answer_gss_indicate_mechs},
> +    {MONITOR_REQ_GSSUPCREDS, 0, mm_answer_gss_updatecreds},
> +#endif
>      {MONITOR_REQ_MODULI, 0, mm_answer_moduli},
>      {MONITOR_REQ_SIGN, 0, mm_answer_sign},
>      {MONITOR_REQ_PTY, 0, mm_answer_pty},
> @@ -292,8 +309,15 @@
>      {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery},
>      {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond},
>  #endif
> +#ifdef GSSAPI
> +    {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx},
> +    {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx},
> +    {MONITOR_REQ_GSSSIGN, MON_ONCE, mm_answer_gss_sign},
> +    {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok},
> +    {MONITOR_REQ_GSSMECHS, MON_ISAUTH, mm_answer_gss_indicate_mechs},
> +#endif
>  #ifdef USE_PAM
> -    {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start},
> +    {MONITOR_REQ_PAM_START, MON_ISAUTH, mm_answer_pam_start},
>      {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},
> @@ -371,6 +395,12 @@
>  		/* Permit requests for moduli and signatures */
>  		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
>  		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
> +#ifdef GSSAPI		
> +		/* and for the GSSAPI key exchange */
> +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP, 1);
> +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSERR, 1);
> +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS, 1);
> +#endif
>  	} else {
>  		mon_dispatch = mon_dispatch_proto15;
>  
> @@ -468,10 +498,21 @@
>  		monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
>  		monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
>  		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
7517c6626,6631
< +	channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
---
> +#ifdef GSSAPI
> +		/* and for the GSSAPI key exchange */
> +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSMECHS,1);
> +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSETUP,1);
> +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSERR,1);
> +#endif
7519,7523c6633,6635
<  	packetmax = CHAN_SES_PACKET_DEFAULT;
<  	if (tty_flag) {
< +		window = 4*CHAN_SES_PACKET_DEFAULT;
<  		window >>= 1;
<  		packetmax >>= 1;
---
>  	} else {
>  		mon_dispatch = mon_dispatch_postauth15;
>  		monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
7525,7528c6637,6648
< @@ -1399,7 +1501,10 @@
<  	    "session", SSH_CHANNEL_OPENING, in, out, err,
<  	    window, packetmax, CHAN_EXTENDED_WRITE,
<  	    "client-session", /*nonblock*/0);
---
> +#ifdef GSSAPI		
> +	monitor_permit(mon_dispatch, MONITOR_REQ_GSSERR, 1);
> +#endif
>  	if (!no_pty_flag) {
>  		monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
>  		monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1);
> @@ -735,14 +776,17 @@
>  
>  	debug3("%s", __func__);
>  
> -	if (authctxt->attempt++ != 0)
> -		fatal("%s: multiple attempts for getpwnam", __func__);
7530,7532c6650,6672
< +	if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) {
< +		c->dynamic_window = 1;
< +		debug ("Enabled Dynamic Window Scaling\n");
---
>  	username = buffer_get_string(m, NULL);
>  
>  	pwent = getpwnamallow(username);
>  
> +	if (authctxt->user) xfree(authctxt->user);
>  	authctxt->user = xstrdup(username);
> +#ifdef USE_PAM
> +    if (options.permit_pam_user_change)
> +        setproctitle("%s [priv]", pwent ? "[pam]" : "unknown");
> +    else
> +#endif
>  	setproctitle("%s [priv]", pwent ? username : "unknown");
>  	xfree(username);
>  
> @@ -1803,6 +1847,13 @@
>  	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
>  	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
>  	kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
> +#ifdef GSSAPI
> +	if (options.gss_keyex) {
> +		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
> +		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
> +		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
7534c6674,6680
<  	debug3("ssh_session2_open: channel_new: %d", c->self);
---
> +#endif
>  	kex->server = 1;
>  	kex->hostkey_type = buffer_get_int(m);
>  	kex->kex_type = buffer_get_int(m);
> @@ -2009,6 +2060,9 @@
>  	OM_uint32 major;
>  	u_int len;
7536,7655c6682,6683
<  	channel_send_open(c->self);
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/ssh_config openssh-6.0p1/ssh_config
< --- openssh-6.0p1.orig/ssh_config	2010-01-12 02:40:27.000000000 -0600
< +++ openssh-6.0p1/ssh_config	2012-05-27 17:50:01.000000000 -0500
< @@ -24,8 +24,10 @@
<  #   RSAAuthentication yes
<  #   PasswordAuthentication yes
<  #   HostbasedAuthentication no
< -#   GSSAPIAuthentication no
< -#   GSSAPIDelegateCredentials no
< +#   GSSAPIAuthentication yes
< +#   GSSAPIDelegateCredentials yes
< +#   GSSAPIKeyExchange yes
< +#   GSSAPITrustDNS yes
<  #   BatchMode no
<  #   CheckHostIP yes
<  #   AddressFamily any
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/ssh_config.5 openssh-6.0p1/ssh_config.5
< --- openssh-6.0p1.orig/ssh_config.5	2011-09-22 06:37:13.000000000 -0500
< +++ openssh-6.0p1/ssh_config.5	2012-05-27 17:50:01.000000000 -0500
< @@ -55,6 +55,12 @@
<  user's configuration file
<  .Pq Pa ~/.ssh/config
<  .It
< +GSSAPI configuration file
< +.Pq Pa $HOME/.ssh/config.gssapi
< +.It
< +Kerberos configuration file
< +.Pq Pa $HOME/.ssh/config.krb
< +.It
<  system-wide configuration file
<  .Pq Pa /etc/ssh/ssh_config
<  .El
< @@ -525,13 +531,45 @@
<  .It Cm GSSAPIAuthentication
<  Specifies whether user authentication based on GSSAPI is allowed.
<  The default is
< -.Dq no .
< +.Dq yes .
< +Note that this option applies to protocol version 2 only.
< +.It Cm GSSAPIKeyExchange
< +Specifies whether key exchange based on GSSAPI may be used. When using
< +GSSAPI key exchange the server need not have a host key.
< +The default is
< +.Dq yes .
<  Note that this option applies to protocol version 2 only.
< +.It Cm GSSAPIClientIdentity
< +If set, specifies the GSSAPI client identity that ssh should use when 
< +connecting to the server. The default is unset, which means that the default 
< +identity will be used.
< +.It Cm GSSAPIServerIdentity
< +If set, specifies the GSSAPI server identity that ssh should expect when 
< +connecting to the server. The default is unset, which means that the
< +expected GSSAPI server identity will be determined from the target
< +hostname.
<  .It Cm GSSAPIDelegateCredentials
<  Forward (delegate) credentials to the server.
<  The default is
< -.Dq no .
< -Note that this option applies to protocol version 2 only.
< +.Dq yes .
< +Note that this option applies to protocol version 2 connections using GSSAPI.
< +.It Cm GSSAPIRenewalForcesRekey
< +If set to 
< +.Dq yes
< +then renewal of the client's GSSAPI credentials will force the rekeying of the
< +ssh connection. With a compatible server, this can delegate the renewed 
< +credentials to a session on the server.
< +The default is
< +.Dq yes .
< +.It Cm GSSAPITrustDns
< +Set to 
< +.Dq yes to indicate that the DNS is trusted to securely canonicalize
< +the name of the host being connected to. If 
< +.Dq no, the hostname entered on the
< +command line will be passed untouched to the GSSAPI library.
< +The default is
< +.Dq yes .
< +This option only applies to protocol version 2 connections using GSSAPI.
<  .It Cm HashKnownHosts
<  Indicates that
<  .Xr ssh 1
< @@ -850,7 +888,7 @@
<  .Cm password ) .
<  The default is:
<  .Bd -literal -offset indent
< -gssapi-with-mic,hostbased,publickey,
< +gssapi-keyex,gssapi-with-mic,hostbased,publickey,
<  keyboard-interactive,password
<  .Ed
<  .It Cm Protocol
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/sshconnect.c openssh-6.0p1/sshconnect.c
< --- openssh-6.0p1.orig/sshconnect.c	2011-05-29 06:42:34.000000000 -0500
< +++ openssh-6.0p1/sshconnect.c	2012-05-27 17:50:01.000000000 -0500
< @@ -182,6 +182,31 @@
<  }
<  
<  /*
< + * Set TCP receive buffer if requested.
< + * Note: tuning needs to happen after the socket is
< + * created but before the connection happens
< + * so winscale is negotiated properly -cjr
< + */
< +static void
< +ssh_set_socket_recvbuf(int sock)
< +{
< +	void *buf = (void *)&options.tcp_rcv_buf;
< +	int sz = sizeof(options.tcp_rcv_buf);
< +	int socksize;
< +	int socksizelen = sizeof(int);
< +
< +	debug("setsockopt Attempting to set SO_RCVBUF to %d", options.tcp_rcv_buf);
< +	if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, buf, sz) >= 0) {
< +	  getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &socksize, &socksizelen);
< +	  debug("setsockopt SO_RCVBUF: %.100s %d", strerror(errno), socksize);
< +	}
< +	else
< +		error("Couldn't set socket receive buffer to %d: %.100s",
< +		    options.tcp_rcv_buf, strerror(errno));
< +}
---
> +	if (!options.gss_authentication && !options.gss_keyex)
> +		fatal("In GSSAPI monitor when GSSAPI is disabled");
7656a6685,6693
>  	goid.elements = buffer_get_string(m, &len);
>  	goid.length = len;
>  
> @@ -2036,6 +2090,9 @@
>  	OM_uint32 flags = 0; /* GSI needs this */
>  	u_int len;
>  
> +	if (!options.gss_authentication && !options.gss_keyex)
> +		fatal("In GSSAPI monitor when GSSAPI is disabled");
7658,7671c6695,6704
< +/*
<   * Creates a (possibly privileged) socket for use as the ssh connection.
<   */
<  static int
< @@ -204,6 +229,8 @@
<  			    strerror(errno));
<  		else
<  			debug("Allocated local port %d.", p);
< +		if (options.tcp_rcv_buf > 0)
< +			ssh_set_socket_recvbuf(sock);
<  		return sock;
<  	}
<  	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
< @@ -213,6 +240,9 @@
---
>  	in.value = buffer_get_string(m, &len);
>  	in.length = len;
>  	major = ssh_gssapi_accept_ctx(gsscontext, &in, &out, &flags);
> @@ -2052,7 +2109,9 @@
>  	if (major == GSS_S_COMPLETE) {
>  		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSTEP, 0);
>  		monitor_permit(mon_dispatch, MONITOR_REQ_GSSUSEROK, 1);
> +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
>  		monitor_permit(mon_dispatch, MONITOR_REQ_GSSCHECKMIC, 1);
> +		monitor_permit(mon_dispatch, MONITOR_REQ_GSSSIGN, 1);
7673c6706,6710
<  	fcntl(sock, F_SETFD, FD_CLOEXEC);
---
>  	return (0);
>  }
> @@ -2064,6 +2123,9 @@
>  	OM_uint32 ret;
>  	u_int len;
7675,7676c6712,6713
< +	if (options.tcp_rcv_buf > 0)
< +		ssh_set_socket_recvbuf(sock);
---
> +	if (!options.gss_authentication && !options.gss_keyex)
> +		fatal("In GSSAPI monitor when GSSAPI is disabled");
7678,7697c6715,6726
<  	/* Bind the socket to an alternative local IP address */
<  	if (options.bind_address == NULL)
<  		return sock;
< @@ -556,7 +586,7 @@
<  	snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s",
<  	    compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
<  	    compat20 ? PROTOCOL_MINOR_2 : minor1,
< -	    SSH_VERSION, compat20 ? "\r\n" : "\n");
< +	    SSH_RELEASE, compat20 ? "\r\n" : "\n");
<  	if (roaming_atomicio(vwrite, connection_out, buf, strlen(buf))
<  	    != strlen(buf))
<  		fatal("write: %.100s", strerror(errno));
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/sshconnect2.c openssh-6.0p1/sshconnect2.c
< --- openssh-6.0p1.orig/sshconnect2.c	2011-05-29 06:42:34.000000000 -0500
< +++ openssh-6.0p1/sshconnect2.c	2012-05-27 17:50:01.000000000 -0500
< @@ -81,6 +81,12 @@
<  extern char *client_version_string;
<  extern char *server_version_string;
<  extern Options options;
< +extern Kex *xxx_kex;
---
>  	gssbuf.value = buffer_get_string(m, &len);
>  	gssbuf.length = len;
>  	mic.value = buffer_get_string(m, &len);
> @@ -2089,8 +2151,18 @@
>  mm_answer_gss_userok(int sock, Buffer *m)
>  {
>  	int authenticated;
> +	int gssapi_keyex;
>  
> -	authenticated = authctxt->valid && ssh_gssapi_userok(authctxt->user);
> +	if (!options.gss_authentication && !options.gss_keyex)
> +		fatal("In GSSAPI monitor when GSSAPI is disabled");
7699,7700c6728
< +/* tty_flag is set in ssh.c. use this in ssh_userauth2 */
< +/* if it is set then prevent the switch to the null cipher */
---
> +	gssapi_keyex = buffer_get_int(m);
7702c6730,6734
< +extern int tty_flag;
---
> +	if (!options.gss_authentication && !options.gss_keyex)
> +		fatal("In GSSAPI monitor when GSSAPI is disabled");
> +
> +	authenticated = authctxt->valid && 
> +	    ssh_gssapi_userok(authctxt->user, authctxt->pw, gssapi_keyex);
7704,7708c6736,6740
<  /*
<   * SSH2 key exchange
< @@ -160,9 +166,34 @@
<  {
<  	Kex *kex;
---
>  	buffer_clear(m);
>  	buffer_put_int(m, authenticated);
> @@ -2098,11 +2170,146 @@
>  	debug3("%s: sending result %d", __func__, authenticated);
>  	mm_request_send(sock, MONITOR_ANS_GSSUSEROK, m);
7710,7716c6742,6746
< +#ifdef GSSAPI
< +	char *orig = NULL, *gss = NULL;
< +	char *gss_host = NULL;
< +#endif
< +
<  	xxx_host = host;
<  	xxx_hostaddr = hostaddr;
---
> -	auth_method = "gssapi-with-mic";
> +	if (gssapi_keyex)
> +		auth_method = "gssapi-keyex";
> +	else
> +		auth_method = "gssapi-with-mic";
7718,7722c6748,6750
< +#ifdef GSSAPI
< +	if (options.gss_keyex) {
< +		/* Add the GSSAPI mechanisms currently supported on this 
< +		 * client to the key exchange algorithm proposal */
< +		orig = myproposal[PROPOSAL_KEX_ALGS];
---
>  	/* Monitor loop will terminate if authenticated */
>  	return (authenticated);
>  }
7724,7727c6752,6755
< +		if (options.gss_trust_dns)
< +			gss_host = (char *)get_canonical_hostname(1);
< +		else
< +			gss_host = host;
---
> +int
> +mm_answer_gss_error(int socket, Buffer *m) {
> +        OM_uint32 major,minor;
> +        char *msg;
7729,7734c6757,6783
< +		gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity);
< +		if (gss) {
< +			debug("Offering GSSAPI proposal: %s", gss);
< +			xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
< +			    "%s,%s", gss, orig);
< +		}
---
> +	msg=ssh_gssapi_last_error(gsscontext,&major,&minor);
> +	buffer_clear(m);
> +	buffer_put_int(m,major);
> +	buffer_put_int(m,minor);
> +	buffer_put_cstring(m,msg);
> +
> +	mm_request_send(socket,MONITOR_ANS_GSSERR,m);
> +
> +	xfree(msg);
> +	
> +        return(0);
> +}
> +
> +int
> +mm_answer_gss_indicate_mechs(int socket, Buffer *m) {
> +        OM_uint32 major,minor;
> +	gss_OID_set mech_set;
> +	size_t i;
> +
> +	major=gss_indicate_mechs(&minor, &mech_set);
> +
> +	buffer_clear(m);
> +	buffer_put_int(m, major);
> +	buffer_put_int(m, mech_set->count);
> +	for (i=0; i < mech_set->count; i++) {
> +	    buffer_put_string(m, mech_set->elements[i].elements,
> +			      mech_set->elements[i].length);
7735a6785,6787
> +
> +#if !defined(MECHGLUE) /* mechglue memory management bug ??? */
> +	gss_release_oid_set(&minor,&mech_set);
7736a6789,6790
> +	
> +	mm_request_send(socket,MONITOR_ANS_GSSMECHS,m);
7738,7752c6792,6808
<  	if (options.ciphers == (char *)-1) {
<  		logit("No valid ciphers for protocol version 2 given, using defaults.");
<  		options.ciphers = NULL;
< @@ -197,6 +228,17 @@
<  	if (options.kex_algorithms != NULL)
<  		myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
<  
< +#ifdef GSSAPI
< +	/* If we've got GSSAPI algorithms, then we also support the
< +	 * 'null' hostkey, as a last resort */
< +	if (options.gss_keyex && gss) {
< +		orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
< +		xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], 
< +		    "%s,null", orig);
< +		xfree(gss);
---
> +	return(0);
> +}
> +
> +int
> +mm_answer_gss_localname(int socket, Buffer *m) {
> +	char *name;
> +
> +	ssh_gssapi_localname(&name);
> +
> +        buffer_clear(m);
> +	if (name) {
> +	    buffer_put_cstring(m, name);
> +	    debug3("%s: sending result %s", __func__, name);
> +	    xfree(name);
> +	} else {
> +	    buffer_put_cstring(m, "");
> +	    debug3("%s: sending result \"\"", __func__);
7754d6809
< +#endif
7756,7785c6811
<  	if (options.rekey_limit)
<  		packet_set_rekey_limit((u_int32_t)options.rekey_limit);
<  
< @@ -207,10 +249,30 @@
<  	kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
<  	kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
<  	kex->kex[KEX_ECDH_SHA2] = kexecdh_client;
< +#ifdef GSSAPI
< +	if (options.gss_keyex) {
< +		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
< +		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client;
< +		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client;
< +	}
< +#endif
<  	kex->client_version_string=client_version_string;
<  	kex->server_version_string=server_version_string;
<  	kex->verify_host_key=&verify_host_key_callback;
<  
< +#ifdef GSSAPI
< +	if (options.gss_keyex) {
< +		kex->gss_deleg_creds = options.gss_deleg_creds;
< +		kex->gss_trust_dns = options.gss_trust_dns;
< +		kex->gss_client = options.gss_client_identity;
< +		if (options.gss_server_identity) {
< +			kex->gss_host = options.gss_server_identity;
< +		} else {
< +			kex->gss_host = gss_host;
< +        }
< +	}
< +#endif
---
> +        mm_request_send(socket, MONITOR_ANS_GSSLOCALNAME, m);
7787,7843c6813,6814
<  	xxx_kex = kex;
<  
<  	dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
< @@ -305,6 +367,7 @@
<  void	input_gssapi_hash(int type, u_int32_t, void *);
<  void	input_gssapi_error(int, u_int32_t, void *);
<  void	input_gssapi_errtok(int, u_int32_t, void *);
< +int	userauth_gsskeyex(Authctxt *authctxt);
<  #endif
<  
<  void	userauth(Authctxt *, char *);
< @@ -320,6 +383,11 @@
<  
<  Authmethod authmethods[] = {
<  #ifdef GSSAPI
< +	{"gssapi-keyex",
< +		userauth_gsskeyex,
< +		NULL,
< +		&options.gss_authentication,
< +		NULL},
<  	{"gssapi-with-mic",
<  		userauth_gssapi,
<  		NULL,
< @@ -420,6 +488,28 @@
<  	pubkey_cleanup(&authctxt);
<  	dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
<  
< +	/* if the user wants to use the none cipher do it */
< +	/* post authentication and only if the right conditions are met */
< +	/* both of the NONE commands must be true and there must be no */
< +	/* tty allocated */
< +	if ((options.none_switch == 1) && (options.none_enabled == 1)) 
< +	{
< +		if (!tty_flag) /* no null on tty sessions */
< +		{
< +			debug("Requesting none rekeying...");
< +			myproposal[PROPOSAL_ENC_ALGS_STOC] = "none";
< +			myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none";
< +			kex_prop2buf(&xxx_kex->my,myproposal);
< +			packet_request_rekeying();
< +			fprintf(stderr, "WARNING: ENABLED NONE CIPHER\n");
< +		}
< +		else
< +		{
< +			/* requested NONE cipher when in a tty */
< +			debug("Cannot switch to NONE cipher with tty allocated");
< +			fprintf(stderr, "NONE cipher switch disabled when a TTY is allocated\n");
< +		}
< +	}
<  	debug("Authentication succeeded (%s).", authctxt.method->name);
<  }
<  
< @@ -626,19 +716,36 @@
<  	static u_int mech = 0;
<  	OM_uint32 min;
<  	int ok = 0;
< +	char *gss_host = NULL;
---
> +        return(0);
> +}
7845,7847c6816,6837
< +	if (!options.gss_authentication) {
< +		verbose("GSSAPI authentication disabled.");
< +		return 0;
---
> +int 
> +mm_answer_gss_sign(int socket, Buffer *m)
> +{
> +	gss_buffer_desc data;
> +	gss_buffer_desc hash = GSS_C_EMPTY_BUFFER;
> +	OM_uint32 major, minor;
> +	u_int len;
> +
> +	if (!options.gss_authentication && !options.gss_keyex)
> +		fatal("In GSSAPI monitor when GSSAPI is disabled");
> +
> +	data.value = buffer_get_string(m, &len);
> +	data.length = len;
> +	if (data.length != 20) 
> +		fatal("%s: data length incorrect: %d", __func__, 
> +		    (int) data.length);
> +
> +	/* Save the session ID on the first time around */
> +	if (session_id2_len == 0) {
> +		session_id2_len = data.length;
> +		session_id2 = xmalloc(session_id2_len);
> +		memcpy(session_id2, data.value, session_id2_len);
7848a6839
> +	major = ssh_gssapi_sign(gsscontext, &data, &hash);
7850,7902c6841
< +	if (options.gss_server_identity)
< +		gss_host = (char *)options.gss_server_identity;
< +	else if (options.gss_trust_dns)
< +		gss_host = (char *)get_canonical_hostname(1);
< +	else
< +		gss_host = (char *)authctxt->host;
<  
<  	/* Try one GSSAPI method at a time, rather than sending them all at
<  	 * once. */
<  
<  	if (gss_supported == NULL)
< -		gss_indicate_mechs(&min, &gss_supported);
< +		if (GSS_ERROR(gss_indicate_mechs(&min, &gss_supported))) {
< +			gss_supported = NULL;
< +			return 0;
< +		}
<  
<  	/* Check to see if the mechanism is usable before we offer it */
<  	while (mech < gss_supported->count && !ok) {
<  		/* My DER encoding requires length<128 */
<  		if (gss_supported->elements[mech].length < 128 &&
<  		    ssh_gssapi_check_mechanism(&gssctxt, 
< -		    &gss_supported->elements[mech], authctxt->host)) {
< +		    &gss_supported->elements[mech], gss_host, 
< +                    options.gss_client_identity)) {
<  			ok = 1; /* Mechanism works */
<  		} else {
<  			mech++;
< @@ -702,7 +809,8 @@
<  
<  	if (status == GSS_S_COMPLETE) {
<  		/* send either complete or MIC, depending on mechanism */
< -		if (!(flags & GSS_C_INTEG_FLAG)) {
< +		if (strcmp(authctxt->method->name,"gssapi")==0 ||
< +		    (!(flags & GSS_C_INTEG_FLAG))) {
<  			packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
<  			packet_send();
<  		} else {
< @@ -735,8 +843,8 @@
<  {
<  	Authctxt *authctxt = ctxt;
<  	Gssctxt *gssctxt;
< -	int oidlen;
< -	char *oidv;
< +	u_int oidlen;
< +	u_char *oidv;
<  
<  	if (authctxt == NULL)
<  		fatal("input_gssapi_response: no authentication context");
< @@ -846,6 +954,73 @@
<  	xfree(msg);
<  	xfree(lang);
<  }
---
> +	xfree(data.value);
7904,7911c6843,6845
< +#ifdef GSI
< +extern
< +const gss_OID_desc * const              gss_mech_globus_gssapi_openssl;
< +#define is_gsi_oid(oid) \
< +  (oid->length == gss_mech_globus_gssapi_openssl->length && \
< +   (memcmp(oid->elements, gss_mech_globus_gssapi_openssl->elements, \
< +	   oid->length) == 0))
< +#endif
---
> +	buffer_clear(m);
> +	buffer_put_int(m, major);
> +	buffer_put_string(m, hash.value, hash.length);
7913,7919c6847
< +int
< +userauth_gsskeyex(Authctxt *authctxt)
< +{
< +	Buffer b;
< +	gss_buffer_desc gssbuf;
< +	gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
< +	OM_uint32 ms;
---
> +	mm_request_send(socket, MONITOR_ANS_GSSSIGN, m);
7921,7923c6849
< +	static int attempt = 0;
< +	if (attempt++ >= 1)
< +		return (0);
---
> +	gss_release_buffer(&minor, &hash);
7925,7928c6851,6855
< +	if (gss_kex_context == NULL) {
< +		debug("No valid Key exchange context"); 
< +		return (0);
< +	}
---
> +	/* Turn on getpwnam permissions */
> +	monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
> +	
> +	/* And credential updating, for when rekeying */
> +	monitor_permit(mon_dispatch, MONITOR_REQ_GSSUPCREDS, 1);
7930,7939c6857,6858
< +#ifdef GSI
< +    if (options.implicit && is_gsi_oid(gss_kex_context->oid)) {
< +        ssh_gssapi_buildmic(&b, "", authctxt->service, "gssapi-keyex");
< +	} else {
< +#endif
< +        ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service,
< +                            "gssapi-keyex");
< +#ifdef GSI
< +	}
< +#endif
---
> +	return (0);
> +}
7941,7942c6860,6863
< +	gssbuf.value = buffer_ptr(&b);
< +	gssbuf.length = buffer_len(&b);
---
> +int
> +mm_answer_gss_updatecreds(int socket, Buffer *m) {
> +	ssh_gssapi_ccache store;
> +	int ok;
7944,7947c6865,6867
< +	if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) {
< +		buffer_free(&b);
< +		return (0);
< +	}
---
> +	store.filename = buffer_get_string(m, NULL);
> +	store.envvar   = buffer_get_string(m, NULL);
> +	store.envval   = buffer_get_string(m, NULL);
7949,7962c6869
< +	packet_start(SSH2_MSG_USERAUTH_REQUEST);
< +#ifdef GSI
< +    if (options.implicit && is_gsi_oid(gss_kex_context->oid)) {
< +        packet_put_cstring("");
< +	} else {
< +#endif
< +	packet_put_cstring(authctxt->server_user);
< +#ifdef GSI
< +	}
< +#endif
< +	packet_put_cstring(authctxt->service);
< +	packet_put_cstring(authctxt->method->name);
< +	packet_put_string(mic.value, mic.length);
< +	packet_send();
---
> +	ok = ssh_gssapi_update_creds(&store);
7964,7965c6871,6873
< +	buffer_free(&b);
< +	gss_release_buffer(&ms, &mic);
---
> +	xfree(store.filename);
> +	xfree(store.envvar);
> +	xfree(store.envval);
7967c6875,6880
< +	return (1);
---
> +	buffer_clear(m);
> +	buffer_put_int(m, ok);
> +
> +	mm_request_send(socket, MONITOR_ANS_GSSUPCREDS, m);
> +
> +	return(0);
7972,8092c6885,6908
<  int
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/sshd.8 openssh-6.0p1/sshd.8
< --- openssh-6.0p1.orig/sshd.8	2011-10-02 02:57:38.000000000 -0500
< +++ openssh-6.0p1/sshd.8	2012-05-27 17:50:01.000000000 -0500
< @@ -759,6 +759,73 @@
<  # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org
<  @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W...
<  .Ed
< +.Sh ENVIRONMENT
< +.Nm
< +will normally set the following environment variables:
< +.Bl -tag -width "SSH_ORIGINAL_COMMAND"
< +.It Ev GLOBUS_USAGE_OPTOUT
< +Setting this environment variable to "1" will disable the reporting
< +of usage metrics. Usage metrics can also be disabled using the
< +.Cm DisableUsageStats
< +setting in
< +.Xr sshd_config 5 .
< +.It Ev GLOBUS_USAGE_TARGETS
< +If
< +.Cm UsageStatsTargets
< +is not specified in
< +.Xr sshd_config 5 ,
< +a comma-separated list of targets (without any tags specified) if
< +specified in the environment variable
< +.Ev GLOBUS_USAGE_TARGETS
< +will be used.
< +.It Ev GRIDMAP
< +Applies to GSI authentication/authorization. Specifies the location of the
< +gridmapfile. If not specified, the gridmap file is assumed to be available at
< +/etc/grid-security/grid-mapfile for services running as root and at
< +HOME/.gridmap for services running as non-root where HOME is the home directory
< +of the effective user from the password file entry.
< +.It Ev GSSAPI_MECH_CONF
< +Applies to mechglue used to support both GSI and Kerberos GSSAPI mechanisms.
< +Used to specify the location of the mech.conf file that lists the mechanism-
< +specific GSSAPI libraries (both Kerberos and GSI versions). If
< +.Ev GSSAPI_MECH_CONF
< +is not set then /etc/mech.conf is used. This applies to both the clients and
< +the server. The NCSA GSSAPI mechglue distribution includes a sample mech.conf
< +file. You will need to edit the library paths in that file and install it in
< +an appropriate location on your system. If the mech.conf file is not found,
< +the GSSAPI mechglue library will not load any GSSAPI mechanisms and GSI-OpenSSH
< +will simply skip GSSAPI authentication.
< +.It LD_LIBRARY_PATH
< +The sshd server is typically linked dynamically with Globus
< +security libraries, which must be present in the dynamic linker's
< +search path.  This typically requires
< +.Cm $GLOBUS_LOCATION/lib
< +to be included in the list in the
< +.Ev LD_LIBRARY_PATH
< +environment variable, which is set by the
< +.Cm $GLOBUS_LOCATION/libexec/globus-script-initializer
< +script, which should be called from any
< +.Cm sshd
< +startup script.
< +Alternatively, to set
< +.Ev LD_LIBRARY_PATH
< +appropriately for the Globus libraries in an interactive shell, source
< +.Cm $GLOBUS_LOCATION/etc/globus-user-env.sh
< +(for sh shells) or
< +.Cm $GLOBUS_LOCATION/etc/globus-user.env.csh
< +(for csh shells).
< +.It Ev X509_CERT_DIR
< +Used for GSI authentication. Specifies a non-standard location for the
< +CA certificates directory.
< +.It Ev X509_USER_CERT
< +Used for GSI authentication. Specifies a non-standard location for the
< +certificate to be used for authentication to the client.
< +.It Ev X509_USER_KEY
< +Used for GSI authentication. Specifies a non-standard location for the
< +private key to be used for authentication to the client.
< +.It Ev X509_USER_PROXY
< +Used for GSI authentication. Specifies a non-standard location for the
< +proxy credential to be used for authentication to the client.
<  .Sh FILES
<  .Bl -tag -width Ds -compact
<  .It Pa ~/.hushlogin
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/sshd.c openssh-6.0p1/sshd.c
< --- openssh-6.0p1.orig/sshd.c	2012-02-14 12:03:31.000000000 -0600
< +++ openssh-6.0p1/sshd.c	2012-05-27 17:50:01.000000000 -0500
< @@ -120,6 +120,11 @@
<  #include "roaming.h"
<  #include "ssh-sandbox.h"
<  #include "version.h"
< +#include "ssh-globus-usage.h"
< +
< +#ifdef USE_SECURITY_SESSION_API
< +#include <Security/AuthSession.h>
< +#endif
<  
<  #ifdef LIBWRAP
<  #include <tcpd.h>
< @@ -138,6 +143,9 @@
<  #define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 3)
<  #define REEXEC_MIN_FREE_FD		(STDERR_FILENO + 4)
<  
< +int myflag = 0;
< +
< +
<  extern char *__progname;
<  
<  /* Server configuration options. */
< @@ -420,7 +428,7 @@
<  		minor = PROTOCOL_MINOR_1;
<  	}
<  	snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor,
< -	    SSH_VERSION, newline);
< +	    SSH_RELEASE, newline);
<  	server_version_string = xstrdup(buf);
<  
<  	/* Send our protocol version identification. */
< @@ -471,6 +479,9 @@
<  	}
<  	debug("Client protocol version %d.%d; client software version %.100s",
<  	    remote_major, remote_minor, remote_version);
< +	logit("SSH: Server;Ltype: Version;Remote: %s-%d;Protocol: %d.%d;Client: %.100s",
< +	      get_remote_ipaddr(), get_remote_port(),
< +	    remote_major, remote_minor, remote_version);
<  
<  	compat_datafellows(remote_version);
---
>  #ifdef JPAKE
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/monitor.h openssh-6.0p1/monitor.h
> --- openssh-6.0p1.orig/monitor.h	2012-07-12 17:00:49.502204418 +0200
> +++ openssh-6.0p1/monitor.h	2012-07-12 17:01:14.338690385 +0200
> @@ -52,7 +52,12 @@
>  	MONITOR_REQ_GSSSETUP, MONITOR_ANS_GSSSETUP,
>  	MONITOR_REQ_GSSSTEP, MONITOR_ANS_GSSSTEP,
>  	MONITOR_REQ_GSSUSEROK, MONITOR_ANS_GSSUSEROK,
> +	MONITOR_REQ_GSSMECHS, MONITOR_ANS_GSSMECHS,
> +	MONITOR_REQ_GSSLOCALNAME, MONITOR_ANS_GSSLOCALNAME,
> +	MONITOR_REQ_GSSERR, MONITOR_ANS_GSSERR,
>  	MONITOR_REQ_GSSCHECKMIC, MONITOR_ANS_GSSCHECKMIC,
> +	MONITOR_REQ_GSSSIGN, MONITOR_ANS_GSSSIGN,
> +	MONITOR_REQ_GSSUPCREDS, MONITOR_ANS_GSSUPCREDS,
>  	MONITOR_REQ_PAM_START,
>  	MONITOR_REQ_PAM_ACCOUNT, MONITOR_ANS_PAM_ACCOUNT,
>  	MONITOR_REQ_PAM_INIT_CTX, MONITOR_ANS_PAM_INIT_CTX,
> @@ -65,7 +70,7 @@
>  	MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA,
>  	MONITOR_REQ_JPAKE_STEP2, MONITOR_ANS_JPAKE_STEP2,
>  	MONITOR_REQ_JPAKE_KEY_CONFIRM, MONITOR_ANS_JPAKE_KEY_CONFIRM,
> -	MONITOR_REQ_JPAKE_CHECK_CONFIRM, MONITOR_ANS_JPAKE_CHECK_CONFIRM,
> +	MONITOR_REQ_JPAKE_CHECK_CONFIRM, MONITOR_ANS_JPAKE_CHECK_CONFIRM
>  };
8094,8099c6910,6915
< @@ -1027,6 +1038,8 @@
<  	int ret, listen_sock, on = 1;
<  	struct addrinfo *ai;
<  	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
< +	int socksize;
< +	int socksizelen = sizeof(int);
---
>  struct mm_master;
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/monitor_wrap.c openssh-6.0p1/monitor_wrap.c
> --- openssh-6.0p1.orig/monitor_wrap.c	2012-07-12 17:00:49.526204887 +0200
> +++ openssh-6.0p1/monitor_wrap.c	2012-07-12 17:01:14.346690541 +0200
> @@ -1270,12 +1270,13 @@
>  }
8101,8103c6917,6922
<  	for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
<  		if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
< @@ -1067,6 +1080,11 @@
---
>  int
> -mm_ssh_gssapi_userok(char *user)
> +mm_ssh_gssapi_userok(char *user, struct passwd *pw, int gssapi_keyex)
>  {
>  	Buffer m;
>  	int authenticated = 0;
8105c6924,6925
<  		debug("Bind to port %s on %s.", strport, ntop);
---
>  	buffer_init(&m);
> +	buffer_put_int(&m, gssapi_keyex);
8107,8110c6927,6932
< +		getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, 
< +				   &socksize, &socksizelen);
< +		debug("Server TCP RWIN socket size: %d", socksize);
< +		debug("HPN Buffer Size: %d", options.hpn_buffer_size);
---
>  	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUSEROK, &m);
>  	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUSEROK,
> @@ -1287,6 +1288,128 @@
>  	debug3("%s: user %sauthenticated",__func__, authenticated ? "" : "not ");
>  	return (authenticated);
>  }
8112,8124c6934,6940
<  		/* Bind the socket to the desired port. */
<  		if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
<  			error("Bind to port %s on %s failed: %.200s.",
< @@ -1555,6 +1573,13 @@
<  	/* Fill in default values for those options not explicitly set. */
<  	fill_default_server_options(&options);
<  
< +#ifdef HAVE_GLOBUS_USAGE
< +	if (ssh_usage_stats_init(options.disable_usage_stats,
< +			options.usage_stats_targets) != GLOBUS_SUCCESS) {
< +		error("Error initializing Globus Usage Metrics, but continuing ...");
< +	}
< +#endif /* HAVE_GLOBUS_USAGE */
---
> +char *
> +mm_ssh_gssapi_last_error(Gssctxt *ctx, OM_uint32 *major, OM_uint32 *minor) {
> +	Buffer m;
> +	OM_uint32 maj,min;
> +	char *errstr;
> +	
> +	buffer_init(&m);
8126,8148c6942,6943
<  	/* challenge-response is implemented via keyboard interactive */
<  	if (options.challenge_response_authentication)
<  		options.kbd_interactive_authentication = 1;
< @@ -1616,10 +1641,13 @@
<  		logit("Disabling protocol version 1. Could not load host key");
<  		options.protocol &= ~SSH_PROTO_1;
<  	}
< +#ifndef GSSAPI
< +	/* The GSSAPI key exchange can run without a host key */
<  	if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
<  		logit("Disabling protocol version 2. Could not load host key");
<  		options.protocol &= ~SSH_PROTO_2;
<  	}
< +#endif
<  	if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
<  		logit("sshd: no hostkeys available -- exiting.");
<  		exit(1);
< @@ -1911,6 +1939,9 @@
<  		cleanup_exit(255);
<  	}
<  
< +	/* set the HPN options for the child */
< +	channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
---
> +	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSERR, &m);
> +	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSERR, &m);
8150,8179c6945,6946
<  	/*
<  	 * We use get_canonical_hostname with usedns = 0 instead of
<  	 * get_remote_ipaddr here so IP options will be checked.
< @@ -1948,6 +1979,60 @@
<  	/* Log the connection. */
<  	verbose("Connection from %.500s port %d", remote_ip, remote_port);
<  
< +#ifdef USE_SECURITY_SESSION_API
< +	/*
< +	 * Create a new security session for use by the new user login if
< +	 * the current session is the root session or we are not launched
< +	 * by inetd (eg: debugging mode or server mode).  We do not
< +	 * necessarily need to create a session if we are launched from
< +	 * inetd because Panther xinetd will create a session for us.
< +	 *
< +	 * The only case where this logic will fail is if there is an
< +	 * inetd running in a non-root session which is not creating
< +	 * new sessions for us.  Then all the users will end up in the
< +	 * same session (bad).
< +	 *
< +	 * When the client exits, the session will be destroyed for us
< +	 * automatically.
< +	 *
< +	 * We must create the session before any credentials are stored
< +	 * (including AFS pags, which happens a few lines below).
< +	 */
< +	{
< +		OSStatus err = 0;
< +		SecuritySessionId sid = 0;
< +		SessionAttributeBits sattrs = 0;
---
> +	maj = buffer_get_int(&m);
> +	min = buffer_get_int(&m);
8181,8187c6948,6951
< +		err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
< +		if (err)
< +			error("SessionGetInfo() failed with error %.8X",
< +			    (unsigned) err);
< +		else
< +			debug("Current Session ID is %.8X / Session Attributes are %.8X",
< +			    (unsigned) sid, (unsigned) sattrs);
---
> +	if (major) *major=maj;
> +	if (minor) *minor=min;
> +	
> +	errstr=buffer_get_string(&m,NULL);
8189,8197c6953,6956
< +		if (inetd_flag && !(sattrs & sessionIsRoot))
< +			debug("Running in inetd mode in a non-root session... "
< +			    "assuming inetd created the session for us.");
< +		else {
< +			debug("Creating new security session...");
< +			err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
< +			if (err)
< +				error("SessionCreate() failed with error %.8X",
< +				    (unsigned) err);
---
> +	buffer_free(&m);
> +	
> +	return(errstr);
> +}	
8199,8209c6958,6965
< +			err = SessionGetInfo(callerSecuritySession, &sid, 
< +			    &sattrs);
< +			if (err)
< +				error("SessionGetInfo() failed with error %.8X",
< +				    (unsigned) err);
< +			else
< +				debug("New Session ID is %.8X / Session Attributes are %.8X",
< +				    (unsigned) sid, (unsigned) sattrs);
< +		}
< +	}
< +#endif
---
> +OM_uint32
> +mm_gss_indicate_mechs(OM_uint32 *minor_status, gss_OID_set *mech_set)
> +{
> +        Buffer m;
> +	OM_uint32 major,minor;
> +	int count;
> +	gss_OID_desc oid;
> +        u_int length;
8211,8222c6967,6979
<  	/*
<  	 * We don't want to listen forever unless the other side
<  	 * successfully authenticates itself.  So we set up an alarm which is
< @@ -1961,6 +2046,13 @@
<  		alarm(options.login_grace_time);
<  
<  	sshd_exchange_identification(sock_in, sock_out);
< +#if defined(AFS_KRB5)
< +	/* If machine has AFS, set process authentication group. */
< +	if (k_hasafs()) {
< +		k_setpag();
< +		k_unlog();
---
> +	buffer_init(&m);
> +
> +	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSMECHS, &m);
> +        mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSMECHS,
> +				  &m);
> +        major=buffer_get_int(&m);
> +	count=buffer_get_int(&m);
> +	
> +        gss_create_empty_oid_set(&minor,mech_set);
> +	while(count-->0) {
> +	    oid.elements=buffer_get_string(&m,&length);
> +	    oid.length=length;
> +	    gss_add_oid_set_member(&minor,&oid,mech_set);
8224,8262d6980
< +#endif /* AFS || AFS_KRB5 */
<  
<  	/* In inetd mode, generate ephemeral key only for proto 1 connections */
<  	if (!compat20 && inetd_flag && sensitive_data.server_key == NULL)
< @@ -2020,7 +2112,7 @@
<  #endif
<  
<  #ifdef GSSAPI
< -	if (options.gss_authentication) {
< +	if (options.gss_authentication && options.gss_deleg_creds) {
<  		temporarily_use_uid(authctxt->pw);
<  		ssh_gssapi_storecreds();
<  		restore_uid();
< @@ -2304,9 +2396,15 @@
<  {
<  	Kex *kex;
<  
< +	myflag++;
< +	debug ("MYFLAG IS %d", myflag);
<  	if (options.ciphers != NULL) {
<  		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
<  		myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
< +	} else if (options.none_enabled == 1) {
< +		debug ("WARNING: None cipher enabled");
< +		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
< +		myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_ENCRYPT_INCLUDE_NONE;
<  	}
<  	myproposal[PROPOSAL_ENC_ALGS_CTOS] =
<  	    compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
< @@ -2329,6 +2427,48 @@
<  
<  	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
<  
< +#ifdef GSSAPI
< +	{
< +	char *orig;
< +	char *gss = NULL;
< +	char *newstr = NULL;
< +	orig = myproposal[PROPOSAL_KEX_ALGS];
8264,8267c6982,6985
< +	/* 
< +	 * If we don't have a host key, then there's no point advertising
< +	 * the other key exchange algorithms
< +	 */
---
> +	buffer_free(&m);
> +	
> +        return(major);
> +}
8269,8270c6987,6990
< +	if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
< +		orig = NULL;
---
> +int
> +mm_ssh_gssapi_localname(char **lname)
> +{
> +        Buffer m;
8272,8275c6992,6993
< +	if (options.gss_keyex)
< +		gss = ssh_gssapi_server_mechanisms();
< +	else
< +		gss = NULL;
---
> +	buffer_init(&m);
> +        mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSLOCALNAME, &m);
8277,8282c6995,6997
< +	if (gss && orig)
< +		xasprintf(&newstr, "%s,%s", gss, orig);
< +	else if (gss)
< +		newstr = gss;
< +	else if (orig)
< +		newstr = orig;
---
> +        debug3("%s: waiting for MONITOR_ANS_GSSLOCALNAME", __func__);
> +        mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSLOCALNAME,
> +                                  &m);
8284,8290c6999
< +	/* 
< +	 * If we've got GSSAPI mechanisms, then we've got the 'null' host
< +	 * key alg, but we can't tell people about it unless its the only
< +  	 * host key algorithm we support
< +	 */
< +	if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
< +		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
---
> +	*lname = buffer_get_string(&m, NULL);
8292,8295c7001,7005
< +	if (newstr)
< +		myproposal[PROPOSAL_KEX_ALGS] = newstr;
< +	else
< +		fatal("No supported key exchange algorithms");
---
> +        buffer_free(&m);
> +	if (lname[0] == '\0') {
> +	    debug3("%s: gssapi identity mapping failed", __func__);
> +	} else {
> +	    debug3("%s: gssapi identity mapped to %s", __func__, *lname);
8297c7007,7009
< +#endif
---
> +	
> +        return(0);
> +}	
8299,8326c7011,7016
<  	/* start key exchange */
<  	kex = kex_setup(myproposal);
<  	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
< @@ -2336,6 +2476,13 @@
<  	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
<  	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
<  	kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
< +#ifdef GSSAPI
< +	if (options.gss_keyex) {
< +		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
< +		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
< +		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
< +	}
< +#endif
<  	kex->server = 1;
<  	kex->client_version_string=client_version_string;
<  	kex->server_version_string=server_version_string;
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/sshd_config openssh-6.0p1/sshd_config
< --- openssh-6.0p1.orig/sshd_config	2011-05-29 06:39:39.000000000 -0500
< +++ openssh-6.0p1/sshd_config	2012-05-27 17:50:01.000000000 -0500
< @@ -72,9 +72,17 @@
<  #KerberosTicketCleanup yes
<  #KerberosGetAFSToken no
<  
< +# Session hooks: if allowed, specify the commands to execute
< +#AllowSessionHooks no
< +#SessionHookStartupCmd /bin/true
< +#SessionHookShutdownCmd /bin/true
---
> +OM_uint32
> +mm_ssh_gssapi_sign(Gssctxt *ctx, gss_buffer_desc *data, gss_buffer_desc *hash)
> +{
> +	Buffer m;
> +	OM_uint32 major;
> +	u_int len;
8328,8344c7018,7019
<  # GSSAPI options
< -#GSSAPIAuthentication no
< +#GSSAPIAuthentication yes
< +#GSSAPIDelegateCredentials yes
<  #GSSAPICleanupCredentials yes
< +#GSSAPIStrictAcceptorCheck yes
< +#GSSAPIKeyExchange yes
<  
<  # Set this to 'yes' to enable PAM authentication, account processing, 
<  # and session processing. If this is enabled, PAM authentication will 
< @@ -87,6 +95,10 @@
<  # and ChallengeResponseAuthentication to 'no'.
<  #UsePAM no
<  
< +# Set to 'yes' to allow the PAM stack to change the user name during
< +# calls to authentication
< +#PermitPAMUserChange no
---
> +	buffer_init(&m);
> +	buffer_put_string(&m, data->value, data->length);
8346,8358c7021,7022
<  #AllowAgentForwarding yes
<  #AllowTcpForwarding yes
<  #GatewayPorts no
< @@ -114,8 +126,27 @@
<  # override default of no subsystems
<  Subsystem	sftp	/usr/libexec/sftp-server
<  
< +# the following are HPN related configuration options
< +# tcp receive buffer polling. disable in non autotuning kernels
< +#TcpRcvBufPoll yes
< + 
< +# allow the use of the none cipher
< +#NoneEnabled no
---
> +	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSSIGN, &m);
> +	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSSIGN, &m);
8360,8361c7024,7026
< +# disable hpn performance boosts. 
< +#HPNDisabled no
---
> +	major = buffer_get_int(&m);
> +	hash->value = buffer_get_string(&m, &len);
> +	hash->length = len;
8363,8364c7028
< +# buffer size for hpn to non-hpn connections
< +#HPNBufferSize 2048
---
> +	buffer_free(&m);
8365a7030,7031
> +	return(major);
> +}
8367,8371c7033,7037
<  # Example of overriding settings on a per-user basis
<  #Match User anoncvs
<  #	X11Forwarding no
<  #	AllowTcpForwarding no
<  #	ForceCommand cvs server
---
> +int
> +mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *store)
> +{
> +	Buffer m;
> +	int ok;
8372a7039
> +	buffer_init(&m);
8374,8437c7041,10512
< +# Usage Metrics
< +#UsageStatsTargets usage-stats.cilogon.org:4810
< +#DisableUsageStats No
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/sshd_config.5 openssh-6.0p1/sshd_config.5
< --- openssh-6.0p1.orig/sshd_config.5	2011-09-22 06:37:13.000000000 -0500
< +++ openssh-6.0p1/sshd_config.5	2012-05-27 17:50:01.000000000 -0500
< @@ -380,6 +380,16 @@
<  in
<  .Xr ssh_config 5
<  for more information on patterns.
< +.It Cm DisableUsageStats
< +This keyword can be followed by one of the keywords "true", "enabled", "yes",
< +"on" or "1" to disable reporting of usage metrics. Or it can be set to "false",
< +"disabled", "no", "off", "0" to enable reporting of usage metrics, which is the
< +default. Setting the
< +.Cm GLOBUS_USAGE_OPTOUT
< +environment variable to "1" will also disable the reporting of usage metrics.
< +Disabling reporting of usage metrics will cause the
< +.Cm UsageStatsTargets
< +setting to be ignored.
<  .It Cm ForceCommand
<  Forces the execution of the command specified by
<  .Cm ForceCommand ,
< @@ -422,7 +432,17 @@
<  .It Cm GSSAPIAuthentication
<  Specifies whether user authentication based on GSSAPI is allowed.
<  The default is
< -.Dq no .
< +.Dq yes .
< +Note that this option applies to protocol version 2 only.
< +.It Cm GSSAPIDelegateCredentials
< +Specifies whether delegated credentials are stored in the user's environment.
< +The default is
< +.Dq yes .
< +.It Cm GSSAPIKeyExchange
< +Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange 
< +doesn't rely on ssh keys to verify host identity.
< +The default is
< +.Dq yes .
<  Note that this option applies to protocol version 2 only.
<  .It Cm GSSAPICleanupCredentials
<  Specifies whether to automatically destroy the user's credentials cache
< @@ -430,6 +450,44 @@
<  The default is
<  .Dq yes .
<  Note that this option applies to protocol version 2 only.
< +.It Cm GSSAPICredentialsPath
< +If specified, the delegated GSSAPI credential is stored in the
< +given path, overwriting any existing credentials.  
< +Paths can be specified with syntax similar to the AuthorizedKeysFile 
< +option (i.e., accepting %h and %u tokens).  
< +When using this option,
< +setting 'GssapiCleanupCredentials no' is recommended,
< +so logging out of one session
< +doesn't remove the credentials in use by another session of
< +the same user.
< +Currently only implemented for the GSI mechanism.
< +.It Cm GSIAllowLimitedProxy
< +Specifies whether to accept limited proxy credentials for
< +authentication.
< +The default is
< +.Dq no .
< +.It Cm GSSAPIStrictAcceptorCheck
< +Determines whether to be strict about the identity of the GSSAPI acceptor 
---
> +	buffer_put_cstring(&m, store->filename ? store->filename : "");
> +	buffer_put_cstring(&m, store->envvar ? store->envvar : "");
> +	buffer_put_cstring(&m, store->envval ? store->envval : "");
> +	
> +	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GSSUPCREDS, &m);
> +	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GSSUPCREDS, &m);
> +
> +	ok = buffer_get_int(&m);
> +
> +	buffer_free(&m);
> +	
> +	return (ok);
> +}
> +
>  #endif /* GSSAPI */
>  
>  #ifdef JPAKE
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/monitor_wrap.h openssh-6.0p1/monitor_wrap.h
> --- openssh-6.0p1.orig/monitor_wrap.h	2012-07-12 17:00:49.530204966 +0200
> +++ openssh-6.0p1/monitor_wrap.h	2012-07-12 17:01:14.358690776 +0200
> @@ -58,8 +58,14 @@
>  OM_uint32 mm_ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
>  OM_uint32 mm_ssh_gssapi_accept_ctx(Gssctxt *,
>     gss_buffer_desc *, gss_buffer_desc *, OM_uint32 *);
> -int mm_ssh_gssapi_userok(char *user);
> +int mm_ssh_gssapi_userok(char *user, struct passwd *, int gssapi_keyex);
>  OM_uint32 mm_ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
> +OM_uint32 mm_ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
> +int mm_ssh_gssapi_localname(char **user);
> +OM_uint32 mm_gss_indicate_mechs(OM_uint32 *minor_status,
> +				gss_OID_set *mech_set);
> +char *mm_ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *maj, OM_uint32 *min);
> +int mm_ssh_gssapi_update_creds(ssh_gssapi_ccache *);
>  #endif
>  
>  #ifdef USE_PAM
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/mux.c openssh-6.0p1/mux.c
> --- openssh-6.0p1.orig/mux.c	2012-07-12 17:00:49.546205279 +0200
> +++ openssh-6.0p1/mux.c	2012-07-12 17:01:14.370691011 +0200
> @@ -441,6 +441,7 @@
>  		set_nonblock(new_fd[2]);
>  
>  	window = CHAN_SES_WINDOW_DEFAULT;
> +
>  	packetmax = CHAN_SES_PACKET_DEFAULT;
>  	if (cctx->want_tty) {
>  		window >>= 1;
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/myproposal.h openssh-6.0p1/myproposal.h
> --- openssh-6.0p1.orig/myproposal.h	2012-07-12 17:00:49.554205435 +0200
> +++ openssh-6.0p1/myproposal.h	2012-07-12 17:01:14.378691167 +0200
> @@ -75,6 +75,8 @@
>  	"arcfour256,arcfour128," \
>  	"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
>  	"aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se"
> +#define KEX_ENCRYPT_INCLUDE_NONE KEX_DEFAULT_ENCRYPT \
> +	",none"
>  #ifdef HAVE_EVP_SHA256
>  #define	SHA2_HMAC_MODES \
>  	"hmac-sha2-256," \
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/openbsd-compat/port-aix.c openssh-6.0p1/openbsd-compat/port-aix.c
> --- openssh-6.0p1.orig/openbsd-compat/port-aix.c	2012-07-12 17:00:50.582225550 +0200
> +++ openssh-6.0p1/openbsd-compat/port-aix.c	2012-07-12 17:01:14.402691637 +0200
> @@ -50,6 +50,7 @@
>  # include <login.h>
>  # include <userpw.h>
>  # if defined(HAVE_SYS_AUDIT_H) && defined(AIX_LOGINFAILED_4ARG)
> +#  undef T_NULL
>  #  include <sys/audit.h>
>  # endif
>  # include <usersec.h>
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/packet.c openssh-6.0p1/packet.c
> --- openssh-6.0p1.orig/packet.c	2012-07-12 17:00:49.582205983 +0200
> +++ openssh-6.0p1/packet.c	2012-07-12 17:01:14.410691793 +0200
> @@ -838,7 +838,7 @@
>  /*
>   * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
>   */
> -static void
> +static int
>  packet_send2_wrapped(void)
>  {
>  	u_char type, *cp, *macbuf = NULL;
> @@ -957,11 +957,13 @@
>  		set_newkeys(MODE_OUT);
>  	else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side)
>  		packet_enable_delayed_compress();
> +	return(packet_length);
>  }
>  
> -static void
> +static int
>  packet_send2(void)
>  {
> +	static int packet_length = 0;
>  	struct packet *p;
>  	u_char type, *cp;
>  
> @@ -981,7 +983,7 @@
>  			    sizeof(Buffer));
>  			buffer_init(&active_state->outgoing_packet);
>  			TAILQ_INSERT_TAIL(&active_state->outgoing, p, next);
> -			return;
> +			return(sizeof(Buffer));
>  		}
>  	}
>  
> @@ -989,7 +991,7 @@
>  	if (type == SSH2_MSG_KEXINIT)
>  		active_state->rekeying = 1;
>  
> -	packet_send2_wrapped();
> +	packet_length = packet_send2_wrapped();
>  
>  	/* after a NEWKEYS message we can send the complete queue */
>  	if (type == SSH2_MSG_NEWKEYS) {
> @@ -1002,19 +1004,22 @@
>  			    sizeof(Buffer));
>  			TAILQ_REMOVE(&active_state->outgoing, p, next);
>  			xfree(p);
> -			packet_send2_wrapped();
> +			packet_length += packet_send2_wrapped();
>  		}
>  	}
> +	return(packet_length);
>  }
>  
> -void
> +int
>  packet_send(void)
>  {
> +  int packet_len = 0;
>  	if (compat20)
> -		packet_send2();
> +		packet_len = packet_send2();
>  	else
>  		packet_send1();
>  	DBG(debug("packet_send done"));
> +	return(packet_len);
>  }
>  
>  /*
> @@ -1647,12 +1652,14 @@
>  
>  /* Checks if there is any buffered output, and tries to write some of the output. */
>  
> -void
> +int
>  packet_write_poll(void)
>  {
> -	int len = buffer_len(&active_state->output);
> +	int len = 0;
>  	int cont;
>  
> +	len = buffer_len(&active_state->output);
> +
>  	if (len > 0) {
>  		cont = 0;
>  		len = roaming_write(active_state->connection_out,
> @@ -1660,13 +1667,14 @@
>  		if (len == -1) {
>  			if (errno == EINTR || errno == EAGAIN ||
>  			    errno == EWOULDBLOCK)
> -				return;
> +				return (0);
>  			fatal("Write failed: %.100s", strerror(errno));
>  		}
>  		if (len == 0 && !cont)
>  			fatal("Write connection closed");
>  		buffer_consume(&active_state->output, len);
>  	}
> +	return(len);
>  }
>  
>  /*
> @@ -1867,12 +1875,24 @@
>  	}
>  }
>  
> +int rekey_requested = 0;
> +void
> +packet_request_rekeying(void)
> +{
> +	rekey_requested = 1;
> +}
> +
>  #define MAX_PACKETS	(1U<<31)
>  int
>  packet_need_rekeying(void)
>  {
>  	if (datafellows & SSH_BUG_NOREKEY)
>  		return 0;
> +	if (rekey_requested == 1)
> +	{
> +		rekey_requested = 0;
> +		return 1;
> +	}
>  	return
>  	    (active_state->p_send.packets > MAX_PACKETS) ||
>  	    (active_state->p_read.packets > MAX_PACKETS) ||
> @@ -1964,3 +1984,9 @@
>  		add_recv_bytes(len);
>  	}
>  }
> +
> +int
> +packet_authentication_state(void)
> +{
> +	return(active_state->after_authentication);
> +}
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/packet.h openssh-6.0p1/packet.h
> --- openssh-6.0p1.orig/packet.h	2012-07-12 17:00:49.590206140 +0200
> +++ openssh-6.0p1/packet.h	2012-07-12 17:01:14.414691872 +0200
> @@ -23,6 +23,12 @@
>  #include <openssl/ec.h>
>  #endif
>  
> +void
> +packet_request_rekeying(void);
> +
> +void
> +packet_request_rekeying(void);
> +
>  void     packet_set_connection(int, int);
>  void     packet_set_timeout(int, int);
>  void     packet_set_nonblocking(void);
> @@ -38,6 +44,7 @@
>  int      packet_is_interactive(void);
>  void     packet_set_server(void);
>  void     packet_set_authenticated(void);
> +int	 packet_authentication_state(void);
>  
>  void     packet_start(u_char);
>  void     packet_put_char(int ch);
> @@ -51,7 +58,7 @@
>  void     packet_put_string(const void *buf, u_int len);
>  void     packet_put_cstring(const char *str);
>  void     packet_put_raw(const void *buf, u_int len);
> -void     packet_send(void);
> +int      packet_send(void);
>  
>  int      packet_read(void);
>  void     packet_read_expect(int type);
> @@ -85,7 +92,7 @@
>  void	 packet_set_iv(int, u_char *);
>  void	*packet_get_newkeys(int);
>  
> -void     packet_write_poll(void);
> +int      packet_write_poll(void);
>  void     packet_write_wait(void);
>  int      packet_have_data_to_write(void);
>  int      packet_not_very_much_data_to_write(void);
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/progressmeter.c openssh-6.0p1/progressmeter.c
> --- openssh-6.0p1.orig/progressmeter.c	2012-07-12 17:00:49.614206609 +0200
> +++ openssh-6.0p1/progressmeter.c	2012-07-12 17:01:14.422692028 +0200
> @@ -68,6 +68,8 @@
>  static char *file;		/* name of the file being transferred */
>  static off_t end_pos;		/* ending position of transfer */
>  static off_t cur_pos;		/* transfer position as of last refresh */
> +static off_t last_pos;
> +static off_t max_delta_pos = 0;
>  static volatile off_t *counter;	/* progress counter */
>  static long stalled;		/* how long we have been stalled */
>  static int bytes_per_second;	/* current speed in bytes per second */
> @@ -128,12 +130,17 @@
>  	int hours, minutes, seconds;
>  	int i, len;
>  	int file_len;
> +	off_t delta_pos;
>  
>  	transferred = *counter - cur_pos;
>  	cur_pos = *counter;
>  	now = time(NULL);
>  	bytes_left = end_pos - cur_pos;
>  
> +	delta_pos = cur_pos - last_pos;
> +	if (delta_pos > max_delta_pos) 
> +		max_delta_pos = delta_pos;
> +
>  	if (bytes_left > 0)
>  		elapsed = now - last_update;
>  	else {
> @@ -158,7 +165,7 @@
>  
>  	/* filename */
>  	buf[0] = '\0';
> -	file_len = win_size - 35;
> +	file_len = win_size - 45;
>  	if (file_len > 0) {
>  		len = snprintf(buf, file_len + 1, "\r%s", file);
>  		if (len < 0)
> @@ -175,7 +182,8 @@
>  		percent = ((float)cur_pos / end_pos) * 100;
>  	else
>  		percent = 100;
> -	snprintf(buf + strlen(buf), win_size - strlen(buf),
> +
> +	snprintf(buf + strlen(buf), win_size - strlen(buf-8),
>  	    " %3d%% ", percent);
>  
>  	/* amount transferred */
> @@ -188,6 +196,15 @@
>  	    (off_t)bytes_per_second);
>  	strlcat(buf, "/s ", win_size);
>  
> +	/* instantaneous rate */
> +	if (bytes_left > 0)
> +		format_rate(buf + strlen(buf), win_size - strlen(buf),
> +			    delta_pos);
> +	else
> +		format_rate(buf + strlen(buf), win_size - strlen(buf),
> +			    max_delta_pos);
> +	strlcat(buf, "/s ", win_size);
> +
>  	/* ETA */
>  	if (!transferred)
>  		stalled += elapsed;
> @@ -224,6 +241,7 @@
>  
>  	atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1);
>  	last_update = now;
> +	last_pos = cur_pos;
>  }
>  
>  /*ARGSUSED*/
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/readconf.c openssh-6.0p1/readconf.c
> --- openssh-6.0p1.orig/readconf.c	2012-07-12 17:00:51.338240343 +0200
> +++ openssh-6.0p1/readconf.c	2012-07-12 17:25:46.575503938 +0200
> @@ -129,12 +129,16 @@
>  	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
>  	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
>  	oAddressFamily, oGssAuthentication, oGssDelegateCreds, oGssEnableMITM,
> + 	oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey,
> + 	oGssServerIdentity, 
>  	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
>  	oSendEnv, oControlPath, oControlMaster, oControlPersist,
>  	oHashKnownHosts,
>  	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
>  	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
>  	oKexAlgorithms, oIPQoS, oRequestTTY,
> + 	oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
> + 	oHPNBufferSize,
>  	oDeprecated, oUnsupported
>  } OpCodes;
>  
> @@ -169,11 +173,20 @@
>  	{ "afstokenpassing", oUnsupported },
>  #if defined(GSSAPI)
>  	{ "gssapiauthentication", oGssAuthentication },
> + 	{ "gssapikeyexchange", oGssKeyEx },
>  	{ "gssapidelegatecredentials", oGssDelegateCreds },
> + 	{ "gssapitrustdns", oGssTrustDns },
> + 	{ "gssapiclientidentity", oGssClientIdentity },
> + 	{ "gssapiserveridentity", oGssServerIdentity },
> + 	{ "gssapirenewalforcesrekey", oGssRenewalRekey },
>  	{ "gssapienablemitmattack", oGssEnableMITM },
>  #else
>  	{ "gssapiauthentication", oUnsupported },
> + 	{ "gssapikeyexchange", oUnsupported },
>  	{ "gssapidelegatecredentials", oUnsupported },
> + 	{ "gssapitrustdns", oUnsupported },
> + 	{ "gssapiclientidentity", oUnsupported },
> + 	{ "gssapirenewalforcesrekey", oUnsupported },
>  	{ "gssapienablemitmattack", oUnsupported },
>  #endif
>  	{ "fallbacktorsh", oDeprecated },
> @@ -248,6 +261,12 @@
>  	{ "kexalgorithms", oKexAlgorithms },
>  	{ "ipqos", oIPQoS },
>  	{ "requesttty", oRequestTTY },
> +	{ "noneenabled", oNoneEnabled },
> +	{ "tcprcvbufpoll", oTcpRcvBufPoll },
> +	{ "tcprcvbuf", oTcpRcvBuf },
> +	{ "noneswitch", oNoneSwitch },
> +	{ "hpndisabled", oHPNDisabled },
> +	{ "hpnbuffersize", oHPNBufferSize },
>  
>  	{ NULL, oBadOption }
>  };
> @@ -485,6 +504,10 @@
>  		intptr = &options->gss_authentication;
>  		goto parse_flag;
>  
> + 	case oGssKeyEx:
> + 		intptr = &options->gss_keyex;
> + 		goto parse_flag;
> +
>  	case oGssDelegateCreds:
>  		intptr = &options->gss_deleg_creds;
>  		goto parse_flag;
> @@ -493,6 +516,22 @@
>  		intptr = &options->gss_enable_mitm;
>  		goto parse_flag;
>  
> + 	case oGssTrustDns:
> + 		intptr = &options->gss_trust_dns;
> + 		goto parse_flag;
> + 
> + 	case oGssClientIdentity:
> + 		charptr = &options->gss_client_identity;
> + 		goto parse_string;
> + 
> + 	case oGssServerIdentity:
> + 		charptr = &options->gss_server_identity;
> + 		goto parse_string;
> + 
> + 	case oGssRenewalRekey:
> + 		intptr = &options->gss_renewal_rekey;
> + 		goto parse_flag;
> +
>  	case oBatchMode:
>  		intptr = &options->batch_mode;
>  		goto parse_flag;
> @@ -501,6 +540,37 @@
>  		intptr = &options->check_host_ip;
>  		goto parse_flag;
>  
> +	case oNoneEnabled:
> +		intptr = &options->none_enabled;
> +		goto parse_flag;
> + 
> +	/* we check to see if the command comes from the */
> +	/* command line or not. If it does then enable it */
> +	/* otherwise fail. NONE should never be a default configuration */
> +	case oNoneSwitch:
> +		if(strcmp(filename,"command-line")==0)
> +		{		
> +		    intptr = &options->none_switch;
> +		    goto parse_flag;
> +		} else {
> +		    error("NoneSwitch is found in %.200s.\nYou may only use this configuration option from the command line", filename);
> +		    error("Continuing...");
> +		    debug("NoneSwitch directive found in %.200s.", filename);
> +		    return 0;
> +	        }
> +
> +	case oHPNDisabled:
> +		intptr = &options->hpn_disabled;
> +		goto parse_flag;
> +
> +	case oHPNBufferSize:
> +		intptr = &options->hpn_buffer_size;
> +		goto parse_int;
> +
> +	case oTcpRcvBufPoll:
> +		intptr = &options->tcp_rcv_buf_poll;
> +		goto parse_flag;
> +
>  	case oVerifyHostKeyDNS:
>  		intptr = &options->verify_host_key_dns;
>  		goto parse_yesnoask;
> @@ -686,6 +756,10 @@
>  		intptr = &options->connection_attempts;
>  		goto parse_int;
>  
> +	case oTcpRcvBuf:
> +		intptr = &options->tcp_rcv_buf;
> +		goto parse_int;
> +
>  	case oCipher:
>  		intptr = &options->cipher;
>  		arg = strdelim(&s);
> @@ -1145,7 +1219,12 @@
>  	options->pubkey_authentication = -1;
>  	options->challenge_response_authentication = -1;
>  	options->gss_authentication = -1;
> + 	options->gss_keyex = -1;
>  	options->gss_deleg_creds = -1;
> + 	options->gss_trust_dns = -1;
> + 	options->gss_renewal_rekey = -1;
> + 	options->gss_client_identity = NULL;
> + 	options->gss_server_identity = NULL;
>  	options->gss_enable_mitm = -1;
>  	options->password_authentication = -1;
>  	options->kbd_interactive_authentication = -1;
> @@ -1210,6 +1289,12 @@
>  	options->ip_qos_interactive = -1;
>  	options->ip_qos_bulk = -1;
>  	options->request_tty = -1;
> +	options->none_switch = -1;
> +	options->none_enabled = -1;
> +	options->hpn_disabled = -1;
> +	options->hpn_buffer_size = -1;
> +	options->tcp_rcv_buf_poll = -1;
> +	options->tcp_rcv_buf = -1;
>  }
>  
>  /*
> @@ -1245,9 +1330,15 @@
>  	if (options->challenge_response_authentication == -1)
>  		options->challenge_response_authentication = 1;
>  	if (options->gss_authentication == -1)
> -		options->gss_authentication = 0;
> + 		options->gss_authentication = 1;
> + 	if (options->gss_keyex == -1)
> + 		options->gss_keyex = 1;
>  	if (options->gss_deleg_creds == -1)
> -		options->gss_deleg_creds = 0;
> + 		options->gss_deleg_creds = 1;
> + 	if (options->gss_trust_dns == -1)
> + 		options->gss_trust_dns = 1;
> + 	if (options->gss_renewal_rekey == -1)
> + 		options->gss_renewal_rekey = 0;
>  	if (options->gss_enable_mitm == -1)
>  		options->gss_enable_mitm = 0;
>  	if (options->password_authentication == -1)
> @@ -1348,6 +1439,29 @@
>  		options->server_alive_interval = 0;
>  	if (options->server_alive_count_max == -1)
>  		options->server_alive_count_max = 3;
> +	if (options->none_switch == -1)
> +	        options->none_switch = 0;
> +	if (options->hpn_disabled == -1)
> +	        options->hpn_disabled = 0;
> +	if (options->hpn_buffer_size > -1)
> +	{
> +	  /* if a user tries to set the size to 0 set it to 1KB */
> +		if (options->hpn_buffer_size == 0)
> +		options->hpn_buffer_size = 1024;
> +		/*limit the buffer to 64MB*/
> +		if (options->hpn_buffer_size > 65536)
> +		{
> +			options->hpn_buffer_size = 65536*1024;
> +			debug("User requested buffer larger than 64MB. Request reverted to 64MB");
> +		}
> +		debug("hpn_buffer_size set to %d", options->hpn_buffer_size);
> +	}
> +	if (options->tcp_rcv_buf == 0)
> +		options->tcp_rcv_buf = 1;
> +	if (options->tcp_rcv_buf > -1) 
> +		options->tcp_rcv_buf *=1024;
> +	if (options->tcp_rcv_buf_poll == -1)
> +		options->tcp_rcv_buf_poll = 1;
>  	if (options->control_master == -1)
>  		options->control_master = 0;
>  	if (options->control_persist == -1) {
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/readconf.c.orig openssh-6.0p1/readconf.c.orig
> --- openssh-6.0p1.orig/readconf.c.orig	2012-07-12 17:00:51.330240186 +0200
> +++ openssh-6.0p1/readconf.c.orig	2012-07-12 16:59:38.480814788 +0200
> @@ -128,7 +128,7 @@
>  	oHostKeyAlgorithms, oBindAddress, oPKCS11Provider,
>  	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
>  	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
> -	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
> +	oAddressFamily, oGssAuthentication, oGssDelegateCreds, oGssEnableMITM,
>  	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
>  	oSendEnv, oControlPath, oControlMaster, oControlPersist,
>  	oHashKnownHosts,
> @@ -170,9 +170,11 @@
>  #if defined(GSSAPI)
>  	{ "gssapiauthentication", oGssAuthentication },
>  	{ "gssapidelegatecredentials", oGssDelegateCreds },
> +	{ "gssapienablemitmattack", oGssEnableMITM },
>  #else
>  	{ "gssapiauthentication", oUnsupported },
>  	{ "gssapidelegatecredentials", oUnsupported },
> +	{ "gssapienablemitmattack", oUnsupported },
>  #endif
>  	{ "fallbacktorsh", oDeprecated },
>  	{ "usersh", oDeprecated },
> @@ -487,6 +489,10 @@
>  		intptr = &options->gss_deleg_creds;
>  		goto parse_flag;
>  
> +	case oGssEnableMITM:
> +		intptr = &options->gss_enable_mitm;
> +		goto parse_flag;
> +
>  	case oBatchMode:
>  		intptr = &options->batch_mode;
>  		goto parse_flag;
> @@ -1140,6 +1146,7 @@
>  	options->challenge_response_authentication = -1;
>  	options->gss_authentication = -1;
>  	options->gss_deleg_creds = -1;
> +	options->gss_enable_mitm = -1;
>  	options->password_authentication = -1;
>  	options->kbd_interactive_authentication = -1;
>  	options->kbd_interactive_devices = NULL;
> @@ -1241,6 +1248,8 @@
>  		options->gss_authentication = 0;
>  	if (options->gss_deleg_creds == -1)
>  		options->gss_deleg_creds = 0;
> +	if (options->gss_enable_mitm == -1)
> +		options->gss_enable_mitm = 0;
>  	if (options->password_authentication == -1)
>  		options->password_authentication = 1;
>  	if (options->kbd_interactive_authentication == -1)
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/readconf.c.rej openssh-6.0p1/readconf.c.rej
> --- openssh-6.0p1.orig/readconf.c.rej	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/readconf.c.rej	2012-07-12 17:01:14.446692498 +0200
> @@ -0,0 +1,155 @@
> +***************
> +*** 129,140 ****
> +  	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
> +  	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
> +  	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
> +  	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
> +  	oSendEnv, oControlPath, oControlMaster, oControlPersist,
> +  	oHashKnownHosts,
> +  	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
> +  	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
> +  	oKexAlgorithms, oIPQoS, oRequestTTY,
> +  	oDeprecated, oUnsupported
> +  } OpCodes;
> +  
> +--- 129,144 ----
> +  	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
> +  	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
> +  	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
> ++ 	oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey,
> ++ 	oGssServerIdentity, 
> +  	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
> +  	oSendEnv, oControlPath, oControlMaster, oControlPersist,
> +  	oHashKnownHosts,
> +  	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
> +  	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
> +  	oKexAlgorithms, oIPQoS, oRequestTTY,
> ++ 	oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
> ++ 	oHPNBufferSize,
> +  	oDeprecated, oUnsupported
> +  } OpCodes;
> +  
> +***************
> +*** 169,178 ****
> +  	{ "afstokenpassing", oUnsupported },
> +  #if defined(GSSAPI)
> +  	{ "gssapiauthentication", oGssAuthentication },
> +  	{ "gssapidelegatecredentials", oGssDelegateCreds },
> +  #else
> +  	{ "gssapiauthentication", oUnsupported },
> +  	{ "gssapidelegatecredentials", oUnsupported },
> +  #endif
> +  	{ "fallbacktorsh", oDeprecated },
> +  	{ "usersh", oDeprecated },
> +--- 173,191 ----
> +  	{ "afstokenpassing", oUnsupported },
> +  #if defined(GSSAPI)
> +  	{ "gssapiauthentication", oGssAuthentication },
> ++ 	{ "gssapikeyexchange", oGssKeyEx },
> +  	{ "gssapidelegatecredentials", oGssDelegateCreds },
> ++ 	{ "gssapitrustdns", oGssTrustDns },
> ++ 	{ "gssapiclientidentity", oGssClientIdentity },
> ++ 	{ "gssapiserveridentity", oGssServerIdentity },
> ++ 	{ "gssapirenewalforcesrekey", oGssRenewalRekey },
> +  #else
> +  	{ "gssapiauthentication", oUnsupported },
> ++ 	{ "gssapikeyexchange", oUnsupported },
> +  	{ "gssapidelegatecredentials", oUnsupported },
> ++ 	{ "gssapitrustdns", oUnsupported },
> ++ 	{ "gssapiclientidentity", oUnsupported },
> ++ 	{ "gssapirenewalforcesrekey", oUnsupported },
> +  #endif
> +  	{ "fallbacktorsh", oDeprecated },
> +  	{ "usersh", oDeprecated },
> +***************
> +*** 485,494 ****
> +  		intptr = &options->gss_authentication;
> +  		goto parse_flag;
> +  
> +  	case oGssDelegateCreds:
> +  		intptr = &options->gss_deleg_creds;
> +  		goto parse_flag;
> +  
> +  	case oBatchMode:
> +  		intptr = &options->batch_mode;
> +  		goto parse_flag;
> +--- 504,533 ----
> +  		intptr = &options->gss_authentication;
> +  		goto parse_flag;
> +  
> ++ 	case oGssKeyEx:
> ++ 		intptr = &options->gss_keyex;
> ++ 		goto parse_flag;
> ++ 
> +  	case oGssDelegateCreds:
> +  		intptr = &options->gss_deleg_creds;
> +  		goto parse_flag;
> +  
> ++ 	case oGssTrustDns:
> ++ 		intptr = &options->gss_trust_dns;
> ++ 		goto parse_flag;
> ++ 
> ++ 	case oGssClientIdentity:
> ++ 		charptr = &options->gss_client_identity;
> ++ 		goto parse_string;
> ++ 
> ++ 	case oGssServerIdentity:
> ++ 		charptr = &options->gss_server_identity;
> ++ 		goto parse_string;
> ++ 
> ++ 	case oGssRenewalRekey:
> ++ 		intptr = &options->gss_renewal_rekey;
> ++ 		goto parse_flag;
> ++ 
> +  	case oBatchMode:
> +  		intptr = &options->batch_mode;
> +  		goto parse_flag;
> +***************
> +*** 1145,1151 ****
> +  	options->pubkey_authentication = -1;
> +  	options->challenge_response_authentication = -1;
> +  	options->gss_authentication = -1;
> +  	options->gss_deleg_creds = -1;
> +  	options->password_authentication = -1;
> +  	options->kbd_interactive_authentication = -1;
> +  	options->kbd_interactive_devices = NULL;
> +--- 1219,1230 ----
> +  	options->pubkey_authentication = -1;
> +  	options->challenge_response_authentication = -1;
> +  	options->gss_authentication = -1;
> ++ 	options->gss_keyex = -1;
> +  	options->gss_deleg_creds = -1;
> ++ 	options->gss_trust_dns = -1;
> ++ 	options->gss_renewal_rekey = -1;
> ++ 	options->gss_client_identity = NULL;
> ++ 	options->gss_server_identity = NULL;
> +  	options->password_authentication = -1;
> +  	options->kbd_interactive_authentication = -1;
> +  	options->kbd_interactive_devices = NULL;
> +***************
> +*** 1245,1253 ****
> +  	if (options->challenge_response_authentication == -1)
> +  		options->challenge_response_authentication = 1;
> +  	if (options->gss_authentication == -1)
> +- 		options->gss_authentication = 0;
> +  	if (options->gss_deleg_creds == -1)
> +- 		options->gss_deleg_creds = 0;
> +  	if (options->password_authentication == -1)
> +  		options->password_authentication = 1;
> +  	if (options->kbd_interactive_authentication == -1)
> +--- 1330,1344 ----
> +  	if (options->challenge_response_authentication == -1)
> +  		options->challenge_response_authentication = 1;
> +  	if (options->gss_authentication == -1)
> ++ 		options->gss_authentication = 1;
> ++ 	if (options->gss_keyex == -1)
> ++ 		options->gss_keyex = 1;
> +  	if (options->gss_deleg_creds == -1)
> ++ 		options->gss_deleg_creds = 1;
> ++ 	if (options->gss_trust_dns == -1)
> ++ 		options->gss_trust_dns = 1;
> ++ 	if (options->gss_renewal_rekey == -1)
> ++ 		options->gss_renewal_rekey = 0;
> +  	if (options->password_authentication == -1)
> +  		options->password_authentication = 1;
> +  	if (options->kbd_interactive_authentication == -1)
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/readconf.h openssh-6.0p1/readconf.h
> --- openssh-6.0p1.orig/readconf.h	2012-07-12 17:00:51.346240499 +0200
> +++ openssh-6.0p1/readconf.h	2012-07-12 17:26:25.816272118 +0200
> @@ -48,7 +48,12 @@
>  	int     challenge_response_authentication;
>  					/* Try S/Key or TIS, authentication. */
>  	int     gss_authentication;	/* Try GSS authentication */
> -	int     gss_deleg_creds;	/* Delegate GSS credentials */
> + 	int     gss_keyex;		/* Try GSS key exchange */
> +  	int     gss_deleg_creds;	/* Delegate GSS credentials */
> + 	int	gss_trust_dns;		/* Trust DNS for GSS canonicalization */
> + 	int	gss_renewal_rekey;	/* Credential renewal forces rekey */
> + 	char    *gss_client_identity;   /* Principal to initiate GSSAPI with */
> + 	char    *gss_server_identity;   /* GSSAPI target principal */
>  	int 	gss_enable_mitm;	/* Enable old style gssapi auth */
>  	int     password_authentication;	/* Try password
>  						 * authentication. */
> @@ -62,6 +67,10 @@
>  	int     compression_level;	/* Compression level 1 (fast) to 9
>  					 * (best). */
>  	int     tcp_keep_alive;	/* Set SO_KEEPALIVE. */
> +	int     tcp_rcv_buf; /* user switch to set tcp recv buffer */
> +	int     tcp_rcv_buf_poll; /* Option to poll recv buf every window transfer */
> +	int     hpn_disabled;    /* Switch to disable HPN buffer management */
> +	int     hpn_buffer_size; /* User definable size for HPN buffer window */
>  	int	ip_qos_interactive;	/* IP ToS/DSCP/class for interactive */
>  	int	ip_qos_bulk;		/* IP ToS/DSCP/class for bulk traffic */
>  	LogLevel log_level;	/* Level for logging. */
> @@ -84,6 +93,8 @@
>  	char   *host_key_alias;	/* hostname alias for .ssh/known_hosts */
>  	char   *proxy_command;	/* Proxy command for connecting the host. */
>  	char   *user;		/* User to log in as. */
> +	int    implicit;	/* Login user was not specified.
> +				   Server may choose based on authctxt. */
>  	int     escape_char;	/* Escape character; -2 = none */
>  
>  	u_int	num_system_hostfiles;	/* Paths for /etc/ssh/ssh_known_hosts */
> @@ -110,6 +121,8 @@
>  
>  	int	enable_ssh_keysign;
>  	int64_t rekey_limit;
> +	int     none_switch;    /* Use none cipher */
> +	int     none_enabled;   /* Allow none to be used */
>  	int	no_host_authentication_for_localhost;
>  	int	identities_only;
>  	int	server_alive_interval;
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/readconf.h.orig openssh-6.0p1/readconf.h.orig
> --- openssh-6.0p1.orig/readconf.h.orig	2012-07-12 17:00:51.342240421 +0200
> +++ openssh-6.0p1/readconf.h.orig	2012-07-12 16:59:38.520815576 +0200
> @@ -49,6 +49,7 @@
>  					/* Try S/Key or TIS, authentication. */
>  	int     gss_authentication;	/* Try GSS authentication */
>  	int     gss_deleg_creds;	/* Delegate GSS credentials */
> +	int 	gss_enable_mitm;	/* Enable old style gssapi auth */
>  	int     password_authentication;	/* Try password
>  						 * authentication. */
>  	int     kbd_interactive_authentication; /* Try keyboard-interactive auth. */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/readconf.h.rej openssh-6.0p1/readconf.h.rej
> --- openssh-6.0p1.orig/readconf.h.rej	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/readconf.h.rej	2012-07-12 17:01:14.466692889 +0200
> @@ -0,0 +1,22 @@
> +***************
> +*** 48,54 ****
> +  	int     challenge_response_authentication;
> +  					/* Try S/Key or TIS, authentication. */
> +  	int     gss_authentication;	/* Try GSS authentication */
> +  	int     gss_deleg_creds;	/* Delegate GSS credentials */
> +  	int     password_authentication;	/* Try password
> +  						 * authentication. */
> +  	int     kbd_interactive_authentication; /* Try keyboard-interactive auth. */
> +--- 48,59 ----
> +  	int     challenge_response_authentication;
> +  					/* Try S/Key or TIS, authentication. */
> +  	int     gss_authentication;	/* Try GSS authentication */
> ++ 	int     gss_keyex;		/* Try GSS key exchange */
> +  	int     gss_deleg_creds;	/* Delegate GSS credentials */
> ++ 	int	gss_trust_dns;		/* Trust DNS for GSS canonicalization */
> ++ 	int	gss_renewal_rekey;	/* Credential renewal forces rekey */
> ++ 	char    *gss_client_identity;   /* Principal to initiate GSSAPI with */
> ++ 	char    *gss_server_identity;   /* GSSAPI target principal */
> +  	int     password_authentication;	/* Try password
> +  						 * authentication. */
> +  	int     kbd_interactive_authentication; /* Try keyboard-interactive auth. */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/scp.c openssh-6.0p1/scp.c
> --- openssh-6.0p1.orig/scp.c	2012-07-12 17:00:49.786209975 +0200
> +++ openssh-6.0p1/scp.c	2012-07-12 17:01:14.474693046 +0200
> @@ -731,7 +731,7 @@
>  	off_t i, statbytes;
>  	size_t amt;
>  	int fd = -1, haderr, indx;
> -	char *last, *name, buf[2048], encname[MAXPATHLEN];
> +	char *last, *name, buf[16384], encname[MAXPATHLEN];
>  	int len;
>  
>  	for (indx = 0; indx < argc; ++indx) {
> @@ -913,7 +913,7 @@
>  	mode_t mode, omode, mask;
>  	off_t size, statbytes;
>  	int setimes, targisdir, wrerrno = 0;
> -	char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
> +	char ch, *cp, *np, *targ, *why, *vect[1], buf[16384];
>  	struct timeval tv[2];
>  
>  #define	atime	tv[0]
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/servconf.c openssh-6.0p1/servconf.c
> --- openssh-6.0p1.orig/servconf.c	2012-07-12 17:00:51.358240734 +0200
> +++ openssh-6.0p1/servconf.c	2012-07-12 17:48:40.802408147 +0200
> @@ -62,6 +62,7 @@
>  
>  	/* Portable-specific options */
>  	options->use_pam = -1;
> +	options->permit_pam_user_change = -1;
>  
>  	/* Standard Options */
>  	options->num_ports = 0;
> @@ -95,9 +96,19 @@
>  	options->kerberos_authentication = -1;
>  	options->kerberos_or_local_passwd = -1;
>  	options->kerberos_ticket_cleanup = -1;
> +#ifdef  SESSION_HOOKS
> +        options->session_hooks_allow = -1;
> +        options->session_hooks_startup_cmd = NULL;
> +        options->session_hooks_shutdown_cmd = NULL;
> +#endif
>  	options->kerberos_get_afs_token = -1;
> -	options->gss_authentication=-1;
> + 	options->gss_authentication = -1;
> + 	options->gss_deleg_creds = -1;
> + 	options->gss_keyex = -1;
>  	options->gss_cleanup_creds = -1;
> + 	options->gss_strict_acceptor = -1;
> + 	options->gsi_allow_limited_proxy = -1;
> + 	options->gss_store_rekey = -1;
>  	options->gss_enable_mitm = -1;
>  	options->password_authentication = -1;
>  	options->kbd_interactive_authentication = -1;
> @@ -134,9 +145,15 @@
>  	options->adm_forced_command = NULL;
>  	options->chroot_directory = NULL;
>  	options->zero_knowledge_password_authentication = -1;
> +	options->disable_usage_stats = 0;
> +	options->usage_stats_targets = NULL;
>  	options->revoked_keys_file = NULL;
>  	options->trusted_user_ca_keys = NULL;
>  	options->authorized_principals_file = NULL;
> +	options->none_enabled = -1;
> +	options->tcp_rcv_buf_poll = -1;
> +	options->hpn_disabled = -1;
> +	options->hpn_buffer_size = -1;
>  	options->ip_qos_interactive = -1;
>  	options->ip_qos_bulk = -1;
>  }
> @@ -144,9 +161,16 @@
>  void
>  fill_default_server_options(ServerOptions *options)
>  {
> +	/* needed for hpn socket tests */
> +	int sock;
> +	int socksize;
> +	int socksizelen = sizeof(int);
> +
>  	/* Portable-specific options */
>  	if (options->use_pam == -1)
>  		options->use_pam = 0;
> +	if (options->permit_pam_user_change == -1)
> +		options->permit_pam_user_change = 0;
>  
>  	/* Standard Options */
>  	if (options->protocol == SSH_PROTO_UNKNOWN)
> @@ -222,12 +246,26 @@
>  		options->kerberos_or_local_passwd = 1;
>  	if (options->kerberos_ticket_cleanup == -1)
>  		options->kerberos_ticket_cleanup = 1;
> +#ifdef  SESSION_HOOKS
> +        if (options->session_hooks_allow == -1)
> +                options->session_hooks_allow = 0;
> +#endif
>  	if (options->kerberos_get_afs_token == -1)
>  		options->kerberos_get_afs_token = 0;
>  	if (options->gss_authentication == -1)
> -		options->gss_authentication = 0;
> + 		options->gss_authentication = 1;
> + 	if (options->gss_deleg_creds == -1)
> + 		options->gss_deleg_creds = 1;
> + 	if (options->gss_keyex == -1)
> + 		options->gss_keyex = 1;
>  	if (options->gss_cleanup_creds == -1)
>  		options->gss_cleanup_creds = 1;
> + 	if (options->gss_strict_acceptor == -1)
> + 		options->gss_strict_acceptor = 1;
> + 	if (options->gsi_allow_limited_proxy == -1)
> + 		options->gsi_allow_limited_proxy = 0;
> + 	if (options->gss_store_rekey == -1)
> + 		options->gss_store_rekey = 0;
>  	if (options->gss_enable_mitm == -1)
>  		options->gss_enable_mitm = 0;
>  	if (options->password_authentication == -1)
> @@ -281,6 +319,42 @@
>  	if (options->ip_qos_bulk == -1)
>  		options->ip_qos_bulk = IPTOS_THROUGHPUT;
>  
> +	if (options->hpn_disabled == -1) 
> +		options->hpn_disabled = 0;
> +
> +	if (options->hpn_buffer_size == -1) {
> +		/* option not explicitly set. Now we have to figure out */
> +		/* what value to use */
> +		if (options->hpn_disabled == 1) {
> +			options->hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
> +		} else {
> +			/* get the current RCV size and set it to that */
> +			/*create a socket but don't connect it */
> +			/* we use that the get the rcv socket size */
> +			sock = socket(AF_INET, SOCK_STREAM, 0);
> +			getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
> +				   &socksize, &socksizelen);
> +			close(sock);
> +			options->hpn_buffer_size = socksize;
> +			debug ("HPN Buffer Size: %d", options->hpn_buffer_size);
> +			
> +		} 
> +	} else {
> +		/* we have to do this incase the user sets both values in a contradictory */
> +		/* manner. hpn_disabled overrrides hpn_buffer_size*/
> +		if (options->hpn_disabled <= 0) {
> +			if (options->hpn_buffer_size == 0)
> +				options->hpn_buffer_size = 1;
> +			/* limit the maximum buffer to 64MB */
> +			if (options->hpn_buffer_size > 64*1024) {
> +				options->hpn_buffer_size = 64*1024*1024;
> +			} else {
> +				options->hpn_buffer_size *= 1024;
> +			}
> +		} else
> +			options->hpn_buffer_size = CHAN_TCP_WINDOW_DEFAULT;
> +	}
> +
>  	/* Turn privilege separation on by default */
>  	if (use_privsep == -1)
>  		use_privsep = PRIVSEP_ON;
> @@ -293,14 +367,13 @@
>  		options->compression = 0;
>  	}
>  #endif
> -
>  }
>  
>  /* Keyword tokens. */
>  typedef enum {
>  	sBadOption,		/* == unknown option */
>  	/* Portable-specific options */
> -	sUsePAM,
> +	sUsePAM, sPermitPAMUserChange,
>  	/* Standard Options */
>  	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
>  	sPermitRootLogin, sLogFacility, sLogLevel,
> @@ -308,6 +381,9 @@
>  	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
>  	sKerberosGetAFSToken,
>  	sKerberosTgtPassing, sChallengeResponseAuthentication,
> +#ifdef SESSION_HOOKS
> +        sAllowSessionHooks, sSessionHookStartupCmd, sSessionHookShutdownCmd,
> +#endif
>  	sPasswordAuthentication, sKbdInteractiveAuthentication,
>  	sListenAddress, sAddressFamily,
>  	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
> @@ -321,11 +397,18 @@
>  	sBanner, sUseDNS, sHostbasedAuthentication,
>  	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
>  	sClientAliveCountMax, sAuthorizedKeysFile,
> -	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sGssEnableMITM,
> -	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
> +        sGssDelegateCreds,
> +        sGssCredsPath,
> + 	sGsiAllowLimitedProxy,
> + 	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
> + 	sGssKeyEx, sGssStoreRekey,
> + 	sAcceptEnv, sPermitTunnel,
> +	sGssEnableMITM, sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
>  	sUsePrivilegeSeparation, sAllowAgentForwarding,
> + 	sDisUsageStats, sUsageStatsTarg,
>  	sZeroKnowledgePasswordAuthentication, sHostCertificate,
>  	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
> + 	sNoneEnabled, sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize,
>  	sKexAlgorithms, sIPQoS,
>  	sDeprecated, sUnsupported
>  } ServerOpCodes;
> @@ -343,8 +426,10 @@
>  	/* Portable-specific options */
>  #ifdef USE_PAM
>  	{ "usepam", sUsePAM, SSHCFG_GLOBAL },
> +	{ "permitpamuserchange", sPermitPAMUserChange, SSHCFG_GLOBAL },
>  #else
>  	{ "usepam", sUnsupported, SSHCFG_GLOBAL },
> +	{ "permitpamuserchange", sUnsupported, SSHCFG_GLOBAL },
>  #endif
>  	{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
>  	/* Standard Options */
> @@ -384,13 +469,38 @@
>  	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
>  #ifdef GSSAPI
>  	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
> +	{ "gssapidelegatecredentials", sGssDelegateCreds, SSHCFG_ALL },
>  	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
> +	{ "gssapicleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL },
> +	{ "gssapicredentialspath", sGssCredsPath, SSHCFG_GLOBAL },
> +#ifdef GSI
> +	{ "gsiallowlimitedproxy", sGsiAllowLimitedProxy, SSHCFG_GLOBAL },
> +#endif
> +	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
> +	{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
> +	{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
>  	{ "gssapienablemitmattack", sGssEnableMITM },
>  #else
>  	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
> +	{ "gssapidelegatecredentials", sUnsupported, SSHCFG_ALL },
>  	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
> +	{ "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL },
> +	{ "gssapicredentialspath", sUnsupported, SSHCFG_GLOBAL },
> +#ifdef GSI
> +	{ "gsiallowlimitedproxy", sUnsupported, SSHCFG_GLOBAL },
> +#endif
> +	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
> +	{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
> +	{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
>  	{ "gssapienablemitmattack", sUnsupported },
>  #endif
> +#ifdef SESSION_HOOKS
> +    	{ "allowsessionhooks", sAllowSessionHooks, SSHCFG_GLOBAL },
> +    	{ "sessionhookstartupcmd", sSessionHookStartupCmd, SSHCFG_GLOBAL },
> +    	{ "sessionhookshutdowncmd", sSessionHookShutdownCmd, SSHCFG_GLOBAL },
> +#endif        
> +	{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
> +	{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
>  	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
>  	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
>  	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
> @@ -447,10 +557,16 @@
>  	{ "permitopen", sPermitOpen, SSHCFG_ALL },
>  	{ "forcecommand", sForceCommand, SSHCFG_ALL },
>  	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
> +	{ "disableusagestats", sDisUsageStats, SSHCFG_GLOBAL},
> +	{ "usagestatstargets", sUsageStatsTarg, SSHCFG_GLOBAL},
>  	{ "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
>  	{ "revokedkeys", sRevokedKeys, SSHCFG_ALL },
>  	{ "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
>  	{ "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
> +	{ "noneenabled", sNoneEnabled, SSHCFG_ALL },
> +	{ "hpndisabled", sHPNDisabled, SSHCFG_ALL },
> +	{ "hpnbuffersize", sHPNBufferSize, SSHCFG_ALL },
> +	{ "tcprcvbufpoll", sTcpRcvBufPoll, SSHCFG_ALL },
>  	{ "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
>  	{ "ipqos", sIPQoS, SSHCFG_ALL },
>  	{ NULL, sBadOption, 0 }
> @@ -479,6 +595,7 @@
>  
>  	for (i = 0; keywords[i].name; i++)
>  		if (strcasecmp(cp, keywords[i].name) == 0) {
> +		        debug ("Config token is %s", keywords[i].name);
>  			*flags = keywords[i].flags;
>  			return keywords[i].opcode;
>  		}
> @@ -763,6 +880,10 @@
>  		intptr = &options->use_pam;
>  		goto parse_flag;
>  
> +	case sPermitPAMUserChange:
> +		intptr = &options->permit_pam_user_change;
> +		goto parse_flag;
> +
>  	/* Standard Options */
>  	case sBadOption:
>  		return -1;
> @@ -923,6 +1044,22 @@
>  			*intptr = value;
>  		break;
>  
> +	case sNoneEnabled:
> +		intptr = &options->none_enabled;
> +		goto parse_flag;
> +
> +	case sTcpRcvBufPoll:
> +		intptr = &options->tcp_rcv_buf_poll;
> +		goto parse_flag;
> +
> +	case sHPNDisabled:
> +		intptr = &options->hpn_disabled;
> +		goto parse_flag;
> +
> +	case sHPNBufferSize:
> +		intptr = &options->hpn_buffer_size;
> +		goto parse_int;
> +
>  	case sIgnoreUserKnownHosts:
>  		intptr = &options->ignore_user_known_hosts;
>  		goto parse_flag;
> @@ -967,10 +1104,53 @@
>  		intptr = &options->gss_authentication;
>  		goto parse_flag;
>  
> + 	case sGssDelegateCreds:
> + 		intptr = &options->gss_deleg_creds;
> + 		goto parse_flag;
> + 
> + 	case sGssKeyEx:
> + 		intptr = &options->gss_keyex;
> + 		goto parse_flag;
> +
>  	case sGssCleanupCreds:
>  		intptr = &options->gss_cleanup_creds;
>  		goto parse_flag;
>  
> +	case sGssCredsPath:
> +		charptr = &options->gss_creds_path;
> +		goto parse_filename;
> +
> +	case sGssStrictAcceptor:
> +		intptr = &options->gss_strict_acceptor;
> +		goto parse_flag;
> +
> +	case sGssStoreRekey:
> +		intptr = &options->gss_store_rekey;
> +		goto parse_flag;
> +
> +#ifdef GSI
> +	case sGsiAllowLimitedProxy:
> +		intptr = &options->gsi_allow_limited_proxy;
> +		goto parse_flag;
> +#endif
> +
> +#ifdef SESSION_HOOKS
> +        case sAllowSessionHooks:
> +                intptr = &options->session_hooks_allow;
> +                goto parse_flag;
> +        case sSessionHookStartupCmd:
> +        case sSessionHookShutdownCmd:
> +                arg = strdelim(&cp);
> +                if (!arg || *arg == '\0')
> +                    fatal("%s line %d: empty session hook command",
> +                          filename, linenum);
> +                if (opcode==sSessionHookStartupCmd)
> +                    options->session_hooks_startup_cmd = strdup(arg);
> +                else
> +                    options->session_hooks_shutdown_cmd = strdup(arg);
> +                break;
> +#endif                  
> +
>  	case sGssEnableMITM:
>  		intptr = &options->gss_enable_mitm;
>  		goto parse_flag;
> @@ -1379,6 +1559,39 @@
>  			*charptr = xstrdup(arg);
>  		break;
>  
> +	case sDisUsageStats:
> +		charptr = &options->chroot_directory;
> +
> +		arg = strdelim(&cp);
> +		if (!arg || *arg == '\0')
> +			fatal("%s line %d: missing value.",
> +			    filename, linenum);
> +		if (!strcasecmp(arg, "true") ||
> +		    !strcasecmp(arg, "enabled") ||
> +		    !strcasecmp(arg, "yes") ||
> +		    !strcasecmp(arg, "on") ||
> +		    !strcasecmp(arg, "1"))
> +			options->disable_usage_stats = 1;
> +		else if (!strcasecmp(arg, "false") ||
> +			 !strcasecmp(arg, "disabled") ||
> +			 !strcasecmp(arg, "no") ||
> +			 !strcasecmp(arg, "off") ||
> +			 !strcasecmp(arg, "0"))
> +			options->disable_usage_stats = 0;
> +		else
> +			fatal("Incorrect value for disable_usage_stats");
> +		break;
> +
> +	case sUsageStatsTarg:
> +		charptr = &options->chroot_directory;
> +
> +		arg = strdelim(&cp);
> +		if (!arg || *arg == '\0')
> +			fatal("%s line %d: missing value.",
> +			    filename, linenum);
> +		options->usage_stats_targets = xstrdup(arg);
> +		break;
> +
>  	case sTrustedUserCAKeys:
>  		charptr = &options->trusted_user_ca_keys;
>  		goto parse_filename;
> @@ -1501,6 +1714,7 @@
>  {
>  	M_CP_INTOPT(password_authentication);
>  	M_CP_INTOPT(gss_authentication);
> +	M_CP_INTOPT(gss_deleg_creds);
>  	M_CP_INTOPT(rsa_authentication);
>  	M_CP_INTOPT(pubkey_authentication);
>  	M_CP_INTOPT(kerberos_authentication);
> @@ -1729,7 +1943,10 @@
>  #endif
>  #ifdef GSSAPI
>  	dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
> +	dump_cfg_fmtint(sGssKeyEx, o->gss_keyex);
>  	dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
> +	dump_cfg_fmtint(sGssStrictAcceptor, o->gss_strict_acceptor);
> +	dump_cfg_fmtint(sGssStoreRekey, o->gss_store_rekey);
>  #endif
>  #ifdef JPAKE
>  	dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/servconf.c.orig openssh-6.0p1/servconf.c.orig
> --- openssh-6.0p1.orig/servconf.c.orig	2012-07-12 17:00:51.350240577 +0200
> +++ openssh-6.0p1/servconf.c.orig	2012-07-12 16:59:38.544816040 +0200
> @@ -98,6 +98,7 @@
>  	options->kerberos_get_afs_token = -1;
>  	options->gss_authentication=-1;
>  	options->gss_cleanup_creds = -1;
> +	options->gss_enable_mitm = -1;
>  	options->password_authentication = -1;
>  	options->kbd_interactive_authentication = -1;
>  	options->challenge_response_authentication = -1;
> @@ -227,6 +228,8 @@
>  		options->gss_authentication = 0;
>  	if (options->gss_cleanup_creds == -1)
>  		options->gss_cleanup_creds = 1;
> +	if (options->gss_enable_mitm == -1)
> +		options->gss_enable_mitm = 0;
>  	if (options->password_authentication == -1)
>  		options->password_authentication = 1;
>  	if (options->kbd_interactive_authentication == -1)
> @@ -318,7 +321,7 @@
>  	sBanner, sUseDNS, sHostbasedAuthentication,
>  	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
>  	sClientAliveCountMax, sAuthorizedKeysFile,
> -	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
> +	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sGssEnableMITM,
>  	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
>  	sUsePrivilegeSeparation, sAllowAgentForwarding,
>  	sZeroKnowledgePasswordAuthentication, sHostCertificate,
> @@ -382,9 +385,11 @@
>  #ifdef GSSAPI
>  	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
>  	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
> +	{ "gssapienablemitmattack", sGssEnableMITM },
>  #else
>  	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
>  	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
> +	{ "gssapienablemitmattack", sUnsupported },
>  #endif
>  	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
>  	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
> @@ -966,6 +971,10 @@
>  		intptr = &options->gss_cleanup_creds;
>  		goto parse_flag;
>  
> +	case sGssEnableMITM:
> +		intptr = &options->gss_enable_mitm;
> +		goto parse_flag;
> +
>  	case sPasswordAuthentication:
>  		intptr = &options->password_authentication;
>  		goto parse_flag;
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/servconf.c.rej openssh-6.0p1/servconf.c.rej
> --- openssh-6.0p1.orig/servconf.c.rej	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/servconf.c.rej	2012-07-12 17:01:14.502693594 +0200
> @@ -0,0 +1,220 @@
> +***************
> +*** 95,103 ****
> +  	options->kerberos_authentication = -1;
> +  	options->kerberos_or_local_passwd = -1;
> +  	options->kerberos_ticket_cleanup = -1;
> +  	options->kerberos_get_afs_token = -1;
> +- 	options->gss_authentication=-1;
> +  	options->gss_cleanup_creds = -1;
> +  	options->password_authentication = -1;
> +  	options->kbd_interactive_authentication = -1;
> +  	options->challenge_response_authentication = -1;
> +--- 96,114 ----
> +  	options->kerberos_authentication = -1;
> +  	options->kerberos_or_local_passwd = -1;
> +  	options->kerberos_ticket_cleanup = -1;
> ++ #ifdef  SESSION_HOOKS
> ++         options->session_hooks_allow = -1;
> ++         options->session_hooks_startup_cmd = NULL;
> ++         options->session_hooks_shutdown_cmd = NULL;
> ++ #endif
> +  	options->kerberos_get_afs_token = -1;
> ++ 	options->gss_authentication = -1;
> ++ 	options->gss_deleg_creds = -1;
> ++ 	options->gss_keyex = -1;
> +  	options->gss_cleanup_creds = -1;
> ++ 	options->gss_strict_acceptor = -1;
> ++ 	options->gsi_allow_limited_proxy = -1;
> ++ 	options->gss_store_rekey = -1;
> +  	options->password_authentication = -1;
> +  	options->kbd_interactive_authentication = -1;
> +  	options->challenge_response_authentication = -1;
> +***************
> +*** 222,233 ****
> +  		options->kerberos_or_local_passwd = 1;
> +  	if (options->kerberos_ticket_cleanup == -1)
> +  		options->kerberos_ticket_cleanup = 1;
> +  	if (options->kerberos_get_afs_token == -1)
> +  		options->kerberos_get_afs_token = 0;
> +  	if (options->gss_authentication == -1)
> +- 		options->gss_authentication = 0;
> +  	if (options->gss_cleanup_creds == -1)
> +  		options->gss_cleanup_creds = 1;
> +  	if (options->password_authentication == -1)
> +  		options->password_authentication = 1;
> +  	if (options->kbd_interactive_authentication == -1)
> +--- 246,271 ----
> +  		options->kerberos_or_local_passwd = 1;
> +  	if (options->kerberos_ticket_cleanup == -1)
> +  		options->kerberos_ticket_cleanup = 1;
> ++ #ifdef  SESSION_HOOKS
> ++     if (options->session_hooks_allow == -1)
> ++         options->session_hooks_allow = 0;
> ++ #endif
> +  	if (options->kerberos_get_afs_token == -1)
> +  		options->kerberos_get_afs_token = 0;
> +  	if (options->gss_authentication == -1)
> ++ 		options->gss_authentication = 1;
> ++ 	if (options->gss_deleg_creds == -1)
> ++ 		options->gss_deleg_creds = 1;
> ++ 	if (options->gss_keyex == -1)
> ++ 		options->gss_keyex = 1;
> +  	if (options->gss_cleanup_creds == -1)
> +  		options->gss_cleanup_creds = 1;
> ++ 	if (options->gss_strict_acceptor == -1)
> ++ 		options->gss_strict_acceptor = 1;
> ++ 	if (options->gsi_allow_limited_proxy == -1)
> ++ 		options->gsi_allow_limited_proxy = 0;
> ++ 	if (options->gss_store_rekey == -1)
> ++ 		options->gss_store_rekey = 0;
> +  	if (options->password_authentication == -1)
> +  		options->password_authentication = 1;
> +  	if (options->kbd_interactive_authentication == -1)
> +***************
> +*** 321,331 ****
> +  	sBanner, sUseDNS, sHostbasedAuthentication,
> +  	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
> +  	sClientAliveCountMax, sAuthorizedKeysFile,
> +- 	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
> +  	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
> +  	sUsePrivilegeSeparation, sAllowAgentForwarding,
> +  	sZeroKnowledgePasswordAuthentication, sHostCertificate,
> +  	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
> +  	sKexAlgorithms, sIPQoS,
> +  	sDeprecated, sUnsupported
> +  } ServerOpCodes;
> +--- 397,414 ----
> +  	sBanner, sUseDNS, sHostbasedAuthentication,
> +  	sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
> +  	sClientAliveCountMax, sAuthorizedKeysFile,
> ++     sGssDelegateCreds,
> ++     sGssCredsPath,
> ++ 	sGsiAllowLimitedProxy,
> ++ 	sGssAuthentication, sGssCleanupCreds, sGssStrictAcceptor,
> ++ 	sGssKeyEx, sGssStoreRekey,
> ++ 	sAcceptEnv, sPermitTunnel,
> +  	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
> +  	sUsePrivilegeSeparation, sAllowAgentForwarding,
> ++ 	sDisUsageStats, sUsageStatsTarg,
> +  	sZeroKnowledgePasswordAuthentication, sHostCertificate,
> +  	sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
> ++ 	sNoneEnabled, sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize,
> +  	sKexAlgorithms, sIPQoS,
> +  	sDeprecated, sUnsupported
> +  } ServerOpCodes;
> +***************
> +*** 384,394 ****
> +  	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
> +  #ifdef GSSAPI
> +  	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
> +  	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
> +  #else
> +  	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
> +  	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
> +  #endif
> +  	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
> +  	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
> +  	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
> +--- 469,504 ----
> +  	{ "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
> +  #ifdef GSSAPI
> +  	{ "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
> ++ 	{ "gssapidelegatecredentials", sGssDelegateCreds, SSHCFG_ALL },
> +  	{ "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
> ++ 	{ "gssapicleanupcreds", sGssCleanupCreds, SSHCFG_GLOBAL },
> ++ 	{ "gssapicredentialspath", sGssCredsPath, SSHCFG_GLOBAL },
> ++ #ifdef GSI
> ++ 	{ "gsiallowlimitedproxy", sGsiAllowLimitedProxy, SSHCFG_GLOBAL },
> ++ #endif
> ++ 	{ "gssapistrictacceptorcheck", sGssStrictAcceptor, SSHCFG_GLOBAL },
> ++ 	{ "gssapikeyexchange", sGssKeyEx, SSHCFG_GLOBAL },
> ++ 	{ "gssapistorecredentialsonrekey", sGssStoreRekey, SSHCFG_GLOBAL },
> +  #else
> +  	{ "gssapiauthentication", sUnsupported, SSHCFG_ALL },
> ++ 	{ "gssapidelegatecredentials", sUnsupported, SSHCFG_ALL },
> +  	{ "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
> ++ 	{ "gssapicleanupcreds", sUnsupported, SSHCFG_GLOBAL },
> ++ 	{ "gssapicredentialspath", sUnsupported, SSHCFG_GLOBAL },
> ++ #ifdef GSI
> ++ 	{ "gsiallowlimitedproxy", sUnsupported, SSHCFG_GLOBAL },
> ++ #endif
> ++ 	{ "gssapistrictacceptorcheck", sUnsupported, SSHCFG_GLOBAL },
> ++ 	{ "gssapikeyexchange", sUnsupported, SSHCFG_GLOBAL },
> ++ 	{ "gssapistorecredentialsonrekey", sUnsupported, SSHCFG_GLOBAL },
> +  #endif
> ++ #ifdef SESSION_HOOKS
> ++     { "allowsessionhooks", sAllowSessionHooks, SSHCFG_GLOBAL },
> ++     { "sessionhookstartupcmd", sSessionHookStartupCmd, SSHCFG_GLOBAL },
> ++     { "sessionhookshutdowncmd", sSessionHookShutdownCmd, SSHCFG_GLOBAL },
> ++ #endif        
> ++ 	{ "gssusesessionccache", sUnsupported, SSHCFG_GLOBAL },
> ++ 	{ "gssapiusesessioncredcache", sUnsupported, SSHCFG_GLOBAL },
> +  	{ "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
> +  	{ "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
> +  	{ "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
> +***************
> +*** 967,976 ****
> +  		intptr = &options->gss_authentication;
> +  		goto parse_flag;
> +  
> +  	case sGssCleanupCreds:
> +  		intptr = &options->gss_cleanup_creds;
> +  		goto parse_flag;
> +  
> +  	case sPasswordAuthentication:
> +  		intptr = &options->password_authentication;
> +  		goto parse_flag;
> +--- 1104,1156 ----
> +  		intptr = &options->gss_authentication;
> +  		goto parse_flag;
> +  
> ++ 	case sGssDelegateCreds:
> ++ 		intptr = &options->gss_deleg_creds;
> ++ 		goto parse_flag;
> ++ 
> ++ 	case sGssKeyEx:
> ++ 		intptr = &options->gss_keyex;
> ++ 		goto parse_flag;
> ++ 
> +  	case sGssCleanupCreds:
> +  		intptr = &options->gss_cleanup_creds;
> +  		goto parse_flag;
> +  
> ++ 	case sGssCredsPath:
> ++ 		charptr = &options->gss_creds_path;
> ++ 		goto parse_filename;
> ++ 
> ++ 	case sGssStrictAcceptor:
> ++ 		intptr = &options->gss_strict_acceptor;
> ++ 		goto parse_flag;
> ++ 
> ++ 	case sGssStoreRekey:
> ++ 		intptr = &options->gss_store_rekey;
> ++ 		goto parse_flag;
> ++ 
> ++ #ifdef GSI
> ++ 	case sGsiAllowLimitedProxy:
> ++ 		intptr = &options->gsi_allow_limited_proxy;
> ++ 		goto parse_flag;
> ++ #endif
> ++ 
> ++ #ifdef SESSION_HOOKS
> ++         case sAllowSessionHooks:
> ++                 intptr = &options->session_hooks_allow;
> ++                 goto parse_flag;
> ++         case sSessionHookStartupCmd:
> ++         case sSessionHookShutdownCmd:
> ++                 arg = strdelim(&cp);
> ++                 if (!arg || *arg == '\0')
> ++                     fatal("%s line %d: empty session hook command",
> ++                           filename, linenum);
> ++                 if (opcode==sSessionHookStartupCmd)
> ++                     options->session_hooks_startup_cmd = strdup(arg);
> ++                 else
> ++                     options->session_hooks_shutdown_cmd = strdup(arg);
> ++                 break;
> ++ #endif                  
> ++ 
> +  	case sPasswordAuthentication:
> +  		intptr = &options->password_authentication;
> +  		goto parse_flag;
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/servconf.h openssh-6.0p1/servconf.h
> --- openssh-6.0p1.orig/servconf.h	2012-07-12 17:00:51.370240969 +0200
> +++ openssh-6.0p1/servconf.h	2012-07-12 17:50:20.848365923 +0200
> @@ -100,10 +100,21 @@
>  						 * /etc/passwd */
>  	int     kerberos_ticket_cleanup;	/* If true, destroy ticket
>  						 * file on logout. */
> +#ifdef SESSION_HOOKS
> +        int     session_hooks_allow;        /* If true, permit user hooks */
> +        char*   session_hooks_startup_cmd;  /* cmd to be executed before */
> +        char*   session_hooks_shutdown_cmd; /* cmd to be executed after */
> +#endif
>  	int     kerberos_get_afs_token;		/* If true, try to get AFS token if
>  						 * authenticated with Kerberos. */
> + 	int     gsi_allow_limited_proxy;	/* If true, accept limited proxies */
>  	int     gss_authentication;	/* If true, permit GSSAPI authentication */
> + 	int     gss_deleg_creds;	/* If true, store delegated GSSAPI credentials*/
> + 	int     gss_keyex;		/* If true, permit GSSAPI key exchange */
>  	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
> + 	char*   gss_creds_path;	/* If true, destroy cred cache on logout */
> + 	int 	gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */
> + 	int 	gss_store_rekey;
>  	int	gss_enable_mitm;	/* If true, enable old style GSSAPI */
>  	int     password_authentication;	/* If true, permit password
>  						 * authentication. */
> @@ -158,12 +169,21 @@
>  	char   *adm_forced_command;
>  
>  	int	use_pam;		/* Enable auth via PAM */
> + 	int	permit_pam_user_change;	/* Allow PAM to change user name */
> +        int     none_enabled;           /* enable NONE cipher switch */
> +        int     tcp_rcv_buf_poll;       /* poll tcp rcv window in autotuning kernels*/
> +	int	hpn_disabled;		/* disable hpn functionality. false by default */
> +	int	hpn_buffer_size;	/* set the hpn buffer size - default 3MB */
>  
>  	int	permit_tun;
>  
>  	int	num_permitted_opens;
>  
>  	char   *chroot_directory;
> +
> +	int    disable_usage_stats;
> +	char   *usage_stats_targets;
> +
>  	char   *revoked_keys_file;
>  	char   *trusted_user_ca_keys;
>  	char   *authorized_principals_file;
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/servconf.h.orig openssh-6.0p1/servconf.h.orig
> --- openssh-6.0p1.orig/servconf.h.orig	2012-07-12 17:00:51.366240891 +0200
> +++ openssh-6.0p1/servconf.h.orig	2012-07-12 16:59:38.568816507 +0200
> @@ -104,6 +104,7 @@
>  						 * authenticated with Kerberos. */
>  	int     gss_authentication;	/* If true, permit GSSAPI authentication */
>  	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
> +	int	gss_enable_mitm;	/* If true, enable old style GSSAPI */
>  	int     password_authentication;	/* If true, permit password
>  						 * authentication. */
>  	int     kbd_interactive_authentication;	/* If true, permit */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/servconf.h.rej openssh-6.0p1/servconf.h.rej
> --- openssh-6.0p1.orig/servconf.h.rej	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/servconf.h.rej	2012-07-12 17:01:14.522693985 +0200
> @@ -0,0 +1,34 @@
> +***************
> +*** 100,109 ****
> +  						 * /etc/passwd */
> +  	int     kerberos_ticket_cleanup;	/* If true, destroy ticket
> +  						 * file on logout. */
> +  	int     kerberos_get_afs_token;		/* If true, try to get AFS token if
> +  						 * authenticated with Kerberos. */
> +  	int     gss_authentication;	/* If true, permit GSSAPI authentication */
> +  	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
> +  	int     password_authentication;	/* If true, permit password
> +  						 * authentication. */
> +  	int     kbd_interactive_authentication;	/* If true, permit */
> +--- 100,120 ----
> +  						 * /etc/passwd */
> +  	int     kerberos_ticket_cleanup;	/* If true, destroy ticket
> +  						 * file on logout. */
> ++ #ifdef SESSION_HOOKS
> ++         int     session_hooks_allow;        /* If true, permit user hooks */
> ++         char*   session_hooks_startup_cmd;  /* cmd to be executed before */
> ++         char*   session_hooks_shutdown_cmd; /* cmd to be executed after */
> ++ #endif
> +  	int     kerberos_get_afs_token;		/* If true, try to get AFS token if
> +  						 * authenticated with Kerberos. */
> ++ 	int     gsi_allow_limited_proxy;	/* If true, accept limited proxies */
> +  	int     gss_authentication;	/* If true, permit GSSAPI authentication */
> ++ 	int     gss_deleg_creds;	/* If true, store delegated GSSAPI credentials*/
> ++ 	int     gss_keyex;		/* If true, permit GSSAPI key exchange */
> +  	int     gss_cleanup_creds;	/* If true, destroy cred cache on logout */
> ++ 	char*   gss_creds_path;	/* If true, destroy cred cache on logout */
> ++ 	int 	gss_strict_acceptor;	/* If true, restrict the GSSAPI acceptor name */
> ++ 	int 	gss_store_rekey;
> +  	int     password_authentication;	/* If true, permit password
> +  						 * authentication. */
> +  	int     kbd_interactive_authentication;	/* If true, permit */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/serverloop.c openssh-6.0p1/serverloop.c
> --- openssh-6.0p1.orig/serverloop.c	2012-07-12 17:00:49.790210053 +0200
> +++ openssh-6.0p1/serverloop.c	2012-07-12 17:01:14.530694142 +0200
> @@ -94,10 +94,10 @@
>  static int fdout;		/* Descriptor for stdout (for reading);
>  				   May be same number as fdin. */
>  static int fderr;		/* Descriptor for stderr.  May be -1. */
> -static long stdin_bytes = 0;	/* Number of bytes written to stdin. */
> -static long stdout_bytes = 0;	/* Number of stdout bytes sent to client. */
> -static long stderr_bytes = 0;	/* Number of stderr bytes sent to client. */
> -static long fdout_bytes = 0;	/* Number of stdout bytes read from program. */
> +static u_long stdin_bytes = 0;	/* Number of bytes written to stdin. */
> +static u_long stdout_bytes = 0;	/* Number of stdout bytes sent to client. */
> +static u_long stderr_bytes = 0;	/* Number of stderr bytes sent to client. */
> +static u_long fdout_bytes = 0;	/* Number of stdout bytes read from program. */
>  static int stdin_eof = 0;	/* EOF message received from client. */
>  static int fdout_eof = 0;	/* EOF encountered reading from fdout. */
>  static int fderr_eof = 0;	/* EOF encountered readung from fderr. */
> @@ -122,6 +122,20 @@
>  static void server_init_dispatch(void);
>  
>  /*
> + * Returns current time in seconds from Jan 1, 1970 with the maximum
> + * available resolution.
> + */
> +
> +static double
> +get_current_time(void)
> +{
> +	struct timeval tv;
> +	gettimeofday(&tv, NULL);
> +	return (double) tv.tv_sec + (double) tv.tv_usec / 1000000.0;
> +}
> +
> +
> +/*
>   * we write to this pipe if a SIGCHLD is caught in order to avoid
>   * the race between select() and child_terminated
>   */
> @@ -414,6 +428,7 @@
>  		} else {
>  			/* Buffer any received data. */
>  			packet_process_incoming(buf, len);
> +			fdout_bytes += len;
>  		}
>  	}
>  	if (compat20)
> @@ -436,6 +451,7 @@
>  		} else {
>  			buffer_append(&stdout_buffer, buf, len);
>  			fdout_bytes += len;
> +			debug ("FD out now: %ld", fdout_bytes);
>  		}
>  	}
>  	/* Read and buffer any available stderr data from the program. */
> @@ -503,7 +519,7 @@
>  	}
>  	/* Send any buffered packet data to the client. */
>  	if (FD_ISSET(connection_out, writeset))
> -		packet_write_poll();
> +		stdin_bytes += packet_write_poll();
>  }
>  
>  /*
> @@ -820,8 +836,10 @@
>  {
>  	fd_set *readset = NULL, *writeset = NULL;
>  	int rekeying = 0, max_fd, nalloc = 0;
> +	double start_time, total_time;
>  
>  	debug("Entering interactive session for SSH2.");
> +	start_time = get_current_time();
>  
>  	mysignal(SIGCHLD, sigchld_handler);
>  	child_terminated = 0;
> @@ -883,6 +901,11 @@
>  
>  	/* free remaining sessions, e.g. remove wtmp entries */
>  	session_destroy_all(NULL);
> +	total_time = get_current_time() - start_time;
> +	logit("SSH: Server;LType: Throughput;Remote: %s-%d;IN: %lu;OUT: %lu;Duration: %.1f;tPut_in: %.1f;tPut_out: %.1f",
> +	      get_remote_ipaddr(), get_remote_port(),
> +	      stdin_bytes, fdout_bytes, total_time, stdin_bytes / total_time, 
> +	      fdout_bytes / total_time);
>  }
>  
>  static void
> @@ -998,8 +1021,12 @@
>  	sock = tun_open(tun, mode);
>  	if (sock < 0)
>  		goto done;
> +	if (options.hpn_disabled)
>  	c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
>  	    CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
> +	else
> +		c = channel_new("tun", SSH_CHANNEL_OPEN, sock, sock, -1,
> +		    options.hpn_buffer_size, CHAN_TCP_PACKET_DEFAULT, 0, "tun", 1);
>  	c->datagram = 1;
>  #if defined(SSH_TUN_FILTER)
>  	if (mode == SSH_TUNMODE_POINTOPOINT)
> @@ -1035,6 +1062,8 @@
>  	c = channel_new("session", SSH_CHANNEL_LARVAL,
>  	    -1, -1, -1, /*window size*/0, CHAN_SES_PACKET_DEFAULT,
>  	    0, "server-session", 1);
> +	if ((options.tcp_rcv_buf_poll) && (!options.hpn_disabled))
> +		c->dynamic_window = 1;
>  	if (session_open(the_authctxt, c->self) != 1) {
>  		debug("session open failed, free channel %d", c->self);
>  		channel_free(c);
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/session.c openssh-6.0p1/session.c
> --- openssh-6.0p1.orig/session.c	2012-07-12 17:00:51.522243943 +0200
> +++ openssh-6.0p1/session.c	2012-07-12 17:01:14.554694611 +0200
> @@ -131,6 +131,11 @@
>  
>  static int session_pty_req(Session *);
>  
> +#ifdef SESSION_HOOKS
> +static void execute_session_hook(char* prog, Authctxt *authctxt,
> +                                 int startup, int save);
> +#endif
> +
>  /* import */
>  extern ServerOptions options;
>  extern char *__progname;
> @@ -238,6 +243,7 @@
>  	}
>  
>  	/* Allocate a channel for the authentication agent socket. */
> +	/* this shouldn't matter if its hpn or not - cjr */
>  	nc = channel_new("auth socket",
>  	    SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1,
>  	    CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT,
> @@ -285,6 +291,21 @@
>  	else
>  		do_authenticated1(authctxt);
>  
> +#ifdef SESSION_HOOKS
> +        if (options.session_hooks_allow &&
> +            options.session_hooks_shutdown_cmd)
> +        {
> +            execute_session_hook(options.session_hooks_shutdown_cmd,
> +                                 authctxt,
> +                                 /* startup = */ 0, /* save = */ 0);
> +
> +            if (authctxt->session_env_file)
> +            {
> +                free(authctxt->session_env_file);
> +            }
> +        }
> +#endif
> +
>  	do_cleanup(authctxt);
>  }
>  
> @@ -819,6 +840,26 @@
>  		exit (1);
>  	}
>  
> +#if defined(SESSION_HOOKS)
> +	if (options.session_hooks_allow &&
> +	    (options.session_hooks_startup_cmd ||
> +	     options.session_hooks_shutdown_cmd))
> +	{
> +		char env_file[1000];
> +		struct stat st;
> +		do
> +		{
> +			snprintf(env_file,
> +				 sizeof(env_file),
> +				 "/tmp/ssh_env_%d%d%d",
> +				 getuid(),
> +				 getpid(),
> +				 rand());
> +		} while (stat(env_file, &st)==0);
> +		s->authctxt->session_env_file = strdup(env_file);
> +	}
> +#endif
> +
>  #ifdef SSH_AUDIT_EVENTS
>  	if (command != NULL)
>  		PRIVSEP(audit_run_command(command));
> @@ -1047,6 +1088,117 @@
>  	fclose(f);
>  }
>  
> +#ifdef SESSION_HOOKS
> +#define SSH_SESSION_ENV_FILE "SSH_SESSION_ENV_FILE"
> +
> +typedef enum { no_op, execute, clear_env, restore_env,
> +               read_env, save_or_rm_env } session_action_t;
> +
> +static session_action_t action_order[2][5] = {
> +    { clear_env, read_env, execute, save_or_rm_env, restore_env }, /*shutdown*/
> +    { execute, read_env, save_or_rm_env, no_op, no_op }            /*startup */
> +};
> +
> +static
> +void execute_session_hook(char* prog, Authctxt *authctxt,
> +                          int startup, int save)
> +{
> +    extern char **environ;
> +
> +    struct stat  st;
> +    char         **saved_env, **tmpenv;
> +    char         *env_file = authctxt->session_env_file;
> +    int          i, status = 0;
> +
> +    for (i=0; i<5; i++)
> +    {
> +        switch (action_order[startup][i])
> +        {
> +          case no_op:
> +            break;
> +
> +          case execute:
> +            {
> +                FILE* fp;
> +                char  buf[1000];
> +
> +                snprintf(buf,
> +                         sizeof(buf),
> +                         "%s -c '%s'",
> +                         authctxt->pw->pw_shell,
> +                         prog);
> +
> +                debug("executing session hook: [%s]", buf);
> +                setenv(SSH_SESSION_ENV_FILE, env_file, /* overwrite = */ 1);
> +
> +                /* flusing is recommended in the popen(3) man page, to avoid
> +                   intermingling of output */
> +                fflush(stdout);
> +                fflush(stderr);
> +                if ((fp=popen(buf, "w")) == NULL)
> +                {
> +                    perror("Unable to run session hook");
> +                    return;
> +                }
> +                status = pclose(fp);
> +                debug2("session hook executed, status=%d", status);
> +                unsetenv(SSH_SESSION_ENV_FILE);
> +            }
> +            break;
> +
> +          case clear_env:
> +            saved_env = environ;
> +            tmpenv = (char**) malloc(sizeof(char*));
> +            tmpenv[0] = NULL;
> +            environ = tmpenv;
> +            break;
> +
> +          case restore_env:
> +            environ = saved_env;
> +            free(tmpenv);
> +            break;
> +
> +          case read_env:
> +            if (status==0 && stat(env_file, &st)==0)
> +            {
> +                int envsize = 0;
> +
> +                debug("reading environment from %s", env_file);
> +                while (environ[envsize++]) ;
> +                read_environment_file(&environ, &envsize, env_file);
> +            }
> +            break;
> +
> +          case save_or_rm_env:
> +            if (status==0 && save)
> +            {
> +                FILE* fp;
> +                int    envcount=0;
> +
> +                debug2("saving environment to %s", env_file);
> +                if ((fp = fopen(env_file, "w")) == NULL) /* hmm: file perms? */
> +                {
> +                    perror("Unable to save session hook info");
> +                }
> +                while (environ[envcount])
> +                {
> +                    fprintf(fp, "%s\n", environ[envcount++]);
> +                }
> +                fflush(fp);
> +                fclose(fp);
> +            }
> +            else if (stat(env_file, &st)==0)
> +            {
> +                debug2("removing environment file %s", env_file);
> +                remove(env_file);
> +            }
> +            break;
> +        }
> +    }
> +
> +}
> +#endif
> +
>  #ifdef HAVE_ETC_DEFAULT_LOGIN
>  /*
>   * Return named variable from specified environment, or NULL if not present.
> @@ -1210,6 +1362,23 @@
>  	if (getenv("TZ"))
>  		child_set_env(&env, &envsize, "TZ", getenv("TZ"));
>  
> +#ifdef GSI /* GSI shared libs typically installed in non-system locations. */
> +	{
> +		char *cp;
> +
> +		if ((cp = getenv("LD_LIBRARY_PATH")) != NULL)
> +			child_set_env(&env, &envsize, "LD_LIBRARY_PATH", cp);
> +		if ((cp = getenv("LIBPATH")) != NULL)
> +			child_set_env(&env, &envsize, "LIBPATH", cp);
> +		if ((cp = getenv("SHLIB_PATH")) != NULL)
> +			child_set_env(&env, &envsize, "SHLIB_PATH", cp);
> +		if ((cp = getenv("LD_LIBRARYN32_PATH")) != NULL)
> +			child_set_env(&env, &envsize, "LD_LIBRARYN32_PATH",cp);
> +		if ((cp = getenv("LD_LIBRARY64_PATH")) != NULL)
> +			child_set_env(&env, &envsize, "LD_LIBRARY64_PATH",cp);
> +	}
> +#endif
> +
>  	/* Set custom environment options from RSA authentication. */
>  	if (!options.use_login) {
>  		while (custom_environment) {
> @@ -1706,6 +1875,18 @@
>  	struct passwd *pw = s->pw;
>  	int r = 0;
>  
> +#ifdef AFS_KRB5
> +/* Default place to look for aklog. */
> +#ifdef AKLOG_PATH
> +#define KPROGDIR AKLOG_PATH
> +#else
> +#define KPROGDIR "/usr/bin/aklog"
> +#endif /* AKLOG_PATH */
> +
> +	struct stat st;
> +	char *aklog_path;
> +#endif /* AFS_KRB5 */
> +
>  	/* remove hostkey from the child's memory */
>  	destroy_sensitive_data();
>  
> @@ -1818,6 +1999,41 @@
>  	}
>  #endif
>  
> +#ifdef AFS_KRB5
> +
> +	/* User has authenticated, and if a ticket was going to be
> +	 * passed we would have it.  KRB5CCNAME should already be set.
> +	 * Now try to get an AFS token using aklog.
> +	 */
> +	if (k_hasafs()) {  /* Do we have AFS? */
> +
> +		aklog_path = xstrdup(KPROGDIR);
> +
> +		/*
> +		 * Make sure it exists before we try to run it
> +		 */
> +		if (stat(aklog_path, &st) == 0) {
> +			debug("Running %s to get afs token.",aklog_path);
> +			system(aklog_path);
> +		} else {
> +			debug("%s does not exist.",aklog_path);
> +		}
> +
> +		xfree(aklog_path);
> +	}
> +#endif /* AFS_KRB5 */
> +
> +#ifdef SESSION_HOOKS
> +        if (options.session_hooks_allow &&
> +            options.session_hooks_startup_cmd)
> +        {
> +            execute_session_hook(options.session_hooks_startup_cmd,
> +                                 s->authctxt,
> +                                 /* startup = */ 1,
> +                                 options.session_hooks_shutdown_cmd != NULL);
> +        }
> +#endif
> +
>  	/* Change current directory to the user's home directory. */
>  	if (chdir(pw->pw_dir) < 0) {
>  		/* Suppress missing homedir warning for chroot case */
> @@ -1898,7 +2114,7 @@
>  		/* Execute the shell. */
>  		argv[0] = argv0;
>  		argv[1] = NULL;
> -		execve(shell, argv, env);
> +		execve(shell, argv, environ);
>  
>  		/* Executing the shell failed. */
>  		perror(shell);
> @@ -1912,7 +2128,7 @@
>  	argv[1] = "-c";
>  	argv[2] = (char *) command;
>  	argv[3] = NULL;
> -	execve(shell, argv, env);
> +	execve(shell, argv, environ);
>  	perror(shell);
>  	exit(1);
>  }
> @@ -2364,10 +2580,16 @@
>  	 */
>  	if (s->chanid == -1)
>  		fatal("no channel for session %d", s->self);
> +	if (options.hpn_disabled)
>  	channel_set_fds(s->chanid,
>  	    fdout, fdin, fderr,
>  	    ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
>  	    1, is_tty, CHAN_SES_WINDOW_DEFAULT);
> +	else
> +		channel_set_fds(s->chanid,
> +		    fdout, fdin, fderr,
> +		    ignore_fderr ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
> +		    1, is_tty, options.hpn_buffer_size);
>  }
>  
>  /*
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/session.c.orig openssh-6.0p1/session.c.orig
> --- openssh-6.0p1.orig/session.c.orig	2012-07-12 17:00:51.482243160 +0200
> +++ openssh-6.0p1/session.c.orig	2012-07-12 16:59:38.836821752 +0200
> @@ -124,6 +124,8 @@
>  void	do_motd(void);
>  int	check_quietlogin(Session *, const char *);
>  
> +int	chroot_no_tree = 0;
> +
>  static void do_authenticated1(Authctxt *);
>  static void do_authenticated2(Authctxt *);
>  
> @@ -812,6 +814,11 @@
>  		debug("Forced command (key option) '%.900s'", command);
>  	}
>  
> +	if ((s->is_subsystem != SUBSYSTEM_INT_SFTP) && chroot_no_tree) {
> +		logit("You aren't welcomed, go away!");
> +		exit (1);
> +	}
> +
>  #ifdef SSH_AUDIT_EVENTS
>  	if (command != NULL)
>  		PRIVSEP(audit_run_command(command));
> @@ -1425,6 +1432,63 @@
>  }
>  
>  /*
> + * Test if filesystem is mounted nosuid and nodev
> + */
> +
> +static void
> +test_nosuid (char * path, dev_t fs)
> +{
> +	FILE *f;
> +	struct stat st;
> +	char buf[4096], *s, *on, *mountpoint, *opt;
> +	int nodev, nosuid;
> +
> +	if (!(f = popen ("/bin/mount", "r")))
> +		fatal ("%s: popen(\"/bin/mount\", \"r\"): %s",
> +		    __func__, strerror (errno));
> +	for (;;) {
> +		s = fgets (buf, sizeof (buf), f);
> +		if (ferror (f))
> +			fatal ("%s: read from popen: %s", __func__,
> +			    strerror (errno));
> +		if (!s) {
> +			pclose (f);
> +			fatal ("cannot found filesystem with the chroot directory");
> +		}
> +		(void) strtok (buf, " ");
> +		on = strtok (NULL, " ");
> +		if (strcmp (on, "on")) {
> +			pclose (f);
> +			fatal ("bad format of mount output");
> +		}
> +		mountpoint = strtok (NULL, " ");
> +		if (memcmp (path, mountpoint, strlen (mountpoint)))
> +			continue;
> +		if (stat(mountpoint, &st) != 0) {
> +			pclose (f);
> +			fatal("%s: stat(\"%s\"): %s", __func__,
> +			    mountpoint, strerror(errno));
> +		}
> +		if (fs != st.st_dev)
> +			continue;
> +		nodev = nosuid = 0;
> +		for (opt = strtok (NULL, "("); opt; opt = strtok (NULL, " ,)")) {
> +			if (!strcmp (opt, "nodev"))
> +				nodev = 1;
> +			else if (!strcmp (opt, "nosuid"))
> +				nosuid = 1;
> +			else if (!strcmp (opt, "noexec"))
> +				nosuid = 1;
> +			if (nodev && nosuid) {
> +				pclose (f);
> +				return;
> +			}
> +		}
> +		fatal ("chroot into directory without nodev or nosuid");
> +	}
> +}
> +
> +/*
>   * Chroot into a directory after checking it for safety: all path components
>   * must be root-owned directories with strict permissions.
>   */
> @@ -1434,6 +1498,7 @@
>  	const char *cp;
>  	char component[MAXPATHLEN];
>  	struct stat st;
> +	int last;
>  
>  	if (*path != '/')
>  		fatal("chroot path does not begin at root");
> @@ -1445,7 +1510,7 @@
>  	 * root-owned directory with strict permissions.
>  	 */
>  	for (cp = path; cp != NULL;) {
> -		if ((cp = strchr(cp, '/')) == NULL)
> +		if (((last = ((cp = strchr(cp, '/')) == NULL))))
>  			strlcpy(component, path, sizeof(component));
>  		else {
>  			cp++;
> @@ -1458,14 +1523,20 @@
>  		if (stat(component, &st) != 0)
>  			fatal("%s: stat(\"%s\"): %s", __func__,
>  			    component, strerror(errno));
> -		if (st.st_uid != 0 || (st.st_mode & 022) != 0)
> +		if ((st.st_uid != 0 || (st.st_mode & 022) != 0) && !(last && st.st_uid == uid))
>  			fatal("bad ownership or modes for chroot "
>  			    "directory %s\"%s\"", 
>  			    cp == NULL ? "" : "component ", component);
>  		if (!S_ISDIR(st.st_mode))
>  			fatal("chroot path %s\"%s\" is not a directory",
>  			    cp == NULL ? "" : "component ", component);
> +	}
> +	setenv ("TZ", "/etc/localtime", 0);
> +	tzset ();
>  
> +	if (st.st_uid) {
> +		test_nosuid (path, st.st_dev);
> +		++chroot_no_tree;
>  	}
>  
>  	if (chdir(path) == -1)
> @@ -1476,6 +1547,10 @@
>  	if (chdir("/") == -1)
>  		fatal("%s: chdir(/) after chroot: %s",
>  		    __func__, strerror(errno));
> +
> +	if (access ("/etc/localtime", R_OK) < 0)
> +		++chroot_no_tree;
> +
>  	verbose("Changed root directory to \"%s\"", path);
>  }
>  
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/sftp.1 openssh-6.0p1/sftp.1
> --- openssh-6.0p1.orig/sftp.1	2012-07-12 17:00:49.846211149 +0200
> +++ openssh-6.0p1/sftp.1	2012-07-12 17:01:14.562694768 +0200
> @@ -247,7 +247,8 @@
>  Specify how many requests may be outstanding at any one time.
>  Increasing this may slightly improve file transfer speed
>  but will increase memory usage.
> -The default is 64 outstanding requests.
> +The default is 256 outstanding requests providing for 8MB 
> +of outstanding data with a 32KB buffer.
>  .It Fl r
>  Recursively copy entire directories when uploading and downloading.
>  Note that
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/sftp.c openssh-6.0p1/sftp.c
> --- openssh-6.0p1.orig/sftp.c	2012-07-12 17:00:49.850211227 +0200
> +++ openssh-6.0p1/sftp.c	2012-07-12 17:01:14.570694924 +0200
> @@ -69,7 +69,7 @@
>  #include "sftp-client.h"
>  
>  #define DEFAULT_COPY_BUFLEN	32768	/* Size of buffer for up/download */
> -#define DEFAULT_NUM_REQUESTS	64	/* # concurrent outstanding requests */
> +#define DEFAULT_NUM_REQUESTS	256	/* # concurrent outstanding requests */
>  
>  /* File to read commands from */
>  FILE* infile;
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/ssh.1 openssh-6.0p1/ssh.1
> --- openssh-6.0p1.orig/ssh.1	2012-07-12 17:00:49.958213340 +0200
> +++ openssh-6.0p1/ssh.1	2012-07-12 17:01:14.598695472 +0200
> @@ -1195,8 +1195,38 @@
>  explicitly, as that
>  will render the X11 connection insecure (and will require the user to
>  manually copy any required authorization cookies).
> +.It Ev GSSAPI_MECH_CONF
> +Applies to mechglue used to support both GSI and Kerberos GSSAPI mechanisms.
> +Used to specify the location of the mech.conf file that lists the mechanism-
> +specific GSSAPI libraries (both Kerberos and GSI versions). If
> +.Ev GSSAPI_MECH_CONF
> +is not set then /etc/mech.conf is used. This applies to both the clients and
> +the server. The NCSA GSSAPI mechglue distribution includes a sample mech.conf
> +file. You will need to edit the library paths in that file and install it in
> +an appropriate location on your system. If the mech.conf file is not found,
> +the GSSAPI mechglue library will not load any GSSAPI mechanisms and GSI-OpenSSH
> +will simply skip GSSAPI authentication.
>  .It Ev HOME
>  Set to the path of the user's home directory.
> +.It LD_LIBRARY_PATH
> +The ssh client is typically linked dynamically with Globus
> +security libraries, which must be present in the dynamic linker's
> +search path.  This typically requires
> +.Cm $GLOBUS_LOCATION/lib
> +to be included in the list in the
> +.Ev LD_LIBRARY_PATH
> +environment variable, which is set by the
> +.Cm $GLOBUS_LOCATION/libexec/globus-script-initializer
> +script, which should be called from any
> +.Cm ssh
> +invocation script.
> +Alternatively, to set
> +.Ev LD_LIBRARY_PATH
> +appropriately for the Globus libraries in an interactive shell, source
> +.Cm $GLOBUS_LOCATION/etc/globus-user-env.sh
> +(for sh shells) or
> +.Cm $GLOBUS_LOCATION/etc/globus-user.env.csh
> +(for csh shells).
>  .It Ev LOGNAME
>  Synonym for
>  .Ev USER ;
> @@ -1255,6 +1285,18 @@
>  on to new connections).
>  .It Ev USER
>  Set to the name of the user logging in.
> +.It Ev X509_CERT_DIR
> +Used for GSI authentication. Specifies a non-standard location for the
> +CA certificates directory.
> +.It Ev X509_USER_CERT
> +Used for GSI authentication. Specifies a non-standard location for the
> +certificate to be used for authentication to the server.
> +.It Ev X509_USER_KEY
> +Used for GSI authentication. Specifies a non-standard location for the
> +private key to be used for authentication to the server.
> +.It Ev X509_USER_PROXY
> +Used for GSI authentication. Specifies a non-standard location for the
> +proxy credential to be used for authentication to the server.
>  .El
>  .Pp
>  Additionally,
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/ssh.c openssh-6.0p1/ssh.c
> --- openssh-6.0p1.orig/ssh.c	2012-07-12 17:00:51.458242691 +0200
> +++ openssh-6.0p1/ssh.c	2012-07-12 17:01:14.622695942 +0200
> @@ -580,6 +580,10 @@
>  			break;
>  		case 'T':
>  			options.request_tty = REQUEST_TTY_NO;
> +			/* ensure that the user doesn't try to backdoor a */
> +			/* null cipher switch on an interactive session */
> +			/* so explicitly disable it no matter what */
> +			options.none_switch=0;
>  			break;
>  		case 'o':
>  			dummy = 1;
> @@ -708,6 +712,32 @@
>  			fatal("Can't open user config file %.100s: "
>  			    "%.100s", config, strerror(errno));
>  	} else {
> +	    /*
> +	     * Since the config file parsing code aborts if it sees
> +	     * options it doesn't recognize, allow users to put
> +	     * options specific to compile-time add-ons in alternate
> +	     * config files so their primary config file will
> +	     * interoperate SSH versions that don't support those
> +	     * options.
> +	     */
> +#ifdef GSSAPI
> +		r = snprintf(buf, sizeof buf, "%s/%s.gssapi", pw->pw_dir,
> +		    _PATH_SSH_USER_CONFFILE);
> +		if (r > 0 && (size_t)r < sizeof(buf))
> +			(void)read_config_file(buf, host, &options, 1);
> +#ifdef GSI
> +		r = snprintf(buf, sizeof buf, "%s/%s.gsi", pw->pw_dir,
> +		    _PATH_SSH_USER_CONFFILE);
> +		if (r > 0 && (size_t)r < sizeof(buf))
> +			(void)read_config_file(buf, host, &options, 1);
> +#endif
> +#if defined(KRB5)
> +		r = snprintf(buf, sizeof buf, "%s/%s.krb", pw->pw_dir,
> +		    _PATH_SSH_USER_CONFFILE);
> +		if (r > 0 && (size_t)r < sizeof(buf))
> +			(void)read_config_file(buf, host, &options, 1);
> +#endif
> +#endif
>  		r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir,
>  		    _PATH_SSH_USER_CONFFILE);
>  		if (r > 0 && (size_t)r < sizeof(buf))
> @@ -728,8 +758,11 @@
>  
>  	seed_rng();
>  
> -	if (options.user == NULL)
> +	if (options.user == NULL) {
>  		options.user = xstrdup(pw->pw_name);
> +		options.implicit = 1;
> +	}
> +        else options.implicit = 0;
>  
>  	/* Get default port if port has not been set. */
>  	if (options.port == 0) {
> @@ -1374,6 +1407,9 @@
>  {
>  	Channel *c;
>  	int window, packetmax, in, out, err;
> +	int sock;
> +	int socksize;
> +	int socksizelen = sizeof(int);
>  
>  	if (stdin_null_flag) {
>  		in = open(_PATH_DEVNULL, O_RDONLY);
> @@ -1394,9 +1430,75 @@
>  	if (!isatty(err))
>  		set_nonblock(err);
>  
> -	window = CHAN_SES_WINDOW_DEFAULT;
> +	/* we need to check to see if what they want to do about buffer */
> +	/* sizes here. In a hpn to nonhpn connection we want to limit */
> +	/* the window size to something reasonable in case the far side */
> +	/* has the large window bug. In hpn to hpn connection we want to */
> +	/* use the max window size but allow the user to override it */
> +	/* lastly if they disabled hpn then use the ssh std window size */
> +
> +	/* so why don't we just do a getsockopt() here and set the */
> +	/* ssh window to that? In the case of a autotuning receive */
> +	/* window the window would get stuck at the initial buffer */
> +	/* size generally less than 96k. Therefore we need to set the */
> +	/* maximum ssh window size to the maximum hpn buffer size */
> +	/* unless the user has specifically set the tcprcvbufpoll */
> +	/* to no. In which case we *can* just set the window to the */
> +	/* minimum of the hpn buffer size and tcp receive buffer size */
> +	
> +	if (tty_flag)
> +		options.hpn_buffer_size = CHAN_SES_WINDOW_DEFAULT;
> +	else
> +		options.hpn_buffer_size = 2*1024*1024;
> +
> +	if (datafellows & SSH_BUG_LARGEWINDOW) 
> +	{
> +		debug("HPN to Non-HPN Connection");
> +	} 
> +	else 
> +	{
> +		if (options.tcp_rcv_buf_poll <= 0) 
> +		{
> +			sock = socket(AF_INET, SOCK_STREAM, 0);
> +			getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
> +				   &socksize, &socksizelen);
> +			close(sock);
> +			debug("socksize %d", socksize);
> +			options.hpn_buffer_size = socksize;
> +			debug ("HPNBufferSize set to TCP RWIN: %d", options.hpn_buffer_size);
> +		} 
> +		else
> +		{
> +			if (options.tcp_rcv_buf > 0) 
> +			{
> +				/*create a socket but don't connect it */
> +				/* we use that the get the rcv socket size */
> +				sock = socket(AF_INET, SOCK_STREAM, 0);
> +				/* if they are using the tcp_rcv_buf option */
> +				/* attempt to set the buffer size to that */
> +				if (options.tcp_rcv_buf) 
> +					setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (void *)&options.tcp_rcv_buf, 
> +						   sizeof(options.tcp_rcv_buf));
> +				getsockopt(sock, SOL_SOCKET, SO_RCVBUF, 
> +					   &socksize, &socksizelen);
> +				close(sock);
> +				debug("socksize %d", socksize);
> +				options.hpn_buffer_size = socksize;
> +				debug ("HPNBufferSize set to user TCPRcvBuf: %d", options.hpn_buffer_size);
> +			}
> + 		}
> +		
> +	}
> +
> +	debug("Final hpn_buffer_size = %d", options.hpn_buffer_size);
> +
> +	window = options.hpn_buffer_size;
> +
> +	channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
> +
>  	packetmax = CHAN_SES_PACKET_DEFAULT;
>  	if (tty_flag) {
> +		window = 4*CHAN_SES_PACKET_DEFAULT;
>  		window >>= 1;
>  		packetmax >>= 1;
>  	}
> @@ -1404,7 +1506,10 @@
>  	    "session", SSH_CHANNEL_OPENING, in, out, err,
>  	    window, packetmax, CHAN_EXTENDED_WRITE,
>  	    "client-session", /*nonblock*/0);
> -
> +	if ((options.tcp_rcv_buf_poll > 0) && (!options.hpn_disabled)) {
> +		c->dynamic_window = 1;
> +		debug ("Enabled Dynamic Window Scaling\n");
> +	}
>  	debug3("ssh_session2_open: channel_new: %d", c->self);
>  
>  	channel_send_open(c->self);
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/ssh_config openssh-6.0p1/ssh_config
> --- openssh-6.0p1.orig/ssh_config	2012-07-12 17:00:49.978213732 +0200
> +++ openssh-6.0p1/ssh_config	2012-07-12 17:01:14.638696255 +0200
> @@ -35,8 +35,10 @@
>  #   RSAAuthentication yes
>  #   PasswordAuthentication yes
>  #   HostbasedAuthentication no
> -#   GSSAPIAuthentication no
> -#   GSSAPIDelegateCredentials no
> +#   GSSAPIAuthentication yes
> +#   GSSAPIDelegateCredentials yes
> +#   GSSAPIKeyExchange yes
> +#   GSSAPITrustDNS yes
>  #   BatchMode no
>  #   CheckHostIP yes
>  #   AddressFamily any
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/ssh_config.5 openssh-6.0p1/ssh_config.5
> --- openssh-6.0p1.orig/ssh_config.5	2012-07-12 17:00:49.982213810 +0200
> +++ openssh-6.0p1/ssh_config.5	2012-07-12 17:01:14.646696411 +0200
> @@ -55,6 +55,12 @@
>  user's configuration file
>  .Pq Pa ~/.ssh/config
>  .It
> +GSSAPI configuration file
> +.Pq Pa $HOME/.ssh/config.gssapi
> +.It
> +Kerberos configuration file
> +.Pq Pa $HOME/.ssh/config.krb
> +.It
>  system-wide configuration file
>  .Pq Pa /etc/ssh/ssh_config
>  .El
> @@ -525,13 +531,45 @@
>  .It Cm GSSAPIAuthentication
>  Specifies whether user authentication based on GSSAPI is allowed.
>  The default is
> -.Dq no .
> +.Dq yes .
> +Note that this option applies to protocol version 2 only.
> +.It Cm GSSAPIKeyExchange
> +Specifies whether key exchange based on GSSAPI may be used. When using
> +GSSAPI key exchange the server need not have a host key.
> +The default is
> +.Dq yes .
>  Note that this option applies to protocol version 2 only.
> +.It Cm GSSAPIClientIdentity
> +If set, specifies the GSSAPI client identity that ssh should use when 
> +connecting to the server. The default is unset, which means that the default 
> +identity will be used.
> +.It Cm GSSAPIServerIdentity
> +If set, specifies the GSSAPI server identity that ssh should expect when 
> +connecting to the server. The default is unset, which means that the
> +expected GSSAPI server identity will be determined from the target
> +hostname.
>  .It Cm GSSAPIDelegateCredentials
>  Forward (delegate) credentials to the server.
>  The default is
> -.Dq no .
> -Note that this option applies to protocol version 2 only.
> +.Dq yes .
> +Note that this option applies to protocol version 2 connections using GSSAPI.
> +.It Cm GSSAPIRenewalForcesRekey
> +If set to 
> +.Dq yes
> +then renewal of the client's GSSAPI credentials will force the rekeying of the
> +ssh connection. With a compatible server, this can delegate the renewed 
> +credentials to a session on the server.
> +The default is
> +.Dq yes .
> +.It Cm GSSAPITrustDns
> +Set to 
> +.Dq yes to indicate that the DNS is trusted to securely canonicalize
> +the name of the host being connected to. If 
> +.Dq no, the hostname entered on the
> +command line will be passed untouched to the GSSAPI library.
> +The default is
> +.Dq yes .
> +This option only applies to protocol version 2 connections using GSSAPI.
>  .It Cm HashKnownHosts
>  Indicates that
>  .Xr ssh 1
> @@ -850,7 +888,7 @@
>  .Cm password ) .
>  The default is:
>  .Bd -literal -offset indent
> -gssapi-with-mic,hostbased,publickey,
> +gssapi-keyex,gssapi-with-mic,hostbased,publickey,
>  keyboard-interactive,password
>  .Ed
>  .It Cm Protocol
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/ssh_config.orig openssh-6.0p1/ssh_config.orig
> --- openssh-6.0p1.orig/ssh_config.orig	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/ssh_config.orig	2012-07-12 16:59:35.428755071 +0200
> @@ -0,0 +1,79 @@
> +#	$OpenBSD: ssh_config,v 1.26 2010/01/11 01:39:46 dtucker Exp $
> +
> +# This is the ssh client system-wide configuration file.  See
> +# ssh_config(5) for more information.  This file provides defaults for
> +# users, and the values can be changed in per-user configuration files
> +# or on the command line.
> +
> +# Configuration data is parsed as follows:
> +#  1. command line options
> +#  2. user-specific file
> +#  3. system-wide file
> +# Any configuration value is only changed the first time it is set.
> +# Thus, host-specific definitions should be at the beginning of the
> +# configuration file, and defaults at the end.
> +
> +# Site-wide defaults for some commonly used options.  For a comprehensive
> +# list of available options, their meanings and defaults, please see the
> +# ssh_config(5) man page.
> +
> +Host *
> +#   ForwardAgent no
> +#   ForwardX11 no
> +
> +# If you do not trust your remote host (or its administrator), you
> +# should not forward X11 connections to your local X11-display for
> +# security reasons: Someone stealing the authentification data on the
> +# remote side (the "spoofed" X-server by the remote sshd) can read your
> +# keystrokes as you type, just like any other X11 client could do.
> +# Set this to "no" here for global effect or in your own ~/.ssh/config
> +# file if you want to have the remote X11 authentification data to
> +# expire after two minutes after remote login.
> +ForwardX11Trusted yes
> +
> +#   RhostsRSAAuthentication no
> +#   RSAAuthentication yes
> +#   PasswordAuthentication yes
> +#   HostbasedAuthentication no
> +#   GSSAPIAuthentication no
> +#   GSSAPIDelegateCredentials no
> +#   BatchMode no
> +#   CheckHostIP yes
> +#   AddressFamily any
> +#   ConnectTimeout 0
> +#   StrictHostKeyChecking ask
> +#   IdentityFile ~/.ssh/identity
> +#   IdentityFile ~/.ssh/id_rsa
> +#   IdentityFile ~/.ssh/id_dsa
> +#   Port 22
> +    Protocol 2
> +#   Cipher 3des
> +#   Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc
> +#   MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160
> +#   EscapeChar ~
> +#   Tunnel no
> +#   TunnelDevice any:any
> +#   PermitLocalCommand no
> +#   GSSAPIAuthentication no
> +#   GSSAPIDelegateCredentials no
> +
> +# Set this to 'yes' to enable support for the deprecated 'gssapi' authentication
> +# mechanism to OpenSSH 3.8p1. The newer 'gssapi-with-mic' mechanism is included
> +# in this release. The use of 'gssapi' is deprecated due to the presence of
> +# potential man-in-the-middle attacks, which 'gssapi-with-mic' is not susceptible to.
> +#   GSSAPIEnableMITMAttack no
> +
> +# This enables sending locale enviroment variables LC_* LANG, see ssh_config(5).
> +SendEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
> +SendEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
> +SendEnv LC_IDENTIFICATION LC_ALL
> +
> +# This will print the fingerprint of the host key in "visual" form
> +# this should make it easier to also recognize bad things
> +VisualHostKey no
> +
> +# This will hash new host keys and make them so unusable for malicious
> +# people or software trying to use known_hosts to find further hops.
> +HashKnownHosts yes
> +
> +#   ProxyCommand ssh -q -W %h:%p gateway.example.com
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/sshconnect2.c openssh-6.0p1/sshconnect2.c
> --- openssh-6.0p1.orig/sshconnect2.c	2012-07-12 17:00:51.382241204 +0200
> +++ openssh-6.0p1/sshconnect2.c	2012-07-12 17:01:14.674696959 +0200
> @@ -81,6 +81,12 @@
>  extern char *client_version_string;
>  extern char *server_version_string;
>  extern Options options;
> +extern Kex *xxx_kex;
> +
> +/* tty_flag is set in ssh.c. use this in ssh_userauth2 */
> +/* if it is set then prevent the switch to the null cipher */
> +
> +extern int tty_flag;
>  
>  /*
>   * SSH2 key exchange
> @@ -160,9 +166,34 @@
>  {
>  	Kex *kex;
>  
> +#ifdef GSSAPI
> +	char *orig = NULL, *gss = NULL;
> +	char *gss_host = NULL;
> +#endif
> +
>  	xxx_host = host;
>  	xxx_hostaddr = hostaddr;
>  
> +#ifdef GSSAPI
> +	if (options.gss_keyex) {
> +		/* Add the GSSAPI mechanisms currently supported on this 
> +		 * client to the key exchange algorithm proposal */
> +		orig = myproposal[PROPOSAL_KEX_ALGS];
> +
> +		if (options.gss_trust_dns)
> +			gss_host = (char *)get_canonical_hostname(1);
> +		else
> +			gss_host = host;
> +
> +		gss = ssh_gssapi_client_mechanisms(gss_host, options.gss_client_identity);
> +		if (gss) {
> +			debug("Offering GSSAPI proposal: %s", gss);
> +			xasprintf(&myproposal[PROPOSAL_KEX_ALGS],
> +			    "%s,%s", gss, orig);
> +		}
> +	}
> +#endif
> +
>  	if (options.ciphers == (char *)-1) {
>  		logit("No valid ciphers for protocol version 2 given, using defaults.");
>  		options.ciphers = NULL;
> @@ -197,6 +228,17 @@
>  	if (options.kex_algorithms != NULL)
>  		myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms;
>  
> +#ifdef GSSAPI
> +	/* If we've got GSSAPI algorithms, then we also support the
> +	 * 'null' hostkey, as a last resort */
> +	if (options.gss_keyex && gss) {
> +		orig = myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS];
> +		xasprintf(&myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], 
> +		    "%s,null", orig);
> +		xfree(gss);
> +	}
> +#endif
> +
>  	if (options.rekey_limit)
>  		packet_set_rekey_limit((u_int32_t)options.rekey_limit);
>  
> @@ -207,10 +249,30 @@
>  	kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
>  	kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
>  	kex->kex[KEX_ECDH_SHA2] = kexecdh_client;
> +#ifdef GSSAPI
> +	if (options.gss_keyex) {
> +		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_client;
> +		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_client;
> +		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_client;
> +	}
> +#endif
>  	kex->client_version_string=client_version_string;
>  	kex->server_version_string=server_version_string;
>  	kex->verify_host_key=&verify_host_key_callback;
>  
> +#ifdef GSSAPI
> +	if (options.gss_keyex) {
> +		kex->gss_deleg_creds = options.gss_deleg_creds;
> +		kex->gss_trust_dns = options.gss_trust_dns;
> +		kex->gss_client = options.gss_client_identity;
> +		if (options.gss_server_identity) {
> +			kex->gss_host = options.gss_server_identity;
> +		} else {
> +			kex->gss_host = gss_host;
> +        }
> +	}
> +#endif
> +
>  	xxx_kex = kex;
>  
>  	dispatch_run(DISPATCH_BLOCK, &kex->done, kex);
> @@ -305,6 +367,7 @@
>  void	input_gssapi_hash(int type, u_int32_t, void *);
>  void	input_gssapi_error(int, u_int32_t, void *);
>  void	input_gssapi_errtok(int, u_int32_t, void *);
> +int	userauth_gsskeyex(Authctxt *authctxt);
>  #endif
>  
>  void	userauth(Authctxt *, char *);
> @@ -320,6 +383,11 @@
>  
>  Authmethod authmethods[] = {
>  #ifdef GSSAPI
> +	{"gssapi-keyex",
> +		userauth_gsskeyex,
> +		NULL,
> +		&options.gss_authentication,
> +		NULL},
>  	{"gssapi-with-mic",
>  		userauth_gssapi,
>  		NULL,
> @@ -424,6 +492,28 @@
>  	pubkey_cleanup(&authctxt);
>  	dispatch_range(SSH2_MSG_USERAUTH_MIN, SSH2_MSG_USERAUTH_MAX, NULL);
>  
> +	/* if the user wants to use the none cipher do it */
> +	/* post authentication and only if the right conditions are met */
> +	/* both of the NONE commands must be true and there must be no */
> +	/* tty allocated */
> +	if ((options.none_switch == 1) && (options.none_enabled == 1)) 
> +	{
> +		if (!tty_flag) /* no null on tty sessions */
> +		{
> +			debug("Requesting none rekeying...");
> +			myproposal[PROPOSAL_ENC_ALGS_STOC] = "none";
> +			myproposal[PROPOSAL_ENC_ALGS_CTOS] = "none";
> +			kex_prop2buf(&xxx_kex->my,myproposal);
> +			packet_request_rekeying();
> +			fprintf(stderr, "WARNING: ENABLED NONE CIPHER\n");
> +		}
> +		else
> +		{
> +			/* requested NONE cipher when in a tty */
> +			debug("Cannot switch to NONE cipher with tty allocated");
> +			fprintf(stderr, "NONE cipher switch disabled when a TTY is allocated\n");
> +		}
> +	}
>  	debug("Authentication succeeded (%s).", authctxt.method->name);
>  }
>  
> @@ -630,19 +720,36 @@
>  	static u_int mech = 0;
>  	OM_uint32 min;
>  	int ok = 0;
> +	char *gss_host = NULL;
> +
> +	if (!options.gss_authentication) {
> +		verbose("GSSAPI authentication disabled.");
> +		return 0;
> +	}
> +
> +	if (options.gss_server_identity)
> +		gss_host = (char *)options.gss_server_identity;
> +	else if (options.gss_trust_dns)
> +		gss_host = (char *)get_canonical_hostname(1);
> +	else
> +		gss_host = (char *)authctxt->host;
>  
>  	/* Try one GSSAPI method at a time, rather than sending them all at
>  	 * once. */
>  
>  	if (gss_supported == NULL)
> -		gss_indicate_mechs(&min, &gss_supported);
> +		if (GSS_ERROR(gss_indicate_mechs(&min, &gss_supported))) {
> +			gss_supported = NULL;
> +			return 0;
> +		}
>  
>  	/* Check to see if the mechanism is usable before we offer it */
>  	while (mech < gss_supported->count && !ok) {
>  		/* My DER encoding requires length<128 */
>  		if (gss_supported->elements[mech].length < 128 &&
>  		    ssh_gssapi_check_mechanism(&gssctxt, 
> -		    &gss_supported->elements[mech], authctxt->host)) {
> +		    &gss_supported->elements[mech], gss_host, 
> +                    options.gss_client_identity)) {
>  			ok = 1; /* Mechanism works */
>  		} else {
>  			mech++;
> @@ -741,8 +848,8 @@
>  {
>  	Authctxt *authctxt = ctxt;
>  	Gssctxt *gssctxt;
> -	int oidlen;
> -	char *oidv;
> +	u_int oidlen;
> +	u_char *oidv;
>  
>  	if (authctxt == NULL)
>  		fatal("input_gssapi_response: no authentication context");
> @@ -852,6 +959,73 @@
>  	xfree(msg);
>  	xfree(lang);
>  }
> +
> +#ifdef GSI
> +extern
> +const gss_OID_desc * const              gss_mech_globus_gssapi_openssl;
> +#define is_gsi_oid(oid) \
> +  (oid->length == gss_mech_globus_gssapi_openssl->length && \
> +   (memcmp(oid->elements, gss_mech_globus_gssapi_openssl->elements, \
> +	   oid->length) == 0))
> +#endif
> +
> +int
> +userauth_gsskeyex(Authctxt *authctxt)
> +{
> +	Buffer b;
> +	gss_buffer_desc gssbuf;
> +	gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
> +	OM_uint32 ms;
> +
> +	static int attempt = 0;
> +	if (attempt++ >= 1)
> +		return (0);
> +
> +	if (gss_kex_context == NULL) {
> +		debug("No valid Key exchange context"); 
> +		return (0);
> +	}
> +
> +#ifdef GSI
> +    if (options.implicit && is_gsi_oid(gss_kex_context->oid)) {
> +        ssh_gssapi_buildmic(&b, "", authctxt->service, "gssapi-keyex");
> +	} else {
> +#endif
> +        ssh_gssapi_buildmic(&b, authctxt->server_user, authctxt->service,
> +                            "gssapi-keyex");
> +#ifdef GSI
> +	}
> +#endif
> +
> +	gssbuf.value = buffer_ptr(&b);
> +	gssbuf.length = buffer_len(&b);
> +
> +	if (GSS_ERROR(ssh_gssapi_sign(gss_kex_context, &gssbuf, &mic))) {
> +		buffer_free(&b);
> +		return (0);
> +	}
> +
> +	packet_start(SSH2_MSG_USERAUTH_REQUEST);
> +#ifdef GSI
> +    if (options.implicit && is_gsi_oid(gss_kex_context->oid)) {
> +        packet_put_cstring("");
> +	} else {
> +#endif
> +	packet_put_cstring(authctxt->server_user);
> +#ifdef GSI
> +	}
> +#endif
> +	packet_put_cstring(authctxt->service);
> +	packet_put_cstring(authctxt->method->name);
> +	packet_put_string(mic.value, mic.length);
> +	packet_send();
> +
> +	buffer_free(&b);
> +	gss_release_buffer(&ms, &mic);
> +
> +	return (1);
> +}
> +
>  #endif /* GSSAPI */
>  
>  int
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/sshconnect2.c.orig openssh-6.0p1/sshconnect2.c.orig
> --- openssh-6.0p1.orig/sshconnect2.c.orig	2012-07-12 17:00:51.374241047 +0200
> +++ openssh-6.0p1/sshconnect2.c.orig	2012-07-12 16:59:38.592816979 +0200
> @@ -325,6 +325,10 @@
>  		NULL,
>  		&options.gss_authentication,
>  		NULL},
> +	{"gssapi",
> +		userauth_gssapi,
> +		&options.gss_enable_mitm,
> +		NULL},
>  #endif
>  	{"hostbased",
>  		userauth_hostbased,
> @@ -702,7 +706,9 @@
>  
>  	if (status == GSS_S_COMPLETE) {
>  		/* send either complete or MIC, depending on mechanism */
> -		if (!(flags & GSS_C_INTEG_FLAG)) {
> +
> +		if (strcmp(authctxt->method->name,"gssapi")==0 ||
> +		    (!(flags & GSS_C_INTEG_FLAG))) {
>  			packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
>  			packet_send();
>  		} else {
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/sshconnect2.c.rej openssh-6.0p1/sshconnect2.c.rej
> --- openssh-6.0p1.orig/sshconnect2.c.rej	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/sshconnect2.c.rej	2012-07-12 17:01:14.678697037 +0200
> @@ -0,0 +1,18 @@
> +***************
> +*** 706,712 ****
> +  
> +  	if (status == GSS_S_COMPLETE) {
> +  		/* send either complete or MIC, depending on mechanism */
> +- 		if (!(flags & GSS_C_INTEG_FLAG)) {
> +  			packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
> +  			packet_send();
> +  		} else {
> +--- 813,820 ----
> +  
> +  	if (status == GSS_S_COMPLETE) {
> +  		/* send either complete or MIC, depending on mechanism */
> ++ 		if (strcmp(authctxt->method->name,"gssapi")==0 ||
> ++ 		    (!(flags & GSS_C_INTEG_FLAG))) {
> +  			packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
> +  			packet_send();
> +  		} else {
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/sshconnect.c openssh-6.0p1/sshconnect.c
> --- openssh-6.0p1.orig/sshconnect.c	2012-07-12 17:00:49.998214123 +0200
> +++ openssh-6.0p1/sshconnect.c	2012-07-12 17:01:14.654696568 +0200
> @@ -182,6 +182,31 @@
>  }
>  
>  /*
> + * Set TCP receive buffer if requested.
> + * Note: tuning needs to happen after the socket is
> + * created but before the connection happens
> + * so winscale is negotiated properly -cjr
> + */
> +static void
> +ssh_set_socket_recvbuf(int sock)
> +{
> +	void *buf = (void *)&options.tcp_rcv_buf;
> +	int sz = sizeof(options.tcp_rcv_buf);
> +	int socksize;
> +	int socksizelen = sizeof(int);
> +
> +	debug("setsockopt Attempting to set SO_RCVBUF to %d", options.tcp_rcv_buf);
> +	if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, buf, sz) >= 0) {
> +	  getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &socksize, &socksizelen);
> +	  debug("setsockopt SO_RCVBUF: %.100s %d", strerror(errno), socksize);
> +	}
> +	else
> +		error("Couldn't set socket receive buffer to %d: %.100s",
> +		    options.tcp_rcv_buf, strerror(errno));
> +}
> +
> +
> +/*
>   * Creates a (possibly privileged) socket for use as the ssh connection.
>   */
>  static int
> @@ -204,6 +229,8 @@
>  			    strerror(errno));
>  		else
>  			debug("Allocated local port %d.", p);
> +		if (options.tcp_rcv_buf > 0)
> +			ssh_set_socket_recvbuf(sock);
>  		return sock;
>  	}
>  	sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
> @@ -213,6 +240,9 @@
>  	}
>  	fcntl(sock, F_SETFD, FD_CLOEXEC);
>  
> +	if (options.tcp_rcv_buf > 0)
> +		ssh_set_socket_recvbuf(sock);
> +
>  	/* Bind the socket to an alternative local IP address */
>  	if (options.bind_address == NULL)
>  		return sock;
> @@ -556,7 +586,7 @@
>  	snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s",
>  	    compat20 ? PROTOCOL_MAJOR_2 : PROTOCOL_MAJOR_1,
>  	    compat20 ? PROTOCOL_MINOR_2 : minor1,
> -	    SSH_VERSION, compat20 ? "\r\n" : "\n");
> +	    SSH_RELEASE, compat20 ? "\r\n" : "\n");
>  	if (roaming_atomicio(vwrite, connection_out, buf, strlen(buf))
>  	    != strlen(buf))
>  		fatal("write: %.100s", strerror(errno));
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/ssh.c.orig openssh-6.0p1/ssh.c.orig
> --- openssh-6.0p1.orig/ssh.c.orig	2012-07-12 17:00:51.450242534 +0200
> +++ openssh-6.0p1/ssh.c.orig	2012-07-12 16:59:38.740819876 +0200
> @@ -75,6 +75,7 @@
>  #include <openssl/err.h>
>  #include "openbsd-compat/openssl-compat.h"
>  #include "openbsd-compat/sys-queue.h"
> +#include <openssl/engine.h>
>  
>  #include "xmalloc.h"
>  #include "ssh.h"
> @@ -635,6 +636,10 @@
>  	OpenSSL_add_all_algorithms();
>  	ERR_load_crypto_strings();
>  
> +	/* Init available hardware crypto engines. */
> +	ENGINE_load_builtin_engines();
> +	ENGINE_register_all_complete();
> +
>  	/* Initialize the command to execute on remote host. */
>  	buffer_init(&command);
>  
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/sshd.8 openssh-6.0p1/sshd.8
> --- openssh-6.0p1.orig/sshd.8	2012-07-12 17:00:51.390241360 +0200
> +++ openssh-6.0p1/sshd.8	2012-07-12 17:01:14.686697194 +0200
> @@ -759,6 +759,73 @@
>  # A CA key, accepted for any host in *.mydomain.com or *.mydomain.org
>  @cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W...
>  .Ed
> +.Sh ENVIRONMENT
> +.Nm
> +will normally set the following environment variables:
> +.Bl -tag -width "SSH_ORIGINAL_COMMAND"
> +.It Ev GLOBUS_USAGE_OPTOUT
> +Setting this environment variable to "1" will disable the reporting
> +of usage metrics. Usage metrics can also be disabled using the
> +.Cm DisableUsageStats
> +setting in
> +.Xr sshd_config 5 .
> +.It Ev GLOBUS_USAGE_TARGETS
> +If
> +.Cm UsageStatsTargets
> +is not specified in
> +.Xr sshd_config 5 ,
> +a comma-separated list of targets (without any tags specified) if
> +specified in the environment variable
> +.Ev GLOBUS_USAGE_TARGETS
> +will be used.
> +.It Ev GRIDMAP
> +Applies to GSI authentication/authorization. Specifies the location of the
> +gridmapfile. If not specified, the gridmap file is assumed to be available at
> +/etc/grid-security/grid-mapfile for services running as root and at
> +HOME/.gridmap for services running as non-root where HOME is the home directory
> +of the effective user from the password file entry.
> +.It Ev GSSAPI_MECH_CONF
> +Applies to mechglue used to support both GSI and Kerberos GSSAPI mechanisms.
> +Used to specify the location of the mech.conf file that lists the mechanism-
> +specific GSSAPI libraries (both Kerberos and GSI versions). If
> +.Ev GSSAPI_MECH_CONF
> +is not set then /etc/mech.conf is used. This applies to both the clients and
> +the server. The NCSA GSSAPI mechglue distribution includes a sample mech.conf
> +file. You will need to edit the library paths in that file and install it in
> +an appropriate location on your system. If the mech.conf file is not found,
> +the GSSAPI mechglue library will not load any GSSAPI mechanisms and GSI-OpenSSH
> +will simply skip GSSAPI authentication.
> +.It LD_LIBRARY_PATH
> +The sshd server is typically linked dynamically with Globus
> +security libraries, which must be present in the dynamic linker's
> +search path.  This typically requires
> +.Cm $GLOBUS_LOCATION/lib
> +to be included in the list in the
> +.Ev LD_LIBRARY_PATH
> +environment variable, which is set by the
> +.Cm $GLOBUS_LOCATION/libexec/globus-script-initializer
> +script, which should be called from any
> +.Cm sshd
> +startup script.
> +Alternatively, to set
> +.Ev LD_LIBRARY_PATH
> +appropriately for the Globus libraries in an interactive shell, source
> +.Cm $GLOBUS_LOCATION/etc/globus-user-env.sh
> +(for sh shells) or
> +.Cm $GLOBUS_LOCATION/etc/globus-user.env.csh
> +(for csh shells).
> +.It Ev X509_CERT_DIR
> +Used for GSI authentication. Specifies a non-standard location for the
> +CA certificates directory.
> +.It Ev X509_USER_CERT
> +Used for GSI authentication. Specifies a non-standard location for the
> +certificate to be used for authentication to the client.
> +.It Ev X509_USER_KEY
> +Used for GSI authentication. Specifies a non-standard location for the
> +private key to be used for authentication to the client.
> +.It Ev X509_USER_PROXY
> +Used for GSI authentication. Specifies a non-standard location for the
> +proxy credential to be used for authentication to the client.
>  .Sh FILES
>  .Bl -tag -width Ds -compact
>  .It Pa ~/.hushlogin
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/sshd.c openssh-6.0p1/sshd.c
> --- openssh-6.0p1.orig/sshd.c	2012-07-12 17:00:51.466242847 +0200
> +++ openssh-6.0p1/sshd.c	2012-07-12 17:01:14.706697585 +0200
> @@ -121,6 +121,11 @@
>  #include "roaming.h"
>  #include "ssh-sandbox.h"
>  #include "version.h"
> +#include "ssh-globus-usage.h"
> +
> +#ifdef USE_SECURITY_SESSION_API
> +#include <Security/AuthSession.h>
> +#endif
>  
>  #ifdef LIBWRAP
>  #include <tcpd.h>
> @@ -139,6 +144,9 @@
>  #define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 3)
>  #define REEXEC_MIN_FREE_FD		(STDERR_FILENO + 4)
>  
> +int myflag = 0;
> +
> +
>  extern char *__progname;
>  
>  /* Server configuration options. */
> @@ -422,7 +430,7 @@
>  		minor = PROTOCOL_MINOR_1;
>  	}
>  	snprintf(buf, sizeof buf, "SSH-%d.%d-%.100s%s", major, minor,
> -	    SSH_VERSION, newline);
> +	    SSH_RELEASE, newline);
>  	server_version_string = xstrdup(buf);
>  
>  	/* Send our protocol version identification. */
> @@ -473,6 +481,9 @@
>  	}
>  	debug("Client protocol version %d.%d; client software version %.100s",
>  	    remote_major, remote_minor, remote_version);
> +	logit("SSH: Server;Ltype: Version;Remote: %s-%d;Protocol: %d.%d;Client: %.100s",
> +	      get_remote_ipaddr(), get_remote_port(),
> +	    remote_major, remote_minor, remote_version);
>  
>  	compat_datafellows(remote_version);
>  
> @@ -1029,6 +1040,8 @@
>  	int ret, listen_sock, on = 1;
>  	struct addrinfo *ai;
>  	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
> +	int socksize;
> +	int socksizelen = sizeof(int);
>  
>  	for (ai = options.listen_addrs; ai; ai = ai->ai_next) {
>  		if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
> @@ -1069,6 +1082,11 @@
>  
>  		debug("Bind to port %s on %s.", strport, ntop);
>  
> +		getsockopt(listen_sock, SOL_SOCKET, SO_RCVBUF, 
> +				   &socksize, &socksizelen);
> +		debug("Server TCP RWIN socket size: %d", socksize);
> +		debug("HPN Buffer Size: %d", options.hpn_buffer_size);
> +
>  		/* Bind the socket to the desired port. */
>  		if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) < 0) {
>  			error("Bind to port %s on %s failed: %.200s.",
> @@ -1565,6 +1583,13 @@
>  	/* Fill in default values for those options not explicitly set. */
>  	fill_default_server_options(&options);
>  
> +#ifdef HAVE_GLOBUS_USAGE
> +	if (ssh_usage_stats_init(options.disable_usage_stats,
> +			options.usage_stats_targets) != GLOBUS_SUCCESS) {
> +		error("Error initializing Globus Usage Metrics, but continuing ...");
> +	}
> +#endif /* HAVE_GLOBUS_USAGE */
> +
>  	/* challenge-response is implemented via keyboard interactive */
>  	if (options.challenge_response_authentication)
>  		options.kbd_interactive_authentication = 1;
> @@ -1626,10 +1651,13 @@
>  		logit("Disabling protocol version 1. Could not load host key");
>  		options.protocol &= ~SSH_PROTO_1;
>  	}
> +#ifndef GSSAPI
> +	/* The GSSAPI key exchange can run without a host key */
>  	if ((options.protocol & SSH_PROTO_2) && !sensitive_data.have_ssh2_key) {
>  		logit("Disabling protocol version 2. Could not load host key");
>  		options.protocol &= ~SSH_PROTO_2;
>  	}
> +#endif
>  	if (!(options.protocol & (SSH_PROTO_1|SSH_PROTO_2))) {
>  		logit("sshd: no hostkeys available -- exiting.");
>  		exit(1);
> @@ -1921,6 +1949,9 @@
>  		cleanup_exit(255);
>  	}
>  
> +	/* set the HPN options for the child */
> +	channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
> +
>  	/*
>  	 * We use get_canonical_hostname with usedns = 0 instead of
>  	 * get_remote_ipaddr here so IP options will be checked.
> @@ -1958,6 +1989,60 @@
>  	/* Log the connection. */
>  	verbose("Connection from %.500s port %d", remote_ip, remote_port);
>  
> +#ifdef USE_SECURITY_SESSION_API
> +	/*
> +	 * Create a new security session for use by the new user login if
> +	 * the current session is the root session or we are not launched
> +	 * by inetd (eg: debugging mode or server mode).  We do not
> +	 * necessarily need to create a session if we are launched from
> +	 * inetd because Panther xinetd will create a session for us.
> +	 *
> +	 * The only case where this logic will fail is if there is an
> +	 * inetd running in a non-root session which is not creating
> +	 * new sessions for us.  Then all the users will end up in the
> +	 * same session (bad).
> +	 *
> +	 * When the client exits, the session will be destroyed for us
> +	 * automatically.
> +	 *
> +	 * We must create the session before any credentials are stored
> +	 * (including AFS pags, which happens a few lines below).
> +	 */
> +	{
> +		OSStatus err = 0;
> +		SecuritySessionId sid = 0;
> +		SessionAttributeBits sattrs = 0;
> +
> +		err = SessionGetInfo(callerSecuritySession, &sid, &sattrs);
> +		if (err)
> +			error("SessionGetInfo() failed with error %.8X",
> +			    (unsigned) err);
> +		else
> +			debug("Current Session ID is %.8X / Session Attributes are %.8X",
> +			    (unsigned) sid, (unsigned) sattrs);
> +
> +		if (inetd_flag && !(sattrs & sessionIsRoot))
> +			debug("Running in inetd mode in a non-root session... "
> +			    "assuming inetd created the session for us.");
> +		else {
> +			debug("Creating new security session...");
> +			err = SessionCreate(0, sessionHasTTY | sessionIsRemote);
> +			if (err)
> +				error("SessionCreate() failed with error %.8X",
> +				    (unsigned) err);
> +
> +			err = SessionGetInfo(callerSecuritySession, &sid, 
> +			    &sattrs);
> +			if (err)
> +				error("SessionGetInfo() failed with error %.8X",
> +				    (unsigned) err);
> +			else
> +				debug("New Session ID is %.8X / Session Attributes are %.8X",
> +				    (unsigned) sid, (unsigned) sattrs);
> +		}
> +	}
> +#endif
> +
>  	/*
>  	 * We don't want to listen forever unless the other side
>  	 * successfully authenticates itself.  So we set up an alarm which is
> @@ -1971,6 +2056,13 @@
>  		alarm(options.login_grace_time);
>  
>  	sshd_exchange_identification(sock_in, sock_out);
> +#if defined(AFS_KRB5)
> +	/* If machine has AFS, set process authentication group. */
> +	if (k_hasafs()) {
> +		k_setpag();
> +		k_unlog();
> +	}
> +#endif /* AFS || AFS_KRB5 */
>  
>  	/* In inetd mode, generate ephemeral key only for proto 1 connections */
>  	if (!compat20 && inetd_flag && sensitive_data.server_key == NULL)
> @@ -2030,7 +2122,7 @@
>  #endif
>  
>  #ifdef GSSAPI
> -	if (options.gss_authentication) {
> +	if (options.gss_authentication && options.gss_deleg_creds) {
>  		temporarily_use_uid(authctxt->pw);
>  		ssh_gssapi_storecreds();
>  		restore_uid();
> @@ -2314,9 +2406,15 @@
>  {
>  	Kex *kex;
>  
> +	myflag++;
> +	debug ("MYFLAG IS %d", myflag);
>  	if (options.ciphers != NULL) {
>  		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
>  		myproposal[PROPOSAL_ENC_ALGS_STOC] = options.ciphers;
> +	} else if (options.none_enabled == 1) {
> +		debug ("WARNING: None cipher enabled");
> +		myproposal[PROPOSAL_ENC_ALGS_CTOS] =
> +		myproposal[PROPOSAL_ENC_ALGS_STOC] = KEX_ENCRYPT_INCLUDE_NONE;
>  	}
>  	myproposal[PROPOSAL_ENC_ALGS_CTOS] =
>  	    compat_cipher_proposal(myproposal[PROPOSAL_ENC_ALGS_CTOS]);
> @@ -2339,6 +2437,48 @@
>  
>  	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types();
>  
> +#ifdef GSSAPI
> +	{
> +	char *orig;
> +	char *gss = NULL;
> +	char *newstr = NULL;
> +	orig = myproposal[PROPOSAL_KEX_ALGS];
> +
> +	/* 
> +	 * If we don't have a host key, then there's no point advertising
> +	 * the other key exchange algorithms
> +	 */
> +
> +	if (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]) == 0)
> +		orig = NULL;
> +
> +	if (options.gss_keyex)
> +		gss = ssh_gssapi_server_mechanisms();
> +	else
> +		gss = NULL;
> +
> +	if (gss && orig)
> +		xasprintf(&newstr, "%s,%s", gss, orig);
> +	else if (gss)
> +		newstr = gss;
> +	else if (orig)
> +		newstr = orig;
> +
> +	/* 
> +	 * If we've got GSSAPI mechanisms, then we've got the 'null' host
> +	 * key alg, but we can't tell people about it unless its the only
> +  	 * host key algorithm we support
> +	 */
> +	if (gss && (strlen(myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS])) == 0)
> +		myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = "null";
> +
> +	if (newstr)
> +		myproposal[PROPOSAL_KEX_ALGS] = newstr;
> +	else
> +		fatal("No supported key exchange algorithms");
> +	}
> +#endif
> +
>  	/* start key exchange */
>  	kex = kex_setup(myproposal);
>  	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
> @@ -2346,6 +2486,13 @@
>  	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
>  	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
>  	kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
> +#ifdef GSSAPI
> +	if (options.gss_keyex) {
> +		kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
> +		kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
> +		kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
> +	}
> +#endif
>  	kex->server = 1;
>  	kex->client_version_string=client_version_string;
>  	kex->server_version_string=server_version_string;
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/sshd_config openssh-6.0p1/sshd_config
> --- openssh-6.0p1.orig/sshd_config	2012-07-12 17:00:51.474243004 +0200
> +++ openssh-6.0p1/sshd_config	2012-07-12 17:01:14.726697977 +0200
> @@ -72,9 +72,17 @@
>  #KerberosTicketCleanup yes
>  #KerberosGetAFSToken no
>  
> +# Session hooks: if allowed, specify the commands to execute
> +#AllowSessionHooks no
> +#SessionHookStartupCmd /bin/true
> +#SessionHookShutdownCmd /bin/true
> +
>  # GSSAPI options
> -#GSSAPIAuthentication no
> +#GSSAPIAuthentication yes
> +#GSSAPIDelegateCredentials yes
>  #GSSAPICleanupCredentials yes
> +#GSSAPIStrictAcceptorCheck yes
> +#GSSAPIKeyExchange yes
>  
>  # Set this to 'yes' to enable support for the deprecated 'gssapi' authentication
>  # mechanism to OpenSSH 3.8p1. The newer 'gssapi-with-mic' mechanism is included
> @@ -93,6 +101,10 @@
>  # and ChallengeResponseAuthentication to 'no'.
>  UsePAM yes
>  
> +# Set to 'yes' to allow the PAM stack to change the user name during
> +# calls to authentication
> +#PermitPAMUserChange no
> +
>  #AllowAgentForwarding yes
>  #AllowTcpForwarding yes
>  #GatewayPorts no
> @@ -125,8 +137,27 @@
>  AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
>  AcceptEnv LC_IDENTIFICATION LC_ALL
>  
> +# the following are HPN related configuration options
> +# tcp receive buffer polling. disable in non autotuning kernels
> +#TcpRcvBufPoll yes
> + 
> +# allow the use of the none cipher
> +#NoneEnabled no
> +
> +# disable hpn performance boosts. 
> +#HPNDisabled no
> +
> +# buffer size for hpn to non-hpn connections
> +#HPNBufferSize 2048
> +
> +
>  # Example of overriding settings on a per-user basis
>  #Match User anoncvs
>  #	X11Forwarding no
>  #	AllowTcpForwarding no
>  #	ForceCommand cvs server
> +
> +
> +# Usage Metrics
> +#UsageStatsTargets usage-stats.cilogon.org:4810
> +#DisableUsageStats No
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/sshd_config.5 openssh-6.0p1/sshd_config.5
> --- openssh-6.0p1.orig/sshd_config.5	2012-07-12 17:00:51.538244256 +0200
> +++ openssh-6.0p1/sshd_config.5	2012-07-12 17:01:14.770698838 +0200
> @@ -391,6 +391,16 @@
>  in
>  .Xr ssh_config 5
>  for more information on patterns.
> +.It Cm DisableUsageStats
> +This keyword can be followed by one of the keywords "true", "enabled", "yes",
> +"on" or "1" to disable reporting of usage metrics. Or it can be set to "false",
> +"disabled", "no", "off", "0" to enable reporting of usage metrics, which is the
> +default. Setting the
> +.Cm GLOBUS_USAGE_OPTOUT
> +environment variable to "1" will also disable the reporting of usage metrics.
> +Disabling reporting of usage metrics will cause the
> +.Cm UsageStatsTargets
> +setting to be ignored.
>  .It Cm ForceCommand
>  Forces the execution of the command specified by
>  .Cm ForceCommand ,
> @@ -433,7 +443,17 @@
>  .It Cm GSSAPIAuthentication
>  Specifies whether user authentication based on GSSAPI is allowed.
>  The default is
> -.Dq no .
> +.Dq yes .
> +Note that this option applies to protocol version 2 only.
> +.It Cm GSSAPIDelegateCredentials
> +Specifies whether delegated credentials are stored in the user's environment.
> +The default is
> +.Dq yes .
> +.It Cm GSSAPIKeyExchange
> +Specifies whether key exchange based on GSSAPI is allowed. GSSAPI key exchange 
> +doesn't rely on ssh keys to verify host identity.
> +The default is
> +.Dq yes .
>  Note that this option applies to protocol version 2 only.
>  .It Cm GSSAPICleanupCredentials
>  Specifies whether to automatically destroy the user's credentials cache
> @@ -441,6 +461,44 @@
>  The default is
>  .Dq yes .
>  Note that this option applies to protocol version 2 only.
> +.It Cm GSSAPICredentialsPath
> +If specified, the delegated GSSAPI credential is stored in the
> +given path, overwriting any existing credentials.  
> +Paths can be specified with syntax similar to the AuthorizedKeysFile 
> +option (i.e., accepting %h and %u tokens).  
> +When using this option,
> +setting 'GssapiCleanupCredentials no' is recommended,
> +so logging out of one session
> +doesn't remove the credentials in use by another session of
> +the same user.
> +Currently only implemented for the GSI mechanism.
> +.It Cm GSIAllowLimitedProxy
> +Specifies whether to accept limited proxy credentials for
> +authentication.
> +The default is
> +.Dq no .
> +.It Cm GSSAPIStrictAcceptorCheck
> +Determines whether to be strict about the identity of the GSSAPI acceptor 
8461c10536
< @@ -995,6 +1053,121 @@
---
> @@ -1006,6 +1064,121 @@
8583c10658
< @@ -1062,6 +1235,12 @@
---
> @@ -1073,6 +1246,12 @@
8596,8598c10671,11313
< diff -Naur --exclude=autom4te.cache openssh-6.0p1.orig/version.h openssh-6.0p1/version.h
< --- openssh-6.0p1.orig/version.h	2012-02-10 15:19:44.000000000 -0600
< +++ openssh-6.0p1/version.h	2012-05-27 17:50:01.000000000 -0500
---
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/sshd_config.5.orig openssh-6.0p1/sshd_config.5.orig
> --- openssh-6.0p1.orig/sshd_config.5.orig	2012-07-12 17:00:51.398241517 +0200
> +++ openssh-6.0p1/sshd_config.5.orig	2012-07-12 16:59:38.856822143 +0200
> @@ -269,6 +269,17 @@
>  .Xr sftp-server 8
>  for details).
>  .Pp
> +In the special case when only sftp is used, not ssh nor scp,
> +it is possible to use
> +.Cm ChrootDirectory
> +%h or
> +.Cm ChrootDirectory
> +/some/path/%u. The file system containing this directory must be
> +mounted with options nodev and either nosuid or noexec. The owner of the
> +directory should be the user. The ownership of the other components of the path
> +must fulfill the usual conditions. No aditional files are required to be present
> +in the directory.
> +.Pp
>  The default is not to
>  .Xr chroot 2 .
>  .It Cm Ciphers
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/sshd_config.orig openssh-6.0p1/sshd_config.orig
> --- openssh-6.0p1.orig/sshd_config.orig	2012-07-12 17:00:51.314239873 +0200
> +++ openssh-6.0p1/sshd_config.orig	2012-07-12 16:59:38.764820346 +0200
> @@ -120,6 +120,11 @@
>  # override default of no subsystems
>  Subsystem	sftp	/usr/libexec/sftp-server
>  
> +# This enables accepting locale enviroment variables LC_* LANG, see sshd_config(5).
> +AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
> +AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
> +AcceptEnv LC_IDENTIFICATION LC_ALL
> +
>  # Example of overriding settings on a per-user basis
>  #Match User anoncvs
>  #	X11Forwarding no
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/sshd.c.orig openssh-6.0p1/sshd.c.orig
> --- openssh-6.0p1.orig/sshd.c.orig	2012-07-12 17:00:51.318239951 +0200
> +++ openssh-6.0p1/sshd.c.orig	2012-07-12 16:59:38.752820108 +0200
> @@ -77,6 +77,7 @@
>  #include <openssl/md5.h>
>  #include <openssl/rand.h>
>  #include "openbsd-compat/openssl-compat.h"
> +#include <openssl/engine.h>
>  
>  #ifdef HAVE_SECUREWARE
>  #include <sys/security.h>
> @@ -1500,6 +1501,10 @@
>  
>  	OpenSSL_add_all_algorithms();
>  
> +	/* Init available hardware crypto engines. */
> +	ENGINE_load_builtin_engines();
> +	ENGINE_register_all_complete();
> +
>  	/*
>  	 * Force logging to stderr until we have loaded the private host
>  	 * key (unless started from inetd)
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/ssh-globus-usage.c openssh-6.0p1/ssh-globus-usage.c
> --- openssh-6.0p1.orig/ssh-globus-usage.c	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/ssh-globus-usage.c	2012-07-12 17:01:14.574695002 +0200
> @@ -0,0 +1,396 @@
> +/*
> + * Copyright 2009 The Board of Trustees of the University
> + * of Illinois.  See the LICENSE file for detailed license information.
> + *
> + * Portions, specifically log_usage_stats(), ssh_usage_stats_init(),
> + * ssh_usage_stats_close(), ssh_usage_ent_s, ssh_usage_tag_e and
> + * TAG #defines were based on those from Usage Metrics portions of:
> + * gridftp/server/source/globus_i_gfs_log.c
> + *
> + * Copyright 1999-2006 University of Chicago
> + *
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + *
> + * http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#include "includes.h"
> +
> +#ifdef HAVE_GLOBUS_USAGE
> +
> +#include <stdarg.h>
> +#include <unistd.h> 
> +
> +#include "log.h"
> +#include "ssh-globus-usage.h"
> +
> +static globus_list_t *usage_handle_list = NULL;
> +
> +#define SSH_GLOBUS_USAGE_ID 12
> +#define SSH_GLOBUS_USAGE_VER 0
> +
> +#define SSH_GLOBUS_DEFAULT_TAGLIST "VvMm"
> +#define SSH_GLOBUS_ALL_TAGLIST     "VvMmIuU"
> +#define SSH_GLOBUS_TAGCOUNT 25
> +
> +typedef enum ssh_usage_tag_e
> +{
> +    SSH_GLOBUS_USAGE_SSH_VER        = 'V',
> +    SSH_GLOBUS_USAGE_SSL_VER        = 'v',
> +    SSH_GLOBUS_USAGE_METHOD         = 'M',
> +    SSH_GLOBUS_USAGE_MECHANISM      = 'm',
> +    SSH_GLOBUS_USAGE_CLIENTIP       = 'I',
> +    SSH_GLOBUS_USAGE_USERNAME       = 'u',
> +    SSH_GLOBUS_USAGE_USERDN         = 'U'
> +    /* !! ADD to ALL_TAGLIST above and to globus_usage_stats_send()
> +          invocation below when adding here */
> +} ssh_usage_tag_t;
> +
> +typedef struct ssh_usage_ent_s
> +{
> +    globus_usage_stats_handle_t         handle;
> +    char *                              target;
> +    char *                              taglist;
> +} ssh_usage_ent_t;
> +
> +
> +globus_result_t
> +ssh_usage_stats_init(int disable_usage_stats, char *usage_stats_targets)
> +{
> +    globus_result_t                     result;
> +    char *                              target_str = NULL;
> +    char *                              ptr = ptr;
> +    char *                              target = NULL;
> +    char *                              entry = NULL;
> +    globus_list_t *                     list = NULL;
> +    ssh_usage_ent_t *               usage_ent = NULL;
> +
> +    if (disable_usage_stats)
> +	return GLOBUS_SUCCESS;
> +
> +    result = globus_module_activate(GLOBUS_USAGE_MODULE);
> +    if (result != GLOBUS_SUCCESS)
> +    {
> +        error("ERROR: couldn't activate USAGE STATS module");
> +        return result;
> +    }
> +
> +    if (!usage_stats_targets ||
> +        !strcasecmp(usage_stats_targets, "default"))
> +        target_str = strdup(CILOGON_COLLECTOR);
> +    else
> +        target_str = strdup(usage_stats_targets);
> +
> +    if (target_str == NULL)
> +    {
> +        error("ERROR: strdup failure for target_str");
> +        goto error;
> +    }
> +    debug("Processing usage_stats_target (%s)\n", target_str);
> +
> +    if(target_str && (strchr(target_str, ',') || strchr(target_str, '!')))
> +    {
> +        target = target_str;
> +
> +        do {
> +            usage_ent = (ssh_usage_ent_t *) malloc(sizeof(ssh_usage_ent_t));
> +            if (usage_ent == NULL)
> +            {
> +                error("ERROR: couldn't allocate for ssh_usage_ent_t");
> +                goto error;
> +            }
> +
> +            if ((ptr = strchr(target, ',')) != NULL)
> +                *ptr = '\0';
> +
> +            entry = strdup(target);
> +            if (entry == NULL)
> +            {
> +                error("ERROR: strdup failure for target");
> +                goto error;
> +            }
> +
> +            if (ptr)
> +                target = ptr + 1;
> +            else
> +                target = NULL;
> +
> +            if((ptr = strchr(entry, '!')) != NULL)
> +            {
> +                *ptr = '\0';
> +                usage_ent->taglist = strdup(ptr + 1);
> +                if (usage_ent->taglist == NULL)
> +                {
> +                    error("ERROR: strdup failure for taglist");
> +                    goto error;
> +                }
> +                if(strlen(usage_ent->taglist) > SSH_GLOBUS_TAGCOUNT)
> +                {
> +                    usage_ent->taglist[SSH_GLOBUS_TAGCOUNT + 1] = '\0';
> +                }
> +            }
> +            else
> +            {
> +                usage_ent->taglist = strdup(SSH_GLOBUS_DEFAULT_TAGLIST);
> +                if (usage_ent->taglist == NULL)
> +                {
> +                    error("ERROR: couldn't allocate for taglist");
> +                    goto error;
> +                }
> +            }
> +            
> +            if(strcasecmp(usage_ent->taglist, "default") == 0)
> +            {
> +                free(usage_ent->taglist);
> +                usage_ent->taglist = strdup(SSH_GLOBUS_DEFAULT_TAGLIST);
> +                if (usage_ent->taglist == NULL)
> +                {
> +                    error("ERROR: couldn't allocate for taglist");
> +                    goto error;
> +                }
> +            }                
> +            else if(strcasecmp(usage_ent->taglist, "all") == 0)
> +            {
> +                free(usage_ent->taglist);
> +                usage_ent->taglist = strdup(SSH_GLOBUS_ALL_TAGLIST);
> +                if (usage_ent->taglist == NULL)
> +                {
> +                    error("ERROR: couldn't allocate for taglist");
> +                    goto error;
> +                }
> +            }
> +            
> +            usage_ent->target = entry;
> +
> +            globus_list_insert(&usage_handle_list, usage_ent);
> +        }
> +        while(target != NULL);
> +
> +        free(target_str);
> +    }
> +    else
> +    {
> +        usage_ent = (ssh_usage_ent_t *) malloc(sizeof(ssh_usage_ent_t));
> +        if (usage_ent == NULL)
> +        {
> +             error("ERROR: couldn't allocate for usage_ent");
> +             goto error;
> +        }
> +
> +        usage_ent->target = target_str;
> +        usage_ent->taglist = strdup(SSH_GLOBUS_DEFAULT_TAGLIST);
> +        if (usage_ent->taglist == NULL)
> +        {
> +             error("ERROR: couldn't allocate for taglist");
> +             goto error;
> +        }
> +
> +        globus_list_insert(&usage_handle_list, usage_ent);
> +    }
> +
> +    result = GLOBUS_SUCCESS;
> +    for(list = usage_handle_list;
> +        !globus_list_empty(list);
> +        list = globus_list_rest(list))
> +    {
> +        usage_ent = (ssh_usage_ent_t *) globus_list_first(list);
> +
> +        usage_ent->handle = NULL;
> +        if (globus_usage_stats_handle_init(
> +            &usage_ent->handle,
> +            SSH_GLOBUS_USAGE_ID,
> +            SSH_GLOBUS_USAGE_VER,
> +            usage_ent->target) != GLOBUS_SUCCESS)
> +        {
> +            error("USAGE-STATS: Error initializing (%s) (%s)",
> +                     usage_ent->target?:"NULL",
> +                     usage_ent->taglist?:"NULL");
> +            result = GLOBUS_FAILURE;
> +        } else
> +            debug("USAGE-STATS: Initialized (%s) (%s)", usage_ent->target?:"NULL",
> +                     usage_ent->taglist?:"NULL");
> +
> +    }
> +
> +    return result;
> +
> +error:
> +    if (target_str)
> +    {
> +        free(target_str); 
> +        target_str = NULL;
> +    }
> +    if (entry)
> +    {
> +        free(target_str); 
> +        target_str = NULL;
> +    }
> +    return GLOBUS_FAILURE;
> +}
> +
> +void
> +ssh_usage_stats_close(int disable_usage_stats)
> +{
> +    globus_list_t *list;
> +
> +    if (disable_usage_stats)
> +	return;
> +
> +    list = usage_handle_list;
> +    
> +    while(!globus_list_empty(list))
> +    {
> +        ssh_usage_ent_t *usage_ent;
> +        
> +        usage_ent = (ssh_usage_ent_t *) 
> +            globus_list_remove(&list, list);
> +    
> +        if(usage_ent)
> +        {
> +            if(usage_ent->handle)
> +            {
> +                globus_usage_stats_handle_destroy(usage_ent->handle);
> +            }
> +            if(usage_ent->target)
> +            {
> +                free(usage_ent->target);
> +            }
> +            if(usage_ent->taglist)
> +            {
> +                free(usage_ent->taglist);
> +            }
> +            free(usage_ent);
> +        }
> +    }
> +    usage_handle_list = NULL;
> +}
> +
> +static void
> +log_usage_stats(char *ssh_release, const char *ssl_release,
> +                char *method, char *mechanism, const char *clientip,
> +                char *username, char *userdn)
> +{
> +    globus_result_t                     result;
> +    globus_list_t *                     list;
> +    ssh_usage_ent_t *                   usage_ent;
> +    char *                              keys[SSH_GLOBUS_TAGCOUNT];
> +    char *                              values[SSH_GLOBUS_TAGCOUNT];
> +    char *                              ptr;
> +    char *                              key;
> +    char *                              value;
> +    int                                 i = 0;
> +    char *                              save_taglist = NULL;
> +
> +    for(list = usage_handle_list;
> +        !globus_list_empty(list);
> +        list = globus_list_rest(list))
> +    {
> +        usage_ent = (ssh_usage_ent_t *) globus_list_first(list);
> +
> +        if(!usage_ent || usage_ent->handle == NULL)
> +            continue;
> +        
> +        if(save_taglist == NULL || 
> +            strcmp(save_taglist, usage_ent->taglist) != 0)
> +        {
> +            save_taglist = usage_ent->taglist;
> +            
> +            ptr = usage_ent->taglist;
> +            i = 0;
> +            while(ptr && *ptr)
> +            {
> +                switch(*ptr)
> +                {
> +                  case SSH_GLOBUS_USAGE_SSH_VER:
> +                    key = "SSH_VER";
> +                    value = ssh_release;
> +                    break;
> +    
> +                  case SSH_GLOBUS_USAGE_SSL_VER:
> +                    key = "SSL_VER";
> +                    value = (char *) ssl_release;
> +                    break;
> +    
> +                  case SSH_GLOBUS_USAGE_METHOD:
> +                    key = "METHOD";
> +                    value = method;
> +                    break;
> +    
> +                  case SSH_GLOBUS_USAGE_MECHANISM:
> +                    key = "MECH";
> +                    value = mechanism?:"";
> +                    break;
> +    
> +                  case SSH_GLOBUS_USAGE_CLIENTIP:
> +                    key = "CLIENTIP";
> +                    value = (char *) clientip?:"";
> +                    break;
> +    
> +                  case SSH_GLOBUS_USAGE_USERNAME:
> +                    key = "USER";
> +                    value = username?:"";
> +                    break;
> +    
> +                  case SSH_GLOBUS_USAGE_USERDN:
> +                    key = "USERDN";
> +                    value = userdn?:"";
> +                    break;
> +    
> +                  default:
> +                    key = NULL;
> +                    value = NULL;
> +                    break;
> +                }
> +                
> +                if(key != NULL && value != NULL)
> +                {
> +                    keys[i] = key;
> +                    values[i] = value;
> +                    i++;
> +                }
> +                
> +                ptr++;
> +            }
> +        }
> +
> +#ifdef HAVE_GLOBUS_USAGE_SEND_ARRAY
> +        result = globus_usage_stats_send_array(
> +            usage_ent->handle, i, keys, values);
> +#else
> +        if (i)
> +            result = globus_usage_stats_send(
> +                usage_ent->handle, i,
> +                i>0?keys[0]:NULL, i>0?values[0]:NULL,
> +                i>1?keys[1]:NULL, i>1?values[1]:NULL,
> +                i>2?keys[2]:NULL, i>2?values[2]:NULL,
> +                i>3?keys[3]:NULL, i>3?values[3]:NULL,
> +                i>4?keys[4]:NULL, i>4?values[4]:NULL,
> +                i>5?keys[5]:NULL, i>5?values[5]:NULL,
> +                i>6?keys[6]:NULL, i>6?values[6]:NULL);
> +#endif /* HAVE_GLOBUS_USAGE_SEND_ARRAY */
> +    }
> +    
> +    return;
> +}
> +#endif /* HAVE_GLOBUS_USAGE */
> +
> +void
> +ssh_globus_send_usage_metrics(char *ssh_release, const char *ssl_release,
> +                              char *method, char *mechanism, const char *client_ip,
> +                              char *username, char *userdn)
> +{
> +#ifdef HAVE_GLOBUS_USAGE
> +
> +    log_usage_stats(ssh_release, ssl_release, method, mechanism,
> +                    client_ip, username, userdn);
> +
> +#endif /* HAVE_GLOBUS_USAGE */
> +}
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/ssh-globus-usage.h openssh-6.0p1/ssh-globus-usage.h
> --- openssh-6.0p1.orig/ssh-globus-usage.h	1970-01-01 01:00:00.000000000 +0100
> +++ openssh-6.0p1/ssh-globus-usage.h	2012-07-12 17:01:14.582695159 +0200
> @@ -0,0 +1,46 @@
> +/*
> + * Copyright 2009 The Board of Trustees of the University
> + * of Illinois.  See the LICENSE file for detailed license information.
> + *
> + * Portions, specifically ssh_usage_stats_init(), ssh_usage_stats_close()
> + * were based on those from: gridftp/server/source/globus_i_gfs_log.h
> + * Copyright 1999-2006 University of Chicago
> + * 
> + * Licensed under the Apache License, Version 2.0 (the "License");
> + * you may not use this file except in compliance with the License.
> + * You may obtain a copy of the License at
> + * 
> + * http://www.apache.org/licenses/LICENSE-2.0
> + * 
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +
> +#ifndef __SSH_GLOBUS_USAGE_H
> +#define __SSH_GLOBUS_USAGE_H
> +
> +#include "includes.h"
> +
> +#ifdef HAVE_GLOBUS_USAGE
> +
> +#include "globus_usage.h"
> +
> +#define CILOGON_COLLECTOR "usage-stats.cilogon.org:4810"
> +
> +globus_result_t
> +ssh_usage_stats_init(int disable_usage_stats, char *usage_stats_targets);
> +
> +void
> +ssh_usage_stats_close(int disable_usage_stats);
> +
> +#endif /* HAVE_GLOBUS_USAGE */
> +
> +void
> +ssh_globus_send_usage_metrics(char *ssh_release, const char *ssl_release,
> +                           char *method, char *mechanism, const char *client_ip,
> +                           char *username, char *userdn);
> +
> +#endif /* __SSH_GLOBUS_USAGE_H */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/ssh-gss.h openssh-6.0p1/ssh-gss.h
> --- openssh-6.0p1.orig/ssh-gss.h	2012-07-12 17:00:49.886211931 +0200
> +++ openssh-6.0p1/ssh-gss.h	2012-07-12 17:01:14.586695237 +0200
> @@ -1,6 +1,6 @@
>  /* $OpenBSD: ssh-gss.h,v 1.10 2007/06/12 08:20:00 djm Exp $ */
>  /*
> - * Copyright (c) 2001-2003 Simon Wilkinson. All rights reserved.
> + * Copyright (c) 2001-2009 Simon Wilkinson. All rights reserved.
>   *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions
> @@ -34,6 +34,7 @@
>  #include <gssapi/gssapi.h>
>  #endif
>  
> +#ifndef MECHGLUE
>  #ifdef KRB5
>  # ifndef HEIMDAL
>  #  ifdef HAVE_GSSAPI_GENERIC_H
> @@ -49,6 +50,7 @@
>  #endif /* GSS_C_NT_... */
>  #endif /* !HEIMDAL */
>  #endif /* KRB5 */
> +#endif /* !MECHGLUE */
>  
>  /* draft-ietf-secsh-gsskeyex-06 */
>  #define SSH2_MSG_USERAUTH_GSSAPI_RESPONSE		60
> @@ -60,10 +62,22 @@
>  
>  #define SSH_GSS_OIDTYPE 0x06
>  
> +#define SSH2_MSG_KEXGSS_INIT                            30
> +#define SSH2_MSG_KEXGSS_CONTINUE                        31
> +#define SSH2_MSG_KEXGSS_COMPLETE                        32
> +#define SSH2_MSG_KEXGSS_HOSTKEY                         33
> +#define SSH2_MSG_KEXGSS_ERROR                           34
> +#define SSH2_MSG_KEXGSS_GROUPREQ			40
> +#define SSH2_MSG_KEXGSS_GROUP				41
> +#define KEX_GSS_GRP1_SHA1_ID				"gss-group1-sha1-"
> +#define KEX_GSS_GRP14_SHA1_ID				"gss-group14-sha1-"
> +#define KEX_GSS_GEX_SHA1_ID				"gss-gex-sha1-"
> +
>  typedef struct {
>  	char *filename;
>  	char *envvar;
>  	char *envval;
> +	struct passwd *owner;
>  	void *data;
>  } ssh_gssapi_ccache;
>  
> @@ -71,8 +85,12 @@
>  	gss_buffer_desc displayname;
>  	gss_buffer_desc exportedname;
>  	gss_cred_id_t creds;
> +	gss_name_t name;
>  	struct ssh_gssapi_mech_struct *mech;
>  	ssh_gssapi_ccache store;
> +    gss_ctx_id_t context; /* needed for globus_gss_assist_map_and_authorize() */
> +	int used;
> +	int updated;
>  } ssh_gssapi_client;
>  
>  typedef struct ssh_gssapi_mech_struct {
> @@ -83,6 +101,7 @@
>  	int (*userok) (ssh_gssapi_client *, char *);
>  	int (*localname) (ssh_gssapi_client *, char **);
>  	void (*storecreds) (ssh_gssapi_client *);
> +	int (*updatecreds) (ssh_gssapi_ccache *, ssh_gssapi_client *);
>  } ssh_gssapi_mech;
>  
>  typedef struct {
> @@ -90,13 +109,14 @@
>  	OM_uint32	minor; /* both */
>  	gss_ctx_id_t	context; /* both */
>  	gss_name_t	name; /* both */
> -	gss_OID		oid; /* client */
> +	gss_OID		oid; /* both */
>  	gss_cred_id_t	creds; /* server */
>  	gss_name_t	client; /* server */
> -	gss_cred_id_t	client_creds; /* server */
> +	gss_cred_id_t	client_creds; /* both */
>  } Gssctxt;
>  
>  extern ssh_gssapi_mech *supported_mechs[];
> +extern Gssctxt *gss_kex_context;
>  
>  int  ssh_gssapi_check_oid(Gssctxt *, void *, size_t);
>  void ssh_gssapi_set_oid_data(Gssctxt *, void *, size_t);
> @@ -116,16 +136,41 @@
>  void ssh_gssapi_delete_ctx(Gssctxt **);
>  OM_uint32 ssh_gssapi_sign(Gssctxt *, gss_buffer_t, gss_buffer_t);
>  void ssh_gssapi_buildmic(Buffer *, const char *, const char *, const char *);
> -int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *);
> +int ssh_gssapi_check_mechanism(Gssctxt **, gss_OID, const char *, const char *);
> +OM_uint32 ssh_gssapi_client_identity(Gssctxt *, const char *);
> +int ssh_gssapi_credentials_updated(Gssctxt *);
> +
> +int ssh_gssapi_localname(char **name);
> +void ssh_gssapi_rekey_creds();
>  
>  /* In the server */
> +typedef int ssh_gssapi_check_fn(Gssctxt **, gss_OID, const char *, 
> +    const char *);
> +char *ssh_gssapi_client_mechanisms(const char *, const char *);
> +char *ssh_gssapi_kex_mechs(gss_OID_set, ssh_gssapi_check_fn *, const char *,
> +    const char *);
> +gss_OID ssh_gssapi_id_kex(Gssctxt *, char *, int);
> +int ssh_gssapi_server_check_mech(Gssctxt **,gss_OID, const char *, 
> +    const char *);
>  OM_uint32 ssh_gssapi_server_ctx(Gssctxt **, gss_OID);
> -int ssh_gssapi_userok(char *name);
> +int ssh_gssapi_userok(char *name, struct passwd *, int gssapi_keyex);
>  OM_uint32 ssh_gssapi_checkmic(Gssctxt *, gss_buffer_t, gss_buffer_t);
>  void ssh_gssapi_do_child(char ***, u_int *);
>  void ssh_gssapi_cleanup_creds(void);
>  void ssh_gssapi_storecreds(void);
>  
> +#ifdef MECHGLUE
> +gss_cred_id_t __gss_get_mechanism_cred
> +   (gss_cred_id_t,	/* union_cred */
> +    gss_OID		/* mech_type */
> +   );
> +#endif
> +
> +char *ssh_gssapi_server_mechanisms(void);
> +int ssh_gssapi_oid_table_ok();
> +
> +int ssh_gssapi_update_creds(ssh_gssapi_ccache *store);
> +void ssh_gssapi_get_client_info(char **userdn, char **mech);
>  #endif /* GSSAPI */
>  
>  #endif /* _SSH_GSS_H */
> diff -Naur '--exclude=autom4te.cache' openssh-6.0p1.orig/version.h openssh-6.0p1/version.h
> --- openssh-6.0p1.orig/version.h	2012-07-12 17:00:50.094216001 +0200
> +++ openssh-6.0p1/version.h	2012-07-12 17:01:14.798699385 +0200