ports/135407: [MAINTAINER] security/openssh-portable: update HPN and LPK patches to newer versions

Denis Barov dindin at dindin.ru
Tue Jun 9 09:00:16 UTC 2009


>Number:         135407
>Category:       ports
>Synopsis:       [MAINTAINER] security/openssh-portable: update HPN and LPK patches to newer versions
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          maintainer-update
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jun 09 09:00:15 UTC 2009
>Closed-Date:
>Last-Modified:
>Originator:     Denis Barov
>Release:        FreeBSD 7.2-RELEASE i386
>Organization:
Yandex
>Environment:
System: FreeBSD sepulca.yandex.ru 7.2-RELEASE FreeBSD 7.2-RELEASE #0: Tue Jun  2 19:57:10 MSD
>Description:
[DESCRIBE CHANGES]


Added file(s):
- files/contrib-openssh-5.1_p1-lpk-64bit.patch
- files/contrib-openssh-lpk-5.1p1-0.3.10-servconf.c.patch
- files/contrib-openssh-lpk-5.1p1-0.3.10.patch
- files/lpk+hpn-servconf.c.patch
- files/openssh-5.2p1-hpn13v6-servconf.c.diff
- files/openssh-5.2p1-hpn13v6.diff

Removed file(s):
- files/openssh-5.2p1-hpn-servconf.patch
- files/openssh-5.2p1-hpn.patch
- files/openssh-lpk+hpn-servconf.patch
- files/openssh-lpk-5.0p1-0.3.9-servconv.patch
- files/openssh-lpk-5.0p1-0.3.9.patch
- files/openssh-lpk-5.0p1-64bit.patch

Generated with FreeBSD Port Tools 0.77
>How-To-Repeat:
>Fix:

--- openssh-portable-5.2.p1_2,1.patch begins here ---
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/Makefile /usr/home/dindin/workspace/openssh-portable/Makefile
--- /usr/ports/security/openssh-portable/Makefile	2009-05-19 14:13:28.000000000 +0400
+++ /usr/home/dindin/workspace/openssh-portable/Makefile	2009-06-04 18:59:41.000000000 +0400
@@ -2,12 +2,12 @@
 # Date created:  18 Mar 1999
 # Whom:   dwcjr at inethouston.net
 #
-# $FreeBSD$
+# $FreeBSD: ports/security/openssh-portable/Makefile,v 1.136 2009/05/19 10:13:28 osa Exp $
 #
 
 PORTNAME=	openssh
 DISTVERSION=	5.2p1
-PORTREVISION=	1
+PORTREVISION=	2
 PORTEPOCH=	1
 CATEGORIES=	security ipv6
 .if defined(OPENSSH_SNAPSHOT)
@@ -81,7 +81,7 @@
 WITH_OVERWRITE_BASE=	yes
 .endif
 
-.if !defined(WITHOUT_PAM) && exists(/usr/include/security/pam_modules.h)
+.if !defined(WITHOUT_PAM) && exists(${PREFIX}/security/pam_modules.h)
 CONFIGURE_ARGS+=	--with-pam
 .endif
 
@@ -142,12 +142,12 @@
 .endif
 
 .if defined(WITH_HPN)
-EXTRA_PATCHES+=	${FILESDIR}/openssh-5.2p1-hpn.patch
+EXTRA_PATCHES+=	${FILESDIR}/openssh-5.2p1-hpn13v6.diff
 .endif
 
 # See http://dev.inversepath.com/trac/openssh-lpk
 .if defined(WITH_LPK)
-EXTRA_PATCHES+=		${FILESDIR}/openssh-lpk-5.0p1-0.3.9.patch
+EXTRA_PATCHES+=		${FILESDIR}/contrib-openssh-lpk-5.1p1-0.3.10.patch
 USE_OPENLDAP=		yes
 CPPFLAGS+=		"-I${LOCALBASE}/include -DWITH_LDAP_PUBKEY"
 CONFIGURE_ARGS+=	--with-libs='-lldap' --with-ldflags='-L${LOCALBASE}/lib' \
@@ -157,15 +157,15 @@
 # resolve some patches incompatibility between LPK and HPN patches
 
 .if defined(WITH_HPN) && defined(WITH_LPK)
-EXTRA_PATCHES+=		${FILESDIR}/openssh-lpk+hpn-servconf.patch
+EXTRA_PATCHES+=		${FILESDIR}/lpk+hpn-servconf.c.patch
 .elif defined(WITH_HPN) && !defined(WITH_LPK)
-EXTRA_PATCHES+=		${FILESDIR}/openssh-5.2p1-hpn-servconf.patch
+EXTRA_PATCHES+=		${FILESDIR}/openssh-5.2p1-hpn13v6-servconf.c.diff
 .elif defined(WITH_LPK) && !defined(WITH_HPN)
-EXTRA_PATCHES+=		${FILESDIR}/openssh-lpk-5.0p1-0.3.9-servconv.patch
+EXTRA_PATCHES+=		${FILESDIR}/contrib-openssh-lpk-5.1p1-0.3.10-servconf.c.patch
 .endif
 
 .if defined(WITH_LPK) && ${ARCH} == "amd64"
-EXTRA_PATCHES+=		${FILESDIR}/openssh-lpk-5.0p1-64bit.patch
+EXTRA_PATCHES+=		${FILESDIR}/contrib-openssh-5.1_p1-lpk-64bit.patch
 .endif
 
 # See http://www.roumenpetrov.info/openssh/
@@ -182,8 +182,7 @@
 EMPTYDIR=		/var/empty
 PREFIX=			/usr
 ETCSSH=			/etc/ssh
-USE_RC_SUBR=		yes
-SUB_FILES+=		openssh
+USE_RC_SUBR=	openssh
 PLIST_SUB+=		NOTBASE="@comment "
 PLIST_SUB+=		BASE=""
 PLIST_SUB+=		BASEPREFIX="${PREFIX}"
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/distinfo /usr/home/dindin/workspace/openssh-portable/distinfo
--- /usr/ports/security/openssh-portable/distinfo	2009-05-15 15:00:27.000000000 +0400
+++ /usr/home/dindin/workspace/openssh-portable/distinfo	2009-06-04 19:00:30.000000000 +0400
@@ -1,6 +1,3 @@
 MD5 (openssh-5.2p1.tar.gz) = ada79c7328a8551bdf55c95e631e7dad
 SHA256 (openssh-5.2p1.tar.gz) = 4023710c37d0b3d79e6299cb79b6de2a31db7d581fe59e775a5351784034ecae
 SIZE (openssh-5.2p1.tar.gz) = 1016612
-MD5 (openssh-5.2p1+x509-6.2.diff.gz) = 8dbbfb743226864f6bb49b56e77776d9
-SHA256 (openssh-5.2p1+x509-6.2.diff.gz) = 72cfb1e232b6ae0a9df6e8539a9f6b53db7c0a2141cf2e4dd65b407748fa9f34
-SIZE (openssh-5.2p1+x509-6.2.diff.gz) = 153010
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/files/contrib-openssh-5.1_p1-lpk-64bit.patch /usr/home/dindin/workspace/openssh-portable/files/contrib-openssh-5.1_p1-lpk-64bit.patch
--- /usr/ports/security/openssh-portable/files/contrib-openssh-5.1_p1-lpk-64bit.patch	1970-01-01 03:00:00.000000000 +0300
+++ /usr/home/dindin/workspace/openssh-portable/files/contrib-openssh-5.1_p1-lpk-64bit.patch	2009-05-26 18:21:48.000000000 +0400
@@ -0,0 +1,44 @@
+diff -Nuar --exclude '*.rej' servconf.c.orig servconf.c
+--- servconf.c.orig	2008-08-23 15:02:47.000000000 -0700
++++ servconf.c	2008-08-23 15:04:21.000000000 -0700
+@@ -701,6 +701,7 @@
+ 	int cmdline = 0, *intptr, value, n;
+ 	SyslogFacility *log_facility_ptr;
+ 	LogLevel *log_level_ptr;
++ 	unsigned long lvalue, *longptr;
+ 	ServerOpCodes opcode;
+ 	u_short port;
+ 	u_int i, flags = 0;
+@@ -715,6 +716,7 @@
+ 	if (!arg || !*arg || *arg == '#')
+ 		return 0;
+ 	intptr = NULL;
++	longptr = NULL;
+ 	charptr = NULL;
+ 	opcode = parse_token(arg, filename, linenum, &flags);
+ 
+@@ -1449,11 +1451,20 @@
+ 			*intptr = value;
+ 		break;
+ 	case sBindTimeout:
+-		intptr = (int *) &options->lpk.b_timeout.tv_sec;
+-		goto parse_int;
++		longptr = (unsigned long *) &options->lpk.b_timeout.tv_sec;
++parse_ulong:
++		arg = strdelim(&cp);
++		if (!arg || *arg == '\0')
++			fatal("%s line %d: missing integer value.",
++			    filename, linenum);
++		lvalue = atol(arg);
++		if (*activep && *longptr == -1)
++			*longptr = lvalue;
++		break;
++
+ 	case sSearchTimeout:
+-		intptr = (int *) &options->lpk.s_timeout.tv_sec;
+-		goto parse_int;
++		longptr = (unsigned long *) &options->lpk.s_timeout.tv_sec;
++		goto parse_ulong;
+ 		break;
+ 	case sLdapConf:
+ 		arg = cp;
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/files/contrib-openssh-lpk-5.1p1-0.3.10-servconf.c.patch /usr/home/dindin/workspace/openssh-portable/files/contrib-openssh-lpk-5.1p1-0.3.10-servconf.c.patch
--- /usr/ports/security/openssh-portable/files/contrib-openssh-lpk-5.1p1-0.3.10-servconf.c.patch	1970-01-01 03:00:00.000000000 +0300
+++ /usr/home/dindin/workspace/openssh-portable/files/contrib-openssh-lpk-5.1p1-0.3.10-servconf.c.patch	2009-05-26 19:19:54.000000000 +0400
@@ -0,0 +1,213 @@
+--- servconf.c.orig	2009-05-26 15:13:32.000000000 +0400
++++ servconf.c	2009-05-26 15:24:39.000000000 +0400
+@@ -42,6 +42,10 @@
+ #include "channels.h"
+ #include "groupaccess.h"
+ 
++#ifdef WITH_LDAP_PUBKEY
++#include "ldapauth.h"
++#endif
++
+ static void add_listen_addr(ServerOptions *, char *, int);
+ static void add_one_listen_addr(ServerOptions *, char *, int);
+ 
+@@ -128,6 +132,24 @@
+ 	options->adm_forced_command = NULL;
+ 	options->chroot_directory = NULL;
+ 	options->zero_knowledge_password_authentication = -1;
++#ifdef WITH_LDAP_PUBKEY
++ 	/* XXX dirty */
++ 	options->lpk.ld = NULL;
++ 	options->lpk.on = -1;
++ 	options->lpk.servers = NULL;
++ 	options->lpk.u_basedn = NULL;
++ 	options->lpk.g_basedn = NULL;
++ 	options->lpk.binddn = NULL;
++ 	options->lpk.bindpw = NULL;
++ 	options->lpk.sgroup = NULL;
++ 	options->lpk.filter = NULL;
++ 	options->lpk.fgroup = NULL;
++ 	options->lpk.l_conf = NULL;
++ 	options->lpk.tls = -1;
++ 	options->lpk.b_timeout.tv_sec = -1;
++ 	options->lpk.s_timeout.tv_sec = -1;
++ 	options->lpk.flags = FLAG_EMPTY;
++#endif
+ }
+ 
+ void
+@@ -265,6 +287,32 @@
+ 		options->permit_tun = SSH_TUNMODE_NO;
+ 	if (options->zero_knowledge_password_authentication == -1)
+ 		options->zero_knowledge_password_authentication = 0;
++#ifdef WITH_LDAP_PUBKEY
++	if (options->lpk.on == -1)
++	    options->lpk.on = _DEFAULT_LPK_ON;
++	if (options->lpk.servers == NULL)
++	    options->lpk.servers = _DEFAULT_LPK_SERVERS;
++	if (options->lpk.u_basedn == NULL)
++	    options->lpk.u_basedn = _DEFAULT_LPK_UDN;
++	if (options->lpk.g_basedn == NULL)
++	    options->lpk.g_basedn = _DEFAULT_LPK_GDN;
++	if (options->lpk.binddn == NULL)
++	    options->lpk.binddn = _DEFAULT_LPK_BINDDN;
++	if (options->lpk.bindpw == NULL)
++	    options->lpk.bindpw = _DEFAULT_LPK_BINDPW;
++	if (options->lpk.sgroup == NULL)
++	    options->lpk.sgroup = _DEFAULT_LPK_SGROUP;
++	if (options->lpk.filter == NULL)
++	    options->lpk.filter = _DEFAULT_LPK_FILTER;
++	if (options->lpk.tls == -1)
++	    options->lpk.tls = _DEFAULT_LPK_TLS;
++	if (options->lpk.b_timeout.tv_sec == -1)
++	    options->lpk.b_timeout.tv_sec = _DEFAULT_LPK_BTIMEOUT;
++	if (options->lpk.s_timeout.tv_sec == -1)
++	    options->lpk.s_timeout.tv_sec = _DEFAULT_LPK_STIMEOUT;
++	if (options->lpk.l_conf == NULL)
++	    options->lpk.l_conf = _DEFAULT_LPK_LDP;
++#endif
+ 
+ 	/* Turn privilege separation on by default */
+ 	if (use_privsep == -1)
+@@ -311,6 +359,12 @@
+ 	sUsePrivilegeSeparation, sAllowAgentForwarding,
+ 	sZeroKnowledgePasswordAuthentication,
+ 	sDeprecated, sUnsupported
++#ifdef WITH_LDAP_PUBKEY
++	,sLdapPublickey, sLdapServers, sLdapUserDN
++	,sLdapGroupDN, sBindDN, sBindPw, sMyGroup
++	,sLdapFilter, sForceTLS, sBindTimeout
++	,sSearchTimeout, sLdapConf
++#endif
+ } ServerOpCodes;
+ 
+ #define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
+@@ -421,6 +475,20 @@
+ 	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
+ 	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
+ 	{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
++#ifdef WITH_LDAP_PUBKEY
++	{ _DEFAULT_LPK_TOKEN, sLdapPublickey, SSHCFG_GLOBAL },
++	{ _DEFAULT_SRV_TOKEN, sLdapServers, SSHCFG_GLOBAL },
++	{ _DEFAULT_USR_TOKEN, sLdapUserDN, SSHCFG_GLOBAL },
++	{ _DEFAULT_GRP_TOKEN, sLdapGroupDN, SSHCFG_GLOBAL },
++	{ _DEFAULT_BDN_TOKEN, sBindDN, SSHCFG_GLOBAL },
++	{ _DEFAULT_BPW_TOKEN, sBindPw, SSHCFG_GLOBAL },
++	{ _DEFAULT_MYG_TOKEN, sMyGroup, SSHCFG_GLOBAL },
++	{ _DEFAULT_FIL_TOKEN, sLdapFilter, SSHCFG_GLOBAL },
++	{ _DEFAULT_TLS_TOKEN, sForceTLS, SSHCFG_GLOBAL },
++	{ _DEFAULT_BTI_TOKEN, sBindTimeout, SSHCFG_GLOBAL },
++	{ _DEFAULT_STI_TOKEN, sSearchTimeout, SSHCFG_GLOBAL },
++	{ _DEFAULT_LDP_TOKEN, sLdapConf, SSHCFG_GLOBAL },
++#endif
+ 	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
+ 	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
+ 	{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
+@@ -1311,6 +1379,107 @@
+ 		while (arg)
+ 		    arg = strdelim(&cp);
+ 		break;
++#ifdef WITH_LDAP_PUBKEY
++	case sLdapPublickey:
++		intptr = &options->lpk.on;
++		goto parse_flag;
++	case sLdapServers:
++		/* arg = strdelim(&cp); */
++		p = line;
++		while(*p++);
++		arg = p;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing ldap server",filename,linenum);
++		arg[strlen(arg)] = '\0';
++		if ((options->lpk.servers = ldap_parse_servers(arg)) == NULL)
++		    fatal("%s line %d: error in ldap servers", filename, linenum);
++		memset(arg,0,strlen(arg));
++		break;
++	case sLdapUserDN:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing ldap server",filename,linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.u_basedn = xstrdup(arg);
++		memset(arg,0,strlen(arg));
++		break;
++	case sLdapGroupDN:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing ldap server",filename,linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.g_basedn = xstrdup(arg);
++		memset(arg,0,strlen(arg));
++		break;
++	case sBindDN:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing binddn",filename,linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.binddn = xstrdup(arg);
++		memset(arg,0,strlen(arg));
++		break;
++	case sBindPw:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing bindpw",filename,linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.bindpw = xstrdup(arg);
++		memset(arg,0,strlen(arg));
++		break;
++	case sMyGroup:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing groupname",filename, linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.sgroup = xstrdup(arg);
++		if (options->lpk.sgroup)
++		    options->lpk.fgroup = ldap_parse_groups(options->lpk.sgroup);
++		memset(arg,0,strlen(arg));
++		break;
++	case sLdapFilter:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing filter",filename, linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.filter = xstrdup(arg);
++		memset(arg,0,strlen(arg));
++		break;
++	case sForceTLS:
++		intptr = &options->lpk.tls;
++		arg = strdelim(&cp);
++		if (!arg || *arg == '\0')
++			fatal("%s line %d: missing yes/no argument.",
++			    filename, linenum);
++		value = 0;	/* silence compiler */
++		if (strcmp(arg, "yes") == 0)
++			value = 1;
++		else if (strcmp(arg, "no") == 0)
++			value = 0;
++		else if (strcmp(arg, "try") == 0)
++			value = -1;
++		else
++			fatal("%s line %d: Bad yes/no argument: %s",
++				filename, linenum, arg);
++		if (*intptr == -1)
++			*intptr = value;
++		break;
++	case sBindTimeout:
++		intptr = (int *) &options->lpk.b_timeout.tv_sec;
++		goto parse_int;
++	case sSearchTimeout:
++		intptr = (int *) &options->lpk.s_timeout.tv_sec;
++		goto parse_int;
++		break;
++	case sLdapConf:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing LpkLdapConf", filename, linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.l_conf = xstrdup(arg);
++		memset(arg, 0, strlen(arg));
++		break;
++#endif
+ 
+ 	default:
+ 		fatal("%s line %d: Missing handler for opcode %s (%d)",
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/files/contrib-openssh-lpk-5.1p1-0.3.10.patch /usr/home/dindin/workspace/openssh-portable/files/contrib-openssh-lpk-5.1p1-0.3.10.patch
--- /usr/ports/security/openssh-portable/files/contrib-openssh-lpk-5.1p1-0.3.10.patch	1970-01-01 03:00:00.000000000 +0300
+++ /usr/home/dindin/workspace/openssh-portable/files/contrib-openssh-lpk-5.1p1-0.3.10.patch	2009-05-26 14:17:48.000000000 +0400
@@ -0,0 +1,1682 @@
+This is a forward-port of the OpenSSH LPK support patch.
+
+It adds support for storing OpenSSH public keys in LDAP. It also supports
+grouping of machines in the LDAP data to limit users to specific machines.
+
+The latest homepage for the LPK project is:
+http://code.google.com/p/openssh-lpk/
+
+The 0.3.10 version of the patch includes a fix for 64-bit platforms, as
+discovered by Gentoo, where the bind timeout and search timeout values were not
+being parsed correctly: http://bugs.gentoo.org/210110
+
+Forward-ported-from: openssh-lpk-5.1p1-0.3.9.patch
+Signed-off-by: Robin H. Johnson <robbat2 at gentoo.org>
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' auth2-pubkey.c auth2-pubkey.c
+--- auth2-pubkey.c	2008-07-03 19:54:25.000000000 -0700
++++ auth2-pubkey.c	2008-08-23 15:02:47.000000000 -0700
+@@ -55,6 +55,10 @@
+ #include "monitor_wrap.h"
+ #include "misc.h"
+ 
++#ifdef WITH_LDAP_PUBKEY
++#include "ldapauth.h"
++#endif
++
+ /* import */
+ extern ServerOptions options;
+ extern u_char *session_id2;
+@@ -187,10 +191,79 @@
+ 	u_long linenum = 0;
+ 	Key *found;
+ 	char *fp;
++#ifdef WITH_LDAP_PUBKEY
++	ldap_key_t * k;
++	unsigned int i = 0;
++#endif
+ 
+ 	/* Temporarily use the user's uid. */
+ 	temporarily_use_uid(pw);
+ 
++#ifdef WITH_LDAP_PUBKEY
++ 	found_key = 0;
++ 	/* allocate a new key type */
++ 	found = key_new(key->type);
++ 
++ 	/* first check if the options is enabled, then try.. */
++	if (options.lpk.on) {
++	    debug("[LDAP] trying LDAP first uid=%s",pw->pw_name);
++	    if (ldap_ismember(&options.lpk, pw->pw_name) > 0) {
++		if ((k = ldap_getuserkey(&options.lpk, pw->pw_name)) != NULL) {
++		    /* Skip leading whitespace, empty and comment lines. */
++		    for (i = 0 ; i < k->num ; i++) {
++			/* dont forget if multiple keys to reset options */
++			char *cp, *options = NULL;
++
++			for (cp = (char *)k->keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++)
++			    ;
++			if (!*cp || *cp == '\n' || *cp == '#')
++			    continue;
++
++			if (key_read(found, &cp) != 1) {
++			    /* no key?  check if there are options for this key */
++			    int quoted = 0;
++			    debug2("[LDAP] user_key_allowed: check options: '%s'", cp);
++			    options = cp;
++			    for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
++				if (*cp == '\\' && cp[1] == '"')
++				    cp++;	/* Skip both */
++				else if (*cp == '"')
++				    quoted = !quoted;
++			    }
++			    /* Skip remaining whitespace. */
++			    for (; *cp == ' ' || *cp == '\t'; cp++)
++				;
++			    if (key_read(found, &cp) != 1) {
++				debug2("[LDAP] user_key_allowed: advance: '%s'", cp);
++				/* still no key?  advance to next line*/
++				continue;
++			    }
++			}
++
++			if (key_equal(found, key) &&
++				auth_parse_options(pw, options, file, linenum) == 1) {
++			    found_key = 1;
++			    debug("[LDAP] matching key found");
++			    fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
++			    verbose("[LDAP] Found matching %s key: %s", key_type(found), fp);
++
++			    /* restoring memory */
++			    ldap_keys_free(k);
++			    xfree(fp);
++			    restore_uid();
++			    key_free(found);
++			    return found_key;
++			    break;
++			}
++		    }/* end of LDAP for() */
++		} else {
++		    logit("[LDAP] no keys found for '%s'!", pw->pw_name);
++		}
++	    } else {
++		logit("[LDAP] '%s' is not in '%s'", pw->pw_name, options.lpk.sgroup);
++	    }
++	}
++#endif
+ 	debug("trying public key file %s", file);
+ 	f = auth_openkeyfile(file, pw, options.strict_modes);
+ 
+diff -Nuar --exclude '*.orig' --exclude '*.rej' auth-rsa.c auth-rsa.c
+--- auth-rsa.c	2008-07-02 05:37:30.000000000 -0700
++++ auth-rsa.c	2008-08-23 15:02:47.000000000 -0700
+@@ -174,10 +174,96 @@
+ 	FILE *f;
+ 	u_long linenum = 0;
+ 	Key *key;
++#ifdef WITH_LDAP_PUBKEY
++	ldap_key_t * k;
++	unsigned int i = 0;
++#endif
+ 
+ 	/* Temporarily use the user's uid. */
+ 	temporarily_use_uid(pw);
+ 
++#ifdef WITH_LDAP_PUBKEY
++	/* here is the job */
++	key = key_new(KEY_RSA1);
++
++	if (options.lpk.on) {
++	    debug("[LDAP] trying LDAP first uid=%s", pw->pw_name);
++	    if ( ldap_ismember(&options.lpk, pw->pw_name) > 0) {
++		if ( (k = ldap_getuserkey(&options.lpk, pw->pw_name)) != NULL) {
++		    for (i = 0 ; i < k->num ; i++) {
++			char *cp, *options = NULL;
++
++			for (cp = k->keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++)
++			    ;
++			if (!*cp || *cp == '\n' || *cp == '#')
++			    continue;
++
++			/*
++			* Check if there are options for this key, and if so,
++			* save their starting address and skip the option part
++			* for now.  If there are no options, set the starting
++			* address to NULL.
++			 */
++			if (*cp < '0' || *cp > '9') {
++			    int quoted = 0;
++			    options = cp;
++			    for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
++				if (*cp == '\\' && cp[1] == '"')
++				    cp++;	/* Skip both */
++				else if (*cp == '"')
++				    quoted = !quoted;
++			    }
++			} else
++			    options = NULL;
++
++			/* Parse the key from the line. */
++			if (hostfile_read_key(&cp, &bits, key) == 0) {
++			    debug("[LDAP] line %d: non ssh1 key syntax", i);
++			    continue;
++			}
++			/* cp now points to the comment part. */
++
++			/* Check if the we have found the desired key (identified by its modulus). */
++			if (BN_cmp(key->rsa->n, client_n) != 0)
++			    continue;
++
++			/* check the real bits  */
++			if (bits != (unsigned int)BN_num_bits(key->rsa->n))
++			    logit("[LDAP] Warning: ldap, line %lu: keysize mismatch: "
++				    "actual %d vs. announced %d.", (unsigned long)i, BN_num_bits(key->rsa->n), bits);
++
++			/* We have found the desired key. */
++			/*
++			* If our options do not allow this key to be used,
++			* do not send challenge.
++			 */
++			if (!auth_parse_options(pw, options, "[LDAP]", (unsigned long) i))
++			    continue;
++
++			/* break out, this key is allowed */
++			allowed = 1;
++
++			/* add the return stuff etc... */
++			/* Restore the privileged uid. */
++			restore_uid();
++
++			/* return key if allowed */
++			if (allowed && rkey != NULL)
++			    *rkey = key;
++			else
++			    key_free(key);
++
++			ldap_keys_free(k);
++			return (allowed);
++		    }
++		} else {
++		    logit("[LDAP] no keys found for '%s'!", pw->pw_name);
++		}
++	    } else {
++		logit("[LDAP] '%s' is not in '%s'", pw->pw_name, options.lpk.sgroup);
++	    }
++	}
++#endif
+ 	/* The authorized keys. */
+ 	file = authorized_keys_file(pw);
+ 	debug("trying public RSA key file %s", file);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' config.h.in config.h.in
+--- config.h.in	2008-07-21 01:30:49.000000000 -0700
++++ config.h.in	2008-08-23 15:02:47.000000000 -0700
+@@ -560,6 +560,9 @@
+ /* Define to 1 if you have the <linux/if_tun.h> header file. */
+ #undef HAVE_LINUX_IF_TUN_H
+ 
++/* Define if you want LDAP support */
++#undef WITH_LDAP_PUBKEY
++
+ /* Define if your libraries define login() */
+ #undef HAVE_LOGIN
+ 
+diff -Nuar --exclude '*.orig' --exclude '*.rej' configure configure
+--- configure	2008-07-21 01:30:50.000000000 -0700
++++ configure	2008-08-23 15:02:47.000000000 -0700
+@@ -1340,6 +1340,7 @@
+   --with-tcp-wrappers[=PATH] Enable tcpwrappers support (optionally in PATH)
+   --with-libedit[=PATH]   Enable libedit support for sftp
+   --with-audit=module     Enable EXPERIMENTAL audit support (modules=debug,bsm)
++  --with-ldap[=PATH]      Enable LDAP pubkey support (optionally in PATH)
+   --with-ssl-dir=PATH     Specify path to OpenSSL installation
+   --without-openssl-header-check Disable OpenSSL version consistency check
+   --with-ssl-engine       Enable OpenSSL (hardware) ENGINE support
+@@ -12568,6 +12569,85 @@
+ fi
+ 
+ 
++# Check whether user wants LDAP support
++LDAP_MSG="no"
++
++# Check whether --with-ldap was given.
++if test "${with_ldap+set}" = set; then
++  withval=$with_ldap;
++		if test "x$withval" != "xno" ; then
++
++			if test "x$withval" != "xyes" ; then
++				CPPFLAGS="$CPPFLAGS -I${withval}/include"
++				LDFLAGS="$LDFLAGS -L${withval}/lib"
++			fi
++
++
++cat >>confdefs.h <<\_ACEOF
++#define WITH_LDAP_PUBKEY 1
++_ACEOF
++
++			LIBS="-lldap $LIBS"
++			LDAP_MSG="yes"
++
++			{ echo "$as_me:$LINENO: checking for LDAP support" >&5
++echo $ECHO_N "checking for LDAP support... $ECHO_C" >&6; }
++			cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h.  */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h.  */
++#include <sys/types.h>
++				 #include <ldap.h>
++int
++main ()
++{
++(void)ldap_init(0, 0);
++  ;
++  return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext
++if { (ac_try="$ac_compile"
++case "(($ac_try" in
++  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
++  *) ac_try_echo=$ac_try;;
++esac
++eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
++  (eval "$ac_compile") 2>conftest.er1
++  ac_status=$?
++  grep -v '^ *+' conftest.er1 >conftest.err
++  rm -f conftest.er1
++  cat conftest.err >&5
++  echo "$as_me:$LINENO: \$? = $ac_status" >&5
++  (exit $ac_status); } && {
++	 test -z "$ac_c_werror_flag" ||
++	 test ! -s conftest.err
++       } && test -s conftest.$ac_objext; then
++  { echo "$as_me:$LINENO: result: yes" >&5
++echo "${ECHO_T}yes" >&6; }
++else
++  echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++
++				    { echo "$as_me:$LINENO: result: no" >&5
++echo "${ECHO_T}no" >&6; }
++					{ { echo "$as_me:$LINENO: error: ** Incomplete or missing ldap libraries **" >&5
++echo "$as_me: error: ** Incomplete or missing ldap libraries **" >&2;}
++   { (exit 1); exit 1; }; }
++
++
++fi
++
++rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
++		fi
++
++
++fi
++
++
+ 
+ 
+ 
+@@ -30135,6 +30215,7 @@
+ echo "                 Smartcard support: $SCARD_MSG"
+ echo "                     S/KEY support: $SKEY_MSG"
+ echo "              TCP Wrappers support: $TCPW_MSG"
++echo "                      LDAP support: $LDAP_MSG"
+ echo "              MD5 password support: $MD5_MSG"
+ echo "                   libedit support: $LIBEDIT_MSG"
+ echo "  Solaris process contract support: $SPC_MSG"
+diff -Nuar --exclude '*.orig' --exclude '*.rej' configure.ac configure.ac
+--- configure.ac	2008-07-09 04:07:19.000000000 -0700
++++ configure.ac	2008-08-23 15:02:47.000000000 -0700
+@@ -1299,6 +1299,37 @@
+ 	esac ]
+ )
+ 
++# Check whether user wants LDAP support
++LDAP_MSG="no"
++AC_ARG_WITH(ldap,
++	[  --with-ldap[[=PATH]]      Enable LDAP pubkey support (optionally in PATH)],
++	[
++		if test "x$withval" != "xno" ; then
++
++			if test "x$withval" != "xyes" ; then
++				CPPFLAGS="$CPPFLAGS -I${withval}/include"
++				LDFLAGS="$LDFLAGS -L${withval}/lib"
++			fi
++
++			AC_DEFINE([WITH_LDAP_PUBKEY], 1, [Enable LDAP pubkey support])
++			LIBS="-lldap $LIBS"
++			LDAP_MSG="yes"
++	
++			AC_MSG_CHECKING([for LDAP support])
++			AC_TRY_COMPILE(
++				[#include <sys/types.h>
++				 #include <ldap.h>],
++				[(void)ldap_init(0, 0);],
++				[AC_MSG_RESULT(yes)],
++				[
++				    AC_MSG_RESULT(no) 
++					AC_MSG_ERROR([** Incomplete or missing ldap libraries **])
++				]
++        	)
++		fi
++	]
++)
++
+ dnl    Checks for library functions. Please keep in alphabetical order
+ AC_CHECK_FUNCS( \
+ 	arc4random \
+@@ -4137,6 +4168,7 @@
+ echo "                 Smartcard support: $SCARD_MSG"
+ echo "                     S/KEY support: $SKEY_MSG"
+ echo "              TCP Wrappers support: $TCPW_MSG"
++echo "                      LDAP support: $LDAP_MSG"
+ echo "              MD5 password support: $MD5_MSG"
+ echo "                   libedit support: $LIBEDIT_MSG"
+ echo "  Solaris process contract support: $SPC_MSG"
+diff -Nuar --exclude '*.orig' --exclude '*.rej' ldapauth.c ldapauth.c
+--- ldapauth.c	1969-12-31 16:00:00.000000000 -0800
++++ ldapauth.c	2008-08-23 15:02:47.000000000 -0700
+@@ -0,0 +1,575 @@
++/* 
++ * $Id: openssh-lpk-4.3p1-0.3.7.patch,v 1.3 2006/04/18 15:29:09 eau Exp $
++ */
++
++/*
++ *
++ * Copyright (c) 2005, Eric AUGE <eau at phear.org>
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
++ *
++ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
++ * 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.
++ * Neither the name of the phear.org nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
++ *
++ *
++ */
++
++#include "includes.h"
++
++#ifdef WITH_LDAP_PUBKEY
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <string.h>
++
++#include "ldapauth.h"
++#include "log.h"
++
++static char *attrs[] = {
++    PUBKEYATTR,
++    NULL
++};
++
++/* filter building infos */
++#define FILTER_GROUP_PREFIX "(&(objectclass=posixGroup)"
++#define FILTER_OR_PREFIX "(|"
++#define FILTER_OR_SUFFIX ")"
++#define FILTER_CN_PREFIX "(cn="
++#define FILTER_CN_SUFFIX ")"
++#define FILTER_UID_FORMAT "(memberUid=%s)"
++#define FILTER_GROUP_SUFFIX ")"
++#define FILTER_GROUP_SIZE(group) (size_t) (strlen(group)+(ldap_count_group(group)*5)+52)
++
++/* just filter building stuff */
++#define REQUEST_GROUP_SIZE(filter, uid) (size_t) (strlen(filter)+strlen(uid)+1)
++#define REQUEST_GROUP(buffer, prefilter, pwname) \
++    buffer = (char *) calloc(REQUEST_GROUP_SIZE(prefilter, pwname), sizeof(char)); \
++    if (!buffer) { \
++        perror("calloc()"); \
++        return FAILURE; \
++    } \
++    snprintf(buffer, REQUEST_GROUP_SIZE(prefilter,pwname), prefilter, pwname)
++/*
++XXX OLD group building macros
++#define REQUEST_GROUP_SIZE(grp, uid) (size_t) (strlen(grp)+strlen(uid)+46)
++#define REQUEST_GROUP(buffer,pwname,grp) \
++    buffer = (char *) calloc(REQUEST_GROUP_SIZE(grp, pwname), sizeof(char)); \
++    if (!buffer) { \
++        perror("calloc()"); \
++        return FAILURE; \
++    } \
++    snprintf(buffer,REQUEST_GROUP_SIZE(grp,pwname),"(&(objectclass=posixGroup)(cn=%s)(memberUid=%s))",grp,pwname)
++    */
++
++/*
++XXX stock upstream version without extra filter support
++#define REQUEST_USER_SIZE(uid) (size_t) (strlen(uid)+64)
++#define REQUEST_USER(buffer, pwname) \
++    buffer = (char *) calloc(REQUEST_USER_SIZE(pwname), sizeof(char)); \
++    if (!buffer) { \
++        perror("calloc()"); \
++        return NULL; \
++    } \
++    snprintf(buffer,REQUEST_USER_SIZE(pwname),"(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s))",pwname)
++   */
++
++#define REQUEST_USER_SIZE(uid, filter) (size_t) (strlen(uid)+64+(filter != NULL ? strlen(filter) : 0))
++#define REQUEST_USER(buffer, pwname, customfilter) \
++    buffer = (char *) calloc(REQUEST_USER_SIZE(pwname, customfilter), sizeof(char)); \
++    if (!buffer) { \
++        perror("calloc()"); \
++        return NULL; \
++    } \
++    snprintf(buffer, REQUEST_USER_SIZE(pwname, customfilter), \
++    	"(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s)%s)", \
++	pwname, (customfilter != NULL ? customfilter : ""))
++
++/* some portable and working tokenizer, lame though */
++static int tokenize(char ** o, size_t size, char * input) {
++    unsigned int i = 0, num;
++    const char * charset = " \t";
++    char * ptr = input;
++
++    /* leading white spaces are ignored */
++    num = strspn(ptr, charset);
++    ptr += num;
++
++    while ((num = strcspn(ptr, charset))) {
++        if (i < size-1) {
++            o[i++] = ptr;
++            ptr += num;
++            if (*ptr)
++                *ptr++ = '\0';
++        }
++    }
++    o[i] = NULL;
++    return SUCCESS;
++}
++
++void ldap_close(ldap_opt_t * ldap) {
++
++    if (!ldap)
++        return;
++
++    if ( ldap_unbind_ext(ldap->ld, NULL, NULL) < 0)
++	ldap_perror(ldap->ld, "ldap_unbind()");
++
++    ldap->ld = NULL;
++    FLAG_SET_DISCONNECTED(ldap->flags);
++
++    return;
++}
++
++/* init && bind */
++int ldap_connect(ldap_opt_t * ldap) {
++    int version = LDAP_VERSION3;
++
++    if (!ldap->servers)
++        return FAILURE;
++
++    /* Connection Init and setup */
++    ldap->ld = ldap_init(ldap->servers, LDAP_PORT);
++    if (!ldap->ld) {
++        ldap_perror(ldap->ld, "ldap_init()");
++        return FAILURE;
++    }
++
++    if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) {
++        ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_PROTOCOL_VERSION)");
++        return FAILURE;
++    }
++
++    /* Timeouts setup */
++    if (ldap_set_option(ldap->ld, LDAP_OPT_NETWORK_TIMEOUT, &ldap->b_timeout) != LDAP_SUCCESS) {
++        ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT)");
++    }
++    if (ldap_set_option(ldap->ld, LDAP_OPT_TIMEOUT, &ldap->s_timeout) != LDAP_SUCCESS) {
++        ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_TIMEOUT)");
++    }
++
++    /* TLS support */
++    if ( (ldap->tls == -1) || (ldap->tls == 1) ) {
++        if (ldap_start_tls_s(ldap->ld, NULL, NULL ) != LDAP_SUCCESS) {
++            /* failed then reinit the initial connect */
++            ldap_perror(ldap->ld, "ldap_connect: (TLS) ldap_start_tls()");
++            if (ldap->tls == 1)
++                return FAILURE;
++
++            ldap->ld = ldap_init(ldap->servers, LDAP_PORT);
++            if (!ldap->ld) { 
++                ldap_perror(ldap->ld, "ldap_init()");
++                return FAILURE;
++            }
++
++            if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) {
++                 ldap_perror(ldap->ld, "ldap_set_option()");
++                 return FAILURE;
++            }
++        }
++    }
++
++
++    if ( ldap_simple_bind_s(ldap->ld, ldap->binddn, ldap->bindpw) != LDAP_SUCCESS) {
++        ldap_perror(ldap->ld, "ldap_simple_bind_s()");
++        return FAILURE;
++    }
++
++    /* says it is connected */
++    FLAG_SET_CONNECTED(ldap->flags);
++
++    return SUCCESS;
++}
++
++/* must free allocated ressource */
++static char * ldap_build_host(char *host, int port) {
++    unsigned int size = strlen(host)+11;
++    char * h = (char *) calloc (size, sizeof(char));
++    int rc;
++    if (!h)
++         return NULL;
++
++    rc = snprintf(h, size, "%s:%d ", host, port);
++    if (rc == -1)
++        return NULL;
++    return h;
++}
++
++static int ldap_count_group(const char * input) {
++    const char * charset = " \t";
++    const char * ptr = input;
++    unsigned int count = 0;
++    unsigned int num;
++
++    num = strspn(ptr, charset);
++    ptr += num;
++
++    while ((num = strcspn(ptr, charset))) {
++    count++;
++    ptr += num;
++    ptr++;
++    }
++
++    return count;
++}
++
++/* format filter */
++char * ldap_parse_groups(const char * groups) {
++    unsigned int buffer_size = FILTER_GROUP_SIZE(groups);
++    char * buffer = (char *) calloc(buffer_size, sizeof(char));
++    char * g = NULL;
++    char * garray[32];
++    unsigned int i = 0;
++
++    if ((!groups)||(!buffer))
++        return NULL;
++
++    g = strdup(groups);
++    if (!g) {
++        free(buffer);
++        return NULL;
++    }
++
++    /* first separate into n tokens */
++    if ( tokenize(garray, sizeof(garray)/sizeof(*garray), g) < 0) {
++        free(g);
++        free(buffer);
++        return NULL;
++    }
++
++    /* build the final filter format */
++    strlcat(buffer, FILTER_GROUP_PREFIX, buffer_size);
++    strlcat(buffer, FILTER_OR_PREFIX, buffer_size);
++    i = 0;
++    while (garray[i]) {
++        strlcat(buffer, FILTER_CN_PREFIX, buffer_size);
++        strlcat(buffer, garray[i], buffer_size);
++        strlcat(buffer, FILTER_CN_SUFFIX, buffer_size);
++        i++;
++    }
++    strlcat(buffer, FILTER_OR_SUFFIX, buffer_size);
++    strlcat(buffer, FILTER_UID_FORMAT, buffer_size);
++    strlcat(buffer, FILTER_GROUP_SUFFIX, buffer_size);
++
++    free(g);
++    return buffer;
++}
++
++/* a bit dirty but leak free  */
++char * ldap_parse_servers(const char * servers) {
++    char * s = NULL;
++    char * tmp = NULL, *urls[32];
++    unsigned int num = 0 , i = 0 , asize = 0;
++    LDAPURLDesc *urld[32];
++
++    if (!servers)
++        return NULL;
++
++    /* local copy of the arg */
++    s = strdup(servers);
++    if (!s)
++        return NULL;
++
++    /* first separate into URL tokens */
++    if ( tokenize(urls, sizeof(urls)/sizeof(*urls), s) < 0)
++        return NULL;
++
++    i = 0;
++    while (urls[i]) {
++        if (! ldap_is_ldap_url(urls[i]) ||
++           (ldap_url_parse(urls[i], &urld[i]) != 0)) {
++                return NULL;
++        }
++        i++;
++    }
++
++    /* now free(s) */
++    free (s);
++
++    /* how much memory do we need */
++    num = i;
++    for (i = 0 ; i < num ; i++)
++        asize += strlen(urld[i]->lud_host)+11;
++
++    /* alloc */
++    s = (char *) calloc( asize+1 , sizeof(char));
++    if (!s) {
++        for (i = 0 ; i < num ; i++)
++            ldap_free_urldesc(urld[i]);
++        return NULL;
++    }
++
++    /* then build the final host string */
++    for (i = 0 ; i < num ; i++) {
++        /* built host part */
++        tmp = ldap_build_host(urld[i]->lud_host, urld[i]->lud_port);
++        strncat(s, tmp, strlen(tmp));
++        ldap_free_urldesc(urld[i]);
++        free(tmp);
++    }
++
++    return s;
++}
++
++void ldap_options_print(ldap_opt_t * ldap) {
++    debug("ldap options:");
++    debug("servers: %s", ldap->servers);
++    if (ldap->u_basedn)
++        debug("user basedn: %s", ldap->u_basedn);
++    if (ldap->g_basedn)
++        debug("group basedn: %s", ldap->g_basedn);
++    if (ldap->binddn)
++        debug("binddn: %s", ldap->binddn);
++    if (ldap->bindpw)
++        debug("bindpw: %s", ldap->bindpw);
++    if (ldap->sgroup)
++        debug("group: %s", ldap->sgroup);
++    if (ldap->filter)
++        debug("filter: %s", ldap->filter);
++}
++
++void ldap_options_free(ldap_opt_t * l) {
++    if (!l)
++        return;
++    if (l->servers)
++        free(l->servers);
++    if (l->u_basedn)
++        free(l->u_basedn);
++    if (l->g_basedn)
++        free(l->g_basedn);
++    if (l->binddn)
++        free(l->binddn);
++    if (l->bindpw)
++        free(l->bindpw);
++    if (l->sgroup)
++        free(l->sgroup);
++    if (l->fgroup)
++        free(l->fgroup);
++    if (l->filter)
++        free(l->filter);
++    if (l->l_conf)
++        free(l->l_conf);
++    free(l);
++}
++
++/* free keys */
++void ldap_keys_free(ldap_key_t * k) {
++    ldap_value_free_len(k->keys);
++    free(k);
++    return;
++}
++
++ldap_key_t * ldap_getuserkey(ldap_opt_t *l, const char * user) {
++    ldap_key_t * k = (ldap_key_t *) calloc (1, sizeof(ldap_key_t));
++    LDAPMessage *res, *e;
++    char * filter;
++    int i;
++
++    if ((!k) || (!l))
++         return NULL;
++
++    /* Am i still connected ? RETRY n times */
++    /* XXX TODO: setup some conf value for retrying */
++    if (!(l->flags & FLAG_CONNECTED))
++        for (i = 0 ; i < 2 ; i++)
++            if (ldap_connect(l) == 0)
++                break;
++
++    /* quick check for attempts to be evil */
++    if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) ||
++        (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL))
++        return NULL;
++
++    /* build  filter for LDAP request */
++    REQUEST_USER(filter, user, l->filter);
++
++    if ( ldap_search_st( l->ld,
++        l->u_basedn,
++        LDAP_SCOPE_SUBTREE,
++        filter,
++        attrs, 0, &l->s_timeout, &res ) != LDAP_SUCCESS) {
++        
++        ldap_perror(l->ld, "ldap_search_st()");
++
++        free(filter);
++        free(k);
++
++        /* XXX error on search, timeout etc.. close ask for reconnect */
++        ldap_close(l);
++
++        return NULL;
++    } 
++
++    /* free */
++    free(filter);
++
++    /* check if any results */
++    i = ldap_count_entries(l->ld,res);
++    if (i <= 0) {
++        ldap_msgfree(res);
++        free(k);
++        return NULL;
++    }
++
++    if (i > 1)
++        debug("[LDAP] duplicate entries, using the FIRST entry returned");
++
++    e = ldap_first_entry(l->ld, res);
++    k->keys = ldap_get_values_len(l->ld, e, PUBKEYATTR);
++    k->num = ldap_count_values_len(k->keys);
++
++    ldap_msgfree(res);
++    return k;
++}
++
++
++/* -1 if trouble
++   0 if user is NOT member of current server group
++   1 if user IS MEMBER of current server group 
++ */
++int ldap_ismember(ldap_opt_t * l, const char * user) {
++    LDAPMessage *res;
++    char * filter;
++    int i;
++
++    if ((!l->sgroup) || !(l->g_basedn))
++        return 1;
++
++    /* Am i still connected ? RETRY n times */
++    /* XXX TODO: setup some conf value for retrying */
++    if (!(l->flags & FLAG_CONNECTED)) 
++        for (i = 0 ; i < 2 ; i++)
++            if (ldap_connect(l) == 0)
++                 break;
++
++    /* quick check for attempts to be evil */
++    if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) ||
++        (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL))
++        return FAILURE;
++
++    /* build filter for LDAP request */
++    REQUEST_GROUP(filter, l->fgroup, user);
++
++    if (ldap_search_st( l->ld, 
++        l->g_basedn,
++        LDAP_SCOPE_SUBTREE,
++        filter,
++        NULL, 0, &l->s_timeout, &res) != LDAP_SUCCESS) {
++    
++        ldap_perror(l->ld, "ldap_search_st()");
++
++        free(filter);
++
++        /* XXX error on search, timeout etc.. close ask for reconnect */
++        ldap_close(l);
++
++        return FAILURE;
++    }
++
++    free(filter);
++
++    /* check if any results */
++    if (ldap_count_entries(l->ld, res) > 0) {
++        ldap_msgfree(res);
++        return 1;
++    }
++
++    ldap_msgfree(res);
++    return 0;
++}
++
++/*
++ * ldap.conf simple parser
++ * XXX TODO:  sanity checks
++ * must either
++ * - free the previous ldap_opt_before replacing entries
++ * - free each necessary previously parsed elements
++ * ret:
++ * -1 on FAILURE, 0 on SUCCESS
++ */
++int ldap_parse_lconf(ldap_opt_t * l) {
++    FILE * lcd; /* ldap.conf descriptor */
++    char buf[BUFSIZ];
++    char * s = NULL, * k = NULL, * v = NULL;
++    int li, len;
++
++    lcd = fopen (l->l_conf, "r");
++    if (lcd == NULL) {
++        /* debug("Cannot open %s", l->l_conf); */
++        perror("ldap_parse_lconf()");
++        return FAILURE;
++    }
++    
++    while (fgets (buf, sizeof (buf), lcd) != NULL) {
++
++        if (*buf == '\n' || *buf == '#')
++            continue;
++
++        k = buf;
++        v = k;
++        while (*v != '\0' && *v != ' ' && *v != '\t')
++            v++;
++
++        if (*v == '\0')
++            continue;
++
++        *(v++) = '\0';
++
++        while (*v == ' ' || *v == '\t')
++            v++;
++
++        li = strlen (v) - 1;
++        while (v[li] == ' ' || v[li] == '\t' || v[li] == '\n')
++            --li;
++        v[li + 1] = '\0';
++
++        if (!strcasecmp (k, "uri")) {
++            if ((l->servers = ldap_parse_servers(v)) == NULL) {
++                fatal("error in ldap servers");
++            return FAILURE;
++            }
++
++        }
++        else if (!strcasecmp (k, "base")) { 
++            s = strchr (v, '?');
++            if (s != NULL) {
++                len = s - v;
++                l->u_basedn = malloc (len + 1);
++                strncpy (l->u_basedn, v, len);
++                l->u_basedn[len] = '\0';
++            } else {
++                l->u_basedn = strdup (v);
++            }
++        }
++        else if (!strcasecmp (k, "binddn")) {
++            l->binddn = strdup (v);
++        }
++        else if (!strcasecmp (k, "bindpw")) {
++            l->bindpw = strdup (v);
++        }
++        else if (!strcasecmp (k, "timelimit")) {
++            l->s_timeout.tv_sec = atoi (v);
++                }
++        else if (!strcasecmp (k, "bind_timelimit")) {
++            l->b_timeout.tv_sec = atoi (v);
++        }
++        else if (!strcasecmp (k, "ssl")) {
++            if (!strcasecmp (v, "start_tls"))
++                l->tls = 1;
++        }
++    }
++
++    fclose (lcd);
++    return SUCCESS;
++}
++
++#endif /* WITH_LDAP_PUBKEY */
+diff -Nuar --exclude '*.orig' --exclude '*.rej' ldapauth.h ldapauth.h
+--- ldapauth.h	1969-12-31 16:00:00.000000000 -0800
++++ ldapauth.h	2008-08-23 15:02:47.000000000 -0700
+@@ -0,0 +1,124 @@
++/*
++ * $Id: openssh-lpk-4.3p1-0.3.7.patch,v 1.3 2006/04/18 15:29:09 eau Exp $ 
++ */
++
++/*
++ *
++ * Copyright (c) 2005, Eric AUGE <eau at phear.org>
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
++ *
++ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
++ * 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.
++ * Neither the name of the phear.org nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
++ *
++ *
++ */
++
++#ifndef LDAPAUTH_H
++#define LDAPAUTH_H
++
++#define LDAP_DEPRECATED 1
++
++#include <string.h>
++#include <time.h>
++#include <ldap.h>
++#include <lber.h>
++
++/* tokens in use for config */
++#define _DEFAULT_LPK_TOKEN "UseLPK"
++#define _DEFAULT_SRV_TOKEN "LpkServers"
++#define _DEFAULT_USR_TOKEN "LpkUserDN"
++#define _DEFAULT_GRP_TOKEN "LpkGroupDN"
++#define _DEFAULT_BDN_TOKEN "LpkBindDN"
++#define _DEFAULT_BPW_TOKEN "LpkBindPw"
++#define _DEFAULT_MYG_TOKEN "LpkServerGroup"
++#define _DEFAULT_FIL_TOKEN "LpkFilter"
++#define _DEFAULT_TLS_TOKEN "LpkForceTLS"
++#define _DEFAULT_BTI_TOKEN "LpkBindTimelimit"
++#define _DEFAULT_STI_TOKEN "LpkSearchTimelimit"
++#define _DEFAULT_LDP_TOKEN "LpkLdapConf"
++
++/* default options */
++#define _DEFAULT_LPK_ON 0
++#define _DEFAULT_LPK_SERVERS NULL
++#define _DEFAULT_LPK_UDN NULL
++#define _DEFAULT_LPK_GDN NULL
++#define _DEFAULT_LPK_BINDDN NULL
++#define _DEFAULT_LPK_BINDPW NULL
++#define _DEFAULT_LPK_SGROUP NULL
++#define _DEFAULT_LPK_FILTER NULL
++#define _DEFAULT_LPK_TLS -1
++#define _DEFAULT_LPK_BTIMEOUT 10
++#define _DEFAULT_LPK_STIMEOUT 10
++#define _DEFAULT_LPK_LDP NULL
++
++/* flags */
++#define FLAG_EMPTY	    0x00000000
++#define FLAG_CONNECTED	    0x00000001
++
++/* flag macros */
++#define FLAG_SET_EMPTY(x)		x&=(FLAG_EMPTY)
++#define FLAG_SET_CONNECTED(x)		x|=(FLAG_CONNECTED)
++#define FLAG_SET_DISCONNECTED(x)	x&=~(FLAG_CONNECTED)
++
++/* defines */
++#define FAILURE -1
++#define SUCCESS 0
++#define PUBKEYATTR "sshPublicKey"
++
++/* 
++ *
++ * defined files path 
++ * (should be relocated to pathnames.h,
++ * if one day it's included within the tree) 
++ *
++ */
++#define _PATH_LDAP_CONFIG_FILE "/etc/ldap.conf"
++
++/* structures */
++typedef struct ldap_options {
++    int on;			/* Use it or NOT */
++    LDAP * ld;			/* LDAP file desc */
++    char * servers;		/* parsed servers for ldaplib failover handling */
++    char * u_basedn;		/* user basedn */
++    char * g_basedn;		/* group basedn */
++    char * binddn;		/* binddn */
++    char * bindpw;		/* bind password */
++    char * sgroup;		/* server group */
++    char * fgroup;		/* group filter */
++    char * filter;		/* additional filter */
++    char * l_conf;		/* use ldap.conf */
++    int tls;			/* TLS only */
++    struct timeval b_timeout;   /* bind timeout */
++    struct timeval s_timeout;   /* search timeout */
++    unsigned int flags;		/* misc flags (reconnection, future use?) */
++} ldap_opt_t;
++
++typedef struct ldap_keys {
++    struct berval ** keys;	/* the public keys retrieved */
++    unsigned int num;		/* number of keys */
++} ldap_key_t;
++
++
++/* function headers */
++void ldap_close(ldap_opt_t *);
++int ldap_connect(ldap_opt_t *);
++char * ldap_parse_groups(const char *);
++char * ldap_parse_servers(const char *);
++void ldap_options_print(ldap_opt_t *);
++void ldap_options_free(ldap_opt_t *);
++void ldap_keys_free(ldap_key_t *);
++int ldap_parse_lconf(ldap_opt_t *);
++ldap_key_t * ldap_getuserkey(ldap_opt_t *, const char *);
++int ldap_ismember(ldap_opt_t *, const char *);
++
++#endif
+diff -Nuar --exclude '*.orig' --exclude '*.rej' lpk-user-example.txt lpk-user-example.txt
+--- lpk-user-example.txt	1969-12-31 16:00:00.000000000 -0800
++++ lpk-user-example.txt	2008-08-23 15:02:47.000000000 -0700
+@@ -0,0 +1,117 @@
++
++Post to ML -> User Made Quick Install Doc.
++Contribution from John Lane <john at lane.uk.net>
++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++
++OpenSSH LDAP keystore Patch
++===========================
++
++NOTE: these notes are a transcript of a specific installation
++      they work for me, your specifics may be different!
++      from John Lane March 17th 2005         john at lane.uk.net
++
++This is a patch to OpenSSH 4.0p1 to allow it to obtain users' public keys
++from their LDAP record as an alternative to ~/.ssh/authorized_keys.
++
++(Assuming here that necessary build stuff is in $BUILD)
++
++cd $BUILD/openssh-4.0p1
++patch -Np1 -i $BUILD/openssh-lpk-4.0p1-0.3.patch
++mkdir -p /var/empty &&
++./configure --prefix=/usr --sysconfdir=/etc/ssh \
++    --libexecdir=/usr/sbin --with-md5-passwords --with-pam \
++    --with-libs="-lldap" --with-cppflags="-DWITH_LDAP_PUBKEY"
++Now do.
++make &&
++make install
++
++Add the following config to /etc/ssh/ssh_config
++UseLPK yes
++LpkServers ldap://myhost.mydomain.com
++LpkUserDN  ou=People,dc=mydomain,dc=com
++
++We need to tell sshd about the SSL keys during boot, as root's
++environment does not exist at that time. Edit /etc/rc.d/init.d/sshd.
++Change the startup code from this:
++                echo "Starting SSH Server..."
++                loadproc /usr/sbin/sshd
++                ;;
++to this:
++                echo "Starting SSH Server..."
++                LDAPRC="/root/.ldaprc" loadproc /usr/sbin/sshd
++                ;;
++
++Re-start the sshd daemon:
++/etc/rc.d/init.d/sshd restart
++
++Install the additional LDAP schema
++cp $BUILD/openssh-lpk-0.2.schema  /etc/openldap/schema/openssh.schema
++
++Now add the openSSH LDAP schema to /etc/openldap/slapd.conf:
++Add the following to the end of the existing block of schema includes
++include         /etc/openldap/schema/openssh.schema
++
++Re-start the LDAP server:
++/etc/rc.d/init.d/slapd restart
++
++To add one or more public keys to a user, eg "testuser" :
++ldapsearch -x -W -Z -LLL -b "uid=testuser,ou=People,dc=mydomain,dc=com" -D
++"uid=testuser,ou=People,dc=mydomain,dc=com" > /tmp/testuser
++
++append the following to this /tmp/testuser file
++objectclass: ldapPublicKey
++sshPublicKey: ssh-rsa
++AAAAB3NzaC1yc2EAAAABJQAAAIB3dsrwqXqD7E4zYYrxwdDKBUQxKMioXy9pxFVai64kAPxjU9KS
++qIo7QfkjslfsjflksjfldfkjsldfjLX/5zkzRmT28I5piGzunPv17S89z8XwSsuAoR1t86t+5dlI
++7eZE/gVbn2UQkQq7+kdDTS2yXV6VnC52N/kKLG3ciBkBAw== General Purpose RSA Key
++
++Then do a modify:
++ldapmodify -x -D "uid=testuser,ou=People,dc=mydomain,dc=com" -W -f
++/tmp/testuser -Z
++Enter LDAP Password:
++modifying entry "uid=testuser,ou=People,dc=mydomain,dc=com"
++And check the modify is ok:
++ldapsearch -x -W -Z -b "uid=testuser,ou=People,dc=mydomain,dc=com" -D
++"uid=testuser,ou=People,dc=mydomain,dc=com"
++Enter LDAP Password:
++# extended LDIF
++#
++# LDAPv3
++# base <uid=testuser,ou=People,dc=mydomain,dc=com> with scope sub
++# filter: (objectclass=*)
++# requesting: ALL
++#
++
++# testuser, People, mydomain.com
++dn: uid=testuser,ou=People,dc=mydomain,dc=com
++uid: testuser
++cn: testuser
++objectClass: account
++objectClass: posixAccount
++objectClass: top
++objectClass: shadowAccount
++objectClass: ldapPublicKey
++shadowLastChange: 12757
++shadowMax: 99999
++shadowWarning: 7
++loginShell: /bin/bash
++uidNumber: 9999
++gidNumber: 501
++homeDirectory: /home/testuser
++userPassword:: e1NTSEF9UDgwV1hnM1VjUDRJK0k1YnFiL1d4ZUJObXlZZ3Z3UTU=
++sshPublicKey: ssh-rsa
++AAAAB3NzaC1yc2EAAAABJQAAAIB3dsrwqXqD7E4zYYrxwdDKBUQxKMioXy9pxFVai64kAPxjU9KSqIo7QfkjslfsjflksjfldfkjsldfjLX/5zkzRmT28I5piGzunPv17S89z
++8XwSsuAoR1t86t+5dlI7eZE/gVbn2UQkQq7+kdDTS2yXV6VnC52N/kKLG3ciBkBAw== General Purpose RSA Key
++
++# search result
++search: 3
++result: 0 Success
++
++# numResponses: 2
++# numEntries: 1
++
++Now start a ssh session to user "testuser" from usual ssh client (e.g.
++puTTY). Login should succeed.
++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+diff -Nuar --exclude '*.orig' --exclude '*.rej' Makefile.in Makefile.in
+--- Makefile.in	2008-07-08 07:21:12.000000000 -0700
++++ Makefile.in	2008-08-23 15:02:47.000000000 -0700
+@@ -86,7 +86,7 @@
+ 	auth-krb5.o \
+ 	auth2-gss.o gss-serv.o gss-serv-krb5.o \
+ 	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
+-	audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o
++	audit.o audit-bsm.o platform.o ldapauth.o sftp-server.o sftp-common.o
+ 
+ MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out
+ MANPAGES_IN	= moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
+diff -Nuar --exclude '*.orig' --exclude '*.rej' openssh-lpk_openldap.schema openssh-lpk_openldap.schema
+--- openssh-lpk_openldap.schema	1969-12-31 16:00:00.000000000 -0800
++++ openssh-lpk_openldap.schema	2008-08-23 15:02:47.000000000 -0700
+@@ -0,0 +1,19 @@
++#
++# LDAP Public Key Patch schema for use with openssh-ldappubkey
++# Author: Eric AUGE <eau at phear.org>
++# 
++# Based on the proposal of : Mark Ruijter
++#
++
++
++# octetString SYNTAX
++attributetype ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' 
++	DESC 'MANDATORY: OpenSSH Public key' 
++	EQUALITY octetStringMatch
++	SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
++
++# printableString SYNTAX yes|no
++objectclass ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
++	DESC 'MANDATORY: OpenSSH LPK objectclass'
++	MUST ( sshPublicKey $ uid ) 
++	)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' openssh-lpk_sun.schema openssh-lpk_sun.schema
+--- openssh-lpk_sun.schema	1969-12-31 16:00:00.000000000 -0800
++++ openssh-lpk_sun.schema	2008-08-23 15:02:47.000000000 -0700
+@@ -0,0 +1,21 @@
++#
++# LDAP Public Key Patch schema for use with openssh-ldappubkey
++# Author: Eric AUGE <eau at phear.org>
++# 
++# Schema for Sun Directory Server.
++# Based on the original schema, modified by Stefan Fischer.
++#
++
++dn: cn=schema
++
++# octetString SYNTAX
++attributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' 
++	DESC 'MANDATORY: OpenSSH Public key' 
++	EQUALITY octetStringMatch
++	SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
++
++# printableString SYNTAX yes|no
++objectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
++	DESC 'MANDATORY: OpenSSH LPK objectclass'
++	MUST ( sshPublicKey $ uid ) 
++	)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' README.lpk README.lpk
+--- README.lpk	1969-12-31 16:00:00.000000000 -0800
++++ README.lpk	2008-08-23 15:02:47.000000000 -0700
+@@ -0,0 +1,267 @@
++OpenSSH LDAP PUBLIC KEY PATCH 
++Copyright (c) 2003 Eric AUGE (eau at phear.org)
++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.
++3. The name of the author may not be used to endorse or promote products
++   derived from this software without specific prior written permission.
++
++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.
++
++purposes of this patch:
++
++This patch would help to have authentication centralization policy
++using ssh public key authentication.
++This patch could be an alternative to other "secure" authentication system
++working in a similar way (Kerberos, SecurID, etc...), except the fact 
++that it's based on OpenSSH and its public key abilities.
++
++>> FYI: <<
++'uid': means unix accounts existing on the current server
++'lpkServerGroup:' mean server group configured on the current server ('lpkServerGroup' in sshd_config)
++
++example schema:
++
++
++                                  server1 (uid: eau,rival,toto) (lpkServerGroup: unix)
++                ___________      /
++               /           \ --- - server3 (uid: eau, titi) (lpkServerGroup: unix)
++              | LDAP Server |    \
++	      | eau  ,rival |     server2 (uid: rival, eau) (lpkServerGroup: unix)
++	      | titi ,toto  |
++	      | userx,....  |         server5 (uid: eau)  (lpkServerGroup: mail)
++               \___________/ \       /
++	                       ----- - server4 (uid: eau, rival)  (no group configured)
++			             \
++				        etc...
++
++- WHAT WE NEED :
++
++  * configured LDAP server somewhere on the network (i.e. OpenLDAP)
++  * patched sshd (with this patch ;)
++  * LDAP user(/group) entry (look at users.ldif (& groups.ldif)):
++        User entry:
++	- attached to the 'ldapPublicKey' objectclass
++	- attached to the 'posixAccount' objectclass
++	- with a filled 'sshPublicKey' attribute 
++	Example:
++		dn: uid=eau,ou=users,dc=cuckoos,dc=net
++		objectclass: top
++		objectclass: person
++		objectclass: organizationalPerson
++		objectclass: posixAccount
++		objectclass: ldapPublicKey
++		description: Eric AUGE Account
++		userPassword: blah
++		cn: Eric AUGE
++		sn: Eric AUGE
++		uid: eau
++		uidNumber: 1034
++		gidNumber: 1
++		homeDirectory: /export/home/eau
++		sshPublicKey: ssh-dss AAAAB3...
++		sshPublicKey: ssh-dss AAAAM5...
++
++	Group entry:
++	- attached to the 'posixGroup' objectclass
++	- with a 'cn' groupname attribute
++	- with multiple 'memberUid' attributes filled with usernames allowed in this group
++	Example:
++		# few members
++		dn: cn=unix,ou=groups,dc=cuckoos,dc=net
++		objectclass: top
++		objectclass: posixGroup
++		description: Unix based servers group
++		cn: unix
++		gidNumber: 1002
++		memberUid: eau
++		memberUid: user1
++		memberUid: user2
++
++
++- HOW IT WORKS :
++
++  * without patch
++  If a user wants to authenticate to log in a server the sshd, will first look for authentication method allowed (RSAauth,kerberos,etc..)
++  and if RSAauth and tickets based auth fails, it will fallback to standard password authentication (if enabled).
++
++  * with the patch
++  If a user want to authenticate to log in a server, the sshd will first look for auth method including LDAP pubkey, if the ldappubkey options is enabled.
++  It will do an ldapsearch to get the public key directly from the LDAP instead of reading it from the server filesystem. 
++  (usually in $HOME/.ssh/authorized_keys)
++
++  If groups are enabled, it will also check if the user that wants to login is in the group of the server he is trying to log into.
++  If it fails, it falls back on RSA auth files ($HOME/.ssh/authorized_keys), etc.. and finally to standard password authentication (if enabled).
++
++  7 tokens are added to sshd_config :
++  # here is the new patched ldap related tokens
++  # entries in your LDAP must be posixAccount & strongAuthenticationUser & posixGroup
++  UseLPK yes								# look the pub key into LDAP
++  LpkServers ldap://10.31.32.5/ ldap://10.31.32.4 ldap://10.31.32.3	# which LDAP server for users ? (URL format)
++  LpkUserDN  ou=users,dc=foobar,dc=net					# which base DN for users ?
++  LpkGroupDN ou=groups,dc=foobar,dc=net					# which base DN for groups ? 
++  LpkBindDN cn=manager,dc=foobar,dc=net					# which bind DN ?
++  LpkBindPw asecret							# bind DN credidentials
++  LpkServerGroup agroupname						# the group the server is part of
++
++  Right now i'm using anonymous binding to get public keys, because getting public keys of someone doesn't impersonate him¸ but there is some
++  flaws you have to take care of.
++
++- HOW TO INSERT A USER/KEY INTO AN LDAP ENTRY
++
++  * my way (there is plenty :)
++  - create ldif file (i.e. users.ldif)
++  - cat ~/.ssh/id_dsa.pub OR cat ~/.ssh/id_rsa.pub OR cat ~/.ssh/identity.pub
++  - my way in 4 steps :
++  Example:
++
++  # you add this to the user entry in the LDIF file :
++  [...]
++  objectclass: posixAccount
++  objectclass: ldapPublicKey
++  [...]
++  sshPubliKey: ssh-dss AAAABDh12DDUR2...
++  [...]
++
++  # insert your entry and you're done :)
++  ldapadd -D balblabla -w bleh < file.ldif 
++  
++  all standard options can be present in the 'sshPublicKey' attribute.
++
++- WHY :
++
++  Simply because, i was looking for a way to centralize all sysadmins authentication, easily,  without completely using LDAP 
++  as authentication method (like pam_ldap etc..).  
++  
++  After looking into Kerberos, SecurID, and other centralized secure authentications systems, the use of RSA and LDAP to get 
++  public key for authentication allows us to control who has access to which server (the user needs an account and to be in 'strongAuthenticationUser'
++  objectclass within LDAP and part of the group the SSH server is in). 
++
++  Passwords update are no longer a nightmare for a server farm (key pair passphrase is stored on each user's box and private key is locally encrypted using his passphrase 
++  so each user can change it as much as he wants). 
++
++  Blocking a user account can be done directly from the LDAP (if sshd is using RSAAuth + ldap only).
++
++- RULES :  
++  Entry in the LDAP server must respect 'posixAccount' and 'ldapPublicKey' which are defined in core.schema. 
++  and the additionnal lpk.schema.
++
++  This patch could allow a smooth transition between standard auth (/etc/passwd) and complete LDAP based authentication 
++  (pamldap, nss_ldap, etc..).
++
++  This can be an alternative to other (old?/expensive?) authentication methods (Kerberos/SecurID/..).
++  
++  Referring to schema at the beginning of this file if user 'eau' is only in group 'unix'
++  'eau' would ONLY access 'server1', 'server2', 'server3' AND 'server4' BUT NOT 'server5'.
++  If you then modify the LDAP 'mail' group entry to add 'memberUid: eau' THEN user 'eau' would be able
++  to log in 'server5' (i hope you got the idea, my english is bad :).
++
++  Each server's sshd is patched and configured to ask the public key and the group infos in the LDAP
++  server.
++  When you want to allow a new user to have access to the server parc, you just add him an account on 
++  your servers, you add his public key into his entry on the LDAP server, it's done. 
++
++  Because sshds are looking public keys into the LDAP directly instead of a file ($HOME/.ssh/authorized_keys).
++
++  When the user needs to change his passphrase he can do it directly from his workstation by changing 
++  his own key set lock passphrase, and all servers are automatically aware.
++ 
++  With a CAREFUL LDAP server configuration you could allow a user to add/delete/modify his own entry himself
++  so he can add/modify/delete himself his public key when needed.
++
++­ FLAWS :
++  LDAP must be well configured, getting the public key of some user is not a problem, but if anonymous LDAP 
++  allow write to users dn, somebody could replace someuser's public key by its own and impersonate some 
++  of your users in all your server farm be VERY CAREFUL.
++  
++  MITM attack when sshd is requesting the public key, could lead to a compromise of your servers allowing login 
++  as the impersonnated user.
++
++  If LDAP server is down then, fallback on passwd auth.
++  
++  the ldap code part has not been well audited yet.
++
++- LDAP USER ENTRY EXAMPLES (LDIF Format, look in users.ldif)
++    --- CUT HERE ---
++    dn: uid=jdoe,ou=users,dc=foobar,dc=net
++    objectclass: top
++    objectclass: person
++    objectclass: organizationalPerson
++    objectclass: posixAccount
++    objectclass: ldapPublicKey
++    description: My account
++    cn: John Doe
++    sn: John Doe
++    uid: jdoe
++    uidNumber: 100
++    gidNumber: 100
++    homeDirectory: /home/jdoe
++    sshPublicKey: ssh-dss AAAAB3NzaC1kc3MAAAEBAOvL8pREUg9wSy/8+hQJ54YF3AXkB0OZrXB....
++    [...]
++    --- CUT HERE ---
++
++- LDAP GROUP ENTRY EXAMPLES (LDIF Format, look in groups.ldif)
++    --- CUT HERE ---
++    dn: cn=unix,ou=groups,dc=cuckoos,dc=net
++    objectclass: top
++    objectclass: posixGroup
++    description: Unix based servers group
++    cn: unix
++    gidNumber: 1002
++    memberUid: jdoe
++    memberUid: user1
++    memberUid: user2
++    [...]
++    --- CUT HERE ---
++
++>> FYI: << 
++Multiple 'sshPublicKey' in a user entry are allowed, as well as multiple 'memberUid' attributes in a group entry
++
++- COMPILING:
++  1. Apply the patch
++  2. ./configure --with-your-options --with-ldap=/prefix/to/ldap_libs_and_includes
++  3. make
++  4. it's done.
++
++- BLA :
++  I hope this could help, and i hope to be clear enough,, or give ideas.  questions/comments/improvements are welcome.
++  
++- TODO :
++  Redesign differently.
++
++- DOCS/LINK :
++  http://pacsec.jp/core05/psj05-barisani-en.pdf
++  http://fritz.potsdam.edu/projects/openssh-lpk/
++  http://fritz.potsdam.edu/projects/sshgate/
++  http://dev.inversepath.com/trac/openssh-lpk
++  http://lam.sf.net/ ( http://lam.sourceforge.net/documentation/supportedSchemas.htm )
++
++- CONTRIBUTORS/IDEAS/GREETS :
++  - Falk Siemonsmeier.
++  - Jacob Rief.
++  - Michael Durchgraf.
++  - frederic peters.
++  - Finlay dobbie.
++  - Stefan Fisher.
++  - Robin H. Johnson.
++  - Adrian Bridgett.
++
++- CONTACT :
++  - Eric AUGE <eau at phear.org>
++  - Andrea Barisani <andrea at inversepath.com>
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' servconf.h servconf.h
+--- servconf.h	2008-06-10 06:01:51.000000000 -0700
++++ servconf.h	2008-08-23 15:02:47.000000000 -0700
+@@ -16,6 +16,10 @@
+ #ifndef SERVCONF_H
+ #define SERVCONF_H
+ 
++#ifdef WITH_LDAP_PUBKEY
++#include "ldapauth.h"
++#endif
++
+ #define MAX_PORTS		256	/* Max # ports. */
+ 
+ #define MAX_ALLOW_USERS		256	/* Max # users on allow list. */
+@@ -145,6 +149,9 @@
+ 	int	use_pam;		/* Enable auth via PAM */
+ 
+ 	int	permit_tun;
++#ifdef WITH_LDAP_PUBKEY
++        ldap_opt_t lpk;
++#endif
+ 
+ 	int	num_permitted_opens;
+ 
+diff -Nuar --exclude '*.orig' --exclude '*.rej' sshd.c sshd.c
+--- sshd.c	2008-07-11 00:36:49.000000000 -0700
++++ sshd.c	2008-08-23 15:02:47.000000000 -0700
+@@ -127,6 +127,10 @@
+ int deny_severity;
+ #endif /* LIBWRAP */
+ 
++#ifdef WITH_LDAP_PUBKEY
++#include "ldapauth.h"
++#endif
++
+ #ifndef O_NOCTTY
+ #define O_NOCTTY	0
+ #endif
+@@ -1484,6 +1488,16 @@
+ 		exit(1);
+ 	}
+ 
++#ifdef WITH_LDAP_PUBKEY
++    /* ldap_options_print(&options.lpk); */
++    /* XXX initialize/check ldap connection and set *LD */
++    if (options.lpk.on) {
++        if (options.lpk.l_conf && (ldap_parse_lconf(&options.lpk) < 0) )
++            error("[LDAP] could not parse %s", options.lpk.l_conf);
++        if (ldap_connect(&options.lpk) < 0)
++            error("[LDAP] could not initialize ldap connection");
++    }
++#endif
+ 	debug("sshd version %.100s", SSH_RELEASE);
+ 
+ 	/* Store privilege separation user for later use if required. */
+diff -Nuar --exclude '*.orig' --exclude '*.rej' sshd_config sshd_config
+--- sshd_config	2008-07-02 05:35:43.000000000 -0700
++++ sshd_config	2008-08-23 15:02:47.000000000 -0700
+@@ -109,6 +109,21 @@
+ # no default banner path
+ #Banner none
+ 
++# here are the new patched ldap related tokens
++# entries in your LDAP must have posixAccount & ldapPublicKey objectclass
++#UseLPK yes
++#LpkLdapConf /etc/ldap.conf
++#LpkServers  ldap://10.1.7.1/ ldap://10.1.7.2/
++#LpkUserDN   ou=users,dc=phear,dc=org
++#LpkGroupDN  ou=groups,dc=phear,dc=org
++#LpkBindDN cn=Manager,dc=phear,dc=org
++#LpkBindPw secret
++#LpkServerGroup mail
++#LpkFilter (hostAccess=master.phear.org)
++#LpkForceTLS no
++#LpkSearchTimelimit 3
++#LpkBindTimelimit 3
++
+ # override default of no subsystems
+ Subsystem	sftp	/usr/libexec/sftp-server
+ 
+diff -Nuar --exclude '*.orig' --exclude '*.rej' sshd_config.5 sshd_config.5
+--- sshd_config.5	2008-07-02 05:35:43.000000000 -0700
++++ sshd_config.5	2008-08-23 15:02:47.000000000 -0700
+@@ -1003,6 +1003,62 @@
+ program.
+ The default is
+ .Pa /usr/X11R6/bin/xauth .
++.It Cm UseLPK
++Specifies whether LDAP public key retrieval must be used or not. It allow
++an easy centralisation of public keys within an LDAP directory. The argument must be
++.Dq yes
++or
++.Dq no .
++.It Cm LpkLdapConf
++Specifies whether LDAP Public keys should parse the specified ldap.conf file
++instead of sshd_config Tokens. The argument must be a valid path to an ldap.conf
++file like
++.Pa /etc/ldap.conf
++.It Cm LpkServers
++Specifies LDAP one or more [:space:] separated server's url the following form may be used:
++.Pp
++LpkServers ldaps://127.0.0.1 ldap://127.0.0.2 ldap://127.0.0.3
++.It Cm LpkUserDN
++Specifies the LDAP user DN.
++.Pp
++LpkUserDN ou=users,dc=phear,dc=org
++.It Cm LpkGroupDN
++Specifies the LDAP groups DN.
++.Pp
++LpkGroupDN ou=groups,dc=phear,dc=org
++.It Cm LpkBindDN
++Specifies the LDAP bind DN to use if necessary.
++.Pp
++LpkBindDN cn=Manager,dc=phear,dc=org
++.It Cm LpkBindPw
++Specifies the LDAP bind credential. 
++.Pp
++LpkBindPw secret
++.It Cm LpkServerGroup
++Specifies one or more [:space:] separated group the server is part of. 
++.Pp
++LpkServerGroup unix mail prod
++.It Cm LpkFilter
++Specifies an additional LDAP filter to use for finding SSH keys
++.Pp
++LpkFilter (hostAccess=master.phear.org)
++.It Cm LpkForceTLS
++Specifies if the LDAP server connection must be tried, forced or not used. The argument must be 
++.Dq yes
++or
++.Dq no
++or
++.Dq try .
++.It Cm LpkSearchTimelimit
++Sepcifies the search time limit before the search is considered over. value is
++in seconds.
++.Pp
++LpkSearchTimelimit 3
++.It Cm LpkBindTimelimit
++Sepcifies the bind time limit before the connection is considered dead. value is
++in seconds.
++.Pp
++LpkBindTimelimit 3
+ .El
+ .Sh TIME FORMATS
+ .Xr sshd 8
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/files/lpk+hpn-servconf.c.patch /usr/home/dindin/workspace/openssh-portable/files/lpk+hpn-servconf.c.patch
--- /usr/ports/security/openssh-portable/files/lpk+hpn-servconf.c.patch	1970-01-01 03:00:00.000000000 +0300
+++ /usr/home/dindin/workspace/openssh-portable/files/lpk+hpn-servconf.c.patch	2009-05-26 18:10:08.000000000 +0400
@@ -0,0 +1,307 @@
+--- servconf.c.orig	2009-05-26 15:13:32.000000000 +0400
++++ servconf.c	2009-05-26 18:09:30.000000000 +0400
+@@ -42,6 +42,10 @@
+ #include "channels.h"
+ #include "groupaccess.h"
+ 
++#ifdef WITH_LDAP_PUBKEY
++#include "ldapauth.h"
++#endif
++
+ static void add_listen_addr(ServerOptions *, char *, int);
+ static void add_one_listen_addr(ServerOptions *, char *, int);
+ 
+@@ -128,11 +132,38 @@
+ 	options->adm_forced_command = NULL;
+ 	options->chroot_directory = NULL;
+ 	options->zero_knowledge_password_authentication = -1;
++	options->none_enabled = -1;
++	options->tcp_rcv_buf_poll = -1;
++	options->hpn_disabled = -1;
++	options->hpn_buffer_size = -1;
++#ifdef WITH_LDAP_PUBKEY
++ 	/* XXX dirty */
++ 	options->lpk.ld = NULL;
++ 	options->lpk.on = -1;
++ 	options->lpk.servers = NULL;
++ 	options->lpk.u_basedn = NULL;
++ 	options->lpk.g_basedn = NULL;
++ 	options->lpk.binddn = NULL;
++ 	options->lpk.bindpw = NULL;
++ 	options->lpk.sgroup = NULL;
++ 	options->lpk.filter = NULL;
++ 	options->lpk.fgroup = NULL;
++ 	options->lpk.l_conf = NULL;
++ 	options->lpk.tls = -1;
++ 	options->lpk.b_timeout.tv_sec = -1;
++ 	options->lpk.s_timeout.tv_sec = -1;
++ 	options->lpk.flags = FLAG_EMPTY;
++#endif
+ }
+ 
+ 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 = 1;
+@@ -265,6 +296,68 @@
+ 		options->permit_tun = SSH_TUNMODE_NO;
+ 	if (options->zero_knowledge_password_authentication == -1)
+ 		options->zero_knowledge_password_authentication = 0;
++	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;
++	}
++
++#ifdef WITH_LDAP_PUBKEY
++	if (options->lpk.on == -1)
++	    options->lpk.on = _DEFAULT_LPK_ON;
++	if (options->lpk.servers == NULL)
++	    options->lpk.servers = _DEFAULT_LPK_SERVERS;
++	if (options->lpk.u_basedn == NULL)
++	    options->lpk.u_basedn = _DEFAULT_LPK_UDN;
++	if (options->lpk.g_basedn == NULL)
++	    options->lpk.g_basedn = _DEFAULT_LPK_GDN;
++	if (options->lpk.binddn == NULL)
++	    options->lpk.binddn = _DEFAULT_LPK_BINDDN;
++	if (options->lpk.bindpw == NULL)
++	    options->lpk.bindpw = _DEFAULT_LPK_BINDPW;
++	if (options->lpk.sgroup == NULL)
++	    options->lpk.sgroup = _DEFAULT_LPK_SGROUP;
++	if (options->lpk.filter == NULL)
++	    options->lpk.filter = _DEFAULT_LPK_FILTER;
++	if (options->lpk.tls == -1)
++	    options->lpk.tls = _DEFAULT_LPK_TLS;
++	if (options->lpk.b_timeout.tv_sec == -1)
++	    options->lpk.b_timeout.tv_sec = _DEFAULT_LPK_BTIMEOUT;
++	if (options->lpk.s_timeout.tv_sec == -1)
++	    options->lpk.s_timeout.tv_sec = _DEFAULT_LPK_STIMEOUT;
++	if (options->lpk.l_conf == NULL)
++	    options->lpk.l_conf = _DEFAULT_LPK_LDP;
++#endif
+ 
+ 	/* Turn privilege separation on by default */
+ 	if (use_privsep == -1)
+@@ -310,7 +403,14 @@
+ 	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
+ 	sUsePrivilegeSeparation, sAllowAgentForwarding,
+ 	sZeroKnowledgePasswordAuthentication,
++	sNoneEnabled, sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize,
+ 	sDeprecated, sUnsupported
++#ifdef WITH_LDAP_PUBKEY
++	,sLdapPublickey, sLdapServers, sLdapUserDN
++	,sLdapGroupDN, sBindDN, sBindPw, sMyGroup
++	,sLdapFilter, sForceTLS, sBindTimeout
++	,sSearchTimeout, sLdapConf
++#endif
+ } ServerOpCodes;
+ 
+ #define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
+@@ -421,6 +521,20 @@
+ 	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
+ 	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
+ 	{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
++#ifdef WITH_LDAP_PUBKEY
++	{ _DEFAULT_LPK_TOKEN, sLdapPublickey, SSHCFG_GLOBAL },
++	{ _DEFAULT_SRV_TOKEN, sLdapServers, SSHCFG_GLOBAL },
++	{ _DEFAULT_USR_TOKEN, sLdapUserDN, SSHCFG_GLOBAL },
++	{ _DEFAULT_GRP_TOKEN, sLdapGroupDN, SSHCFG_GLOBAL },
++	{ _DEFAULT_BDN_TOKEN, sBindDN, SSHCFG_GLOBAL },
++	{ _DEFAULT_BPW_TOKEN, sBindPw, SSHCFG_GLOBAL },
++	{ _DEFAULT_MYG_TOKEN, sMyGroup, SSHCFG_GLOBAL },
++	{ _DEFAULT_FIL_TOKEN, sLdapFilter, SSHCFG_GLOBAL },
++	{ _DEFAULT_TLS_TOKEN, sForceTLS, SSHCFG_GLOBAL },
++	{ _DEFAULT_BTI_TOKEN, sBindTimeout, SSHCFG_GLOBAL },
++	{ _DEFAULT_STI_TOKEN, sSearchTimeout, SSHCFG_GLOBAL },
++	{ _DEFAULT_LDP_TOKEN, sLdapConf, SSHCFG_GLOBAL },
++#endif
+ 	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
+ 	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
+ 	{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
+@@ -428,6 +542,10 @@
+ 	{ "permitopen", sPermitOpen, SSHCFG_ALL },
+ 	{ "forcecommand", sForceCommand, SSHCFG_ALL },
+ 	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
++	{ "noneenabled", sNoneEnabled },
++	{ "hpndisabled", sHPNDisabled },
++	{ "hpnbuffersize", sHPNBufferSize },
++	{ "tcprcvbufpoll", sTcpRcvBufPoll },
+ 	{ NULL, sBadOption, 0 }
+ };
+ 
+@@ -454,6 +572,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;
+ 		}
+@@ -851,6 +970,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;
+@@ -1311,6 +1446,107 @@
+ 		while (arg)
+ 		    arg = strdelim(&cp);
+ 		break;
++#ifdef WITH_LDAP_PUBKEY
++	case sLdapPublickey:
++		intptr = &options->lpk.on;
++		goto parse_flag;
++	case sLdapServers:
++		/* arg = strdelim(&cp); */
++		p = line;
++		while(*p++);
++		arg = p;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing ldap server",filename,linenum);
++		arg[strlen(arg)] = '\0';
++		if ((options->lpk.servers = ldap_parse_servers(arg)) == NULL)
++		    fatal("%s line %d: error in ldap servers", filename, linenum);
++		memset(arg,0,strlen(arg));
++		break;
++	case sLdapUserDN:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing ldap server",filename,linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.u_basedn = xstrdup(arg);
++		memset(arg,0,strlen(arg));
++		break;
++	case sLdapGroupDN:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing ldap server",filename,linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.g_basedn = xstrdup(arg);
++		memset(arg,0,strlen(arg));
++		break;
++	case sBindDN:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing binddn",filename,linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.binddn = xstrdup(arg);
++		memset(arg,0,strlen(arg));
++		break;
++	case sBindPw:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing bindpw",filename,linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.bindpw = xstrdup(arg);
++		memset(arg,0,strlen(arg));
++		break;
++	case sMyGroup:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing groupname",filename, linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.sgroup = xstrdup(arg);
++		if (options->lpk.sgroup)
++		    options->lpk.fgroup = ldap_parse_groups(options->lpk.sgroup);
++		memset(arg,0,strlen(arg));
++		break;
++	case sLdapFilter:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing filter",filename, linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.filter = xstrdup(arg);
++		memset(arg,0,strlen(arg));
++		break;
++	case sForceTLS:
++		intptr = &options->lpk.tls;
++		arg = strdelim(&cp);
++		if (!arg || *arg == '\0')
++			fatal("%s line %d: missing yes/no argument.",
++			    filename, linenum);
++		value = 0;	/* silence compiler */
++		if (strcmp(arg, "yes") == 0)
++			value = 1;
++		else if (strcmp(arg, "no") == 0)
++			value = 0;
++		else if (strcmp(arg, "try") == 0)
++			value = -1;
++		else
++			fatal("%s line %d: Bad yes/no argument: %s",
++				filename, linenum, arg);
++		if (*intptr == -1)
++			*intptr = value;
++		break;
++	case sBindTimeout:
++		intptr = (int *) &options->lpk.b_timeout.tv_sec;
++		goto parse_int;
++	case sSearchTimeout:
++		intptr = (int *) &options->lpk.s_timeout.tv_sec;
++		goto parse_int;
++		break;
++	case sLdapConf:
++		arg = cp;
++		if (!arg || *arg == '\0')
++		    fatal("%s line %d: missing LpkLdapConf", filename, linenum);
++		arg[strlen(arg)] = '\0';
++		options->lpk.l_conf = xstrdup(arg);
++		memset(arg, 0, strlen(arg));
++		break;
++#endif
+ 
+ 	default:
+ 		fatal("%s line %d: Missing handler for opcode %s (%d)",
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/files/openssh-5.2p1-hpn-servconf.patch /usr/home/dindin/workspace/openssh-portable/files/openssh-5.2p1-hpn-servconf.patch
--- /usr/ports/security/openssh-portable/files/openssh-5.2p1-hpn-servconf.patch	2009-05-15 15:00:27.000000000 +0400
+++ /usr/home/dindin/workspace/openssh-portable/files/openssh-5.2p1-hpn-servconf.patch	1970-01-01 03:00:00.000000000 +0300
@@ -1,32 +0,0 @@
---- servconf.c.orig	2009-05-02 18:22:38.000000000 +0400
-+++ servconf.c	2009-05-02 18:24:15.000000000 +0400
-@@ -127,12 +127,21 @@
- 	options->num_permitted_opens = -1;
- 	options->adm_forced_command = NULL;
- 	options->chroot_directory = NULL;
-+ 	options->none_enabled = -1;
-+ 	options->tcp_rcv_buf_poll = -1;
-+ 	options->hpn_disabled = -1;
-+ 	options->hpn_buffer_size = -1;
- 	options->zero_knowledge_password_authentication = -1;
- }
- 
- 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 = 1;
-@@ -345,6 +354,7 @@
- 	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
- 	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
- 	sUsePrivilegeSeparation, sAllowAgentForwarding,
-+ 	sNoneEnabled, sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize,
- 	sZeroKnowledgePasswordAuthentication,
- 	sDeprecated, sUnsupported
- } ServerOpCodes;
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/files/openssh-5.2p1-hpn.patch /usr/home/dindin/workspace/openssh-portable/files/openssh-5.2p1-hpn.patch
--- /usr/ports/security/openssh-portable/files/openssh-5.2p1-hpn.patch	2009-05-17 07:00:11.000000000 +0400
+++ /usr/home/dindin/workspace/openssh-portable/files/openssh-5.2p1-hpn.patch	1970-01-01 03:00:00.000000000 +0300
@@ -1,2196 +0,0 @@
-diff -urN HPN-README HPN-README
---- HPN-README	1970-01-01 03:00:00.000000000 +0300
-+++ HPN-README	2009-05-02 17:38:18.000000000 +0400
-@@ -0,0 +1,128 @@
-+Notes:
-+
-+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 at host.com
-+		scp -oCipher=aes256-ctr file you at host.com:~/file
-+
-+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. 
-+
-+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. 
-+
-+http://www.psc.edu/networking/projects/hpn-ssh
-+
-+BUFFER SIZES:
-+
-+If HPN is disabled the receive buffer size will be set to the 
-+OpenSSH default of 64K.
-+
-+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.
-+
-+If an HPN to HPN connection is established a number of different things might
-+happen based on the user options and conditions. 
-+
-+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. 
-+
-+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
-+
-+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).
-+
-+Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf SET
-+HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. 
-+Generally there is no need to set both.
-+
-+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. 
-+
-+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.
-+
-+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.
-+
-+
-+HPN Specific Configuration options
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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.
-+
-+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. 
-+
-+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.
-+
-+
-+Credits: This patch was conceived, designed, and led by Chris Rapier (rapier at psc.edu)
-+         The majority of the actual coding for versions up to HPN12v1 was performed
-+         by Michael Stevens (mstevens at andrew.cmu.edu). The MT-AES-CTR cipher was 
-+	 implemented by Ben Bennet (ben at psc.edu). This work was financed, in part,
-+         by Cisco System, Inc., the National Library of Medicine, 
-+	 and the National Science Foundation. 
-diff -urN Makefile.in Makefile.in
---- Makefile.in	2009-05-02 17:37:11.000000000 +0400
-+++ Makefile.in	2009-05-02 17:38:18.000000000 +0400
-@@ -43,7 +43,7 @@
- LD=@LD@
- CFLAGS=@CFLAGS@
- CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
--LIBS=@LIBS@
-+LIBS=@LIBS@ -lpthread
- SSHDLIBS=@SSHDLIBS@
- LIBEDIT=@LIBEDIT@
- AR=@AR@
-@@ -64,7 +64,7 @@
- 
- LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
- 	canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
--	cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
-+	cipher-bf1.o cipher-ctr.o cipher-ctr-mt.o cipher-3des1.o cleanup.o \
- 	compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
- 	log.o match.o md-sha256.o moduli.o nchan.o packet.o \
- 	readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \
-diff -urN auth2.c auth2.c
---- auth2.c	2009-05-02 17:37:11.000000000 +0400
-+++ auth2.c	2009-05-02 17:38:18.000000000 +0400
-@@ -50,6 +50,7 @@
- #include "dispatch.h"
- #include "pathnames.h"
- #include "buffer.h"
-+#include "canohost.h"
- 
- #ifdef GSSAPI
- #include "ssh-gss.h"
-@@ -76,6 +77,9 @@
- extern Authmethod method_jpake;
- #endif
- 
-+static int log_flag = 0;
-+
-+
- Authmethod *authmethods[] = {
- 	&method_none,
- 	&method_pubkey,
-@@ -233,6 +237,11 @@
- 	service = packet_get_string(NULL);
- 	method = packet_get_string(NULL);
- 	debug("userauth-request for user %s service %s method %s", user, service, method);
-+	if (!log_flag) {
-+		logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", 
-+		      get_remote_ipaddr(), get_remote_port(), user);
-+		log_flag = 1;
-+	}
- 	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
- 
- 	if ((style = strchr(user, ':')) != NULL)
-diff -urN buffer.c buffer.c
---- buffer.c	2006-08-05 06:39:39.000000000 +0400
-+++ buffer.c	2009-05-02 17:38:18.000000000 +0400
-@@ -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 -urN buffer.h buffer.h
---- buffer.h	2008-05-19 08:59:37.000000000 +0400
-+++ buffer.h	2009-05-02 17:38:18.000000000 +0400
-@@ -16,6 +16,9 @@
- #ifndef BUFFER_H
- #define BUFFER_H
- 
-+/* 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 -urN channels.c channels.c
---- channels.c	2009-02-14 08:28:21.000000000 +0300
-+++ channels.c	2009-05-02 17:41:46.000000000 +0400
-@@ -169,8 +169,14 @@
- static int connect_next(struct channel_connect *);
- static void channel_connect_ctx_free(struct channel_connect *);
- 
-+
-+static int hpn_disabled = 0;
-+static int hpn_buffer_size = 2 * 1024 * 1024;
-+
- /* -- channel core */
- 
-+
-+
- Channel *
- channel_by_id(int id)
- {
-@@ -308,6 +314,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;
-@@ -798,11 +805,35 @@
- 		FD_SET(c->sock, writeset);
- }
- 
-+int channel_tcpwinsz () {
-+        u_int32_t tcpwinsz = 0;
-+        socklen_t optsz = sizeof(tcpwinsz);
-+	int ret = -1;
-+
-+	/* 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;
-+	debug2("tcpwinsz: %d for connection: %d", tcpwinsz, 
-+	       packet_get_connection_in());
-+	return(tcpwinsz);
-+}
-+
- 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 &&
-@@ -1759,14 +1790,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;
-@@ -1969,11 +2007,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];
-@@ -2013,7 +2052,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);
- 				}
-@@ -2043,7 +2082,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;
- 			}
-@@ -2078,12 +2117,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);
- }
- 
- 
-@@ -2459,6 +2499,15 @@
- 	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);
-+}
-+
- static int
- channel_setup_fwd_listener(int type, const char *listen_addr,
-     u_short listen_port, int *allocated_listen_port,
-@@ -2610,9 +2659,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_port = listen_port;
-@@ -3151,10 +3206,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 -urN channels.h channels.h
---- channels.h	2009-02-14 08:28:21.000000000 +0300
-+++ channels.h	2009-05-02 17:38:18.000000000 +0400
-@@ -115,8 +115,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 */
- 
-@@ -146,9 +148,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)
-+
- #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)
-+
- #define CHAN_X11_PACKET_DEFAULT	(16*1024)
- #define CHAN_X11_WINDOW_DEFAULT	(4*CHAN_X11_PACKET_DEFAULT)
- 
-@@ -221,7 +225,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);
-@@ -277,4 +281,7 @@
- void	 chan_write_failed(Channel *);
- void	 chan_obuf_empty(Channel *);
- 
-+/* hpn handler */
-+void     channel_set_hpn(int, int);
-+
- #endif
-diff -urN cipher-ctr-mt.c cipher-ctr-mt.c
---- cipher-ctr-mt.c	1970-01-01 03:00:00.000000000 +0300
-+++ cipher-ctr-mt.c	2009-05-02 17:38:18.000000000 +0400
-@@ -0,0 +1,473 @@
-+/*
-+ * OpenSSH Multi-threaded AES-CTR Cipher
-+ *
-+ * Author: Benjamin Bennett <ben at psc.edu>
-+ * Copyright (c) 2008 Pittsburgh Supercomputing Center. All rights reserved.
-+ *
-+ * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged,
-+ * Copyright (c) 2003 Markus Friedl <markus at openbsd.org>
-+ *
-+ * 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.
-+ */
-+#include "includes.h"
-+
-+#include <sys/types.h>
-+
-+#include <stdarg.h>
-+#include <string.h>
-+
-+#include <openssl/evp.h>
-+
-+#include "xmalloc.h"
-+#include "log.h"
-+
-+/* compatibility with old or broken OpenSSL versions */
-+#include "openbsd-compat/openssl-compat.h"
-+
-+#ifndef USE_BUILTIN_RIJNDAEL
-+#include <openssl/aes.h>
-+#endif
-+
-+#include <pthread.h>
-+
-+/*-------------------- TUNABLES --------------------*/
-+/* Number of pregen threads to use */
-+#define CIPHER_THREADS	2
-+
-+/* Number of keystream queues */
-+#define NUMKQ		(CIPHER_THREADS + 2)
-+
-+/* Length of a keystream queue */
-+#define KQLEN		4096
-+
-+/* Processor cacheline length */
-+#define CACHELINE_LEN	64
-+
-+/* Collect thread stats and print at cancellation when in debug mode */
-+/* #define CIPHER_THREAD_STATS */
-+
-+/* Use single-byte XOR instead of 8-byte XOR */
-+/* #define CIPHER_BYTE_XOR */
-+/*-------------------- END TUNABLES --------------------*/
-+
-+
-+const EVP_CIPHER *evp_aes_ctr_mt(void);
-+
-+#ifdef CIPHER_THREAD_STATS
-+/*
-+ * Struct to collect thread stats
-+ */
-+struct thread_stats {
-+	u_int	fills;
-+	u_int	skips;
-+	u_int	waits;
-+	u_int	drains;
-+};
-+
-+/*
-+ * Debug print the thread stats
-+ * Use with pthread_cleanup_push for displaying at thread cancellation
-+ */
-+static void
-+thread_loop_stats(void *x)
-+{
-+	struct thread_stats *s = x;
-+
-+	debug("tid %lu - %u fills, %u skips, %u waits", pthread_self(),
-+			s->fills, s->skips, s->waits);
-+}
-+
-+ #define STATS_STRUCT(s)	struct thread_stats s
-+ #define STATS_INIT(s)		{ memset(&s, 0, sizeof(s)); }
-+ #define STATS_FILL(s)		{ s.fills++; }
-+ #define STATS_SKIP(s)		{ s.skips++; }
-+ #define STATS_WAIT(s)		{ s.waits++; }
-+ #define STATS_DRAIN(s)		{ s.drains++; }
-+#else
-+ #define STATS_STRUCT(s)
-+ #define STATS_INIT(s)
-+ #define STATS_FILL(s)
-+ #define STATS_SKIP(s)
-+ #define STATS_WAIT(s)
-+ #define STATS_DRAIN(s)
-+#endif
-+
-+/* Keystream Queue state */
-+enum {
-+	KQINIT,
-+	KQEMPTY,
-+	KQFILLING,
-+	KQFULL,
-+	KQDRAINING
-+};
-+
-+/* Keystream Queue struct */
-+struct kq {
-+	u_char		keys[KQLEN][AES_BLOCK_SIZE];
-+	u_char		ctr[AES_BLOCK_SIZE];
-+	u_char		pad0[CACHELINE_LEN];
-+	volatile int	qstate;
-+	pthread_mutex_t	lock;
-+	pthread_cond_t	cond;
-+	u_char		pad1[CACHELINE_LEN];
-+};
-+
-+/* Context struct */
-+struct ssh_aes_ctr_ctx
-+{
-+	struct kq	q[NUMKQ];
-+	AES_KEY		aes_ctx;
-+	STATS_STRUCT(stats);
-+	u_char		aes_counter[AES_BLOCK_SIZE];
-+	pthread_t	tid[CIPHER_THREADS];
-+	int		state;
-+	int		qidx;
-+	int		ridx;
-+};
-+
-+/* <friedl>
-+ * increment counter 'ctr',
-+ * the counter is of size 'len' bytes and stored in network-byte-order.
-+ * (LSB at ctr[len-1], MSB at ctr[0])
-+ */
-+static void
-+ssh_ctr_inc(u_char *ctr, u_int len)
-+{
-+	int i;
-+
-+	for (i = len - 1; i >= 0; i--)
-+		if (++ctr[i])	/* continue on overflow */
-+			return;
-+}
-+
-+/*
-+ * Add num to counter 'ctr'
-+ */
-+static void
-+ssh_ctr_add(u_char *ctr, uint32_t num, u_int len)
-+{
-+	int i;
-+	uint16_t n;
-+
-+	for (n = 0, i = len - 1; i >= 0 && (num || n); i--) {
-+		n = ctr[i] + (num & 0xff) + n;
-+		num >>= 8;
-+		ctr[i] = n & 0xff;
-+		n >>= 8;
-+	}
-+}
-+
-+/*
-+ * Threads may be cancelled in a pthread_cond_wait, we must free the mutex
-+ */
-+static void
-+thread_loop_cleanup(void *x)
-+{
-+	pthread_mutex_unlock((pthread_mutex_t *)x);
-+}
-+
-+/*
-+ * The life of a pregen thread:
-+ *    Find empty keystream queues and fill them using their counter.
-+ *    When done, update counter for the next fill.
-+ */
-+static void *
-+thread_loop(void *x)
-+{
-+	AES_KEY key;
-+	STATS_STRUCT(stats);
-+	struct ssh_aes_ctr_ctx *c = x;
-+	struct kq *q;
-+	int i;
-+	int qidx;
-+
-+	/* Threads stats on cancellation */
-+	STATS_INIT(stats);
-+#ifdef CIPHER_THREAD_STATS
-+	pthread_cleanup_push(thread_loop_stats, &stats);
-+#endif
-+
-+	/* Thread local copy of AES key */
-+	memcpy(&key, &c->aes_ctx, sizeof(key));
-+
-+	/*
-+	 * Handle the special case of startup, one thread must fill
-+ 	 * the first KQ then mark it as draining. Lock held throughout.
-+ 	 */
-+	if (pthread_equal(pthread_self(), c->tid[0])) {
-+		q = &c->q[0];
-+		pthread_mutex_lock(&q->lock);
-+		if (q->qstate == KQINIT) {
-+			for (i = 0; i < KQLEN; i++) {
-+				AES_encrypt(q->ctr, q->keys[i], &key);
-+				ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
-+			}
-+			ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
-+			q->qstate = KQDRAINING;
-+			STATS_FILL(stats);
-+			pthread_cond_broadcast(&q->cond);
-+		}
-+		pthread_mutex_unlock(&q->lock);
-+	}
-+	else 
-+		STATS_SKIP(stats);
-+
-+	/*
-+ 	 * Normal case is to find empty queues and fill them, skipping over
-+ 	 * queues already filled by other threads and stopping to wait for
-+ 	 * a draining queue to become empty.
-+ 	 *
-+ 	 * Multiple threads may be waiting on a draining queue and awoken
-+ 	 * when empty.  The first thread to wake will mark it as filling,
-+ 	 * others will move on to fill, skip, or wait on the next queue.
-+ 	 */
-+	for (qidx = 1;; qidx = (qidx + 1) % NUMKQ) {
-+		/* Check if I was cancelled, also checked in cond_wait */
-+		pthread_testcancel();
-+
-+		/* Lock queue and block if its draining */
-+		q = &c->q[qidx];
-+		pthread_mutex_lock(&q->lock);
-+		pthread_cleanup_push(thread_loop_cleanup, &q->lock);
-+		while (q->qstate == KQDRAINING || q->qstate == KQINIT) {
-+			STATS_WAIT(stats);
-+			pthread_cond_wait(&q->cond, &q->lock);
-+		}
-+		pthread_cleanup_pop(0);
-+
-+		/* If filling or full, somebody else got it, skip */
-+		if (q->qstate != KQEMPTY) {
-+			pthread_mutex_unlock(&q->lock);
-+			STATS_SKIP(stats);
-+			continue;
-+		}
-+
-+		/*
-+ 		 * Empty, let's fill it.
-+ 		 * Queue lock is relinquished while we do this so others
-+ 		 * can see that it's being filled.
-+ 		 */
-+		q->qstate = KQFILLING;
-+		pthread_mutex_unlock(&q->lock);
-+		for (i = 0; i < KQLEN; i++) {
-+			AES_encrypt(q->ctr, q->keys[i], &key);
-+			ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
-+		}
-+
-+		/* Re-lock, mark full and signal consumer */
-+		pthread_mutex_lock(&q->lock);
-+		ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
-+		q->qstate = KQFULL;
-+		STATS_FILL(stats);
-+		pthread_cond_signal(&q->cond);
-+		pthread_mutex_unlock(&q->lock);
-+	}
-+
-+#ifdef CIPHER_THREAD_STATS
-+	/* Stats */
-+	pthread_cleanup_pop(1);
-+#endif
-+
-+	return NULL;
-+}
-+
-+static int
-+ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
-+    u_int len)
-+{
-+	struct ssh_aes_ctr_ctx *c;
-+	struct kq *q, *oldq;
-+	int ridx;
-+	u_char *buf;
-+
-+	if (len == 0)
-+		return (1);
-+	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
-+		return (0);
-+
-+	q = &c->q[c->qidx];
-+	ridx = c->ridx;
-+
-+	/* src already padded to block multiple */
-+	while (len > 0) {
-+		buf = q->keys[ridx];
-+
-+#ifdef CIPHER_BYTE_XOR
-+		dest[0] = src[0] ^ buf[0];
-+		dest[1] = src[1] ^ buf[1];
-+		dest[2] = src[2] ^ buf[2];
-+		dest[3] = src[3] ^ buf[3];
-+		dest[4] = src[4] ^ buf[4];
-+		dest[5] = src[5] ^ buf[5];
-+		dest[6] = src[6] ^ buf[6];
-+		dest[7] = src[7] ^ buf[7];
-+		dest[8] = src[8] ^ buf[8];
-+		dest[9] = src[9] ^ buf[9];
-+		dest[10] = src[10] ^ buf[10];
-+		dest[11] = src[11] ^ buf[11];
-+		dest[12] = src[12] ^ buf[12];
-+		dest[13] = src[13] ^ buf[13];
-+		dest[14] = src[14] ^ buf[14];
-+		dest[15] = src[15] ^ buf[15];
-+#else
-+		*(uint64_t *)dest = *(uint64_t *)src ^ *(uint64_t *)buf;
-+		*(uint64_t *)(dest + 8) = *(uint64_t *)(src + 8) ^
-+						*(uint64_t *)(buf + 8);
-+#endif
-+
-+		dest += 16;
-+		src += 16;
-+		len -= 16;
-+		ssh_ctr_inc(ctx->iv, AES_BLOCK_SIZE);
-+
-+		/* Increment read index, switch queues on rollover */
-+		if ((ridx = (ridx + 1) % KQLEN) == 0) {
-+			oldq = q;
-+
-+			/* Mark next queue draining, may need to wait */
-+			c->qidx = (c->qidx + 1) % NUMKQ;
-+			q = &c->q[c->qidx];
-+			pthread_mutex_lock(&q->lock);
-+			while (q->qstate != KQFULL) {
-+				STATS_WAIT(c->stats);
-+				pthread_cond_wait(&q->cond, &q->lock);
-+			}
-+			q->qstate = KQDRAINING;
-+			pthread_mutex_unlock(&q->lock);
-+
-+			/* Mark consumed queue empty and signal producers */
-+			pthread_mutex_lock(&oldq->lock);
-+			oldq->qstate = KQEMPTY;
-+			STATS_DRAIN(c->stats);
-+			pthread_cond_broadcast(&oldq->cond);
-+			pthread_mutex_unlock(&oldq->lock);
-+		}
-+	}
-+	c->ridx = ridx;
-+	return (1);
-+}
-+
-+#define HAVE_NONE       0
-+#define HAVE_KEY        1
-+#define HAVE_IV         2
-+static int
-+ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
-+    int enc)
-+{
-+	struct ssh_aes_ctr_ctx *c;
-+	int i;
-+
-+	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
-+		c = xmalloc(sizeof(*c));
-+
-+		c->state = HAVE_NONE;
-+		for (i = 0; i < NUMKQ; i++) {
-+			pthread_mutex_init(&c->q[i].lock, NULL);
-+			pthread_cond_init(&c->q[i].cond, NULL);
-+		}
-+
-+		STATS_INIT(c->stats);
-+		
-+		EVP_CIPHER_CTX_set_app_data(ctx, c);
-+	}
-+
-+	if (c->state == (HAVE_KEY | HAVE_IV)) {
-+		/* Cancel pregen threads */
-+		for (i = 0; i < CIPHER_THREADS; i++)
-+			pthread_cancel(c->tid[i]);
-+		for (i = 0; i < CIPHER_THREADS; i++)
-+			pthread_join(c->tid[i], NULL);
-+		/* Start over getting key & iv */
-+		c->state = HAVE_NONE;
-+	}
-+
-+	if (key != NULL) {
-+		AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
-+		    &c->aes_ctx);
-+		c->state |= HAVE_KEY;
-+	}
-+
-+	if (iv != NULL) {
-+		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
-+		c->state |= HAVE_IV;
-+	}
-+
-+	if (c->state == (HAVE_KEY | HAVE_IV)) {
-+		/* Clear queues */
-+		memcpy(c->q[0].ctr, ctx->iv, AES_BLOCK_SIZE);
-+		c->q[0].qstate = KQINIT;
-+		for (i = 1; i < NUMKQ; i++) {
-+			memcpy(c->q[i].ctr, ctx->iv, AES_BLOCK_SIZE);
-+			ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE);
-+			c->q[i].qstate = KQEMPTY;
-+		}
-+		c->qidx = 0;
-+		c->ridx = 0;
-+
-+		/* Start threads */
-+		for (i = 0; i < CIPHER_THREADS; i++) {
-+			pthread_create(&c->tid[i], NULL, thread_loop, c);
-+		}
-+		pthread_mutex_lock(&c->q[0].lock);
-+		while (c->q[0].qstate != KQDRAINING)
-+			pthread_cond_wait(&c->q[0].cond, &c->q[0].lock);
-+		pthread_mutex_unlock(&c->q[0].lock);
-+		
-+	}
-+	return (1);
-+}
-+
-+static int
-+ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
-+{
-+	struct ssh_aes_ctr_ctx *c;
-+	int i;
-+
-+	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
-+#ifdef CIPHER_THREAD_STATS
-+		debug("main thread: %u drains, %u waits", c->stats.drains,
-+				c->stats.waits);
-+#endif
-+		/* Cancel pregen threads */
-+		for (i = 0; i < CIPHER_THREADS; i++)
-+			pthread_cancel(c->tid[i]);
-+		for (i = 0; i < CIPHER_THREADS; i++)
-+			pthread_join(c->tid[i], NULL);
-+
-+		memset(c, 0, sizeof(*c));
-+		xfree(c);
-+		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
-+	}
-+	return (1);
-+}
-+
-+/* <friedl> */
-+const EVP_CIPHER *
-+evp_aes_ctr_mt(void)
-+{
-+	static EVP_CIPHER aes_ctr;
-+
-+	memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
-+	aes_ctr.nid = NID_undef;
-+	aes_ctr.block_size = AES_BLOCK_SIZE;
-+	aes_ctr.iv_len = AES_BLOCK_SIZE;
-+	aes_ctr.key_len = 16;
-+	aes_ctr.init = ssh_aes_ctr_init;
-+	aes_ctr.cleanup = ssh_aes_ctr_cleanup;
-+	aes_ctr.do_cipher = ssh_aes_ctr;
-+#ifndef SSH_OLD_EVP
-+	aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
-+	    EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
-+#endif
-+	return (&aes_ctr);
-+}
-diff -urN cipher.c cipher.c
---- cipher.c	2009-01-28 08:38:41.000000000 +0300
-+++ cipher.c	2009-05-02 17:43:11.000000000 +0400
-@@ -55,6 +55,7 @@
- extern const EVP_CIPHER *evp_ssh1_3des(void);
- extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
- extern const EVP_CIPHER *evp_aes_128_ctr(void);
-+extern const EVP_CIPHER *evp_aes_ctr_mt(void);
- extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
- 
- struct Cipher {
-@@ -82,9 +83,9 @@
- 	{ "aes256-cbc",		SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
- 	{ "rijndael-cbc at lysator.liu.se",
- 				SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
--	{ "aes128-ctr",		SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr },
--	{ "aes192-ctr",		SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr },
--	{ "aes256-ctr",		SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr },
-+ 	{ "aes128-ctr",		SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_ctr_mt },
-+ 	{ "aes192-ctr",		SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_ctr_mt },
-+ 	{ "aes256-ctr",		SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_ctr_mt },
- #ifdef USE_CIPHER_ACSS
- 	{ "acss at openssh.org",	SSH_CIPHER_SSH2, 16, 5, 0, 0, EVP_acss },
- #endif
-@@ -163,7 +164,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 +339,7 @@
- 	int evplen;
- 
- 	switch (c->number) {
-+	case SSH_CIPHER_NONE:
- 	case SSH_CIPHER_SSH2:
- 	case SSH_CIPHER_DES:
- 	case SSH_CIPHER_BLOWFISH:
-@@ -371,6 +374,7 @@
- 	int evplen = 0;
- 
- 	switch (c->number) {
-+	case SSH_CIPHER_NONE:
- 	case SSH_CIPHER_SSH2:
- 	case SSH_CIPHER_DES:
- 	case SSH_CIPHER_BLOWFISH:
-diff -urN clientloop.c clientloop.c
---- clientloop.c	2009-02-14 08:28:21.000000000 +0300
-+++ clientloop.c	2009-05-02 17:38:18.000000000 +0400
-@@ -1688,9 +1688,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;
- }
-@@ -1710,9 +1716,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;
-@@ -1740,10 +1752,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;
- 
-+
-+
- #if defined(SSH_TUN_FILTER)
- 	if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
- 		channel_register_filter(c->self, sys_tun_infilter,
-diff -urN compat.c compat.c
---- compat.c	2008-11-03 11:20:14.000000000 +0300
-+++ compat.c	2009-05-02 17:38:18.000000000 +0400
-@@ -170,6 +170,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 -urN compat.h compat.h
---- compat.h	2008-11-03 11:20:14.000000000 +0300
-+++ compat.h	2009-05-02 17:40:04.000000000 +0400
-@@ -58,6 +58,7 @@
- #define SSH_OLD_FORWARD_ADDR	0x01000000
- #define SSH_BUG_RFWD_ADDR	0x02000000
- #define SSH_NEW_OPENSSH		0x04000000
-+#define SSH_BUG_LARGEWINDOW     0x08000000
- 
- void     enable_compat13(void);
- void     enable_compat20(void);
-diff -urN kex.c kex.c
---- kex.c	2008-11-03 11:19:12.000000000 +0300
-+++ kex.c	2009-05-02 17:38:18.000000000 +0400
-@@ -48,6 +48,7 @@
- #include "match.h"
- #include "dispatch.h"
- #include "monitor.h"
-+#include "canohost.h"
- 
- #define KEX_COOKIE_LEN	16
- 
-@@ -64,7 +65,8 @@
- static void kex_choose_conf(Kex *);
- 
- /* 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;
-@@ -376,6 +378,13 @@
- 	int nenc, nmac, ncomp;
- 	u_int mode, ctos, need;
- 	int first_kex_follows, type;
-+	int log_flag = 0;
-+
-+	int auth_flag;
-+
-+	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);
-@@ -400,11 +409,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);
-+		}
-+		log_flag = 1;
- 	}
- 	choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
- 	choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
-diff -urN kex.h kex.h
---- kex.h	2007-06-11 08:01:42.000000000 +0400
-+++ kex.h	2009-05-02 17:38:18.000000000 +0400
-@@ -127,6 +127,8 @@
- 	void	(*kex[KEX_MAX])(Kex *);
- };
- 
-+void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]);
-+
- Kex	*kex_setup(char *[PROPOSAL_MAX]);
- void	 kex_finish(Kex *);
- 
-diff -urN myproposal.h myproposal.h
---- myproposal.h	2009-01-28 08:33:31.000000000 +0300
-+++ myproposal.h	2009-05-02 17:45:01.000000000 +0400
-@@ -47,6 +47,8 @@
- 	"arcfour256,arcfour128," \
- 	"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
- 	"aes192-cbc,aes256-cbc,arcfour,rijndael-cbc at lysator.liu.se"
-+#define KEX_ENCRYPT_INCLUDE_NONE KEX_DEFAULT_ENCRYPT \
-+ 	",none"
- #define	KEX_DEFAULT_MAC \
- 	"hmac-md5,hmac-sha1,umac-64 at openssh.com,hmac-ripemd160," \
- 	"hmac-ripemd160 at openssh.com," \
-diff -urN packet.c packet.c
---- packet.c	2009-02-14 08:35:01.000000000 +0300
-+++ packet.c	2009-05-02 17:38:18.000000000 +0400
-@@ -775,7 +775,7 @@
- /*
-  * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
-  */
--static void
-+static int
- packet_send2_wrapped(void)
- {
- 	u_char type, *cp, *macbuf = NULL;
-@@ -888,11 +888,13 @@
- 		set_newkeys(MODE_OUT);
- 	else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side)
- 		packet_enable_delayed_compress();
-+	return(packet_length);
- }
- 
--static void
-+static int
- packet_send2(void)
- {
-+        static int packet_length = 0;
- 	static int rekeying = 0;
- 	struct packet *p;
- 	u_char type, *cp;
-@@ -910,7 +912,7 @@
- 			memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
- 			buffer_init(&outgoing_packet);
- 			TAILQ_INSERT_TAIL(&outgoing, p, next);
--			return;
-+			return(sizeof(Buffer));
- 		}
- 	}
- 
-@@ -918,7 +920,7 @@
- 	if (type == SSH2_MSG_KEXINIT)
- 		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) {
-@@ -931,19 +933,22 @@
- 			    sizeof(Buffer));
- 			TAILQ_REMOVE(&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);
- }
- 
- /*
-@@ -1544,23 +1549,25 @@
- 
- /* 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(&output);
-+	int len = 0;
-+	len = buffer_len(&output);
- 
- 	if (len > 0) {
- 		len = write(connection_out, buffer_ptr(&output), len);
- 		if (len == -1) {
- 			if (errno == EINTR || errno == EAGAIN ||
- 			    errno == EWOULDBLOCK)
--				return;
-+				return (0);
- 			fatal("Write failed: %.100s", strerror(errno));
- 		}
- 		if (len == 0)
- 			fatal("Write connection closed");
- 		buffer_consume(&output, len);
- 	}
-+	return(len);
- }
- 
- 
-@@ -1569,16 +1576,17 @@
-  * written.
-  */
- 
--void
-+int
- packet_write_wait(void)
- {
- 	fd_set *setp;
- 	int ret, ms_remain;
- 	struct timeval start, timeout, *timeoutp = NULL;
-+	u_int bytes_sent = 0;
- 
- 	setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
- 	    sizeof(fd_mask));
--	packet_write_poll();
-+	bytes_sent += packet_write_poll();
- 	while (packet_have_data_to_write()) {
- 		memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
- 		    sizeof(fd_mask));
-@@ -1612,7 +1620,7 @@
- 			    "waiting to write", get_remote_ipaddr());
- 			cleanup_exit(255);
- 		}
--		packet_write_poll();
-+		bytes_sent += packet_write_poll();
- 	}
- 	xfree(setp);
- }
-@@ -1736,12 +1744,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
- 	    (p_send.packets > MAX_PACKETS) ||
- 	    (p_read.packets > MAX_PACKETS) ||
-@@ -1766,3 +1786,9 @@
- {
- 	after_authentication = 1;
- }
-+
-+int
-+packet_authentication_state(void)
-+{
-+	return(after_authentication);
-+}
-diff -urN packet.h packet.h
---- packet.h	2008-07-11 11:36:48.000000000 +0400
-+++ packet.h	2009-05-02 17:38:18.000000000 +0400
-@@ -20,6 +20,9 @@
- 
- #include <openssl/bn.h>
- 
-+void
-+packet_request_rekeying(void);
-+
- void     packet_set_connection(int, int);
- void     packet_set_timeout(int, int);
- void     packet_set_nonblocking(void);
-@@ -35,6 +38,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);
-@@ -44,7 +48,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);
-@@ -73,8 +77,8 @@
- int	 packet_get_ssh1_cipher(void);
- void	 packet_set_iv(int, u_char *);
- 
--void     packet_write_poll(void);
--void     packet_write_wait(void);
-+int      packet_write_poll(void);
-+int      packet_write_wait(void);
- int      packet_have_data_to_write(void);
- int      packet_not_very_much_data_to_write(void);
- 
-diff -urN progressmeter.c progressmeter.c
---- progressmeter.c	2006-08-05 06:39:40.000000000 +0400
-+++ progressmeter.c	2009-05-02 17:38:18.000000000 +0400
-@@ -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 -urN readconf.c readconf.c
---- readconf.c	2009-05-02 17:37:11.000000000 +0400
-+++ readconf.c	2009-05-02 17:47:56.000000000 +0400
-@@ -131,6 +131,8 @@
- 	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
- 	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
- 	oVisualHostKey, oZeroKnowledgePasswordAuthentication,
-+ 	oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
-+ 	oHPNBufferSize,
- 	oDeprecated, oUnsupported
- } OpCodes;
- 
-@@ -228,6 +230,12 @@
- 	{ "localcommand", oLocalCommand },
- 	{ "permitlocalcommand", oPermitLocalCommand },
- 	{ "visualhostkey", oVisualHostKey },
-+ 	{ "noneenabled", oNoneEnabled },
-+ 	{ "tcprcvbufpoll", oTcpRcvBufPoll },
-+ 	{ "tcprcvbuf", oTcpRcvBuf },
-+ 	{ "noneswitch", oNoneSwitch },
-+ 	{ "hpndisabled", oHPNDisabled },
-+ 	{ "hpnbuffersize", oHPNBufferSize },
- #ifdef JPAKE
- 	{ "zeroknowledgepasswordauthentication",
- 	    oZeroKnowledgePasswordAuthentication },
-@@ -465,6 +473,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;
-@@ -643,6 +682,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);
-@@ -1065,6 +1108,12 @@
- 	options->permit_local_command = -1;
- 	options->visual_host_key = -1;
- 	options->zero_knowledge_password_authentication = -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;
- }
- 
- /*
-@@ -1187,6 +1236,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->hash_known_hosts == -1)
-diff -urN readconf.h readconf.h
---- readconf.h	2009-02-14 08:28:21.000000000 +0300
-+++ readconf.h	2009-05-02 17:38:19.000000000 +0400
-@@ -57,6 +57,11 @@
- 	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 */
-+
- 	LogLevel log_level;	/* Level for logging. */
- 
- 	int     port;		/* Port to connect. */
-@@ -102,6 +107,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 -urN scp.c scp.c
---- scp.c	2008-11-03 11:23:45.000000000 +0300
-+++ scp.c	2009-05-02 17:38:19.000000000 +0400
-@@ -632,7 +632,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) {
-@@ -868,7 +868,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 -urN servconf.c servconf.c
---- servconf.c	2009-05-02 17:37:11.000000000 +0400
-+++ servconf.c	2009-05-02 17:38:19.000000000 +0400
-@@ -266,6 +266,42 @@
- 	if (options->zero_knowledge_password_authentication == -1)
- 		options->zero_knowledge_password_authentication = 0;
- 
-+	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 = 1;
-@@ -428,6 +464,10 @@
- 	{ "permitopen", sPermitOpen, SSHCFG_ALL },
- 	{ "forcecommand", sForceCommand, SSHCFG_ALL },
- 	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
-+	{ "noneenabled", sNoneEnabled },
-+	{ "hpndisabled", sHPNDisabled },
-+	{ "hpnbuffersize", sHPNBufferSize },
-+	{ "tcprcvbufpoll", sTcpRcvBufPoll },
- 	{ NULL, sBadOption, 0 }
- };
- 
-@@ -454,6 +494,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;
- 		}
-@@ -851,6 +892,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;
-diff -urN servconf.h servconf.h
---- servconf.h	2009-01-28 08:31:23.000000000 +0300
-+++ servconf.h	2009-05-02 17:38:19.000000000 +0400
-@@ -145,6 +145,10 @@
- 	char   *adm_forced_command;
- 
- 	int	use_pam;		/* Enable auth via PAM */
-+        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;
- 
-diff -urN serverloop.c serverloop.c
---- serverloop.c	2009-02-14 08:33:09.000000000 +0300
-+++ serverloop.c	2009-05-02 17:38:19.000000000 +0400
-@@ -93,10 +93,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. */
-@@ -121,6 +121,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
-  */
-@@ -410,6 +424,7 @@
- 		} else {
- 			/* Buffer any received data. */
- 			packet_process_incoming(buf, len);
-+			fdout_bytes += len;
- 		}
- 	}
- 	if (compat20)
-@@ -432,6 +447,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. */
-@@ -499,7 +515,7 @@
- 	}
- 	/* Send any buffered packet data to the client. */
- 	if (FD_ISSET(connection_out, writeset))
--		packet_write_poll();
-+		stdin_bytes += packet_write_poll();
- }
- 
- /*
-@@ -816,8 +832,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;
-@@ -879,6 +897,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
-@@ -994,8 +1017,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)
-@@ -1031,6 +1058,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 -urN session.c session.c
---- session.c	2009-05-02 17:37:11.000000000 +0400
-+++ session.c	2009-05-02 17:38:19.000000000 +0400
-@@ -230,6 +230,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,
-@@ -2351,10 +2352,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,
- 	    fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
- 	    1, is_tty, CHAN_SES_WINDOW_DEFAULT);
-+	else 
-+		channel_set_fds(s->chanid,
-+		    fdout, fdin, fderr,
-+	            fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
-+		    1, is_tty, options.hpn_buffer_size);
- }
- 
- /*
-diff -urN sftp.1 sftp.1
---- sftp.1	2009-01-28 08:14:09.000000000 +0300
-+++ sftp.1	2009-05-02 17:38:19.000000000 +0400
-@@ -203,7 +203,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 S Ar program
- Name of the
- .Ar program
-diff -urN sftp.c sftp.c
---- sftp.c	2009-02-14 08:26:19.000000000 +0300
-+++ sftp.c	2009-05-02 17:38:19.000000000 +0400
-@@ -75,7 +75,7 @@
- size_t copy_buffer_len = 32768;
- 
- /* Number of concurrent outstanding requests */
--size_t num_requests = 64;
-+size_t num_requests = 256;
- 
- /* PID of ssh transport process */
- static pid_t sshpid = -1;
-diff -urN ssh.c ssh.c
---- ssh.c	2009-05-02 17:37:11.000000000 +0400
-+++ ssh.c	2009-05-02 17:38:19.000000000 +0400
-@@ -492,9 +492,6 @@
- 			no_shell_flag = 1;
- 			no_tty_flag = 1;
- 			break;
--		case 'T':
--			no_tty_flag = 1;
--			break;
- 		case 'o':
- 			dummy = 1;
- 			line = xstrdup(optarg);
-@@ -503,6 +500,13 @@
- 				exit(255);
- 			xfree(line);
- 			break;
-+		case 'T':
-+			no_tty_flag = 1;
-+			/* 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 's':
- 			subsystem_flag = 1;
- 			break;
-@@ -1159,6 +1163,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);
-@@ -1179,9 +1186,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;
- 	}
-@@ -1189,7 +1262,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 -urN sshconnect.c sshconnect.c
---- sshconnect.c	2009-02-01 14:19:54.000000000 +0300
-+++ sshconnect.c	2009-05-02 17:38:19.000000000 +0400
-@@ -165,6 +165,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
-@@ -187,12 +212,18 @@
- 			    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);
- 	if (sock < 0)
- 		error("socket: %.100s", strerror(errno));
- 
-+	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;
-@@ -536,7 +567,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 (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
- 		fatal("write: %.100s", strerror(errno));
- 	client_version_string = xstrdup(buf);
-diff -urN sshconnect2.c sshconnect2.c
---- sshconnect2.c	2008-11-05 08:20:47.000000000 +0300
-+++ sshconnect2.c	2009-05-02 17:38:19.000000000 +0400
-@@ -78,6 +78,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
-@@ -350,6 +356,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);
- }
- 
-diff -urN sshd.c sshd.c
---- sshd.c	2009-05-02 17:37:11.000000000 +0400
-+++ sshd.c	2009-05-02 17:38:19.000000000 +0400
-@@ -143,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. */
-@@ -422,7 +425,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 +476,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);
- 
-@@ -951,6 +957,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)
-@@ -997,6 +1005,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.",
-@@ -1847,6 +1860,9 @@
- 	/* Log the connection. */
- 	verbose("Connection from %.500s port %d", remote_ip, remote_port);
- 
-+	/* set the HPN options for the child */
-+	channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
-+
- 	/*
- 	 * We don't want to listen forever unless the other side
- 	 * successfully authenticates itself.  So we set up an alarm which is
-@@ -2201,9 +2217,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]);
-diff -urN sshd_config sshd_config
---- sshd_config	2009-05-02 17:37:11.000000000 +0400
-+++ sshd_config	2009-05-02 17:38:19.000000000 +0400
-@@ -112,6 +112,20 @@
- # 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
-+
-+# 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
---- version.h.orig      2009-02-23 03:09:26.000000000 +0300
-+++ version.h   2009-05-02 18:53:20.000000000 +0400
-@@ -3,4 +3,5 @@
- #define SSH_VERSION    "OpenSSH_5.2"
- 
- #define SSH_PORTABLE   "p1"
--#define SSH_RELEASE    SSH_VERSION SSH_PORTABLE
-+#define SSH_HPN         "-hpn13v5"
-+#define SSH_RELEASE    SSH_VERSION SSH_PORTABLE SSH_HPN
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/files/openssh-5.2p1-hpn13v6-servconf.c.diff /usr/home/dindin/workspace/openssh-portable/files/openssh-5.2p1-hpn13v6-servconf.c.diff
--- /usr/ports/security/openssh-portable/files/openssh-5.2p1-hpn13v6-servconf.c.diff	1970-01-01 03:00:00.000000000 +0300
+++ /usr/home/dindin/workspace/openssh-portable/files/openssh-5.2p1-hpn13v6-servconf.c.diff	2009-05-26 15:34:24.000000000 +0400
@@ -0,0 +1,117 @@
+diff -NupwB servconf.c servconf.c
+--- servconf.c	2009-01-28 00:31:23.000000000 -0500
++++ servconf.c	2009-05-14 12:36:10.000000000 -0400
+@@ -128,11 +128,20 @@ initialize_server_options(ServerOptions 
+ 	options->adm_forced_command = NULL;
+ 	options->chroot_directory = NULL;
+ 	options->zero_knowledge_password_authentication = -1;
++	options->none_enabled = -1;
++	options->tcp_rcv_buf_poll = -1;
++	options->hpn_disabled = -1;
++	options->hpn_buffer_size = -1;
+ }
+ 
+ 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;
+@@ -262,6 +271,42 @@ fill_default_server_options(ServerOption
+ 	if (options->zero_knowledge_password_authentication == -1)
+ 		options->zero_knowledge_password_authentication = 0;
+ 
++	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 = 1;
+@@ -306,6 +351,7 @@ typedef enum {
+ 	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
+ 	sUsePrivilegeSeparation, sAllowAgentForwarding,
+ 	sZeroKnowledgePasswordAuthentication,
++	sNoneEnabled, sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize,
+ 	sDeprecated, sUnsupported
+ } ServerOpCodes;
+ 
+@@ -424,6 +470,10 @@ static struct {
+ 	{ "permitopen", sPermitOpen, SSHCFG_ALL },
+ 	{ "forcecommand", sForceCommand, SSHCFG_ALL },
+ 	{ "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
++	{ "noneenabled", sNoneEnabled },
++	{ "hpndisabled", sHPNDisabled },
++	{ "hpnbuffersize", sHPNBufferSize },
++	{ "tcprcvbufpoll", sTcpRcvBufPoll },
+ 	{ NULL, sBadOption, 0 }
+ };
+ 
+@@ -450,6 +500,7 @@ parse_token(const char *cp, const char *
+ 
+ 	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;
+ 		}
+@@ -847,6 +898,22 @@ process_server_config_line(ServerOptions
+ 			*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;
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/files/openssh-5.2p1-hpn13v6.diff /usr/home/dindin/workspace/openssh-portable/files/openssh-5.2p1-hpn13v6.diff
--- /usr/ports/security/openssh-portable/files/openssh-5.2p1-hpn13v6.diff	1970-01-01 03:00:00.000000000 +0300
+++ /usr/home/dindin/workspace/openssh-portable/files/openssh-5.2p1-hpn13v6.diff	2009-05-26 15:34:08.000000000 +0400
@@ -0,0 +1,3576 @@
+diff -NupwB auth2.c auth2.c
+--- auth2.c	2008-11-05 00:20:46.000000000 -0500
++++ auth2.c	2009-05-14 12:36:10.000000000 -0400
+@@ -49,6 +49,7 @@
+ #include "dispatch.h"
+ #include "pathnames.h"
+ #include "buffer.h"
++#include "canohost.h"
+ 
+ #ifdef GSSAPI
+ #include "ssh-gss.h"
+@@ -75,6 +76,9 @@ extern Authmethod method_gssapi;
+ extern Authmethod method_jpake;
+ #endif
+ 
++static int log_flag = 0;
++
++
+ Authmethod *authmethods[] = {
+ 	&method_none,
+ 	&method_pubkey,
+@@ -225,6 +229,11 @@ input_userauth_request(int type, u_int32
+ 	service = packet_get_string(NULL);
+ 	method = packet_get_string(NULL);
+ 	debug("userauth-request for user %s service %s method %s", user, service, method);
++	if (!log_flag) {
++		logit("SSH: Server;Ltype: Authname;Remote: %s-%d;Name: %s", 
++		      get_remote_ipaddr(), get_remote_port(), user);
++		log_flag = 1;
++	}
+ 	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
+ 
+ 	if ((style = strchr(user, ':')) != NULL)
+diff -NupwB buffer.c buffer.c
+--- buffer.c	2006-08-04 22:39:39.000000000 -0400
++++ buffer.c	2009-05-14 12:36:10.000000000 -0400
+@@ -127,7 +127,7 @@ restart:
+ 
+ 	/* 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 -NupwB buffer.h buffer.h
+--- buffer.h	2008-05-19 00:59:37.000000000 -0400
++++ buffer.h	2009-05-14 12:36:10.000000000 -0400
+@@ -16,6 +16,9 @@
+ #ifndef BUFFER_H
+ #define BUFFER_H
+ 
++/* 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 -NupwB channels.c channels.c
+--- channels.c	2009-02-14 00:28:21.000000000 -0500
++++ channels.c	2009-05-14 12:36:10.000000000 -0400
+@@ -169,8 +169,14 @@ static void port_open_helper(Channel *c,
+ static int connect_next(struct channel_connect *);
+ static void channel_connect_ctx_free(struct channel_connect *);
+ 
++
++static int hpn_disabled = 0;
++static int hpn_buffer_size = 2 * 1024 * 1024;
++
+ /* -- channel core */
+ 
++
++
+ Channel *
+ channel_by_id(int id)
+ {
+@@ -308,6 +314,7 @@ channel_new(char *ctype, int type, int r
+ 	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;
+@@ -798,11 +805,35 @@ channel_pre_open_13(Channel *c, fd_set *
+ 		FD_SET(c->sock, writeset);
+ }
+ 
++int channel_tcpwinsz () {
++        u_int32_t tcpwinsz = 0;
++        socklen_t optsz = sizeof(tcpwinsz);
++	int ret = -1;
++
++	/* 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;
++	debug2("tcpwinsz: %d for connection: %d", tcpwinsz, 
++	       packet_get_connection_in());
++	return(tcpwinsz);
++}
++
+ 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 &&
+@@ -1759,14 +1790,21 @@ channel_check_window(Channel *c)
+ 	    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;
+@@ -1969,11 +2007,12 @@ channel_after_select(fd_set *readset, fd
+ 
+ 
+ /* 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];
+@@ -2013,7 +2052,7 @@ channel_output_poll(void)
+ 					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);
+ 				}
+@@ -2043,7 +2082,7 @@ channel_output_poll(void)
+ 				    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;
+ 			}
+@@ -2078,12 +2117,13 @@ channel_output_poll(void)
+ 			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);
+ }
+ 
+ 
+@@ -2459,6 +2499,15 @@ channel_set_af(int af)
+ 	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);
++}
++
+ static int
+ channel_setup_fwd_listener(int type, const char *listen_addr,
+     u_short listen_port, int *allocated_listen_port,
+@@ -2610,9 +2659,15 @@ channel_setup_fwd_listener(int type, con
+ 		}
+ 
+ 		/* 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_port = listen_port;
+@@ -3151,10 +3206,17 @@ x11_create_display_inet(int x11_display_
+ 	*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 -NupwB channels.h channels.h
+--- channels.h	2009-02-14 00:28:21.000000000 -0500
++++ channels.h	2009-05-14 12:36:10.000000000 -0400
+@@ -115,8 +115,10 @@ struct Channel {
+ 	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 */
+ 
+@@ -146,9 +148,11 @@ struct Channel {
+ 
+ /* 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)
++
+ #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)
++
+ #define CHAN_X11_PACKET_DEFAULT	(16*1024)
+ #define CHAN_X11_WINDOW_DEFAULT	(4*CHAN_X11_PACKET_DEFAULT)
+ 
+@@ -221,7 +225,7 @@ void	 channel_input_status_confirm(int, 
+ 
+ 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);
+@@ -277,4 +281,7 @@ void	 chan_rcvd_ieof(Channel *);
+ void	 chan_write_failed(Channel *);
+ void	 chan_obuf_empty(Channel *);
+ 
++/* hpn handler */
++void     channel_set_hpn(int, int);
++
+ #endif
+diff -NupwB cipher.c cipher.c
+--- cipher.c	2009-01-28 00:38:41.000000000 -0500
++++ cipher.c	2009-05-14 12:36:10.000000000 -0400
+@@ -55,6 +55,7 @@ extern const EVP_CIPHER *evp_ssh1_bf(voi
+ extern const EVP_CIPHER *evp_ssh1_3des(void);
+ extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
+ extern const EVP_CIPHER *evp_aes_128_ctr(void);
++extern const EVP_CIPHER *evp_aes_ctr_mt(void);
+ extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
+ 
+ struct Cipher {
+@@ -82,9 +83,9 @@ struct Cipher {
+ 	{ "aes256-cbc",		SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
+ 	{ "rijndael-cbc at lysator.liu.se",
+ 				SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
+-	{ "aes128-ctr",		SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr },
+-	{ "aes192-ctr",		SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr },
+-	{ "aes256-ctr",		SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr },
++	{ "aes128-ctr",		SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_ctr_mt },
++	{ "aes192-ctr",		SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_ctr_mt },
++	{ "aes256-ctr",		SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_ctr_mt },
+ #ifdef USE_CIPHER_ACSS
+ 	{ "acss at openssh.org",	SSH_CIPHER_SSH2, 16, 5, 0, 0, EVP_acss },
+ #endif
+@@ -163,7 +164,8 @@ ciphers_valid(const char *names)
+ 	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 +339,7 @@ cipher_get_keyiv(CipherContext *cc, u_ch
+ 	int evplen;
+ 
+ 	switch (c->number) {
++	case SSH_CIPHER_NONE:
+ 	case SSH_CIPHER_SSH2:
+ 	case SSH_CIPHER_DES:
+ 	case SSH_CIPHER_BLOWFISH:
+@@ -371,6 +374,7 @@ cipher_set_keyiv(CipherContext *cc, u_ch
+ 	int evplen = 0;
+ 
+ 	switch (c->number) {
++	case SSH_CIPHER_NONE:
+ 	case SSH_CIPHER_SSH2:
+ 	case SSH_CIPHER_DES:
+ 	case SSH_CIPHER_BLOWFISH:
+diff -NupwB cipher-ctr-mt.c cipher-ctr-mt.c
+--- cipher-ctr-mt.c	1969-12-31 19:00:00.000000000 -0500
++++ cipher-ctr-mt.c	2009-05-14 12:36:10.000000000 -0400
+@@ -0,0 +1,473 @@
++/*
++ * OpenSSH Multi-threaded AES-CTR Cipher
++ *
++ * Author: Benjamin Bennett <ben at psc.edu>
++ * Copyright (c) 2008 Pittsburgh Supercomputing Center. All rights reserved.
++ *
++ * Based on original OpenSSH AES-CTR cipher. Small portions remain unchanged,
++ * Copyright (c) 2003 Markus Friedl <markus at openbsd.org>
++ *
++ * 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.
++ */
++#include "includes.h"
++
++#include <sys/types.h>
++
++#include <stdarg.h>
++#include <string.h>
++
++#include <openssl/evp.h>
++
++#include "xmalloc.h"
++#include "log.h"
++
++/* compatibility with old or broken OpenSSL versions */
++#include "openbsd-compat/openssl-compat.h"
++
++#ifndef USE_BUILTIN_RIJNDAEL
++#include <openssl/aes.h>
++#endif
++
++#include <pthread.h>
++
++/*-------------------- TUNABLES --------------------*/
++/* Number of pregen threads to use */
++#define CIPHER_THREADS	2
++
++/* Number of keystream queues */
++#define NUMKQ		(CIPHER_THREADS + 2)
++
++/* Length of a keystream queue */
++#define KQLEN		4096
++
++/* Processor cacheline length */
++#define CACHELINE_LEN	64
++
++/* Collect thread stats and print at cancellation when in debug mode */
++/* #define CIPHER_THREAD_STATS */
++
++/* Use single-byte XOR instead of 8-byte XOR */
++/* #define CIPHER_BYTE_XOR */
++/*-------------------- END TUNABLES --------------------*/
++
++
++const EVP_CIPHER *evp_aes_ctr_mt(void);
++
++#ifdef CIPHER_THREAD_STATS
++/*
++ * Struct to collect thread stats
++ */
++struct thread_stats {
++	u_int	fills;
++	u_int	skips;
++	u_int	waits;
++	u_int	drains;
++};
++
++/*
++ * Debug print the thread stats
++ * Use with pthread_cleanup_push for displaying at thread cancellation
++ */
++static void
++thread_loop_stats(void *x)
++{
++	struct thread_stats *s = x;
++
++	debug("tid %lu - %u fills, %u skips, %u waits", pthread_self(),
++			s->fills, s->skips, s->waits);
++}
++
++ #define STATS_STRUCT(s)	struct thread_stats s
++ #define STATS_INIT(s)		{ memset(&s, 0, sizeof(s)); }
++ #define STATS_FILL(s)		{ s.fills++; }
++ #define STATS_SKIP(s)		{ s.skips++; }
++ #define STATS_WAIT(s)		{ s.waits++; }
++ #define STATS_DRAIN(s)		{ s.drains++; }
++#else
++ #define STATS_STRUCT(s)
++ #define STATS_INIT(s)
++ #define STATS_FILL(s)
++ #define STATS_SKIP(s)
++ #define STATS_WAIT(s)
++ #define STATS_DRAIN(s)
++#endif
++
++/* Keystream Queue state */
++enum {
++	KQINIT,
++	KQEMPTY,
++	KQFILLING,
++	KQFULL,
++	KQDRAINING
++};
++
++/* Keystream Queue struct */
++struct kq {
++	u_char		keys[KQLEN][AES_BLOCK_SIZE];
++	u_char		ctr[AES_BLOCK_SIZE];
++	u_char		pad0[CACHELINE_LEN];
++	volatile int	qstate;
++	pthread_mutex_t	lock;
++	pthread_cond_t	cond;
++	u_char		pad1[CACHELINE_LEN];
++};
++
++/* Context struct */
++struct ssh_aes_ctr_ctx
++{
++	struct kq	q[NUMKQ];
++	AES_KEY		aes_ctx;
++	STATS_STRUCT(stats);
++	u_char		aes_counter[AES_BLOCK_SIZE];
++	pthread_t	tid[CIPHER_THREADS];
++	int		state;
++	int		qidx;
++	int		ridx;
++};
++
++/* <friedl>
++ * increment counter 'ctr',
++ * the counter is of size 'len' bytes and stored in network-byte-order.
++ * (LSB at ctr[len-1], MSB at ctr[0])
++ */
++static void
++ssh_ctr_inc(u_char *ctr, u_int len)
++{
++	int i;
++
++	for (i = len - 1; i >= 0; i--)
++		if (++ctr[i])	/* continue on overflow */
++			return;
++}
++
++/*
++ * Add num to counter 'ctr'
++ */
++static void
++ssh_ctr_add(u_char *ctr, uint32_t num, u_int len)
++{
++	int i;
++	uint16_t n;
++
++	for (n = 0, i = len - 1; i >= 0 && (num || n); i--) {
++		n = ctr[i] + (num & 0xff) + n;
++		num >>= 8;
++		ctr[i] = n & 0xff;
++		n >>= 8;
++	}
++}
++
++/*
++ * Threads may be cancelled in a pthread_cond_wait, we must free the mutex
++ */
++static void
++thread_loop_cleanup(void *x)
++{
++	pthread_mutex_unlock((pthread_mutex_t *)x);
++}
++
++/*
++ * The life of a pregen thread:
++ *    Find empty keystream queues and fill them using their counter.
++ *    When done, update counter for the next fill.
++ */
++static void *
++thread_loop(void *x)
++{
++	AES_KEY key;
++	STATS_STRUCT(stats);
++	struct ssh_aes_ctr_ctx *c = x;
++	struct kq *q;
++	int i;
++	int qidx;
++
++	/* Threads stats on cancellation */
++	STATS_INIT(stats);
++#ifdef CIPHER_THREAD_STATS
++	pthread_cleanup_push(thread_loop_stats, &stats);
++#endif
++
++	/* Thread local copy of AES key */
++	memcpy(&key, &c->aes_ctx, sizeof(key));
++
++	/*
++	 * Handle the special case of startup, one thread must fill
++ 	 * the first KQ then mark it as draining. Lock held throughout.
++ 	 */
++	if (pthread_equal(pthread_self(), c->tid[0])) {
++		q = &c->q[0];
++		pthread_mutex_lock(&q->lock);
++		if (q->qstate == KQINIT) {
++			for (i = 0; i < KQLEN; i++) {
++				AES_encrypt(q->ctr, q->keys[i], &key);
++				ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
++			}
++			ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
++			q->qstate = KQDRAINING;
++			STATS_FILL(stats);
++			pthread_cond_broadcast(&q->cond);
++		}
++		pthread_mutex_unlock(&q->lock);
++	}
++	else 
++		STATS_SKIP(stats);
++
++	/*
++ 	 * Normal case is to find empty queues and fill them, skipping over
++ 	 * queues already filled by other threads and stopping to wait for
++ 	 * a draining queue to become empty.
++ 	 *
++ 	 * Multiple threads may be waiting on a draining queue and awoken
++ 	 * when empty.  The first thread to wake will mark it as filling,
++ 	 * others will move on to fill, skip, or wait on the next queue.
++ 	 */
++	for (qidx = 1;; qidx = (qidx + 1) % NUMKQ) {
++		/* Check if I was cancelled, also checked in cond_wait */
++		pthread_testcancel();
++
++		/* Lock queue and block if its draining */
++		q = &c->q[qidx];
++		pthread_mutex_lock(&q->lock);
++		pthread_cleanup_push(thread_loop_cleanup, &q->lock);
++		while (q->qstate == KQDRAINING || q->qstate == KQINIT) {
++			STATS_WAIT(stats);
++			pthread_cond_wait(&q->cond, &q->lock);
++		}
++		pthread_cleanup_pop(0);
++
++		/* If filling or full, somebody else got it, skip */
++		if (q->qstate != KQEMPTY) {
++			pthread_mutex_unlock(&q->lock);
++			STATS_SKIP(stats);
++			continue;
++		}
++
++		/*
++ 		 * Empty, let's fill it.
++ 		 * Queue lock is relinquished while we do this so others
++ 		 * can see that it's being filled.
++ 		 */
++		q->qstate = KQFILLING;
++		pthread_mutex_unlock(&q->lock);
++		for (i = 0; i < KQLEN; i++) {
++			AES_encrypt(q->ctr, q->keys[i], &key);
++			ssh_ctr_inc(q->ctr, AES_BLOCK_SIZE);
++		}
++
++		/* Re-lock, mark full and signal consumer */
++		pthread_mutex_lock(&q->lock);
++		ssh_ctr_add(q->ctr, KQLEN * (NUMKQ - 1), AES_BLOCK_SIZE);
++		q->qstate = KQFULL;
++		STATS_FILL(stats);
++		pthread_cond_signal(&q->cond);
++		pthread_mutex_unlock(&q->lock);
++	}
++
++#ifdef CIPHER_THREAD_STATS
++	/* Stats */
++	pthread_cleanup_pop(1);
++#endif
++
++	return NULL;
++}
++
++static int
++ssh_aes_ctr(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
++    u_int len)
++{
++	struct ssh_aes_ctr_ctx *c;
++	struct kq *q, *oldq;
++	int ridx;
++	u_char *buf;
++
++	if (len == 0)
++		return (1);
++	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
++		return (0);
++
++	q = &c->q[c->qidx];
++	ridx = c->ridx;
++
++	/* src already padded to block multiple */
++	while (len > 0) {
++		buf = q->keys[ridx];
++
++#ifdef CIPHER_BYTE_XOR
++		dest[0] = src[0] ^ buf[0];
++		dest[1] = src[1] ^ buf[1];
++		dest[2] = src[2] ^ buf[2];
++		dest[3] = src[3] ^ buf[3];
++		dest[4] = src[4] ^ buf[4];
++		dest[5] = src[5] ^ buf[5];
++		dest[6] = src[6] ^ buf[6];
++		dest[7] = src[7] ^ buf[7];
++		dest[8] = src[8] ^ buf[8];
++		dest[9] = src[9] ^ buf[9];
++		dest[10] = src[10] ^ buf[10];
++		dest[11] = src[11] ^ buf[11];
++		dest[12] = src[12] ^ buf[12];
++		dest[13] = src[13] ^ buf[13];
++		dest[14] = src[14] ^ buf[14];
++		dest[15] = src[15] ^ buf[15];
++#else
++		*(uint64_t *)dest = *(uint64_t *)src ^ *(uint64_t *)buf;
++		*(uint64_t *)(dest + 8) = *(uint64_t *)(src + 8) ^
++						*(uint64_t *)(buf + 8);
++#endif
++
++		dest += 16;
++		src += 16;
++		len -= 16;
++		ssh_ctr_inc(ctx->iv, AES_BLOCK_SIZE);
++
++		/* Increment read index, switch queues on rollover */
++		if ((ridx = (ridx + 1) % KQLEN) == 0) {
++			oldq = q;
++
++			/* Mark next queue draining, may need to wait */
++			c->qidx = (c->qidx + 1) % NUMKQ;
++			q = &c->q[c->qidx];
++			pthread_mutex_lock(&q->lock);
++			while (q->qstate != KQFULL) {
++				STATS_WAIT(c->stats);
++				pthread_cond_wait(&q->cond, &q->lock);
++			}
++			q->qstate = KQDRAINING;
++			pthread_mutex_unlock(&q->lock);
++
++			/* Mark consumed queue empty and signal producers */
++			pthread_mutex_lock(&oldq->lock);
++			oldq->qstate = KQEMPTY;
++			STATS_DRAIN(c->stats);
++			pthread_cond_broadcast(&oldq->cond);
++			pthread_mutex_unlock(&oldq->lock);
++		}
++	}
++	c->ridx = ridx;
++	return (1);
++}
++
++#define HAVE_NONE       0
++#define HAVE_KEY        1
++#define HAVE_IV         2
++static int
++ssh_aes_ctr_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
++    int enc)
++{
++	struct ssh_aes_ctr_ctx *c;
++	int i;
++
++	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
++		c = xmalloc(sizeof(*c));
++
++		c->state = HAVE_NONE;
++		for (i = 0; i < NUMKQ; i++) {
++			pthread_mutex_init(&c->q[i].lock, NULL);
++			pthread_cond_init(&c->q[i].cond, NULL);
++		}
++
++		STATS_INIT(c->stats);
++		
++		EVP_CIPHER_CTX_set_app_data(ctx, c);
++	}
++
++	if (c->state == (HAVE_KEY | HAVE_IV)) {
++		/* Cancel pregen threads */
++		for (i = 0; i < CIPHER_THREADS; i++)
++			pthread_cancel(c->tid[i]);
++		for (i = 0; i < CIPHER_THREADS; i++)
++			pthread_join(c->tid[i], NULL);
++		/* Start over getting key & iv */
++		c->state = HAVE_NONE;
++	}
++
++	if (key != NULL) {
++		AES_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8,
++		    &c->aes_ctx);
++		c->state |= HAVE_KEY;
++	}
++
++	if (iv != NULL) {
++		memcpy(ctx->iv, iv, AES_BLOCK_SIZE);
++		c->state |= HAVE_IV;
++	}
++
++	if (c->state == (HAVE_KEY | HAVE_IV)) {
++		/* Clear queues */
++		memcpy(c->q[0].ctr, ctx->iv, AES_BLOCK_SIZE);
++		c->q[0].qstate = KQINIT;
++		for (i = 1; i < NUMKQ; i++) {
++			memcpy(c->q[i].ctr, ctx->iv, AES_BLOCK_SIZE);
++			ssh_ctr_add(c->q[i].ctr, i * KQLEN, AES_BLOCK_SIZE);
++			c->q[i].qstate = KQEMPTY;
++		}
++		c->qidx = 0;
++		c->ridx = 0;
++
++		/* Start threads */
++		for (i = 0; i < CIPHER_THREADS; i++) {
++			pthread_create(&c->tid[i], NULL, thread_loop, c);
++		}
++		pthread_mutex_lock(&c->q[0].lock);
++		while (c->q[0].qstate != KQDRAINING)
++			pthread_cond_wait(&c->q[0].cond, &c->q[0].lock);
++		pthread_mutex_unlock(&c->q[0].lock);
++		
++	}
++	return (1);
++}
++
++static int
++ssh_aes_ctr_cleanup(EVP_CIPHER_CTX *ctx)
++{
++	struct ssh_aes_ctr_ctx *c;
++	int i;
++
++	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
++#ifdef CIPHER_THREAD_STATS
++		debug("main thread: %u drains, %u waits", c->stats.drains,
++				c->stats.waits);
++#endif
++		/* Cancel pregen threads */
++		for (i = 0; i < CIPHER_THREADS; i++)
++			pthread_cancel(c->tid[i]);
++		for (i = 0; i < CIPHER_THREADS; i++)
++			pthread_join(c->tid[i], NULL);
++
++		memset(c, 0, sizeof(*c));
++		xfree(c);
++		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
++	}
++	return (1);
++}
++
++/* <friedl> */
++const EVP_CIPHER *
++evp_aes_ctr_mt(void)
++{
++	static EVP_CIPHER aes_ctr;
++
++	memset(&aes_ctr, 0, sizeof(EVP_CIPHER));
++	aes_ctr.nid = NID_undef;
++	aes_ctr.block_size = AES_BLOCK_SIZE;
++	aes_ctr.iv_len = AES_BLOCK_SIZE;
++	aes_ctr.key_len = 16;
++	aes_ctr.init = ssh_aes_ctr_init;
++	aes_ctr.cleanup = ssh_aes_ctr_cleanup;
++	aes_ctr.do_cipher = ssh_aes_ctr;
++#ifndef SSH_OLD_EVP
++	aes_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
++	    EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
++#endif
++	return (&aes_ctr);
++}
+diff -NupwB clientloop.c clientloop.c
+--- clientloop.c	2009-02-14 00:28:21.000000000 -0500
++++ clientloop.c	2009-05-14 12:36:10.000000000 -0400
+@@ -1688,9 +1688,15 @@ client_request_x11(const char *request_t
+ 	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;
+ }
+@@ -1710,9 +1716,15 @@ client_request_agent(const char *request
+ 	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;
+@@ -1740,10 +1752,18 @@ client_request_tun_fwd(int tun_mode, int
+ 		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;
+ 
++
++
+ #if defined(SSH_TUN_FILTER)
+ 	if (options.tun_open == SSH_TUNMODE_POINTOPOINT)
+ 		channel_register_filter(c->self, sys_tun_infilter,
+diff -NupwB compat.c compat.c
+--- compat.c	2008-11-03 03:20:14.000000000 -0500
++++ compat.c	2009-05-14 12:36:10.000000000 -0400
+@@ -170,6 +170,15 @@ compat_datafellows(const char *version)
+ 		    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 -NupwB compat.h compat.h
+--- compat.h	2008-11-03 03:20:14.000000000 -0500
++++ compat.h	2009-05-14 12:36:10.000000000 -0400
+@@ -58,6 +58,7 @@
+ #define SSH_OLD_FORWARD_ADDR	0x01000000
+ #define SSH_BUG_RFWD_ADDR	0x02000000
+ #define SSH_NEW_OPENSSH		0x04000000
++#define SSH_BUG_LARGEWINDOW     0x08000000
+ 
+ void     enable_compat13(void);
+ void     enable_compat20(void);
+Common subdirectories: contrib and contrib
+diff -NupwB HPN-README HPN-README
+--- HPN-README	1969-12-31 19:00:00.000000000 -0500
++++ HPN-README	2009-05-14 12:36:10.000000000 -0400
+@@ -0,0 +1,128 @@
++Notes:
++
++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 at host.com
++		scp -oCipher=aes256-ctr file you at host.com:~/file
++
++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. 
++
++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. 
++
++http://www.psc.edu/networking/projects/hpn-ssh
++
++BUFFER SIZES:
++
++If HPN is disabled the receive buffer size will be set to the 
++OpenSSH default of 64K.
++
++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.
++
++If an HPN to HPN connection is established a number of different things might
++happen based on the user options and conditions. 
++
++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. 
++
++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
++
++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).
++
++Conditions: HPNBufferSize SET, TCPRcvBufPoll disabled, TCPRcvBuf SET
++HPN Buffer Size = minmum of TCPRcvBuf and HPNBufferSize. 
++Generally there is no need to set both.
++
++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. 
++
++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.
++
++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.
++
++
++HPN Specific Configuration options
++
++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.
++
++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.
++
++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.
++
++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.
++
++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. 
++
++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.
++
++
++Credits: This patch was conceived, designed, and led by Chris Rapier (rapier at psc.edu)
++         The majority of the actual coding for versions up to HPN12v1 was performed
++         by Michael Stevens (mstevens at andrew.cmu.edu). The MT-AES-CTR cipher was 
++	 implemented by Ben Bennet (ben at psc.edu). This work was financed, in part,
++         by Cisco System, Inc., the National Library of Medicine, 
++	 and the National Science Foundation. 
+diff -NupwB kex.c kex.c
+--- kex.c	2008-11-03 03:19:12.000000000 -0500
++++ kex.c	2009-05-14 12:36:10.000000000 -0400
+@@ -48,6 +48,7 @@
+ #include "match.h"
+ #include "dispatch.h"
+ #include "monitor.h"
++#include "canohost.h"
+ 
+ #define KEX_COOKIE_LEN	16
+ 
+@@ -64,7 +65,8 @@ static void kex_kexinit_finish(Kex *);
+ static void kex_choose_conf(Kex *);
+ 
+ /* 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;
+@@ -376,6 +378,13 @@ kex_choose_conf(Kex *kex)
+ 	int nenc, nmac, ncomp;
+ 	u_int mode, ctos, need;
+ 	int first_kex_follows, type;
++	int log_flag = 0;
++
++	int auth_flag;
++
++	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);
+@@ -400,11 +409,34 @@ kex_choose_conf(Kex *kex)
+ 		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);
++		}
++		log_flag = 1;
+ 	}
+ 	choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
+ 	choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
+diff -NupwB kex.h kex.h
+--- kex.h	2007-06-11 00:01:42.000000000 -0400
++++ kex.h	2009-05-14 12:36:10.000000000 -0400
+@@ -127,6 +127,8 @@ struct Kex {
+ 	void	(*kex[KEX_MAX])(Kex *);
+ };
+ 
++void kex_prop2buf(Buffer *, char *proposal[PROPOSAL_MAX]);
++
+ Kex	*kex_setup(char *[PROPOSAL_MAX]);
+ void	 kex_finish(Kex *);
+ 
+diff -NupwB Makefile.in Makefile.in
+--- Makefile.in	2008-11-05 00:20:46.000000000 -0500
++++ Makefile.in	2009-05-14 12:36:10.000000000 -0400
+@@ -43,7 +43,7 @@ CC=@CC@
+ LD=@LD@
+ CFLAGS=@CFLAGS@
+ CPPFLAGS=-I. -I$(srcdir) @CPPFLAGS@ $(PATHS) @DEFS@
+-LIBS=@LIBS@
++LIBS=@LIBS@ -lpthread
+ SSHDLIBS=@SSHDLIBS@
+ LIBEDIT=@LIBEDIT@
+ AR=@AR@
+@@ -64,7 +64,7 @@ TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-a
+ 
+ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \
+ 	canohost.o channels.o cipher.o cipher-acss.o cipher-aes.o \
+-	cipher-bf1.o cipher-ctr.o cipher-3des1.o cleanup.o \
++	cipher-bf1.o cipher-ctr.o cipher-ctr-mt.o cipher-3des1.o cleanup.o \
+ 	compat.o compress.o crc32.o deattack.o fatal.o hostfile.o \
+ 	log.o match.o md-sha256.o moduli.o nchan.o packet.o \
+ 	readpass.o rsa.o ttymodes.o xmalloc.o addrmatch.o \
+diff -NupwB myproposal.h myproposal.h
+--- myproposal.h	2009-01-28 00:33:31.000000000 -0500
++++ myproposal.h	2009-05-14 12:36:10.000000000 -0400
+@@ -47,6 +47,8 @@
+ 	"arcfour256,arcfour128," \
+ 	"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
+ 	"aes192-cbc,aes256-cbc,arcfour,rijndael-cbc at lysator.liu.se"
++#define KEX_ENCRYPT_INCLUDE_NONE KEX_DEFAULT_ENCRYPT \
++	",none"
+ #define	KEX_DEFAULT_MAC \
+ 	"hmac-md5,hmac-sha1,umac-64 at openssh.com,hmac-ripemd160," \
+ 	"hmac-ripemd160 at openssh.com," \
+Common subdirectories: openbsd-compat and openbsd-compat
+diff -NupwB packet.c packet.c
+--- packet.c	2009-02-14 00:35:01.000000000 -0500
++++ packet.c	2009-05-14 12:36:10.000000000 -0400
+@@ -775,7 +775,7 @@ packet_enable_delayed_compress(void)
+ /*
+  * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
+  */
+-static void
++static int
+ packet_send2_wrapped(void)
+ {
+ 	u_char type, *cp, *macbuf = NULL;
+@@ -888,11 +888,13 @@ packet_send2_wrapped(void)
+ 		set_newkeys(MODE_OUT);
+ 	else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side)
+ 		packet_enable_delayed_compress();
++	return(packet_length);
+ }
+ 
+-static void
++static int
+ packet_send2(void)
+ {
++        static int packet_length = 0;
+ 	static int rekeying = 0;
+ 	struct packet *p;
+ 	u_char type, *cp;
+@@ -910,7 +912,7 @@ packet_send2(void)
+ 			memcpy(&p->payload, &outgoing_packet, sizeof(Buffer));
+ 			buffer_init(&outgoing_packet);
+ 			TAILQ_INSERT_TAIL(&outgoing, p, next);
+-			return;
++			return(sizeof(Buffer));
+ 		}
+ 	}
+ 
+@@ -918,7 +920,7 @@ packet_send2(void)
+ 	if (type == SSH2_MSG_KEXINIT)
+ 		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) {
+@@ -931,19 +933,22 @@ packet_send2(void)
+ 			    sizeof(Buffer));
+ 			TAILQ_REMOVE(&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);
+ }
+ 
+ /*
+@@ -1544,23 +1549,25 @@ packet_disconnect(const char *fmt,...)
+ 
+ /* 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(&output);
++	int len = 0;
++	len = buffer_len(&output);
+ 
+ 	if (len > 0) {
+ 		len = write(connection_out, buffer_ptr(&output), len);
+ 		if (len == -1) {
+ 			if (errno == EINTR || errno == EAGAIN ||
+ 			    errno == EWOULDBLOCK)
+-				return;
++				return (0);
+ 			fatal("Write failed: %.100s", strerror(errno));
+ 		}
+ 		if (len == 0)
+ 			fatal("Write connection closed");
+ 		buffer_consume(&output, len);
+ 	}
++	return(len);
+ }
+ 
+ 
+@@ -1569,16 +1576,17 @@ packet_write_poll(void)
+  * written.
+  */
+ 
+-void
++int
+ packet_write_wait(void)
+ {
+ 	fd_set *setp;
+ 	int ret, ms_remain;
+ 	struct timeval start, timeout, *timeoutp = NULL;
++	u_int bytes_sent = 0;
+ 
+ 	setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS),
+ 	    sizeof(fd_mask));
+-	packet_write_poll();
++	bytes_sent += packet_write_poll();
+ 	while (packet_have_data_to_write()) {
+ 		memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
+ 		    sizeof(fd_mask));
+@@ -1612,7 +1620,7 @@ packet_write_wait(void)
+ 			    "waiting to write", get_remote_ipaddr());
+ 			cleanup_exit(255);
+ 		}
+-		packet_write_poll();
++		bytes_sent += packet_write_poll();
+ 	}
+ 	xfree(setp);
+ }
+@@ -1736,12 +1744,24 @@ packet_send_ignore(int nbytes)
+ 	}
+ }
+ 
++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
+ 	    (p_send.packets > MAX_PACKETS) ||
+ 	    (p_read.packets > MAX_PACKETS) ||
+@@ -1766,3 +1786,9 @@ packet_set_authenticated(void)
+ {
+ 	after_authentication = 1;
+ }
++
++int
++packet_authentication_state(void)
++{
++	return(after_authentication);
++}
+diff -NupwB packet.h packet.h
+--- packet.h	2008-07-11 03:36:48.000000000 -0400
++++ packet.h	2009-05-14 12:36:10.000000000 -0400
+@@ -20,6 +20,9 @@
+ 
+ #include <openssl/bn.h>
+ 
++void
++packet_request_rekeying(void);
++
+ void     packet_set_connection(int, int);
+ void     packet_set_timeout(int, int);
+ void     packet_set_nonblocking(void);
+@@ -35,6 +38,7 @@ void     packet_set_interactive(int);
+ 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);
+@@ -44,7 +48,7 @@ void     packet_put_bignum2(BIGNUM * val
+ 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);
+@@ -73,8 +77,8 @@ void	 packet_set_state(int, u_int32_t, u
+ int	 packet_get_ssh1_cipher(void);
+ void	 packet_set_iv(int, u_char *);
+ 
+-void     packet_write_poll(void);
+-void     packet_write_wait(void);
++int      packet_write_poll(void);
++int      packet_write_wait(void);
+ int      packet_have_data_to_write(void);
+ int      packet_not_very_much_data_to_write(void);
+ 
+diff -NupwB progressmeter.c progressmeter.c
+--- progressmeter.c	2006-08-04 22:39:40.000000000 -0400
++++ progressmeter.c	2009-05-14 12:36:10.000000000 -0400
+@@ -68,6 +68,8 @@ static time_t last_update;	/* last progr
+ 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 @@ refresh_progress_meter(void)
+ 	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 @@ refresh_progress_meter(void)
+ 
+ 	/* 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 @@ refresh_progress_meter(void)
+ 		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 @@ refresh_progress_meter(void)
+ 	    (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 @@ refresh_progress_meter(void)
+ 
+ 	atomicio(vwrite, STDOUT_FILENO, buf, win_size - 1);
+ 	last_update = now;
++	last_pos = cur_pos;
+ }
+ 
+ /*ARGSUSED*/
+diff -NupwB readconf.c readconf.c
+--- readconf.c	2009-02-14 00:28:21.000000000 -0500
++++ readconf.c	2009-05-14 12:36:10.000000000 -0400
+@@ -131,6 +131,8 @@ typedef enum {
+ 	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
+ 	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
+ 	oVisualHostKey, oZeroKnowledgePasswordAuthentication,
++	oNoneEnabled, oTcpRcvBufPoll, oTcpRcvBuf, oNoneSwitch, oHPNDisabled,
++	oHPNBufferSize,
+ 	oDeprecated, oUnsupported
+ } OpCodes;
+ 
+@@ -234,6 +236,12 @@ static struct {
+ #else
+ 	{ "zeroknowledgepasswordauthentication", oUnsupported },
+ #endif
++	{ "noneenabled", oNoneEnabled },
++	{ "tcprcvbufpoll", oTcpRcvBufPoll },
++	{ "tcprcvbuf", oTcpRcvBuf },
++	{ "noneswitch", oNoneSwitch },
++	{ "hpndisabled", oHPNDisabled },
++	{ "hpnbuffersize", oHPNBufferSize },
+ 
+ 	{ NULL, oBadOption }
+ };
+@@ -465,6 +473,37 @@ parse_flag:
+ 		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;
+@@ -643,6 +682,10 @@ parse_int:
+ 		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);
+@@ -1065,6 +1108,12 @@ initialize_options(Options * options)
+ 	options->permit_local_command = -1;
+ 	options->visual_host_key = -1;
+ 	options->zero_knowledge_password_authentication = -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;
+ }
+ 
+ /*
+@@ -1187,6 +1236,29 @@ fill_default_options(Options * options)
+ 		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->hash_known_hosts == -1)
+diff -NupwB readconf.c.orig readconf.c.orig
+--- readconf.c.orig	1969-12-31 19:00:00.000000000 -0500
++++ readconf.c.orig	2009-02-14 00:28:21.000000000 -0500
+@@ -0,0 +1,1310 @@
++/* $OpenBSD: readconf.c,v 1.176 2009/02/12 03:00:56 djm Exp $ */
++/*
++ * Author: Tatu Ylonen <ylo at cs.hut.fi>
++ * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
++ *                    All rights reserved
++ * Functions for reading the configuration files.
++ *
++ * As far as I am concerned, the code I have written for this software
++ * can be used freely for any purpose.  Any derived versions of this
++ * software must be clearly marked as such, and if the derived work is
++ * incompatible with the protocol description in the RFC file, it must be
++ * called by a name other than "ssh" or "Secure Shell".
++ */
++
++#include "includes.h"
++
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <sys/socket.h>
++
++#include <netinet/in.h>
++
++#include <ctype.h>
++#include <errno.h>
++#include <netdb.h>
++#include <signal.h>
++#include <stdarg.h>
++#include <stdio.h>
++#include <string.h>
++#include <unistd.h>
++
++#include "xmalloc.h"
++#include "ssh.h"
++#include "compat.h"
++#include "cipher.h"
++#include "pathnames.h"
++#include "log.h"
++#include "key.h"
++#include "readconf.h"
++#include "match.h"
++#include "misc.h"
++#include "buffer.h"
++#include "kex.h"
++#include "mac.h"
++
++/* Format of the configuration file:
++
++   # 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.
++
++   # Host-specific declarations.  These may override anything above.  A single
++   # host may match multiple declarations; these are processed in the order
++   # that they are given in.
++
++   Host *.ngs.fi ngs.fi
++     User foo
++
++   Host fake.com
++     HostName another.host.name.real.org
++     User blaah
++     Port 34289
++     ForwardX11 no
++     ForwardAgent no
++
++   Host books.com
++     RemoteForward 9999 shadows.cs.hut.fi:9999
++     Cipher 3des
++
++   Host fascist.blob.com
++     Port 23123
++     User tylonen
++     PasswordAuthentication no
++
++   Host puukko.hut.fi
++     User t35124p
++     ProxyCommand ssh-proxy %h %p
++
++   Host *.fr
++     PublicKeyAuthentication no
++
++   Host *.su
++     Cipher none
++     PasswordAuthentication no
++
++   Host vpn.fake.com
++     Tunnel yes
++     TunnelDevice 3
++
++   # Defaults for various options
++   Host *
++     ForwardAgent no
++     ForwardX11 no
++     PasswordAuthentication yes
++     RSAAuthentication yes
++     RhostsRSAAuthentication yes
++     StrictHostKeyChecking yes
++     TcpKeepAlive no
++     IdentityFile ~/.ssh/identity
++     Port 22
++     EscapeChar ~
++
++*/
++
++/* Keyword tokens. */
++
++typedef enum {
++	oBadOption,
++	oForwardAgent, oForwardX11, oForwardX11Trusted, oGatewayPorts,
++	oExitOnForwardFailure,
++	oPasswordAuthentication, oRSAAuthentication,
++	oChallengeResponseAuthentication, oXAuthLocation,
++	oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
++	oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
++	oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
++	oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
++	oCompressionLevel, oTCPKeepAlive, oNumberOfPasswordPrompts,
++	oUsePrivilegedPort, oLogLevel, oCiphers, oProtocol, oMacs,
++	oGlobalKnownHostsFile2, oUserKnownHostsFile2, oPubkeyAuthentication,
++	oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
++	oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
++	oHostKeyAlgorithms, oBindAddress, oSmartcardDevice,
++	oClearAllForwardings, oNoHostAuthenticationForLocalhost,
++	oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
++	oAddressFamily, oGssAuthentication, oGssDelegateCreds,
++	oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
++	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
++	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
++	oVisualHostKey, oZeroKnowledgePasswordAuthentication,
++	oDeprecated, oUnsupported
++} OpCodes;
++
++/* Textual representations of the tokens. */
++
++static struct {
++	const char *name;
++	OpCodes opcode;
++} keywords[] = {
++	{ "forwardagent", oForwardAgent },
++	{ "forwardx11", oForwardX11 },
++	{ "forwardx11trusted", oForwardX11Trusted },
++	{ "exitonforwardfailure", oExitOnForwardFailure },
++	{ "xauthlocation", oXAuthLocation },
++	{ "gatewayports", oGatewayPorts },
++	{ "useprivilegedport", oUsePrivilegedPort },
++	{ "rhostsauthentication", oDeprecated },
++	{ "passwordauthentication", oPasswordAuthentication },
++	{ "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
++	{ "kbdinteractivedevices", oKbdInteractiveDevices },
++	{ "rsaauthentication", oRSAAuthentication },
++	{ "pubkeyauthentication", oPubkeyAuthentication },
++	{ "dsaauthentication", oPubkeyAuthentication },		    /* alias */
++	{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
++	{ "hostbasedauthentication", oHostbasedAuthentication },
++	{ "challengeresponseauthentication", oChallengeResponseAuthentication },
++	{ "skeyauthentication", oChallengeResponseAuthentication }, /* alias */
++	{ "tisauthentication", oChallengeResponseAuthentication },  /* alias */
++	{ "kerberosauthentication", oUnsupported },
++	{ "kerberostgtpassing", oUnsupported },
++	{ "afstokenpassing", oUnsupported },
++#if defined(GSSAPI)
++	{ "gssapiauthentication", oGssAuthentication },
++	{ "gssapidelegatecredentials", oGssDelegateCreds },
++#else
++	{ "gssapiauthentication", oUnsupported },
++	{ "gssapidelegatecredentials", oUnsupported },
++#endif
++	{ "fallbacktorsh", oDeprecated },
++	{ "usersh", oDeprecated },
++	{ "identityfile", oIdentityFile },
++	{ "identityfile2", oIdentityFile },			/* obsolete */
++	{ "identitiesonly", oIdentitiesOnly },
++	{ "hostname", oHostName },
++	{ "hostkeyalias", oHostKeyAlias },
++	{ "proxycommand", oProxyCommand },
++	{ "port", oPort },
++	{ "cipher", oCipher },
++	{ "ciphers", oCiphers },
++	{ "macs", oMacs },
++	{ "protocol", oProtocol },
++	{ "remoteforward", oRemoteForward },
++	{ "localforward", oLocalForward },
++	{ "user", oUser },
++	{ "host", oHost },
++	{ "escapechar", oEscapeChar },
++	{ "globalknownhostsfile", oGlobalKnownHostsFile },
++	{ "globalknownhostsfile2", oGlobalKnownHostsFile2 },	/* obsolete */
++	{ "userknownhostsfile", oUserKnownHostsFile },
++	{ "userknownhostsfile2", oUserKnownHostsFile2 },	/* obsolete */
++	{ "connectionattempts", oConnectionAttempts },
++	{ "batchmode", oBatchMode },
++	{ "checkhostip", oCheckHostIP },
++	{ "stricthostkeychecking", oStrictHostKeyChecking },
++	{ "compression", oCompression },
++	{ "compressionlevel", oCompressionLevel },
++	{ "tcpkeepalive", oTCPKeepAlive },
++	{ "keepalive", oTCPKeepAlive },				/* obsolete */
++	{ "numberofpasswordprompts", oNumberOfPasswordPrompts },
++	{ "loglevel", oLogLevel },
++	{ "dynamicforward", oDynamicForward },
++	{ "preferredauthentications", oPreferredAuthentications },
++	{ "hostkeyalgorithms", oHostKeyAlgorithms },
++	{ "bindaddress", oBindAddress },
++#ifdef SMARTCARD
++	{ "smartcarddevice", oSmartcardDevice },
++#else
++	{ "smartcarddevice", oUnsupported },
++#endif
++	{ "clearallforwardings", oClearAllForwardings },
++	{ "enablesshkeysign", oEnableSSHKeysign },
++	{ "verifyhostkeydns", oVerifyHostKeyDNS },
++	{ "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
++	{ "rekeylimit", oRekeyLimit },
++	{ "connecttimeout", oConnectTimeout },
++	{ "addressfamily", oAddressFamily },
++	{ "serveraliveinterval", oServerAliveInterval },
++	{ "serveralivecountmax", oServerAliveCountMax },
++	{ "sendenv", oSendEnv },
++	{ "controlpath", oControlPath },
++	{ "controlmaster", oControlMaster },
++	{ "hashknownhosts", oHashKnownHosts },
++	{ "tunnel", oTunnel },
++	{ "tunneldevice", oTunnelDevice },
++	{ "localcommand", oLocalCommand },
++	{ "permitlocalcommand", oPermitLocalCommand },
++	{ "visualhostkey", oVisualHostKey },
++#ifdef JPAKE
++	{ "zeroknowledgepasswordauthentication",
++	    oZeroKnowledgePasswordAuthentication },
++#else
++	{ "zeroknowledgepasswordauthentication", oUnsupported },
++#endif
++
++	{ NULL, oBadOption }
++};
++
++/*
++ * Adds a local TCP/IP port forward to options.  Never returns if there is an
++ * error.
++ */
++
++void
++add_local_forward(Options *options, const Forward *newfwd)
++{
++	Forward *fwd;
++#ifndef NO_IPPORT_RESERVED_CONCEPT
++	extern uid_t original_real_uid;
++	if (newfwd->listen_port < IPPORT_RESERVED && original_real_uid != 0)
++		fatal("Privileged ports can only be forwarded by root.");
++#endif
++	if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
++		fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
++	fwd = &options->local_forwards[options->num_local_forwards++];
++
++	fwd->listen_host = newfwd->listen_host;
++	fwd->listen_port = newfwd->listen_port;
++	fwd->connect_host = newfwd->connect_host;
++	fwd->connect_port = newfwd->connect_port;
++}
++
++/*
++ * Adds a remote TCP/IP port forward to options.  Never returns if there is
++ * an error.
++ */
++
++void
++add_remote_forward(Options *options, const Forward *newfwd)
++{
++	Forward *fwd;
++	if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
++		fatal("Too many remote forwards (max %d).",
++		    SSH_MAX_FORWARDS_PER_DIRECTION);
++	fwd = &options->remote_forwards[options->num_remote_forwards++];
++
++	fwd->listen_host = newfwd->listen_host;
++	fwd->listen_port = newfwd->listen_port;
++	fwd->connect_host = newfwd->connect_host;
++	fwd->connect_port = newfwd->connect_port;
++}
++
++static void
++clear_forwardings(Options *options)
++{
++	int i;
++
++	for (i = 0; i < options->num_local_forwards; i++) {
++		if (options->local_forwards[i].listen_host != NULL)
++			xfree(options->local_forwards[i].listen_host);
++		xfree(options->local_forwards[i].connect_host);
++	}
++	options->num_local_forwards = 0;
++	for (i = 0; i < options->num_remote_forwards; i++) {
++		if (options->remote_forwards[i].listen_host != NULL)
++			xfree(options->remote_forwards[i].listen_host);
++		xfree(options->remote_forwards[i].connect_host);
++	}
++	options->num_remote_forwards = 0;
++	options->tun_open = SSH_TUNMODE_NO;
++}
++
++/*
++ * Returns the number of the token pointed to by cp or oBadOption.
++ */
++
++static OpCodes
++parse_token(const char *cp, const char *filename, int linenum)
++{
++	u_int i;
++
++	for (i = 0; keywords[i].name; i++)
++		if (strcasecmp(cp, keywords[i].name) == 0)
++			return keywords[i].opcode;
++
++	error("%s: line %d: Bad configuration option: %s",
++	    filename, linenum, cp);
++	return oBadOption;
++}
++
++/*
++ * Processes a single option line as used in the configuration files. This
++ * only sets those values that have not already been set.
++ */
++#define WHITESPACE " \t\r\n"
++
++int
++process_config_line(Options *options, const char *host,
++		    char *line, const char *filename, int linenum,
++		    int *activep)
++{
++	char *s, **charptr, *endofnumber, *keyword, *arg, *arg2, fwdarg[256];
++	int opcode, *intptr, value, value2, scale;
++	LogLevel *log_level_ptr;
++	long long orig, val64;
++	size_t len;
++	Forward fwd;
++
++	/* Strip trailing whitespace */
++	for (len = strlen(line) - 1; len > 0; len--) {
++		if (strchr(WHITESPACE, line[len]) == NULL)
++			break;
++		line[len] = '\0';
++	}
++
++	s = line;
++	/* Get the keyword. (Each line is supposed to begin with a keyword). */
++	if ((keyword = strdelim(&s)) == NULL)
++		return 0;
++	/* Ignore leading whitespace. */
++	if (*keyword == '\0')
++		keyword = strdelim(&s);
++	if (keyword == NULL || !*keyword || *keyword == '\n' || *keyword == '#')
++		return 0;
++
++	opcode = parse_token(keyword, filename, linenum);
++
++	switch (opcode) {
++	case oBadOption:
++		/* don't panic, but count bad options */
++		return -1;
++		/* NOTREACHED */
++	case oConnectTimeout:
++		intptr = &options->connection_timeout;
++parse_time:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%s line %d: missing time value.",
++			    filename, linenum);
++		if ((value = convtime(arg)) == -1)
++			fatal("%s line %d: invalid time value.",
++			    filename, linenum);
++		if (*activep && *intptr == -1)
++			*intptr = value;
++		break;
++
++	case oForwardAgent:
++		intptr = &options->forward_agent;
++parse_flag:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
++		value = 0;	/* To avoid compiler warning... */
++		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
++			value = 1;
++		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
++			value = 0;
++		else
++			fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
++		if (*activep && *intptr == -1)
++			*intptr = value;
++		break;
++
++	case oForwardX11:
++		intptr = &options->forward_x11;
++		goto parse_flag;
++
++	case oForwardX11Trusted:
++		intptr = &options->forward_x11_trusted;
++		goto parse_flag;
++
++	case oGatewayPorts:
++		intptr = &options->gateway_ports;
++		goto parse_flag;
++
++	case oExitOnForwardFailure:
++		intptr = &options->exit_on_forward_failure;
++		goto parse_flag;
++
++	case oUsePrivilegedPort:
++		intptr = &options->use_privileged_port;
++		goto parse_flag;
++
++	case oPasswordAuthentication:
++		intptr = &options->password_authentication;
++		goto parse_flag;
++
++	case oZeroKnowledgePasswordAuthentication:
++		intptr = &options->zero_knowledge_password_authentication;
++		goto parse_flag;
++
++	case oKbdInteractiveAuthentication:
++		intptr = &options->kbd_interactive_authentication;
++		goto parse_flag;
++
++	case oKbdInteractiveDevices:
++		charptr = &options->kbd_interactive_devices;
++		goto parse_string;
++
++	case oPubkeyAuthentication:
++		intptr = &options->pubkey_authentication;
++		goto parse_flag;
++
++	case oRSAAuthentication:
++		intptr = &options->rsa_authentication;
++		goto parse_flag;
++
++	case oRhostsRSAAuthentication:
++		intptr = &options->rhosts_rsa_authentication;
++		goto parse_flag;
++
++	case oHostbasedAuthentication:
++		intptr = &options->hostbased_authentication;
++		goto parse_flag;
++
++	case oChallengeResponseAuthentication:
++		intptr = &options->challenge_response_authentication;
++		goto parse_flag;
++
++	case oGssAuthentication:
++		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;
++
++	case oCheckHostIP:
++		intptr = &options->check_host_ip;
++		goto parse_flag;
++
++	case oVerifyHostKeyDNS:
++		intptr = &options->verify_host_key_dns;
++		goto parse_yesnoask;
++
++	case oStrictHostKeyChecking:
++		intptr = &options->strict_host_key_checking;
++parse_yesnoask:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing yes/no/ask argument.",
++			    filename, linenum);
++		value = 0;	/* To avoid compiler warning... */
++		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
++			value = 1;
++		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
++			value = 0;
++		else if (strcmp(arg, "ask") == 0)
++			value = 2;
++		else
++			fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
++		if (*activep && *intptr == -1)
++			*intptr = value;
++		break;
++
++	case oCompression:
++		intptr = &options->compression;
++		goto parse_flag;
++
++	case oTCPKeepAlive:
++		intptr = &options->tcp_keep_alive;
++		goto parse_flag;
++
++	case oNoHostAuthenticationForLocalhost:
++		intptr = &options->no_host_authentication_for_localhost;
++		goto parse_flag;
++
++	case oNumberOfPasswordPrompts:
++		intptr = &options->number_of_password_prompts;
++		goto parse_int;
++
++	case oCompressionLevel:
++		intptr = &options->compression_level;
++		goto parse_int;
++
++	case oRekeyLimit:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		if (arg[0] < '0' || arg[0] > '9')
++			fatal("%.200s line %d: Bad number.", filename, linenum);
++		orig = val64 = strtoll(arg, &endofnumber, 10);
++		if (arg == endofnumber)
++			fatal("%.200s line %d: Bad number.", filename, linenum);
++		switch (toupper(*endofnumber)) {
++		case '\0':
++			scale = 1;
++			break;
++		case 'K':
++			scale = 1<<10;
++			break;
++		case 'M':
++			scale = 1<<20;
++			break;
++		case 'G':
++			scale = 1<<30;
++			break;
++		default:
++			fatal("%.200s line %d: Invalid RekeyLimit suffix",
++			    filename, linenum);
++		}
++		val64 *= scale;
++		/* detect integer wrap and too-large limits */
++		if ((val64 / scale) != orig || val64 > UINT_MAX)
++			fatal("%.200s line %d: RekeyLimit too large",
++			    filename, linenum);
++		if (val64 < 16)
++			fatal("%.200s line %d: RekeyLimit too small",
++			    filename, linenum);
++		if (*activep && options->rekey_limit == -1)
++			options->rekey_limit = (u_int32_t)val64;
++		break;
++
++	case oIdentityFile:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		if (*activep) {
++			intptr = &options->num_identity_files;
++			if (*intptr >= SSH_MAX_IDENTITY_FILES)
++				fatal("%.200s line %d: Too many identity files specified (max %d).",
++				    filename, linenum, SSH_MAX_IDENTITY_FILES);
++			charptr = &options->identity_files[*intptr];
++			*charptr = xstrdup(arg);
++			*intptr = *intptr + 1;
++		}
++		break;
++
++	case oXAuthLocation:
++		charptr=&options->xauth_location;
++		goto parse_string;
++
++	case oUser:
++		charptr = &options->user;
++parse_string:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		if (*activep && *charptr == NULL)
++			*charptr = xstrdup(arg);
++		break;
++
++	case oGlobalKnownHostsFile:
++		charptr = &options->system_hostfile;
++		goto parse_string;
++
++	case oUserKnownHostsFile:
++		charptr = &options->user_hostfile;
++		goto parse_string;
++
++	case oGlobalKnownHostsFile2:
++		charptr = &options->system_hostfile2;
++		goto parse_string;
++
++	case oUserKnownHostsFile2:
++		charptr = &options->user_hostfile2;
++		goto parse_string;
++
++	case oHostName:
++		charptr = &options->hostname;
++		goto parse_string;
++
++	case oHostKeyAlias:
++		charptr = &options->host_key_alias;
++		goto parse_string;
++
++	case oPreferredAuthentications:
++		charptr = &options->preferred_authentications;
++		goto parse_string;
++
++	case oBindAddress:
++		charptr = &options->bind_address;
++		goto parse_string;
++
++	case oSmartcardDevice:
++		charptr = &options->smartcard_device;
++		goto parse_string;
++
++	case oProxyCommand:
++		charptr = &options->proxy_command;
++parse_command:
++		if (s == NULL)
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		len = strspn(s, WHITESPACE "=");
++		if (*activep && *charptr == NULL)
++			*charptr = xstrdup(s + len);
++		return 0;
++
++	case oPort:
++		intptr = &options->port;
++parse_int:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		if (arg[0] < '0' || arg[0] > '9')
++			fatal("%.200s line %d: Bad number.", filename, linenum);
++
++		/* Octal, decimal, or hex format? */
++		value = strtol(arg, &endofnumber, 0);
++		if (arg == endofnumber)
++			fatal("%.200s line %d: Bad number.", filename, linenum);
++		if (*activep && *intptr == -1)
++			*intptr = value;
++		break;
++
++	case oConnectionAttempts:
++		intptr = &options->connection_attempts;
++		goto parse_int;
++
++	case oCipher:
++		intptr = &options->cipher;
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		value = cipher_number(arg);
++		if (value == -1)
++			fatal("%.200s line %d: Bad cipher '%s'.",
++			    filename, linenum, arg ? arg : "<NONE>");
++		if (*activep && *intptr == -1)
++			*intptr = value;
++		break;
++
++	case oCiphers:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		if (!ciphers_valid(arg))
++			fatal("%.200s line %d: Bad SSH2 cipher spec '%s'.",
++			    filename, linenum, arg ? arg : "<NONE>");
++		if (*activep && options->ciphers == NULL)
++			options->ciphers = xstrdup(arg);
++		break;
++
++	case oMacs:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		if (!mac_valid(arg))
++			fatal("%.200s line %d: Bad SSH2 Mac spec '%s'.",
++			    filename, linenum, arg ? arg : "<NONE>");
++		if (*activep && options->macs == NULL)
++			options->macs = xstrdup(arg);
++		break;
++
++	case oHostKeyAlgorithms:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		if (!key_names_valid2(arg))
++			fatal("%.200s line %d: Bad protocol 2 host key algorithms '%s'.",
++			    filename, linenum, arg ? arg : "<NONE>");
++		if (*activep && options->hostkeyalgorithms == NULL)
++			options->hostkeyalgorithms = xstrdup(arg);
++		break;
++
++	case oProtocol:
++		intptr = &options->protocol;
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		value = proto_spec(arg);
++		if (value == SSH_PROTO_UNKNOWN)
++			fatal("%.200s line %d: Bad protocol spec '%s'.",
++			    filename, linenum, arg ? arg : "<NONE>");
++		if (*activep && *intptr == SSH_PROTO_UNKNOWN)
++			*intptr = value;
++		break;
++
++	case oLogLevel:
++		log_level_ptr = &options->log_level;
++		arg = strdelim(&s);
++		value = log_level_number(arg);
++		if (value == SYSLOG_LEVEL_NOT_SET)
++			fatal("%.200s line %d: unsupported log level '%s'",
++			    filename, linenum, arg ? arg : "<NONE>");
++		if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
++			*log_level_ptr = (LogLevel) value;
++		break;
++
++	case oLocalForward:
++	case oRemoteForward:
++	case oDynamicForward:
++		arg = strdelim(&s);
++		if (arg == NULL || *arg == '\0')
++			fatal("%.200s line %d: Missing port argument.",
++			    filename, linenum);
++
++		if (opcode == oLocalForward ||
++		    opcode == oRemoteForward) {
++			arg2 = strdelim(&s);
++			if (arg2 == NULL || *arg2 == '\0')
++				fatal("%.200s line %d: Missing target argument.",
++				    filename, linenum);
++
++			/* construct a string for parse_forward */
++			snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2);
++		} else if (opcode == oDynamicForward) {
++			strlcpy(fwdarg, arg, sizeof(fwdarg));
++		}
++
++		if (parse_forward(&fwd, fwdarg,
++		    opcode == oDynamicForward ? 1 : 0,
++		    opcode == oRemoteForward ? 1 : 0) == 0)
++			fatal("%.200s line %d: Bad forwarding specification.",
++			    filename, linenum);
++
++		if (*activep) {
++			if (opcode == oLocalForward ||
++			    opcode == oDynamicForward)
++				add_local_forward(options, &fwd);
++			else if (opcode == oRemoteForward)
++				add_remote_forward(options, &fwd);
++		}
++		break;
++
++	case oClearAllForwardings:
++		intptr = &options->clear_forwardings;
++		goto parse_flag;
++
++	case oHost:
++		*activep = 0;
++		while ((arg = strdelim(&s)) != NULL && *arg != '\0')
++			if (match_pattern(host, arg)) {
++				debug("Applying options for %.100s", arg);
++				*activep = 1;
++				break;
++			}
++		/* Avoid garbage check below, as strdelim is done. */
++		return 0;
++
++	case oEscapeChar:
++		intptr = &options->escape_char;
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		if (arg[0] == '^' && arg[2] == 0 &&
++		    (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
++			value = (u_char) arg[1] & 31;
++		else if (strlen(arg) == 1)
++			value = (u_char) arg[0];
++		else if (strcmp(arg, "none") == 0)
++			value = SSH_ESCAPECHAR_NONE;
++		else {
++			fatal("%.200s line %d: Bad escape character.",
++			    filename, linenum);
++			/* NOTREACHED */
++			value = 0;	/* Avoid compiler warning. */
++		}
++		if (*activep && *intptr == -1)
++			*intptr = value;
++		break;
++
++	case oAddressFamily:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%s line %d: missing address family.",
++			    filename, linenum);
++		intptr = &options->address_family;
++		if (strcasecmp(arg, "inet") == 0)
++			value = AF_INET;
++		else if (strcasecmp(arg, "inet6") == 0)
++			value = AF_INET6;
++		else if (strcasecmp(arg, "any") == 0)
++			value = AF_UNSPEC;
++		else
++			fatal("Unsupported AddressFamily \"%s\"", arg);
++		if (*activep && *intptr == -1)
++			*intptr = value;
++		break;
++
++	case oEnableSSHKeysign:
++		intptr = &options->enable_ssh_keysign;
++		goto parse_flag;
++
++	case oIdentitiesOnly:
++		intptr = &options->identities_only;
++		goto parse_flag;
++
++	case oServerAliveInterval:
++		intptr = &options->server_alive_interval;
++		goto parse_time;
++
++	case oServerAliveCountMax:
++		intptr = &options->server_alive_count_max;
++		goto parse_int;
++
++	case oSendEnv:
++		while ((arg = strdelim(&s)) != NULL && *arg != '\0') {
++			if (strchr(arg, '=') != NULL)
++				fatal("%s line %d: Invalid environment name.",
++				    filename, linenum);
++			if (!*activep)
++				continue;
++			if (options->num_send_env >= MAX_SEND_ENV)
++				fatal("%s line %d: too many send env.",
++				    filename, linenum);
++			options->send_env[options->num_send_env++] =
++			    xstrdup(arg);
++		}
++		break;
++
++	case oControlPath:
++		charptr = &options->control_path;
++		goto parse_string;
++
++	case oControlMaster:
++		intptr = &options->control_master;
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing ControlMaster argument.",
++			    filename, linenum);
++		value = 0;	/* To avoid compiler warning... */
++		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
++			value = SSHCTL_MASTER_YES;
++		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
++			value = SSHCTL_MASTER_NO;
++		else if (strcmp(arg, "auto") == 0)
++			value = SSHCTL_MASTER_AUTO;
++		else if (strcmp(arg, "ask") == 0)
++			value = SSHCTL_MASTER_ASK;
++		else if (strcmp(arg, "autoask") == 0)
++			value = SSHCTL_MASTER_AUTO_ASK;
++		else
++			fatal("%.200s line %d: Bad ControlMaster argument.",
++			    filename, linenum);
++		if (*activep && *intptr == -1)
++			*intptr = value;
++		break;
++
++	case oHashKnownHosts:
++		intptr = &options->hash_known_hosts;
++		goto parse_flag;
++
++	case oTunnel:
++		intptr = &options->tun_open;
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%s line %d: Missing yes/point-to-point/"
++			    "ethernet/no argument.", filename, linenum);
++		value = 0;	/* silence compiler */
++		if (strcasecmp(arg, "ethernet") == 0)
++			value = SSH_TUNMODE_ETHERNET;
++		else if (strcasecmp(arg, "point-to-point") == 0)
++			value = SSH_TUNMODE_POINTOPOINT;
++		else if (strcasecmp(arg, "yes") == 0)
++			value = SSH_TUNMODE_DEFAULT;
++		else if (strcasecmp(arg, "no") == 0)
++			value = SSH_TUNMODE_NO;
++		else
++			fatal("%s line %d: Bad yes/point-to-point/ethernet/"
++			    "no argument: %s", filename, linenum, arg);
++		if (*activep)
++			*intptr = value;
++		break;
++
++	case oTunnelDevice:
++		arg = strdelim(&s);
++		if (!arg || *arg == '\0')
++			fatal("%.200s line %d: Missing argument.", filename, linenum);
++		value = a2tun(arg, &value2);
++		if (value == SSH_TUNID_ERR)
++			fatal("%.200s line %d: Bad tun device.", filename, linenum);
++		if (*activep) {
++			options->tun_local = value;
++			options->tun_remote = value2;
++		}
++		break;
++
++	case oLocalCommand:
++		charptr = &options->local_command;
++		goto parse_command;
++
++	case oPermitLocalCommand:
++		intptr = &options->permit_local_command;
++		goto parse_flag;
++
++	case oVisualHostKey:
++		intptr = &options->visual_host_key;
++		goto parse_flag;
++
++	case oDeprecated:
++		debug("%s line %d: Deprecated option \"%s\"",
++		    filename, linenum, keyword);
++		return 0;
++
++	case oUnsupported:
++		error("%s line %d: Unsupported option \"%s\"",
++		    filename, linenum, keyword);
++		return 0;
++
++	default:
++		fatal("process_config_line: Unimplemented opcode %d", opcode);
++	}
++
++	/* Check that there is no garbage at end of line. */
++	if ((arg = strdelim(&s)) != NULL && *arg != '\0') {
++		fatal("%.200s line %d: garbage at end of line; \"%.200s\".",
++		    filename, linenum, arg);
++	}
++	return 0;
++}
++
++
++/*
++ * Reads the config file and modifies the options accordingly.  Options
++ * should already be initialized before this call.  This never returns if
++ * there is an error.  If the file does not exist, this returns 0.
++ */
++
++int
++read_config_file(const char *filename, const char *host, Options *options,
++    int checkperm)
++{
++	FILE *f;
++	char line[1024];
++	int active, linenum;
++	int bad_options = 0;
++
++	if ((f = fopen(filename, "r")) == NULL)
++		return 0;
++
++	if (checkperm) {
++		struct stat sb;
++
++		if (fstat(fileno(f), &sb) == -1)
++			fatal("fstat %s: %s", filename, strerror(errno));
++		if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
++		    (sb.st_mode & 022) != 0))
++			fatal("Bad owner or permissions on %s", filename);
++	}
++
++	debug("Reading configuration data %.200s", filename);
++
++	/*
++	 * Mark that we are now processing the options.  This flag is turned
++	 * on/off by Host specifications.
++	 */
++	active = 1;
++	linenum = 0;
++	while (fgets(line, sizeof(line), f)) {
++		/* Update line number counter. */
++		linenum++;
++		if (process_config_line(options, host, line, filename, linenum, &active) != 0)
++			bad_options++;
++	}
++	fclose(f);
++	if (bad_options > 0)
++		fatal("%s: terminating, %d bad configuration options",
++		    filename, bad_options);
++	return 1;
++}
++
++/*
++ * Initializes options to special values that indicate that they have not yet
++ * been set.  Read_config_file will only set options with this value. Options
++ * are processed in the following order: command line, user config file,
++ * system config file.  Last, fill_default_options is called.
++ */
++
++void
++initialize_options(Options * options)
++{
++	memset(options, 'X', sizeof(*options));
++	options->forward_agent = -1;
++	options->forward_x11 = -1;
++	options->forward_x11_trusted = -1;
++	options->exit_on_forward_failure = -1;
++	options->xauth_location = NULL;
++	options->gateway_ports = -1;
++	options->use_privileged_port = -1;
++	options->rsa_authentication = -1;
++	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;
++	options->rhosts_rsa_authentication = -1;
++	options->hostbased_authentication = -1;
++	options->batch_mode = -1;
++	options->check_host_ip = -1;
++	options->strict_host_key_checking = -1;
++	options->compression = -1;
++	options->tcp_keep_alive = -1;
++	options->compression_level = -1;
++	options->port = -1;
++	options->address_family = -1;
++	options->connection_attempts = -1;
++	options->connection_timeout = -1;
++	options->number_of_password_prompts = -1;
++	options->cipher = -1;
++	options->ciphers = NULL;
++	options->macs = NULL;
++	options->hostkeyalgorithms = NULL;
++	options->protocol = SSH_PROTO_UNKNOWN;
++	options->num_identity_files = 0;
++	options->hostname = NULL;
++	options->host_key_alias = NULL;
++	options->proxy_command = NULL;
++	options->user = NULL;
++	options->escape_char = -1;
++	options->system_hostfile = NULL;
++	options->user_hostfile = NULL;
++	options->system_hostfile2 = NULL;
++	options->user_hostfile2 = NULL;
++	options->num_local_forwards = 0;
++	options->num_remote_forwards = 0;
++	options->clear_forwardings = -1;
++	options->log_level = SYSLOG_LEVEL_NOT_SET;
++	options->preferred_authentications = NULL;
++	options->bind_address = NULL;
++	options->smartcard_device = NULL;
++	options->enable_ssh_keysign = - 1;
++	options->no_host_authentication_for_localhost = - 1;
++	options->identities_only = - 1;
++	options->rekey_limit = - 1;
++	options->verify_host_key_dns = -1;
++	options->server_alive_interval = -1;
++	options->server_alive_count_max = -1;
++	options->num_send_env = 0;
++	options->control_path = NULL;
++	options->control_master = -1;
++	options->hash_known_hosts = -1;
++	options->tun_open = -1;
++	options->tun_local = -1;
++	options->tun_remote = -1;
++	options->local_command = NULL;
++	options->permit_local_command = -1;
++	options->visual_host_key = -1;
++	options->zero_knowledge_password_authentication = -1;
++}
++
++/*
++ * Called after processing other sources of option data, this fills those
++ * options for which no value has been specified with their default values.
++ */
++
++void
++fill_default_options(Options * options)
++{
++	int len;
++
++	if (options->forward_agent == -1)
++		options->forward_agent = 0;
++	if (options->forward_x11 == -1)
++		options->forward_x11 = 0;
++	if (options->forward_x11_trusted == -1)
++		options->forward_x11_trusted = 0;
++	if (options->exit_on_forward_failure == -1)
++		options->exit_on_forward_failure = 0;
++	if (options->xauth_location == NULL)
++		options->xauth_location = _PATH_XAUTH;
++	if (options->gateway_ports == -1)
++		options->gateway_ports = 0;
++	if (options->use_privileged_port == -1)
++		options->use_privileged_port = 0;
++	if (options->rsa_authentication == -1)
++		options->rsa_authentication = 1;
++	if (options->pubkey_authentication == -1)
++		options->pubkey_authentication = 1;
++	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)
++		options->kbd_interactive_authentication = 1;
++	if (options->rhosts_rsa_authentication == -1)
++		options->rhosts_rsa_authentication = 0;
++	if (options->hostbased_authentication == -1)
++		options->hostbased_authentication = 0;
++	if (options->batch_mode == -1)
++		options->batch_mode = 0;
++	if (options->check_host_ip == -1)
++		options->check_host_ip = 1;
++	if (options->strict_host_key_checking == -1)
++		options->strict_host_key_checking = 2;	/* 2 is default */
++	if (options->compression == -1)
++		options->compression = 0;
++	if (options->tcp_keep_alive == -1)
++		options->tcp_keep_alive = 1;
++	if (options->compression_level == -1)
++		options->compression_level = 6;
++	if (options->port == -1)
++		options->port = 0;	/* Filled in ssh_connect. */
++	if (options->address_family == -1)
++		options->address_family = AF_UNSPEC;
++	if (options->connection_attempts == -1)
++		options->connection_attempts = 1;
++	if (options->number_of_password_prompts == -1)
++		options->number_of_password_prompts = 3;
++	/* Selected in ssh_login(). */
++	if (options->cipher == -1)
++		options->cipher = SSH_CIPHER_NOT_SET;
++	/* options->ciphers, default set in myproposals.h */
++	/* options->macs, default set in myproposals.h */
++	/* options->hostkeyalgorithms, default set in myproposals.h */
++	if (options->protocol == SSH_PROTO_UNKNOWN)
++		options->protocol = SSH_PROTO_1|SSH_PROTO_2;
++	if (options->num_identity_files == 0) {
++		if (options->protocol & SSH_PROTO_1) {
++			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
++			options->identity_files[options->num_identity_files] =
++			    xmalloc(len);
++			snprintf(options->identity_files[options->num_identity_files++],
++			    len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
++		}
++		if (options->protocol & SSH_PROTO_2) {
++			len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
++			options->identity_files[options->num_identity_files] =
++			    xmalloc(len);
++			snprintf(options->identity_files[options->num_identity_files++],
++			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_RSA);
++
++			len = 2 + strlen(_PATH_SSH_CLIENT_ID_DSA) + 1;
++			options->identity_files[options->num_identity_files] =
++			    xmalloc(len);
++			snprintf(options->identity_files[options->num_identity_files++],
++			    len, "~/%.100s", _PATH_SSH_CLIENT_ID_DSA);
++		}
++	}
++	if (options->escape_char == -1)
++		options->escape_char = '~';
++	if (options->system_hostfile == NULL)
++		options->system_hostfile = _PATH_SSH_SYSTEM_HOSTFILE;
++	if (options->user_hostfile == NULL)
++		options->user_hostfile = _PATH_SSH_USER_HOSTFILE;
++	if (options->system_hostfile2 == NULL)
++		options->system_hostfile2 = _PATH_SSH_SYSTEM_HOSTFILE2;
++	if (options->user_hostfile2 == NULL)
++		options->user_hostfile2 = _PATH_SSH_USER_HOSTFILE2;
++	if (options->log_level == SYSLOG_LEVEL_NOT_SET)
++		options->log_level = SYSLOG_LEVEL_INFO;
++	if (options->clear_forwardings == 1)
++		clear_forwardings(options);
++	if (options->no_host_authentication_for_localhost == - 1)
++		options->no_host_authentication_for_localhost = 0;
++	if (options->identities_only == -1)
++		options->identities_only = 0;
++	if (options->enable_ssh_keysign == -1)
++		options->enable_ssh_keysign = 0;
++	if (options->rekey_limit == -1)
++		options->rekey_limit = 0;
++	if (options->verify_host_key_dns == -1)
++		options->verify_host_key_dns = 0;
++	if (options->server_alive_interval == -1)
++		options->server_alive_interval = 0;
++	if (options->server_alive_count_max == -1)
++		options->server_alive_count_max = 3;
++	if (options->control_master == -1)
++		options->control_master = 0;
++	if (options->hash_known_hosts == -1)
++		options->hash_known_hosts = 0;
++	if (options->tun_open == -1)
++		options->tun_open = SSH_TUNMODE_NO;
++	if (options->tun_local == -1)
++		options->tun_local = SSH_TUNID_ANY;
++	if (options->tun_remote == -1)
++		options->tun_remote = SSH_TUNID_ANY;
++	if (options->permit_local_command == -1)
++		options->permit_local_command = 0;
++	if (options->visual_host_key == -1)
++		options->visual_host_key = 0;
++	if (options->zero_knowledge_password_authentication == -1)
++		options->zero_knowledge_password_authentication = 0;
++	/* options->local_command should not be set by default */
++	/* options->proxy_command should not be set by default */
++	/* options->user will be set in the main program if appropriate */
++	/* options->hostname will be set in the main program if appropriate */
++	/* options->host_key_alias should not be set by default */
++	/* options->preferred_authentications will be set in ssh */
++}
++
++/*
++ * parse_forward
++ * parses a string containing a port forwarding specification of the form:
++ *   dynamicfwd == 0
++ *	[listenhost:]listenport:connecthost:connectport
++ *   dynamicfwd == 1
++ *	[listenhost:]listenport
++ * returns number of arguments parsed or zero on error
++ */
++int
++parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
++{
++	int i;
++	char *p, *cp, *fwdarg[4];
++
++	memset(fwd, '\0', sizeof(*fwd));
++
++	cp = p = xstrdup(fwdspec);
++
++	/* skip leading spaces */
++	while (isspace(*cp))
++		cp++;
++
++	for (i = 0; i < 4; ++i)
++		if ((fwdarg[i] = hpdelim(&cp)) == NULL)
++			break;
++
++	/* Check for trailing garbage */
++	if (cp != NULL)
++		i = 0;	/* failure */
++
++	switch (i) {
++	case 1:
++		fwd->listen_host = NULL;
++		fwd->listen_port = a2port(fwdarg[0]);
++		fwd->connect_host = xstrdup("socks");
++		break;
++
++	case 2:
++		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
++		fwd->listen_port = a2port(fwdarg[1]);
++		fwd->connect_host = xstrdup("socks");
++		break;
++
++	case 3:
++		fwd->listen_host = NULL;
++		fwd->listen_port = a2port(fwdarg[0]);
++		fwd->connect_host = xstrdup(cleanhostname(fwdarg[1]));
++		fwd->connect_port = a2port(fwdarg[2]);
++		break;
++
++	case 4:
++		fwd->listen_host = xstrdup(cleanhostname(fwdarg[0]));
++		fwd->listen_port = a2port(fwdarg[1]);
++		fwd->connect_host = xstrdup(cleanhostname(fwdarg[2]));
++		fwd->connect_port = a2port(fwdarg[3]);
++		break;
++	default:
++		i = 0; /* failure */
++	}
++
++	xfree(p);
++
++	if (dynamicfwd) {
++		if (!(i == 1 || i == 2))
++			goto fail_free;
++	} else {
++		if (!(i == 3 || i == 4))
++			goto fail_free;
++		if (fwd->connect_port <= 0)
++			goto fail_free;
++	}
++
++	if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0))
++		goto fail_free;
++
++	if (fwd->connect_host != NULL &&
++	    strlen(fwd->connect_host) >= NI_MAXHOST)
++		goto fail_free;
++	if (fwd->listen_host != NULL &&
++	    strlen(fwd->listen_host) >= NI_MAXHOST)
++		goto fail_free;
++
++
++	return (i);
++
++ fail_free:
++	if (fwd->connect_host != NULL) {
++		xfree(fwd->connect_host);
++		fwd->connect_host = NULL;
++	}
++	if (fwd->listen_host != NULL) {
++		xfree(fwd->listen_host);
++		fwd->listen_host = NULL;
++	}
++	return (0);
++}
+diff -NupwB readconf.h readconf.h
+--- readconf.h	2009-02-14 00:28:21.000000000 -0500
++++ readconf.h	2009-05-14 12:36:10.000000000 -0400
+@@ -57,6 +57,11 @@ typedef struct {
+ 	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 */
++
+ 	LogLevel log_level;	/* Level for logging. */
+ 
+ 	int     port;		/* Port to connect. */
+@@ -102,6 +107,8 @@ typedef struct {
+ 
+ 	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 -NupwB readconf.h.orig readconf.h.orig
+--- readconf.h.orig	1969-12-31 19:00:00.000000000 -0500
++++ readconf.h.orig	2009-02-14 00:28:21.000000000 -0500
+@@ -0,0 +1,145 @@
++/* $OpenBSD: readconf.h,v 1.78 2009/02/12 03:00:56 djm Exp $ */
++
++/*
++ * Author: Tatu Ylonen <ylo at cs.hut.fi>
++ * Copyright (c) 1995 Tatu Ylonen <ylo at cs.hut.fi>, Espoo, Finland
++ *                    All rights reserved
++ * Functions for reading the configuration file.
++ *
++ * As far as I am concerned, the code I have written for this software
++ * can be used freely for any purpose.  Any derived versions of this
++ * software must be clearly marked as such, and if the derived work is
++ * incompatible with the protocol description in the RFC file, it must be
++ * called by a name other than "ssh" or "Secure Shell".
++ */
++
++#ifndef READCONF_H
++#define READCONF_H
++
++/* Data structure for representing a forwarding request. */
++
++typedef struct {
++	char	 *listen_host;		/* Host (address) to listen on. */
++	int	  listen_port;		/* Port to forward. */
++	char	 *connect_host;		/* Host to connect. */
++	int	  connect_port;		/* Port to connect on connect_host. */
++}       Forward;
++/* Data structure for representing option data. */
++
++#define MAX_SEND_ENV	256
++
++typedef struct {
++	int     forward_agent;	/* Forward authentication agent. */
++	int     forward_x11;	/* Forward X11 display. */
++	int     forward_x11_trusted;	/* Trust Forward X11 display. */
++	int     exit_on_forward_failure;	/* Exit if bind(2) fails for -L/-R */
++	char   *xauth_location;	/* Location for xauth program */
++	int     gateway_ports;	/* Allow remote connects to forwarded ports. */
++	int     use_privileged_port;	/* Don't use privileged port if false. */
++	int     rhosts_rsa_authentication;	/* Try rhosts with RSA
++						 * authentication. */
++	int     rsa_authentication;	/* Try RSA authentication. */
++	int     pubkey_authentication;	/* Try ssh2 pubkey authentication. */
++	int     hostbased_authentication;	/* ssh2's rhosts_rsa */
++	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. */
++	char	*kbd_interactive_devices; /* Keyboard-interactive auth devices. */
++	int     zero_knowledge_password_authentication;	/* Try jpake */
++	int     batch_mode;	/* Batch mode: do not ask for passwords. */
++	int     check_host_ip;	/* Also keep track of keys for IP address */
++	int     strict_host_key_checking;	/* Strict host key checking. */
++	int     compression;	/* Compress packets in both directions. */
++	int     compression_level;	/* Compression level 1 (fast) to 9
++					 * (best). */
++	int     tcp_keep_alive;	/* Set SO_KEEPALIVE. */
++	LogLevel log_level;	/* Level for logging. */
++
++	int     port;		/* Port to connect. */
++	int     address_family;
++	int     connection_attempts;	/* Max attempts (seconds) before
++					 * giving up */
++	int     connection_timeout;	/* Max time (seconds) before
++					 * aborting connection attempt */
++	int     number_of_password_prompts;	/* Max number of password
++						 * prompts. */
++	int     cipher;		/* Cipher to use. */
++	char   *ciphers;	/* SSH2 ciphers in order of preference. */
++	char   *macs;		/* SSH2 macs in order of preference. */
++	char   *hostkeyalgorithms;	/* SSH2 server key types in order of preference. */
++	int	protocol;	/* Protocol in order of preference. */
++	char   *hostname;	/* Real host to connect. */
++	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     escape_char;	/* Escape character; -2 = none */
++
++	char   *system_hostfile;/* Path for /etc/ssh/ssh_known_hosts. */
++	char   *user_hostfile;	/* Path for $HOME/.ssh/known_hosts. */
++	char   *system_hostfile2;
++	char   *user_hostfile2;
++	char   *preferred_authentications;
++	char   *bind_address;	/* local socket address for connection to sshd */
++	char   *smartcard_device; /* Smartcard reader device */
++	int	verify_host_key_dns;	/* Verify host key using DNS */
++
++	int     num_identity_files;	/* Number of files for RSA/DSA identities. */
++	char   *identity_files[SSH_MAX_IDENTITY_FILES];
++	Key    *identity_keys[SSH_MAX_IDENTITY_FILES];
++
++	/* Local TCP/IP forward requests. */
++	int     num_local_forwards;
++	Forward local_forwards[SSH_MAX_FORWARDS_PER_DIRECTION];
++
++	/* Remote TCP/IP forward requests. */
++	int     num_remote_forwards;
++	Forward remote_forwards[SSH_MAX_FORWARDS_PER_DIRECTION];
++	int	clear_forwardings;
++
++	int	enable_ssh_keysign;
++	int64_t rekey_limit;
++	int	no_host_authentication_for_localhost;
++	int	identities_only;
++	int	server_alive_interval;
++	int	server_alive_count_max;
++
++	int     num_send_env;
++	char   *send_env[MAX_SEND_ENV];
++
++	char	*control_path;
++	int	control_master;
++
++	int	hash_known_hosts;
++
++	int	tun_open;	/* tun(4) */
++	int     tun_local;	/* force tun device (optional) */
++	int     tun_remote;	/* force tun device (optional) */
++
++	char	*local_command;
++	int	permit_local_command;
++	int	visual_host_key;
++
++}       Options;
++
++#define SSHCTL_MASTER_NO	0
++#define SSHCTL_MASTER_YES	1
++#define SSHCTL_MASTER_AUTO	2
++#define SSHCTL_MASTER_ASK	3
++#define SSHCTL_MASTER_AUTO_ASK	4
++
++void     initialize_options(Options *);
++void     fill_default_options(Options *);
++int	 read_config_file(const char *, const char *, Options *, int);
++int	 parse_forward(Forward *, const char *, int, int);
++
++int
++process_config_line(Options *, const char *, char *, const char *, int, int *);
++
++void	 add_local_forward(Options *, const Forward *);
++void	 add_remote_forward(Options *, const Forward *);
++
++#endif				/* READCONF_H */
+Common subdirectories: regress and regress
+Common subdirectories: scard and scard
+diff -NupwB scp.c scp.c
+--- scp.c	2008-11-03 03:23:45.000000000 -0500
++++ scp.c	2009-05-14 12:36:10.000000000 -0400
+@@ -632,7 +632,7 @@ source(int argc, char **argv)
+ 	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) {
+@@ -868,7 +868,7 @@ sink(int argc, char **argv)
+ 	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 -NupwB servconf.h servconf.h
+--- servconf.h	2009-01-28 00:31:23.000000000 -0500
++++ servconf.h	2009-05-14 12:36:10.000000000 -0400
+@@ -145,6 +145,10 @@ typedef struct {
+ 	char   *adm_forced_command;
+ 
+ 	int	use_pam;		/* Enable auth via PAM */
++        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;
+ 
+diff -NupwB serverloop.c serverloop.c
+--- serverloop.c	2009-02-14 00:33:09.000000000 -0500
++++ serverloop.c	2009-05-14 12:36:10.000000000 -0400
+@@ -93,10 +93,10 @@ static int fdin;		/* Descriptor for stdi
+ 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. */
+@@ -121,6 +121,20 @@ static volatile sig_atomic_t received_si
+ 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
+  */
+@@ -410,6 +424,7 @@ process_input(fd_set *readset)
+ 		} else {
+ 			/* Buffer any received data. */
+ 			packet_process_incoming(buf, len);
++			fdout_bytes += len;
+ 		}
+ 	}
+ 	if (compat20)
+@@ -432,6 +447,7 @@ process_input(fd_set *readset)
+ 		} 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. */
+@@ -499,7 +515,7 @@ process_output(fd_set *writeset)
+ 	}
+ 	/* Send any buffered packet data to the client. */
+ 	if (FD_ISSET(connection_out, writeset))
+-		packet_write_poll();
++		stdin_bytes += packet_write_poll();
+ }
+ 
+ /*
+@@ -816,8 +832,10 @@ server_loop2(Authctxt *authctxt)
+ {
+ 	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;
+@@ -879,6 +897,11 @@ server_loop2(Authctxt *authctxt)
+ 
+ 	/* 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
+@@ -994,8 +1017,12 @@ server_request_tun(void)
+ 	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)
+@@ -1031,6 +1058,8 @@ server_request_session(void)
+ 	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 -NupwB session.c session.c
+--- session.c	2009-01-28 00:29:49.000000000 -0500
++++ session.c	2009-05-14 12:36:10.000000000 -0400
+@@ -230,6 +230,7 @@ auth_input_request_forwarding(struct pas
+ 	}
+ 
+ 	/* 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,
+@@ -2301,10 +2302,16 @@ session_set_fds(Session *s, int fdin, in
+ 	 */
+ 	if (s->chanid == -1)
+ 		fatal("no channel for session %d", s->self);
++	if (options.hpn_disabled)
+ 	channel_set_fds(s->chanid,
+ 	    fdout, fdin, fderr,
+ 	    fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
+ 	    1, is_tty, CHAN_SES_WINDOW_DEFAULT);
++	else 
++		channel_set_fds(s->chanid,
++		    fdout, fdin, fderr,
++	            fderr == -1 ? CHAN_EXTENDED_IGNORE : CHAN_EXTENDED_READ,
++		    1, is_tty, options.hpn_buffer_size);
+ }
+ 
+ /*
+diff -NupwB sftp.1 sftp.1
+--- sftp.1	2009-01-28 00:14:09.000000000 -0500
++++ sftp.1	2009-05-14 12:36:10.000000000 -0400
+@@ -203,7 +203,8 @@ This option may be useful in debugging t
+ 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 S Ar program
+ Name of the
+ .Ar program
+diff -NupwB sftp.c sftp.c
+--- sftp.c	2009-02-14 00:26:19.000000000 -0500
++++ sftp.c	2009-05-14 12:36:10.000000000 -0400
+@@ -75,7 +75,7 @@ int batchmode = 0;
+ size_t copy_buffer_len = 32768;
+ 
+ /* Number of concurrent outstanding requests */
+-size_t num_requests = 64;
++size_t num_requests = 256;
+ 
+ /* PID of ssh transport process */
+ static pid_t sshpid = -1;
+diff -NupwB ssh.c ssh.c
+--- ssh.c	2009-02-14 00:28:21.000000000 -0500
++++ ssh.c	2009-05-14 12:36:10.000000000 -0400
+@@ -492,9 +492,6 @@ main(int ac, char **av)
+ 			no_shell_flag = 1;
+ 			no_tty_flag = 1;
+ 			break;
+-		case 'T':
+-			no_tty_flag = 1;
+-			break;
+ 		case 'o':
+ 			dummy = 1;
+ 			line = xstrdup(optarg);
+@@ -503,6 +500,13 @@ main(int ac, char **av)
+ 				exit(255);
+ 			xfree(line);
+ 			break;
++		case 'T':
++			no_tty_flag = 1;
++			/* 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 's':
+ 			subsystem_flag = 1;
+ 			break;
+@@ -1142,6 +1146,9 @@ ssh_session2_open(void)
+ {
+ 	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);
+@@ -1162,9 +1169,75 @@ ssh_session2_open(void)
+ 	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;
+ 	}
+@@ -1172,7 +1245,10 @@ ssh_session2_open(void)
+ 	    "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 -NupwB sshconnect2.c sshconnect2.c
+--- sshconnect2.c	2008-11-05 00:20:47.000000000 -0500
++++ sshconnect2.c	2009-05-14 12:36:10.000000000 -0400
+@@ -78,6 +78,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
+@@ -350,6 +356,28 @@ ssh_userauth2(const char *local_user, co
+ 	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);
+ }
+ 
+diff -NupwB sshconnect.c sshconnect.c
+--- sshconnect.c	2009-02-01 06:19:54.000000000 -0500
++++ sshconnect.c	2009-05-14 12:36:10.000000000 -0400
+@@ -165,6 +165,31 @@ ssh_proxy_connect(const char *host, u_sh
+ }
+ 
+ /*
++ * 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
+@@ -187,12 +212,18 @@ ssh_create_socket(int privileged, struct
+ 			    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);
+ 	if (sock < 0)
+ 		error("socket: %.100s", strerror(errno));
+ 
++	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;
+@@ -536,7 +567,7 @@ ssh_exchange_identification(int timeout_
+ 	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 (atomicio(vwrite, connection_out, buf, strlen(buf)) != strlen(buf))
+ 		fatal("write: %.100s", strerror(errno));
+ 	client_version_string = xstrdup(buf);
+diff -NupwB sshd.c sshd.c
+--- sshd.c	2009-01-28 00:31:23.000000000 -0500
++++ sshd.c	2009-05-14 12:36:10.000000000 -0400
+@@ -136,6 +136,9 @@ int deny_severity;
+ #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. */
+@@ -415,7 +418,7 @@ sshd_exchange_identification(int sock_in
+ 		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. */
+@@ -466,6 +469,9 @@ sshd_exchange_identification(int sock_in
+ 	}
+ 	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);
+ 
+@@ -944,6 +950,8 @@ server_listen(void)
+ 	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)
+@@ -990,6 +998,11 @@ server_listen(void)
+ 
+ 		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.",
+@@ -1817,6 +1830,9 @@ main(int ac, char **av)
+ 	/* Log the connection. */
+ 	verbose("Connection from %.500s port %d", remote_ip, remote_port);
+ 
++	/* set the HPN options for the child */
++	channel_set_hpn(options.hpn_disabled, options.hpn_buffer_size);
++
+ 	/*
+ 	 * We don't want to listen forever unless the other side
+ 	 * successfully authenticates itself.  So we set up an alarm which is
+@@ -2171,9 +2187,15 @@ do_ssh2_kex(void)
+ {
+ 	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]);
+diff -NupwB sshd_config sshd_config
+--- sshd_config	2008-07-02 08:35:43.000000000 -0400
++++ sshd_config	2009-05-14 12:36:10.000000000 -0400
+@@ -112,6 +112,20 @@ Protocol 2
+ # 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
++
++# 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
+diff -NupwB version.h version.h
+--- version.h	2009-02-22 19:09:26.000000000 -0500
++++ version.h	2009-05-14 12:42:05.000000000 -0400
+@@ -3,4 +3,5 @@
+ #define SSH_VERSION	"OpenSSH_5.2"
+ 
+ #define SSH_PORTABLE	"p1"
+-#define SSH_RELEASE	SSH_VERSION SSH_PORTABLE
++#define SSH_HPN         "-hpn13v6"
++#define SSH_RELEASE	SSH_VERSION SSH_PORTABLE SSH_HPN
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/files/openssh-lpk+hpn-servconf.patch /usr/home/dindin/workspace/openssh-portable/files/openssh-lpk+hpn-servconf.patch
--- /usr/ports/security/openssh-portable/files/openssh-lpk+hpn-servconf.patch	2009-05-15 15:00:27.000000000 +0400
+++ /usr/home/dindin/workspace/openssh-portable/files/openssh-lpk+hpn-servconf.patch	1970-01-01 03:00:00.000000000 +0300
@@ -1,240 +0,0 @@
---- servconf.c.orig	2009-05-02 19:35:42.000000000 +0400
-+++ servconf.c	2009-05-02 19:37:13.000000000 +0400
-@@ -42,6 +42,10 @@
- #include "channels.h"
- #include "groupaccess.h"
- 
-+#ifdef WITH_LDAP_PUBKEY
-+#include "ldapauth.h"
-+#endif
-+
- static void add_listen_addr(ServerOptions *, char *, int);
- static void add_one_listen_addr(ServerOptions *, char *, int);
- 
-@@ -74,7 +78,7 @@
- 	options->ignore_user_known_hosts = -1;
- 	options->print_motd = -1;
- 	options->print_lastlog = -1;
--	options->x11_forwarding = -1;
-+	options->x11_forwarding = 1;
- 	options->x11_display_offset = -1;
- 	options->x11_use_localhost = -1;
- 	options->xauth_location = NULL;
-@@ -127,12 +131,39 @@
- 	options->num_permitted_opens = -1;
- 	options->adm_forced_command = NULL;
- 	options->chroot_directory = NULL;
-+ 	options->none_enabled = -1;
-+ 	options->tcp_rcv_buf_poll = -1;
-+ 	options->hpn_disabled = -1;
-+ 	options->hpn_buffer_size = -1;
- 	options->zero_knowledge_password_authentication = -1;
-+#ifdef WITH_LDAP_PUBKEY
-+	/* XXX dirty */
-+	options->lpk.ld = NULL;
-+	options->lpk.on = -1;
-+	options->lpk.servers = NULL;
-+	options->lpk.u_basedn = NULL;
-+	options->lpk.g_basedn = NULL;
-+	options->lpk.binddn = NULL;
-+	options->lpk.bindpw = NULL;
-+	options->lpk.sgroup = NULL;
-+	options->lpk.filter = NULL;
-+	options->lpk.fgroup = NULL;
-+	options->lpk.l_conf = NULL;
-+	options->lpk.tls = -1;
-+	options->lpk.b_timeout.tv_sec = -1;
-+	options->lpk.s_timeout.tv_sec = -1;
-+	options->lpk.flags = FLAG_EMPTY;
-+#endif
- }
- 
- 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 = 1;
-@@ -265,6 +296,32 @@
- 		options->permit_tun = SSH_TUNMODE_NO;
- 	if (options->zero_knowledge_password_authentication == -1)
- 		options->zero_knowledge_password_authentication = 0;
-+#ifdef WITH_LDAP_PUBKEY
-+	if (options->lpk.on == -1)
-+	    options->lpk.on = _DEFAULT_LPK_ON;
-+	if (options->lpk.servers == NULL)
-+	    options->lpk.servers = _DEFAULT_LPK_SERVERS;
-+	if (options->lpk.u_basedn == NULL)
-+	    options->lpk.u_basedn = _DEFAULT_LPK_UDN;
-+	if (options->lpk.g_basedn == NULL)
-+	    options->lpk.g_basedn = _DEFAULT_LPK_GDN;
-+	if (options->lpk.binddn == NULL)
-+	    options->lpk.binddn = _DEFAULT_LPK_BINDDN;
-+	if (options->lpk.bindpw == NULL)
-+	    options->lpk.bindpw = _DEFAULT_LPK_BINDPW;
-+	if (options->lpk.sgroup == NULL)
-+	    options->lpk.sgroup = _DEFAULT_LPK_SGROUP;
-+	if (options->lpk.filter == NULL)
-+	    options->lpk.filter = _DEFAULT_LPK_FILTER;
-+	if (options->lpk.tls == -1)
-+	    options->lpk.tls = _DEFAULT_LPK_TLS;
-+	if (options->lpk.b_timeout.tv_sec == -1)
-+	    options->lpk.b_timeout.tv_sec = _DEFAULT_LPK_BTIMEOUT;
-+	if (options->lpk.s_timeout.tv_sec == -1)
-+	    options->lpk.s_timeout.tv_sec = _DEFAULT_LPK_STIMEOUT;
-+	if (options->lpk.l_conf == NULL)
-+	    options->lpk.l_conf = _DEFAULT_LPK_LDP;
-+#endif
- 
- 	if (options->hpn_disabled == -1) 
- 		options->hpn_disabled = 0;
-@@ -345,8 +402,15 @@
- 	sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
- 	sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
- 	sUsePrivilegeSeparation, sAllowAgentForwarding,
-+ 	sNoneEnabled, sTcpRcvBufPoll, sHPNDisabled, sHPNBufferSize,
- 	sZeroKnowledgePasswordAuthentication,
- 	sDeprecated, sUnsupported
-+#ifdef WITH_LDAP_PUBKEY
-+	,sLdapPublickey, sLdapServers, sLdapUserDN
-+	,sLdapGroupDN, sBindDN, sBindPw, sMyGroup
-+	,sLdapFilter, sForceTLS, sBindTimeout
-+	,sSearchTimeout, sLdapConf
-+#endif
- } ServerOpCodes;
- 
- #define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
-@@ -457,6 +521,20 @@
- 	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
- 	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
- 	{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
-+#ifdef WITH_LDAP_PUBKEY
-+	{ _DEFAULT_LPK_TOKEN, sLdapPublickey, SSHCFG_GLOBAL },
-+	{ _DEFAULT_SRV_TOKEN, sLdapServers, SSHCFG_GLOBAL },
-+	{ _DEFAULT_USR_TOKEN, sLdapUserDN, SSHCFG_GLOBAL },
-+	{ _DEFAULT_GRP_TOKEN, sLdapGroupDN, SSHCFG_GLOBAL },
-+	{ _DEFAULT_BDN_TOKEN, sBindDN, SSHCFG_GLOBAL },
-+	{ _DEFAULT_BPW_TOKEN, sBindPw, SSHCFG_GLOBAL },
-+	{ _DEFAULT_MYG_TOKEN, sMyGroup, SSHCFG_GLOBAL },
-+	{ _DEFAULT_FIL_TOKEN, sLdapFilter, SSHCFG_GLOBAL },
-+	{ _DEFAULT_TLS_TOKEN, sForceTLS, SSHCFG_GLOBAL },
-+	{ _DEFAULT_BTI_TOKEN, sBindTimeout, SSHCFG_GLOBAL },
-+	{ _DEFAULT_STI_TOKEN, sSearchTimeout, SSHCFG_GLOBAL },
-+	{ _DEFAULT_LDP_TOKEN, sLdapConf, SSHCFG_GLOBAL },
-+#endif
- 	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
- 	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
- 	{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
-@@ -1368,6 +1446,107 @@
- 		while (arg)
- 		    arg = strdelim(&cp);
- 		break;
-+#ifdef WITH_LDAP_PUBKEY
-+	case sLdapPublickey:
-+		intptr = &options->lpk.on;
-+		goto parse_flag;
-+	case sLdapServers:
-+		/* arg = strdelim(&cp); */
-+		p = line;
-+		while(*p++);
-+		arg = p;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing ldap server",filename,linenum);
-+		arg[strlen(arg)] = '\0';
-+		if ((options->lpk.servers = ldap_parse_servers(arg)) == NULL)
-+		    fatal("%s line %d: error in ldap servers", filename, linenum);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sLdapUserDN:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing ldap server",filename,linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.u_basedn = xstrdup(arg);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sLdapGroupDN:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing ldap server",filename,linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.g_basedn = xstrdup(arg);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sBindDN:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing binddn",filename,linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.binddn = xstrdup(arg);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sBindPw:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing bindpw",filename,linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.bindpw = xstrdup(arg);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sMyGroup:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing groupname",filename, linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.sgroup = xstrdup(arg);
-+		if (options->lpk.sgroup)
-+		    options->lpk.fgroup = ldap_parse_groups(options->lpk.sgroup);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sLdapFilter:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing filter",filename, linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.filter = xstrdup(arg);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sForceTLS:
-+		intptr = &options->lpk.tls;
-+		arg = strdelim(&cp);
-+		if (!arg || *arg == '\0')
-+			fatal("%s line %d: missing yes/no argument.",
-+			    filename, linenum);
-+		value = 0;	/* silence compiler */
-+		if (strcmp(arg, "yes") == 0)
-+			value = 1;
-+		else if (strcmp(arg, "no") == 0)
-+			value = 0;
-+		else if (strcmp(arg, "try") == 0)
-+			value = -1;
-+		else
-+			fatal("%s line %d: Bad yes/no argument: %s",
-+				filename, linenum, arg);
-+		if (*intptr == -1)
-+			*intptr = value;
-+		break;
-+	case sBindTimeout:
-+		intptr = (int *) &options->lpk.b_timeout.tv_sec;
-+		goto parse_int;
-+	case sSearchTimeout:
-+		intptr = (int *) &options->lpk.s_timeout.tv_sec;
-+		goto parse_int;
-+		break;
-+	case sLdapConf:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing LpkLdapConf", filename, linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.l_conf = xstrdup(arg);
-+		memset(arg, 0, strlen(arg));
-+		break;
-+#endif
- 
- 	default:
- 		fatal("%s line %d: Missing handler for opcode %s (%d)",
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/files/openssh-lpk-5.0p1-0.3.9-servconv.patch /usr/home/dindin/workspace/openssh-portable/files/openssh-lpk-5.0p1-0.3.9-servconv.patch
--- /usr/ports/security/openssh-portable/files/openssh-lpk-5.0p1-0.3.9-servconv.patch	2009-05-15 15:00:27.000000000 +0400
+++ /usr/home/dindin/workspace/openssh-portable/files/openssh-lpk-5.0p1-0.3.9-servconv.patch	1970-01-01 03:00:00.000000000 +0300
@@ -1,222 +0,0 @@
---- servconf.c.orig	2009-05-02 19:24:09.000000000 +0400
-+++ servconf.c	2009-05-02 19:29:37.000000000 +0400
-@@ -42,6 +42,10 @@
- #include "channels.h"
- #include "groupaccess.h"
- 
-+#ifdef WITH_LDAP_PUBKEY
-+#include "ldapauth.h"
-+#endif
-+
- static void add_listen_addr(ServerOptions *, char *, int);
- static void add_one_listen_addr(ServerOptions *, char *, int);
- 
-@@ -74,7 +78,7 @@
- 	options->ignore_user_known_hosts = -1;
- 	options->print_motd = -1;
- 	options->print_lastlog = -1;
--	options->x11_forwarding = -1;
-+	options->x11_forwarding = 1;
- 	options->x11_display_offset = -1;
- 	options->x11_use_localhost = -1;
- 	options->xauth_location = NULL;
-@@ -128,6 +132,24 @@
- 	options->adm_forced_command = NULL;
- 	options->chroot_directory = NULL;
- 	options->zero_knowledge_password_authentication = -1;
-+#ifdef WITH_LDAP_PUBKEY
-+	/* XXX dirty */
-+	options->lpk.ld = NULL;
-+	options->lpk.on = -1;
-+	options->lpk.servers = NULL;
-+	options->lpk.u_basedn = NULL;
-+	options->lpk.g_basedn = NULL;
-+	options->lpk.binddn = NULL;
-+	options->lpk.bindpw = NULL;
-+	options->lpk.sgroup = NULL;
-+	options->lpk.filter = NULL;
-+	options->lpk.fgroup = NULL;
-+	options->lpk.l_conf = NULL;
-+	options->lpk.tls = -1;
-+	options->lpk.b_timeout.tv_sec = -1;
-+	options->lpk.s_timeout.tv_sec = -1;
-+	options->lpk.flags = FLAG_EMPTY;
-+#endif
- }
- 
- void
-@@ -265,6 +287,32 @@
- 		options->permit_tun = SSH_TUNMODE_NO;
- 	if (options->zero_knowledge_password_authentication == -1)
- 		options->zero_knowledge_password_authentication = 0;
-+#ifdef WITH_LDAP_PUBKEY
-+	if (options->lpk.on == -1)
-+	    options->lpk.on = _DEFAULT_LPK_ON;
-+	if (options->lpk.servers == NULL)
-+	    options->lpk.servers = _DEFAULT_LPK_SERVERS;
-+	if (options->lpk.u_basedn == NULL)
-+	    options->lpk.u_basedn = _DEFAULT_LPK_UDN;
-+	if (options->lpk.g_basedn == NULL)
-+	    options->lpk.g_basedn = _DEFAULT_LPK_GDN;
-+	if (options->lpk.binddn == NULL)
-+	    options->lpk.binddn = _DEFAULT_LPK_BINDDN;
-+	if (options->lpk.bindpw == NULL)
-+	    options->lpk.bindpw = _DEFAULT_LPK_BINDPW;
-+	if (options->lpk.sgroup == NULL)
-+	    options->lpk.sgroup = _DEFAULT_LPK_SGROUP;
-+	if (options->lpk.filter == NULL)
-+	    options->lpk.filter = _DEFAULT_LPK_FILTER;
-+	if (options->lpk.tls == -1)
-+	    options->lpk.tls = _DEFAULT_LPK_TLS;
-+	if (options->lpk.b_timeout.tv_sec == -1)
-+	    options->lpk.b_timeout.tv_sec = _DEFAULT_LPK_BTIMEOUT;
-+	if (options->lpk.s_timeout.tv_sec == -1)
-+	    options->lpk.s_timeout.tv_sec = _DEFAULT_LPK_STIMEOUT;
-+	if (options->lpk.l_conf == NULL)
-+	    options->lpk.l_conf = _DEFAULT_LPK_LDP;
-+#endif
- 
- 	/* Turn privilege separation on by default */
- 	if (use_privsep == -1)
-@@ -311,6 +359,12 @@
- 	sUsePrivilegeSeparation, sAllowAgentForwarding,
- 	sZeroKnowledgePasswordAuthentication,
- 	sDeprecated, sUnsupported
-+#ifdef WITH_LDAP_PUBKEY
-+	,sLdapPublickey, sLdapServers, sLdapUserDN
-+	,sLdapGroupDN, sBindDN, sBindPw, sMyGroup
-+	,sLdapFilter, sForceTLS, sBindTimeout
-+	,sSearchTimeout, sLdapConf
-+#endif
- } ServerOpCodes;
- 
- #define SSHCFG_GLOBAL	0x01	/* allowed in main section of sshd_config */
-@@ -421,6 +475,20 @@
- 	{ "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
- 	{ "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_GLOBAL },
- 	{ "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_GLOBAL },
-+#ifdef WITH_LDAP_PUBKEY
-+	{ _DEFAULT_LPK_TOKEN, sLdapPublickey, SSHCFG_GLOBAL },
-+	{ _DEFAULT_SRV_TOKEN, sLdapServers, SSHCFG_GLOBAL },
-+	{ _DEFAULT_USR_TOKEN, sLdapUserDN, SSHCFG_GLOBAL },
-+	{ _DEFAULT_GRP_TOKEN, sLdapGroupDN, SSHCFG_GLOBAL },
-+	{ _DEFAULT_BDN_TOKEN, sBindDN, SSHCFG_GLOBAL },
-+	{ _DEFAULT_BPW_TOKEN, sBindPw, SSHCFG_GLOBAL },
-+	{ _DEFAULT_MYG_TOKEN, sMyGroup, SSHCFG_GLOBAL },
-+	{ _DEFAULT_FIL_TOKEN, sLdapFilter, SSHCFG_GLOBAL },
-+	{ _DEFAULT_TLS_TOKEN, sForceTLS, SSHCFG_GLOBAL },
-+	{ _DEFAULT_BTI_TOKEN, sBindTimeout, SSHCFG_GLOBAL },
-+	{ _DEFAULT_STI_TOKEN, sSearchTimeout, SSHCFG_GLOBAL },
-+	{ _DEFAULT_LDP_TOKEN, sLdapConf, SSHCFG_GLOBAL },
-+#endif
- 	{ "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL },
- 	{ "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
- 	{ "permittunnel", sPermitTunnel, SSHCFG_GLOBAL },
-@@ -1311,6 +1379,107 @@
- 		while (arg)
- 		    arg = strdelim(&cp);
- 		break;
-+#ifdef WITH_LDAP_PUBKEY
-+	case sLdapPublickey:
-+		intptr = &options->lpk.on;
-+		goto parse_flag;
-+	case sLdapServers:
-+		/* arg = strdelim(&cp); */
-+		p = line;
-+		while(*p++);
-+		arg = p;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing ldap server",filename,linenum);
-+		arg[strlen(arg)] = '\0';
-+		if ((options->lpk.servers = ldap_parse_servers(arg)) == NULL)
-+		    fatal("%s line %d: error in ldap servers", filename, linenum);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sLdapUserDN:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing ldap server",filename,linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.u_basedn = xstrdup(arg);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sLdapGroupDN:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing ldap server",filename,linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.g_basedn = xstrdup(arg);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sBindDN:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing binddn",filename,linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.binddn = xstrdup(arg);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sBindPw:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing bindpw",filename,linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.bindpw = xstrdup(arg);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sMyGroup:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing groupname",filename, linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.sgroup = xstrdup(arg);
-+		if (options->lpk.sgroup)
-+		    options->lpk.fgroup = ldap_parse_groups(options->lpk.sgroup);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sLdapFilter:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing filter",filename, linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.filter = xstrdup(arg);
-+		memset(arg,0,strlen(arg));
-+		break;
-+	case sForceTLS:
-+		intptr = &options->lpk.tls;
-+		arg = strdelim(&cp);
-+		if (!arg || *arg == '\0')
-+			fatal("%s line %d: missing yes/no argument.",
-+			    filename, linenum);
-+		value = 0;	/* silence compiler */
-+		if (strcmp(arg, "yes") == 0)
-+			value = 1;
-+		else if (strcmp(arg, "no") == 0)
-+			value = 0;
-+		else if (strcmp(arg, "try") == 0)
-+			value = -1;
-+		else
-+			fatal("%s line %d: Bad yes/no argument: %s",
-+				filename, linenum, arg);
-+		if (*intptr == -1)
-+			*intptr = value;
-+		break;
-+	case sBindTimeout:
-+		intptr = (int *) &options->lpk.b_timeout.tv_sec;
-+		goto parse_int;
-+	case sSearchTimeout:
-+		intptr = (int *) &options->lpk.s_timeout.tv_sec;
-+		goto parse_int;
-+		break;
-+	case sLdapConf:
-+		arg = cp;
-+		if (!arg || *arg == '\0')
-+		    fatal("%s line %d: missing LpkLdapConf", filename, linenum);
-+		arg[strlen(arg)] = '\0';
-+		options->lpk.l_conf = xstrdup(arg);
-+		memset(arg, 0, strlen(arg));
-+		break;
-+#endif
- 
- 	default:
- 		fatal("%s line %d: Missing handler for opcode %s (%d)",
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/files/openssh-lpk-5.0p1-0.3.9.patch /usr/home/dindin/workspace/openssh-portable/files/openssh-lpk-5.0p1-0.3.9.patch
--- /usr/ports/security/openssh-portable/files/openssh-lpk-5.0p1-0.3.9.patch	2009-05-15 15:00:27.000000000 +0400
+++ /usr/home/dindin/workspace/openssh-portable/files/openssh-lpk-5.0p1-0.3.9.patch	1970-01-01 03:00:00.000000000 +0300
@@ -1,1653 +0,0 @@
-#
-# Based on: http://dev.inversepath.com/openssh-lpk/openssh-lpk-4.6p1-0.3.9.patch
-#
---- Makefile.in.orig	2008-03-12 22:41:31.000000000 -0300
-+++ Makefile.in	2008-04-17 21:25:41.000000000 -0300
-@@ -86,7 +86,7 @@
- 	auth-krb5.o \
- 	auth2-gss.o gss-serv.o gss-serv-krb5.o \
- 	loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \
--	audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o
-+	audit.o audit-bsm.o platform.o sftp-server.o sftp-common.o ldapauth.o
- 
- MANPAGES	= scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out ssh-keysign.8.out sshd_config.5.out ssh_config.5.out
- MANPAGES_IN	= scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 ssh-keysign.8 sshd_config.5 ssh_config.5
---- README.lpk.orig	2008-04-17 21:24:57.000000000 -0300
-+++ README.lpk	2008-04-17 21:24:57.000000000 -0300
-@@ -0,0 +1,267 @@
-+OpenSSH LDAP PUBLIC KEY PATCH 
-+Copyright (c) 2003 Eric AUGE (eau at phear.org)
-+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.
-+3. The name of the author may not be used to endorse or promote products
-+   derived from this software without specific prior written permission.
-+
-+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.
-+
-+purposes of this patch:
-+
-+This patch would help to have authentication centralization policy
-+using ssh public key authentication.
-+This patch could be an alternative to other "secure" authentication system
-+working in a similar way (Kerberos, SecurID, etc...), except the fact 
-+that it's based on OpenSSH and its public key abilities.
-+
-+>> FYI: <<
-+'uid': means unix accounts existing on the current server
-+'lpkServerGroup:' mean server group configured on the current server ('lpkServerGroup' in sshd_config)
-+
-+example schema:
-+
-+
-+                                  server1 (uid: eau,rival,toto) (lpkServerGroup: unix)
-+                ___________      /
-+               /           \ --- - server3 (uid: eau, titi) (lpkServerGroup: unix)
-+              | LDAP Server |    \
-+	      | eau  ,rival |     server2 (uid: rival, eau) (lpkServerGroup: unix)
-+	      | titi ,toto  |
-+	      | userx,....  |         server5 (uid: eau)  (lpkServerGroup: mail)
-+               \___________/ \       /
-+	                       ----- - server4 (uid: eau, rival)  (no group configured)
-+			             \
-+				        etc...
-+
-+- WHAT WE NEED :
-+
-+  * configured LDAP server somewhere on the network (i.e. OpenLDAP)
-+  * patched sshd (with this patch ;)
-+  * LDAP user(/group) entry (look at users.ldif (& groups.ldif)):
-+        User entry:
-+	- attached to the 'ldapPublicKey' objectclass
-+	- attached to the 'posixAccount' objectclass
-+	- with a filled 'sshPublicKey' attribute 
-+	Example:
-+		dn: uid=eau,ou=users,dc=cuckoos,dc=net
-+		objectclass: top
-+		objectclass: person
-+		objectclass: organizationalPerson
-+		objectclass: posixAccount
-+		objectclass: ldapPublicKey
-+		description: Eric AUGE Account
-+		userPassword: blah
-+		cn: Eric AUGE
-+		sn: Eric AUGE
-+		uid: eau
-+		uidNumber: 1034
-+		gidNumber: 1
-+		homeDirectory: /export/home/eau
-+		sshPublicKey: ssh-dss AAAAB3...
-+		sshPublicKey: ssh-dss AAAAM5...
-+
-+	Group entry:
-+	- attached to the 'posixGroup' objectclass
-+	- with a 'cn' groupname attribute
-+	- with multiple 'memberUid' attributes filled with usernames allowed in this group
-+	Example:
-+		# few members
-+		dn: cn=unix,ou=groups,dc=cuckoos,dc=net
-+		objectclass: top
-+		objectclass: posixGroup
-+		description: Unix based servers group
-+		cn: unix
-+		gidNumber: 1002
-+		memberUid: eau
-+		memberUid: user1
-+		memberUid: user2
-+
-+
-+- HOW IT WORKS :
-+
-+  * without patch
-+  If a user wants to authenticate to log in a server the sshd, will first look for authentication method allowed (RSAauth,kerberos,etc..)
-+  and if RSAauth and tickets based auth fails, it will fallback to standard password authentication (if enabled).
-+
-+  * with the patch
-+  If a user want to authenticate to log in a server, the sshd will first look for auth method including LDAP pubkey, if the ldappubkey options is enabled.
-+  It will do an ldapsearch to get the public key directly from the LDAP instead of reading it from the server filesystem. 
-+  (usually in $HOME/.ssh/authorized_keys)
-+
-+  If groups are enabled, it will also check if the user that wants to login is in the group of the server he is trying to log into.
-+  If it fails, it falls back on RSA auth files ($HOME/.ssh/authorized_keys), etc.. and finally to standard password authentication (if enabled).
-+
-+  7 tokens are added to sshd_config :
-+  # here is the new patched ldap related tokens
-+  # entries in your LDAP must be posixAccount & strongAuthenticationUser & posixGroup
-+  UseLPK yes								# look the pub key into LDAP
-+  LpkServers ldap://10.31.32.5/ ldap://10.31.32.4 ldap://10.31.32.3	# which LDAP server for users ? (URL format)
-+  LpkUserDN  ou=users,dc=foobar,dc=net					# which base DN for users ?
-+  LpkGroupDN ou=groups,dc=foobar,dc=net					# which base DN for groups ? 
-+  LpkBindDN cn=manager,dc=foobar,dc=net					# which bind DN ?
-+  LpkBindPw asecret							# bind DN credidentials
-+  LpkServerGroup agroupname						# the group the server is part of
-+
-+  Right now i'm using anonymous binding to get public keys, because getting public keys of someone doesn't impersonate him¸ but there is some
-+  flaws you have to take care of.
-+
-+- HOW TO INSERT A USER/KEY INTO AN LDAP ENTRY
-+
-+  * my way (there is plenty :)
-+  - create ldif file (i.e. users.ldif)
-+  - cat ~/.ssh/id_dsa.pub OR cat ~/.ssh/id_rsa.pub OR cat ~/.ssh/identity.pub
-+  - my way in 4 steps :
-+  Example:
-+
-+  # you add this to the user entry in the LDIF file :
-+  [...]
-+  objectclass: posixAccount
-+  objectclass: ldapPublicKey
-+  [...]
-+  sshPubliKey: ssh-dss AAAABDh12DDUR2...
-+  [...]
-+
-+  # insert your entry and you're done :)
-+  ldapadd -D balblabla -w bleh < file.ldif 
-+  
-+  all standard options can be present in the 'sshPublicKey' attribute.
-+
-+- WHY :
-+
-+  Simply because, i was looking for a way to centralize all sysadmins authentication, easily,  without completely using LDAP 
-+  as authentication method (like pam_ldap etc..).  
-+  
-+  After looking into Kerberos, SecurID, and other centralized secure authentications systems, the use of RSA and LDAP to get 
-+  public key for authentication allows us to control who has access to which server (the user needs an account and to be in 'strongAuthenticationUser'
-+  objectclass within LDAP and part of the group the SSH server is in). 
-+
-+  Passwords update are no longer a nightmare for a server farm (key pair passphrase is stored on each user's box and private key is locally encrypted using his passphrase 
-+  so each user can change it as much as he wants). 
-+
-+  Blocking a user account can be done directly from the LDAP (if sshd is using RSAAuth + ldap only).
-+
-+- RULES :  
-+  Entry in the LDAP server must respect 'posixAccount' and 'ldapPublicKey' which are defined in core.schema. 
-+  and the additionnal lpk.schema.
-+
-+  This patch could allow a smooth transition between standard auth (/etc/passwd) and complete LDAP based authentication 
-+  (pamldap, nss_ldap, etc..).
-+
-+  This can be an alternative to other (old?/expensive?) authentication methods (Kerberos/SecurID/..).
-+  
-+  Referring to schema at the beginning of this file if user 'eau' is only in group 'unix'
-+  'eau' would ONLY access 'server1', 'server2', 'server3' AND 'server4' BUT NOT 'server5'.
-+  If you then modify the LDAP 'mail' group entry to add 'memberUid: eau' THEN user 'eau' would be able
-+  to log in 'server5' (i hope you got the idea, my english is bad :).
-+
-+  Each server's sshd is patched and configured to ask the public key and the group infos in the LDAP
-+  server.
-+  When you want to allow a new user to have access to the server parc, you just add him an account on 
-+  your servers, you add his public key into his entry on the LDAP server, it's done. 
-+
-+  Because sshds are looking public keys into the LDAP directly instead of a file ($HOME/.ssh/authorized_keys).
-+
-+  When the user needs to change his passphrase he can do it directly from his workstation by changing 
-+  his own key set lock passphrase, and all servers are automatically aware.
-+ 
-+  With a CAREFUL LDAP server configuration you could allow a user to add/delete/modify his own entry himself
-+  so he can add/modify/delete himself his public key when needed.
-+
-+­ FLAWS :
-+  LDAP must be well configured, getting the public key of some user is not a problem, but if anonymous LDAP 
-+  allow write to users dn, somebody could replace someuser's public key by its own and impersonate some 
-+  of your users in all your server farm be VERY CAREFUL.
-+  
-+  MITM attack when sshd is requesting the public key, could lead to a compromise of your servers allowing login 
-+  as the impersonnated user.
-+
-+  If LDAP server is down then, fallback on passwd auth.
-+  
-+  the ldap code part has not been well audited yet.
-+
-+- LDAP USER ENTRY EXAMPLES (LDIF Format, look in users.ldif)
-+    --- CUT HERE ---
-+    dn: uid=jdoe,ou=users,dc=foobar,dc=net
-+    objectclass: top
-+    objectclass: person
-+    objectclass: organizationalPerson
-+    objectclass: posixAccount
-+    objectclass: ldapPublicKey
-+    description: My account
-+    cn: John Doe
-+    sn: John Doe
-+    uid: jdoe
-+    uidNumber: 100
-+    gidNumber: 100
-+    homeDirectory: /home/jdoe
-+    sshPublicKey: ssh-dss AAAAB3NzaC1kc3MAAAEBAOvL8pREUg9wSy/8+hQJ54YF3AXkB0OZrXB....
-+    [...]
-+    --- CUT HERE ---
-+
-+- LDAP GROUP ENTRY EXAMPLES (LDIF Format, look in groups.ldif)
-+    --- CUT HERE ---
-+    dn: cn=unix,ou=groups,dc=cuckoos,dc=net
-+    objectclass: top
-+    objectclass: posixGroup
-+    description: Unix based servers group
-+    cn: unix
-+    gidNumber: 1002
-+    memberUid: jdoe
-+    memberUid: user1
-+    memberUid: user2
-+    [...]
-+    --- CUT HERE ---
-+
-+>> FYI: << 
-+Multiple 'sshPublicKey' in a user entry are allowed, as well as multiple 'memberUid' attributes in a group entry
-+
-+- COMPILING:
-+  1. Apply the patch
-+  2. ./configure --with-your-options --with-ldap=/prefix/to/ldap_libs_and_includes
-+  3. make
-+  4. it's done.
-+
-+- BLA :
-+  I hope this could help, and i hope to be clear enough,, or give ideas.  questions/comments/improvements are welcome.
-+  
-+- TODO :
-+  Redesign differently.
-+
-+- DOCS/LINK :
-+  http://pacsec.jp/core05/psj05-barisani-en.pdf
-+  http://fritz.potsdam.edu/projects/openssh-lpk/
-+  http://fritz.potsdam.edu/projects/sshgate/
-+  http://dev.inversepath.com/trac/openssh-lpk
-+  http://lam.sf.net/ ( http://lam.sourceforge.net/documentation/supportedSchemas.htm )
-+
-+- CONTRIBUTORS/IDEAS/GREETS :
-+  - Falk Siemonsmeier.
-+  - Jacob Rief.
-+  - Michael Durchgraf.
-+  - frederic peters.
-+  - Finlay dobbie.
-+  - Stefan Fisher.
-+  - Robin H. Johnson.
-+  - Adrian Bridgett.
-+
-+- CONTACT :
-+  - Eric AUGE <eau at phear.org>
-+  - Andrea Barisani <andrea at inversepath.com>
---- auth-rsa.c.orig	2006-11-07 10:14:42.000000000 -0200
-+++ auth-rsa.c	2008-04-17 21:24:57.000000000 -0300
-@@ -175,10 +175,96 @@
- 	u_long linenum = 0;
- 	struct stat st;
- 	Key *key;
-+#ifdef WITH_LDAP_PUBKEY
-+	ldap_key_t * k;
-+	unsigned int i = 0;
-+#endif
- 
- 	/* Temporarily use the user's uid. */
- 	temporarily_use_uid(pw);
- 
-+#ifdef WITH_LDAP_PUBKEY
-+	/* here is the job */
-+	key = key_new(KEY_RSA1);
-+
-+	if (options.lpk.on) {
-+	    debug("[LDAP] trying LDAP first uid=%s", pw->pw_name);
-+	    if ( ldap_ismember(&options.lpk, pw->pw_name) > 0) {
-+		if ( (k = ldap_getuserkey(&options.lpk, pw->pw_name)) != NULL) {
-+		    for (i = 0 ; i < k->num ; i++) {
-+			char *cp, *options = NULL;
-+
-+			for (cp = k->keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++)
-+			    ;
-+			if (!*cp || *cp == '\n' || *cp == '#')
-+			    continue;
-+
-+			/*
-+			* Check if there are options for this key, and if so,
-+			* save their starting address and skip the option part
-+			* for now.  If there are no options, set the starting
-+			* address to NULL.
-+			 */
-+			if (*cp < '0' || *cp > '9') {
-+			    int quoted = 0;
-+			    options = cp;
-+			    for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
-+				if (*cp == '\\' && cp[1] == '"')
-+				    cp++;	/* Skip both */
-+				else if (*cp == '"')
-+				    quoted = !quoted;
-+			    }
-+			} else
-+			    options = NULL;
-+
-+			/* Parse the key from the line. */
-+			if (hostfile_read_key(&cp, &bits, key) == 0) {
-+			    debug("[LDAP] line %d: non ssh1 key syntax", i);
-+			    continue;
-+			}
-+			/* cp now points to the comment part. */
-+
-+			/* Check if the we have found the desired key (identified by its modulus). */
-+			if (BN_cmp(key->rsa->n, client_n) != 0)
-+			    continue;
-+
-+			/* check the real bits  */
-+			if (bits != (unsigned int)BN_num_bits(key->rsa->n))
-+			    logit("[LDAP] Warning: ldap, line %lu: keysize mismatch: "
-+				    "actual %d vs. announced %d.", (unsigned long)i, BN_num_bits(key->rsa->n), bits);
-+
-+			/* We have found the desired key. */
-+			/*
-+			* If our options do not allow this key to be used,
-+			* do not send challenge.
-+			 */
-+			if (!auth_parse_options(pw, options, "[LDAP]", (unsigned long) i))
-+			    continue;
-+
-+			/* break out, this key is allowed */
-+			allowed = 1;
-+
-+			/* add the return stuff etc... */
-+			/* Restore the privileged uid. */
-+			restore_uid();
-+
-+			/* return key if allowed */
-+			if (allowed && rkey != NULL)
-+			    *rkey = key;
-+			else
-+			    key_free(key);
-+
-+			ldap_keys_free(k);
-+			return (allowed);
-+		    }
-+		} else {
-+		    logit("[LDAP] no keys found for '%s'!", pw->pw_name);
-+		}
-+	    } else {
-+		logit("[LDAP] '%s' is not in '%s'", pw->pw_name, options.lpk.sgroup);
-+	    }
-+	}
-+#endif
- 	/* The authorized keys. */
- 	file = authorized_keys_file(pw);
- 	debug("trying public RSA key file %s", file);
---- auth2-pubkey.c.orig	2006-08-04 23:39:39.000000000 -0300
-+++ auth2-pubkey.c	2008-04-17 21:24:57.000000000 -0300
-@@ -53,6 +53,10 @@
- #include "monitor_wrap.h"
- #include "misc.h"
- 
-+#ifdef WITH_LDAP_PUBKEY
-+#include "ldapauth.h"
-+#endif
-+
- /* import */
- extern ServerOptions options;
- extern u_char *session_id2;
-@@ -186,10 +190,79 @@
- 	struct stat st;
- 	Key *found;
- 	char *fp;
-+#ifdef WITH_LDAP_PUBKEY
-+	ldap_key_t * k;
-+	unsigned int i = 0;
-+#endif
- 
- 	/* Temporarily use the user's uid. */
- 	temporarily_use_uid(pw);
- 
-+#ifdef WITH_LDAP_PUBKEY
-+ 	found_key = 0;
-+ 	/* allocate a new key type */
-+ 	found = key_new(key->type);
-+ 
-+ 	/* first check if the options is enabled, then try.. */
-+	if (options.lpk.on) {
-+	    debug("[LDAP] trying LDAP first uid=%s",pw->pw_name);
-+	    if (ldap_ismember(&options.lpk, pw->pw_name) > 0) {
-+		if ((k = ldap_getuserkey(&options.lpk, pw->pw_name)) != NULL) {
-+		    /* Skip leading whitespace, empty and comment lines. */
-+		    for (i = 0 ; i < k->num ; i++) {
-+			/* dont forget if multiple keys to reset options */
-+			char *cp, *options = NULL;
-+
-+			for (cp = (char *)k->keys[i]->bv_val; *cp == ' ' || *cp == '\t'; cp++)
-+			    ;
-+			if (!*cp || *cp == '\n' || *cp == '#')
-+			    continue;
-+
-+			if (key_read(found, &cp) != 1) {
-+			    /* no key?  check if there are options for this key */
-+			    int quoted = 0;
-+			    debug2("[LDAP] user_key_allowed: check options: '%s'", cp);
-+			    options = cp;
-+			    for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
-+				if (*cp == '\\' && cp[1] == '"')
-+				    cp++;	/* Skip both */
-+				else if (*cp == '"')
-+				    quoted = !quoted;
-+			    }
-+			    /* Skip remaining whitespace. */
-+			    for (; *cp == ' ' || *cp == '\t'; cp++)
-+				;
-+			    if (key_read(found, &cp) != 1) {
-+				debug2("[LDAP] user_key_allowed: advance: '%s'", cp);
-+				/* still no key?  advance to next line*/
-+				continue;
-+			    }
-+			}
-+
-+			if (key_equal(found, key) &&
-+				auth_parse_options(pw, options, file, linenum) == 1) {
-+			    found_key = 1;
-+			    debug("[LDAP] matching key found");
-+			    fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
-+			    verbose("[LDAP] Found matching %s key: %s", key_type(found), fp);
-+
-+			    /* restoring memory */
-+			    ldap_keys_free(k);
-+			    xfree(fp);
-+			    restore_uid();
-+			    key_free(found);
-+			    return found_key;
-+			    break;
-+			}
-+		    }/* end of LDAP for() */
-+		} else {
-+		    logit("[LDAP] no keys found for '%s'!", pw->pw_name);
-+		}
-+	    } else {
-+		logit("[LDAP] '%s' is not in '%s'", pw->pw_name, options.lpk.sgroup);
-+	    }
-+	}
-+#endif
- 	debug("trying public key file %s", file);
- 
- 	/* Fail quietly if file does not exist */
---- config.h.in.orig	2008-04-03 07:01:49.000000000 -0300
-+++ config.h.in	2008-04-17 21:24:57.000000000 -0300
-@@ -539,6 +539,9 @@
- /* Define to 1 if you have the <linux/if_tun.h> header file. */
- #undef HAVE_LINUX_IF_TUN_H
- 
-+/* Define if you want LDAP support */
-+#undef WITH_LDAP_PUBKEY
-+
- /* Define if your libraries define login() */
- #undef HAVE_LOGIN
- 
---- configure.ac.orig	2008-03-26 22:33:07.000000000 -0300
-+++ configure.ac	2008-04-17 21:24:57.000000000 -0300
-@@ -1285,6 +1285,37 @@
- 	esac ]
- )
- 
-+# Check whether user wants LDAP support
-+LDAP_MSG="no"
-+AC_ARG_WITH(ldap,
-+	[  --with-ldap[[=PATH]]      Enable LDAP pubkey support (optionally in PATH)],
-+	[
-+		if test "x$withval" != "xno" ; then
-+
-+			if test "x$withval" != "xyes" ; then
-+				CPPFLAGS="$CPPFLAGS -I${withval}/include"
-+				LDFLAGS="$LDFLAGS -L${withval}/lib"
-+			fi
-+
-+			AC_DEFINE([WITH_LDAP_PUBKEY], 1, [Enable LDAP pubkey support])
-+			LIBS="-lldap $LIBS"
-+			LDAP_MSG="yes"
-+	
-+			AC_MSG_CHECKING([for LDAP support])
-+			AC_TRY_COMPILE(
-+				[#include <sys/types.h>
-+				 #include <ldap.h>],
-+				[(void)ldap_init(0, 0);],
-+				[AC_MSG_RESULT(yes)],
-+				[
-+				    AC_MSG_RESULT(no) 
-+					AC_MSG_ERROR([** Incomplete or missing ldap libraries **])
-+				]
-+        	)
-+		fi
-+	]
-+)
-+
- dnl    Checks for library functions. Please keep in alphabetical order
- AC_CHECK_FUNCS( \
- 	arc4random \
-@@ -4089,6 +4120,7 @@
- echo "                 Smartcard support: $SCARD_MSG"
- echo "                     S/KEY support: $SKEY_MSG"
- echo "              TCP Wrappers support: $TCPW_MSG"
-+echo "                      LDAP support: $LDAP_MSG"
- echo "              MD5 password support: $MD5_MSG"
- echo "                   libedit support: $LIBEDIT_MSG"
- echo "  Solaris process contract support: $SPC_MSG"
---- configure.orig	2008-04-03 07:01:50.000000000 -0300
-+++ configure	2008-04-17 21:24:57.000000000 -0300
-@@ -1339,6 +1339,7 @@
-   --with-tcp-wrappers[=PATH] Enable tcpwrappers support (optionally in PATH)
-   --with-libedit[=PATH]   Enable libedit support for sftp
-   --with-audit=module     Enable EXPERIMENTAL audit support (modules=debug,bsm)
-+  --with-ldap[=PATH]      Enable LDAP pubkey support (optionally in PATH)
-   --with-ssl-dir=PATH     Specify path to OpenSSL installation
-   --without-openssl-header-check Disable OpenSSL version consistency check
-   --with-ssl-engine       Enable OpenSSL (hardware) ENGINE support
-@@ -12514,6 +12515,85 @@
- fi
- 
- 
-+# Check whether user wants LDAP support
-+LDAP_MSG="no"
-+
-+# Check whether --with-ldap was given.
-+if test "${with_ldap+set}" = set; then
-+  withval=$with_ldap;
-+		if test "x$withval" != "xno" ; then
-+
-+			if test "x$withval" != "xyes" ; then
-+				CPPFLAGS="$CPPFLAGS -I${withval}/include"
-+				LDFLAGS="$LDFLAGS -L${withval}/lib"
-+			fi
-+
-+
-+cat >>confdefs.h <<\_ACEOF
-+#define WITH_LDAP_PUBKEY 1
-+_ACEOF
-+
-+			LIBS="-lldap $LIBS"
-+			LDAP_MSG="yes"
-+
-+			{ echo "$as_me:$LINENO: checking for LDAP support" >&5
-+echo $ECHO_N "checking for LDAP support... $ECHO_C" >&6; }
-+			cat >conftest.$ac_ext <<_ACEOF
-+/* confdefs.h.  */
-+_ACEOF
-+cat confdefs.h >>conftest.$ac_ext
-+cat >>conftest.$ac_ext <<_ACEOF
-+/* end confdefs.h.  */
-+#include <sys/types.h>
-+				 #include <ldap.h>
-+int
-+main ()
-+{
-+(void)ldap_init(0, 0);
-+  ;
-+  return 0;
-+}
-+_ACEOF
-+rm -f conftest.$ac_objext
-+if { (ac_try="$ac_compile"
-+case "(($ac_try" in
-+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-+  *) ac_try_echo=$ac_try;;
-+esac
-+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-+  (eval "$ac_compile") 2>conftest.er1
-+  ac_status=$?
-+  grep -v '^ *+' conftest.er1 >conftest.err
-+  rm -f conftest.er1
-+  cat conftest.err >&5
-+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-+  (exit $ac_status); } && {
-+	 test -z "$ac_c_werror_flag" ||
-+	 test ! -s conftest.err
-+       } && test -s conftest.$ac_objext; then
-+  { echo "$as_me:$LINENO: result: yes" >&5
-+echo "${ECHO_T}yes" >&6; }
-+else
-+  echo "$as_me: failed program was:" >&5
-+sed 's/^/| /' conftest.$ac_ext >&5
-+
-+
-+				    { echo "$as_me:$LINENO: result: no" >&5
-+echo "${ECHO_T}no" >&6; }
-+					{ { echo "$as_me:$LINENO: error: ** Incomplete or missing ldap libraries **" >&5
-+echo "$as_me: error: ** Incomplete or missing ldap libraries **" >&2;}
-+   { (exit 1); exit 1; }; }
-+
-+
-+fi
-+
-+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-+		fi
-+
-+
-+fi
-+
-+
- 
- 
- 
-@@ -29860,6 +29940,7 @@
- echo "                 Smartcard support: $SCARD_MSG"
- echo "                     S/KEY support: $SKEY_MSG"
- echo "              TCP Wrappers support: $TCPW_MSG"
-+echo "                      LDAP support: $LDAP_MSG"
- echo "              MD5 password support: $MD5_MSG"
- echo "                   libedit support: $LIBEDIT_MSG"
- echo "  Solaris process contract support: $SPC_MSG"
---- ldapauth.c.orig	2008-04-17 21:24:57.000000000 -0300
-+++ ldapauth.c	2008-04-17 21:24:57.000000000 -0300
-@@ -0,0 +1,575 @@
-+/* 
-+ * $Id: openssh-lpk-5.0p1-0.3.9.patch,v 1.2 2009/05/15 11:00:27 pav Exp $
-+ */
-+
-+/*
-+ *
-+ * Copyright (c) 2005, Eric AUGE <eau at phear.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-+ *
-+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-+ * 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.
-+ * Neither the name of the phear.org nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
-+ *
-+ *
-+ */
-+
-+#include "includes.h"
-+
-+#ifdef WITH_LDAP_PUBKEY
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+
-+#include "ldapauth.h"
-+#include "log.h"
-+
-+static char *attrs[] = {
-+    PUBKEYATTR,
-+    NULL
-+};
-+
-+/* filter building infos */
-+#define FILTER_GROUP_PREFIX "(&(objectclass=posixGroup)"
-+#define FILTER_OR_PREFIX "(|"
-+#define FILTER_OR_SUFFIX ")"
-+#define FILTER_CN_PREFIX "(cn="
-+#define FILTER_CN_SUFFIX ")"
-+#define FILTER_UID_FORMAT "(memberUid=%s)"
-+#define FILTER_GROUP_SUFFIX ")"
-+#define FILTER_GROUP_SIZE(group) (size_t) (strlen(group)+(ldap_count_group(group)*5)+52)
-+
-+/* just filter building stuff */
-+#define REQUEST_GROUP_SIZE(filter, uid) (size_t) (strlen(filter)+strlen(uid)+1)
-+#define REQUEST_GROUP(buffer, prefilter, pwname) \
-+    buffer = (char *) calloc(REQUEST_GROUP_SIZE(prefilter, pwname), sizeof(char)); \
-+    if (!buffer) { \
-+        perror("calloc()"); \
-+        return FAILURE; \
-+    } \
-+    snprintf(buffer, REQUEST_GROUP_SIZE(prefilter,pwname), prefilter, pwname)
-+/*
-+XXX OLD group building macros
-+#define REQUEST_GROUP_SIZE(grp, uid) (size_t) (strlen(grp)+strlen(uid)+46)
-+#define REQUEST_GROUP(buffer,pwname,grp) \
-+    buffer = (char *) calloc(REQUEST_GROUP_SIZE(grp, pwname), sizeof(char)); \
-+    if (!buffer) { \
-+        perror("calloc()"); \
-+        return FAILURE; \
-+    } \
-+    snprintf(buffer,REQUEST_GROUP_SIZE(grp,pwname),"(&(objectclass=posixGroup)(cn=%s)(memberUid=%s))",grp,pwname)
-+    */
-+
-+/*
-+XXX stock upstream version without extra filter support
-+#define REQUEST_USER_SIZE(uid) (size_t) (strlen(uid)+64)
-+#define REQUEST_USER(buffer, pwname) \
-+    buffer = (char *) calloc(REQUEST_USER_SIZE(pwname), sizeof(char)); \
-+    if (!buffer) { \
-+        perror("calloc()"); \
-+        return NULL; \
-+    } \
-+    snprintf(buffer,REQUEST_USER_SIZE(pwname),"(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s))",pwname)
-+   */
-+
-+#define REQUEST_USER_SIZE(uid, filter) (size_t) (strlen(uid)+64+(filter != NULL ? strlen(filter) : 0))
-+#define REQUEST_USER(buffer, pwname, customfilter) \
-+    buffer = (char *) calloc(REQUEST_USER_SIZE(pwname, customfilter), sizeof(char)); \
-+    if (!buffer) { \
-+        perror("calloc()"); \
-+        return NULL; \
-+    } \
-+    snprintf(buffer, REQUEST_USER_SIZE(pwname, customfilter), \
-+    	"(&(objectclass=posixAccount)(objectclass=ldapPublicKey)(uid=%s)%s)", \
-+	pwname, (customfilter != NULL ? customfilter : ""))
-+
-+/* some portable and working tokenizer, lame though */
-+static int tokenize(char ** o, size_t size, char * input) {
-+    unsigned int i = 0, num;
-+    const char * charset = " \t";
-+    char * ptr = input;
-+
-+    /* leading white spaces are ignored */
-+    num = strspn(ptr, charset);
-+    ptr += num;
-+
-+    while ((num = strcspn(ptr, charset))) {
-+        if (i < size-1) {
-+            o[i++] = ptr;
-+            ptr += num;
-+            if (*ptr)
-+                *ptr++ = '\0';
-+        }
-+    }
-+    o[i] = NULL;
-+    return SUCCESS;
-+}
-+
-+void ldap_close(ldap_opt_t * ldap) {
-+
-+    if (!ldap)
-+        return;
-+
-+    if ( ldap_unbind_ext(ldap->ld, NULL, NULL) < 0)
-+	ldap_perror(ldap->ld, "ldap_unbind()");
-+
-+    ldap->ld = NULL;
-+    FLAG_SET_DISCONNECTED(ldap->flags);
-+
-+    return;
-+}
-+
-+/* init && bind */
-+int ldap_connect(ldap_opt_t * ldap) {
-+    int version = LDAP_VERSION3;
-+
-+    if (!ldap->servers)
-+        return FAILURE;
-+
-+    /* Connection Init and setup */
-+    ldap->ld = ldap_init(ldap->servers, LDAP_PORT);
-+    if (!ldap->ld) {
-+        ldap_perror(ldap->ld, "ldap_init()");
-+        return FAILURE;
-+    }
-+
-+    if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) {
-+        ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_PROTOCOL_VERSION)");
-+        return FAILURE;
-+    }
-+
-+    /* Timeouts setup */
-+    if (ldap_set_option(ldap->ld, LDAP_OPT_NETWORK_TIMEOUT, &ldap->b_timeout) != LDAP_SUCCESS) {
-+        ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_NETWORK_TIMEOUT)");
-+    }
-+    if (ldap_set_option(ldap->ld, LDAP_OPT_TIMEOUT, &ldap->s_timeout) != LDAP_SUCCESS) {
-+        ldap_perror(ldap->ld, "ldap_set_option(LDAP_OPT_TIMEOUT)");
-+    }
-+
-+    /* TLS support */
-+    if ( (ldap->tls == -1) || (ldap->tls == 1) ) {
-+        if (ldap_start_tls_s(ldap->ld, NULL, NULL ) != LDAP_SUCCESS) {
-+            /* failed then reinit the initial connect */
-+            ldap_perror(ldap->ld, "ldap_connect: (TLS) ldap_start_tls()");
-+            if (ldap->tls == 1)
-+                return FAILURE;
-+
-+            ldap->ld = ldap_init(ldap->servers, LDAP_PORT);
-+            if (!ldap->ld) { 
-+                ldap_perror(ldap->ld, "ldap_init()");
-+                return FAILURE;
-+            }
-+
-+            if ( ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) {
-+                 ldap_perror(ldap->ld, "ldap_set_option()");
-+                 return FAILURE;
-+            }
-+        }
-+    }
-+
-+
-+    if ( ldap_simple_bind_s(ldap->ld, ldap->binddn, ldap->bindpw) != LDAP_SUCCESS) {
-+        ldap_perror(ldap->ld, "ldap_simple_bind_s()");
-+        return FAILURE;
-+    }
-+
-+    /* says it is connected */
-+    FLAG_SET_CONNECTED(ldap->flags);
-+
-+    return SUCCESS;
-+}
-+
-+/* must free allocated ressource */
-+static char * ldap_build_host(char *host, int port) {
-+    unsigned int size = strlen(host)+11;
-+    char * h = (char *) calloc (size, sizeof(char));
-+    int rc;
-+    if (!h)
-+         return NULL;
-+
-+    rc = snprintf(h, size, "%s:%d ", host, port);
-+    if (rc == -1)
-+        return NULL;
-+    return h;
-+}
-+
-+static int ldap_count_group(const char * input) {
-+    const char * charset = " \t";
-+    const char * ptr = input;
-+    unsigned int count = 0;
-+    unsigned int num;
-+
-+    num = strspn(ptr, charset);
-+    ptr += num;
-+
-+    while ((num = strcspn(ptr, charset))) {
-+    count++;
-+    ptr += num;
-+    ptr++;
-+    }
-+
-+    return count;
-+}
-+
-+/* format filter */
-+char * ldap_parse_groups(const char * groups) {
-+    unsigned int buffer_size = FILTER_GROUP_SIZE(groups);
-+    char * buffer = (char *) calloc(buffer_size, sizeof(char));
-+    char * g = NULL;
-+    char * garray[32];
-+    unsigned int i = 0;
-+
-+    if ((!groups)||(!buffer))
-+        return NULL;
-+
-+    g = strdup(groups);
-+    if (!g) {
-+        free(buffer);
-+        return NULL;
-+    }
-+
-+    /* first separate into n tokens */
-+    if ( tokenize(garray, sizeof(garray)/sizeof(*garray), g) < 0) {
-+        free(g);
-+        free(buffer);
-+        return NULL;
-+    }
-+
-+    /* build the final filter format */
-+    strlcat(buffer, FILTER_GROUP_PREFIX, buffer_size);
-+    strlcat(buffer, FILTER_OR_PREFIX, buffer_size);
-+    i = 0;
-+    while (garray[i]) {
-+        strlcat(buffer, FILTER_CN_PREFIX, buffer_size);
-+        strlcat(buffer, garray[i], buffer_size);
-+        strlcat(buffer, FILTER_CN_SUFFIX, buffer_size);
-+        i++;
-+    }
-+    strlcat(buffer, FILTER_OR_SUFFIX, buffer_size);
-+    strlcat(buffer, FILTER_UID_FORMAT, buffer_size);
-+    strlcat(buffer, FILTER_GROUP_SUFFIX, buffer_size);
-+
-+    free(g);
-+    return buffer;
-+}
-+
-+/* a bit dirty but leak free  */
-+char * ldap_parse_servers(const char * servers) {
-+    char * s = NULL;
-+    char * tmp = NULL, *urls[32];
-+    unsigned int num = 0 , i = 0 , asize = 0;
-+    LDAPURLDesc *urld[32];
-+
-+    if (!servers)
-+        return NULL;
-+
-+    /* local copy of the arg */
-+    s = strdup(servers);
-+    if (!s)
-+        return NULL;
-+
-+    /* first separate into URL tokens */
-+    if ( tokenize(urls, sizeof(urls)/sizeof(*urls), s) < 0)
-+        return NULL;
-+
-+    i = 0;
-+    while (urls[i]) {
-+        if (! ldap_is_ldap_url(urls[i]) ||
-+           (ldap_url_parse(urls[i], &urld[i]) != 0)) {
-+                return NULL;
-+        }
-+        i++;
-+    }
-+
-+    /* now free(s) */
-+    free (s);
-+
-+    /* how much memory do we need */
-+    num = i;
-+    for (i = 0 ; i < num ; i++)
-+        asize += strlen(urld[i]->lud_host)+11;
-+
-+    /* alloc */
-+    s = (char *) calloc( asize+1 , sizeof(char));
-+    if (!s) {
-+        for (i = 0 ; i < num ; i++)
-+            ldap_free_urldesc(urld[i]);
-+        return NULL;
-+    }
-+
-+    /* then build the final host string */
-+    for (i = 0 ; i < num ; i++) {
-+        /* built host part */
-+        tmp = ldap_build_host(urld[i]->lud_host, urld[i]->lud_port);
-+        strncat(s, tmp, strlen(tmp));
-+        ldap_free_urldesc(urld[i]);
-+        free(tmp);
-+    }
-+
-+    return s;
-+}
-+
-+void ldap_options_print(ldap_opt_t * ldap) {
-+    debug("ldap options:");
-+    debug("servers: %s", ldap->servers);
-+    if (ldap->u_basedn)
-+        debug("user basedn: %s", ldap->u_basedn);
-+    if (ldap->g_basedn)
-+        debug("group basedn: %s", ldap->g_basedn);
-+    if (ldap->binddn)
-+        debug("binddn: %s", ldap->binddn);
-+    if (ldap->bindpw)
-+        debug("bindpw: %s", ldap->bindpw);
-+    if (ldap->sgroup)
-+        debug("group: %s", ldap->sgroup);
-+    if (ldap->filter)
-+        debug("filter: %s", ldap->filter);
-+}
-+
-+void ldap_options_free(ldap_opt_t * l) {
-+    if (!l)
-+        return;
-+    if (l->servers)
-+        free(l->servers);
-+    if (l->u_basedn)
-+        free(l->u_basedn);
-+    if (l->g_basedn)
-+        free(l->g_basedn);
-+    if (l->binddn)
-+        free(l->binddn);
-+    if (l->bindpw)
-+        free(l->bindpw);
-+    if (l->sgroup)
-+        free(l->sgroup);
-+    if (l->fgroup)
-+        free(l->fgroup);
-+    if (l->filter)
-+        free(l->filter);
-+    if (l->l_conf)
-+        free(l->l_conf);
-+    free(l);
-+}
-+
-+/* free keys */
-+void ldap_keys_free(ldap_key_t * k) {
-+    ldap_value_free_len(k->keys);
-+    free(k);
-+    return;
-+}
-+
-+ldap_key_t * ldap_getuserkey(ldap_opt_t *l, const char * user) {
-+    ldap_key_t * k = (ldap_key_t *) calloc (1, sizeof(ldap_key_t));
-+    LDAPMessage *res, *e;
-+    char * filter;
-+    int i;
-+
-+    if ((!k) || (!l))
-+         return NULL;
-+
-+    /* Am i still connected ? RETRY n times */
-+    /* XXX TODO: setup some conf value for retrying */
-+    if (!(l->flags & FLAG_CONNECTED))
-+        for (i = 0 ; i < 2 ; i++)
-+            if (ldap_connect(l) == 0)
-+                break;
-+
-+    /* quick check for attempts to be evil */
-+    if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) ||
-+        (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL))
-+        return NULL;
-+
-+    /* build  filter for LDAP request */
-+    REQUEST_USER(filter, user, l->filter);
-+
-+    if ( ldap_search_st( l->ld,
-+        l->u_basedn,
-+        LDAP_SCOPE_SUBTREE,
-+        filter,
-+        attrs, 0, &l->s_timeout, &res ) != LDAP_SUCCESS) {
-+        
-+        ldap_perror(l->ld, "ldap_search_st()");
-+
-+        free(filter);
-+        free(k);
-+
-+        /* XXX error on search, timeout etc.. close ask for reconnect */
-+        ldap_close(l);
-+
-+        return NULL;
-+    } 
-+
-+    /* free */
-+    free(filter);
-+
-+    /* check if any results */
-+    i = ldap_count_entries(l->ld,res);
-+    if (i <= 0) {
-+        ldap_msgfree(res);
-+        free(k);
-+        return NULL;
-+    }
-+
-+    if (i > 1)
-+        debug("[LDAP] duplicate entries, using the FIRST entry returned");
-+
-+    e = ldap_first_entry(l->ld, res);
-+    k->keys = ldap_get_values_len(l->ld, e, PUBKEYATTR);
-+    k->num = ldap_count_values_len(k->keys);
-+
-+    ldap_msgfree(res);
-+    return k;
-+}
-+
-+
-+/* -1 if trouble
-+   0 if user is NOT member of current server group
-+   1 if user IS MEMBER of current server group 
-+ */
-+int ldap_ismember(ldap_opt_t * l, const char * user) {
-+    LDAPMessage *res;
-+    char * filter;
-+    int i;
-+
-+    if ((!l->sgroup) || !(l->g_basedn))
-+        return 1;
-+
-+    /* Am i still connected ? RETRY n times */
-+    /* XXX TODO: setup some conf value for retrying */
-+    if (!(l->flags & FLAG_CONNECTED)) 
-+        for (i = 0 ; i < 2 ; i++)
-+            if (ldap_connect(l) == 0)
-+                 break;
-+
-+    /* quick check for attempts to be evil */
-+    if ((strchr(user, '(') != NULL) || (strchr(user, ')') != NULL) ||
-+        (strchr(user, '*') != NULL) || (strchr(user, '\\') != NULL))
-+        return FAILURE;
-+
-+    /* build filter for LDAP request */
-+    REQUEST_GROUP(filter, l->fgroup, user);
-+
-+    if (ldap_search_st( l->ld, 
-+        l->g_basedn,
-+        LDAP_SCOPE_SUBTREE,
-+        filter,
-+        NULL, 0, &l->s_timeout, &res) != LDAP_SUCCESS) {
-+    
-+        ldap_perror(l->ld, "ldap_search_st()");
-+
-+        free(filter);
-+
-+        /* XXX error on search, timeout etc.. close ask for reconnect */
-+        ldap_close(l);
-+
-+        return FAILURE;
-+    }
-+
-+    free(filter);
-+
-+    /* check if any results */
-+    if (ldap_count_entries(l->ld, res) > 0) {
-+        ldap_msgfree(res);
-+        return 1;
-+    }
-+
-+    ldap_msgfree(res);
-+    return 0;
-+}
-+
-+/*
-+ * ldap.conf simple parser
-+ * XXX TODO:  sanity checks
-+ * must either
-+ * - free the previous ldap_opt_before replacing entries
-+ * - free each necessary previously parsed elements
-+ * ret:
-+ * -1 on FAILURE, 0 on SUCCESS
-+ */
-+int ldap_parse_lconf(ldap_opt_t * l) {
-+    FILE * lcd; /* ldap.conf descriptor */
-+    char buf[BUFSIZ];
-+    char * s = NULL, * k = NULL, * v = NULL;
-+    int li, len;
-+
-+    lcd = fopen (l->l_conf, "r");
-+    if (lcd == NULL) {
-+        /* debug("Cannot open %s", l->l_conf); */
-+        perror("ldap_parse_lconf()");
-+        return FAILURE;
-+    }
-+    
-+    while (fgets (buf, sizeof (buf), lcd) != NULL) {
-+
-+        if (*buf == '\n' || *buf == '#')
-+            continue;
-+
-+        k = buf;
-+        v = k;
-+        while (*v != '\0' && *v != ' ' && *v != '\t')
-+            v++;
-+
-+        if (*v == '\0')
-+            continue;
-+
-+        *(v++) = '\0';
-+
-+        while (*v == ' ' || *v == '\t')
-+            v++;
-+
-+        li = strlen (v) - 1;
-+        while (v[li] == ' ' || v[li] == '\t' || v[li] == '\n')
-+            --li;
-+        v[li + 1] = '\0';
-+
-+        if (!strcasecmp (k, "uri")) {
-+            if ((l->servers = ldap_parse_servers(v)) == NULL) {
-+                fatal("error in ldap servers");
-+            return FAILURE;
-+            }
-+
-+        }
-+        else if (!strcasecmp (k, "base")) { 
-+            s = strchr (v, '?');
-+            if (s != NULL) {
-+                len = s - v;
-+                l->u_basedn = malloc (len + 1);
-+                strncpy (l->u_basedn, v, len);
-+                l->u_basedn[len] = '\0';
-+            } else {
-+                l->u_basedn = strdup (v);
-+            }
-+        }
-+        else if (!strcasecmp (k, "binddn")) {
-+            l->binddn = strdup (v);
-+        }
-+        else if (!strcasecmp (k, "bindpw")) {
-+            l->bindpw = strdup (v);
-+        }
-+        else if (!strcasecmp (k, "timelimit")) {
-+            l->s_timeout.tv_sec = atoi (v);
-+                }
-+        else if (!strcasecmp (k, "bind_timelimit")) {
-+            l->b_timeout.tv_sec = atoi (v);
-+        }
-+        else if (!strcasecmp (k, "ssl")) {
-+            if (!strcasecmp (v, "start_tls"))
-+                l->tls = 1;
-+        }
-+    }
-+
-+    fclose (lcd);
-+    return SUCCESS;
-+}
-+
-+#endif /* WITH_LDAP_PUBKEY */
---- ldapauth.h.orig	2008-04-17 21:24:57.000000000 -0300
-+++ ldapauth.h	2008-04-17 21:24:57.000000000 -0300
-@@ -0,0 +1,124 @@
-+/*
-+ * $Id: openssh-lpk-5.0p1-0.3.9.patch,v 1.2 2009/05/15 11:00:27 pav Exp $ 
-+ */
-+
-+/*
-+ *
-+ * Copyright (c) 2005, Eric AUGE <eau at phear.org>
-+ * All rights reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
-+ *
-+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
-+ * 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.
-+ * Neither the name of the phear.org nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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.
-+ *
-+ *
-+ */
-+
-+#ifndef LDAPAUTH_H
-+#define LDAPAUTH_H
-+
-+#define LDAP_DEPRECATED 1
-+
-+#include <string.h>
-+#include <time.h>
-+#include <ldap.h>
-+#include <lber.h>
-+
-+/* tokens in use for config */
-+#define _DEFAULT_LPK_TOKEN "UseLPK"
-+#define _DEFAULT_SRV_TOKEN "LpkServers"
-+#define _DEFAULT_USR_TOKEN "LpkUserDN"
-+#define _DEFAULT_GRP_TOKEN "LpkGroupDN"
-+#define _DEFAULT_BDN_TOKEN "LpkBindDN"
-+#define _DEFAULT_BPW_TOKEN "LpkBindPw"
-+#define _DEFAULT_MYG_TOKEN "LpkServerGroup"
-+#define _DEFAULT_FIL_TOKEN "LpkFilter"
-+#define _DEFAULT_TLS_TOKEN "LpkForceTLS"
-+#define _DEFAULT_BTI_TOKEN "LpkBindTimelimit"
-+#define _DEFAULT_STI_TOKEN "LpkSearchTimelimit"
-+#define _DEFAULT_LDP_TOKEN "LpkLdapConf"
-+
-+/* default options */
-+#define _DEFAULT_LPK_ON 0
-+#define _DEFAULT_LPK_SERVERS NULL
-+#define _DEFAULT_LPK_UDN NULL
-+#define _DEFAULT_LPK_GDN NULL
-+#define _DEFAULT_LPK_BINDDN NULL
-+#define _DEFAULT_LPK_BINDPW NULL
-+#define _DEFAULT_LPK_SGROUP NULL
-+#define _DEFAULT_LPK_FILTER NULL
-+#define _DEFAULT_LPK_TLS -1
-+#define _DEFAULT_LPK_BTIMEOUT 10
-+#define _DEFAULT_LPK_STIMEOUT 10
-+#define _DEFAULT_LPK_LDP NULL
-+
-+/* flags */
-+#define FLAG_EMPTY	    0x00000000
-+#define FLAG_CONNECTED	    0x00000001
-+
-+/* flag macros */
-+#define FLAG_SET_EMPTY(x)		x&=(FLAG_EMPTY)
-+#define FLAG_SET_CONNECTED(x)		x|=(FLAG_CONNECTED)
-+#define FLAG_SET_DISCONNECTED(x)	x&=~(FLAG_CONNECTED)
-+
-+/* defines */
-+#define FAILURE -1
-+#define SUCCESS 0
-+#define PUBKEYATTR "sshPublicKey"
-+
-+/* 
-+ *
-+ * defined files path 
-+ * (should be relocated to pathnames.h,
-+ * if one day it's included within the tree) 
-+ *
-+ */
-+#define _PATH_LDAP_CONFIG_FILE "/etc/ldap.conf"
-+
-+/* structures */
-+typedef struct ldap_options {
-+    int on;			/* Use it or NOT */
-+    LDAP * ld;			/* LDAP file desc */
-+    char * servers;		/* parsed servers for ldaplib failover handling */
-+    char * u_basedn;		/* user basedn */
-+    char * g_basedn;		/* group basedn */
-+    char * binddn;		/* binddn */
-+    char * bindpw;		/* bind password */
-+    char * sgroup;		/* server group */
-+    char * fgroup;		/* group filter */
-+    char * filter;		/* additional filter */
-+    char * l_conf;		/* use ldap.conf */
-+    int tls;			/* TLS only */
-+    struct timeval b_timeout;   /* bind timeout */
-+    struct timeval s_timeout;   /* search timeout */
-+    unsigned int flags;		/* misc flags (reconnection, future use?) */
-+} ldap_opt_t;
-+
-+typedef struct ldap_keys {
-+    struct berval ** keys;	/* the public keys retrieved */
-+    unsigned int num;		/* number of keys */
-+} ldap_key_t;
-+
-+
-+/* function headers */
-+void ldap_close(ldap_opt_t *);
-+int ldap_connect(ldap_opt_t *);
-+char * ldap_parse_groups(const char *);
-+char * ldap_parse_servers(const char *);
-+void ldap_options_print(ldap_opt_t *);
-+void ldap_options_free(ldap_opt_t *);
-+void ldap_keys_free(ldap_key_t *);
-+int ldap_parse_lconf(ldap_opt_t *);
-+ldap_key_t * ldap_getuserkey(ldap_opt_t *, const char *);
-+int ldap_ismember(ldap_opt_t *, const char *);
-+
-+#endif
---- lpk-user-example.txt.orig	2008-04-17 21:24:57.000000000 -0300
-+++ lpk-user-example.txt	2008-04-17 21:24:57.000000000 -0300
-@@ -0,0 +1,117 @@
-+
-+Post to ML -> User Made Quick Install Doc.
-+Contribution from John Lane <john at lane.uk.net>
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-+
-+OpenSSH LDAP keystore Patch
-+===========================
-+
-+NOTE: these notes are a transcript of a specific installation
-+      they work for me, your specifics may be different!
-+      from John Lane March 17th 2005         john at lane.uk.net
-+
-+This is a patch to OpenSSH 4.0p1 to allow it to obtain users' public keys
-+from their LDAP record as an alternative to ~/.ssh/authorized_keys.
-+
-+(Assuming here that necessary build stuff is in $BUILD)
-+
-+cd $BUILD/openssh-4.0p1
-+patch -Np1 -i $BUILD/openssh-lpk-4.0p1-0.3.patch
-+mkdir -p /var/empty &&
-+./configure --prefix=/usr --sysconfdir=/etc/ssh \
-+    --libexecdir=/usr/sbin --with-md5-passwords --with-pam \
-+    --with-libs="-lldap" --with-cppflags="-DWITH_LDAP_PUBKEY"
-+Now do.
-+make &&
-+make install
-+
-+Add the following config to /etc/ssh/ssh_config
-+UseLPK yes
-+LpkServers ldap://myhost.mydomain.com
-+LpkUserDN  ou=People,dc=mydomain,dc=com
-+
-+We need to tell sshd about the SSL keys during boot, as root's
-+environment does not exist at that time. Edit /etc/rc.d/init.d/sshd.
-+Change the startup code from this:
-+                echo "Starting SSH Server..."
-+                loadproc /usr/sbin/sshd
-+                ;;
-+to this:
-+                echo "Starting SSH Server..."
-+                LDAPRC="/root/.ldaprc" loadproc /usr/sbin/sshd
-+                ;;
-+
-+Re-start the sshd daemon:
-+/etc/rc.d/init.d/sshd restart
-+
-+Install the additional LDAP schema
-+cp $BUILD/openssh-lpk-0.2.schema  /etc/openldap/schema/openssh.schema
-+
-+Now add the openSSH LDAP schema to /etc/openldap/slapd.conf:
-+Add the following to the end of the existing block of schema includes
-+include         /etc/openldap/schema/openssh.schema
-+
-+Re-start the LDAP server:
-+/etc/rc.d/init.d/slapd restart
-+
-+To add one or more public keys to a user, eg "testuser" :
-+ldapsearch -x -W -Z -LLL -b "uid=testuser,ou=People,dc=mydomain,dc=com" -D
-+"uid=testuser,ou=People,dc=mydomain,dc=com" > /tmp/testuser
-+
-+append the following to this /tmp/testuser file
-+objectclass: ldapPublicKey
-+sshPublicKey: ssh-rsa
-+AAAAB3NzaC1yc2EAAAABJQAAAIB3dsrwqXqD7E4zYYrxwdDKBUQxKMioXy9pxFVai64kAPxjU9KS
-+qIo7QfkjslfsjflksjfldfkjsldfjLX/5zkzRmT28I5piGzunPv17S89z8XwSsuAoR1t86t+5dlI
-+7eZE/gVbn2UQkQq7+kdDTS2yXV6VnC52N/kKLG3ciBkBAw== General Purpose RSA Key
-+
-+Then do a modify:
-+ldapmodify -x -D "uid=testuser,ou=People,dc=mydomain,dc=com" -W -f
-+/tmp/testuser -Z
-+Enter LDAP Password:
-+modifying entry "uid=testuser,ou=People,dc=mydomain,dc=com"
-+And check the modify is ok:
-+ldapsearch -x -W -Z -b "uid=testuser,ou=People,dc=mydomain,dc=com" -D
-+"uid=testuser,ou=People,dc=mydomain,dc=com"
-+Enter LDAP Password:
-+# extended LDIF
-+#
-+# LDAPv3
-+# base <uid=testuser,ou=People,dc=mydomain,dc=com> with scope sub
-+# filter: (objectclass=*)
-+# requesting: ALL
-+#
-+
-+# testuser, People, mydomain.com
-+dn: uid=testuser,ou=People,dc=mydomain,dc=com
-+uid: testuser
-+cn: testuser
-+objectClass: account
-+objectClass: posixAccount
-+objectClass: top
-+objectClass: shadowAccount
-+objectClass: ldapPublicKey
-+shadowLastChange: 12757
-+shadowMax: 99999
-+shadowWarning: 7
-+loginShell: /bin/bash
-+uidNumber: 9999
-+gidNumber: 501
-+homeDirectory: /home/testuser
-+userPassword:: e1NTSEF9UDgwV1hnM1VjUDRJK0k1YnFiL1d4ZUJObXlZZ3Z3UTU=
-+sshPublicKey: ssh-rsa
-+AAAAB3NzaC1yc2EAAAABJQAAAIB3dsrwqXqD7E4zYYrxwdDKBUQxKMioXy9pxFVai64kAPxjU9KSqIo7QfkjslfsjflksjfldfkjsldfjLX/5zkzRmT28I5piGzunPv17S89z
-+8XwSsuAoR1t86t+5dlI7eZE/gVbn2UQkQq7+kdDTS2yXV6VnC52N/kKLG3ciBkBAw== General Purpose RSA Key
-+
-+# search result
-+search: 3
-+result: 0 Success
-+
-+# numResponses: 2
-+# numEntries: 1
-+
-+Now start a ssh session to user "testuser" from usual ssh client (e.g.
-+puTTY). Login should succeed.
-+
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
---- openssh-lpk_openldap.schema.orig	2008-04-17 21:24:57.000000000 -0300
-+++ openssh-lpk_openldap.schema	2008-04-17 21:24:57.000000000 -0300
-@@ -0,0 +1,19 @@
-+#
-+# LDAP Public Key Patch schema for use with openssh-ldappubkey
-+# Author: Eric AUGE <eau at phear.org>
-+# 
-+# Based on the proposal of : Mark Ruijter
-+#
-+
-+
-+# octetString SYNTAX
-+attributetype ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' 
-+	DESC 'MANDATORY: OpenSSH Public key' 
-+	EQUALITY octetStringMatch
-+	SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
-+
-+# printableString SYNTAX yes|no
-+objectclass ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
-+	DESC 'MANDATORY: OpenSSH LPK objectclass'
-+	MUST ( sshPublicKey $ uid ) 
-+	)
---- openssh-lpk_sun.schema.orig	2008-04-17 21:24:57.000000000 -0300
-+++ openssh-lpk_sun.schema	2008-04-17 21:24:57.000000000 -0300
-@@ -0,0 +1,21 @@
-+#
-+# LDAP Public Key Patch schema for use with openssh-ldappubkey
-+# Author: Eric AUGE <eau at phear.org>
-+# 
-+# Schema for Sun Directory Server.
-+# Based on the original schema, modified by Stefan Fischer.
-+#
-+
-+dn: cn=schema
-+
-+# octetString SYNTAX
-+attributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13 NAME 'sshPublicKey' 
-+	DESC 'MANDATORY: OpenSSH Public key' 
-+	EQUALITY octetStringMatch
-+	SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 )
-+
-+# printableString SYNTAX yes|no
-+objectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0 NAME 'ldapPublicKey' SUP top AUXILIARY
-+	DESC 'MANDATORY: OpenSSH LPK objectclass'
-+	MUST ( sshPublicKey $ uid ) 
-+	)
---- sshd.c.orig	2008-03-11 08:58:25.000000000 -0300
-+++ sshd.c	2008-04-17 21:24:57.000000000 -0300
-@@ -126,6 +126,10 @@
- int deny_severity;
- #endif /* LIBWRAP */
- 
-+#ifdef WITH_LDAP_PUBKEY
-+#include "ldapauth.h"
-+#endif
-+
- #ifndef O_NOCTTY
- #define O_NOCTTY	0
- #endif
-@@ -1454,6 +1458,16 @@
- 		exit(1);
- 	}
- 
-+#ifdef WITH_LDAP_PUBKEY
-+    /* ldap_options_print(&options.lpk); */
-+    /* XXX initialize/check ldap connection and set *LD */
-+    if (options.lpk.on) {
-+        if (options.lpk.l_conf && (ldap_parse_lconf(&options.lpk) < 0) )
-+            error("[LDAP] could not parse %s", options.lpk.l_conf);
-+        if (ldap_connect(&options.lpk) < 0)
-+            error("[LDAP] could not initialize ldap connection");
-+    }
-+#endif
- 	debug("sshd version %.100s", SSH_RELEASE);
- 
- 	/* Store privilege separation user for later use if required. */
---- sshd_config.5.orig	2008-03-26 21:02:02.000000000 -0300
-+++ sshd_config.5	2008-04-17 21:24:57.000000000 -0300
-@@ -964,6 +964,62 @@
- program.
- The default is
- .Pa /usr/X11R6/bin/xauth .
-+.It Cm UseLPK
-+Specifies whether LDAP public key retrieval must be used or not. It allow
-+an easy centralisation of public keys within an LDAP directory. The argument must be
-+.Dq yes
-+or
-+.Dq no .
-+.It Cm LpkLdapConf
-+Specifies whether LDAP Public keys should parse the specified ldap.conf file
-+instead of sshd_config Tokens. The argument must be a valid path to an ldap.conf
-+file like
-+.Pa /etc/ldap.conf
-+.It Cm LpkServers
-+Specifies LDAP one or more [:space:] separated server's url the following form may be used:
-+.Pp
-+LpkServers ldaps://127.0.0.1 ldap://127.0.0.2 ldap://127.0.0.3
-+.It Cm LpkUserDN
-+Specifies the LDAP user DN.
-+.Pp
-+LpkUserDN ou=users,dc=phear,dc=org
-+.It Cm LpkGroupDN
-+Specifies the LDAP groups DN.
-+.Pp
-+LpkGroupDN ou=groups,dc=phear,dc=org
-+.It Cm LpkBindDN
-+Specifies the LDAP bind DN to use if necessary.
-+.Pp
-+LpkBindDN cn=Manager,dc=phear,dc=org
-+.It Cm LpkBindPw
-+Specifies the LDAP bind credential. 
-+.Pp
-+LpkBindPw secret
-+.It Cm LpkServerGroup
-+Specifies one or more [:space:] separated group the server is part of. 
-+.Pp
-+LpkServerGroup unix mail prod
-+.It Cm LpkFilter
-+Specifies an additional LDAP filter to use for finding SSH keys
-+.Pp
-+LpkFilter (hostAccess=master.phear.org)
-+.It Cm LpkForceTLS
-+Specifies if the LDAP server connection must be tried, forced or not used. The argument must be 
-+.Dq yes
-+or
-+.Dq no
-+or
-+.Dq try .
-+.It Cm LpkSearchTimelimit
-+Sepcifies the search time limit before the search is considered over. value is
-+in seconds.
-+.Pp
-+LpkSearchTimelimit 3
-+.It Cm LpkBindTimelimit
-+Sepcifies the bind time limit before the connection is considered dead. value is
-+in seconds.
-+.Pp
-+LpkBindTimelimit 3
- .El
- .Sh TIME FORMATS
- .Xr sshd 8
---- sshd_config.orig	2008-02-10 09:40:12.000000000 -0200
-+++ sshd_config	2008-04-17 21:28:29.000000000 -0300
-@@ -107,6 +107,21 @@
- # no default banner path
- #Banner none
- 
-+# here are the new patched ldap related tokens
-+# entries in your LDAP must have posixAccount & ldapPublicKey objectclass
-+#UseLPK yes
-+#LpkLdapConf /etc/ldap.conf
-+#LpkServers  ldap://10.1.7.1/ ldap://10.1.7.2/
-+#LpkUserDN   ou=users,dc=phear,dc=org
-+#LpkGroupDN  ou=groups,dc=phear,dc=org
-+#LpkBindDN cn=Manager,dc=phear,dc=org
-+#LpkBindPw secret
-+#LpkServerGroup mail
-+#LpkFilter (hostAccess=master.phear.org)
-+#LpkForceTLS no
-+#LpkSearchTimelimit 3
-+#LpkBindTimelimit 3
-+
- # override default of no subsystems
- Subsystem	sftp	/usr/libexec/sftp-server
- 
---- servconf.h.orig	2008-03-07 04:31:24.000000000 -0300
-+++ servconf.h	2008-04-17 21:24:57.000000000 -0300
-@@ -16,6 +16,10 @@
- #ifndef SERVCONF_H
- #define SERVCONF_H
- 
-+#ifdef WITH_LDAP_PUBKEY
-+#include "ldapauth.h"
-+#endif
-+
- #define MAX_PORTS		256	/* Max # ports. */
- 
- #define MAX_ALLOW_USERS		256	/* Max # users on allow list. */
-@@ -142,6 +146,9 @@
- 	int	use_pam;		/* Enable auth via PAM */
- 
- 	int	permit_tun;
-+#ifdef WITH_LDAP_PUBKEY
-+        ldap_opt_t lpk;
-+#endif
- 
- 	int	num_permitted_opens;
- 
diff -ruN --exclude=CVS /usr/ports/security/openssh-portable/files/openssh-lpk-5.0p1-64bit.patch /usr/home/dindin/workspace/openssh-portable/files/openssh-lpk-5.0p1-64bit.patch
--- /usr/ports/security/openssh-portable/files/openssh-lpk-5.0p1-64bit.patch	2009-03-24 20:33:41.000000000 +0300
+++ /usr/home/dindin/workspace/openssh-portable/files/openssh-lpk-5.0p1-64bit.patch	1970-01-01 03:00:00.000000000 +0300
@@ -1,44 +0,0 @@
-diff -Nuar --exclude '*.rej' servconf.c.orig servconf.c
---- servconf.c.orig	2008-08-23 15:02:47.000000000 -0700
-+++ servconf.c	2008-08-23 15:04:21.000000000 -0700
-@@ -701,6 +701,7 @@
- 	int cmdline = 0, *intptr, value, n;
- 	SyslogFacility *log_facility_ptr;
- 	LogLevel *log_level_ptr;
-+ 	unsigned long lvalue, *longptr;
- 	ServerOpCodes opcode;
- 	u_short port;
- 	u_int i, flags = 0;
-@@ -715,6 +716,7 @@
- 	if (!arg || !*arg || *arg == '#')
- 		return 0;
- 	intptr = NULL;
-+	longptr = NULL;
- 	charptr = NULL;
- 	opcode = parse_token(arg, filename, linenum, &flags);
- 
-@@ -1449,11 +1451,20 @@
- 			*intptr = value;
- 		break;
- 	case sBindTimeout:
--		intptr = (int *) &options->lpk.b_timeout.tv_sec;
--		goto parse_int;
-+		longptr = (unsigned long *) &options->lpk.b_timeout.tv_sec;
-+parse_ulong:
-+		arg = strdelim(&cp);
-+		if (!arg || *arg == '\0')
-+			fatal("%s line %d: missing integer value.",
-+			    filename, linenum);
-+		lvalue = atol(arg);
-+		if (*activep && *longptr == -1)
-+			*longptr = lvalue;
-+		break;
-+
- 	case sSearchTimeout:
--		intptr = (int *) &options->lpk.s_timeout.tv_sec;
--		goto parse_int;
-+		longptr = (unsigned long *) &options->lpk.s_timeout.tv_sec;
-+		goto parse_ulong;
- 		break;
- 	case sLdapConf:
- 		arg = cp;
--- openssh-portable-5.2.p1_2,1.patch ends here ---

>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the freebsd-ports-bugs mailing list