Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

452 Commits   2 Branches   1 Tag
Index: create.patch.sh
===================================================================
--- create.patch.sh	(nonexistent)
+++ create.patch.sh	(revision 5)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=8.5p1
+
+tar --files-from=file.list -xzvf ../openssh-$VERSION.tar.gz
+mv openssh-$VERSION openssh-$VERSION-orig
+
+cp -rf ./openssh-$VERSION-new ./openssh-$VERSION
+
+diff --unified -Nr  openssh-$VERSION-orig  openssh-$VERSION > openssh-$VERSION-tcp_wrappers.patch
+
+mv openssh-$VERSION-tcp_wrappers.patch ../patches
+
+rm -rf ./openssh-$VERSION
+rm -rf ./openssh-$VERSION-orig

Property changes on: create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: file.list
===================================================================
--- file.list	(nonexistent)
+++ file.list	(revision 5)
@@ -0,0 +1,3 @@
+openssh-8.5p1/configure.ac
+openssh-8.5p1/sshd.8
+openssh-8.5p1/sshd.c
Index: openssh-8.5p1-new/configure.ac
===================================================================
--- openssh-8.5p1-new/configure.ac	(nonexistent)
+++ openssh-8.5p1-new/configure.ac	(revision 5)
@@ -0,0 +1,5614 @@
+#
+# Copyright (c) 1999-2004 Damien Miller
+#
+# 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.
+
+AC_INIT([OpenSSH], [Portable], [openssh-unix-dev@mindrot.org])
+AC_CONFIG_MACRO_DIR([m4])
+AC_CONFIG_SRCDIR([ssh.c])
+AC_LANG([C])
+
+AC_CONFIG_HEADERS([config.h])
+AC_PROG_CC([cc gcc])
+
+# XXX relax this after reimplementing logit() etc.
+AC_MSG_CHECKING([if $CC supports C99-style variadic macros])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+int f(int a, int b, int c) { return a + b + c; }
+#define F(a, ...) f(a, __VA_ARGS__)
+]], [[return F(1, 2, -3);]])],
+	[ AC_MSG_RESULT([yes]) ],
+	[ AC_MSG_ERROR([*** OpenSSH requires support for C99-style variadic macros]) ]
+)
+
+AC_CANONICAL_HOST
+AC_C_BIGENDIAN
+
+# Checks for programs.
+AC_PROG_AWK
+AC_PROG_CPP
+AC_PROG_RANLIB
+AC_PROG_INSTALL
+AC_PROG_EGREP
+AC_PROG_MKDIR_P
+AC_CHECK_TOOLS([AR], [ar])
+AC_PATH_PROG([CAT], [cat])
+AC_PATH_PROG([KILL], [kill])
+AC_PATH_PROG([SED], [sed])
+AC_PATH_PROG([TEST_MINUS_S_SH], [bash])
+AC_PATH_PROG([TEST_MINUS_S_SH], [ksh])
+AC_PATH_PROG([TEST_MINUS_S_SH], [sh])
+AC_PATH_PROG([SH], [sh])
+AC_PATH_PROG([GROFF], [groff])
+AC_PATH_PROG([NROFF], [nroff awf])
+AC_PATH_PROG([MANDOC], [mandoc])
+AC_SUBST([TEST_SHELL], [sh])
+
+dnl select manpage formatter to be used to build "cat" format pages.
+if test "x$MANDOC" != "x" ; then
+	MANFMT="$MANDOC"
+elif test "x$NROFF" != "x" ; then
+	MANFMT="$NROFF -mandoc"
+elif test "x$GROFF" != "x" ; then
+	MANFMT="$GROFF -mandoc -Tascii"
+else
+	AC_MSG_WARN([no manpage formatter found])
+	MANFMT="false"
+fi
+AC_SUBST([MANFMT])
+
+dnl for buildpkg.sh
+AC_PATH_PROG([PATH_GROUPADD_PROG], [groupadd], [groupadd],
+	[/usr/sbin${PATH_SEPARATOR}/etc])
+AC_PATH_PROG([PATH_USERADD_PROG], [useradd], [useradd],
+	[/usr/sbin${PATH_SEPARATOR}/etc])
+AC_CHECK_PROG([MAKE_PACKAGE_SUPPORTED], [pkgmk], [yes], [no])
+if test -x /sbin/sh; then
+	AC_SUBST([STARTUP_SCRIPT_SHELL], [/sbin/sh])
+else
+	AC_SUBST([STARTUP_SCRIPT_SHELL], [/bin/sh])
+fi
+
+# System features
+AC_SYS_LARGEFILE
+
+if test -z "$AR" ; then
+	AC_MSG_ERROR([*** 'ar' missing, please install or fix your \$PATH ***])
+fi
+
+AC_PATH_PROG([PATH_PASSWD_PROG], [passwd])
+if test ! -z "$PATH_PASSWD_PROG" ; then
+	AC_DEFINE_UNQUOTED([_PATH_PASSWD_PROG], ["$PATH_PASSWD_PROG"],
+		[Full path of your "passwd" program])
+fi
+
+dnl Since autoconf doesn't support it very well,  we no longer allow users to
+dnl override LD, however keeping the hook here for now in case there's a use
+dnl use case we overlooked and someone needs to re-enable it.  Unless a good
+dnl reason is found we'll be removing this in future.
+LD="$CC"
+AC_SUBST([LD])
+
+AC_C_INLINE
+
+AC_CHECK_DECL([LLONG_MAX], [have_llong_max=1], , [#include <limits.h>])
+AC_CHECK_DECL([LONG_LONG_MAX], [have_long_long_max=1], , [#include <limits.h>])
+AC_CHECK_DECL([SYSTR_POLICY_KILL], [have_systr_policy_kill=1], , [
+	#include <sys/types.h>
+	#include <sys/param.h>
+	#include <dev/systrace.h>
+])
+AC_CHECK_DECL([RLIMIT_NPROC],
+    [AC_DEFINE([HAVE_RLIMIT_NPROC], [], [sys/resource.h has RLIMIT_NPROC])], , [
+	#include <sys/types.h>
+	#include <sys/resource.h>
+])
+AC_CHECK_DECL([PR_SET_NO_NEW_PRIVS], [have_linux_no_new_privs=1], , [
+	#include <sys/types.h>
+	#include <linux/prctl.h>
+])
+
+openssl=yes
+AC_ARG_WITH([openssl],
+	[  --without-openssl       Disable use of OpenSSL; use only limited internal crypto **EXPERIMENTAL** ],
+	[  if test "x$withval" = "xno" ; then
+		openssl=no
+	   fi
+	]
+)
+AC_MSG_CHECKING([whether OpenSSL will be used for cryptography])
+if test "x$openssl" = "xyes" ; then
+	AC_MSG_RESULT([yes])
+	AC_DEFINE_UNQUOTED([WITH_OPENSSL], [1], [use libcrypto for cryptography])
+else
+	AC_MSG_RESULT([no])
+fi
+
+use_stack_protector=1
+use_toolchain_hardening=1
+AC_ARG_WITH([stackprotect],
+    [  --without-stackprotect  Don't use compiler's stack protection], [
+    if test "x$withval" = "xno"; then
+	use_stack_protector=0
+    fi ])
+AC_ARG_WITH([hardening],
+    [  --without-hardening     Don't use toolchain hardening flags], [
+    if test "x$withval" = "xno"; then
+	use_toolchain_hardening=0
+    fi ])
+
+# We use -Werror for the tests only so that we catch warnings like "this is
+# on by default" for things like -fPIE.
+AC_MSG_CHECKING([if $CC supports -Werror])
+saved_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Werror"
+AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int main(void) { return 0; }]])],
+	[ AC_MSG_RESULT([yes])
+	  WERROR="-Werror"],
+	[ AC_MSG_RESULT([no])
+	  WERROR="" ]
+)
+CFLAGS="$saved_CFLAGS"
+
+if test "$GCC" = "yes" || test "$GCC" = "egcs"; then
+	OSSH_CHECK_CFLAG_COMPILE([-pipe])
+	OSSH_CHECK_CFLAG_COMPILE([-Wunknown-warning-option])
+	OSSH_CHECK_CFLAG_COMPILE([-Wno-error=format-truncation])
+	OSSH_CHECK_CFLAG_COMPILE([-Qunused-arguments])
+	OSSH_CHECK_CFLAG_COMPILE([-Wall])
+	OSSH_CHECK_CFLAG_COMPILE([-Wextra])
+	OSSH_CHECK_CFLAG_COMPILE([-Wpointer-arith])
+	OSSH_CHECK_CFLAG_COMPILE([-Wuninitialized])
+	OSSH_CHECK_CFLAG_COMPILE([-Wsign-compare])
+	OSSH_CHECK_CFLAG_COMPILE([-Wformat-security])
+	OSSH_CHECK_CFLAG_COMPILE([-Wsizeof-pointer-memaccess])
+	OSSH_CHECK_CFLAG_COMPILE([-Wpointer-sign], [-Wno-pointer-sign])
+	OSSH_CHECK_CFLAG_COMPILE([-Wunused-parameter], [-Wno-unused-parameter])
+	OSSH_CHECK_CFLAG_COMPILE([-Wunused-result], [-Wno-unused-result])
+	OSSH_CHECK_CFLAG_COMPILE([-Wimplicit-fallthrough])
+	OSSH_CHECK_CFLAG_COMPILE([-fno-strict-aliasing])
+    if test "x$use_toolchain_hardening" = "x1"; then
+	OSSH_CHECK_CFLAG_COMPILE([-mretpoline]) # clang
+	OSSH_CHECK_LDFLAG_LINK([-Wl,-z,retpolineplt])
+	OSSH_CHECK_CFLAG_COMPILE([-D_FORTIFY_SOURCE=2])
+	OSSH_CHECK_LDFLAG_LINK([-Wl,-z,relro])
+	OSSH_CHECK_LDFLAG_LINK([-Wl,-z,now])
+	OSSH_CHECK_LDFLAG_LINK([-Wl,-z,noexecstack])
+	# NB. -ftrapv expects certain support functions to be present in
+	# the compiler library (libgcc or similar) to detect integer operations
+	# that can overflow. We must check that the result of enabling it
+	# actually links. The test program compiled/linked includes a number
+	# of integer operations that should exercise this.
+	OSSH_CHECK_CFLAG_LINK([-ftrapv])
+    fi
+	AC_MSG_CHECKING([gcc version])
+	GCC_VER=`$CC -v 2>&1 | $AWK '/gcc version /{print $3}'`
+	case $GCC_VER in
+		1.*) no_attrib_nonnull=1 ;;
+		2.8* | 2.9*)
+		     no_attrib_nonnull=1
+		     ;;
+		2.*) no_attrib_nonnull=1 ;;
+		*) ;;
+	esac
+	AC_MSG_RESULT([$GCC_VER])
+
+	AC_MSG_CHECKING([if $CC accepts -fno-builtin-memset])
+	saved_CFLAGS="$CFLAGS"
+	CFLAGS="$CFLAGS -fno-builtin-memset"
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <string.h> ]],
+			[[ char b[10]; memset(b, 0, sizeof(b)); ]])],
+		[ AC_MSG_RESULT([yes]) ],
+		[ AC_MSG_RESULT([no])
+		  CFLAGS="$saved_CFLAGS" ]
+	)
+
+	# -fstack-protector-all doesn't always work for some GCC versions
+	# and/or platforms, so we test if we can.  If it's not supported
+	# on a given platform gcc will emit a warning so we use -Werror.
+	if test "x$use_stack_protector" = "x1"; then
+	    for t in -fstack-protector-strong -fstack-protector-all \
+		    -fstack-protector; do
+		AC_MSG_CHECKING([if $CC supports $t])
+		saved_CFLAGS="$CFLAGS"
+		saved_LDFLAGS="$LDFLAGS"
+		CFLAGS="$CFLAGS $t -Werror"
+		LDFLAGS="$LDFLAGS $t -Werror"
+		AC_LINK_IFELSE(
+			[AC_LANG_PROGRAM([[
+	#include <stdio.h>
+	int func (int t) {char b[100]; snprintf(b,sizeof b,"%d",t); return t;}
+			 ]],
+			[[
+	char x[256];
+	snprintf(x, sizeof(x), "XXX%d", func(1));
+			 ]])],
+		    [ AC_MSG_RESULT([yes])
+		      CFLAGS="$saved_CFLAGS $t"
+		      LDFLAGS="$saved_LDFLAGS $t"
+		      AC_MSG_CHECKING([if $t works])
+		      AC_RUN_IFELSE(
+			[AC_LANG_PROGRAM([[
+	#include <stdio.h>
+	int func (int t) {char b[100]; snprintf(b,sizeof b,"%d",t); return t;}
+			]],
+			[[
+	char x[256];
+	snprintf(x, sizeof(x), "XXX%d", func(1));
+			]])],
+			[ AC_MSG_RESULT([yes])
+			  break ],
+			[ AC_MSG_RESULT([no]) ],
+			[ AC_MSG_WARN([cross compiling: cannot test])
+			  break ]
+		      )
+		    ],
+		    [ AC_MSG_RESULT([no]) ]
+		)
+		CFLAGS="$saved_CFLAGS"
+		LDFLAGS="$saved_LDFLAGS"
+	    done
+	fi
+
+	if test -z "$have_llong_max"; then
+		# retry LLONG_MAX with -std=gnu99, needed on some Linuxes
+		unset ac_cv_have_decl_LLONG_MAX
+		saved_CFLAGS="$CFLAGS"
+		CFLAGS="$CFLAGS -std=gnu99"
+		AC_CHECK_DECL([LLONG_MAX],
+		    [have_llong_max=1],
+		    [CFLAGS="$saved_CFLAGS"],
+		    [#include <limits.h>]
+		)
+	fi
+fi
+
+AC_MSG_CHECKING([if compiler allows __attribute__ on return types])
+AC_COMPILE_IFELSE(
+    [AC_LANG_PROGRAM([[
+#include <stdlib.h>
+__attribute__((__unused__)) static void foo(void){return;}]],
+    [[ exit(0); ]])],
+    [ AC_MSG_RESULT([yes]) ],
+    [ AC_MSG_RESULT([no])
+      AC_DEFINE(NO_ATTRIBUTE_ON_RETURN_TYPE, 1,
+	 [compiler does not accept __attribute__ on return types]) ]
+)
+
+AC_MSG_CHECKING([if compiler allows __attribute__ prototype args])
+AC_COMPILE_IFELSE(
+    [AC_LANG_PROGRAM([[
+#include <stdlib.h>
+typedef void foo(const char *, ...) __attribute__((format(printf, 1, 2)));]],
+    [[ exit(0); ]])],
+    [ AC_MSG_RESULT([yes]) ],
+    [ AC_MSG_RESULT([no])
+      AC_DEFINE(NO_ATTRIBUTE_ON_PROTOTYPE_ARGS, 1,
+	 [compiler does not accept __attribute__ on prototype args]) ]
+)
+
+AC_MSG_CHECKING([if compiler supports variable length arrays])
+AC_COMPILE_IFELSE(
+    [AC_LANG_PROGRAM([[#include <stdlib.h>]],
+    [[ int i; for (i=0; i<3; i++){int a[i]; a[i-1]=0;} exit(0); ]])],
+    [ AC_MSG_RESULT([yes])
+      AC_DEFINE(VARIABLE_LENGTH_ARRAYS, [1],
+	 [compiler supports variable length arrays]) ],
+    [ AC_MSG_RESULT([no]) ]
+)
+
+if test "x$no_attrib_nonnull" != "x1" ; then
+	AC_DEFINE([HAVE_ATTRIBUTE__NONNULL__], [1], [Have attribute nonnull])
+fi
+
+AC_ARG_WITH([rpath],
+	[  --without-rpath         Disable auto-added -R linker paths],
+	[
+		if test "x$withval" = "xno" ; then
+			rpath_opt=""
+		elif test "x$withval" = "xyes" ; then
+			rpath_opt="-R"
+		else
+			rpath_opt="$withval"
+		fi
+	]
+)
+
+# Allow user to specify flags
+AC_ARG_WITH([cflags],
+	[  --with-cflags           Specify additional flags to pass to compiler],
+	[
+		if test -n "$withval"  &&  test "x$withval" != "xno"  &&  \
+		    test "x${withval}" != "xyes"; then
+			CFLAGS="$CFLAGS $withval"
+		fi
+	]
+)
+
+AC_ARG_WITH([cflags-after],
+	[  --with-cflags-after     Specify additional flags to pass to compiler after configure],
+	[
+		if test -n "$withval"  &&  test "x$withval" != "xno"  &&  \
+		    test "x${withval}" != "xyes"; then
+			CFLAGS_AFTER="$withval"
+		fi
+	]
+)
+AC_ARG_WITH([cppflags],
+	[  --with-cppflags         Specify additional flags to pass to preprocessor] ,
+	[
+		if test -n "$withval"  &&  test "x$withval" != "xno"  &&  \
+		    test "x${withval}" != "xyes"; then
+			CPPFLAGS="$CPPFLAGS $withval"
+		fi
+	]
+)
+AC_ARG_WITH([ldflags],
+	[  --with-ldflags          Specify additional flags to pass to linker],
+	[
+		if test -n "$withval"  &&  test "x$withval" != "xno"  &&  \
+		    test "x${withval}" != "xyes"; then
+			LDFLAGS="$LDFLAGS $withval"
+		fi
+	]
+)
+AC_ARG_WITH([ldflags-after],
+	[  --with-ldflags-after    Specify additional flags to pass to linker after configure],
+	[
+		if test -n "$withval"  &&  test "x$withval" != "xno"  &&  \
+		    test "x${withval}" != "xyes"; then
+			LDFLAGS_AFTER="$withval"
+		fi
+	]
+)
+AC_ARG_WITH([libs],
+	[  --with-libs             Specify additional libraries to link with],
+	[
+		if test -n "$withval"  &&  test "x$withval" != "xno"  &&  \
+		    test "x${withval}" != "xyes"; then
+			LIBS="$LIBS $withval"
+		fi
+	]
+)
+AC_ARG_WITH([Werror],
+	[  --with-Werror           Build main code with -Werror],
+	[
+		if test -n "$withval"  &&  test "x$withval" != "xno"; then
+			werror_flags="-Werror"
+			if test "x${withval}" != "xyes"; then
+				werror_flags="$withval"
+			fi
+		fi
+	]
+)
+
+AC_CHECK_HEADERS([ \
+	blf.h \
+	bstring.h \
+	crypt.h \
+	crypto/sha2.h \
+	dirent.h \
+	endian.h \
+	elf.h \
+	err.h \
+	features.h \
+	fcntl.h \
+	floatingpoint.h \
+	fnmatch.h \
+	getopt.h \
+	glob.h \
+	ia.h \
+	iaf.h \
+	ifaddrs.h \
+	inttypes.h \
+	langinfo.h \
+	limits.h \
+	locale.h \
+	login.h \
+	maillock.h \
+	ndir.h \
+	net/if_tun.h \
+	netdb.h \
+	netgroup.h \
+	pam/pam_appl.h \
+	paths.h \
+	poll.h \
+	pty.h \
+	readpassphrase.h \
+	rpc/types.h \
+	security/pam_appl.h \
+	sha2.h \
+	shadow.h \
+	stddef.h \
+	stdint.h \
+	string.h \
+	strings.h \
+	sys/bitypes.h \
+	sys/byteorder.h \
+	sys/bsdtty.h \
+	sys/cdefs.h \
+	sys/dir.h \
+	sys/file.h \
+	sys/mman.h \
+	sys/label.h \
+	sys/ndir.h \
+	sys/poll.h \
+	sys/prctl.h \
+	sys/pstat.h \
+	sys/ptrace.h \
+	sys/random.h \
+	sys/select.h \
+	sys/stat.h \
+	sys/stream.h \
+	sys/stropts.h \
+	sys/strtio.h \
+	sys/statvfs.h \
+	sys/sysmacros.h \
+	sys/time.h \
+	sys/timers.h \
+	sys/vfs.h \
+	time.h \
+	tmpdir.h \
+	ttyent.h \
+	ucred.h \
+	unistd.h \
+	usersec.h \
+	util.h \
+	utime.h \
+	utmp.h \
+	utmpx.h \
+	vis.h \
+	wchar.h \
+])
+
+# On some platforms (eg SunOS4) sys/audit.h requires sys/[time|types|label.h]
+# to be included first.
+AC_CHECK_HEADERS([sys/audit.h], [], [], [
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_LABEL_H
+# include <sys/label.h>
+#endif
+])
+
+# sys/capsicum.h requires sys/types.h
+AC_CHECK_HEADERS([sys/capsicum.h], [], [], [
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+])
+
+# net/route.h requires sys/socket.h and sys/types.h.
+# sys/sysctl.h also requires sys/param.h
+AC_CHECK_HEADERS([net/route.h sys/sysctl.h], [], [], [
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#include <sys/param.h>
+#include <sys/socket.h>
+])
+
+# lastlog.h requires sys/time.h to be included first on Solaris
+AC_CHECK_HEADERS([lastlog.h], [], [], [
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+])
+
+# sys/ptms.h requires sys/stream.h to be included first on Solaris
+AC_CHECK_HEADERS([sys/ptms.h], [], [], [
+#ifdef HAVE_SYS_STREAM_H
+# include <sys/stream.h>
+#endif
+])
+
+# login_cap.h requires sys/types.h on NetBSD
+AC_CHECK_HEADERS([login_cap.h], [], [], [
+#include <sys/types.h>
+])
+
+# older BSDs need sys/param.h before sys/mount.h
+AC_CHECK_HEADERS([sys/mount.h], [], [], [
+#include <sys/param.h>
+])
+
+# Android requires sys/socket.h to be included before sys/un.h
+AC_CHECK_HEADERS([sys/un.h], [], [], [
+#include <sys/types.h>
+#include <sys/socket.h>
+])
+
+# Messages for features tested for in target-specific section
+SIA_MSG="no"
+SPC_MSG="no"
+SP_MSG="no"
+SPP_MSG="no"
+
+# Support for Solaris/Illumos privileges (this test is used by both
+# the --with-solaris-privs option and --with-sandbox=solaris).
+SOLARIS_PRIVS="no"
+
+# Check for some target-specific stuff
+case "$host" in
+*-*-aix*)
+	# Some versions of VAC won't allow macro redefinitions at
+	# -qlanglevel=ansi, and autoconf 2.60 sometimes insists on using that
+	# particularly with older versions of vac or xlc.
+	# It also throws errors about null macro arguments, but these are
+	# not fatal.
+	AC_MSG_CHECKING([if compiler allows macro redefinitions])
+	AC_COMPILE_IFELSE(
+	    [AC_LANG_PROGRAM([[
+#define testmacro foo
+#define testmacro bar]],
+	    [[ exit(0); ]])],
+	    [ AC_MSG_RESULT([yes]) ],
+	    [ AC_MSG_RESULT([no])
+	      CC="`echo $CC | sed 's/-qlanglvl\=ansi//g'`"
+	      CFLAGS="`echo $CFLAGS | sed 's/-qlanglvl\=ansi//g'`"
+	      CPPFLAGS="`echo $CPPFLAGS | sed 's/-qlanglvl\=ansi//g'`"
+	    ]
+	)
+
+	AC_MSG_CHECKING([how to specify blibpath for linker ($LD)])
+	if (test -z "$blibpath"); then
+		blibpath="/usr/lib:/lib"
+	fi
+	saved_LDFLAGS="$LDFLAGS"
+	if test "$GCC" = "yes"; then
+		flags="-Wl,-blibpath: -Wl,-rpath, -blibpath:"
+	else
+		flags="-blibpath: -Wl,-blibpath: -Wl,-rpath,"
+	fi
+	for tryflags in $flags ;do
+		if (test -z "$blibflags"); then
+			LDFLAGS="$saved_LDFLAGS $tryflags$blibpath"
+			AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
+			[blibflags=$tryflags], [])
+		fi
+	done
+	if (test -z "$blibflags"); then
+		AC_MSG_RESULT([not found])
+		AC_MSG_ERROR([*** must be able to specify blibpath on AIX - check config.log])
+	else
+		AC_MSG_RESULT([$blibflags])
+	fi
+	LDFLAGS="$saved_LDFLAGS"
+	dnl Check for authenticate.  Might be in libs.a on older AIXes
+	AC_CHECK_FUNC([authenticate], [AC_DEFINE([WITH_AIXAUTHENTICATE], [1],
+		[Define if you want to enable AIX4's authenticate function])],
+		[AC_CHECK_LIB([s], [authenticate],
+			[ AC_DEFINE([WITH_AIXAUTHENTICATE])
+				LIBS="$LIBS -ls"
+			])
+		])
+	dnl Check for various auth function declarations in headers.
+	AC_CHECK_DECLS([authenticate, loginrestrictions, loginsuccess,
+	    passwdexpired, setauthdb], , , [#include <usersec.h>])
+	dnl Check if loginfailed is declared and takes 4 arguments (AIX >= 5.2)
+	AC_CHECK_DECLS([loginfailed],
+	    [AC_MSG_CHECKING([if loginfailed takes 4 arguments])
+	    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <usersec.h> ]],
+		[[ (void)loginfailed("user","host","tty",0); ]])],
+		[AC_MSG_RESULT([yes])
+		AC_DEFINE([AIX_LOGINFAILED_4ARG], [1],
+			[Define if your AIX loginfailed() function
+			takes 4 arguments (AIX >= 5.2)])], [AC_MSG_RESULT([no])
+	    ])],
+	    [],
+	    [#include <usersec.h>]
+	)
+	AC_CHECK_FUNCS([getgrset setauthdb])
+	AC_CHECK_DECL([F_CLOSEM],
+	    AC_DEFINE([HAVE_FCNTL_CLOSEM], [1], [Use F_CLOSEM fcntl for closefrom]),
+	    [],
+	    [ #include <limits.h>
+	      #include <fcntl.h> ]
+	)
+	check_for_aix_broken_getaddrinfo=1
+	AC_DEFINE([SETEUID_BREAKS_SETUID], [1],
+	    [Define if your platform breaks doing a seteuid before a setuid])
+	AC_DEFINE([BROKEN_SETREUID], [1], [Define if your setreuid() is broken])
+	AC_DEFINE([BROKEN_SETREGID], [1], [Define if your setregid() is broken])
+	dnl AIX handles lastlog as part of its login message
+	AC_DEFINE([DISABLE_LASTLOG], [1], [Define if you don't want to use lastlog])
+	AC_DEFINE([LOGIN_NEEDS_UTMPX], [1],
+		[Some systems need a utmpx entry for /bin/login to work])
+	AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV],
+		[Define to a Set Process Title type if your system is
+		supported by bsd-setproctitle.c])
+	AC_DEFINE([SSHPAM_CHAUTHTOK_NEEDS_RUID], [1],
+	    [AIX 5.2 and 5.3 (and presumably newer) require this])
+	AC_DEFINE([PTY_ZEROREAD], [1], [read(1) can return 0 for a non-closed fd])
+	AC_DEFINE([PLATFORM_SYS_DIR_UID], 2, [System dirs owned by bin (uid 2)])
+	AC_DEFINE([BROKEN_STRNDUP], 1, [strndup broken, see APAR IY61211])
+	AC_DEFINE([BROKEN_STRNLEN], 1, [strnlen broken, see APAR IY62551])
+	;;
+*-*-android*)
+	AC_DEFINE([DISABLE_UTMP], [1], [Define if you don't want to use utmp])
+	AC_DEFINE([DISABLE_WTMP], [1], [Define if you don't want to use wtmp])
+	;;
+*-*-cygwin*)
+	check_for_libcrypt_later=1
+	LIBS="$LIBS /usr/lib/textreadmode.o"
+	AC_DEFINE([HAVE_CYGWIN], [1], [Define if you are on Cygwin])
+	AC_DEFINE([USE_PIPES], [1], [Use PIPES instead of a socketpair()])
+	AC_DEFINE([NO_UID_RESTORATION_TEST], [1],
+		[Define to disable UID restoration test])
+	AC_DEFINE([DISABLE_SHADOW], [1],
+		[Define if you want to disable shadow passwords])
+	AC_DEFINE([NO_X11_UNIX_SOCKETS], [1],
+		[Define if X11 doesn't support AF_UNIX sockets on that system])
+	AC_DEFINE([DISABLE_FD_PASSING], [1],
+		[Define if your platform needs to skip post auth
+		file descriptor passing])
+	AC_DEFINE([SSH_IOBUFSZ], [65535], [Windows is sensitive to read buffer size])
+	AC_DEFINE([FILESYSTEM_NO_BACKSLASH], [1], [File names may not contain backslash characters])
+	# Cygwin defines optargs, optargs as declspec(dllimport) for historical
+	# reasons which cause compile warnings, so we disable those warnings.
+	OSSH_CHECK_CFLAG_COMPILE([-Wno-attributes])
+	;;
+*-*-dgux*)
+	AC_DEFINE([IP_TOS_IS_BROKEN], [1],
+		[Define if your system choked on IP TOS setting])
+	AC_DEFINE([SETEUID_BREAKS_SETUID])
+	AC_DEFINE([BROKEN_SETREUID])
+	AC_DEFINE([BROKEN_SETREGID])
+	;;
+*-*-darwin*)
+	use_pie=auto
+	AC_MSG_CHECKING([if we have working getaddrinfo])
+	AC_RUN_IFELSE([AC_LANG_SOURCE([[
+#include <mach-o/dyld.h>
+#include <stdlib.h>
+main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16))
+		exit(0);
+	else
+		exit(1);
+}
+			]])],
+	[AC_MSG_RESULT([working])],
+	[AC_MSG_RESULT([buggy])
+	AC_DEFINE([BROKEN_GETADDRINFO], [1],
+		[getaddrinfo is broken (if present)])
+	],
+	[AC_MSG_RESULT([assume it is working])])
+	AC_DEFINE([SETEUID_BREAKS_SETUID])
+	AC_DEFINE([BROKEN_SETREUID])
+	AC_DEFINE([BROKEN_SETREGID])
+	AC_DEFINE([BROKEN_GLOB], [1], [OS X glob does not do what we expect])
+	AC_DEFINE_UNQUOTED([BIND_8_COMPAT], [1],
+		[Define if your resolver libs need this for getrrsetbyname])
+	AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way])
+	AC_DEFINE([SSH_TUN_COMPAT_AF], [1],
+	    [Use tunnel device compatibility to OpenBSD])
+	AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
+	    [Prepend the address family to IP tunnel traffic])
+	m4_pattern_allow([AU_IPv])
+	AC_CHECK_DECL([AU_IPv4], [],
+	    AC_DEFINE([AU_IPv4], [0], [System only supports IPv4 audit records])
+	    [#include <bsm/audit.h>]
+	AC_DEFINE([LASTLOG_WRITE_PUTUTXLINE], [1],
+	    [Define if pututxline updates lastlog too])
+	)
+	AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV],
+		[Define to a Set Process Title type if your system is
+		supported by bsd-setproctitle.c])
+	AC_CHECK_FUNCS([sandbox_init])
+	AC_CHECK_HEADERS([sandbox.h])
+	AC_CHECK_LIB([sandbox], [sandbox_apply], [
+	    SSHDLIBS="$SSHDLIBS -lsandbox"
+	])
+	# proc_pidinfo()-based closefrom() replacement.
+	AC_CHECK_HEADERS([libproc.h])
+	AC_CHECK_FUNCS([proc_pidinfo])
+	;;
+*-*-dragonfly*)
+	SSHDLIBS="$SSHDLIBS -lcrypt"
+	TEST_MALLOC_OPTIONS="AFGJPRX"
+	;;
+*-*-haiku*)
+	LIBS="$LIBS -lbsd "
+	CFLAGS="$CFLAGS -D_BSD_SOURCE"
+	AC_CHECK_LIB([network], [socket])
+	AC_DEFINE([HAVE_U_INT64_T])
+	AC_DEFINE([DISABLE_UTMPX], [1], [no utmpx])
+	MANTYPE=man
+	;;
+*-*-hpux*)
+	# first we define all of the options common to all HP-UX releases
+	CPPFLAGS="$CPPFLAGS -D_HPUX_SOURCE -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1"
+	IPADDR_IN_DISPLAY=yes
+	AC_DEFINE([USE_PIPES])
+	AC_DEFINE([LOGIN_NEEDS_UTMPX])
+	AC_DEFINE([LOCKED_PASSWD_STRING], ["*"],
+		[String used in /etc/passwd to denote locked account])
+	AC_DEFINE([SPT_TYPE], [SPT_PSTAT])
+	AC_DEFINE([PLATFORM_SYS_DIR_UID], 2, [System dirs owned by bin (uid 2)])
+	maildir="/var/mail"
+	LIBS="$LIBS -lsec"
+	AC_CHECK_LIB([xnet], [t_error], ,
+	    [AC_MSG_ERROR([*** -lxnet needed on HP-UX - check config.log ***])])
+
+	# next, we define all of the options specific to major releases
+	case "$host" in
+	*-*-hpux10*)
+		if test -z "$GCC"; then
+			CFLAGS="$CFLAGS -Ae"
+		fi
+		;;
+	*-*-hpux11*)
+		AC_DEFINE([PAM_SUN_CODEBASE], [1],
+			[Define if you are using Solaris-derived PAM which
+			passes pam_messages to the conversation function
+			with an extra level of indirection])
+		AC_DEFINE([DISABLE_UTMP], [1],
+			[Define if you don't want to use utmp])
+		AC_DEFINE([USE_BTMP], [1], [Use btmp to log bad logins])
+		check_for_hpux_broken_getaddrinfo=1
+		check_for_conflicting_getspnam=1
+		;;
+	esac
+
+	# lastly, we define options specific to minor releases
+	case "$host" in
+	*-*-hpux10.26)
+		AC_DEFINE([HAVE_SECUREWARE], [1],
+			[Define if you have SecureWare-based
+			protected password database])
+		disable_ptmx_check=yes
+		LIBS="$LIBS -lsecpw"
+		;;
+	esac
+	;;
+*-*-irix5*)
+	PATH="$PATH:/usr/etc"
+	AC_DEFINE([BROKEN_INET_NTOA], [1],
+		[Define if you system's inet_ntoa is busted
+		(e.g. Irix gcc issue)])
+	AC_DEFINE([SETEUID_BREAKS_SETUID])
+	AC_DEFINE([BROKEN_SETREUID])
+	AC_DEFINE([BROKEN_SETREGID])
+	AC_DEFINE([WITH_ABBREV_NO_TTY], [1],
+		[Define if you shouldn't strip 'tty' from your
+		ttyname in [uw]tmp])
+	AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"])
+	;;
+*-*-irix6*)
+	PATH="$PATH:/usr/etc"
+	AC_DEFINE([WITH_IRIX_ARRAY], [1],
+		[Define if you have/want arrays
+		(cluster-wide session management, not C arrays)])
+	AC_DEFINE([WITH_IRIX_PROJECT], [1],
+		[Define if you want IRIX project management])
+	AC_DEFINE([WITH_IRIX_AUDIT], [1],
+		[Define if you want IRIX audit trails])
+	AC_CHECK_FUNC([jlimit_startjob], [AC_DEFINE([WITH_IRIX_JOBS], [1],
+		[Define if you want IRIX kernel jobs])])
+	AC_DEFINE([BROKEN_INET_NTOA])
+	AC_DEFINE([SETEUID_BREAKS_SETUID])
+	AC_DEFINE([BROKEN_SETREUID])
+	AC_DEFINE([BROKEN_SETREGID])
+	AC_DEFINE([BROKEN_UPDWTMPX], [1], [updwtmpx is broken (if present)])
+	AC_DEFINE([WITH_ABBREV_NO_TTY])
+	AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"])
+	;;
+*-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
+	check_for_libcrypt_later=1
+	AC_DEFINE([PAM_TTY_KLUDGE])
+	AC_DEFINE([LOCKED_PASSWD_PREFIX], ["!"])
+	AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV])
+	AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts])
+	AC_DEFINE([USE_BTMP], [1], [Use btmp to log bad logins])
+	;;
+*-*-linux*)
+	no_dev_ptmx=1
+	use_pie=auto
+	check_for_libcrypt_later=1
+	check_for_openpty_ctty_bug=1
+	dnl Target SUSv3/POSIX.1-2001 plus BSD specifics.
+	dnl _DEFAULT_SOURCE is the new name for _BSD_SOURCE
+	CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE"
+	AC_DEFINE([PAM_TTY_KLUDGE], [1],
+		[Work around problematic Linux PAM modules handling of PAM_TTY])
+	AC_DEFINE([LOCKED_PASSWD_PREFIX], ["!"],
+		[String used in /etc/passwd to denote locked account])
+	AC_DEFINE([SPT_TYPE], [SPT_REUSEARGV])
+	AC_DEFINE([LINK_OPNOTSUPP_ERRNO], [EPERM],
+		[Define to whatever link() returns for "not supported"
+		if it doesn't return EOPNOTSUPP.])
+	AC_DEFINE([_PATH_BTMP], ["/var/log/btmp"], [log for bad login attempts])
+	AC_DEFINE([USE_BTMP])
+	AC_DEFINE([LINUX_OOM_ADJUST], [1], [Adjust Linux out-of-memory killer])
+	inet6_default_4in6=yes
+	case `uname -r` in
+	1.*|2.0.*)
+		AC_DEFINE([BROKEN_CMSG_TYPE], [1],
+			[Define if cmsg_type is not passed correctly])
+		;;
+	esac
+	# tun(4) forwarding compat code
+	AC_CHECK_HEADERS([linux/if_tun.h])
+	if test "x$ac_cv_header_linux_if_tun_h" = "xyes" ; then
+		AC_DEFINE([SSH_TUN_LINUX], [1],
+		    [Open tunnel devices the Linux tun/tap way])
+		AC_DEFINE([SSH_TUN_COMPAT_AF], [1],
+		    [Use tunnel device compatibility to OpenBSD])
+		AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
+		    [Prepend the address family to IP tunnel traffic])
+	fi
+	AC_CHECK_HEADER([linux/if.h],
+	    AC_DEFINE([SYS_RDOMAIN_LINUX], [1],
+		[Support routing domains using Linux VRF]), [], [
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+	    ])
+	AC_CHECK_HEADERS([linux/seccomp.h linux/filter.h linux/audit.h], [],
+	    [], [#include <linux/types.h>])
+	# Obtain MIPS ABI
+	case "$host" in
+	mips*)
+		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#if _MIPS_SIM != _ABIO32
+#error
+#endif
+			]])],[mips_abi="o32"],[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#if _MIPS_SIM != _ABIN32
+#error
+#endif
+				]])],[mips_abi="n32"],[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#if _MIPS_SIM != _ABI64
+#error
+#endif
+					]])],[mips_abi="n64"],[AC_MSG_ERROR([unknown MIPS ABI])
+				])
+			])
+		])
+		;;
+	esac
+	AC_MSG_CHECKING([for seccomp architecture])
+	seccomp_audit_arch=
+	case "$host" in
+	x86_64-*)
+		seccomp_audit_arch=AUDIT_ARCH_X86_64
+		;;
+	i*86-*)
+		seccomp_audit_arch=AUDIT_ARCH_I386
+		;;
+	arm*-*)
+		seccomp_audit_arch=AUDIT_ARCH_ARM
+		;;
+	aarch64*-*)
+		seccomp_audit_arch=AUDIT_ARCH_AARCH64
+		;;
+	s390x-*)
+		seccomp_audit_arch=AUDIT_ARCH_S390X
+		;;
+	s390-*)
+		seccomp_audit_arch=AUDIT_ARCH_S390
+		;;
+	powerpc64-*)
+		seccomp_audit_arch=AUDIT_ARCH_PPC64
+		;;
+	powerpc64le-*)
+		seccomp_audit_arch=AUDIT_ARCH_PPC64LE
+		;;
+	mips-*)
+		seccomp_audit_arch=AUDIT_ARCH_MIPS
+		;;
+	mipsel-*)
+		seccomp_audit_arch=AUDIT_ARCH_MIPSEL
+		;;
+	mips64-*)
+		case "$mips_abi" in
+		"n32")
+			seccomp_audit_arch=AUDIT_ARCH_MIPS64N32
+			;;
+		"n64")
+			seccomp_audit_arch=AUDIT_ARCH_MIPS64
+			;;
+		esac
+		;;
+	mips64el-*)
+		case "$mips_abi" in
+		"n32")
+			seccomp_audit_arch=AUDIT_ARCH_MIPSEL64N32
+			;;
+		"n64")
+			seccomp_audit_arch=AUDIT_ARCH_MIPSEL64
+			;;
+		esac
+		;;
+	riscv64-*)
+		seccomp_audit_arch=AUDIT_ARCH_RISCV64
+		;;
+	esac
+	if test "x$seccomp_audit_arch" != "x" ; then
+		AC_MSG_RESULT(["$seccomp_audit_arch"])
+		AC_DEFINE_UNQUOTED([SECCOMP_AUDIT_ARCH], [$seccomp_audit_arch],
+		    [Specify the system call convention in use])
+	else
+		AC_MSG_RESULT([architecture not supported])
+	fi
+	;;
+mips-sony-bsd|mips-sony-newsos4)
+	AC_DEFINE([NEED_SETPGRP], [1], [Need setpgrp to acquire controlling tty])
+	SONY=1
+	;;
+*-*-netbsd*)
+	check_for_libcrypt_before=1
+	if test "x$withval" != "xno" ; then
+		rpath_opt="-R"
+	fi
+	CPPFLAGS="$CPPFLAGS -D_OPENBSD_SOURCE"
+	AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way])
+	AC_CHECK_HEADER([net/if_tap.h], ,
+	    AC_DEFINE([SSH_TUN_NO_L2], [1], [No layer 2 tunnel support]))
+	AC_DEFINE([SSH_TUN_PREPEND_AF], [1],
+	    [Prepend the address family to IP tunnel traffic])
+	TEST_MALLOC_OPTIONS="AJRX"
+	AC_DEFINE([BROKEN_READ_COMPARISON], [1],
+	    [NetBSD read function is sometimes redirected, breaking atomicio comparisons against it])
+	;;
+*-*-freebsd*)
+	check_for_libcrypt_later=1
+	AC_DEFINE([LOCKED_PASSWD_PREFIX], ["*LOCKED*"], [Account locked with pw(1)])
+	AC_DEFINE([SSH_TUN_FREEBSD], [1], [Open tunnel devices the FreeBSD way])
+	AC_CHECK_HEADER([net/if_tap.h], ,
+	    AC_DEFINE([SSH_TUN_NO_L2], [1], [No layer 2 tunnel support]))
+	AC_DEFINE([BROKEN_GLOB], [1], [FreeBSD glob does not do what we need])
+	TEST_MALLOC_OPTIONS="AJRX"
+	# Preauth crypto occasionally uses file descriptors for crypto offload
+	# and will crash if they cannot be opened.
+	AC_DEFINE([SANDBOX_SKIP_RLIMIT_NOFILE], [1],
+	    [define if setrlimit RLIMIT_NOFILE breaks things])
+	;;
+*-*-bsdi*)
+	AC_DEFINE([SETEUID_BREAKS_SETUID])
+	AC_DEFINE([BROKEN_SETREUID])
+	AC_DEFINE([BROKEN_SETREGID])
+	;;
+*-next-*)
+	conf_lastlog_location="/usr/adm/lastlog"
+	conf_utmp_location=/etc/utmp
+	conf_wtmp_location=/usr/adm/wtmp
+	maildir=/usr/spool/mail
+	AC_DEFINE([HAVE_NEXT], [1], [Define if you are on NeXT])
+	AC_DEFINE([USE_PIPES])
+	AC_DEFINE([BROKEN_SAVED_UIDS], [1], [Needed for NeXT])
+	;;
+*-*-openbsd*)
+	use_pie=auto
+	AC_DEFINE([HAVE_ATTRIBUTE__SENTINEL__], [1], [OpenBSD's gcc has sentinel])
+	AC_DEFINE([HAVE_ATTRIBUTE__BOUNDED__], [1], [OpenBSD's gcc has bounded])
+	AC_DEFINE([SSH_TUN_OPENBSD], [1], [Open tunnel devices the OpenBSD way])
+	AC_DEFINE([SYSLOG_R_SAFE_IN_SIGHAND], [1],
+	    [syslog_r function is safe to use in in a signal handler])
+	TEST_MALLOC_OPTIONS="AFGJPRX"
+	;;
+*-*-solaris*)
+	if test "x$withval" != "xno" ; then
+		rpath_opt="-R"
+	fi
+	AC_DEFINE([PAM_SUN_CODEBASE])
+	AC_DEFINE([LOGIN_NEEDS_UTMPX])
+	AC_DEFINE([PAM_TTY_KLUDGE])
+	AC_DEFINE([SSHPAM_CHAUTHTOK_NEEDS_RUID], [1],
+		[Define if pam_chauthtok wants real uid set
+		to the unpriv'ed user])
+	AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"])
+	# Pushing STREAMS modules will cause sshd to acquire a controlling tty.
+	AC_DEFINE([SSHD_ACQUIRES_CTTY], [1],
+		[Define if sshd somehow reacquires a controlling TTY
+		after setsid()])
+	AC_DEFINE([PASSWD_NEEDS_USERNAME], [1], [must supply username to passwd
+		in case the name is longer than 8 chars])
+	AC_DEFINE([BROKEN_TCGETATTR_ICANON], [1], [tcgetattr with ICANON may hang])
+	external_path_file=/etc/default/login
+	# hardwire lastlog location (can't detect it on some versions)
+	conf_lastlog_location="/var/adm/lastlog"
+	AC_MSG_CHECKING([for obsolete utmp and wtmp in solaris2.x])
+	sol2ver=`echo "$host"| sed -e 's/.*[[0-9]]\.//'`
+	if test "$sol2ver" -ge 8; then
+		AC_MSG_RESULT([yes])
+		AC_DEFINE([DISABLE_UTMP])
+		AC_DEFINE([DISABLE_WTMP], [1],
+			[Define if you don't want to use wtmp])
+	else
+		AC_MSG_RESULT([no])
+	fi
+	AC_CHECK_FUNCS([setpflags])
+	AC_CHECK_FUNCS([setppriv])
+	AC_CHECK_FUNCS([priv_basicset])
+	AC_CHECK_HEADERS([priv.h])
+	AC_ARG_WITH([solaris-contracts],
+		[  --with-solaris-contracts Enable Solaris process contracts (experimental)],
+		[
+		AC_CHECK_LIB([contract], [ct_tmpl_activate],
+			[ AC_DEFINE([USE_SOLARIS_PROCESS_CONTRACTS], [1],
+				[Define if you have Solaris process contracts])
+			  LIBS="$LIBS -lcontract"
+			  SPC_MSG="yes" ], )
+		],
+	)
+	AC_ARG_WITH([solaris-projects],
+		[  --with-solaris-projects Enable Solaris projects (experimental)],
+		[
+		AC_CHECK_LIB([project], [setproject],
+			[ AC_DEFINE([USE_SOLARIS_PROJECTS], [1],
+				[Define if you have Solaris projects])
+			LIBS="$LIBS -lproject"
+			SP_MSG="yes" ], )
+		],
+	)
+	AC_ARG_WITH([solaris-privs],
+		[  --with-solaris-privs    Enable Solaris/Illumos privileges (experimental)],
+		[
+		AC_MSG_CHECKING([for Solaris/Illumos privilege support])
+		if test "x$ac_cv_func_setppriv" = "xyes" -a \
+			"x$ac_cv_header_priv_h" = "xyes" ; then
+			SOLARIS_PRIVS=yes
+			AC_MSG_RESULT([found])
+			AC_DEFINE([NO_UID_RESTORATION_TEST], [1],
+				[Define to disable UID restoration test])
+			AC_DEFINE([USE_SOLARIS_PRIVS], [1],
+				[Define if you have Solaris privileges])
+			SPP_MSG="yes"
+		else
+			AC_MSG_RESULT([not found])
+			AC_MSG_ERROR([*** must have support for Solaris privileges to use --with-solaris-privs])
+		fi
+		],
+	)
+	TEST_SHELL=$SHELL	# let configure find us a capable shell
+	;;
+*-*-sunos4*)
+	CPPFLAGS="$CPPFLAGS -DSUNOS4"
+	AC_CHECK_FUNCS([getpwanam])
+	AC_DEFINE([PAM_SUN_CODEBASE])
+	conf_utmp_location=/etc/utmp
+	conf_wtmp_location=/var/adm/wtmp
+	conf_lastlog_location=/var/adm/lastlog
+	AC_DEFINE([USE_PIPES])
+	AC_DEFINE([DISABLE_UTMPX], [1], [no utmpx])
+	;;
+*-ncr-sysv*)
+	LIBS="$LIBS -lc89"
+	AC_DEFINE([USE_PIPES])
+	AC_DEFINE([SSHD_ACQUIRES_CTTY])
+	AC_DEFINE([SETEUID_BREAKS_SETUID])
+	AC_DEFINE([BROKEN_SETREUID])
+	AC_DEFINE([BROKEN_SETREGID])
+	;;
+*-sni-sysv*)
+	# /usr/ucblib MUST NOT be searched on ReliantUNIX
+	AC_CHECK_LIB([dl], [dlsym], ,)
+	# -lresolv needs to be at the end of LIBS or DNS lookups break
+	AC_CHECK_LIB([resolv], [res_query], [ LIBS="$LIBS -lresolv" ])
+	IPADDR_IN_DISPLAY=yes
+	AC_DEFINE([USE_PIPES])
+	AC_DEFINE([IP_TOS_IS_BROKEN])
+	AC_DEFINE([SETEUID_BREAKS_SETUID])
+	AC_DEFINE([BROKEN_SETREUID])
+	AC_DEFINE([BROKEN_SETREGID])
+	AC_DEFINE([SSHD_ACQUIRES_CTTY])
+	external_path_file=/etc/default/login
+	# /usr/ucblib/libucb.a no longer needed on ReliantUNIX
+	# Attention: always take care to bind libsocket and libnsl before libc,
+	# otherwise you will find lots of "SIOCGPGRP errno 22" on syslog
+	;;
+# UnixWare 1.x, UnixWare 2.x, and others based on code from Univel.
+*-*-sysv4.2*)
+	AC_DEFINE([USE_PIPES])
+	AC_DEFINE([SETEUID_BREAKS_SETUID])
+	AC_DEFINE([BROKEN_SETREUID])
+	AC_DEFINE([BROKEN_SETREGID])
+	AC_DEFINE([PASSWD_NEEDS_USERNAME], [1], [must supply username to passwd])
+	AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"])
+	TEST_SHELL=$SHELL	# let configure find us a capable shell
+	;;
+# UnixWare 7.x, OpenUNIX 8
+*-*-sysv5*)
+	CPPFLAGS="$CPPFLAGS -Dvsnprintf=_xvsnprintf -Dsnprintf=_xsnprintf"
+	AC_DEFINE([UNIXWARE_LONG_PASSWORDS], [1], [Support passwords > 8 chars])
+	AC_DEFINE([USE_PIPES])
+	AC_DEFINE([SETEUID_BREAKS_SETUID])
+	AC_DEFINE([BROKEN_GETADDRINFO])
+	AC_DEFINE([BROKEN_SETREUID])
+	AC_DEFINE([BROKEN_SETREGID])
+	AC_DEFINE([PASSWD_NEEDS_USERNAME])
+	AC_DEFINE([BROKEN_TCGETATTR_ICANON])
+	TEST_SHELL=$SHELL	# let configure find us a capable shell
+	check_for_libcrypt_later=1
+	case "$host" in
+	*-*-sysv5SCO_SV*)	# SCO OpenServer 6.x
+		maildir=/var/spool/mail
+		AC_DEFINE([BROKEN_UPDWTMPX])
+		AC_CHECK_LIB([prot], [getluid], [ LIBS="$LIBS -lprot"
+			AC_CHECK_FUNCS([getluid setluid], , , [-lprot])
+			], , )
+		;;
+	*)	AC_DEFINE([LOCKED_PASSWD_STRING], ["*LK*"])
+		;;
+	esac
+	;;
+*-*-sysv*)
+	;;
+# SCO UNIX and OEM versions of SCO UNIX
+*-*-sco3.2v4*)
+	AC_MSG_ERROR("This Platform is no longer supported.")
+	;;
+# SCO OpenServer 5.x
+*-*-sco3.2v5*)
+	if test -z "$GCC"; then
+		CFLAGS="$CFLAGS -belf"
+	fi
+	LIBS="$LIBS -lprot -lx -ltinfo -lm"
+	no_dev_ptmx=1
+	AC_DEFINE([USE_PIPES])
+	AC_DEFINE([HAVE_SECUREWARE])
+	AC_DEFINE([DISABLE_SHADOW])
+	AC_DEFINE([DISABLE_FD_PASSING])
+	AC_DEFINE([SETEUID_BREAKS_SETUID])
+	AC_DEFINE([BROKEN_GETADDRINFO])
+	AC_DEFINE([BROKEN_SETREUID])
+	AC_DEFINE([BROKEN_SETREGID])
+	AC_DEFINE([WITH_ABBREV_NO_TTY])
+	AC_DEFINE([BROKEN_UPDWTMPX])
+	AC_DEFINE([PASSWD_NEEDS_USERNAME])
+	AC_CHECK_FUNCS([getluid setluid])
+	MANTYPE=man
+	TEST_SHELL=$SHELL	# let configure find us a capable shell
+	SKIP_DISABLE_LASTLOG_DEFINE=yes
+	;;
+*-dec-osf*)
+	AC_MSG_CHECKING([for Digital Unix SIA])
+	no_osfsia=""
+	AC_ARG_WITH([osfsia],
+		[  --with-osfsia           Enable Digital Unix SIA],
+		[
+			if test "x$withval" = "xno" ; then
+				AC_MSG_RESULT([disabled])
+				no_osfsia=1
+			fi
+		],
+	)
+	if test -z "$no_osfsia" ; then
+		if test -f /etc/sia/matrix.conf; then
+			AC_MSG_RESULT([yes])
+			AC_DEFINE([HAVE_OSF_SIA], [1],
+				[Define if you have Digital Unix Security
+				Integration Architecture])
+			AC_DEFINE([DISABLE_LOGIN], [1],
+				[Define if you don't want to use your
+				system's login() call])
+			AC_DEFINE([DISABLE_FD_PASSING])
+			LIBS="$LIBS -lsecurity -ldb -lm -laud"
+			SIA_MSG="yes"
+		else
+			AC_MSG_RESULT([no])
+			AC_DEFINE([LOCKED_PASSWD_SUBSTR], ["Nologin"],
+			  [String used in /etc/passwd to denote locked account])
+		fi
+	fi
+	AC_DEFINE([BROKEN_GETADDRINFO])
+	AC_DEFINE([SETEUID_BREAKS_SETUID])
+	AC_DEFINE([BROKEN_SETREUID])
+	AC_DEFINE([BROKEN_SETREGID])
+	AC_DEFINE([BROKEN_READV_COMPARISON], [1], [Can't do comparisons on readv])
+	;;
+
+*-*-nto-qnx*)
+	AC_DEFINE([USE_PIPES])
+	AC_DEFINE([NO_X11_UNIX_SOCKETS])
+	AC_DEFINE([DISABLE_LASTLOG])
+	AC_DEFINE([SSHD_ACQUIRES_CTTY])
+	AC_DEFINE([BROKEN_SHADOW_EXPIRE], [1], [QNX shadow support is broken])
+	enable_etc_default_login=no	# has incompatible /etc/default/login
+	case "$host" in
+	*-*-nto-qnx6*)
+		AC_DEFINE([DISABLE_FD_PASSING])
+		;;
+	esac
+	;;
+
+*-*-ultrix*)
+	AC_DEFINE([BROKEN_GETGROUPS], [1], [getgroups(0,NULL) will return -1])
+	AC_DEFINE([NEED_SETPGRP], [1], [Need setpgrp to for controlling tty])
+	AC_DEFINE([HAVE_SYS_SYSLOG_H], [1], [Force use of sys/syslog.h on Ultrix])
+	AC_DEFINE([DISABLE_UTMPX], [1], [Disable utmpx])
+	# DISABLE_FD_PASSING so that we call setpgrp as root, otherwise we
+	# don't get a controlling tty.
+	AC_DEFINE([DISABLE_FD_PASSING], [1], [Need to call setpgrp as root])
+	# On Ultrix some headers are not protected against multiple includes,
+	# so we create wrappers and put it where the compiler will find it.
+	AC_MSG_WARN([creating compat wrappers for headers])
+	mkdir -p netinet
+	for header in netinet/ip.h netdb.h resolv.h; do
+		name=`echo $header | tr 'a-z/.' 'A-Z__'`
+		cat >$header <<EOD
+#ifndef _SSH_COMPAT_${name}
+#define _SSH_COMPAT_${name}
+#include "/usr/include/${header}"
+#endif
+EOD
+	done
+	;;
+
+*-*-lynxos)
+	CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__"
+	AC_DEFINE([BROKEN_SETVBUF], [1],
+	    [LynxOS has broken setvbuf() implementation])
+	;;
+esac
+
+AC_MSG_CHECKING([compiler and flags for sanity])
+AC_RUN_IFELSE([AC_LANG_PROGRAM([[ #include <stdlib.h> ]], [[ exit(0); ]])],
+	[	AC_MSG_RESULT([yes]) ],
+	[
+		AC_MSG_RESULT([no])
+		AC_MSG_ERROR([*** compiler cannot create working executables, check config.log ***])
+	],
+	[	AC_MSG_WARN([cross compiling: not checking compiler sanity]) ]
+)
+
+dnl Checks for header files.
+# Checks for libraries.
+AC_CHECK_FUNC([setsockopt], , [AC_CHECK_LIB([socket], [setsockopt])])
+
+dnl IRIX and Solaris 2.5.1 have dirname() in libgen
+AC_CHECK_FUNCS([dirname], [AC_CHECK_HEADERS([libgen.h])] , [
+	AC_CHECK_LIB([gen], [dirname], [
+		AC_CACHE_CHECK([for broken dirname],
+			ac_cv_have_broken_dirname, [
+			save_LIBS="$LIBS"
+			LIBS="$LIBS -lgen"
+			AC_RUN_IFELSE(
+				[AC_LANG_SOURCE([[
+#include <libgen.h>
+#include <string.h>
+#include <stdlib.h>
+
+int main(int argc, char **argv) {
+    char *s, buf[32];
+
+    strncpy(buf,"/etc", 32);
+    s = dirname(buf);
+    if (!s || strncmp(s, "/", 32) != 0) {
+	exit(1);
+    } else {
+	exit(0);
+    }
+}
+				]])],
+				[ ac_cv_have_broken_dirname="no" ],
+				[ ac_cv_have_broken_dirname="yes" ],
+				[ ac_cv_have_broken_dirname="no" ],
+			)
+			LIBS="$save_LIBS"
+		])
+		if test "x$ac_cv_have_broken_dirname" = "xno" ; then
+			LIBS="$LIBS -lgen"
+			AC_DEFINE([HAVE_DIRNAME])
+			AC_CHECK_HEADERS([libgen.h])
+		fi
+	])
+])
+
+AC_CHECK_FUNC([getspnam], ,
+	[AC_CHECK_LIB([gen], [getspnam], [LIBS="$LIBS -lgen"])])
+AC_SEARCH_LIBS([basename], [gen], [AC_DEFINE([HAVE_BASENAME], [1],
+	[Define if you have the basename function.])])
+
+dnl zlib defaults to enabled
+zlib=yes
+AC_ARG_WITH([zlib],
+	[  --with-zlib=PATH        Use zlib in PATH],
+	[ if test "x$withval" = "xno" ; then
+		zlib=no
+	  elif test "x$withval" != "xyes"; then
+		if test -d "$withval/lib"; then
+			if test -n "${rpath_opt}"; then
+				LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}"
+			else
+				LDFLAGS="-L${withval}/lib ${LDFLAGS}"
+			fi
+		else
+			if test -n "${rpath_opt}"; then
+				LDFLAGS="-L${withval} ${rpath_opt}${withval} ${LDFLAGS}"
+			else
+				LDFLAGS="-L${withval} ${LDFLAGS}"
+			fi
+		fi
+		if test -d "$withval/include"; then
+			CPPFLAGS="-I${withval}/include ${CPPFLAGS}"
+		else
+			CPPFLAGS="-I${withval} ${CPPFLAGS}"
+		fi
+	fi ]
+)
+
+AC_MSG_CHECKING([for zlib])
+if test "x${zlib}" = "xno"; then
+	AC_MSG_RESULT([no])
+else
+	AC_MSG_RESULT([yes])
+	AC_DEFINE([WITH_ZLIB], [1], [Enable zlib])
+    AC_CHECK_HEADER([zlib.h], ,[AC_MSG_ERROR([*** zlib.h missing - please install first or check config.log ***])])
+    AC_CHECK_LIB([z], [deflate], ,
+	[
+		saved_CPPFLAGS="$CPPFLAGS"
+		saved_LDFLAGS="$LDFLAGS"
+		save_LIBS="$LIBS"
+		dnl Check default zlib install dir
+		if test -n "${rpath_opt}"; then
+			LDFLAGS="-L/usr/local/lib ${rpath_opt}/usr/local/lib ${saved_LDFLAGS}"
+		else
+			LDFLAGS="-L/usr/local/lib ${saved_LDFLAGS}"
+		fi
+		CPPFLAGS="-I/usr/local/include ${saved_CPPFLAGS}"
+		LIBS="$LIBS -lz"
+		AC_TRY_LINK_FUNC([deflate], [AC_DEFINE([HAVE_LIBZ])],
+			[
+				AC_MSG_ERROR([*** zlib missing - please install first or check config.log ***])
+			]
+		)
+	]
+    )
+
+    AC_ARG_WITH([zlib-version-check],
+	[  --without-zlib-version-check Disable zlib version check],
+	[  if test "x$withval" = "xno" ; then
+		zlib_check_nonfatal=1
+	   fi
+	]
+    )
+
+    AC_MSG_CHECKING([for possibly buggy zlib])
+    AC_RUN_IFELSE([AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <stdlib.h>
+#include <zlib.h>
+	]],
+	[[
+	int a=0, b=0, c=0, d=0, n, v;
+	n = sscanf(ZLIB_VERSION, "%d.%d.%d.%d", &a, &b, &c, &d);
+	if (n != 3 && n != 4)
+		exit(1);
+	v = a*1000000 + b*10000 + c*100 + d;
+	fprintf(stderr, "found zlib version %s (%d)\n", ZLIB_VERSION, v);
+
+	/* 1.1.4 is OK */
+	if (a == 1 && b == 1 && c >= 4)
+		exit(0);
+
+	/* 1.2.3 and up are OK */
+	if (v >= 1020300)
+		exit(0);
+
+	exit(2);
+	]])],
+	AC_MSG_RESULT([no]),
+	[ AC_MSG_RESULT([yes])
+	  if test -z "$zlib_check_nonfatal" ; then
+		AC_MSG_ERROR([*** zlib too old - check config.log ***
+Your reported zlib version has known security problems.  It's possible your
+vendor has fixed these problems without changing the version number.  If you
+are sure this is the case, you can disable the check by running
+"./configure --without-zlib-version-check".
+If you are in doubt, upgrade zlib to version 1.2.3 or greater.
+See http://www.gzip.org/zlib/ for details.])
+	  else
+		AC_MSG_WARN([zlib version may have security problems])
+	  fi
+	],
+	[	AC_MSG_WARN([cross compiling: not checking zlib version]) ]
+    )
+fi
+
+dnl UnixWare 2.x
+AC_CHECK_FUNC([strcasecmp],
+	[], [ AC_CHECK_LIB([resolv], [strcasecmp], [LIBS="$LIBS -lresolv"]) ]
+)
+AC_CHECK_FUNCS([utimes],
+	[], [ AC_CHECK_LIB([c89], [utimes], [AC_DEFINE([HAVE_UTIMES])
+					LIBS="$LIBS -lc89"]) ]
+)
+
+dnl    Checks for libutil functions
+AC_CHECK_HEADERS([bsd/libutil.h libutil.h])
+AC_SEARCH_LIBS([fmt_scaled], [util bsd])
+AC_SEARCH_LIBS([scan_scaled], [util bsd])
+AC_SEARCH_LIBS([login], [util bsd])
+AC_SEARCH_LIBS([logout], [util bsd])
+AC_SEARCH_LIBS([logwtmp], [util bsd])
+AC_SEARCH_LIBS([openpty], [util bsd])
+AC_SEARCH_LIBS([updwtmp], [util bsd])
+AC_CHECK_FUNCS([fmt_scaled scan_scaled login logout openpty updwtmp logwtmp])
+
+# On some platforms, inet_ntop and gethostbyname may be found in libresolv
+# or libnsl.
+AC_SEARCH_LIBS([inet_ntop], [resolv nsl])
+AC_SEARCH_LIBS([gethostbyname], [resolv nsl])
+
+# Some Linux distribtions ship the BSD libc hashing functions in
+# separate libraries.
+AC_SEARCH_LIBS([SHA256Update], [md bsd])
+
+# "Particular Function Checks"
+# see https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Particular-Functions.html
+AC_FUNC_STRFTIME
+AC_FUNC_MALLOC
+AC_FUNC_REALLOC
+# autoconf doesn't have AC_FUNC_CALLOC so fake it if malloc returns NULL;
+AC_MSG_CHECKING([if calloc(0, N) returns non-null])
+AC_RUN_IFELSE(
+	[AC_LANG_PROGRAM(
+		[[ #include <stdlib.h> ]],
+		[[ void *p = calloc(0, 1); exit(p == NULL); ]]
+	)],
+	[ func_calloc_0_nonnull=yes ],
+	[ func_calloc_0_nonnull=no ],
+	[ AC_MSG_WARN([cross compiling: assuming same as malloc])
+	  func_calloc_0_nonnull="$ac_cv_func_malloc_0_nonnull"]
+)
+AC_MSG_RESULT([$func_calloc_0_nonnull])
+
+if test "x$func_calloc_0_nonnull" = "xyes"; then
+	AC_DEFINE(HAVE_CALLOC, 1, [calloc(0, x) returns non-null])
+else
+	AC_DEFINE(HAVE_CALLOC, 0, [calloc(0, x) returns NULL])
+	AC_DEFINE(calloc, rpl_calloc,
+	    [Define to rpl_calloc if the replacement function should be used.])
+fi
+
+# Check for ALTDIRFUNC glob() extension
+AC_MSG_CHECKING([for GLOB_ALTDIRFUNC support])
+AC_EGREP_CPP([FOUNDIT],
+	[
+		#include <glob.h>
+		#ifdef GLOB_ALTDIRFUNC
+		FOUNDIT
+		#endif
+	],
+	[
+		AC_DEFINE([GLOB_HAS_ALTDIRFUNC], [1],
+			[Define if your system glob() function has
+			the GLOB_ALTDIRFUNC extension])
+		AC_MSG_RESULT([yes])
+	],
+	[
+		AC_MSG_RESULT([no])
+	]
+)
+
+# Check for g.gl_matchc glob() extension
+AC_MSG_CHECKING([for gl_matchc field in glob_t])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <glob.h> ]],
+	[[ glob_t g; g.gl_matchc = 1; ]])],
+	[
+		AC_DEFINE([GLOB_HAS_GL_MATCHC], [1],
+			[Define if your system glob() function has
+			gl_matchc options in glob_t])
+		AC_MSG_RESULT([yes])
+	], [
+		AC_MSG_RESULT([no])
+])
+
+# Check for g.gl_statv glob() extension
+AC_MSG_CHECKING([for gl_statv and GLOB_KEEPSTAT extensions for glob])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <glob.h> ]], [[
+#ifndef GLOB_KEEPSTAT
+#error "glob does not support GLOB_KEEPSTAT extension"
+#endif
+glob_t g;
+g.gl_statv = NULL;
+]])],
+	[
+		AC_DEFINE([GLOB_HAS_GL_STATV], [1],
+			[Define if your system glob() function has
+			gl_statv options in glob_t])
+		AC_MSG_RESULT([yes])
+	], [
+		AC_MSG_RESULT([no])
+
+])
+
+AC_CHECK_DECLS([GLOB_NOMATCH], , , [#include <glob.h>])
+
+AC_CHECK_DECL([VIS_ALL], ,
+    AC_DEFINE(BROKEN_STRNVIS, 1, [missing VIS_ALL]), [#include <vis.h>])
+
+AC_MSG_CHECKING([whether struct dirent allocates space for d_name])
+AC_RUN_IFELSE(
+	[AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdlib.h>
+	]],
+	[[
+	struct dirent d;
+	exit(sizeof(d.d_name)<=sizeof(char));
+	]])],
+	[AC_MSG_RESULT([yes])],
+	[
+		AC_MSG_RESULT([no])
+		AC_DEFINE([BROKEN_ONE_BYTE_DIRENT_D_NAME], [1],
+			[Define if your struct dirent expects you to
+			allocate extra space for d_name])
+	],
+	[
+		AC_MSG_WARN([cross compiling: assuming BROKEN_ONE_BYTE_DIRENT_D_NAME])
+		AC_DEFINE([BROKEN_ONE_BYTE_DIRENT_D_NAME])
+	]
+)
+
+AC_MSG_CHECKING([for /proc/pid/fd directory])
+if test -d "/proc/$$/fd" ; then
+	AC_DEFINE([HAVE_PROC_PID], [1], [Define if you have /proc/$pid/fd])
+	AC_MSG_RESULT([yes])
+else
+	AC_MSG_RESULT([no])
+fi
+
+# Check whether user wants TCP wrappers support
+TCPW_MSG="no"
+AC_ARG_WITH([tcp-wrappers],
+	[  --with-tcp-wrappers[[=PATH]] Enable tcpwrappers support (optionally in PATH)],
+	[
+		if test "x$withval" != "xno" ; then
+			saved_LIBS="$LIBS"
+			saved_LDFLAGS="$LDFLAGS"
+			saved_CPPFLAGS="$CPPFLAGS"
+			if test -n "${withval}" && \
+			    test "x${withval}" != "xyes"; then
+				if test -d "${withval}/lib"; then
+					if test -n "${need_dash_r}"; then
+						LDFLAGS="-L${withval}/lib -R${withval}/lib ${LDFLAGS}"
+					else
+						LDFLAGS="-L${withval}/lib ${LDFLAGS}"
+					fi
+				else
+					if test -n "${need_dash_r}"; then
+						LDFLAGS="-L${withval} -R${withval} ${LDFLAGS}"
+					else
+						LDFLAGS="-L${withval} ${LDFLAGS}"
+					fi
+				fi
+				if test -d "${withval}/include"; then
+					CPPFLAGS="-I${withval}/include ${CPPFLAGS}"
+				else
+					CPPFLAGS="-I${withval} ${CPPFLAGS}"
+				fi
+			fi
+			LIBS="-lwrap -lnsl $LIBS"
+			AC_MSG_CHECKING([for libwrap])
+			AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <tcpd.h>
+int deny_severity = 0, allow_severity = 0;
+				]], [[
+	hosts_access(0);
+				]])], [
+					AC_MSG_RESULT([yes])
+					AC_DEFINE([LIBWRAP], [1],
+						[Define if you want
+						TCP Wrappers support])
+					SSHDLIBS="$SSHDLIBS -lwrap -lnsl"
+					TCPW_MSG="yes"
+				], [
+					AC_MSG_ERROR([*** libwrap missing])
+				
+			])
+			LIBS="$saved_LIBS"
+		fi
+	]
+)
+
+# Check whether user wants to use ldns
+LDNS_MSG="no"
+AC_ARG_WITH(ldns,
+	[  --with-ldns[[=PATH]]      Use ldns for DNSSEC support (optionally in PATH)],
+	[
+	ldns=""
+	if test "x$withval" = "xyes" ; then
+		AC_PATH_TOOL([LDNSCONFIG], [ldns-config], [no])
+		if test "x$LDNSCONFIG" = "xno"; then
+			LIBS="-lldns $LIBS"
+			ldns=yes
+		else
+			LIBS="$LIBS `$LDNSCONFIG --libs`"
+			CPPFLAGS="$CPPFLAGS `$LDNSCONFIG --cflags`"
+			ldns=yes
+		fi
+	elif test "x$withval" != "xno" ; then
+			CPPFLAGS="$CPPFLAGS -I${withval}/include"
+			LDFLAGS="$LDFLAGS -L${withval}/lib"
+			LIBS="-lldns $LIBS"
+			ldns=yes
+	fi
+
+	# Verify that it works.
+	if test "x$ldns" = "xyes" ; then
+		AC_DEFINE(HAVE_LDNS, 1, [Define if you want ldns support])
+		LDNS_MSG="yes"
+		AC_MSG_CHECKING([for ldns support])
+		AC_LINK_IFELSE(
+			[AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <ldns/ldns.h>
+int main() { ldns_status status = ldns_verify_trusted(NULL, NULL, NULL, NULL); status=LDNS_STATUS_OK; exit(0); }
+			]])
+		],
+			[AC_MSG_RESULT(yes)],
+				[
+					AC_MSG_RESULT(no)
+					AC_MSG_ERROR([** Incomplete or missing ldns libraries.])
+				])
+	fi
+])
+
+# Check whether user wants libedit support
+LIBEDIT_MSG="no"
+AC_ARG_WITH([libedit],
+	[  --with-libedit[[=PATH]]   Enable libedit support for sftp],
+	[ if test "x$withval" != "xno" ; then
+		if test "x$withval" = "xyes" ; then
+			AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no])
+			if test "x$PKGCONFIG" != "xno"; then
+				AC_MSG_CHECKING([if $PKGCONFIG knows about libedit])
+				if "$PKGCONFIG" libedit; then
+					AC_MSG_RESULT([yes])
+					use_pkgconfig_for_libedit=yes
+				else
+					AC_MSG_RESULT([no])
+				fi
+			fi
+		else
+			CPPFLAGS="$CPPFLAGS -I${withval}/include"
+			if test -n "${rpath_opt}"; then
+				LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}"
+			else
+				LDFLAGS="-L${withval}/lib ${LDFLAGS}"
+			fi
+		fi
+		if test "x$use_pkgconfig_for_libedit" = "xyes"; then
+			LIBEDIT=`$PKGCONFIG --libs libedit`
+			CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libedit`"
+		else
+			LIBEDIT="-ledit -lcurses"
+		fi
+		OTHERLIBS=`echo $LIBEDIT | sed 's/-ledit//'`
+		AC_CHECK_LIB([edit], [el_init],
+			[ AC_DEFINE([USE_LIBEDIT], [1], [Use libedit for sftp])
+			  LIBEDIT_MSG="yes"
+			  AC_SUBST([LIBEDIT])
+			],
+			[ AC_MSG_ERROR([libedit not found]) ],
+			[ $OTHERLIBS ]
+		)
+		AC_MSG_CHECKING([if libedit version is compatible])
+		AC_COMPILE_IFELSE(
+		    [AC_LANG_PROGRAM([[
+#include <histedit.h>
+#include <stdlib.h>
+		    ]],
+		    [[
+	int i = H_SETSIZE;
+	el_init("", NULL, NULL, NULL);
+	exit(0);
+		    ]])],
+		    [ AC_MSG_RESULT([yes]) ],
+		    [ AC_MSG_RESULT([no])
+		      AC_MSG_ERROR([libedit version is not compatible]) ]
+		)
+	fi ]
+)
+
+AUDIT_MODULE=none
+AC_ARG_WITH([audit],
+	[  --with-audit=module     Enable audit support (modules=debug,bsm,linux)],
+	[
+	  AC_MSG_CHECKING([for supported audit module])
+	  case "$withval" in
+	  bsm)
+		AC_MSG_RESULT([bsm])
+		AUDIT_MODULE=bsm
+		dnl    Checks for headers, libs and functions
+		AC_CHECK_HEADERS([bsm/audit.h], [],
+		    [AC_MSG_ERROR([BSM enabled and bsm/audit.h not found])],
+		    [
+#ifdef HAVE_TIME_H
+# include <time.h>
+#endif
+		    ]
+)
+		AC_CHECK_LIB([bsm], [getaudit], [],
+		    [AC_MSG_ERROR([BSM enabled and required library not found])])
+		AC_CHECK_FUNCS([getaudit], [],
+		    [AC_MSG_ERROR([BSM enabled and required function not found])])
+		# These are optional
+		AC_CHECK_FUNCS([getaudit_addr aug_get_machine])
+		AC_DEFINE([USE_BSM_AUDIT], [1], [Use BSM audit module])
+		if test "$sol2ver" -ge 11; then
+			SSHDLIBS="$SSHDLIBS -lscf"
+			AC_DEFINE([BROKEN_BSM_API], [1],
+				[The system has incomplete BSM API])
+		fi
+		;;
+	  linux)
+		AC_MSG_RESULT([linux])
+		AUDIT_MODULE=linux
+		dnl    Checks for headers, libs and functions
+		AC_CHECK_HEADERS([libaudit.h])
+		SSHDLIBS="$SSHDLIBS -laudit"
+		AC_DEFINE([USE_LINUX_AUDIT], [1], [Use Linux audit module])
+		;;
+	  debug)
+		AUDIT_MODULE=debug
+		AC_MSG_RESULT([debug])
+		AC_DEFINE([SSH_AUDIT_EVENTS], [1], [Use audit debugging module])
+		;;
+	  no)
+		AC_MSG_RESULT([no])
+		;;
+	  *)
+		AC_MSG_ERROR([Unknown audit module $withval])
+		;;
+	esac ]
+)
+
+AC_ARG_WITH([pie],
+    [  --with-pie              Build Position Independent Executables if possible], [
+	if test "x$withval" = "xno"; then
+		use_pie=no
+	fi
+	if test "x$withval" = "xyes"; then
+		use_pie=yes
+	fi
+    ]
+)
+if test "x$use_pie" = "x"; then
+	use_pie=no
+fi
+if test "x$use_toolchain_hardening" != "x1" && test "x$use_pie" = "xauto"; then
+	# Turn off automatic PIE when toolchain hardening is off.
+	use_pie=no
+fi
+if test "x$use_pie" = "xauto"; then
+	# Automatic PIE requires gcc >= 4.x
+	AC_MSG_CHECKING([for gcc >= 4.x])
+	AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+#if !defined(__GNUC__) || __GNUC__ < 4
+#error gcc is too old
+#endif
+]])],
+	[ AC_MSG_RESULT([yes]) ],
+	[ AC_MSG_RESULT([no])
+	  use_pie=no ]
+)
+fi
+if test "x$use_pie" != "xno"; then
+	SAVED_CFLAGS="$CFLAGS"
+	SAVED_LDFLAGS="$LDFLAGS"
+	OSSH_CHECK_CFLAG_COMPILE([-fPIE])
+	OSSH_CHECK_LDFLAG_LINK([-pie])
+	# We use both -fPIE and -pie or neither.
+	AC_MSG_CHECKING([whether both -fPIE and -pie are supported])
+	if echo "x $CFLAGS"  | grep ' -fPIE' >/dev/null 2>&1 && \
+	   echo "x $LDFLAGS" | grep ' -pie'  >/dev/null 2>&1 ; then
+		AC_MSG_RESULT([yes])
+	else
+		AC_MSG_RESULT([no])
+		CFLAGS="$SAVED_CFLAGS"
+		LDFLAGS="$SAVED_LDFLAGS"
+	fi
+fi
+
+AC_MSG_CHECKING([whether -fPIC is accepted])
+SAVED_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -fPIC"
+AC_COMPILE_IFELSE(
+	[AC_LANG_PROGRAM( [[ #include <stdlib.h> ]], [[ exit(0); ]] )],
+   [AC_MSG_RESULT([yes])
+    PICFLAG="-fPIC"; ],
+   [AC_MSG_RESULT([no])
+    PICFLAG=""; ])
+CFLAGS="$SAVED_CFLAGS"
+AC_SUBST([PICFLAG])
+
+dnl    Checks for library functions. Please keep in alphabetical order
+AC_CHECK_FUNCS([ \
+	Blowfish_initstate \
+	Blowfish_expandstate \
+	Blowfish_expand0state \
+	Blowfish_stream2word \
+	SHA256Update \
+	SHA384Update \
+	SHA512Update \
+	asprintf \
+	b64_ntop \
+	__b64_ntop \
+	b64_pton \
+	__b64_pton \
+	bcopy \
+	bcrypt_pbkdf \
+	bindresvport_sa \
+	blf_enc \
+	bzero \
+	cap_rights_limit \
+	clock \
+	closefrom \
+	dirfd \
+	endgrent \
+	err \
+	errx \
+	explicit_bzero \
+	explicit_memset \
+	fchmod \
+	fchmodat \
+	fchown \
+	fchownat \
+	flock \
+	fnmatch \
+	freeaddrinfo \
+	freezero \
+	fstatfs \
+	fstatvfs \
+	futimes \
+	getaddrinfo \
+	getcwd \
+	getgrouplist \
+	getline \
+	getnameinfo \
+	getopt \
+	getpagesize \
+	getpeereid \
+	getpeerucred \
+	getpgid \
+	_getpty \
+	getrlimit \
+	getrandom \
+	getsid \
+	getttyent \
+	glob \
+	group_from_gid \
+	inet_aton \
+	inet_ntoa \
+	inet_ntop \
+	innetgr \
+	llabs \
+	localtime_r \
+	login_getcapbool \
+	login_getpwclass \
+	md5_crypt \
+	memmem \
+	memmove \
+	memset_s \
+	mkdtemp \
+	ngetaddrinfo \
+	nsleep \
+	ogetaddrinfo \
+	openlog_r \
+	pledge \
+	poll \
+	prctl \
+	pstat \
+	raise \
+	readpassphrase \
+	reallocarray \
+	realpath \
+	recvmsg \
+	recallocarray \
+	rresvport_af \
+	sendmsg \
+	setdtablesize \
+	setegid \
+	setenv \
+	seteuid \
+	setgroupent \
+	setgroups \
+	setlinebuf \
+	setlogin \
+	setpassent\
+	setpcred \
+	setproctitle \
+	setregid \
+	setreuid \
+	setrlimit \
+	setsid \
+	setvbuf \
+	sigaction \
+	sigvec \
+	snprintf \
+	socketpair \
+	statfs \
+	statvfs \
+	strcasestr \
+	strdup \
+	strerror \
+	strlcat \
+	strlcpy \
+	strmode \
+	strndup \
+	strnlen \
+	strnvis \
+	strptime \
+	strsignal \
+	strtonum \
+	strtoll \
+	strtoul \
+	strtoull \
+	swap32 \
+	sysconf \
+	tcgetpgrp \
+	timingsafe_bcmp \
+	truncate \
+	unsetenv \
+	updwtmpx \
+	utimensat \
+	user_from_uid \
+	usleep \
+	vasprintf \
+	vsnprintf \
+	waitpid \
+	warn \
+])
+
+AC_CHECK_DECLS([bzero, memmem])
+
+dnl Wide character support.
+AC_CHECK_FUNCS([mblen mbtowc nl_langinfo wcwidth])
+
+TEST_SSH_UTF8=${TEST_SSH_UTF8:=yes}
+AC_MSG_CHECKING([for utf8 locale support])
+AC_RUN_IFELSE(
+	[AC_LANG_PROGRAM([[
+#include <locale.h>
+#include <stdlib.h>
+	]], [[
+	char *loc = setlocale(LC_CTYPE, "en_US.UTF-8");
+	if (loc != NULL)
+		exit(0);
+	exit(1);
+	]])],
+	AC_MSG_RESULT(yes),
+	[AC_MSG_RESULT(no)
+	 TEST_SSH_UTF8=no],
+	AC_MSG_WARN([cross compiling: assuming yes])
+)
+
+AC_LINK_IFELSE(
+        [AC_LANG_PROGRAM(
+           [[ #include <ctype.h> ]],
+           [[ return (isblank('a')); ]])],
+	[AC_DEFINE([HAVE_ISBLANK], [1], [Define if you have isblank(3C).])
+])
+
+disable_pkcs11=
+AC_ARG_ENABLE([pkcs11],
+	[  --disable-pkcs11        disable PKCS#11 support code [no]],
+	[
+		if test "x$enableval" = "xno" ; then
+			disable_pkcs11=1
+		fi
+	]
+)
+
+disable_sk=
+AC_ARG_ENABLE([security-key],
+	[  --disable-security-key  disable U2F/FIDO support code [no]],
+	[
+		if test "x$enableval" = "xno" ; then
+			disable_sk=1
+		fi
+	]
+)
+enable_sk_internal=
+AC_ARG_WITH([security-key-builtin],
+	[  --with-security-key-builtin include builtin U2F/FIDO support],
+	[
+		if test "x$withval" != "xno" ; then
+			enable_sk_internal=yes
+		fi
+	]
+)
+test "x$disable_sk" != "x" && enable_sk_internal=""
+
+AC_SEARCH_LIBS([dlopen], [dl])
+AC_CHECK_FUNCS([dlopen])
+AC_CHECK_DECL([RTLD_NOW], [], [], [#include <dlfcn.h>])
+
+# IRIX has a const char return value for gai_strerror()
+AC_CHECK_FUNCS([gai_strerror], [
+	AC_DEFINE([HAVE_GAI_STRERROR])
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+const char *gai_strerror(int);
+			]], [[
+	char *str;
+	str = gai_strerror(0);
+			]])], [
+		AC_DEFINE([HAVE_CONST_GAI_STRERROR_PROTO], [1],
+		[Define if gai_strerror() returns const char *])], [])])
+
+AC_SEARCH_LIBS([nanosleep], [rt posix4], [AC_DEFINE([HAVE_NANOSLEEP], [1],
+	[Some systems put nanosleep outside of libc])])
+
+AC_SEARCH_LIBS([clock_gettime], [rt],
+	[AC_DEFINE([HAVE_CLOCK_GETTIME], [1], [Have clock_gettime])])
+
+dnl check if we need -D_REENTRANT for localtime_r declaration.
+AC_CHECK_DECL([localtime_r], [],
+	[ saved_CPPFLAGS="$CPPFLAGS"
+	  CPPFLAGS="$CPPFLAGS -D_REENTRANT"
+	  unset ac_cv_have_decl_localtime_r
+	  AC_CHECK_DECL([localtime_r], [],
+		[ CPPFLAGS="$saved_CPPFLAGS" ],
+		[ #include <time.h> ]
+	  )
+	],
+	[ #include <time.h> ]
+)
+
+dnl Make sure prototypes are defined for these before using them.
+AC_CHECK_DECL([strsep],
+	[AC_CHECK_FUNCS([strsep])],
+	[],
+	[
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif
+	])
+
+dnl tcsendbreak might be a macro
+AC_CHECK_DECL([tcsendbreak],
+	[AC_DEFINE([HAVE_TCSENDBREAK])],
+	[AC_CHECK_FUNCS([tcsendbreak])],
+	[#include <termios.h>]
+)
+
+AC_CHECK_DECLS([h_errno], , ,[#include <netdb.h>])
+
+AC_CHECK_DECLS([SHUT_RD, getpeereid], , ,
+	[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+	])
+
+AC_CHECK_DECLS([O_NONBLOCK], , ,
+	[
+#include <sys/types.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+	])
+
+AC_CHECK_DECLS([readv, writev], , , [
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <unistd.h>
+	])
+
+AC_CHECK_DECLS([MAXSYMLINKS], , , [
+#include <sys/param.h>
+	])
+
+AC_CHECK_DECLS([offsetof], , , [
+#include <stddef.h>
+	])
+
+# extra bits for select(2)
+AC_CHECK_DECLS([howmany, NFDBITS], [], [], [[
+#include <sys/param.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SYSMACROS_H
+#include <sys/sysmacros.h>
+#endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+	]])
+AC_CHECK_TYPES([fd_mask], [], [], [[
+#include <sys/param.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+	]])
+
+AC_CHECK_FUNCS([setresuid], [
+	dnl Some platorms have setresuid that isn't implemented, test for this
+	AC_MSG_CHECKING([if setresuid seems to work])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+#include <stdlib.h>
+#include <errno.h>
+		]], [[
+	errno=0;
+	setresuid(0,0,0);
+	if (errno==ENOSYS)
+		exit(1);
+	else
+		exit(0);
+		]])],
+		[AC_MSG_RESULT([yes])],
+		[AC_DEFINE([BROKEN_SETRESUID], [1],
+			[Define if your setresuid() is broken])
+		 AC_MSG_RESULT([not implemented])],
+		[AC_MSG_WARN([cross compiling: not checking setresuid])]
+	)
+])
+
+AC_CHECK_FUNCS([setresgid], [
+	dnl Some platorms have setresgid that isn't implemented, test for this
+	AC_MSG_CHECKING([if setresgid seems to work])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+#include <stdlib.h>
+#include <errno.h>
+		]], [[
+	errno=0;
+	setresgid(0,0,0);
+	if (errno==ENOSYS)
+		exit(1);
+	else
+		exit(0);
+		]])],
+		[AC_MSG_RESULT([yes])],
+		[AC_DEFINE([BROKEN_SETRESGID], [1],
+			[Define if your setresgid() is broken])
+		 AC_MSG_RESULT([not implemented])],
+		[AC_MSG_WARN([cross compiling: not checking setresuid])]
+	)
+])
+
+AC_MSG_CHECKING([for working fflush(NULL)])
+AC_RUN_IFELSE(
+	[AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <stdlib.h>
+	]],
+	[[fflush(NULL); exit(0);]])],
+	AC_MSG_RESULT([yes]),
+	[AC_MSG_RESULT([no])
+	 AC_DEFINE([FFLUSH_NULL_BUG], [1],
+	    [define if fflush(NULL) does not work])],
+	AC_MSG_WARN([cross compiling: assuming working])
+)
+
+dnl    Checks for time functions
+AC_CHECK_FUNCS([gettimeofday time])
+dnl    Checks for utmp functions
+AC_CHECK_FUNCS([endutent getutent getutid getutline pututline setutent])
+AC_CHECK_FUNCS([utmpname])
+dnl    Checks for utmpx functions
+AC_CHECK_FUNCS([endutxent getutxent getutxid getutxline getutxuser pututxline])
+AC_CHECK_FUNCS([setutxdb setutxent utmpxname])
+dnl    Checks for lastlog functions
+AC_CHECK_FUNCS([getlastlogxbyname])
+
+AC_CHECK_FUNC([daemon],
+	[AC_DEFINE([HAVE_DAEMON], [1], [Define if your libraries define daemon()])],
+	[AC_CHECK_LIB([bsd], [daemon],
+		[LIBS="$LIBS -lbsd"; AC_DEFINE([HAVE_DAEMON])])]
+)
+
+AC_CHECK_FUNC([getpagesize],
+	[AC_DEFINE([HAVE_GETPAGESIZE], [1],
+		[Define if your libraries define getpagesize()])],
+	[AC_CHECK_LIB([ucb], [getpagesize],
+		[LIBS="$LIBS -lucb"; AC_DEFINE([HAVE_GETPAGESIZE])])]
+)
+
+# Check for broken snprintf
+if test "x$ac_cv_func_snprintf" = "xyes" ; then
+	AC_MSG_CHECKING([whether snprintf correctly terminates long strings])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <stdlib.h>
+		]],
+		[[
+	char b[5];
+	snprintf(b,5,"123456789");
+	exit(b[4]!='\0');
+		]])],
+		[AC_MSG_RESULT([yes])],
+		[
+			AC_MSG_RESULT([no])
+			AC_DEFINE([BROKEN_SNPRINTF], [1],
+				[Define if your snprintf is busted])
+			AC_MSG_WARN([****** Your snprintf() function is broken, complain to your vendor])
+		],
+		[ AC_MSG_WARN([cross compiling: Assuming working snprintf()]) ]
+	)
+fi
+
+if test "x$ac_cv_func_snprintf" = "xyes" ; then
+	AC_MSG_CHECKING([whether snprintf understands %zu])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+		]],
+		[[
+	size_t a = 1, b = 2;
+	char z[128];
+	snprintf(z, sizeof z, "%zu%zu", a, b);
+	exit(strcmp(z, "12"));
+		]])],
+		[AC_MSG_RESULT([yes])],
+		[
+			AC_MSG_RESULT([no])
+			AC_DEFINE([BROKEN_SNPRINTF], [1],
+				[snprintf does not understand %zu])
+		],
+		[ AC_MSG_WARN([cross compiling: Assuming working snprintf()]) ]
+	)
+fi
+
+# We depend on vsnprintf returning the right thing on overflow: the
+# number of characters it tried to create (as per SUSv3)
+if test "x$ac_cv_func_vsnprintf" = "xyes" ; then
+	AC_MSG_CHECKING([whether vsnprintf returns correct values on overflow])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+int x_snprintf(char *str, size_t count, const char *fmt, ...)
+{
+	size_t ret;
+	va_list ap;
+
+	va_start(ap, fmt);
+	ret = vsnprintf(str, count, fmt, ap);
+	va_end(ap);
+	return ret;
+}
+		]], [[
+char x[1];
+if (x_snprintf(x, 1, "%s %d", "hello", 12345) != 11)
+	return 1;
+if (x_snprintf(NULL, 0, "%s %d", "hello", 12345) != 11)
+	return 1;
+return 0;
+		]])],
+		[AC_MSG_RESULT([yes])],
+		[
+			AC_MSG_RESULT([no])
+			AC_DEFINE([BROKEN_SNPRINTF], [1],
+				[Define if your snprintf is busted])
+			AC_MSG_WARN([****** Your vsnprintf() function is broken, complain to your vendor])
+		],
+		[ AC_MSG_WARN([cross compiling: Assuming working vsnprintf()]) ]
+	)
+fi
+
+# On systems where [v]snprintf is broken, but is declared in stdio,
+# check that the fmt argument is const char * or just char *.
+# This is only useful for when BROKEN_SNPRINTF
+AC_MSG_CHECKING([whether snprintf can declare const char *fmt])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <stdio.h>
+int snprintf(char *a, size_t b, const char *c, ...) { return 0; }
+		]], [[
+	snprintf(0, 0, 0);
+		]])],
+   [AC_MSG_RESULT([yes])
+    AC_DEFINE([SNPRINTF_CONST], [const],
+              [Define as const if snprintf() can declare const char *fmt])],
+   [AC_MSG_RESULT([no])
+    AC_DEFINE([SNPRINTF_CONST], [/* not const */])])
+
+# Check for missing getpeereid (or equiv) support
+NO_PEERCHECK=""
+if test "x$ac_cv_func_getpeereid" != "xyes" -a "x$ac_cv_func_getpeerucred" != "xyes"; then
+	AC_MSG_CHECKING([whether system supports SO_PEERCRED getsockopt])
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>]], [[int i = SO_PEERCRED;]])],
+		[ AC_MSG_RESULT([yes])
+		  AC_DEFINE([HAVE_SO_PEERCRED], [1], [Have PEERCRED socket option])
+		], [AC_MSG_RESULT([no])
+		NO_PEERCHECK=1
+        ])
+fi
+
+dnl make sure that openpty does not reacquire controlling terminal
+if test ! -z "$check_for_openpty_ctty_bug"; then
+	AC_MSG_CHECKING([if openpty correctly handles controlling tty])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/fcntl.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+		]], [[
+	pid_t pid;
+	int fd, ptyfd, ttyfd, status;
+
+	pid = fork();
+	if (pid < 0) {		/* failed */
+		exit(1);
+	} else if (pid > 0) {	/* parent */
+		waitpid(pid, &status, 0);
+		if (WIFEXITED(status))
+			exit(WEXITSTATUS(status));
+		else
+			exit(2);
+	} else {		/* child */
+		close(0); close(1); close(2);
+		setsid();
+		openpty(&ptyfd, &ttyfd, NULL, NULL, NULL);
+		fd = open("/dev/tty", O_RDWR | O_NOCTTY);
+		if (fd >= 0)
+			exit(3);	/* Acquired ctty: broken */
+		else
+			exit(0);	/* Did not acquire ctty: OK */
+	}
+		]])],
+		[
+			AC_MSG_RESULT([yes])
+		],
+		[
+			AC_MSG_RESULT([no])
+			AC_DEFINE([SSHD_ACQUIRES_CTTY])
+		],
+		[
+			AC_MSG_RESULT([cross-compiling, assuming yes])
+		]
+	)
+fi
+
+if test "x$ac_cv_func_getaddrinfo" = "xyes" && \
+    test "x$check_for_hpux_broken_getaddrinfo" = "x1"; then
+	AC_MSG_CHECKING([if getaddrinfo seems to work])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <netinet/in.h>
+
+#define TEST_PORT "2222"
+		]], [[
+	int err, sock;
+	struct addrinfo *gai_ai, *ai, hints;
+	char ntop[NI_MAXHOST], strport[NI_MAXSERV], *name = NULL;
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = PF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_flags = AI_PASSIVE;
+
+	err = getaddrinfo(name, TEST_PORT, &hints, &gai_ai);
+	if (err != 0) {
+		fprintf(stderr, "getaddrinfo failed (%s)", gai_strerror(err));
+		exit(1);
+	}
+
+	for (ai = gai_ai; ai != NULL; ai = ai->ai_next) {
+		if (ai->ai_family != AF_INET6)
+			continue;
+
+		err = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop,
+		    sizeof(ntop), strport, sizeof(strport),
+		    NI_NUMERICHOST|NI_NUMERICSERV);
+
+		if (err != 0) {
+			if (err == EAI_SYSTEM)
+				perror("getnameinfo EAI_SYSTEM");
+			else
+				fprintf(stderr, "getnameinfo failed: %s\n",
+				    gai_strerror(err));
+			exit(2);
+		}
+
+		sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+		if (sock < 0)
+			perror("socket");
+		if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) {
+			if (errno == EBADF)
+				exit(3);
+		}
+	}
+	exit(0);
+		]])],
+		[
+			AC_MSG_RESULT([yes])
+		],
+		[
+			AC_MSG_RESULT([no])
+			AC_DEFINE([BROKEN_GETADDRINFO])
+		],
+		[
+			AC_MSG_RESULT([cross-compiling, assuming yes])
+		]
+	)
+fi
+
+if test "x$ac_cv_func_getaddrinfo" = "xyes" && \
+    test "x$check_for_aix_broken_getaddrinfo" = "x1"; then
+	AC_MSG_CHECKING([if getaddrinfo seems to work])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <netinet/in.h>
+
+#define TEST_PORT "2222"
+		]], [[
+	int err, sock;
+	struct addrinfo *gai_ai, *ai, hints;
+	char ntop[NI_MAXHOST], strport[NI_MAXSERV], *name = NULL;
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_family = PF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_flags = AI_PASSIVE;
+
+	err = getaddrinfo(name, TEST_PORT, &hints, &gai_ai);
+	if (err != 0) {
+		fprintf(stderr, "getaddrinfo failed (%s)", gai_strerror(err));
+		exit(1);
+	}
+
+	for (ai = gai_ai; ai != NULL; ai = ai->ai_next) {
+		if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
+			continue;
+
+		err = getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop,
+		    sizeof(ntop), strport, sizeof(strport),
+		    NI_NUMERICHOST|NI_NUMERICSERV);
+
+		if (ai->ai_family == AF_INET && err != 0) {
+			perror("getnameinfo");
+			exit(2);
+		}
+	}
+	exit(0);
+		]])],
+		[
+			AC_MSG_RESULT([yes])
+			AC_DEFINE([AIX_GETNAMEINFO_HACK], [1],
+				[Define if you have a getaddrinfo that fails
+				for the all-zeros IPv6 address])
+		],
+		[
+			AC_MSG_RESULT([no])
+			AC_DEFINE([BROKEN_GETADDRINFO])
+		],
+		[
+			AC_MSG_RESULT([cross-compiling, assuming no])
+		]
+	)
+fi
+
+if test "x$ac_cv_func_getaddrinfo" = "xyes"; then
+	AC_CHECK_DECLS(AI_NUMERICSERV, , ,
+	    [#include <sys/types.h>
+	     #include <sys/socket.h>
+	     #include <netdb.h>])
+fi
+
+if test "x$check_for_conflicting_getspnam" = "x1"; then
+	AC_MSG_CHECKING([for conflicting getspnam in shadow.h])
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <shadow.h>
+#include <stdlib.h>
+		]],
+		[[ exit(0); ]])],
+		[
+			AC_MSG_RESULT([no])
+		],
+		[
+			AC_MSG_RESULT([yes])
+			AC_DEFINE([GETSPNAM_CONFLICTING_DEFS], [1],
+			    [Conflicting defs for getspnam])
+		]
+	)
+fi
+
+dnl NetBSD added an strnvis and unfortunately made it incompatible with the
+dnl existing one in OpenBSD and Linux's libbsd (the former having existed
+dnl for over ten years). Despite this incompatibility being reported during
+dnl development (see http://gnats.netbsd.org/44977) they still shipped it.
+dnl Even more unfortunately FreeBSD and later MacOS picked up this incompatible
+dnl implementation.  Try to detect this mess, and assume the only safe option
+dnl if we're cross compiling.
+dnl
+dnl OpenBSD, 2001: strnvis(char *dst, const char *src, size_t dlen, int flag);
+dnl NetBSD: 2012,  strnvis(char *dst, size_t dlen, const char *src, int flag);
+if test "x$ac_cv_func_strnvis" = "xyes"; then
+	AC_MSG_CHECKING([for working strnvis])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <vis.h>
+static void sighandler(int sig) { _exit(1); }
+		]], [[
+	char dst[16];
+
+	signal(SIGSEGV, sighandler);
+	if (strnvis(dst, "src", 4, 0) && strcmp(dst, "src") == 0)
+		exit(0);
+	exit(1)
+		]])],
+		[AC_MSG_RESULT([yes])],
+		[AC_MSG_RESULT([no])
+		 AC_DEFINE([BROKEN_STRNVIS], [1], [strnvis detected broken])],
+		[AC_MSG_WARN([cross compiling: assuming broken])
+		 AC_DEFINE([BROKEN_STRNVIS], [1], [strnvis assumed broken])]
+	)
+fi
+
+AC_MSG_CHECKING([if SA_RESTARTed signals interrupt select()])
+AC_RUN_IFELSE(
+	[AC_LANG_PROGRAM([[
+#ifdef HAVE_SYS_SELECT
+# include <sys/select.h>
+#endif
+#include <sys/types.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+static void sighandler(int sig) { }
+		]], [[
+	int r;
+	pid_t pid;
+	struct sigaction sa;
+
+	sa.sa_handler = sighandler;
+	sa.sa_flags = SA_RESTART;
+	(void)sigaction(SIGTERM, &sa, NULL);
+	if ((pid = fork()) == 0) { /* child */
+		pid = getppid();
+		sleep(1);
+		kill(pid, SIGTERM);
+		sleep(1);
+		if (getppid() == pid) /* if parent did not exit, shoot it */
+			kill(pid, SIGKILL);
+		exit(0);
+	} else { /* parent */
+		r = select(0, NULL, NULL, NULL, NULL);
+	}
+	exit(r == -1 ? 0 : 1);
+	]])],
+	[AC_MSG_RESULT([yes])],
+	[AC_MSG_RESULT([no])
+	 AC_DEFINE([NO_SA_RESTART], [1],
+	    [SA_RESTARTed signals do no interrupt select])],
+	[AC_MSG_WARN([cross compiling: assuming yes])]
+)
+
+AC_CHECK_FUNCS([getpgrp],[
+	AC_MSG_CHECKING([if getpgrp accepts zero args])
+	AC_COMPILE_IFELSE(
+		[AC_LANG_PROGRAM([[$ac_includes_default]], [[ getpgrp(); ]])],
+		[ AC_MSG_RESULT([yes])
+		  AC_DEFINE([GETPGRP_VOID], [1], [getpgrp takes zero args])],
+		[ AC_MSG_RESULT([no])
+		  AC_DEFINE([GETPGRP_VOID], [0], [getpgrp takes one arg])]
+	)
+])
+
+# Search for OpenSSL
+saved_CPPFLAGS="$CPPFLAGS"
+saved_LDFLAGS="$LDFLAGS"
+AC_ARG_WITH([ssl-dir],
+	[  --with-ssl-dir=PATH     Specify path to OpenSSL installation ],
+	[
+		if test "x$openssl" = "xno" ; then
+			AC_MSG_ERROR([cannot use --with-ssl-dir when OpenSSL disabled])
+		fi
+		if test "x$withval" != "xno" ; then
+			case "$withval" in
+				# Relative paths
+				./*|../*)	withval="`pwd`/$withval"
+			esac
+			if test -d "$withval/lib"; then
+				if test -n "${rpath_opt}"; then
+					LDFLAGS="-L${withval}/lib ${rpath_opt}${withval}/lib ${LDFLAGS}"
+				else
+					LDFLAGS="-L${withval}/lib ${LDFLAGS}"
+				fi
+			elif test -d "$withval/lib64"; then
+				if test -n "${rpath_opt}"; then
+					LDFLAGS="-L${withval}/lib64 ${rpath_opt}${withval}/lib64 ${LDFLAGS}"
+				else
+					LDFLAGS="-L${withval}/lib64 ${LDFLAGS}"
+				fi
+			else
+				if test -n "${rpath_opt}"; then
+					LDFLAGS="-L${withval} ${rpath_opt}${withval} ${LDFLAGS}"
+				else
+					LDFLAGS="-L${withval} ${LDFLAGS}"
+				fi
+			fi
+			if test -d "$withval/include"; then
+				CPPFLAGS="-I${withval}/include ${CPPFLAGS}"
+			else
+				CPPFLAGS="-I${withval} ${CPPFLAGS}"
+			fi
+		fi
+	]
+)
+
+AC_ARG_WITH([openssl-header-check],
+	[  --without-openssl-header-check Disable OpenSSL version consistency check],
+	[
+		if test "x$withval" = "xno" ; then
+			openssl_check_nonfatal=1
+		fi
+	]
+)
+
+openssl_engine=no
+AC_ARG_WITH([ssl-engine],
+	[  --with-ssl-engine       Enable OpenSSL (hardware) ENGINE support ],
+	[
+		if test "x$withval" != "xno" ; then
+			if test "x$openssl" = "xno" ; then
+				AC_MSG_ERROR([cannot use --with-ssl-engine when OpenSSL disabled])
+			fi
+			openssl_engine=yes
+		fi
+	]
+)
+
+if test "x$openssl" = "xyes" ; then
+	LIBS="-lcrypto $LIBS"
+	AC_TRY_LINK_FUNC([RAND_add], ,
+	    [AC_MSG_ERROR([*** working libcrypto not found, check config.log])])
+	AC_CHECK_HEADER([openssl/opensslv.h], ,
+	    [AC_MSG_ERROR([*** OpenSSL headers missing - please install first or check config.log ***])])
+
+	# Determine OpenSSL header version
+	AC_MSG_CHECKING([OpenSSL header version])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <stdlib.h>
+	#include <stdio.h>
+	#include <string.h>
+	#include <openssl/opensslv.h>
+	#define DATA "conftest.sslincver"
+		]], [[
+		FILE *fd;
+		int rc;
+
+		fd = fopen(DATA,"w");
+		if(fd == NULL)
+			exit(1);
+
+		if ((rc = fprintf(fd, "%08lx (%s)\n",
+		    (unsigned long)OPENSSL_VERSION_NUMBER,
+		     OPENSSL_VERSION_TEXT)) < 0)
+			exit(1);
+
+		exit(0);
+		]])],
+		[
+			ssl_header_ver=`cat conftest.sslincver`
+			AC_MSG_RESULT([$ssl_header_ver])
+		],
+		[
+			AC_MSG_RESULT([not found])
+			AC_MSG_ERROR([OpenSSL version header not found.])
+		],
+		[
+			AC_MSG_WARN([cross compiling: not checking])
+		]
+	)
+
+	# Determining OpenSSL library version is version dependent.
+	AC_CHECK_FUNCS([OpenSSL_version OpenSSL_version_num])
+
+	# Determine OpenSSL library version
+	AC_MSG_CHECKING([OpenSSL library version])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <stdio.h>
+	#include <stdlib.h>
+	#include <string.h>
+	#include <openssl/opensslv.h>
+	#include <openssl/crypto.h>
+	#define DATA "conftest.ssllibver"
+		]], [[
+		FILE *fd;
+		int rc;
+
+		fd = fopen(DATA,"w");
+		if(fd == NULL)
+			exit(1);
+#ifndef OPENSSL_VERSION
+# define OPENSSL_VERSION SSLEAY_VERSION
+#endif
+#ifndef HAVE_OPENSSL_VERSION
+# define OpenSSL_version	SSLeay_version
+#endif
+#ifndef HAVE_OPENSSL_VERSION_NUM
+# define OpenSSL_version_num	SSLeay
+#endif
+		if ((rc = fprintf(fd, "%08lx (%s)\n",
+		    (unsigned long)OpenSSL_version_num(),
+		    OpenSSL_version(OPENSSL_VERSION))) < 0)
+			exit(1);
+
+		exit(0);
+		]])],
+		[
+			ssl_library_ver=`cat conftest.ssllibver`
+			# Check version is supported.
+			case "$ssl_library_ver" in
+			10000*|0*)
+				AC_MSG_ERROR([OpenSSL >= 1.0.1 required (have "$ssl_library_ver")])
+		                ;;
+			100*)   ;; # 1.0.x
+			101000[[0123456]]*)
+				# https://github.com/openssl/openssl/pull/4613
+				AC_MSG_ERROR([OpenSSL 1.1.x versions prior to 1.1.0g have a bug that breaks their use with OpenSSH (have "$ssl_library_ver")])
+				;;
+			101*)   ;; # 1.1.x
+			200*)   ;; # LibreSSL
+			300*)   ;; # OpenSSL development branch.
+		        *)
+				AC_MSG_ERROR([Unknown/unsupported OpenSSL version ("$ssl_library_ver")])
+		                ;;
+			esac
+			AC_MSG_RESULT([$ssl_library_ver])
+		],
+		[
+			AC_MSG_RESULT([not found])
+			AC_MSG_ERROR([OpenSSL library not found.])
+		],
+		[
+			AC_MSG_WARN([cross compiling: not checking])
+		]
+	)
+
+	# Sanity check OpenSSL headers
+	AC_MSG_CHECKING([whether OpenSSL's headers match the library])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <stdlib.h>
+	#include <string.h>
+	#include <openssl/opensslv.h>
+	#include <openssl/crypto.h>
+		]], [[
+#ifndef HAVE_OPENSSL_VERSION_NUM
+# define OpenSSL_version_num	SSLeay
+#endif
+		exit(OpenSSL_version_num() == OPENSSL_VERSION_NUMBER ? 0 : 1);
+		]])],
+		[
+			AC_MSG_RESULT([yes])
+		],
+		[
+			AC_MSG_RESULT([no])
+			if test "x$openssl_check_nonfatal" = "x"; then
+				AC_MSG_ERROR([Your OpenSSL headers do not match your
+	library. Check config.log for details.
+	If you are sure your installation is consistent, you can disable the check
+	by running "./configure --without-openssl-header-check".
+	Also see contrib/findssl.sh for help identifying header/library mismatches.
+	])
+			else
+				AC_MSG_WARN([Your OpenSSL headers do not match your
+	library. Check config.log for details.
+	Also see contrib/findssl.sh for help identifying header/library mismatches.])
+			fi
+		],
+		[
+			AC_MSG_WARN([cross compiling: not checking])
+		]
+	)
+
+	AC_MSG_CHECKING([if programs using OpenSSL functions will link])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[ #include <openssl/err.h> ]],
+		[[ ERR_load_crypto_strings(); ]])],
+		[
+			AC_MSG_RESULT([yes])
+		],
+		[
+			AC_MSG_RESULT([no])
+			saved_LIBS="$LIBS"
+			LIBS="$LIBS -ldl"
+			AC_MSG_CHECKING([if programs using OpenSSL need -ldl])
+			AC_LINK_IFELSE(
+				[AC_LANG_PROGRAM([[ #include <openssl/err.h> ]],
+				[[ ERR_load_crypto_strings(); ]])],
+				[
+					AC_MSG_RESULT([yes])
+				],
+				[
+					AC_MSG_RESULT([no])
+					LIBS="$saved_LIBS"
+				]
+			)
+		]
+	)
+
+	AC_CHECK_FUNCS([ \
+		BN_is_prime_ex \
+		DSA_generate_parameters_ex \
+		EVP_CIPHER_CTX_ctrl \
+		EVP_DigestFinal_ex \
+		EVP_DigestInit_ex \
+		EVP_MD_CTX_cleanup \
+		EVP_MD_CTX_copy_ex \
+		EVP_MD_CTX_init \
+		HMAC_CTX_init \
+		RSA_generate_key_ex \
+		RSA_get_default_method \
+	])
+
+	# OpenSSL_add_all_algorithms may be a macro.
+	AC_CHECK_FUNC(OpenSSL_add_all_algorithms,
+	    AC_DEFINE(HAVE_OPENSSL_ADD_ALL_ALGORITHMS, 1, [as a function]),
+	    AC_CHECK_DECL(OpenSSL_add_all_algorithms,
+		AC_DEFINE(HAVE_OPENSSL_ADD_ALL_ALGORITHMS, 1, [as a macro]), ,
+		[[#include <openssl/evp.h>]]
+	    )
+	)
+
+	# LibreSSL/OpenSSL 1.1x API
+	AC_CHECK_FUNCS([ \
+		OPENSSL_init_crypto \
+		DH_get0_key \
+		DH_get0_pqg \
+		DH_set0_key \
+		DH_set_length \
+		DH_set0_pqg \
+		DSA_get0_key \
+		DSA_get0_pqg \
+		DSA_set0_key \
+		DSA_set0_pqg \
+		DSA_SIG_get0 \
+		DSA_SIG_set0 \
+		ECDSA_SIG_get0 \
+		ECDSA_SIG_set0 \
+		EVP_CIPHER_CTX_iv \
+		EVP_CIPHER_CTX_iv_noconst \
+		EVP_CIPHER_CTX_get_iv \
+		EVP_CIPHER_CTX_get_updated_iv \
+		EVP_CIPHER_CTX_set_iv \
+		RSA_get0_crt_params \
+		RSA_get0_factors \
+		RSA_get0_key \
+		RSA_set0_crt_params \
+		RSA_set0_factors \
+		RSA_set0_key \
+		RSA_meth_free \
+		RSA_meth_dup \
+		RSA_meth_set1_name \
+		RSA_meth_get_finish \
+		RSA_meth_set_priv_enc \
+		RSA_meth_set_priv_dec \
+		RSA_meth_set_finish \
+		EVP_PKEY_get0_RSA \
+		EVP_MD_CTX_new \
+		EVP_MD_CTX_free \
+		EVP_chacha20 \
+	])
+
+	if test "x$openssl_engine" = "xyes" ; then
+		AC_MSG_CHECKING([for OpenSSL ENGINE support])
+		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+	#include <openssl/engine.h>
+			]], [[
+				ENGINE_load_builtin_engines();
+				ENGINE_register_all_complete();
+			]])],
+			[ AC_MSG_RESULT([yes])
+			  AC_DEFINE([USE_OPENSSL_ENGINE], [1],
+			     [Enable OpenSSL engine support])
+			], [ AC_MSG_ERROR([OpenSSL ENGINE support not found])
+		])
+	fi
+
+	# Check for OpenSSL without EVP_aes_{192,256}_cbc
+	AC_MSG_CHECKING([whether OpenSSL has crippled AES support])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <stdlib.h>
+	#include <string.h>
+	#include <openssl/evp.h>
+		]], [[
+		exit(EVP_aes_192_cbc() == NULL || EVP_aes_256_cbc() == NULL);
+		]])],
+		[
+			AC_MSG_RESULT([no])
+		],
+		[
+			AC_MSG_RESULT([yes])
+			AC_DEFINE([OPENSSL_LOBOTOMISED_AES], [1],
+			    [libcrypto is missing AES 192 and 256 bit functions])
+		]
+	)
+
+	# Check for OpenSSL with EVP_aes_*ctr
+	AC_MSG_CHECKING([whether OpenSSL has AES CTR via EVP])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <stdlib.h>
+	#include <string.h>
+	#include <openssl/evp.h>
+		]], [[
+		exit(EVP_aes_128_ctr() == NULL ||
+		    EVP_aes_192_cbc() == NULL ||
+		    EVP_aes_256_cbc() == NULL);
+		]])],
+		[
+			AC_MSG_RESULT([yes])
+			AC_DEFINE([OPENSSL_HAVE_EVPCTR], [1],
+			    [libcrypto has EVP AES CTR])
+		],
+		[
+			AC_MSG_RESULT([no])
+		]
+	)
+
+	# Check for OpenSSL with EVP_aes_*gcm
+	AC_MSG_CHECKING([whether OpenSSL has AES GCM via EVP])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <stdlib.h>
+	#include <string.h>
+	#include <openssl/evp.h>
+		]], [[
+		exit(EVP_aes_128_gcm() == NULL ||
+		    EVP_aes_256_gcm() == NULL ||
+		    EVP_CTRL_GCM_SET_IV_FIXED == 0 ||
+		    EVP_CTRL_GCM_IV_GEN == 0 ||
+		    EVP_CTRL_GCM_SET_TAG == 0 ||
+		    EVP_CTRL_GCM_GET_TAG == 0 ||
+		    EVP_CIPHER_CTX_ctrl(NULL, 0, 0, NULL) == 0);
+		]])],
+		[
+			AC_MSG_RESULT([yes])
+			AC_DEFINE([OPENSSL_HAVE_EVPGCM], [1],
+			    [libcrypto has EVP AES GCM])
+		],
+		[
+			AC_MSG_RESULT([no])
+			unsupported_algorithms="$unsupported_cipers \
+			   aes128-gcm@openssh.com \
+			   aes256-gcm@openssh.com"
+		]
+	)
+
+	AC_MSG_CHECKING([if EVP_DigestUpdate returns an int])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <stdlib.h>
+	#include <string.h>
+	#include <openssl/evp.h>
+		]], [[
+		if(EVP_DigestUpdate(NULL, NULL,0))
+			exit(0);
+		]])],
+		[
+			AC_MSG_RESULT([yes])
+		],
+		[
+			AC_MSG_RESULT([no])
+			AC_DEFINE([OPENSSL_EVP_DIGESTUPDATE_VOID], [1],
+			    [Define if EVP_DigestUpdate returns void])
+		]
+	)
+
+	# Some systems want crypt() from libcrypt, *not* the version in OpenSSL,
+	# because the system crypt() is more featureful.
+	if test "x$check_for_libcrypt_before" = "x1"; then
+		AC_CHECK_LIB([crypt], [crypt])
+	fi
+
+	# Some Linux systems (Slackware) need crypt() from libcrypt, *not* the
+	# version in OpenSSL.
+	if test "x$check_for_libcrypt_later" = "x1"; then
+		AC_CHECK_LIB([crypt], [crypt], [LIBS="$LIBS -lcrypt"])
+	fi
+	AC_CHECK_FUNCS([crypt DES_crypt])
+
+	# Check for SHA256, SHA384 and SHA512 support in OpenSSL
+	AC_CHECK_FUNCS([EVP_sha256 EVP_sha384 EVP_sha512])
+
+	# Check complete ECC support in OpenSSL
+	AC_MSG_CHECKING([whether OpenSSL has NID_X9_62_prime256v1])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <openssl/ec.h>
+	#include <openssl/ecdh.h>
+	#include <openssl/ecdsa.h>
+	#include <openssl/evp.h>
+	#include <openssl/objects.h>
+	#include <openssl/opensslv.h>
+		]], [[
+		EC_KEY *e = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+		const EVP_MD *m = EVP_sha256(); /* We need this too */
+		]])],
+		[ AC_MSG_RESULT([yes])
+		  enable_nistp256=1 ],
+		[ AC_MSG_RESULT([no]) ]
+	)
+
+	AC_MSG_CHECKING([whether OpenSSL has NID_secp384r1])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <openssl/ec.h>
+	#include <openssl/ecdh.h>
+	#include <openssl/ecdsa.h>
+	#include <openssl/evp.h>
+	#include <openssl/objects.h>
+	#include <openssl/opensslv.h>
+		]], [[
+		EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp384r1);
+		const EVP_MD *m = EVP_sha384(); /* We need this too */
+		]])],
+		[ AC_MSG_RESULT([yes])
+		  enable_nistp384=1 ],
+		[ AC_MSG_RESULT([no]) ]
+	)
+
+	AC_MSG_CHECKING([whether OpenSSL has NID_secp521r1])
+	AC_LINK_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <openssl/ec.h>
+	#include <openssl/ecdh.h>
+	#include <openssl/ecdsa.h>
+	#include <openssl/evp.h>
+	#include <openssl/objects.h>
+	#include <openssl/opensslv.h>
+		]], [[
+		EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1);
+		const EVP_MD *m = EVP_sha512(); /* We need this too */
+		]])],
+		[ AC_MSG_RESULT([yes])
+		  AC_MSG_CHECKING([if OpenSSL's NID_secp521r1 is functional])
+		  AC_RUN_IFELSE(
+			[AC_LANG_PROGRAM([[
+	#include <stdlib.h>
+	#include <openssl/ec.h>
+	#include <openssl/ecdh.h>
+	#include <openssl/ecdsa.h>
+	#include <openssl/evp.h>
+	#include <openssl/objects.h>
+	#include <openssl/opensslv.h>
+			]],[[
+			EC_KEY *e = EC_KEY_new_by_curve_name(NID_secp521r1);
+			const EVP_MD *m = EVP_sha512(); /* We need this too */
+			exit(e == NULL || m == NULL);
+			]])],
+			[ AC_MSG_RESULT([yes])
+			  enable_nistp521=1 ],
+			[ AC_MSG_RESULT([no]) ],
+			[ AC_MSG_WARN([cross-compiling: assuming yes])
+			  enable_nistp521=1 ]
+		  )],
+		AC_MSG_RESULT([no])
+	)
+
+	COMMENT_OUT_ECC="#no ecc#"
+	TEST_SSH_ECC=no
+
+	if test x$enable_nistp256 = x1 || test x$enable_nistp384 = x1 || \
+	    test x$enable_nistp521 = x1; then
+		AC_DEFINE(OPENSSL_HAS_ECC, [1], [OpenSSL has ECC])
+		AC_CHECK_FUNCS([EC_KEY_METHOD_new])
+		openssl_ecc=yes
+	else
+		openssl_ecc=no
+	fi
+	if test x$enable_nistp256 = x1; then
+		AC_DEFINE([OPENSSL_HAS_NISTP256], [1],
+		    [libcrypto has NID_X9_62_prime256v1])
+		TEST_SSH_ECC=yes
+		COMMENT_OUT_ECC=""
+	else
+		unsupported_algorithms="$unsupported_algorithms \
+			ecdsa-sha2-nistp256 \
+			ecdh-sha2-nistp256 \
+			ecdsa-sha2-nistp256-cert-v01@openssh.com"
+	fi
+	if test x$enable_nistp384 = x1; then
+		AC_DEFINE([OPENSSL_HAS_NISTP384], [1], [libcrypto has NID_secp384r1])
+		TEST_SSH_ECC=yes
+		COMMENT_OUT_ECC=""
+	else
+		unsupported_algorithms="$unsupported_algorithms \
+			ecdsa-sha2-nistp384 \
+			ecdh-sha2-nistp384 \
+			ecdsa-sha2-nistp384-cert-v01@openssh.com"
+	fi
+	if test x$enable_nistp521 = x1; then
+		AC_DEFINE([OPENSSL_HAS_NISTP521], [1], [libcrypto has NID_secp521r1])
+		TEST_SSH_ECC=yes
+		COMMENT_OUT_ECC=""
+	else
+		unsupported_algorithms="$unsupported_algorithms \
+			ecdh-sha2-nistp521 \
+			ecdsa-sha2-nistp521 \
+			ecdsa-sha2-nistp521-cert-v01@openssh.com"
+	fi
+
+	AC_SUBST([TEST_SSH_ECC])
+	AC_SUBST([COMMENT_OUT_ECC])
+else
+	AC_CHECK_LIB([crypt], [crypt], [LIBS="$LIBS -lcrypt"])
+	AC_CHECK_FUNCS([crypt])
+fi
+
+# PKCS11/U2F depend on OpenSSL and dlopen().
+enable_pkcs11=yes
+enable_sk=yes
+if test "x$openssl" != "xyes" ; then
+	enable_pkcs11="disabled; missing libcrypto"
+	enable_sk="disabled; missing libcrypto"
+fi
+if test "x$openssl_ecc" != "xyes" ; then
+	enable_sk="disabled; OpenSSL has no ECC support"
+fi
+if test "x$ac_cv_func_dlopen" != "xyes" ; then
+	enable_pkcs11="disabled; missing dlopen(3)"
+	enable_sk="disabled; missing dlopen(3)"
+fi
+if test "x$ac_cv_have_decl_RTLD_NOW" != "xyes" ; then
+	enable_pkcs11="disabled; missing RTLD_NOW"
+	enable_sk="disabled; missing RTLD_NOW"
+fi
+if test ! -z "$disable_pkcs11" ; then
+	enable_pkcs11="disabled by user"
+fi
+if test ! -z "$disable_sk" ; then
+	enable_sk="disabled by user"
+fi
+
+AC_MSG_CHECKING([whether to enable PKCS11])
+if test "x$enable_pkcs11" = "xyes" ; then
+	AC_DEFINE([ENABLE_PKCS11], [], [Enable for PKCS#11 support])
+fi
+AC_MSG_RESULT([$enable_pkcs11])
+
+AC_MSG_CHECKING([whether to enable U2F])
+if test "x$enable_sk" = "xyes" ; then
+	AC_DEFINE([ENABLE_SK], [], [Enable for U2F/FIDO support])
+	AC_SUBST(SK_DUMMY_LIBRARY, [regress/misc/sk-dummy/sk-dummy.so])
+else
+	# Do not try to build sk-dummy library.
+	AC_SUBST(SK_DUMMY_LIBRARY, [""])
+fi
+AC_MSG_RESULT([$enable_sk])
+
+# Now check for built-in security key support.
+if test "x$enable_sk" = "xyes" -a "x$enable_sk_internal" = "xyes" ; then
+	AC_PATH_TOOL([PKGCONFIG], [pkg-config], [no])
+	use_pkgconfig_for_libfido2=
+	if test "x$PKGCONFIG" != "xno"; then
+		AC_MSG_CHECKING([if $PKGCONFIG knows about libfido2])
+		if "$PKGCONFIG" libfido2; then
+			AC_MSG_RESULT([yes])
+			use_pkgconfig_for_libfido2=yes
+		else
+			AC_MSG_RESULT([no])
+		fi
+	fi
+	if test "x$use_pkgconfig_for_libfido2" = "xyes"; then
+		LIBFIDO2=`$PKGCONFIG --libs libfido2`
+		CPPFLAGS="$CPPFLAGS `$PKGCONFIG --cflags libfido2`"
+	else
+		LIBFIDO2="-lfido2 -lcbor"
+	fi
+	OTHERLIBS=`echo $LIBFIDO2 | sed 's/-lfido2//'`
+	AC_CHECK_LIB([fido2], [fido_init],
+		[
+			AC_SUBST([LIBFIDO2])
+			AC_DEFINE([ENABLE_SK_INTERNAL], [],
+			    [Enable for built-in U2F/FIDO support])
+			enable_sk="built-in"
+		], [ AC_MSG_ERROR([no usable libfido2 found]) ],
+		[ $OTHERLIBS ]
+	)
+	saved_LIBS="$LIBS"
+	LIBS="$LIBS $LIBFIDO2"
+	AC_CHECK_FUNCS([ \
+		fido_cred_prot \
+		fido_cred_set_prot \
+		fido_dev_get_touch_begin \
+		fido_dev_get_touch_status \
+		fido_dev_supports_cred_prot \
+	])
+	LIBS="$saved_LIBS"
+	AC_CHECK_HEADER([fido.h], [],
+		AC_MSG_ERROR([missing fido.h from libfido2]))
+	AC_CHECK_HEADER([fido/credman.h], [],
+		AC_MSG_ERROR([missing fido/credman.h from libfido2]),
+		[#include <fido.h>]
+	)
+fi
+
+AC_CHECK_FUNCS([ \
+	arc4random \
+	arc4random_buf \
+	arc4random_stir \
+	arc4random_uniform \
+])
+
+saved_LIBS="$LIBS"
+AC_CHECK_LIB([iaf], [ia_openinfo], [
+	LIBS="$LIBS -liaf"
+	AC_CHECK_FUNCS([set_id], [SSHDLIBS="$SSHDLIBS -liaf"
+				AC_DEFINE([HAVE_LIBIAF], [1],
+			[Define if system has libiaf that supports set_id])
+				])
+])
+LIBS="$saved_LIBS"
+
+### Configure cryptographic random number support
+
+# Check whether OpenSSL seeds itself
+if test "x$openssl" = "xyes" ; then
+	AC_MSG_CHECKING([whether OpenSSL's PRNG is internally seeded])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+	#include <stdlib.h>
+	#include <string.h>
+	#include <openssl/rand.h>
+		]], [[
+		exit(RAND_status() == 1 ? 0 : 1);
+		]])],
+		[
+			OPENSSL_SEEDS_ITSELF=yes
+			AC_MSG_RESULT([yes])
+		],
+		[
+			AC_MSG_RESULT([no])
+		],
+		[
+			AC_MSG_WARN([cross compiling: assuming yes])
+			# This is safe, since we will fatal() at runtime if
+			# OpenSSL is not seeded correctly.
+			OPENSSL_SEEDS_ITSELF=yes
+		]
+	)
+fi
+
+# PRNGD TCP socket
+AC_ARG_WITH([prngd-port],
+	[  --with-prngd-port=PORT  read entropy from PRNGD/EGD TCP localhost:PORT],
+	[
+		case "$withval" in
+		no)
+			withval=""
+			;;
+		[[0-9]]*)
+			;;
+		*)
+			AC_MSG_ERROR([You must specify a numeric port number for --with-prngd-port])
+			;;
+		esac
+		if test ! -z "$withval" ; then
+			PRNGD_PORT="$withval"
+			AC_DEFINE_UNQUOTED([PRNGD_PORT], [$PRNGD_PORT],
+				[Port number of PRNGD/EGD random number socket])
+		fi
+	]
+)
+
+# PRNGD Unix domain socket
+AC_ARG_WITH([prngd-socket],
+	[  --with-prngd-socket=FILE read entropy from PRNGD/EGD socket FILE (default=/var/run/egd-pool)],
+	[
+		case "$withval" in
+		yes)
+			withval="/var/run/egd-pool"
+			;;
+		no)
+			withval=""
+			;;
+		/*)
+			;;
+		*)
+			AC_MSG_ERROR([You must specify an absolute path to the entropy socket])
+			;;
+		esac
+
+		if test ! -z "$withval" ; then
+			if test ! -z "$PRNGD_PORT" ; then
+				AC_MSG_ERROR([You may not specify both a PRNGD/EGD port and socket])
+			fi
+			if test ! -r "$withval" ; then
+				AC_MSG_WARN([Entropy socket is not readable])
+			fi
+			PRNGD_SOCKET="$withval"
+			AC_DEFINE_UNQUOTED([PRNGD_SOCKET], ["$PRNGD_SOCKET"],
+				[Location of PRNGD/EGD random number socket])
+		fi
+	],
+	[
+		# Check for existing socket only if we don't have a random device already
+		if test "x$OPENSSL_SEEDS_ITSELF" != "xyes" ; then
+			AC_MSG_CHECKING([for PRNGD/EGD socket])
+			# Insert other locations here
+			for sock in /var/run/egd-pool /dev/egd-pool /etc/entropy; do
+				if test -r $sock && $TEST_MINUS_S_SH -c "test -S $sock -o -p $sock" ; then
+					PRNGD_SOCKET="$sock"
+					AC_DEFINE_UNQUOTED([PRNGD_SOCKET], ["$PRNGD_SOCKET"])
+					break;
+				fi
+			done
+			if test ! -z "$PRNGD_SOCKET" ; then
+				AC_MSG_RESULT([$PRNGD_SOCKET])
+			else
+				AC_MSG_RESULT([not found])
+			fi
+		fi
+	]
+)
+
+# Which randomness source do we use?
+if test ! -z "$PRNGD_PORT" ; then
+	RAND_MSG="PRNGd port $PRNGD_PORT"
+elif test ! -z "$PRNGD_SOCKET" ; then
+	RAND_MSG="PRNGd socket $PRNGD_SOCKET"
+elif test ! -z "$OPENSSL_SEEDS_ITSELF" ; then
+	AC_DEFINE([OPENSSL_PRNG_ONLY], [1],
+		[Define if you want the OpenSSL internally seeded PRNG only])
+	RAND_MSG="OpenSSL internal ONLY"
+elif test "x$openssl" = "xno" ; then
+	AC_MSG_WARN([OpenSSH will use /dev/urandom as a source of random numbers. It will fail if this device is not supported or accessible])
+else
+	AC_MSG_ERROR([OpenSSH has no source of random numbers. Please configure OpenSSL with an entropy source or re-run configure using one of the --with-prngd-port or --with-prngd-socket options])
+fi
+
+# Check for PAM libs
+PAM_MSG="no"
+AC_ARG_WITH([pam],
+	[  --with-pam              Enable PAM support ],
+	[
+		if test "x$withval" != "xno" ; then
+			if test "x$ac_cv_header_security_pam_appl_h" != "xyes" && \
+			   test "x$ac_cv_header_pam_pam_appl_h" != "xyes" ; then
+				AC_MSG_ERROR([PAM headers not found])
+			fi
+
+			saved_LIBS="$LIBS"
+			AC_CHECK_LIB([dl], [dlopen], , )
+			AC_CHECK_LIB([pam], [pam_set_item], , [AC_MSG_ERROR([*** libpam missing])])
+			AC_CHECK_FUNCS([pam_getenvlist])
+			AC_CHECK_FUNCS([pam_putenv])
+			LIBS="$saved_LIBS"
+
+			PAM_MSG="yes"
+
+			SSHDLIBS="$SSHDLIBS -lpam"
+			AC_DEFINE([USE_PAM], [1],
+				[Define if you want to enable PAM support])
+
+			if test $ac_cv_lib_dl_dlopen = yes; then
+				case "$LIBS" in
+				*-ldl*)
+					# libdl already in LIBS
+					;;
+				*)
+					SSHDLIBS="$SSHDLIBS -ldl"
+					;;
+				esac
+			fi
+		fi
+	]
+)
+
+AC_ARG_WITH([pam-service],
+	[  --with-pam-service=name Specify PAM service name ],
+	[
+		if test "x$withval" != "xno" && \
+		   test "x$withval" != "xyes" ; then
+			AC_DEFINE_UNQUOTED([SSHD_PAM_SERVICE],
+				["$withval"], [sshd PAM service name])
+		fi
+	]
+)
+
+# Check for older PAM
+if test "x$PAM_MSG" = "xyes" ; then
+	# Check PAM strerror arguments (old PAM)
+	AC_MSG_CHECKING([whether pam_strerror takes only one argument])
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <stdlib.h>
+#if defined(HAVE_SECURITY_PAM_APPL_H)
+#include <security/pam_appl.h>
+#elif defined (HAVE_PAM_PAM_APPL_H)
+#include <pam/pam_appl.h>
+#endif
+		]], [[
+(void)pam_strerror((pam_handle_t *)NULL, -1);
+		]])], [AC_MSG_RESULT([no])], [
+			AC_DEFINE([HAVE_OLD_PAM], [1],
+				[Define if you have an old version of PAM
+				which takes only one argument to pam_strerror])
+			AC_MSG_RESULT([yes])
+			PAM_MSG="yes (old library)"
+
+	])
+fi
+
+case "$host" in
+*-*-cygwin*)
+	SSH_PRIVSEP_USER=CYGWIN_SSH_PRIVSEP_USER
+	;;
+*)
+	SSH_PRIVSEP_USER=sshd
+	;;
+esac
+AC_ARG_WITH([privsep-user],
+	[  --with-privsep-user=user Specify non-privileged user for privilege separation],
+	[
+		if test -n "$withval"  &&  test "x$withval" != "xno"  &&  \
+		    test "x${withval}" != "xyes"; then
+			SSH_PRIVSEP_USER=$withval
+		fi
+	]
+)
+if test "x$SSH_PRIVSEP_USER" = "xCYGWIN_SSH_PRIVSEP_USER" ; then
+	AC_DEFINE_UNQUOTED([SSH_PRIVSEP_USER], [CYGWIN_SSH_PRIVSEP_USER],
+		[Cygwin function to fetch non-privileged user for privilege separation])
+else
+	AC_DEFINE_UNQUOTED([SSH_PRIVSEP_USER], ["$SSH_PRIVSEP_USER"],
+		[non-privileged user for privilege separation])
+fi
+AC_SUBST([SSH_PRIVSEP_USER])
+
+if test "x$have_linux_no_new_privs" = "x1" ; then
+AC_CHECK_DECL([SECCOMP_MODE_FILTER], [have_seccomp_filter=1], , [
+	#include <sys/types.h>
+	#include <linux/seccomp.h>
+])
+fi
+if test "x$have_seccomp_filter" = "x1" ; then
+AC_MSG_CHECKING([kernel for seccomp_filter support])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+		#include <errno.h>
+		#include <elf.h>
+		#include <linux/audit.h>
+		#include <linux/seccomp.h>
+		#include <stdlib.h>
+		#include <sys/prctl.h>
+	]],
+	[[ int i = $seccomp_audit_arch;
+	   errno = 0;
+	   prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
+	   exit(errno == EFAULT ? 0 : 1); ]])],
+	[ AC_MSG_RESULT([yes]) ], [
+		AC_MSG_RESULT([no])
+		# Disable seccomp filter as a target
+		have_seccomp_filter=0
+	]
+)
+fi
+
+# Decide which sandbox style to use
+sandbox_arg=""
+AC_ARG_WITH([sandbox],
+	[  --with-sandbox=style    Specify privilege separation sandbox (no, capsicum, darwin, rlimit, seccomp_filter, systrace, pledge)],
+	[
+		if test "x$withval" = "xyes" ; then
+			sandbox_arg=""
+		else
+			sandbox_arg="$withval"
+		fi
+	]
+)
+
+# Some platforms (seems to be the ones that have a kernel poll(2)-type
+# function with which they implement select(2)) use an extra file descriptor
+# when calling select(2), which means we can't use the rlimit sandbox.
+AC_MSG_CHECKING([if select works with descriptor rlimit])
+AC_RUN_IFELSE(
+	[AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <sys/resource.h>
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#endif
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+	]],[[
+	struct rlimit rl_zero;
+	int fd, r;
+	fd_set fds;
+	struct timeval tv;
+
+	fd = open("/dev/null", O_RDONLY);
+	FD_ZERO(&fds);
+	FD_SET(fd, &fds);
+	rl_zero.rlim_cur = rl_zero.rlim_max = 0;
+	setrlimit(RLIMIT_FSIZE, &rl_zero);
+	setrlimit(RLIMIT_NOFILE, &rl_zero);
+	tv.tv_sec = 1;
+	tv.tv_usec = 0;
+	r = select(fd+1, &fds, NULL, NULL, &tv);
+	exit (r == -1 ? 1 : 0);
+	]])],
+	[AC_MSG_RESULT([yes])
+	 select_works_with_rlimit=yes],
+	[AC_MSG_RESULT([no])
+	 select_works_with_rlimit=no],
+	[AC_MSG_WARN([cross compiling: assuming yes])
+	 select_works_with_rlimit=yes]
+)
+
+AC_MSG_CHECKING([if setrlimit(RLIMIT_NOFILE,{0,0}) works])
+AC_RUN_IFELSE(
+	[AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <sys/resource.h>
+#include <errno.h>
+#include <stdlib.h>
+	]],[[
+	struct rlimit rl_zero;
+	int r;
+
+	rl_zero.rlim_cur = rl_zero.rlim_max = 0;
+	r = setrlimit(RLIMIT_NOFILE, &rl_zero);
+	exit (r == -1 ? 1 : 0);
+	]])],
+	[AC_MSG_RESULT([yes])
+	 rlimit_nofile_zero_works=yes],
+	[AC_MSG_RESULT([no])
+	 rlimit_nofile_zero_works=no],
+	[AC_MSG_WARN([cross compiling: assuming yes])
+	 rlimit_nofile_zero_works=yes]
+)
+
+AC_MSG_CHECKING([if setrlimit RLIMIT_FSIZE works])
+AC_RUN_IFELSE(
+	[AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <stdlib.h>
+	]],[[
+		struct rlimit rl_zero;
+
+		rl_zero.rlim_cur = rl_zero.rlim_max = 0;
+		exit(setrlimit(RLIMIT_FSIZE, &rl_zero) != 0);
+	]])],
+	[AC_MSG_RESULT([yes])],
+	[AC_MSG_RESULT([no])
+	 AC_DEFINE(SANDBOX_SKIP_RLIMIT_FSIZE, 1,
+	    [setrlimit RLIMIT_FSIZE works])],
+	[AC_MSG_WARN([cross compiling: assuming yes])]
+)
+
+if test "x$sandbox_arg" = "xpledge" || \
+   ( test -z "$sandbox_arg" && test "x$ac_cv_func_pledge" = "xyes" ) ; then
+	test "x$ac_cv_func_pledge" != "xyes" && \
+		AC_MSG_ERROR([pledge sandbox requires pledge(2) support])
+	SANDBOX_STYLE="pledge"
+	AC_DEFINE([SANDBOX_PLEDGE], [1], [Sandbox using pledge(2)])
+elif test "x$sandbox_arg" = "xsystrace" || \
+   ( test -z "$sandbox_arg" && test "x$have_systr_policy_kill" = "x1" ) ; then
+	test "x$have_systr_policy_kill" != "x1" && \
+		AC_MSG_ERROR([systrace sandbox requires systrace headers and SYSTR_POLICY_KILL support])
+	SANDBOX_STYLE="systrace"
+	AC_DEFINE([SANDBOX_SYSTRACE], [1], [Sandbox using systrace(4)])
+elif test "x$sandbox_arg" = "xdarwin" || \
+     ( test -z "$sandbox_arg" && test "x$ac_cv_func_sandbox_init" = "xyes" && \
+       test "x$ac_cv_header_sandbox_h" = "xyes") ; then
+	test "x$ac_cv_func_sandbox_init" != "xyes" -o \
+	     "x$ac_cv_header_sandbox_h" != "xyes" && \
+		AC_MSG_ERROR([Darwin seatbelt sandbox requires sandbox.h and sandbox_init function])
+	SANDBOX_STYLE="darwin"
+	AC_DEFINE([SANDBOX_DARWIN], [1], [Sandbox using Darwin sandbox_init(3)])
+elif test "x$sandbox_arg" = "xseccomp_filter" || \
+     ( test -z "$sandbox_arg" && \
+       test "x$have_seccomp_filter" = "x1" && \
+       test "x$ac_cv_header_elf_h" = "xyes" && \
+       test "x$ac_cv_header_linux_audit_h" = "xyes" && \
+       test "x$ac_cv_header_linux_filter_h" = "xyes" && \
+       test "x$seccomp_audit_arch" != "x" && \
+       test "x$have_linux_no_new_privs" = "x1" && \
+       test "x$ac_cv_func_prctl" = "xyes" ) ; then
+	test "x$seccomp_audit_arch" = "x" && \
+		AC_MSG_ERROR([seccomp_filter sandbox not supported on $host])
+	test "x$have_linux_no_new_privs" != "x1" && \
+		AC_MSG_ERROR([seccomp_filter sandbox requires PR_SET_NO_NEW_PRIVS])
+	test "x$have_seccomp_filter" != "x1" && \
+		AC_MSG_ERROR([seccomp_filter sandbox requires seccomp headers])
+	test "x$ac_cv_func_prctl" != "xyes" && \
+		AC_MSG_ERROR([seccomp_filter sandbox requires prctl function])
+	SANDBOX_STYLE="seccomp_filter"
+	AC_DEFINE([SANDBOX_SECCOMP_FILTER], [1], [Sandbox using seccomp filter])
+elif test "x$sandbox_arg" = "xcapsicum" || \
+     ( test -z "$sandbox_arg" && \
+       test "x$ac_cv_header_sys_capsicum_h" = "xyes" && \
+       test "x$ac_cv_func_cap_rights_limit" = "xyes") ; then
+       test "x$ac_cv_header_sys_capsicum_h" != "xyes" && \
+		AC_MSG_ERROR([capsicum sandbox requires sys/capsicum.h header])
+       test "x$ac_cv_func_cap_rights_limit" != "xyes" && \
+		AC_MSG_ERROR([capsicum sandbox requires cap_rights_limit function])
+       SANDBOX_STYLE="capsicum"
+       AC_DEFINE([SANDBOX_CAPSICUM], [1], [Sandbox using capsicum])
+elif test "x$sandbox_arg" = "xrlimit" || \
+     ( test -z "$sandbox_arg" && test "x$ac_cv_func_setrlimit" = "xyes" && \
+       test "x$select_works_with_rlimit" = "xyes" && \
+       test "x$rlimit_nofile_zero_works" = "xyes" ) ; then
+	test "x$ac_cv_func_setrlimit" != "xyes" && \
+		AC_MSG_ERROR([rlimit sandbox requires setrlimit function])
+	test "x$select_works_with_rlimit" != "xyes" && \
+		AC_MSG_ERROR([rlimit sandbox requires select to work with rlimit])
+	SANDBOX_STYLE="rlimit"
+	AC_DEFINE([SANDBOX_RLIMIT], [1], [Sandbox using setrlimit(2)])
+elif test "x$sandbox_arg" = "xsolaris" || \
+   ( test -z "$sandbox_arg" && test "x$SOLARIS_PRIVS" = "xyes" ) ; then
+	SANDBOX_STYLE="solaris"
+	AC_DEFINE([SANDBOX_SOLARIS], [1], [Sandbox using Solaris/Illumos privileges])
+elif test -z "$sandbox_arg" || test "x$sandbox_arg" = "xno" || \
+     test "x$sandbox_arg" = "xnone" || test "x$sandbox_arg" = "xnull" ; then
+	SANDBOX_STYLE="none"
+	AC_DEFINE([SANDBOX_NULL], [1], [no privsep sandboxing])
+else
+	AC_MSG_ERROR([unsupported --with-sandbox])
+fi
+
+# Cheap hack to ensure NEWS-OS libraries are arranged right.
+if test ! -z "$SONY" ; then
+  LIBS="$LIBS -liberty";
+fi
+
+# Check for  long long datatypes
+AC_CHECK_TYPES([long long, unsigned long long, long double])
+
+# Check datatype sizes
+AC_CHECK_SIZEOF([short int])
+AC_CHECK_SIZEOF([int])
+AC_CHECK_SIZEOF([long int])
+AC_CHECK_SIZEOF([long long int])
+
+# Sanity check long long for some platforms (AIX)
+if test "x$ac_cv_sizeof_long_long_int" = "x4" ; then
+	ac_cv_sizeof_long_long_int=0
+fi
+
+# compute LLONG_MIN and LLONG_MAX if we don't know them.
+if test -z "$have_llong_max" && test -z "$have_long_long_max"; then
+	AC_MSG_CHECKING([for max value of long long])
+	AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <stdlib.h>
+/* Why is this so damn hard? */
+#ifdef __GNUC__
+# undef __GNUC__
+#endif
+#define __USE_ISOC99
+#include <limits.h>
+#define DATA "conftest.llminmax"
+#define my_abs(a) ((a) < 0 ? ((a) * -1) : (a))
+
+/*
+ * printf in libc on some platforms (eg old Tru64) does not understand %lld so
+ * we do this the hard way.
+ */
+static int
+fprint_ll(FILE *f, long long n)
+{
+	unsigned int i;
+	int l[sizeof(long long) * 8];
+
+	if (n < 0)
+		if (fprintf(f, "-") < 0)
+			return -1;
+	for (i = 0; n != 0; i++) {
+		l[i] = my_abs(n % 10);
+		n /= 10;
+	}
+	do {
+		if (fprintf(f, "%d", l[--i]) < 0)
+			return -1;
+	} while (i != 0);
+	if (fprintf(f, " ") < 0)
+		return -1;
+	return 0;
+}
+		]], [[
+	FILE *f;
+	long long i, llmin, llmax = 0;
+
+	if((f = fopen(DATA,"w")) == NULL)
+		exit(1);
+
+#if defined(LLONG_MIN) && defined(LLONG_MAX)
+	fprintf(stderr, "Using system header for LLONG_MIN and LLONG_MAX\n");
+	llmin = LLONG_MIN;
+	llmax = LLONG_MAX;
+#else
+	fprintf(stderr, "Calculating  LLONG_MIN and LLONG_MAX\n");
+	/* This will work on one's complement and two's complement */
+	for (i = 1; i > llmax; i <<= 1, i++)
+		llmax = i;
+	llmin = llmax + 1LL;	/* wrap */
+#endif
+
+	/* Sanity check */
+	if (llmin + 1 < llmin || llmin - 1 < llmin || llmax + 1 > llmax
+	    || llmax - 1 > llmax || llmin == llmax || llmin == 0
+	    || llmax == 0 || llmax < LONG_MAX || llmin > LONG_MIN) {
+		fprintf(f, "unknown unknown\n");
+		exit(2);
+	}
+
+	if (fprint_ll(f, llmin) < 0)
+		exit(3);
+	if (fprint_ll(f, llmax) < 0)
+		exit(4);
+	if (fclose(f) < 0)
+		exit(5);
+	exit(0);
+		]])],
+		[
+			llong_min=`$AWK '{print $1}' conftest.llminmax`
+			llong_max=`$AWK '{print $2}' conftest.llminmax`
+
+			AC_MSG_RESULT([$llong_max])
+			AC_DEFINE_UNQUOTED([LLONG_MAX], [${llong_max}LL],
+			    [max value of long long calculated by configure])
+			AC_MSG_CHECKING([for min value of long long])
+			AC_MSG_RESULT([$llong_min])
+			AC_DEFINE_UNQUOTED([LLONG_MIN], [${llong_min}LL],
+			    [min value of long long calculated by configure])
+		],
+		[
+			AC_MSG_RESULT([not found])
+		],
+		[
+			AC_MSG_WARN([cross compiling: not checking])
+		]
+	)
+fi
+
+AC_CHECK_DECLS([UINT32_MAX], , , [[
+#ifdef HAVE_SYS_LIMITS_H
+# include <sys/limits.h>
+#endif
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+]])
+
+# More checks for data types
+AC_CACHE_CHECK([for u_int type], ac_cv_have_u_int, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
+	[[ u_int a; a = 1;]])],
+	[ ac_cv_have_u_int="yes" ], [ ac_cv_have_u_int="no"
+	])
+])
+if test "x$ac_cv_have_u_int" = "xyes" ; then
+	AC_DEFINE([HAVE_U_INT], [1], [define if you have u_int data type])
+	have_u_int=1
+fi
+
+AC_CACHE_CHECK([for intXX_t types], ac_cv_have_intxx_t, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
+	[[ int8_t a; int16_t b; int32_t c; a = b = c = 1;]])],
+	[ ac_cv_have_intxx_t="yes" ], [ ac_cv_have_intxx_t="no"
+	])
+])
+if test "x$ac_cv_have_intxx_t" = "xyes" ; then
+	AC_DEFINE([HAVE_INTXX_T], [1], [define if you have intxx_t data type])
+	have_intxx_t=1
+fi
+
+if (test -z "$have_intxx_t" && \
+	   test "x$ac_cv_header_stdint_h" = "xyes")
+then
+    AC_MSG_CHECKING([for intXX_t types in stdint.h])
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdint.h> ]],
+	[[ int8_t a; int16_t b; int32_t c; a = b = c = 1;]])],
+		[
+			AC_DEFINE([HAVE_INTXX_T])
+			AC_MSG_RESULT([yes])
+		], [ AC_MSG_RESULT([no])
+	])
+fi
+
+AC_CACHE_CHECK([for int64_t type], ac_cv_have_int64_t, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#include <sys/socket.h>
+#ifdef HAVE_SYS_BITYPES_H
+# include <sys/bitypes.h>
+#endif
+		]], [[
+int64_t a; a = 1;
+		]])],
+	[ ac_cv_have_int64_t="yes" ], [ ac_cv_have_int64_t="no"
+	])
+])
+if test "x$ac_cv_have_int64_t" = "xyes" ; then
+	AC_DEFINE([HAVE_INT64_T], [1], [define if you have int64_t data type])
+fi
+
+AC_CACHE_CHECK([for u_intXX_t types], ac_cv_have_u_intxx_t, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
+	[[ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;]])],
+	[ ac_cv_have_u_intxx_t="yes" ], [ ac_cv_have_u_intxx_t="no"
+	])
+])
+if test "x$ac_cv_have_u_intxx_t" = "xyes" ; then
+	AC_DEFINE([HAVE_U_INTXX_T], [1], [define if you have u_intxx_t data type])
+	have_u_intxx_t=1
+fi
+
+if test -z "$have_u_intxx_t" ; then
+    AC_MSG_CHECKING([for u_intXX_t types in sys/socket.h])
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/socket.h> ]],
+	[[ u_int8_t a; u_int16_t b; u_int32_t c; a = b = c = 1;]])],
+		[
+			AC_DEFINE([HAVE_U_INTXX_T])
+			AC_MSG_RESULT([yes])
+		], [ AC_MSG_RESULT([no])
+	])
+fi
+
+AC_CACHE_CHECK([for u_int64_t types], ac_cv_have_u_int64_t, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
+	[[ u_int64_t a; a = 1;]])],
+	[ ac_cv_have_u_int64_t="yes" ], [ ac_cv_have_u_int64_t="no"
+	])
+])
+if test "x$ac_cv_have_u_int64_t" = "xyes" ; then
+	AC_DEFINE([HAVE_U_INT64_T], [1], [define if you have u_int64_t data type])
+	have_u_int64_t=1
+fi
+
+if (test -z "$have_u_int64_t" && \
+	   test "x$ac_cv_header_sys_bitypes_h" = "xyes")
+then
+    AC_MSG_CHECKING([for u_int64_t type in sys/bitypes.h])
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/bitypes.h> ]],
+	[[ u_int64_t a; a = 1]])],
+		[
+			AC_DEFINE([HAVE_U_INT64_T])
+			AC_MSG_RESULT([yes])
+		], [ AC_MSG_RESULT([no])
+	])
+fi
+
+if test -z "$have_u_intxx_t" ; then
+	AC_CACHE_CHECK([for uintXX_t types], ac_cv_have_uintxx_t, [
+		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+			]], [[
+	uint8_t a;
+	uint16_t b;
+	uint32_t c;
+	a = b = c = 1;
+			]])],
+		[ ac_cv_have_uintxx_t="yes" ], [ ac_cv_have_uintxx_t="no"
+		])
+	])
+	if test "x$ac_cv_have_uintxx_t" = "xyes" ; then
+		AC_DEFINE([HAVE_UINTXX_T], [1],
+			[define if you have uintxx_t data type])
+	fi
+fi
+
+if (test -z "$have_uintxx_t" && \
+	   test "x$ac_cv_header_stdint_h" = "xyes")
+then
+    AC_MSG_CHECKING([for uintXX_t types in stdint.h])
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <stdint.h> ]],
+	[[ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1;]])],
+		[
+			AC_DEFINE([HAVE_UINTXX_T])
+			AC_MSG_RESULT([yes])
+		], [ AC_MSG_RESULT([no])
+	])
+fi
+
+if (test -z "$have_uintxx_t" && \
+	   test "x$ac_cv_header_inttypes_h" = "xyes")
+then
+    AC_MSG_CHECKING([for uintXX_t types in inttypes.h])
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <inttypes.h> ]],
+	[[ uint8_t a; uint16_t b; uint32_t c; a = b = c = 1;]])],
+		[
+			AC_DEFINE([HAVE_UINTXX_T])
+			AC_MSG_RESULT([yes])
+		], [ AC_MSG_RESULT([no])
+	])
+fi
+
+if (test -z "$have_u_intxx_t" || test -z "$have_intxx_t" && \
+	   test "x$ac_cv_header_sys_bitypes_h" = "xyes")
+then
+	AC_MSG_CHECKING([for intXX_t and u_intXX_t types in sys/bitypes.h])
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/bitypes.h>
+		]], [[
+			int8_t a; int16_t b; int32_t c;
+			u_int8_t e; u_int16_t f; u_int32_t g;
+			a = b = c = e = f = g = 1;
+		]])],
+		[
+			AC_DEFINE([HAVE_U_INTXX_T])
+			AC_DEFINE([HAVE_INTXX_T])
+			AC_MSG_RESULT([yes])
+		], [AC_MSG_RESULT([no])
+	])
+fi
+
+
+AC_CACHE_CHECK([for u_char], ac_cv_have_u_char, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
+	[[ u_char foo; foo = 125; ]])],
+	[ ac_cv_have_u_char="yes" ], [ ac_cv_have_u_char="no"
+	])
+])
+if test "x$ac_cv_have_u_char" = "xyes" ; then
+	AC_DEFINE([HAVE_U_CHAR], [1], [define if you have u_char data type])
+fi
+
+AC_CHECK_TYPES([intmax_t, uintmax_t], , , [
+#include <sys/types.h>
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+])
+
+TYPE_SOCKLEN_T
+
+AC_CHECK_TYPES([sig_atomic_t], , , [#include <signal.h>])
+AC_CHECK_TYPES([fsblkcnt_t, fsfilcnt_t], , , [
+#include <sys/types.h>
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#ifdef HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+])
+
+AC_CHECK_MEMBERS([struct statfs.f_files, struct statfs.f_flags], [], [], [[
+#include <sys/param.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#ifdef HAVE_SYS_STATFS_H
+#include <sys/statfs.h>
+#endif
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+#ifdef HAVE_SYS_VFS_H
+#include <sys/vfs.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+]])
+
+
+AC_CHECK_TYPES([in_addr_t, in_port_t], , ,
+[#include <sys/types.h>
+#include <netinet/in.h>])
+
+AC_CACHE_CHECK([for size_t], ac_cv_have_size_t, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
+	[[ size_t foo; foo = 1235; ]])],
+	[ ac_cv_have_size_t="yes" ], [ ac_cv_have_size_t="no"
+	])
+])
+if test "x$ac_cv_have_size_t" = "xyes" ; then
+	AC_DEFINE([HAVE_SIZE_T], [1], [define if you have size_t data type])
+fi
+
+AC_CACHE_CHECK([for ssize_t], ac_cv_have_ssize_t, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
+	[[ ssize_t foo; foo = 1235; ]])],
+	[ ac_cv_have_ssize_t="yes" ], [ ac_cv_have_ssize_t="no"
+	])
+])
+if test "x$ac_cv_have_ssize_t" = "xyes" ; then
+	AC_DEFINE([HAVE_SSIZE_T], [1], [define if you have ssize_t data type])
+fi
+
+AC_CACHE_CHECK([for clock_t], ac_cv_have_clock_t, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <time.h> ]],
+	[[ clock_t foo; foo = 1235; ]])],
+	[ ac_cv_have_clock_t="yes" ], [ ac_cv_have_clock_t="no"
+	])
+])
+if test "x$ac_cv_have_clock_t" = "xyes" ; then
+	AC_DEFINE([HAVE_CLOCK_T], [1], [define if you have clock_t data type])
+fi
+
+AC_CACHE_CHECK([for sa_family_t], ac_cv_have_sa_family_t, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+		]], [[ sa_family_t foo; foo = 1235; ]])],
+	[ ac_cv_have_sa_family_t="yes" ],
+	[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+		]], [[ sa_family_t foo; foo = 1235; ]])],
+		[ ac_cv_have_sa_family_t="yes" ],
+		[ ac_cv_have_sa_family_t="no" ]
+	)
+	])
+])
+if test "x$ac_cv_have_sa_family_t" = "xyes" ; then
+	AC_DEFINE([HAVE_SA_FAMILY_T], [1],
+		[define if you have sa_family_t data type])
+fi
+
+AC_CACHE_CHECK([for pid_t], ac_cv_have_pid_t, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
+	[[ pid_t foo; foo = 1235; ]])],
+	[ ac_cv_have_pid_t="yes" ], [ ac_cv_have_pid_t="no"
+	])
+])
+if test "x$ac_cv_have_pid_t" = "xyes" ; then
+	AC_DEFINE([HAVE_PID_T], [1], [define if you have pid_t data type])
+fi
+
+AC_CACHE_CHECK([for mode_t], ac_cv_have_mode_t, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/types.h> ]],
+	[[ mode_t foo; foo = 1235; ]])],
+	[ ac_cv_have_mode_t="yes" ], [ ac_cv_have_mode_t="no"
+	])
+])
+if test "x$ac_cv_have_mode_t" = "xyes" ; then
+	AC_DEFINE([HAVE_MODE_T], [1], [define if you have mode_t data type])
+fi
+
+
+AC_CACHE_CHECK([for struct sockaddr_storage], ac_cv_have_struct_sockaddr_storage, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+		]], [[ struct sockaddr_storage s; ]])],
+	[ ac_cv_have_struct_sockaddr_storage="yes" ],
+	[ ac_cv_have_struct_sockaddr_storage="no"
+	])
+])
+if test "x$ac_cv_have_struct_sockaddr_storage" = "xyes" ; then
+	AC_DEFINE([HAVE_STRUCT_SOCKADDR_STORAGE], [1],
+		[define if you have struct sockaddr_storage data type])
+fi
+
+AC_CACHE_CHECK([for struct sockaddr_in6], ac_cv_have_struct_sockaddr_in6, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <netinet/in.h>
+		]], [[ struct sockaddr_in6 s; s.sin6_family = 0; ]])],
+	[ ac_cv_have_struct_sockaddr_in6="yes" ],
+	[ ac_cv_have_struct_sockaddr_in6="no"
+	])
+])
+if test "x$ac_cv_have_struct_sockaddr_in6" = "xyes" ; then
+	AC_DEFINE([HAVE_STRUCT_SOCKADDR_IN6], [1],
+		[define if you have struct sockaddr_in6 data type])
+fi
+
+AC_CACHE_CHECK([for struct in6_addr], ac_cv_have_struct_in6_addr, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <netinet/in.h>
+		]], [[ struct in6_addr s; s.s6_addr[0] = 0; ]])],
+	[ ac_cv_have_struct_in6_addr="yes" ],
+	[ ac_cv_have_struct_in6_addr="no"
+	])
+])
+if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then
+	AC_DEFINE([HAVE_STRUCT_IN6_ADDR], [1],
+		[define if you have struct in6_addr data type])
+
+dnl Now check for sin6_scope_id
+	AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_scope_id], , ,
+		[
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#include <netinet/in.h>
+		])
+fi
+
+AC_CACHE_CHECK([for struct addrinfo], ac_cv_have_struct_addrinfo, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+		]], [[ struct addrinfo s; s.ai_flags = AI_PASSIVE; ]])],
+	[ ac_cv_have_struct_addrinfo="yes" ],
+	[ ac_cv_have_struct_addrinfo="no"
+	])
+])
+if test "x$ac_cv_have_struct_addrinfo" = "xyes" ; then
+	AC_DEFINE([HAVE_STRUCT_ADDRINFO], [1],
+		[define if you have struct addrinfo data type])
+fi
+
+AC_CACHE_CHECK([for struct timeval], ac_cv_have_struct_timeval, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <sys/time.h> ]],
+	[[ struct timeval tv; tv.tv_sec = 1;]])],
+	[ ac_cv_have_struct_timeval="yes" ],
+	[ ac_cv_have_struct_timeval="no"
+	])
+])
+if test "x$ac_cv_have_struct_timeval" = "xyes" ; then
+	AC_DEFINE([HAVE_STRUCT_TIMEVAL], [1], [define if you have struct timeval])
+	have_struct_timeval=1
+fi
+
+AC_CACHE_CHECK([for struct timespec], ac_cv_have_struct_timespec, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+    #ifdef HAVE_SYS_TIME_H
+    # include <sys/time.h>
+    #endif
+    #ifdef HAVE_TIME_H
+    # include <time.h>
+    #endif
+	]],
+	[[ struct timespec ts; ts.tv_sec = 1;]])],
+	[ ac_cv_have_struct_timespec="yes" ],
+	[ ac_cv_have_struct_timespec="no"
+	])
+])
+if test "x$ac_cv_have_struct_timespec" = "xyes" ; then
+	AC_DEFINE([HAVE_STRUCT_TIMESPEC], [1], [define if you have struct timespec])
+	have_struct_timespec=1
+fi
+
+# We need int64_t or else certain parts of the compile will fail.
+if test "x$ac_cv_have_int64_t" = "xno" && \
+	test "x$ac_cv_sizeof_long_int" != "x8" && \
+	test "x$ac_cv_sizeof_long_long_int" = "x0" ; then
+	echo "OpenSSH requires int64_t support.  Contact your vendor or install"
+	echo "an alternative compiler (I.E., GCC) before continuing."
+	echo ""
+	exit 1;
+else
+dnl test snprintf (broken on SCO w/gcc)
+	AC_RUN_IFELSE(
+		[AC_LANG_SOURCE([[
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_SNPRINTF
+main()
+{
+	char buf[50];
+	char expected_out[50];
+	int mazsize = 50 ;
+#if (SIZEOF_LONG_INT == 8)
+	long int num = 0x7fffffffffffffff;
+#else
+	long long num = 0x7fffffffffffffffll;
+#endif
+	strcpy(expected_out, "9223372036854775807");
+	snprintf(buf, mazsize, "%lld", num);
+	if(strcmp(buf, expected_out) != 0)
+		exit(1);
+	exit(0);
+}
+#else
+main() { exit(0); }
+#endif
+		]])], [ true ], [ AC_DEFINE([BROKEN_SNPRINTF]) ],
+		AC_MSG_WARN([cross compiling: Assuming working snprintf()])
+	)
+fi
+
+dnl Checks for structure members
+OSSH_CHECK_HEADER_FOR_FIELD([ut_host], [utmp.h], [HAVE_HOST_IN_UTMP])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_host], [utmpx.h], [HAVE_HOST_IN_UTMPX])
+OSSH_CHECK_HEADER_FOR_FIELD([syslen], [utmpx.h], [HAVE_SYSLEN_IN_UTMPX])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_pid], [utmp.h], [HAVE_PID_IN_UTMP])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_type], [utmp.h], [HAVE_TYPE_IN_UTMP])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_type], [utmpx.h], [HAVE_TYPE_IN_UTMPX])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_tv], [utmp.h], [HAVE_TV_IN_UTMP])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_id], [utmp.h], [HAVE_ID_IN_UTMP])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_id], [utmpx.h], [HAVE_ID_IN_UTMPX])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_addr], [utmp.h], [HAVE_ADDR_IN_UTMP])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_addr], [utmpx.h], [HAVE_ADDR_IN_UTMPX])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_addr_v6], [utmp.h], [HAVE_ADDR_V6_IN_UTMP])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_addr_v6], [utmpx.h], [HAVE_ADDR_V6_IN_UTMPX])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_exit], [utmp.h], [HAVE_EXIT_IN_UTMP])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_time], [utmp.h], [HAVE_TIME_IN_UTMP])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_time], [utmpx.h], [HAVE_TIME_IN_UTMPX])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_tv], [utmpx.h], [HAVE_TV_IN_UTMPX])
+OSSH_CHECK_HEADER_FOR_FIELD([ut_ss], [utmpx.h], [HAVE_SS_IN_UTMPX])
+
+AC_CHECK_MEMBERS([struct stat.st_blksize])
+AC_CHECK_MEMBERS([struct stat.st_mtim])
+AC_CHECK_MEMBERS([struct stat.st_mtime])
+AC_CHECK_MEMBERS([struct passwd.pw_gecos, struct passwd.pw_class,
+struct passwd.pw_change, struct passwd.pw_expire],
+[], [], [[
+#include <sys/types.h>
+#include <pwd.h>
+]])
+
+AC_CHECK_MEMBER([struct __res_state.retrans], [], [AC_DEFINE([__res_state], [state],
+	[Define if we don't have struct __res_state in resolv.h])],
+[[
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+]])
+
+AC_CACHE_CHECK([for ss_family field in struct sockaddr_storage],
+		ac_cv_have_ss_family_in_struct_ss, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+		]], [[ struct sockaddr_storage s; s.ss_family = 1; ]])],
+	[ ac_cv_have_ss_family_in_struct_ss="yes" ],
+	[ ac_cv_have_ss_family_in_struct_ss="no" ])
+])
+if test "x$ac_cv_have_ss_family_in_struct_ss" = "xyes" ; then
+	AC_DEFINE([HAVE_SS_FAMILY_IN_SS], [1], [Fields in struct sockaddr_storage])
+fi
+
+AC_CACHE_CHECK([for __ss_family field in struct sockaddr_storage],
+		ac_cv_have___ss_family_in_struct_ss, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+		]], [[ struct sockaddr_storage s; s.__ss_family = 1; ]])],
+	[ ac_cv_have___ss_family_in_struct_ss="yes" ],
+	[ ac_cv_have___ss_family_in_struct_ss="no"
+	])
+])
+if test "x$ac_cv_have___ss_family_in_struct_ss" = "xyes" ; then
+	AC_DEFINE([HAVE___SS_FAMILY_IN_SS], [1],
+		[Fields in struct sockaddr_storage])
+fi
+
+dnl make sure we're using the real structure members and not defines
+AC_CACHE_CHECK([for msg_accrights field in struct msghdr],
+		ac_cv_have_accrights_in_msghdr, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <stdlib.h>
+		]], [[
+#ifdef msg_accrights
+#error "msg_accrights is a macro"
+exit(1);
+#endif
+struct msghdr m;
+m.msg_accrights = 0;
+exit(0);
+		]])],
+		[ ac_cv_have_accrights_in_msghdr="yes" ],
+		[ ac_cv_have_accrights_in_msghdr="no" ]
+	)
+])
+if test "x$ac_cv_have_accrights_in_msghdr" = "xyes" ; then
+	AC_DEFINE([HAVE_ACCRIGHTS_IN_MSGHDR], [1],
+		[Define if your system uses access rights style
+		file descriptor passing])
+fi
+
+AC_MSG_CHECKING([if struct statvfs.f_fsid is integral type])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/param.h>
+#include <sys/stat.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_MOUNT_H
+#include <sys/mount.h>
+#endif
+#ifdef HAVE_SYS_STATVFS_H
+#include <sys/statvfs.h>
+#endif
+	]], [[ struct statvfs s; s.f_fsid = 0; ]])],
+	[ AC_MSG_RESULT([yes]) ],
+	[ AC_MSG_RESULT([no])
+
+	AC_MSG_CHECKING([if fsid_t has member val])
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/statvfs.h>
+	]], [[ fsid_t t; t.val[0] = 0; ]])],
+	[ AC_MSG_RESULT([yes])
+	  AC_DEFINE([FSID_HAS_VAL], [1], [fsid_t has member val]) ],
+	[ AC_MSG_RESULT([no]) ])
+
+	AC_MSG_CHECKING([if f_fsid has member __val])
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/statvfs.h>
+	]], [[ fsid_t t; t.__val[0] = 0; ]])],
+	[ AC_MSG_RESULT([yes])
+	  AC_DEFINE([FSID_HAS___VAL], [1], [fsid_t has member __val]) ],
+	[ AC_MSG_RESULT([no]) ])
+])
+
+AC_CACHE_CHECK([for msg_control field in struct msghdr],
+		ac_cv_have_control_in_msghdr, [
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <stdlib.h>
+		]], [[
+#ifdef msg_control
+#error "msg_control is a macro"
+exit(1);
+#endif
+struct msghdr m;
+m.msg_control = 0;
+exit(0);
+		]])],
+		[ ac_cv_have_control_in_msghdr="yes" ],
+		[ ac_cv_have_control_in_msghdr="no" ]
+	)
+])
+if test "x$ac_cv_have_control_in_msghdr" = "xyes" ; then
+	AC_DEFINE([HAVE_CONTROL_IN_MSGHDR], [1],
+		[Define if your system uses ancillary data style
+		file descriptor passing])
+fi
+
+AC_CACHE_CHECK([if libc defines __progname], ac_cv_libc_defines___progname, [
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]],
+		[[ extern char *__progname; printf("%s", __progname); ]])],
+	[ ac_cv_libc_defines___progname="yes" ],
+	[ ac_cv_libc_defines___progname="no"
+	])
+])
+if test "x$ac_cv_libc_defines___progname" = "xyes" ; then
+	AC_DEFINE([HAVE___PROGNAME], [1], [Define if libc defines __progname])
+fi
+
+AC_CACHE_CHECK([whether $CC implements __FUNCTION__], ac_cv_cc_implements___FUNCTION__, [
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]],
+		[[ printf("%s", __FUNCTION__); ]])],
+	[ ac_cv_cc_implements___FUNCTION__="yes" ],
+	[ ac_cv_cc_implements___FUNCTION__="no"
+	])
+])
+if test "x$ac_cv_cc_implements___FUNCTION__" = "xyes" ; then
+	AC_DEFINE([HAVE___FUNCTION__], [1],
+		[Define if compiler implements __FUNCTION__])
+fi
+
+AC_CACHE_CHECK([whether $CC implements __func__], ac_cv_cc_implements___func__, [
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]],
+		[[ printf("%s", __func__); ]])],
+	[ ac_cv_cc_implements___func__="yes" ],
+	[ ac_cv_cc_implements___func__="no"
+	])
+])
+if test "x$ac_cv_cc_implements___func__" = "xyes" ; then
+	AC_DEFINE([HAVE___func__], [1], [Define if compiler implements __func__])
+fi
+
+AC_CACHE_CHECK([whether va_copy exists], ac_cv_have_va_copy, [
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <stdarg.h>
+va_list x,y;
+		]], [[ va_copy(x,y); ]])],
+	[ ac_cv_have_va_copy="yes" ],
+	[ ac_cv_have_va_copy="no"
+	])
+])
+if test "x$ac_cv_have_va_copy" = "xyes" ; then
+	AC_DEFINE([HAVE_VA_COPY], [1], [Define if va_copy exists])
+fi
+
+AC_CACHE_CHECK([whether __va_copy exists], ac_cv_have___va_copy, [
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <stdarg.h>
+va_list x,y;
+		]], [[ __va_copy(x,y); ]])],
+	[ ac_cv_have___va_copy="yes" ], [ ac_cv_have___va_copy="no"
+	])
+])
+if test "x$ac_cv_have___va_copy" = "xyes" ; then
+	AC_DEFINE([HAVE___VA_COPY], [1], [Define if __va_copy exists])
+fi
+
+AC_CACHE_CHECK([whether getopt has optreset support],
+		ac_cv_have_getopt_optreset, [
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <getopt.h> ]],
+		[[ extern int optreset; optreset = 0; ]])],
+	[ ac_cv_have_getopt_optreset="yes" ],
+	[ ac_cv_have_getopt_optreset="no"
+	])
+])
+if test "x$ac_cv_have_getopt_optreset" = "xyes" ; then
+	AC_DEFINE([HAVE_GETOPT_OPTRESET], [1],
+		[Define if your getopt(3) defines and uses optreset])
+fi
+
+AC_CACHE_CHECK([if libc defines sys_errlist], ac_cv_libc_defines_sys_errlist, [
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]],
+[[ extern const char *const sys_errlist[]; printf("%s", sys_errlist[0]);]])],
+	[ ac_cv_libc_defines_sys_errlist="yes" ],
+	[ ac_cv_libc_defines_sys_errlist="no"
+	])
+])
+if test "x$ac_cv_libc_defines_sys_errlist" = "xyes" ; then
+	AC_DEFINE([HAVE_SYS_ERRLIST], [1],
+		[Define if your system defines sys_errlist[]])
+fi
+
+
+AC_CACHE_CHECK([if libc defines sys_nerr], ac_cv_libc_defines_sys_nerr, [
+	AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <stdio.h> ]],
+[[ extern int sys_nerr; printf("%i", sys_nerr);]])],
+	[ ac_cv_libc_defines_sys_nerr="yes" ],
+	[ ac_cv_libc_defines_sys_nerr="no"
+	])
+])
+if test "x$ac_cv_libc_defines_sys_nerr" = "xyes" ; then
+	AC_DEFINE([HAVE_SYS_NERR], [1], [Define if your system defines sys_nerr])
+fi
+
+# Check libraries needed by DNS fingerprint support
+AC_SEARCH_LIBS([getrrsetbyname], [resolv],
+	[AC_DEFINE([HAVE_GETRRSETBYNAME], [1],
+		[Define if getrrsetbyname() exists])],
+	[
+		# Needed by our getrrsetbyname()
+		AC_SEARCH_LIBS([res_query], [resolv])
+		AC_SEARCH_LIBS([dn_expand], [resolv])
+		AC_MSG_CHECKING([if res_query will link])
+		AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+				]], [[
+	res_query (0, 0, 0, 0, 0);
+				]])],
+		    AC_MSG_RESULT([yes]),
+		   [AC_MSG_RESULT([no])
+		    saved_LIBS="$LIBS"
+		    LIBS="$LIBS -lresolv"
+		    AC_MSG_CHECKING([for res_query in -lresolv])
+		    AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+				]], [[
+	res_query (0, 0, 0, 0, 0);
+				]])],
+			[AC_MSG_RESULT([yes])],
+			[LIBS="$saved_LIBS"
+			 AC_MSG_RESULT([no])])
+		    ])
+		AC_CHECK_FUNCS([_getshort _getlong])
+		AC_CHECK_DECLS([_getshort, _getlong], , ,
+		    [#include <sys/types.h>
+		    #include <arpa/nameser.h>])
+		AC_CHECK_MEMBER([HEADER.ad],
+			[AC_DEFINE([HAVE_HEADER_AD], [1],
+			    [Define if HEADER.ad exists in arpa/nameser.h])], ,
+			[#include <arpa/nameser.h>])
+	])
+
+AC_MSG_CHECKING([if struct __res_state _res is an extern])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+extern struct __res_state _res;
+		]], [[
+struct __res_state *volatile p = &_res;  /* force resolution of _res */
+return 0;
+		]],)],
+		[AC_MSG_RESULT([yes])
+		 AC_DEFINE([HAVE__RES_EXTERN], [1],
+		    [Define if you have struct __res_state _res as an extern])
+		],
+		[ AC_MSG_RESULT([no]) ]
+)
+
+# Check whether user wants SELinux support
+SELINUX_MSG="no"
+LIBSELINUX=""
+AC_ARG_WITH([selinux],
+	[  --with-selinux          Enable SELinux support],
+	[ if test "x$withval" != "xno" ; then
+		save_LIBS="$LIBS"
+		AC_DEFINE([WITH_SELINUX], [1],
+			[Define if you want SELinux support.])
+		SELINUX_MSG="yes"
+		AC_CHECK_HEADER([selinux/selinux.h], ,
+			AC_MSG_ERROR([SELinux support requires selinux.h header]))
+		AC_CHECK_LIB([selinux], [setexeccon],
+			[ LIBSELINUX="-lselinux"
+			  LIBS="$LIBS -lselinux"
+			],
+			AC_MSG_ERROR([SELinux support requires libselinux library]))
+		AC_CHECK_FUNCS([getseuserbyname get_default_context_with_level])
+		LIBS="$save_LIBS $LIBSELINUX"
+	fi ]
+)
+AC_SUBST([SSHDLIBS])
+
+# Check whether user wants Kerberos 5 support
+KRB5_MSG="no"
+AC_ARG_WITH([kerberos5],
+	[  --with-kerberos5=PATH   Enable Kerberos 5 support],
+	[ if test "x$withval" != "xno" ; then
+		if test "x$withval" = "xyes" ; then
+			KRB5ROOT="/usr/local"
+		else
+			KRB5ROOT=${withval}
+		fi
+
+		AC_DEFINE([KRB5], [1], [Define if you want Kerberos 5 support])
+		KRB5_MSG="yes"
+
+		AC_PATH_TOOL([KRB5CONF], [krb5-config],
+			     [$KRB5ROOT/bin/krb5-config],
+			     [$KRB5ROOT/bin:$PATH])
+		if test -x $KRB5CONF ; then
+			K5CFLAGS="`$KRB5CONF --cflags`"
+			K5LIBS="`$KRB5CONF --libs`"
+			CPPFLAGS="$CPPFLAGS $K5CFLAGS"
+
+			AC_MSG_CHECKING([for gssapi support])
+			if $KRB5CONF | grep gssapi >/dev/null ; then
+				AC_MSG_RESULT([yes])
+				AC_DEFINE([GSSAPI], [1],
+					[Define this if you want GSSAPI
+					support in the version 2 protocol])
+				GSSCFLAGS="`$KRB5CONF --cflags gssapi`"
+				GSSLIBS="`$KRB5CONF --libs gssapi`"
+				CPPFLAGS="$CPPFLAGS $GSSCFLAGS"
+			else
+				AC_MSG_RESULT([no])
+			fi
+			AC_MSG_CHECKING([whether we are using Heimdal])
+			AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <krb5.h>
+				]], [[ char *tmp = heimdal_version; ]])],
+				[ AC_MSG_RESULT([yes])
+				AC_DEFINE([HEIMDAL], [1],
+				[Define this if you are using the Heimdal
+				version of Kerberos V5]) ],
+				[AC_MSG_RESULT([no])
+			])
+		else
+			CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include"
+			LDFLAGS="$LDFLAGS -L${KRB5ROOT}/lib"
+			AC_MSG_CHECKING([whether we are using Heimdal])
+			AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <krb5.h>
+				]], [[ char *tmp = heimdal_version; ]])],
+					[ AC_MSG_RESULT([yes])
+					 AC_DEFINE([HEIMDAL])
+					 K5LIBS="-lkrb5"
+					 K5LIBS="$K5LIBS -lcom_err -lasn1"
+					 AC_CHECK_LIB([roken], [net_write],
+					   [K5LIBS="$K5LIBS -lroken"])
+					 AC_CHECK_LIB([des], [des_cbc_encrypt],
+					   [K5LIBS="$K5LIBS -ldes"])
+				       ], [ AC_MSG_RESULT([no])
+					 K5LIBS="-lkrb5 -lk5crypto -lcom_err"
+			])
+			AC_SEARCH_LIBS([dn_expand], [resolv])
+
+			AC_CHECK_LIB([gssapi_krb5], [gss_init_sec_context],
+				[ AC_DEFINE([GSSAPI])
+				  GSSLIBS="-lgssapi_krb5" ],
+				[ AC_CHECK_LIB([gssapi], [gss_init_sec_context],
+					[ AC_DEFINE([GSSAPI])
+					  GSSLIBS="-lgssapi" ],
+					[ AC_CHECK_LIB([gss], [gss_init_sec_context],
+						[ AC_DEFINE([GSSAPI])
+						  GSSLIBS="-lgss" ],
+						AC_MSG_WARN([Cannot find any suitable gss-api library - build may fail]))
+					])
+				])
+
+			AC_CHECK_HEADER([gssapi.h], ,
+				[ unset ac_cv_header_gssapi_h
+				  CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
+				  AC_CHECK_HEADERS([gssapi.h], ,
+					AC_MSG_WARN([Cannot find any suitable gss-api header - build may fail])
+				  )
+				]
+			)
+
+			oldCPP="$CPPFLAGS"
+			CPPFLAGS="$CPPFLAGS -I${KRB5ROOT}/include/gssapi"
+			AC_CHECK_HEADER([gssapi_krb5.h], ,
+					[ CPPFLAGS="$oldCPP" ])
+
+		fi
+		if test -n "${rpath_opt}" ; then
+			LDFLAGS="$LDFLAGS ${rpath_opt}${KRB5ROOT}/lib"
+		fi
+		if test ! -z "$blibpath" ; then
+			blibpath="$blibpath:${KRB5ROOT}/lib"
+		fi
+
+		AC_CHECK_HEADERS([gssapi.h gssapi/gssapi.h])
+		AC_CHECK_HEADERS([gssapi_krb5.h gssapi/gssapi_krb5.h])
+		AC_CHECK_HEADERS([gssapi_generic.h gssapi/gssapi_generic.h])
+
+		AC_SEARCH_LIBS([k_hasafs], [kafs], [AC_DEFINE([USE_AFS], [1],
+			[Define this if you want to use libkafs' AFS support])])
+
+		AC_CHECK_DECLS([GSS_C_NT_HOSTBASED_SERVICE], [], [], [[
+#ifdef HAVE_GSSAPI_H
+# include <gssapi.h>
+#elif defined(HAVE_GSSAPI_GSSAPI_H)
+# include <gssapi/gssapi.h>
+#endif
+
+#ifdef HAVE_GSSAPI_GENERIC_H
+# include <gssapi_generic.h>
+#elif defined(HAVE_GSSAPI_GSSAPI_GENERIC_H)
+# include <gssapi/gssapi_generic.h>
+#endif
+		]])
+		saved_LIBS="$LIBS"
+		LIBS="$LIBS $K5LIBS"
+		AC_CHECK_FUNCS([krb5_cc_new_unique krb5_get_error_message krb5_free_error_message])
+		LIBS="$saved_LIBS"
+
+	fi
+	]
+)
+AC_SUBST([GSSLIBS])
+AC_SUBST([K5LIBS])
+
+# Looking for programs, paths and files
+
+PRIVSEP_PATH=/var/empty
+AC_ARG_WITH([privsep-path],
+	[  --with-privsep-path=xxx Path for privilege separation chroot (default=/var/empty)],
+	[
+		if test -n "$withval"  &&  test "x$withval" != "xno"  &&  \
+		    test "x${withval}" != "xyes"; then
+			PRIVSEP_PATH=$withval
+		fi
+	]
+)
+AC_SUBST([PRIVSEP_PATH])
+
+AC_ARG_WITH([xauth],
+	[  --with-xauth=PATH       Specify path to xauth program ],
+	[
+		if test -n "$withval"  &&  test "x$withval" != "xno"  &&  \
+		    test "x${withval}" != "xyes"; then
+			xauth_path=$withval
+		fi
+	],
+	[
+		TestPath="$PATH"
+		TestPath="${TestPath}${PATH_SEPARATOR}/usr/X/bin"
+		TestPath="${TestPath}${PATH_SEPARATOR}/usr/bin/X11"
+		TestPath="${TestPath}${PATH_SEPARATOR}/usr/X11R6/bin"
+		TestPath="${TestPath}${PATH_SEPARATOR}/usr/openwin/bin"
+		AC_PATH_PROG([xauth_path], [xauth], , [$TestPath])
+		if (test ! -z "$xauth_path" && test -x "/usr/openwin/bin/xauth") ; then
+			xauth_path="/usr/openwin/bin/xauth"
+		fi
+	]
+)
+
+STRIP_OPT=-s
+AC_ARG_ENABLE([strip],
+	[  --disable-strip         Disable calling strip(1) on install],
+	[
+		if test "x$enableval" = "xno" ; then
+			STRIP_OPT=
+		fi
+	]
+)
+AC_SUBST([STRIP_OPT])
+
+if test -z "$xauth_path" ; then
+	XAUTH_PATH="undefined"
+	AC_SUBST([XAUTH_PATH])
+else
+	AC_DEFINE_UNQUOTED([XAUTH_PATH], ["$xauth_path"],
+		[Define if xauth is found in your path])
+	XAUTH_PATH=$xauth_path
+	AC_SUBST([XAUTH_PATH])
+fi
+
+dnl # --with-maildir=/path/to/mail gets top priority.
+dnl # if maildir is set in the platform case statement above we use that.
+dnl # Otherwise we run a program to get the dir from system headers.
+dnl # We first look for _PATH_MAILDIR then MAILDIR then _PATH_MAIL
+dnl # If we find _PATH_MAILDIR we do nothing because that is what
+dnl # session.c expects anyway. Otherwise we set to the value found
+dnl # stripping any trailing slash. If for some strage reason our program
+dnl # does not find what it needs, we default to /var/spool/mail.
+# Check for mail directory
+AC_ARG_WITH([maildir],
+    [  --with-maildir=/path/to/mail    Specify your system mail directory],
+    [
+	if test "X$withval" != X  &&  test "x$withval" != xno  &&  \
+	    test "x${withval}" != xyes; then
+		AC_DEFINE_UNQUOTED([MAIL_DIRECTORY], ["$withval"],
+            [Set this to your mail directory if you do not have _PATH_MAILDIR])
+	    fi
+     ],[
+	if test "X$maildir" != "X"; then
+	    AC_DEFINE_UNQUOTED([MAIL_DIRECTORY], ["$maildir"])
+	else
+	    AC_MSG_CHECKING([Discovering system mail directory])
+	    AC_RUN_IFELSE(
+		[AC_LANG_PROGRAM([[
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#ifdef HAVE_MAILLOCK_H
+#include <maillock.h>
+#endif
+#define DATA "conftest.maildir"
+	]], [[
+	FILE *fd;
+	int rc;
+
+	fd = fopen(DATA,"w");
+	if(fd == NULL)
+		exit(1);
+
+#if defined (_PATH_MAILDIR)
+	if ((rc = fprintf(fd ,"_PATH_MAILDIR:%s\n", _PATH_MAILDIR)) <0)
+		exit(1);
+#elif defined (MAILDIR)
+	if ((rc = fprintf(fd ,"MAILDIR:%s\n", MAILDIR)) <0)
+		exit(1);
+#elif defined (_PATH_MAIL)
+	if ((rc = fprintf(fd ,"_PATH_MAIL:%s\n", _PATH_MAIL)) <0)
+		exit(1);
+#else
+	exit (2);
+#endif
+
+	exit(0);
+		]])],
+		[
+		    maildir_what=`awk -F: '{print $1}' conftest.maildir`
+		    maildir=`awk -F: '{print $2}' conftest.maildir \
+			| sed 's|/$||'`
+		    AC_MSG_RESULT([Using: $maildir from $maildir_what])
+		    if test "x$maildir_what" != "x_PATH_MAILDIR"; then
+			AC_DEFINE_UNQUOTED([MAIL_DIRECTORY], ["$maildir"])
+		    fi
+		],
+		[
+		    if test "X$ac_status" = "X2";then
+# our test program didn't find it. Default to /var/spool/mail
+			AC_MSG_RESULT([Using: default value of /var/spool/mail])
+			AC_DEFINE_UNQUOTED([MAIL_DIRECTORY], ["/var/spool/mail"])
+		     else
+			AC_MSG_RESULT([*** not found ***])
+		     fi
+		],
+		[
+			AC_MSG_WARN([cross compiling: use --with-maildir=/path/to/mail])
+		]
+	    )
+	fi
+    ]
+) # maildir
+
+if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes"; then
+	AC_MSG_WARN([cross compiling: Disabling /dev/ptmx test])
+	disable_ptmx_check=yes
+fi
+if test -z "$no_dev_ptmx" ; then
+	if test "x$disable_ptmx_check" != "xyes" ; then
+		AC_CHECK_FILE(["/dev/ptmx"],
+			[
+				AC_DEFINE_UNQUOTED([HAVE_DEV_PTMX], [1],
+					[Define if you have /dev/ptmx])
+				have_dev_ptmx=1
+			]
+		)
+	fi
+fi
+
+if test ! -z "$cross_compiling" && test "x$cross_compiling" != "xyes"; then
+	AC_CHECK_FILE(["/dev/ptc"],
+		[
+			AC_DEFINE_UNQUOTED([HAVE_DEV_PTS_AND_PTC], [1],
+				[Define if you have /dev/ptc])
+			have_dev_ptc=1
+		]
+	)
+else
+	AC_MSG_WARN([cross compiling: Disabling /dev/ptc test])
+fi
+
+# Options from here on. Some of these are preset by platform above
+AC_ARG_WITH([mantype],
+	[  --with-mantype=man|cat|doc  Set man page type],
+	[
+		case "$withval" in
+		man|cat|doc)
+			MANTYPE=$withval
+			;;
+		*)
+			AC_MSG_ERROR([invalid man type: $withval])
+			;;
+		esac
+	]
+)
+if test -z "$MANTYPE"; then
+	if ${MANDOC} ${srcdir}/ssh.1 >/dev/null 2>&1; then
+		MANTYPE=doc
+	elif ${NROFF} -mdoc ${srcdir}/ssh.1 >/dev/null 2>&1; then
+		MANTYPE=doc
+	elif ${NROFF} -man ${srcdir}/ssh.1 >/dev/null 2>&1; then
+		MANTYPE=man
+	else
+		MANTYPE=cat
+	fi
+fi
+AC_SUBST([MANTYPE])
+if test "$MANTYPE" = "doc"; then
+	mansubdir=man;
+else
+	mansubdir=$MANTYPE;
+fi
+AC_SUBST([mansubdir])
+
+# Check whether to enable MD5 passwords
+MD5_MSG="no"
+AC_ARG_WITH([md5-passwords],
+	[  --with-md5-passwords    Enable use of MD5 passwords],
+	[
+		if test "x$withval" != "xno" ; then
+			AC_DEFINE([HAVE_MD5_PASSWORDS], [1],
+				[Define if you want to allow MD5 passwords])
+			MD5_MSG="yes"
+		fi
+	]
+)
+
+# Whether to disable shadow password support
+AC_ARG_WITH([shadow],
+	[  --without-shadow        Disable shadow password support],
+	[
+		if test "x$withval" = "xno" ; then
+			AC_DEFINE([DISABLE_SHADOW])
+			disable_shadow=yes
+		fi
+	]
+)
+
+if test -z "$disable_shadow" ; then
+	AC_MSG_CHECKING([if the systems has expire shadow information])
+	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <shadow.h>
+struct spwd sp;
+		]], [[ sp.sp_expire = sp.sp_lstchg = sp.sp_inact = 0; ]])],
+		[ sp_expire_available=yes ], [
+	])
+
+	if test "x$sp_expire_available" = "xyes" ; then
+		AC_MSG_RESULT([yes])
+		AC_DEFINE([HAS_SHADOW_EXPIRE], [1],
+		    [Define if you want to use shadow password expire field])
+	else
+		AC_MSG_RESULT([no])
+	fi
+fi
+
+# Use ip address instead of hostname in $DISPLAY
+if test ! -z "$IPADDR_IN_DISPLAY" ; then
+	DISPLAY_HACK_MSG="yes"
+	AC_DEFINE([IPADDR_IN_DISPLAY], [1],
+		[Define if you need to use IP address
+		instead of hostname in $DISPLAY])
+else
+	DISPLAY_HACK_MSG="no"
+	AC_ARG_WITH([ipaddr-display],
+		[  --with-ipaddr-display   Use ip address instead of hostname in $DISPLAY],
+		[
+			if test "x$withval" != "xno" ; then
+				AC_DEFINE([IPADDR_IN_DISPLAY])
+				DISPLAY_HACK_MSG="yes"
+			fi
+		]
+	)
+fi
+
+# check for /etc/default/login and use it if present.
+AC_ARG_ENABLE([etc-default-login],
+	[  --disable-etc-default-login Disable using PATH from /etc/default/login [no]],
+	[ if test "x$enableval" = "xno"; then
+		AC_MSG_NOTICE([/etc/default/login handling disabled])
+		etc_default_login=no
+	  else
+		etc_default_login=yes
+	  fi ],
+	[ if test ! -z "$cross_compiling" && test "x$cross_compiling" = "xyes";
+	  then
+		AC_MSG_WARN([cross compiling: not checking /etc/default/login])
+		etc_default_login=no
+	  else
+		etc_default_login=yes
+	  fi ]
+)
+
+if test "x$etc_default_login" != "xno"; then
+	AC_CHECK_FILE(["/etc/default/login"],
+	    [ external_path_file=/etc/default/login ])
+	if test "x$external_path_file" = "x/etc/default/login"; then
+		AC_DEFINE([HAVE_ETC_DEFAULT_LOGIN], [1],
+			[Define if your system has /etc/default/login])
+	fi
+fi
+
+dnl BSD systems use /etc/login.conf so --with-default-path= has no effect
+if test $ac_cv_func_login_getcapbool = "yes" && \
+	test $ac_cv_header_login_cap_h = "yes" ; then
+	external_path_file=/etc/login.conf
+fi
+
+# Whether to mess with the default path
+SERVER_PATH_MSG="(default)"
+AC_ARG_WITH([default-path],
+	[  --with-default-path=    Specify default $PATH environment for server],
+	[
+		if test "x$external_path_file" = "x/etc/login.conf" ; then
+			AC_MSG_WARN([
+--with-default-path=PATH has no effect on this system.
+Edit /etc/login.conf instead.])
+		elif test "x$withval" != "xno" ; then
+			if test ! -z "$external_path_file" ; then
+				AC_MSG_WARN([
+--with-default-path=PATH will only be used if PATH is not defined in
+$external_path_file .])
+			fi
+			user_path="$withval"
+			SERVER_PATH_MSG="$withval"
+		fi
+	],
+	[ if test "x$external_path_file" = "x/etc/login.conf" ; then
+		AC_MSG_WARN([Make sure the path to scp is in /etc/login.conf])
+	else
+		if test ! -z "$external_path_file" ; then
+			AC_MSG_WARN([
+If PATH is defined in $external_path_file, ensure the path to scp is included,
+otherwise scp will not work.])
+		fi
+		AC_RUN_IFELSE(
+			[AC_LANG_PROGRAM([[
+/* find out what STDPATH is */
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_PATHS_H
+# include <paths.h>
+#endif
+#ifndef _PATH_STDPATH
+# ifdef _PATH_USERPATH	/* Irix */
+#  define _PATH_STDPATH _PATH_USERPATH
+# else
+#  define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin"
+# endif
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#define DATA "conftest.stdpath"
+			]], [[
+	FILE *fd;
+	int rc;
+
+	fd = fopen(DATA,"w");
+	if(fd == NULL)
+		exit(1);
+
+	if ((rc = fprintf(fd,"%s", _PATH_STDPATH)) < 0)
+		exit(1);
+
+	exit(0);
+		]])],
+		[ user_path=`cat conftest.stdpath` ],
+		[ user_path="/usr/bin:/bin:/usr/sbin:/sbin" ],
+		[ user_path="/usr/bin:/bin:/usr/sbin:/sbin" ]
+	)
+# make sure $bindir is in USER_PATH so scp will work
+		t_bindir="${bindir}"
+		while echo "${t_bindir}" | egrep '\$\{|NONE/' >/dev/null 2>&1; do
+			t_bindir=`eval echo ${t_bindir}`
+			case $t_bindir in
+				NONE/*) t_bindir=`echo $t_bindir | sed "s~NONE~$prefix~"` ;;
+			esac
+			case $t_bindir in
+				NONE/*) t_bindir=`echo $t_bindir | sed "s~NONE~$ac_default_prefix~"` ;;
+			esac
+		done
+		echo $user_path | grep ":$t_bindir"  > /dev/null 2>&1
+		if test $? -ne 0  ; then
+			echo $user_path | grep "^$t_bindir"  > /dev/null 2>&1
+			if test $? -ne 0  ; then
+				user_path=$user_path:$t_bindir
+				AC_MSG_RESULT([Adding $t_bindir to USER_PATH so scp will work])
+			fi
+		fi
+	fi ]
+)
+if test "x$external_path_file" != "x/etc/login.conf" ; then
+	AC_DEFINE_UNQUOTED([USER_PATH], ["$user_path"], [Specify default $PATH])
+	AC_SUBST([user_path])
+fi
+
+# Set superuser path separately to user path
+AC_ARG_WITH([superuser-path],
+	[  --with-superuser-path=  Specify different path for super-user],
+	[
+		if test -n "$withval"  &&  test "x$withval" != "xno"  &&  \
+		    test "x${withval}" != "xyes"; then
+			AC_DEFINE_UNQUOTED([SUPERUSER_PATH], ["$withval"],
+				[Define if you want a different $PATH
+				for the superuser])
+			superuser_path=$withval
+		fi
+	]
+)
+
+
+AC_MSG_CHECKING([if we need to convert IPv4 in IPv6-mapped addresses])
+IPV4_IN6_HACK_MSG="no"
+AC_ARG_WITH(4in6,
+	[  --with-4in6             Check for and convert IPv4 in IPv6 mapped addresses],
+	[
+		if test "x$withval" != "xno" ; then
+			AC_MSG_RESULT([yes])
+			AC_DEFINE([IPV4_IN_IPV6], [1],
+				[Detect IPv4 in IPv6 mapped addresses
+				and treat as IPv4])
+			IPV4_IN6_HACK_MSG="yes"
+		else
+			AC_MSG_RESULT([no])
+		fi
+	], [
+		if test "x$inet6_default_4in6" = "xyes"; then
+			AC_MSG_RESULT([yes (default)])
+			AC_DEFINE([IPV4_IN_IPV6])
+			IPV4_IN6_HACK_MSG="yes"
+		else
+			AC_MSG_RESULT([no (default)])
+		fi
+	]
+)
+
+# Whether to enable BSD auth support
+BSD_AUTH_MSG=no
+AC_ARG_WITH([bsd-auth],
+	[  --with-bsd-auth         Enable BSD auth support],
+	[
+		if test "x$withval" != "xno" ; then
+			AC_DEFINE([BSD_AUTH], [1],
+				[Define if you have BSD auth support])
+			BSD_AUTH_MSG=yes
+		fi
+	]
+)
+
+# Where to place sshd.pid
+piddir=/var/run
+# make sure the directory exists
+if test ! -d $piddir ; then
+	piddir=`eval echo ${sysconfdir}`
+	case $piddir in
+		NONE/*) piddir=`echo $piddir | sed "s~NONE~$ac_default_prefix~"` ;;
+	esac
+fi
+
+AC_ARG_WITH([pid-dir],
+	[  --with-pid-dir=PATH     Specify location of sshd.pid file],
+	[
+		if test -n "$withval"  &&  test "x$withval" != "xno"  &&  \
+		    test "x${withval}" != "xyes"; then
+			piddir=$withval
+			if test ! -d $piddir ; then
+			AC_MSG_WARN([** no $piddir directory on this system **])
+			fi
+		fi
+	]
+)
+
+AC_DEFINE_UNQUOTED([_PATH_SSH_PIDDIR], ["$piddir"],
+	[Specify location of ssh.pid])
+AC_SUBST([piddir])
+
+dnl allow user to disable some login recording features
+AC_ARG_ENABLE([lastlog],
+	[  --disable-lastlog       disable use of lastlog even if detected [no]],
+	[
+		if test "x$enableval" = "xno" ; then
+			AC_DEFINE([DISABLE_LASTLOG])
+		fi
+	]
+)
+AC_ARG_ENABLE([utmp],
+	[  --disable-utmp          disable use of utmp even if detected [no]],
+	[
+		if test "x$enableval" = "xno" ; then
+			AC_DEFINE([DISABLE_UTMP])
+		fi
+	]
+)
+AC_ARG_ENABLE([utmpx],
+	[  --disable-utmpx         disable use of utmpx even if detected [no]],
+	[
+		if test "x$enableval" = "xno" ; then
+			AC_DEFINE([DISABLE_UTMPX], [1],
+				[Define if you don't want to use utmpx])
+		fi
+	]
+)
+AC_ARG_ENABLE([wtmp],
+	[  --disable-wtmp          disable use of wtmp even if detected [no]],
+	[
+		if test "x$enableval" = "xno" ; then
+			AC_DEFINE([DISABLE_WTMP])
+		fi
+	]
+)
+AC_ARG_ENABLE([wtmpx],
+	[  --disable-wtmpx         disable use of wtmpx even if detected [no]],
+	[
+		if test "x$enableval" = "xno" ; then
+			AC_DEFINE([DISABLE_WTMPX], [1],
+				[Define if you don't want to use wtmpx])
+		fi
+	]
+)
+AC_ARG_ENABLE([libutil],
+	[  --disable-libutil       disable use of libutil (login() etc.) [no]],
+	[
+		if test "x$enableval" = "xno" ; then
+			AC_DEFINE([DISABLE_LOGIN])
+		fi
+	]
+)
+AC_ARG_ENABLE([pututline],
+	[  --disable-pututline     disable use of pututline() etc. ([uw]tmp) [no]],
+	[
+		if test "x$enableval" = "xno" ; then
+			AC_DEFINE([DISABLE_PUTUTLINE], [1],
+				[Define if you don't want to use pututline()
+				etc. to write [uw]tmp])
+		fi
+	]
+)
+AC_ARG_ENABLE([pututxline],
+	[  --disable-pututxline    disable use of pututxline() etc. ([uw]tmpx) [no]],
+	[
+		if test "x$enableval" = "xno" ; then
+			AC_DEFINE([DISABLE_PUTUTXLINE], [1],
+				[Define if you don't want to use pututxline()
+				etc. to write [uw]tmpx])
+		fi
+	]
+)
+AC_ARG_WITH([lastlog],
+  [  --with-lastlog=FILE|DIR specify lastlog location [common locations]],
+	[
+		if test "x$withval" = "xno" ; then
+			AC_DEFINE([DISABLE_LASTLOG])
+		elif test -n "$withval"  &&  test "x${withval}" != "xyes"; then
+			conf_lastlog_location=$withval
+		fi
+	]
+)
+
+dnl lastlog, [uw]tmpx? detection
+dnl  NOTE: set the paths in the platform section to avoid the
+dnl   need for command-line parameters
+dnl lastlog and [uw]tmp are subject to a file search if all else fails
+
+dnl lastlog detection
+dnl  NOTE: the code itself will detect if lastlog is a directory
+AC_MSG_CHECKING([if your system defines LASTLOG_FILE])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <utmp.h>
+#ifdef HAVE_LASTLOG_H
+#  include <lastlog.h>
+#endif
+#ifdef HAVE_PATHS_H
+#  include <paths.h>
+#endif
+#ifdef HAVE_LOGIN_H
+# include <login.h>
+#endif
+	]], [[ char *lastlog = LASTLOG_FILE; ]])],
+		[ AC_MSG_RESULT([yes]) ],
+		[
+		AC_MSG_RESULT([no])
+		AC_MSG_CHECKING([if your system defines _PATH_LASTLOG])
+		AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <utmp.h>
+#ifdef HAVE_LASTLOG_H
+#  include <lastlog.h>
+#endif
+#ifdef HAVE_PATHS_H
+#  include <paths.h>
+#endif
+		]], [[ char *lastlog = _PATH_LASTLOG; ]])],
+		[ AC_MSG_RESULT([yes]) ],
+		[
+			AC_MSG_RESULT([no])
+			system_lastlog_path=no
+		])
+])
+
+if test -z "$conf_lastlog_location"; then
+	if test x"$system_lastlog_path" = x"no" ; then
+		for f in /var/log/lastlog /usr/adm/lastlog /var/adm/lastlog /etc/security/lastlog ; do
+				if (test -d "$f" || test -f "$f") ; then
+					conf_lastlog_location=$f
+				fi
+		done
+		if test -z "$conf_lastlog_location"; then
+			AC_MSG_WARN([** Cannot find lastlog **])
+			dnl Don't define DISABLE_LASTLOG - that means we don't try wtmp/wtmpx
+		fi
+	fi
+fi
+
+if test -n "$conf_lastlog_location"; then
+	AC_DEFINE_UNQUOTED([CONF_LASTLOG_FILE], ["$conf_lastlog_location"],
+		[Define if you want to specify the path to your lastlog file])
+fi
+
+dnl utmp detection
+AC_MSG_CHECKING([if your system defines UTMP_FILE])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <utmp.h>
+#ifdef HAVE_PATHS_H
+#  include <paths.h>
+#endif
+	]], [[ char *utmp = UTMP_FILE; ]])],
+	[ AC_MSG_RESULT([yes]) ],
+	[ AC_MSG_RESULT([no])
+	  system_utmp_path=no
+])
+if test -z "$conf_utmp_location"; then
+	if test x"$system_utmp_path" = x"no" ; then
+		for f in /etc/utmp /usr/adm/utmp /var/run/utmp; do
+			if test -f $f ; then
+				conf_utmp_location=$f
+			fi
+		done
+		if test -z "$conf_utmp_location"; then
+			AC_DEFINE([DISABLE_UTMP])
+		fi
+	fi
+fi
+if test -n "$conf_utmp_location"; then
+	AC_DEFINE_UNQUOTED([CONF_UTMP_FILE], ["$conf_utmp_location"],
+		[Define if you want to specify the path to your utmp file])
+fi
+
+dnl wtmp detection
+AC_MSG_CHECKING([if your system defines WTMP_FILE])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <utmp.h>
+#ifdef HAVE_PATHS_H
+#  include <paths.h>
+#endif
+	]], [[ char *wtmp = WTMP_FILE; ]])],
+	[ AC_MSG_RESULT([yes]) ],
+	[ AC_MSG_RESULT([no])
+	  system_wtmp_path=no
+])
+if test -z "$conf_wtmp_location"; then
+	if test x"$system_wtmp_path" = x"no" ; then
+		for f in /usr/adm/wtmp /var/log/wtmp; do
+			if test -f $f ; then
+				conf_wtmp_location=$f
+			fi
+		done
+		if test -z "$conf_wtmp_location"; then
+			AC_DEFINE([DISABLE_WTMP])
+		fi
+	fi
+fi
+if test -n "$conf_wtmp_location"; then
+	AC_DEFINE_UNQUOTED([CONF_WTMP_FILE], ["$conf_wtmp_location"],
+		[Define if you want to specify the path to your wtmp file])
+fi
+
+dnl wtmpx detection
+AC_MSG_CHECKING([if your system defines WTMPX_FILE])
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <sys/types.h>
+#include <utmp.h>
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif
+#ifdef HAVE_PATHS_H
+#  include <paths.h>
+#endif
+	]], [[ char *wtmpx = WTMPX_FILE; ]])],
+	[ AC_MSG_RESULT([yes]) ],
+	[ AC_MSG_RESULT([no])
+	  system_wtmpx_path=no
+])
+if test -z "$conf_wtmpx_location"; then
+	if test x"$system_wtmpx_path" = x"no" ; then
+		AC_DEFINE([DISABLE_WTMPX])
+	fi
+else
+	AC_DEFINE_UNQUOTED([CONF_WTMPX_FILE], ["$conf_wtmpx_location"],
+		[Define if you want to specify the path to your wtmpx file])
+fi
+
+
+if test ! -z "$blibpath" ; then
+	LDFLAGS="$LDFLAGS $blibflags$blibpath"
+	AC_MSG_WARN([Please check and edit blibpath in LDFLAGS in Makefile])
+fi
+
+AC_CHECK_MEMBER([struct lastlog.ll_line], [], [
+    if test x$SKIP_DISABLE_LASTLOG_DEFINE != "xyes" ; then
+	AC_DEFINE([DISABLE_LASTLOG])
+    fi
+	], [
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif
+#ifdef HAVE_LASTLOG_H
+#include <lastlog.h>
+#endif
+	])
+
+AC_CHECK_MEMBER([struct utmp.ut_line], [], [
+	AC_DEFINE([DISABLE_UTMP])
+	AC_DEFINE([DISABLE_WTMP])
+	], [
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UTMP_H
+#include <utmp.h>
+#endif
+#ifdef HAVE_UTMPX_H
+#include <utmpx.h>
+#endif
+#ifdef HAVE_LASTLOG_H
+#include <lastlog.h>
+#endif
+	])
+
+dnl Adding -Werror to CFLAGS early prevents configure tests from running.
+dnl Add now.
+CFLAGS="$CFLAGS $werror_flags"
+
+if test "x$ac_cv_func_getaddrinfo" != "xyes" ; then
+	TEST_SSH_IPV6=no
+else
+	TEST_SSH_IPV6=yes
+fi
+AC_CHECK_DECL([BROKEN_GETADDRINFO],  [TEST_SSH_IPV6=no])
+AC_SUBST([TEST_SSH_IPV6], [$TEST_SSH_IPV6])
+AC_SUBST([TEST_SSH_UTF8], [$TEST_SSH_UTF8])
+AC_SUBST([TEST_MALLOC_OPTIONS], [$TEST_MALLOC_OPTIONS])
+AC_SUBST([UNSUPPORTED_ALGORITHMS], [$unsupported_algorithms])
+AC_SUBST([DEPEND], [$(cat $srcdir/.depend)])
+
+CFLAGS="${CFLAGS} ${CFLAGS_AFTER}"
+LDFLAGS="${LDFLAGS} ${LDFLAGS_AFTER}"
+
+# Make a copy of CFLAGS/LDFLAGS without PIE options.
+LDFLAGS_NOPIE=`echo "$LDFLAGS" | sed 's/ -pie//'`
+CFLAGS_NOPIE=`echo "$CFLAGS" | sed 's/ -fPIE//'`
+AC_SUBST([LDFLAGS_NOPIE])
+AC_SUBST([CFLAGS_NOPIE])
+
+AC_EXEEXT
+AC_CONFIG_FILES([Makefile buildpkg.sh opensshd.init openssh.xml \
+	openbsd-compat/Makefile openbsd-compat/regress/Makefile \
+	survey.sh])
+AC_OUTPUT
+
+# Print summary of options
+
+# Someone please show me a better way :)
+A=`eval echo ${prefix}` ; A=`eval echo ${A}`
+B=`eval echo ${bindir}` ; B=`eval echo ${B}`
+C=`eval echo ${sbindir}` ; C=`eval echo ${C}`
+D=`eval echo ${sysconfdir}` ; D=`eval echo ${D}`
+E=`eval echo ${libexecdir}/ssh-askpass` ; E=`eval echo ${E}`
+F=`eval echo ${mandir}/${mansubdir}X` ; F=`eval echo ${F}`
+G=`eval echo ${piddir}` ; G=`eval echo ${G}`
+H=`eval echo ${PRIVSEP_PATH}` ; H=`eval echo ${H}`
+I=`eval echo ${user_path}` ; I=`eval echo ${I}`
+J=`eval echo ${superuser_path}` ; J=`eval echo ${J}`
+
+echo ""
+echo "OpenSSH has been configured with the following options:"
+echo "                     User binaries: $B"
+echo "                   System binaries: $C"
+echo "               Configuration files: $D"
+echo "                   Askpass program: $E"
+echo "                      Manual pages: $F"
+echo "                          PID file: $G"
+echo "  Privilege separation chroot path: $H"
+if test "x$external_path_file" = "x/etc/login.conf" ; then
+echo "   At runtime, sshd will use the path defined in $external_path_file"
+echo "   Make sure the path to scp is present, otherwise scp will not work"
+else
+echo "            sshd default user PATH: $I"
+	if test ! -z "$external_path_file"; then
+echo "   (If PATH is set in $external_path_file it will be used instead. If"
+echo "   used, ensure the path to scp is present, otherwise scp will not work.)"
+	fi
+fi
+if test ! -z "$superuser_path" ; then
+echo "          sshd superuser user PATH: $J"
+fi
+echo "                    Manpage format: $MANTYPE"
+echo "                       PAM support: $PAM_MSG"
+echo "                   OSF SIA support: $SIA_MSG"
+echo "                 KerberosV support: $KRB5_MSG"
+echo "                   SELinux support: $SELINUX_MSG"
+echo "              TCP Wrappers support: $TCPW_MSG"
+echo "              MD5 password support: $MD5_MSG"
+echo "                   libedit support: $LIBEDIT_MSG"
+echo "                   libldns support: $LDNS_MSG"
+echo "  Solaris process contract support: $SPC_MSG"
+echo "           Solaris project support: $SP_MSG"
+echo "         Solaris privilege support: $SPP_MSG"
+echo "       IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG"
+echo "           Translate v4 in v6 hack: $IPV4_IN6_HACK_MSG"
+echo "                  BSD Auth support: $BSD_AUTH_MSG"
+echo "              Random number source: $RAND_MSG"
+echo "             Privsep sandbox style: $SANDBOX_STYLE"
+echo "                   PKCS#11 support: $enable_pkcs11"
+echo "                  U2F/FIDO support: $enable_sk"
+
+echo ""
+
+echo "              Host: ${host}"
+echo "          Compiler: ${CC}"
+echo "    Compiler flags: ${CFLAGS}"
+echo "Preprocessor flags: ${CPPFLAGS}"
+echo "      Linker flags: ${LDFLAGS}"
+echo "         Libraries: ${LIBS}"
+if test ! -z "${SSHDLIBS}"; then
+echo "         +for sshd: ${SSHDLIBS}"
+fi
+
+echo ""
+
+if test "x$MAKE_PACKAGE_SUPPORTED" = "xyes" ; then
+	echo "SVR4 style packages are supported with \"make package\""
+	echo ""
+fi
+
+if test "x$PAM_MSG" = "xyes" ; then
+	echo "PAM is enabled. You may need to install a PAM control file "
+	echo "for sshd, otherwise password authentication may fail. "
+	echo "Example PAM control files can be found in the contrib/ "
+	echo "subdirectory"
+	echo ""
+fi
+
+if test ! -z "$NO_PEERCHECK" ; then
+	echo "WARNING: the operating system that you are using does not"
+	echo "appear to support getpeereid(), getpeerucred() or the"
+	echo "SO_PEERCRED getsockopt() option. These facilities are used to"
+	echo "enforce security checks to prevent unauthorised connections to"
+	echo "ssh-agent. Their absence increases the risk that a malicious"
+	echo "user can connect to your agent."
+	echo ""
+fi
+
+if test "$AUDIT_MODULE" = "bsm" ; then
+	echo "WARNING: BSM audit support is currently considered EXPERIMENTAL."
+	echo "See the Solaris section in README.platform for details."
+fi
Index: openssh-8.5p1-new/sshd.8
===================================================================
--- openssh-8.5p1-new/sshd.8	(nonexistent)
+++ openssh-8.5p1-new/sshd.8	(revision 5)
@@ -0,0 +1,1027 @@
+.\"
+.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
+.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+.\"                    All rights reserved
+.\"
+.\" 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".
+.\"
+.\" Copyright (c) 1999,2000 Markus Friedl.  All rights reserved.
+.\" Copyright (c) 1999 Aaron Campbell.  All rights reserved.
+.\" Copyright (c) 1999 Theo de Raadt.  All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $OpenBSD: sshd.8,v 1.313 2020/08/27 01:07:10 djm Exp $
+.Dd $Mdocdate: August 27 2020 $
+.Dt SSHD 8
+.Os
+.Sh NAME
+.Nm sshd
+.Nd OpenSSH daemon
+.Sh SYNOPSIS
+.Nm sshd
+.Bk -words
+.Op Fl 46DdeiqTt
+.Op Fl C Ar connection_spec
+.Op Fl c Ar host_certificate_file
+.Op Fl E Ar log_file
+.Op Fl f Ar config_file
+.Op Fl g Ar login_grace_time
+.Op Fl h Ar host_key_file
+.Op Fl o Ar option
+.Op Fl p Ar port
+.Op Fl u Ar len
+.Ek
+.Sh DESCRIPTION
+.Nm
+(OpenSSH Daemon) is the daemon program for
+.Xr ssh 1 .
+Together these programs replace rlogin and rsh,
+and provide secure encrypted communications between two untrusted hosts
+over an insecure network.
+.Pp
+.Nm
+listens for connections from clients.
+It is normally started at boot from
+.Pa /etc/rc .
+It forks a new
+daemon for each incoming connection.
+The forked daemons handle
+key exchange, encryption, authentication, command execution,
+and data exchange.
+.Pp
+.Nm
+can be configured using command-line options or a configuration file
+(by default
+.Xr sshd_config 5 ) ;
+command-line options override values specified in the
+configuration file.
+.Nm
+rereads its configuration file when it receives a hangup signal,
+.Dv SIGHUP ,
+by executing itself with the name and options it was started with, e.g.\&
+.Pa /usr/sbin/sshd .
+.Pp
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl 4
+Forces
+.Nm
+to use IPv4 addresses only.
+.It Fl 6
+Forces
+.Nm
+to use IPv6 addresses only.
+.It Fl C Ar connection_spec
+Specify the connection parameters to use for the
+.Fl T
+extended test mode.
+If provided, any
+.Cm Match
+directives in the configuration file that would apply are applied before the
+configuration is written to standard output.
+The connection parameters are supplied as keyword=value pairs and may be
+supplied in any order, either with multiple
+.Fl C
+options or as a comma-separated list.
+The keywords are
+.Dq addr,
+.Dq user ,
+.Dq host ,
+.Dq laddr ,
+.Dq lport ,
+and
+.Dq rdomain
+and correspond to source address, user, resolved source host name,
+local address, local port number and routing domain respectively.
+.It Fl c Ar host_certificate_file
+Specifies a path to a certificate file to identify
+.Nm
+during key exchange.
+The certificate file must match a host key file specified using the
+.Fl h
+option or the
+.Cm HostKey
+configuration directive.
+.It Fl D
+When this option is specified,
+.Nm
+will not detach and does not become a daemon.
+This allows easy monitoring of
+.Nm sshd .
+.It Fl d
+Debug mode.
+The server sends verbose debug output to standard error,
+and does not put itself in the background.
+The server also will not fork and will only process one connection.
+This option is only intended for debugging for the server.
+Multiple
+.Fl d
+options increase the debugging level.
+Maximum is 3.
+.It Fl E Ar log_file
+Append debug logs to
+.Ar log_file
+instead of the system log.
+.It Fl e
+Write debug logs to standard error instead of the system log.
+.It Fl f Ar config_file
+Specifies the name of the configuration file.
+The default is
+.Pa /etc/ssh/sshd_config .
+.Nm
+refuses to start if there is no configuration file.
+.It Fl g Ar login_grace_time
+Gives the grace time for clients to authenticate themselves (default
+120 seconds).
+If the client fails to authenticate the user within
+this many seconds, the server disconnects and exits.
+A value of zero indicates no limit.
+.It Fl h Ar host_key_file
+Specifies a file from which a host key is read.
+This option must be given if
+.Nm
+is not run as root (as the normal
+host key files are normally not readable by anyone but root).
+The default is
+.Pa /etc/ssh/ssh_host_ecdsa_key ,
+.Pa /etc/ssh/ssh_host_ed25519_key
+and
+.Pa /etc/ssh/ssh_host_rsa_key .
+It is possible to have multiple host key files for
+the different host key algorithms.
+.It Fl i
+Specifies that
+.Nm
+is being run from
+.Xr inetd 8 .
+.It Fl o Ar option
+Can be used to give options in the format used in the configuration file.
+This is useful for specifying options for which there is no separate
+command-line flag.
+For full details of the options, and their values, see
+.Xr sshd_config 5 .
+.It Fl p Ar port
+Specifies the port on which the server listens for connections
+(default 22).
+Multiple port options are permitted.
+Ports specified in the configuration file with the
+.Cm Port
+option are ignored when a command-line port is specified.
+Ports specified using the
+.Cm ListenAddress
+option override command-line ports.
+.It Fl q
+Quiet mode.
+Nothing is sent to the system log.
+Normally the beginning,
+authentication, and termination of each connection is logged.
+.It Fl T
+Extended test mode.
+Check the validity of the configuration file, output the effective configuration
+to stdout and then exit.
+Optionally,
+.Cm Match
+rules may be applied by specifying the connection parameters using one or more
+.Fl C
+options.
+.It Fl t
+Test mode.
+Only check the validity of the configuration file and sanity of the keys.
+This is useful for updating
+.Nm
+reliably as configuration options may change.
+.It Fl u Ar len
+This option is used to specify the size of the field
+in the
+.Li utmp
+structure that holds the remote host name.
+If the resolved host name is longer than
+.Ar len ,
+the dotted decimal value will be used instead.
+This allows hosts with very long host names that
+overflow this field to still be uniquely identified.
+Specifying
+.Fl u0
+indicates that only dotted decimal addresses
+should be put into the
+.Pa utmp
+file.
+.Fl u0
+may also be used to prevent
+.Nm
+from making DNS requests unless the authentication
+mechanism or configuration requires it.
+Authentication mechanisms that may require DNS include
+.Cm HostbasedAuthentication
+and using a
+.Cm from="pattern-list"
+option in a key file.
+Configuration options that require DNS include using a
+USER@HOST pattern in
+.Cm AllowUsers
+or
+.Cm DenyUsers .
+.El
+.Sh AUTHENTICATION
+The OpenSSH SSH daemon supports SSH protocol 2 only.
+Each host has a host-specific key,
+used to identify the host.
+Whenever a client connects, the daemon responds with its public
+host key.
+The client compares the
+host key against its own database to verify that it has not changed.
+Forward secrecy is provided through a Diffie-Hellman key agreement.
+This key agreement results in a shared session key.
+The rest of the session is encrypted using a symmetric cipher.
+The client selects the encryption algorithm
+to use from those offered by the server.
+Additionally, session integrity is provided
+through a cryptographic message authentication code (MAC).
+.Pp
+Finally, the server and the client enter an authentication dialog.
+The client tries to authenticate itself using
+host-based authentication,
+public key authentication,
+challenge-response authentication,
+or password authentication.
+.Pp
+Regardless of the authentication type, the account is checked to
+ensure that it is accessible.  An account is not accessible if it is
+locked, listed in
+.Cm DenyUsers
+or its group is listed in
+.Cm DenyGroups
+\&.  The definition of a locked account is system dependent. Some platforms
+have their own account database (eg AIX) and some modify the passwd field (
+.Ql \&*LK\&*
+on Solaris and UnixWare,
+.Ql \&*
+on HP-UX, containing
+.Ql Nologin
+on Tru64,
+a leading
+.Ql \&*LOCKED\&*
+on FreeBSD and a leading
+.Ql \&!
+on most Linuxes).
+If there is a requirement to disable password authentication
+for the account while allowing still public-key, then the passwd field
+should be set to something other than these values (eg
+.Ql NP
+or
+.Ql \&*NP\&*
+).
+.Pp
+If the client successfully authenticates itself, a dialog for
+preparing the session is entered.
+At this time the client may request
+things like allocating a pseudo-tty, forwarding X11 connections,
+forwarding TCP connections, or forwarding the authentication agent
+connection over the secure channel.
+.Pp
+After this, the client either requests a shell or execution of a command.
+The sides then enter session mode.
+In this mode, either side may send
+data at any time, and such data is forwarded to/from the shell or
+command on the server side, and the user terminal in the client side.
+.Pp
+When the user program terminates and all forwarded X11 and other
+connections have been closed, the server sends command exit status to
+the client, and both sides exit.
+.Sh LOGIN PROCESS
+When a user successfully logs in,
+.Nm
+does the following:
+.Bl -enum -offset indent
+.It
+If the login is on a tty, and no command has been specified,
+prints last login time and
+.Pa /etc/motd
+(unless prevented in the configuration file or by
+.Pa ~/.hushlogin ;
+see the
+.Sx FILES
+section).
+.It
+If the login is on a tty, records login time.
+.It
+Checks
+.Pa /etc/nologin ;
+if it exists, prints contents and quits
+(unless root).
+.It
+Changes to run with normal user privileges.
+.It
+Sets up basic environment.
+.It
+Reads the file
+.Pa ~/.ssh/environment ,
+if it exists, and users are allowed to change their environment.
+See the
+.Cm PermitUserEnvironment
+option in
+.Xr sshd_config 5 .
+.It
+Changes to user's home directory.
+.It
+If
+.Pa ~/.ssh/rc
+exists and the
+.Xr sshd_config 5
+.Cm PermitUserRC
+option is set, runs it; else if
+.Pa /etc/ssh/sshrc
+exists, runs
+it; otherwise runs xauth.
+The
+.Dq rc
+files are given the X11
+authentication protocol and cookie in standard input.
+See
+.Sx SSHRC ,
+below.
+.It
+Runs user's shell or command.
+All commands are run under the user's login shell as specified in the
+system password database.
+.El
+.Sh SSHRC
+If the file
+.Pa ~/.ssh/rc
+exists,
+.Xr sh 1
+runs it after reading the
+environment files but before starting the user's shell or command.
+It must not produce any output on stdout; stderr must be used
+instead.
+If X11 forwarding is in use, it will receive the "proto cookie" pair in
+its standard input (and
+.Ev DISPLAY
+in its environment).
+The script must call
+.Xr xauth 1
+because
+.Nm
+will not run xauth automatically to add X11 cookies.
+.Pp
+The primary purpose of this file is to run any initialization routines
+which may be needed before the user's home directory becomes
+accessible; AFS is a particular example of such an environment.
+.Pp
+This file will probably contain some initialization code followed by
+something similar to:
+.Bd -literal -offset 3n
+if read proto cookie && [ -n "$DISPLAY" ]; then
+	if [ `echo $DISPLAY | cut -c1-10` = 'localhost:' ]; then
+		# X11UseLocalhost=yes
+		echo add unix:`echo $DISPLAY |
+		    cut -c11-` $proto $cookie
+	else
+		# X11UseLocalhost=no
+		echo add $DISPLAY $proto $cookie
+	fi | xauth -q -
+fi
+.Ed
+.Pp
+If this file does not exist,
+.Pa /etc/ssh/sshrc
+is run, and if that
+does not exist either, xauth is used to add the cookie.
+.Sh AUTHORIZED_KEYS FILE FORMAT
+.Cm AuthorizedKeysFile
+specifies the files containing public keys for
+public key authentication;
+if this option is not specified, the default is
+.Pa ~/.ssh/authorized_keys
+and
+.Pa ~/.ssh/authorized_keys2 .
+Each line of the file contains one
+key (empty lines and lines starting with a
+.Ql #
+are ignored as
+comments).
+Public keys consist of the following space-separated fields:
+options, keytype, base64-encoded key, comment.
+The options field is optional.
+The supported key types are:
+.Pp
+.Bl -item -compact -offset indent
+.It
+sk-ecdsa-sha2-nistp256@openssh.com
+.It
+ecdsa-sha2-nistp256
+.It
+ecdsa-sha2-nistp384
+.It
+ecdsa-sha2-nistp521
+.It
+sk-ssh-ed25519@openssh.com
+.It
+ssh-ed25519
+.It
+ssh-dss
+.It
+ssh-rsa
+.El
+.Pp
+The comment field is not used for anything (but may be convenient for the
+user to identify the key).
+.Pp
+Note that lines in this file can be several hundred bytes long
+(because of the size of the public key encoding) up to a limit of
+8 kilobytes, which permits RSA keys up to 16 kilobits.
+You don't want to type them in; instead, copy the
+.Pa id_dsa.pub ,
+.Pa id_ecdsa.pub ,
+.Pa id_ecdsa_sk.pub ,
+.Pa id_ed25519.pub ,
+.Pa id_ed25519_sk.pub ,
+or the
+.Pa id_rsa.pub
+file and edit it.
+.Pp
+.Nm
+enforces a minimum RSA key modulus size of 1024 bits.
+.Pp
+The options (if present) consist of comma-separated option
+specifications.
+No spaces are permitted, except within double quotes.
+The following option specifications are supported (note
+that option keywords are case-insensitive):
+.Bl -tag -width Ds
+.It Cm agent-forwarding
+Enable authentication agent forwarding previously disabled by the
+.Cm restrict
+option.
+.It Cm cert-authority
+Specifies that the listed key is a certification authority (CA) that is
+trusted to validate signed certificates for user authentication.
+.Pp
+Certificates may encode access restrictions similar to these key options.
+If both certificate restrictions and key options are present, the most
+restrictive union of the two is applied.
+.It Cm command="command"
+Specifies that the command is executed whenever this key is used for
+authentication.
+The command supplied by the user (if any) is ignored.
+The command is run on a pty if the client requests a pty;
+otherwise it is run without a tty.
+If an 8-bit clean channel is required,
+one must not request a pty or should specify
+.Cm no-pty .
+A quote may be included in the command by quoting it with a backslash.
+.Pp
+This option might be useful
+to restrict certain public keys to perform just a specific operation.
+An example might be a key that permits remote backups but nothing else.
+Note that the client may specify TCP and/or X11
+forwarding unless they are explicitly prohibited, e.g. using the
+.Cm restrict
+key option.
+.Pp
+The command originally supplied by the client is available in the
+.Ev SSH_ORIGINAL_COMMAND
+environment variable.
+Note that this option applies to shell, command or subsystem execution.
+Also note that this command may be superseded by a
+.Xr sshd_config 5
+.Cm ForceCommand
+directive.
+.Pp
+If a command is specified and a forced-command is embedded in a certificate
+used for authentication, then the certificate will be accepted only if the
+two commands are identical.
+.It Cm environment="NAME=value"
+Specifies that the string is to be added to the environment when
+logging in using this key.
+Environment variables set this way
+override other default environment values.
+Multiple options of this type are permitted.
+Environment processing is disabled by default and is
+controlled via the
+.Cm PermitUserEnvironment
+option.
+.It Cm expiry-time="timespec"
+Specifies a time after which the key will not be accepted.
+The time may be specified as a YYYYMMDD date or a YYYYMMDDHHMM[SS] time
+in the system time-zone.
+.It Cm from="pattern-list"
+Specifies that in addition to public key authentication, either the canonical
+name of the remote host or its IP address must be present in the
+comma-separated list of patterns.
+See PATTERNS in
+.Xr ssh_config 5
+for more information on patterns.
+.Pp
+In addition to the wildcard matching that may be applied to hostnames or
+addresses, a
+.Cm from
+stanza may match IP addresses using CIDR address/masklen notation.
+.Pp
+The purpose of this option is to optionally increase security: public key
+authentication by itself does not trust the network or name servers or
+anything (but the key); however, if somebody somehow steals the key, the key
+permits an intruder to log in from anywhere in the world.
+This additional option makes using a stolen key more difficult (name
+servers and/or routers would have to be compromised in addition to
+just the key).
+.It Cm no-agent-forwarding
+Forbids authentication agent forwarding when this key is used for
+authentication.
+.It Cm no-port-forwarding
+Forbids TCP forwarding when this key is used for authentication.
+Any port forward requests by the client will return an error.
+This might be used, e.g. in connection with the
+.Cm command
+option.
+.It Cm no-pty
+Prevents tty allocation (a request to allocate a pty will fail).
+.It Cm no-user-rc
+Disables execution of
+.Pa ~/.ssh/rc .
+.It Cm no-X11-forwarding
+Forbids X11 forwarding when this key is used for authentication.
+Any X11 forward requests by the client will return an error.
+.It Cm permitlisten="[host:]port"
+Limit remote port forwarding with the
+.Xr ssh 1
+.Fl R
+option such that it may only listen on the specified host (optional) and port.
+IPv6 addresses can be specified by enclosing the address in square brackets.
+Multiple
+.Cm permitlisten
+options may be applied separated by commas.
+Hostnames may include wildcards as described in the PATTERNS section in
+.Xr ssh_config 5 .
+A port specification of
+.Cm *
+matches any port.
+Note that the setting of
+.Cm GatewayPorts
+may further restrict listen addresses.
+Note that
+.Xr ssh 1
+will send a hostname of
+.Dq localhost
+if a listen host was not specified when the forwarding was requested, and
+that this name is treated differently to the explicit localhost addresses
+.Dq 127.0.0.1
+and
+.Dq ::1 .
+.It Cm permitopen="host:port"
+Limit local port forwarding with the
+.Xr ssh 1
+.Fl L
+option such that it may only connect to the specified host and port.
+IPv6 addresses can be specified by enclosing the address in square brackets.
+Multiple
+.Cm permitopen
+options may be applied separated by commas.
+No pattern matching or name lookup is performed on the
+specified hostnames, they must be literal host names and/or addresses.
+A port specification of
+.Cm *
+matches any port.
+.It Cm port-forwarding
+Enable port forwarding previously disabled by the
+.Cm restrict
+option.
+.It Cm principals="principals"
+On a
+.Cm cert-authority
+line, specifies allowed principals for certificate authentication as a
+comma-separated list.
+At least one name from the list must appear in the certificate's
+list of principals for the certificate to be accepted.
+This option is ignored for keys that are not marked as trusted certificate
+signers using the
+.Cm cert-authority
+option.
+.It Cm pty
+Permits tty allocation previously disabled by the
+.Cm restrict
+option.
+.It Cm no-touch-required
+Do not require demonstration of user presence
+for signatures made using this key.
+This option only makes sense for the FIDO authenticator algorithms
+.Cm ecdsa-sk
+and
+.Cm ed25519-sk .
+.It Cm verify-required
+Require that signatures made using this key attest that they verified
+the user, e.g. via a PIN.
+This option only makes sense for the FIDO authenticator algorithms
+.Cm ecdsa-sk
+and
+.Cm ed25519-sk .
+.It Cm restrict
+Enable all restrictions, i.e. disable port, agent and X11 forwarding,
+as well as disabling PTY allocation
+and execution of
+.Pa ~/.ssh/rc .
+If any future restriction capabilities are added to authorized_keys files
+they will be included in this set.
+.It Cm tunnel="n"
+Force a
+.Xr tun 4
+device on the server.
+Without this option, the next available device will be used if
+the client requests a tunnel.
+.It Cm user-rc
+Enables execution of
+.Pa ~/.ssh/rc
+previously disabled by the
+.Cm restrict
+option.
+.It Cm X11-forwarding
+Permits X11 forwarding previously disabled by the
+.Cm restrict
+option.
+.El
+.Pp
+An example authorized_keys file:
+.Bd -literal -offset 3n
+# Comments allowed at start of line
+ssh-rsa AAAAB3Nza...LiPk== user@example.net
+from="*.sales.example.net,!pc.sales.example.net" ssh-rsa
+AAAAB2...19Q== john@example.net
+command="dump /home",no-pty,no-port-forwarding ssh-rsa
+AAAAC3...51R== example.net
+permitopen="192.0.2.1:80",permitopen="192.0.2.2:25" ssh-rsa
+AAAAB5...21S==
+permitlisten="localhost:8080",permitopen="localhost:22000" ssh-rsa
+AAAAB5...21S==
+tunnel="0",command="sh /etc/netstart tun0" ssh-rsa AAAA...==
+jane@example.net
+restrict,command="uptime" ssh-rsa AAAA1C8...32Tv==
+user@example.net
+restrict,pty,command="nethack" ssh-rsa AAAA1f8...IrrC5==
+user@example.net
+no-touch-required sk-ecdsa-sha2-nistp256@openssh.com AAAAInN...Ko==
+user@example.net
+.Ed
+.Sh SSH_KNOWN_HOSTS FILE FORMAT
+The
+.Pa /etc/ssh/ssh_known_hosts
+and
+.Pa ~/.ssh/known_hosts
+files contain host public keys for all known hosts.
+The global file should
+be prepared by the administrator (optional), and the per-user file is
+maintained automatically: whenever the user connects to an unknown host,
+its key is added to the per-user file.
+.Pp
+Each line in these files contains the following fields: markers (optional),
+hostnames, keytype, base64-encoded key, comment.
+The fields are separated by spaces.
+.Pp
+The marker is optional, but if it is present then it must be one of
+.Dq @cert-authority ,
+to indicate that the line contains a certification authority (CA) key,
+or
+.Dq @revoked ,
+to indicate that the key contained on the line is revoked and must not ever
+be accepted.
+Only one marker should be used on a key line.
+.Pp
+Hostnames is a comma-separated list of patterns
+.Pf ( Ql *
+and
+.Ql \&?
+act as
+wildcards); each pattern in turn is matched against the host name.
+When
+.Nm sshd
+is authenticating a client, such as when using
+.Cm HostbasedAuthentication ,
+this will be the canonical client host name.
+When
+.Xr ssh 1
+is authenticating a server, this will be the host name
+given by the user, the value of the
+.Xr ssh 1
+.Cm HostkeyAlias
+if it was specified, or the canonical server hostname if the
+.Xr ssh 1
+.Cm CanonicalizeHostname
+option was used.
+.Pp
+A pattern may also be preceded by
+.Ql \&!
+to indicate negation: if the host name matches a negated
+pattern, it is not accepted (by that line) even if it matched another
+pattern on the line.
+A hostname or address may optionally be enclosed within
+.Ql \&[
+and
+.Ql \&]
+brackets then followed by
+.Ql \&:
+and a non-standard port number.
+.Pp
+Alternately, hostnames may be stored in a hashed form which hides host names
+and addresses should the file's contents be disclosed.
+Hashed hostnames start with a
+.Ql |
+character.
+Only one hashed hostname may appear on a single line and none of the above
+negation or wildcard operators may be applied.
+.Pp
+The keytype and base64-encoded key are taken directly from the host key; they
+can be obtained, for example, from
+.Pa /etc/ssh/ssh_host_rsa_key.pub .
+The optional comment field continues to the end of the line, and is not used.
+.Pp
+Lines starting with
+.Ql #
+and empty lines are ignored as comments.
+.Pp
+When performing host authentication, authentication is accepted if any
+matching line has the proper key; either one that matches exactly or,
+if the server has presented a certificate for authentication, the key
+of the certification authority that signed the certificate.
+For a key to be trusted as a certification authority, it must use the
+.Dq @cert-authority
+marker described above.
+.Pp
+The known hosts file also provides a facility to mark keys as revoked,
+for example when it is known that the associated private key has been
+stolen.
+Revoked keys are specified by including the
+.Dq @revoked
+marker at the beginning of the key line, and are never accepted for
+authentication or as certification authorities, but instead will
+produce a warning from
+.Xr ssh 1
+when they are encountered.
+.Pp
+It is permissible (but not
+recommended) to have several lines or different host keys for the same
+names.
+This will inevitably happen when short forms of host names
+from different domains are put in the file.
+It is possible
+that the files contain conflicting information; authentication is
+accepted if valid information can be found from either file.
+.Pp
+Note that the lines in these files are typically hundreds of characters
+long, and you definitely don't want to type in the host keys by hand.
+Rather, generate them by a script,
+.Xr ssh-keyscan 1
+or by taking, for example,
+.Pa /etc/ssh/ssh_host_rsa_key.pub
+and adding the host names at the front.
+.Xr ssh-keygen 1
+also offers some basic automated editing for
+.Pa ~/.ssh/known_hosts
+including removing hosts matching a host name and converting all host
+names to their hashed representations.
+.Pp
+An example ssh_known_hosts file:
+.Bd -literal -offset 3n
+# Comments allowed at start of line
+closenet,...,192.0.2.53 1024 37 159...93 closenet.example.net
+cvs.example.net,192.0.2.10 ssh-rsa AAAA1234.....=
+# A hashed hostname
+|1|JfKTdBh7rNbXkVAQCRp4OQoPfmI=|USECr3SWf1JUPsms5AqfD5QfxkM= ssh-rsa
+AAAA1234.....=
+# A revoked key
+@revoked * ssh-rsa AAAAB5W...
+# A CA key, accepted for any host in *.mydomain.com or *.mydomain.org
+@cert-authority *.mydomain.org,*.mydomain.com ssh-rsa AAAAB5W...
+.Ed
+.Sh FILES
+.Bl -tag -width Ds -compact
+.It Pa ~/.hushlogin
+This file is used to suppress printing the last login time and
+.Pa /etc/motd ,
+if
+.Cm PrintLastLog
+and
+.Cm PrintMotd ,
+respectively,
+are enabled.
+It does not suppress printing of the banner specified by
+.Cm Banner .
+.Pp
+.It Pa ~/.rhosts
+This file is used for host-based authentication (see
+.Xr ssh 1
+for more information).
+On some machines this file may need to be
+world-readable if the user's home directory is on an NFS partition,
+because
+.Nm
+reads it as root.
+Additionally, this file must be owned by the user,
+and must not have write permissions for anyone else.
+The recommended
+permission for most machines is read/write for the user, and not
+accessible by others.
+.Pp
+.It Pa ~/.shosts
+This file is used in exactly the same way as
+.Pa .rhosts ,
+but allows host-based authentication without permitting login with
+rlogin/rsh.
+.Pp
+.It Pa ~/.ssh/
+This directory is the default location for all user-specific configuration
+and authentication information.
+There is no general requirement to keep the entire contents of this directory
+secret, but the recommended permissions are read/write/execute for the user,
+and not accessible by others.
+.Pp
+.It Pa ~/.ssh/authorized_keys
+Lists the public keys (DSA, ECDSA, Ed25519, RSA)
+that can be used for logging in as this user.
+The format of this file is described above.
+The content of the file is not highly sensitive, but the recommended
+permissions are read/write for the user, and not accessible by others.
+.Pp
+If this file, the
+.Pa ~/.ssh
+directory, or the user's home directory are writable
+by other users, then the file could be modified or replaced by unauthorized
+users.
+In this case,
+.Nm
+will not allow it to be used unless the
+.Cm StrictModes
+option has been set to
+.Dq no .
+.Pp
+.It Pa ~/.ssh/environment
+This file is read into the environment at login (if it exists).
+It can only contain empty lines, comment lines (that start with
+.Ql # ) ,
+and assignment lines of the form name=value.
+The file should be writable
+only by the user; it need not be readable by anyone else.
+Environment processing is disabled by default and is
+controlled via the
+.Cm PermitUserEnvironment
+option.
+.Pp
+.It Pa ~/.ssh/known_hosts
+Contains a list of host keys for all hosts the user has logged into
+that are not already in the systemwide list of known host keys.
+The format of this file is described above.
+This file should be writable only by root/the owner and
+can, but need not be, world-readable.
+.Pp
+.It Pa ~/.ssh/rc
+Contains initialization routines to be run before
+the user's home directory becomes accessible.
+This file should be writable only by the user, and need not be
+readable by anyone else.
+.Pp
+.It Pa /etc/hosts.allow
+.It Pa /etc/hosts.deny
+Access controls that should be enforced by tcp-wrappers are defined here.
+Further details are described in
+.Xr hosts_access 5 .
+.Pp
+.It Pa /etc/hosts.equiv
+This file is for host-based authentication (see
+.Xr ssh 1 ) .
+It should only be writable by root.
+.Pp
+.It Pa /etc/moduli
+Contains Diffie-Hellman groups used for the "Diffie-Hellman Group Exchange"
+key exchange method.
+The file format is described in
+.Xr moduli 5 .
+If no usable groups are found in this file then fixed internal groups will
+be used.
+.Pp
+.It Pa /etc/motd
+See
+.Xr motd 5 .
+.Pp
+.It Pa /etc/nologin
+If this file exists,
+.Nm
+refuses to let anyone except root log in.
+The contents of the file
+are displayed to anyone trying to log in, and non-root connections are
+refused.
+The file should be world-readable.
+.Pp
+.It Pa /etc/shosts.equiv
+This file is used in exactly the same way as
+.Pa hosts.equiv ,
+but allows host-based authentication without permitting login with
+rlogin/rsh.
+.Pp
+.It Pa /etc/ssh/ssh_host_ecdsa_key
+.It Pa /etc/ssh/ssh_host_ed25519_key
+.It Pa /etc/ssh/ssh_host_rsa_key
+These files contain the private parts of the host keys.
+These files should only be owned by root, readable only by root, and not
+accessible to others.
+Note that
+.Nm
+does not start if these files are group/world-accessible.
+.Pp
+.It Pa /etc/ssh/ssh_host_ecdsa_key.pub
+.It Pa /etc/ssh/ssh_host_ed25519_key.pub
+.It Pa /etc/ssh/ssh_host_rsa_key.pub
+These files contain the public parts of the host keys.
+These files should be world-readable but writable only by
+root.
+Their contents should match the respective private parts.
+These files are not
+really used for anything; they are provided for the convenience of
+the user so their contents can be copied to known hosts files.
+These files are created using
+.Xr ssh-keygen 1 .
+.Pp
+.It Pa /etc/ssh/ssh_known_hosts
+Systemwide list of known host keys.
+This file should be prepared by the
+system administrator to contain the public host keys of all machines in the
+organization.
+The format of this file is described above.
+This file should be writable only by root/the owner and
+should be world-readable.
+.Pp
+.It Pa /etc/ssh/sshd_config
+Contains configuration data for
+.Nm sshd .
+The file format and configuration options are described in
+.Xr sshd_config 5 .
+.Pp
+.It Pa /etc/ssh/sshrc
+Similar to
+.Pa ~/.ssh/rc ,
+it can be used to specify
+machine-specific login-time initializations globally.
+This file should be writable only by root, and should be world-readable.
+.Pp
+.It Pa /var/empty
+.Xr chroot 2
+directory used by
+.Nm
+during privilege separation in the pre-authentication phase.
+The directory should not contain any files and must be owned by root
+and not group or world-writable.
+.Pp
+.It Pa /var/run/sshd.pid
+Contains the process ID of the
+.Nm
+listening for connections (if there are several daemons running
+concurrently for different ports, this contains the process ID of the one
+started last).
+The content of this file is not sensitive; it can be world-readable.
+.El
+.Sh SEE ALSO
+.Xr scp 1 ,
+.Xr sftp 1 ,
+.Xr ssh 1 ,
+.Xr ssh-add 1 ,
+.Xr ssh-agent 1 ,
+.Xr ssh-keygen 1 ,
+.Xr ssh-keyscan 1 ,
+.Xr chroot 2 ,
+.Xr hosts_access 5 ,
+.Xr login.conf 5 ,
+.Xr moduli 5 ,
+.Xr sshd_config 5 ,
+.Xr inetd 8 ,
+.Xr sftp-server 8
+.Sh AUTHORS
+OpenSSH is a derivative of the original and free
+ssh 1.2.12 release by Tatu Ylonen.
+Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos,
+Theo de Raadt and Dug Song
+removed many bugs, re-added newer features and
+created OpenSSH.
+Markus Friedl contributed the support for SSH
+protocol versions 1.5 and 2.0.
+Niels Provos and Markus Friedl contributed support
+for privilege separation.
Index: openssh-8.5p1-new/sshd.c
===================================================================
--- openssh-8.5p1-new/sshd.c	(nonexistent)
+++ openssh-8.5p1-new/sshd.c	(revision 5)
@@ -0,0 +1,2452 @@
+/* $OpenBSD: sshd.c,v 1.570 2021/02/05 02:20:23 dtucker Exp $ */
+/*
+ * Author: Tatu Ylonen <ylo@cs.hut.fi>
+ * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
+ *                    All rights reserved
+ * This program is the ssh daemon.  It listens for connections from clients,
+ * and performs authentication, executes use commands or shell, and forwards
+ * information to/from the application to the user client over an encrypted
+ * connection.  This can also handle forwarding of X11, TCP/IP, and
+ * authentication agent connections.
+ *
+ * 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".
+ *
+ * SSH2 implementation:
+ * Privilege Separation:
+ *
+ * Copyright (c) 2000, 2001, 2002 Markus Friedl.  All rights reserved.
+ * Copyright (c) 2002 Niels Provos.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include "openbsd-compat/sys-tree.h"
+#include "openbsd-compat/sys-queue.h"
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+#include <grp.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+
+#ifdef WITH_OPENSSL
+#include <openssl/dh.h>
+#include <openssl/bn.h>
+#include <openssl/rand.h>
+#include "openbsd-compat/openssl-compat.h"
+#endif
+
+#ifdef HAVE_SECUREWARE
+#include <sys/security.h>
+#include <prot.h>
+#endif
+
+#include "xmalloc.h"
+#include "ssh.h"
+#include "ssh2.h"
+#include "sshpty.h"
+#include "packet.h"
+#include "log.h"
+#include "sshbuf.h"
+#include "misc.h"
+#include "match.h"
+#include "servconf.h"
+#include "uidswap.h"
+#include "compat.h"
+#include "cipher.h"
+#include "digest.h"
+#include "sshkey.h"
+#include "kex.h"
+#include "myproposal.h"
+#include "authfile.h"
+#include "pathnames.h"
+#include "atomicio.h"
+#include "canohost.h"
+#include "hostfile.h"
+#include "auth.h"
+#include "authfd.h"
+#include "msg.h"
+#include "dispatch.h"
+#include "channels.h"
+#include "session.h"
+#include "monitor.h"
+#ifdef GSSAPI
+#include "ssh-gss.h"
+#endif
+#include "monitor_wrap.h"
+#include "ssh-sandbox.h"
+#include "auth-options.h"
+#include "version.h"
+#include "ssherr.h"
+#include "sk-api.h"
+#include "srclimit.h"
+
+#ifdef LIBWRAP
+#include <tcpd.h>
+#include <syslog.h>
+int allow_severity;
+int deny_severity;
+#endif /* LIBWRAP */
+
+/* Re-exec fds */
+#define REEXEC_DEVCRYPTO_RESERVED_FD	(STDERR_FILENO + 1)
+#define REEXEC_STARTUP_PIPE_FD		(STDERR_FILENO + 2)
+#define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 3)
+#define REEXEC_MIN_FREE_FD		(STDERR_FILENO + 4)
+
+extern char *__progname;
+
+/* Server configuration options. */
+ServerOptions options;
+
+/* Name of the server configuration file. */
+char *config_file_name = _PATH_SERVER_CONFIG_FILE;
+
+/*
+ * Debug mode flag.  This can be set on the command line.  If debug
+ * mode is enabled, extra debugging output will be sent to the system
+ * log, the daemon will not go to background, and will exit after processing
+ * the first connection.
+ */
+int debug_flag = 0;
+
+/*
+ * Indicating that the daemon should only test the configuration and keys.
+ * If test_flag > 1 ("-T" flag), then sshd will also dump the effective
+ * configuration, optionally using connection information provided by the
+ * "-C" flag.
+ */
+static int test_flag = 0;
+
+/* Flag indicating that the daemon is being started from inetd. */
+static int inetd_flag = 0;
+
+/* Flag indicating that sshd should not detach and become a daemon. */
+static int no_daemon_flag = 0;
+
+/* debug goes to stderr unless inetd_flag is set */
+static int log_stderr = 0;
+
+/* Saved arguments to main(). */
+static char **saved_argv;
+static int saved_argc;
+
+/* re-exec */
+static int rexeced_flag = 0;
+static int rexec_flag = 1;
+static int rexec_argc = 0;
+static char **rexec_argv;
+
+/*
+ * The sockets that the server is listening; this is used in the SIGHUP
+ * signal handler.
+ */
+#define	MAX_LISTEN_SOCKS	16
+static int listen_socks[MAX_LISTEN_SOCKS];
+static int num_listen_socks = 0;
+
+/* Daemon's agent connection */
+int auth_sock = -1;
+static int have_agent = 0;
+
+/*
+ * Any really sensitive data in the application is contained in this
+ * structure. The idea is that this structure could be locked into memory so
+ * that the pages do not get written into swap.  However, there are some
+ * problems. The private key contains BIGNUMs, and we do not (in principle)
+ * have access to the internals of them, and locking just the structure is
+ * not very useful.  Currently, memory locking is not implemented.
+ */
+struct {
+	struct sshkey	**host_keys;		/* all private host keys */
+	struct sshkey	**host_pubkeys;		/* all public host keys */
+	struct sshkey	**host_certificates;	/* all public host certificates */
+	int		have_ssh2_key;
+} sensitive_data;
+
+/* This is set to true when a signal is received. */
+static volatile sig_atomic_t received_sighup = 0;
+static volatile sig_atomic_t received_sigterm = 0;
+
+/* record remote hostname or ip */
+u_int utmp_len = HOST_NAME_MAX+1;
+
+/*
+ * startup_pipes/flags are used for tracking children of the listening sshd
+ * process early in their lifespans. This tracking is needed for three things:
+ *
+ * 1) Implementing the MaxStartups limit of concurrent unauthenticated
+ *    connections.
+ * 2) Avoiding a race condition for SIGHUP processing, where child processes
+ *    may have listen_socks open that could collide with main listener process
+ *    after it restarts.
+ * 3) Ensuring that rexec'd sshd processes have received their initial state
+ *    from the parent listen process before handling SIGHUP.
+ *
+ * Child processes signal that they have completed closure of the listen_socks
+ * and (if applicable) received their rexec state by sending a char over their
+ * sock. Child processes signal that authentication has completed by closing
+ * the sock (or by exiting).
+ */
+static int *startup_pipes = NULL;
+static int *startup_flags = NULL;	/* Indicates child closed listener */
+static int startup_pipe = -1;		/* in child */
+
+/* variables used for privilege separation */
+int use_privsep = -1;
+struct monitor *pmonitor = NULL;
+int privsep_is_preauth = 1;
+static int privsep_chroot = 1;
+
+/* global connection state and authentication contexts */
+Authctxt *the_authctxt = NULL;
+struct ssh *the_active_state;
+
+/* global key/cert auth options. XXX move to permanent ssh->authctxt? */
+struct sshauthopt *auth_opts = NULL;
+
+/* sshd_config buffer */
+struct sshbuf *cfg;
+
+/* Included files from the configuration file */
+struct include_list includes = TAILQ_HEAD_INITIALIZER(includes);
+
+/* message to be displayed after login */
+struct sshbuf *loginmsg;
+
+/* Unprivileged user */
+struct passwd *privsep_pw = NULL;
+
+/* Prototypes for various functions defined later in this file. */
+void destroy_sensitive_data(void);
+void demote_sensitive_data(void);
+static void do_ssh2_kex(struct ssh *);
+
+static char *listener_proctitle;
+
+/*
+ * Close all listening sockets
+ */
+static void
+close_listen_socks(void)
+{
+	int i;
+
+	for (i = 0; i < num_listen_socks; i++)
+		close(listen_socks[i]);
+	num_listen_socks = -1;
+}
+
+static void
+close_startup_pipes(void)
+{
+	int i;
+
+	if (startup_pipes)
+		for (i = 0; i < options.max_startups; i++)
+			if (startup_pipes[i] != -1)
+				close(startup_pipes[i]);
+}
+
+/*
+ * Signal handler for SIGHUP.  Sshd execs itself when it receives SIGHUP;
+ * the effect is to reread the configuration file (and to regenerate
+ * the server key).
+ */
+
+/*ARGSUSED*/
+static void
+sighup_handler(int sig)
+{
+	received_sighup = 1;
+}
+
+/*
+ * Called from the main program after receiving SIGHUP.
+ * Restarts the server.
+ */
+static void
+sighup_restart(void)
+{
+	logit("Received SIGHUP; restarting.");
+	if (options.pid_file != NULL)
+		unlink(options.pid_file);
+	platform_pre_restart();
+	close_listen_socks();
+	close_startup_pipes();
+	ssh_signal(SIGHUP, SIG_IGN); /* will be restored after exec */
+	execv(saved_argv[0], saved_argv);
+	logit("RESTART FAILED: av[0]='%.100s', error: %.100s.", saved_argv[0],
+	    strerror(errno));
+	exit(1);
+}
+
+/*
+ * Generic signal handler for terminating signals in the master daemon.
+ */
+/*ARGSUSED*/
+static void
+sigterm_handler(int sig)
+{
+	received_sigterm = sig;
+}
+
+/*
+ * SIGCHLD handler.  This is called whenever a child dies.  This will then
+ * reap any zombies left by exited children.
+ */
+/*ARGSUSED*/
+static void
+main_sigchld_handler(int sig)
+{
+	int save_errno = errno;
+	pid_t pid;
+	int status;
+
+	while ((pid = waitpid(-1, &status, WNOHANG)) > 0 ||
+	    (pid == -1 && errno == EINTR))
+		;
+	errno = save_errno;
+}
+
+/*
+ * Signal handler for the alarm after the login grace period has expired.
+ */
+/*ARGSUSED*/
+static void
+grace_alarm_handler(int sig)
+{
+	if (use_privsep && pmonitor != NULL && pmonitor->m_pid > 0)
+		kill(pmonitor->m_pid, SIGALRM);
+
+	/*
+	 * Try to kill any processes that we have spawned, E.g. authorized
+	 * keys command helpers.
+	 */
+	if (getpgid(0) == getpid()) {
+		ssh_signal(SIGTERM, SIG_IGN);
+		kill(0, SIGTERM);
+	}
+
+	/* XXX pre-format ipaddr/port so we don't need to access active_state */
+	/* Log error and exit. */
+	sigdie("Timeout before authentication for %s port %d",
+	    ssh_remote_ipaddr(the_active_state),
+	    ssh_remote_port(the_active_state));
+}
+
+/* Destroy the host and server keys.  They will no longer be needed. */
+void
+destroy_sensitive_data(void)
+{
+	u_int i;
+
+	for (i = 0; i < options.num_host_key_files; i++) {
+		if (sensitive_data.host_keys[i]) {
+			sshkey_free(sensitive_data.host_keys[i]);
+			sensitive_data.host_keys[i] = NULL;
+		}
+		if (sensitive_data.host_certificates[i]) {
+			sshkey_free(sensitive_data.host_certificates[i]);
+			sensitive_data.host_certificates[i] = NULL;
+		}
+	}
+}
+
+/* Demote private to public keys for network child */
+void
+demote_sensitive_data(void)
+{
+	struct sshkey *tmp;
+	u_int i;
+	int r;
+
+	for (i = 0; i < options.num_host_key_files; i++) {
+		if (sensitive_data.host_keys[i]) {
+			if ((r = sshkey_from_private(
+			    sensitive_data.host_keys[i], &tmp)) != 0)
+				fatal_r(r, "could not demote host %s key",
+				    sshkey_type(sensitive_data.host_keys[i]));
+			sshkey_free(sensitive_data.host_keys[i]);
+			sensitive_data.host_keys[i] = tmp;
+		}
+		/* Certs do not need demotion */
+	}
+}
+
+static void
+reseed_prngs(void)
+{
+	u_int32_t rnd[256];
+
+#ifdef WITH_OPENSSL
+	RAND_poll();
+#endif
+	arc4random_stir(); /* noop on recent arc4random() implementations */
+	arc4random_buf(rnd, sizeof(rnd)); /* let arc4random notice PID change */
+
+#ifdef WITH_OPENSSL
+	RAND_seed(rnd, sizeof(rnd));
+	/* give libcrypto a chance to notice the PID change */
+	if ((RAND_bytes((u_char *)rnd, 1)) != 1)
+		fatal("%s: RAND_bytes failed", __func__);
+#endif
+
+	explicit_bzero(rnd, sizeof(rnd));
+}
+
+static void
+privsep_preauth_child(void)
+{
+	gid_t gidset[1];
+
+	/* Enable challenge-response authentication for privilege separation */
+	privsep_challenge_enable();
+
+#ifdef GSSAPI
+	/* Cache supported mechanism OIDs for later use */
+	ssh_gssapi_prepare_supported_oids();
+#endif
+
+	reseed_prngs();
+
+	/* Demote the private keys to public keys. */
+	demote_sensitive_data();
+
+	/* Demote the child */
+	if (privsep_chroot) {
+		/* Change our root directory */
+		if (chroot(_PATH_PRIVSEP_CHROOT_DIR) == -1)
+			fatal("chroot(\"%s\"): %s", _PATH_PRIVSEP_CHROOT_DIR,
+			    strerror(errno));
+		if (chdir("/") == -1)
+			fatal("chdir(\"/\"): %s", strerror(errno));
+
+		/* Drop our privileges */
+		debug3("privsep user:group %u:%u", (u_int)privsep_pw->pw_uid,
+		    (u_int)privsep_pw->pw_gid);
+		gidset[0] = privsep_pw->pw_gid;
+		if (setgroups(1, gidset) == -1)
+			fatal("setgroups: %.100s", strerror(errno));
+		permanently_set_uid(privsep_pw);
+	}
+}
+
+static int
+privsep_preauth(struct ssh *ssh)
+{
+	int status, r;
+	pid_t pid;
+	struct ssh_sandbox *box = NULL;
+
+	/* Set up unprivileged child process to deal with network data */
+	pmonitor = monitor_init();
+	/* Store a pointer to the kex for later rekeying */
+	pmonitor->m_pkex = &ssh->kex;
+
+	if (use_privsep == PRIVSEP_ON)
+		box = ssh_sandbox_init(pmonitor);
+	pid = fork();
+	if (pid == -1) {
+		fatal("fork of unprivileged child failed");
+	} else if (pid != 0) {
+		debug2("Network child is on pid %ld", (long)pid);
+
+		pmonitor->m_pid = pid;
+		if (have_agent) {
+			r = ssh_get_authentication_socket(&auth_sock);
+			if (r != 0) {
+				error_r(r, "Could not get agent socket");
+				have_agent = 0;
+			}
+		}
+		if (box != NULL)
+			ssh_sandbox_parent_preauth(box, pid);
+		monitor_child_preauth(ssh, pmonitor);
+
+		/* Wait for the child's exit status */
+		while (waitpid(pid, &status, 0) == -1) {
+			if (errno == EINTR)
+				continue;
+			pmonitor->m_pid = -1;
+			fatal_f("waitpid: %s", strerror(errno));
+		}
+		privsep_is_preauth = 0;
+		pmonitor->m_pid = -1;
+		if (WIFEXITED(status)) {
+			if (WEXITSTATUS(status) != 0)
+				fatal_f("preauth child exited with status %d",
+				    WEXITSTATUS(status));
+		} else if (WIFSIGNALED(status))
+			fatal_f("preauth child terminated by signal %d",
+			    WTERMSIG(status));
+		if (box != NULL)
+			ssh_sandbox_parent_finish(box);
+		return 1;
+	} else {
+		/* child */
+		close(pmonitor->m_sendfd);
+		close(pmonitor->m_log_recvfd);
+
+		/* Arrange for logging to be sent to the monitor */
+		set_log_handler(mm_log_handler, pmonitor);
+
+		privsep_preauth_child();
+		setproctitle("%s", "[net]");
+		if (box != NULL)
+			ssh_sandbox_child(box);
+
+		return 0;
+	}
+}
+
+static void
+privsep_postauth(struct ssh *ssh, Authctxt *authctxt)
+{
+#ifdef DISABLE_FD_PASSING
+	if (1) {
+#else
+	if (authctxt->pw->pw_uid == 0) {
+#endif
+		/* File descriptor passing is broken or root login */
+		use_privsep = 0;
+		goto skip;
+	}
+
+	/* New socket pair */
+	monitor_reinit(pmonitor);
+
+	pmonitor->m_pid = fork();
+	if (pmonitor->m_pid == -1)
+		fatal("fork of unprivileged child failed");
+	else if (pmonitor->m_pid != 0) {
+		verbose("User child is on pid %ld", (long)pmonitor->m_pid);
+		sshbuf_reset(loginmsg);
+		monitor_clear_keystate(ssh, pmonitor);
+		monitor_child_postauth(ssh, pmonitor);
+
+		/* NEVERREACHED */
+		exit(0);
+	}
+
+	/* child */
+
+	close(pmonitor->m_sendfd);
+	pmonitor->m_sendfd = -1;
+
+	/* Demote the private keys to public keys. */
+	demote_sensitive_data();
+
+	reseed_prngs();
+
+	/* Drop privileges */
+	do_setusercontext(authctxt->pw);
+
+ skip:
+	/* It is safe now to apply the key state */
+	monitor_apply_keystate(ssh, pmonitor);
+
+	/*
+	 * Tell the packet layer that authentication was successful, since
+	 * this information is not part of the key state.
+	 */
+	ssh_packet_set_authenticated(ssh);
+}
+
+static void
+append_hostkey_type(struct sshbuf *b, const char *s)
+{
+	int r;
+
+	if (match_pattern_list(s, options.hostkeyalgorithms, 0) != 1) {
+		debug3_f("%s key not permitted by HostkeyAlgorithms", s);
+		return;
+	}
+	if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) > 0 ? "," : "", s)) != 0)
+		fatal_fr(r, "sshbuf_putf");
+}
+
+static char *
+list_hostkey_types(void)
+{
+	struct sshbuf *b;
+	struct sshkey *key;
+	char *ret;
+	u_int i;
+
+	if ((b = sshbuf_new()) == NULL)
+		fatal_f("sshbuf_new failed");
+	for (i = 0; i < options.num_host_key_files; i++) {
+		key = sensitive_data.host_keys[i];
+		if (key == NULL)
+			key = sensitive_data.host_pubkeys[i];
+		if (key == NULL)
+			continue;
+		switch (key->type) {
+		case KEY_RSA:
+			/* for RSA we also support SHA2 signatures */
+			append_hostkey_type(b, "rsa-sha2-512");
+			append_hostkey_type(b, "rsa-sha2-256");
+			/* FALLTHROUGH */
+		case KEY_DSA:
+		case KEY_ECDSA:
+		case KEY_ED25519:
+		case KEY_ECDSA_SK:
+		case KEY_ED25519_SK:
+		case KEY_XMSS:
+			append_hostkey_type(b, sshkey_ssh_name(key));
+			break;
+		}
+		/* If the private key has a cert peer, then list that too */
+		key = sensitive_data.host_certificates[i];
+		if (key == NULL)
+			continue;
+		switch (key->type) {
+		case KEY_RSA_CERT:
+			/* for RSA we also support SHA2 signatures */
+			append_hostkey_type(b,
+			    "rsa-sha2-512-cert-v01@openssh.com");
+			append_hostkey_type(b,
+			    "rsa-sha2-256-cert-v01@openssh.com");
+			/* FALLTHROUGH */
+		case KEY_DSA_CERT:
+		case KEY_ECDSA_CERT:
+		case KEY_ED25519_CERT:
+		case KEY_ECDSA_SK_CERT:
+		case KEY_ED25519_SK_CERT:
+		case KEY_XMSS_CERT:
+			append_hostkey_type(b, sshkey_ssh_name(key));
+			break;
+		}
+	}
+	if ((ret = sshbuf_dup_string(b)) == NULL)
+		fatal_f("sshbuf_dup_string failed");
+	sshbuf_free(b);
+	debug_f("%s", ret);
+	return ret;
+}
+
+static struct sshkey *
+get_hostkey_by_type(int type, int nid, int need_private, struct ssh *ssh)
+{
+	u_int i;
+	struct sshkey *key;
+
+	for (i = 0; i < options.num_host_key_files; i++) {
+		switch (type) {
+		case KEY_RSA_CERT:
+		case KEY_DSA_CERT:
+		case KEY_ECDSA_CERT:
+		case KEY_ED25519_CERT:
+		case KEY_ECDSA_SK_CERT:
+		case KEY_ED25519_SK_CERT:
+		case KEY_XMSS_CERT:
+			key = sensitive_data.host_certificates[i];
+			break;
+		default:
+			key = sensitive_data.host_keys[i];
+			if (key == NULL && !need_private)
+				key = sensitive_data.host_pubkeys[i];
+			break;
+		}
+		if (key == NULL || key->type != type)
+			continue;
+		switch (type) {
+		case KEY_ECDSA:
+		case KEY_ECDSA_SK:
+		case KEY_ECDSA_CERT:
+		case KEY_ECDSA_SK_CERT:
+			if (key->ecdsa_nid != nid)
+				continue;
+			/* FALLTHROUGH */
+		default:
+			return need_private ?
+			    sensitive_data.host_keys[i] : key;
+		}
+	}
+	return NULL;
+}
+
+struct sshkey *
+get_hostkey_public_by_type(int type, int nid, struct ssh *ssh)
+{
+	return get_hostkey_by_type(type, nid, 0, ssh);
+}
+
+struct sshkey *
+get_hostkey_private_by_type(int type, int nid, struct ssh *ssh)
+{
+	return get_hostkey_by_type(type, nid, 1, ssh);
+}
+
+struct sshkey *
+get_hostkey_by_index(int ind)
+{
+	if (ind < 0 || (u_int)ind >= options.num_host_key_files)
+		return (NULL);
+	return (sensitive_data.host_keys[ind]);
+}
+
+struct sshkey *
+get_hostkey_public_by_index(int ind, struct ssh *ssh)
+{
+	if (ind < 0 || (u_int)ind >= options.num_host_key_files)
+		return (NULL);
+	return (sensitive_data.host_pubkeys[ind]);
+}
+
+int
+get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh)
+{
+	u_int i;
+
+	for (i = 0; i < options.num_host_key_files; i++) {
+		if (sshkey_is_cert(key)) {
+			if (key == sensitive_data.host_certificates[i] ||
+			    (compare && sensitive_data.host_certificates[i] &&
+			    sshkey_equal(key,
+			    sensitive_data.host_certificates[i])))
+				return (i);
+		} else {
+			if (key == sensitive_data.host_keys[i] ||
+			    (compare && sensitive_data.host_keys[i] &&
+			    sshkey_equal(key, sensitive_data.host_keys[i])))
+				return (i);
+			if (key == sensitive_data.host_pubkeys[i] ||
+			    (compare && sensitive_data.host_pubkeys[i] &&
+			    sshkey_equal(key, sensitive_data.host_pubkeys[i])))
+				return (i);
+		}
+	}
+	return (-1);
+}
+
+/* Inform the client of all hostkeys */
+static void
+notify_hostkeys(struct ssh *ssh)
+{
+	struct sshbuf *buf;
+	struct sshkey *key;
+	u_int i, nkeys;
+	int r;
+	char *fp;
+
+	/* Some clients cannot cope with the hostkeys message, skip those. */
+	if (ssh->compat & SSH_BUG_HOSTKEYS)
+		return;
+
+	if ((buf = sshbuf_new()) == NULL)
+		fatal_f("sshbuf_new");
+	for (i = nkeys = 0; i < options.num_host_key_files; i++) {
+		key = get_hostkey_public_by_index(i, ssh);
+		if (key == NULL || key->type == KEY_UNSPEC ||
+		    sshkey_is_cert(key))
+			continue;
+		fp = sshkey_fingerprint(key, options.fingerprint_hash,
+		    SSH_FP_DEFAULT);
+		debug3_f("key %d: %s %s", i, sshkey_ssh_name(key), fp);
+		free(fp);
+		if (nkeys == 0) {
+			/*
+			 * Start building the request when we find the
+			 * first usable key.
+			 */
+			if ((r = sshpkt_start(ssh, SSH2_MSG_GLOBAL_REQUEST)) != 0 ||
+			    (r = sshpkt_put_cstring(ssh, "hostkeys-00@openssh.com")) != 0 ||
+			    (r = sshpkt_put_u8(ssh, 0)) != 0) /* want reply */
+				sshpkt_fatal(ssh, r, "%s: start request", __func__);
+		}
+		/* Append the key to the request */
+		sshbuf_reset(buf);
+		if ((r = sshkey_putb(key, buf)) != 0)
+			fatal_fr(r, "couldn't put hostkey %d", i);
+		if ((r = sshpkt_put_stringb(ssh, buf)) != 0)
+			sshpkt_fatal(ssh, r, "%s: append key", __func__);
+		nkeys++;
+	}
+	debug3_f("sent %u hostkeys", nkeys);
+	if (nkeys == 0)
+		fatal_f("no hostkeys");
+	if ((r = sshpkt_send(ssh)) != 0)
+		sshpkt_fatal(ssh, r, "%s: send", __func__);
+	sshbuf_free(buf);
+}
+
+/*
+ * returns 1 if connection should be dropped, 0 otherwise.
+ * dropping starts at connection #max_startups_begin with a probability
+ * of (max_startups_rate/100). the probability increases linearly until
+ * all connections are dropped for startups > max_startups
+ */
+static int
+should_drop_connection(int startups)
+{
+	int p, r;
+
+	if (startups < options.max_startups_begin)
+		return 0;
+	if (startups >= options.max_startups)
+		return 1;
+	if (options.max_startups_rate == 100)
+		return 1;
+
+	p  = 100 - options.max_startups_rate;
+	p *= startups - options.max_startups_begin;
+	p /= options.max_startups - options.max_startups_begin;
+	p += options.max_startups_rate;
+	r = arc4random_uniform(100);
+
+	debug_f("p %d, r %d", p, r);
+	return (r < p) ? 1 : 0;
+}
+
+/*
+ * Check whether connection should be accepted by MaxStartups.
+ * Returns 0 if the connection is accepted. If the connection is refused,
+ * returns 1 and attempts to send notification to client.
+ * Logs when the MaxStartups condition is entered or exited, and periodically
+ * while in that state.
+ */
+static int
+drop_connection(int sock, int startups, int notify_pipe)
+{
+	char *laddr, *raddr;
+	const char msg[] = "Exceeded MaxStartups\r\n";
+	static time_t last_drop, first_drop;
+	static u_int ndropped;
+	LogLevel drop_level = SYSLOG_LEVEL_VERBOSE;
+	time_t now;
+
+	now = monotime();
+	if (!should_drop_connection(startups) &&
+	    srclimit_check_allow(sock, notify_pipe) == 1) {
+		if (last_drop != 0 &&
+		    startups < options.max_startups_begin - 1) {
+			/* XXX maybe need better hysteresis here */
+			logit("exited MaxStartups throttling after %s, "
+			    "%u connections dropped",
+			    fmt_timeframe(now - first_drop), ndropped);
+			last_drop = 0;
+		}
+		return 0;
+	}
+
+#define SSHD_MAXSTARTUPS_LOG_INTERVAL	(5 * 60)
+	if (last_drop == 0) {
+		error("beginning MaxStartups throttling");
+		drop_level = SYSLOG_LEVEL_INFO;
+		first_drop = now;
+		ndropped = 0;
+	} else if (last_drop + SSHD_MAXSTARTUPS_LOG_INTERVAL < now) {
+		/* Periodic logs */
+		error("in MaxStartups throttling for %s, "
+		    "%u connections dropped",
+		    fmt_timeframe(now - first_drop), ndropped + 1);
+		drop_level = SYSLOG_LEVEL_INFO;
+	}
+	last_drop = now;
+	ndropped++;
+
+	laddr = get_local_ipaddr(sock);
+	raddr = get_peer_ipaddr(sock);
+	do_log2(drop_level, "drop connection #%d from [%s]:%d on [%s]:%d "
+	    "past MaxStartups", startups, raddr, get_peer_port(sock),
+	    laddr, get_local_port(sock));
+	free(laddr);
+	free(raddr);
+	/* best-effort notification to client */
+	(void)write(sock, msg, sizeof(msg) - 1);
+	return 1;
+}
+
+static void
+usage(void)
+{
+	fprintf(stderr, "%s, %s\n", SSH_RELEASE, SSH_OPENSSL_VERSION);
+	fprintf(stderr,
+"usage: sshd [-46DdeiqTt] [-C connection_spec] [-c host_cert_file]\n"
+"            [-E log_file] [-f config_file] [-g login_grace_time]\n"
+"            [-h host_key_file] [-o option] [-p port] [-u len]\n"
+	);
+	exit(1);
+}
+
+static void
+send_rexec_state(int fd, struct sshbuf *conf)
+{
+	struct sshbuf *m = NULL, *inc = NULL;
+	struct include_item *item = NULL;
+	int r;
+
+	debug3_f("entering fd = %d config len %zu", fd,
+	    sshbuf_len(conf));
+
+	if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL)
+		fatal_f("sshbuf_new failed");
+
+	/* pack includes into a string */
+	TAILQ_FOREACH(item, &includes, entry) {
+		if ((r = sshbuf_put_cstring(inc, item->selector)) != 0 ||
+		    (r = sshbuf_put_cstring(inc, item->filename)) != 0 ||
+		    (r = sshbuf_put_stringb(inc, item->contents)) != 0)
+			fatal_fr(r, "compose includes");
+	}
+
+	/*
+	 * Protocol from reexec master to child:
+	 *	string	configuration
+	 *	string	included_files[] {
+	 *		string	selector
+	 *		string	filename
+	 *		string	contents
+	 *	}
+	 *	string	rng_seed (if required)
+	 */
+	if ((r = sshbuf_put_stringb(m, conf)) != 0 ||
+	    (r = sshbuf_put_stringb(m, inc)) != 0)
+		fatal_fr(r, "compose config");
+#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
+	rexec_send_rng_seed(m);
+#endif
+	if (ssh_msg_send(fd, 0, m) == -1)
+		error_f("ssh_msg_send failed");
+
+	sshbuf_free(m);
+	sshbuf_free(inc);
+
+	debug3_f("done");
+}
+
+static void
+recv_rexec_state(int fd, struct sshbuf *conf)
+{
+	struct sshbuf *m, *inc;
+	u_char *cp, ver;
+	size_t len;
+	int r;
+	struct include_item *item;
+
+	debug3_f("entering fd = %d", fd);
+
+	if ((m = sshbuf_new()) == NULL || (inc = sshbuf_new()) == NULL)
+		fatal_f("sshbuf_new failed");
+	if (ssh_msg_recv(fd, m) == -1)
+		fatal_f("ssh_msg_recv failed");
+	if ((r = sshbuf_get_u8(m, &ver)) != 0)
+		fatal_fr(r, "parse version");
+	if (ver != 0)
+		fatal_f("rexec version mismatch");
+	if ((r = sshbuf_get_string(m, &cp, &len)) != 0 ||
+	    (r = sshbuf_get_stringb(m, inc)) != 0)
+		fatal_fr(r, "parse config");
+
+#if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY)
+	rexec_recv_rng_seed(m);
+#endif
+
+	if (conf != NULL && (r = sshbuf_put(conf, cp, len)))
+		fatal_fr(r, "sshbuf_put");
+
+	while (sshbuf_len(inc) != 0) {
+		item = xcalloc(1, sizeof(*item));
+		if ((item->contents = sshbuf_new()) == NULL)
+			fatal_f("sshbuf_new failed");
+		if ((r = sshbuf_get_cstring(inc, &item->selector, NULL)) != 0 ||
+		    (r = sshbuf_get_cstring(inc, &item->filename, NULL)) != 0 ||
+		    (r = sshbuf_get_stringb(inc, item->contents)) != 0)
+			fatal_fr(r, "parse includes");
+		TAILQ_INSERT_TAIL(&includes, item, entry);
+	}
+
+	free(cp);
+	sshbuf_free(m);
+
+	debug3_f("done");
+}
+
+/* Accept a connection from inetd */
+static void
+server_accept_inetd(int *sock_in, int *sock_out)
+{
+	if (rexeced_flag) {
+		close(REEXEC_CONFIG_PASS_FD);
+		*sock_in = *sock_out = dup(STDIN_FILENO);
+	} else {
+		*sock_in = dup(STDIN_FILENO);
+		*sock_out = dup(STDOUT_FILENO);
+	}
+	/*
+	 * We intentionally do not close the descriptors 0, 1, and 2
+	 * as our code for setting the descriptors won't work if
+	 * ttyfd happens to be one of those.
+	 */
+	if (stdfd_devnull(1, 1, !log_stderr) == -1)
+		error_f("stdfd_devnull failed");
+	debug("inetd sockets after dupping: %d, %d", *sock_in, *sock_out);
+}
+
+/*
+ * Listen for TCP connections
+ */
+static void
+listen_on_addrs(struct listenaddr *la)
+{
+	int ret, listen_sock;
+	struct addrinfo *ai;
+	char ntop[NI_MAXHOST], strport[NI_MAXSERV];
+
+	for (ai = la->addrs; ai; ai = ai->ai_next) {
+		if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
+			continue;
+		if (num_listen_socks >= MAX_LISTEN_SOCKS)
+			fatal("Too many listen sockets. "
+			    "Enlarge MAX_LISTEN_SOCKS");
+		if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen,
+		    ntop, sizeof(ntop), strport, sizeof(strport),
+		    NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
+			error("getnameinfo failed: %.100s",
+			    ssh_gai_strerror(ret));
+			continue;
+		}
+		/* Create socket for listening. */
+		listen_sock = socket(ai->ai_family, ai->ai_socktype,
+		    ai->ai_protocol);
+		if (listen_sock == -1) {
+			/* kernel may not support ipv6 */
+			verbose("socket: %.100s", strerror(errno));
+			continue;
+		}
+		if (set_nonblock(listen_sock) == -1) {
+			close(listen_sock);
+			continue;
+		}
+		if (fcntl(listen_sock, F_SETFD, FD_CLOEXEC) == -1) {
+			verbose("socket: CLOEXEC: %s", strerror(errno));
+			close(listen_sock);
+			continue;
+		}
+		/* Socket options */
+		set_reuseaddr(listen_sock);
+		if (la->rdomain != NULL &&
+		    set_rdomain(listen_sock, la->rdomain) == -1) {
+			close(listen_sock);
+			continue;
+		}
+
+		/* Only communicate in IPv6 over AF_INET6 sockets. */
+		if (ai->ai_family == AF_INET6)
+			sock_set_v6only(listen_sock);
+
+		debug("Bind to port %s on %s.", strport, ntop);
+
+		/* Bind the socket to the desired port. */
+		if (bind(listen_sock, ai->ai_addr, ai->ai_addrlen) == -1) {
+			error("Bind to port %s on %s failed: %.200s.",
+			    strport, ntop, strerror(errno));
+			close(listen_sock);
+			continue;
+		}
+		listen_socks[num_listen_socks] = listen_sock;
+		num_listen_socks++;
+
+		/* Start listening on the port. */
+		if (listen(listen_sock, SSH_LISTEN_BACKLOG) == -1)
+			fatal("listen on [%s]:%s: %.100s",
+			    ntop, strport, strerror(errno));
+		logit("Server listening on %s port %s%s%s.",
+		    ntop, strport,
+		    la->rdomain == NULL ? "" : " rdomain ",
+		    la->rdomain == NULL ? "" : la->rdomain);
+	}
+}
+
+static void
+server_listen(void)
+{
+	u_int i;
+
+	/* Initialise per-source limit tracking. */
+	srclimit_init(options.max_startups, options.per_source_max_startups,
+	    options.per_source_masklen_ipv4, options.per_source_masklen_ipv6);
+
+	for (i = 0; i < options.num_listen_addrs; i++) {
+		listen_on_addrs(&options.listen_addrs[i]);
+		freeaddrinfo(options.listen_addrs[i].addrs);
+		free(options.listen_addrs[i].rdomain);
+		memset(&options.listen_addrs[i], 0,
+		    sizeof(options.listen_addrs[i]));
+	}
+	free(options.listen_addrs);
+	options.listen_addrs = NULL;
+	options.num_listen_addrs = 0;
+
+	if (!num_listen_socks)
+		fatal("Cannot bind any address.");
+}
+
+/*
+ * The main TCP accept loop. Note that, for the non-debug case, returns
+ * from this function are in a forked subprocess.
+ */
+static void
+server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s)
+{
+	fd_set *fdset;
+	int i, j, ret, maxfd;
+	int ostartups = -1, startups = 0, listening = 0, lameduck = 0;
+	int startup_p[2] = { -1 , -1 };
+	char c = 0;
+	struct sockaddr_storage from;
+	socklen_t fromlen;
+	pid_t pid;
+	u_char rnd[256];
+
+	/* setup fd set for accept */
+	fdset = NULL;
+	maxfd = 0;
+	for (i = 0; i < num_listen_socks; i++)
+		if (listen_socks[i] > maxfd)
+			maxfd = listen_socks[i];
+	/* pipes connected to unauthenticated child sshd processes */
+	startup_pipes = xcalloc(options.max_startups, sizeof(int));
+	startup_flags = xcalloc(options.max_startups, sizeof(int));
+	for (i = 0; i < options.max_startups; i++)
+		startup_pipes[i] = -1;
+
+	/*
+	 * Stay listening for connections until the system crashes or
+	 * the daemon is killed with a signal.
+	 */
+	for (;;) {
+		if (ostartups != startups) {
+			setproctitle("%s [listener] %d of %d-%d startups",
+			    listener_proctitle, startups,
+			    options.max_startups_begin, options.max_startups);
+			ostartups = startups;
+		}
+		if (received_sighup) {
+			if (!lameduck) {
+				debug("Received SIGHUP; waiting for children");
+				close_listen_socks();
+				lameduck = 1;
+			}
+			if (listening <= 0)
+				sighup_restart();
+		}
+		free(fdset);
+		fdset = xcalloc(howmany(maxfd + 1, NFDBITS),
+		    sizeof(fd_mask));
+
+		for (i = 0; i < num_listen_socks; i++)
+			FD_SET(listen_socks[i], fdset);
+		for (i = 0; i < options.max_startups; i++)
+			if (startup_pipes[i] != -1)
+				FD_SET(startup_pipes[i], fdset);
+
+		/* Wait in select until there is a connection. */
+		ret = select(maxfd+1, fdset, NULL, NULL, NULL);
+		if (ret == -1 && errno != EINTR)
+			error("select: %.100s", strerror(errno));
+		if (received_sigterm) {
+			logit("Received signal %d; terminating.",
+			    (int) received_sigterm);
+			close_listen_socks();
+			if (options.pid_file != NULL)
+				unlink(options.pid_file);
+			exit(received_sigterm == SIGTERM ? 0 : 255);
+		}
+		if (ret == -1)
+			continue;
+
+		for (i = 0; i < options.max_startups; i++) {
+			if (startup_pipes[i] == -1 ||
+			    !FD_ISSET(startup_pipes[i], fdset))
+				continue;
+			switch (read(startup_pipes[i], &c, sizeof(c))) {
+			case -1:
+				if (errno == EINTR || errno == EAGAIN)
+					continue;
+				if (errno != EPIPE) {
+					error_f("startup pipe %d (fd=%d): "
+					    "read %s", i, startup_pipes[i],
+					    strerror(errno));
+				}
+				/* FALLTHROUGH */
+			case 0:
+				/* child exited or completed auth */
+				close(startup_pipes[i]);
+				srclimit_done(startup_pipes[i]);
+				startup_pipes[i] = -1;
+				startups--;
+				if (startup_flags[i])
+					listening--;
+				break;
+			case 1:
+				/* child has finished preliminaries */
+				if (startup_flags[i]) {
+					listening--;
+					startup_flags[i] = 0;
+				}
+				break;
+			}
+		}
+		for (i = 0; i < num_listen_socks; i++) {
+			if (!FD_ISSET(listen_socks[i], fdset))
+				continue;
+			fromlen = sizeof(from);
+			*newsock = accept(listen_socks[i],
+			    (struct sockaddr *)&from, &fromlen);
+			if (*newsock == -1) {
+				if (errno != EINTR && errno != EWOULDBLOCK &&
+				    errno != ECONNABORTED && errno != EAGAIN)
+					error("accept: %.100s",
+					    strerror(errno));
+				if (errno == EMFILE || errno == ENFILE)
+					usleep(100 * 1000);
+				continue;
+			}
+			if (unset_nonblock(*newsock) == -1 ||
+			    pipe(startup_p) == -1)
+				continue;
+			if (drop_connection(*newsock, startups, startup_p[0])) {
+				close(*newsock);
+				close(startup_p[0]);
+				close(startup_p[1]);
+				continue;
+			}
+
+			if (rexec_flag && socketpair(AF_UNIX,
+			    SOCK_STREAM, 0, config_s) == -1) {
+				error("reexec socketpair: %s",
+				    strerror(errno));
+				close(*newsock);
+				close(startup_p[0]);
+				close(startup_p[1]);
+				continue;
+			}
+
+			for (j = 0; j < options.max_startups; j++)
+				if (startup_pipes[j] == -1) {
+					startup_pipes[j] = startup_p[0];
+					if (maxfd < startup_p[0])
+						maxfd = startup_p[0];
+					startups++;
+					startup_flags[j] = 1;
+					break;
+				}
+
+			/*
+			 * Got connection.  Fork a child to handle it, unless
+			 * we are in debugging mode.
+			 */
+			if (debug_flag) {
+				/*
+				 * In debugging mode.  Close the listening
+				 * socket, and start processing the
+				 * connection without forking.
+				 */
+				debug("Server will not fork when running in debugging mode.");
+				close_listen_socks();
+				*sock_in = *newsock;
+				*sock_out = *newsock;
+				close(startup_p[0]);
+				close(startup_p[1]);
+				startup_pipe = -1;
+				pid = getpid();
+				if (rexec_flag) {
+					send_rexec_state(config_s[0], cfg);
+					close(config_s[0]);
+				}
+				return;
+			}
+
+			/*
+			 * Normal production daemon.  Fork, and have
+			 * the child process the connection. The
+			 * parent continues listening.
+			 */
+			platform_pre_fork();
+			listening++;
+			if ((pid = fork()) == 0) {
+				/*
+				 * Child.  Close the listening and
+				 * max_startup sockets.  Start using
+				 * the accepted socket. Reinitialize
+				 * logging (since our pid has changed).
+				 * We return from this function to handle
+				 * the connection.
+				 */
+				platform_post_fork_child();
+				startup_pipe = startup_p[1];
+				close_startup_pipes();
+				close_listen_socks();
+				*sock_in = *newsock;
+				*sock_out = *newsock;
+				log_init(__progname,
+				    options.log_level,
+				    options.log_facility,
+				    log_stderr);
+				if (rexec_flag)
+					close(config_s[0]);
+				else {
+					/*
+					 * Signal parent that the preliminaries
+					 * for this child are complete. For the
+					 * re-exec case, this happens after the
+					 * child has received the rexec state
+					 * from the server.
+					 */
+					(void)atomicio(vwrite, startup_pipe,
+					    "\0", 1);
+				}
+				return;
+			}
+
+			/* Parent.  Stay in the loop. */
+			platform_post_fork_parent(pid);
+			if (pid == -1)
+				error("fork: %.100s", strerror(errno));
+			else
+				debug("Forked child %ld.", (long)pid);
+
+			close(startup_p[1]);
+
+			if (rexec_flag) {
+				close(config_s[1]);
+				send_rexec_state(config_s[0], cfg);
+				close(config_s[0]);
+			}
+			close(*newsock);
+
+			/*
+			 * Ensure that our random state differs
+			 * from that of the child
+			 */
+			arc4random_stir();
+			arc4random_buf(rnd, sizeof(rnd));
+#ifdef WITH_OPENSSL
+			RAND_seed(rnd, sizeof(rnd));
+			if ((RAND_bytes((u_char *)rnd, 1)) != 1)
+				fatal("%s: RAND_bytes failed", __func__);
+#endif
+			explicit_bzero(rnd, sizeof(rnd));
+		}
+	}
+}
+
+/*
+ * If IP options are supported, make sure there are none (log and
+ * return an error if any are found).  Basically we are worried about
+ * source routing; it can be used to pretend you are somebody
+ * (ip-address) you are not. That itself may be "almost acceptable"
+ * under certain circumstances, but rhosts authentication is useless
+ * if source routing is accepted. Notice also that if we just dropped
+ * source routing here, the other side could use IP spoofing to do
+ * rest of the interaction and could still bypass security.  So we
+ * exit here if we detect any IP options.
+ */
+static void
+check_ip_options(struct ssh *ssh)
+{
+#ifdef IP_OPTIONS
+	int sock_in = ssh_packet_get_connection_in(ssh);
+	struct sockaddr_storage from;
+	u_char opts[200];
+	socklen_t i, option_size = sizeof(opts), fromlen = sizeof(from);
+	char text[sizeof(opts) * 3 + 1];
+
+	memset(&from, 0, sizeof(from));
+	if (getpeername(sock_in, (struct sockaddr *)&from,
+	    &fromlen) == -1)
+		return;
+	if (from.ss_family != AF_INET)
+		return;
+	/* XXX IPv6 options? */
+
+	if (getsockopt(sock_in, IPPROTO_IP, IP_OPTIONS, opts,
+	    &option_size) >= 0 && option_size != 0) {
+		text[0] = '\0';
+		for (i = 0; i < option_size; i++)
+			snprintf(text + i*3, sizeof(text) - i*3,
+			    " %2.2x", opts[i]);
+		fatal("Connection from %.100s port %d with IP opts: %.800s",
+		    ssh_remote_ipaddr(ssh), ssh_remote_port(ssh), text);
+	}
+	return;
+#endif /* IP_OPTIONS */
+}
+
+/* Set the routing domain for this process */
+static void
+set_process_rdomain(struct ssh *ssh, const char *name)
+{
+#if defined(HAVE_SYS_SET_PROCESS_RDOMAIN)
+	if (name == NULL)
+		return; /* default */
+
+	if (strcmp(name, "%D") == 0) {
+		/* "expands" to routing domain of connection */
+		if ((name = ssh_packet_rdomain_in(ssh)) == NULL)
+			return;
+	}
+	/* NB. We don't pass 'ssh' to sys_set_process_rdomain() */
+	return sys_set_process_rdomain(name);
+#elif defined(__OpenBSD__)
+	int rtable, ortable = getrtable();
+	const char *errstr;
+
+	if (name == NULL)
+		return; /* default */
+
+	if (strcmp(name, "%D") == 0) {
+		/* "expands" to routing domain of connection */
+		if ((name = ssh_packet_rdomain_in(ssh)) == NULL)
+			return;
+	}
+
+	rtable = (int)strtonum(name, 0, 255, &errstr);
+	if (errstr != NULL) /* Shouldn't happen */
+		fatal("Invalid routing domain \"%s\": %s", name, errstr);
+	if (rtable != ortable && setrtable(rtable) != 0)
+		fatal("Unable to set routing domain %d: %s",
+		    rtable, strerror(errno));
+	debug_f("set routing domain %d (was %d)", rtable, ortable);
+#else /* defined(__OpenBSD__) */
+	fatal("Unable to set routing domain: not supported in this platform");
+#endif
+}
+
+static void
+accumulate_host_timing_secret(struct sshbuf *server_cfg,
+    struct sshkey *key)
+{
+	static struct ssh_digest_ctx *ctx;
+	u_char *hash;
+	size_t len;
+	struct sshbuf *buf;
+	int r;
+
+	if (ctx == NULL && (ctx = ssh_digest_start(SSH_DIGEST_SHA512)) == NULL)
+		fatal_f("ssh_digest_start");
+	if (key == NULL) { /* finalize */
+		/* add server config in case we are using agent for host keys */
+		if (ssh_digest_update(ctx, sshbuf_ptr(server_cfg),
+		    sshbuf_len(server_cfg)) != 0)
+			fatal_f("ssh_digest_update");
+		len = ssh_digest_bytes(SSH_DIGEST_SHA512);
+		hash = xmalloc(len);
+		if (ssh_digest_final(ctx, hash, len) != 0)
+			fatal_f("ssh_digest_final");
+		options.timing_secret = PEEK_U64(hash);
+		freezero(hash, len);
+		ssh_digest_free(ctx);
+		ctx = NULL;
+		return;
+	}
+	if ((buf = sshbuf_new()) == NULL)
+		fatal_f("could not allocate buffer");
+	if ((r = sshkey_private_serialize(key, buf)) != 0)
+		fatal_fr(r, "decode key");
+	if (ssh_digest_update(ctx, sshbuf_ptr(buf), sshbuf_len(buf)) != 0)
+		fatal_f("ssh_digest_update");
+	sshbuf_reset(buf);
+	sshbuf_free(buf);
+}
+
+static char *
+prepare_proctitle(int ac, char **av)
+{
+	char *ret = NULL;
+	int i;
+
+	for (i = 0; i < ac; i++)
+		xextendf(&ret, " ", "%s", av[i]);
+	return ret;
+}
+
+/*
+ * Main program for the daemon.
+ */
+int
+main(int ac, char **av)
+{
+	struct ssh *ssh = NULL;
+	extern char *optarg;
+	extern int optind;
+	int r, opt, on = 1, already_daemon, remote_port;
+	int sock_in = -1, sock_out = -1, newsock = -1;
+	const char *remote_ip, *rdomain;
+	char *fp, *line, *laddr, *logfile = NULL;
+	int config_s[2] = { -1 , -1 };
+	u_int i, j;
+	u_int64_t ibytes, obytes;
+	mode_t new_umask;
+	struct sshkey *key;
+	struct sshkey *pubkey;
+	int keytype;
+	Authctxt *authctxt;
+	struct connection_info *connection_info = NULL;
+
+#ifdef HAVE_SECUREWARE
+	(void)set_auth_parameters(ac, av);
+#endif
+	__progname = ssh_get_progname(av[0]);
+
+	/* Save argv. Duplicate so setproctitle emulation doesn't clobber it */
+	saved_argc = ac;
+	rexec_argc = ac;
+	saved_argv = xcalloc(ac + 1, sizeof(*saved_argv));
+	for (i = 0; (int)i < ac; i++)
+		saved_argv[i] = xstrdup(av[i]);
+	saved_argv[i] = NULL;
+
+#ifndef HAVE_SETPROCTITLE
+	/* Prepare for later setproctitle emulation */
+	compat_init_setproctitle(ac, av);
+	av = saved_argv;
+#endif
+
+	if (geteuid() == 0 && setgroups(0, NULL) == -1)
+		debug("setgroups(): %.200s", strerror(errno));
+
+	/* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
+	sanitise_stdfd();
+
+	seed_rng();
+
+	/* Initialize configuration options to their default values. */
+	initialize_server_options(&options);
+
+	/* Parse command-line arguments. */
+	while ((opt = getopt(ac, av,
+	    "C:E:b:c:f:g:h:k:o:p:u:46DQRTdeiqrt")) != -1) {
+		switch (opt) {
+		case '4':
+			options.address_family = AF_INET;
+			break;
+		case '6':
+			options.address_family = AF_INET6;
+			break;
+		case 'f':
+			config_file_name = optarg;
+			break;
+		case 'c':
+			servconf_add_hostcert("[command-line]", 0,
+			    &options, optarg);
+			break;
+		case 'd':
+			if (debug_flag == 0) {
+				debug_flag = 1;
+				options.log_level = SYSLOG_LEVEL_DEBUG1;
+			} else if (options.log_level < SYSLOG_LEVEL_DEBUG3)
+				options.log_level++;
+			break;
+		case 'D':
+			no_daemon_flag = 1;
+			break;
+		case 'E':
+			logfile = optarg;
+			/* FALLTHROUGH */
+		case 'e':
+			log_stderr = 1;
+			break;
+		case 'i':
+			inetd_flag = 1;
+			break;
+		case 'r':
+			rexec_flag = 0;
+			break;
+		case 'R':
+			rexeced_flag = 1;
+			inetd_flag = 1;
+			break;
+		case 'Q':
+			/* ignored */
+			break;
+		case 'q':
+			options.log_level = SYSLOG_LEVEL_QUIET;
+			break;
+		case 'b':
+			/* protocol 1, ignored */
+			break;
+		case 'p':
+			options.ports_from_cmdline = 1;
+			if (options.num_ports >= MAX_PORTS) {
+				fprintf(stderr, "too many ports.\n");
+				exit(1);
+			}
+			options.ports[options.num_ports++] = a2port(optarg);
+			if (options.ports[options.num_ports-1] <= 0) {
+				fprintf(stderr, "Bad port number.\n");
+				exit(1);
+			}
+			break;
+		case 'g':
+			if ((options.login_grace_time = convtime(optarg)) == -1) {
+				fprintf(stderr, "Invalid login grace time.\n");
+				exit(1);
+			}
+			break;
+		case 'k':
+			/* protocol 1, ignored */
+			break;
+		case 'h':
+			servconf_add_hostkey("[command-line]", 0,
+			    &options, optarg, 1);
+			break;
+		case 't':
+			test_flag = 1;
+			break;
+		case 'T':
+			test_flag = 2;
+			break;
+		case 'C':
+			connection_info = get_connection_info(ssh, 0, 0);
+			if (parse_server_match_testspec(connection_info,
+			    optarg) == -1)
+				exit(1);
+			break;
+		case 'u':
+			utmp_len = (u_int)strtonum(optarg, 0, HOST_NAME_MAX+1+1, NULL);
+			if (utmp_len > HOST_NAME_MAX+1) {
+				fprintf(stderr, "Invalid utmp length.\n");
+				exit(1);
+			}
+			break;
+		case 'o':
+			line = xstrdup(optarg);
+			if (process_server_config_line(&options, line,
+			    "command-line", 0, NULL, NULL, &includes) != 0)
+				exit(1);
+			free(line);
+			break;
+		case '?':
+		default:
+			usage();
+			break;
+		}
+	}
+	if (rexeced_flag || inetd_flag)
+		rexec_flag = 0;
+	if (!test_flag && rexec_flag && !path_absolute(av[0]))
+		fatal("sshd re-exec requires execution with an absolute path");
+	if (rexeced_flag)
+		closefrom(REEXEC_MIN_FREE_FD);
+	else
+		closefrom(REEXEC_DEVCRYPTO_RESERVED_FD);
+
+	/* If requested, redirect the logs to the specified logfile. */
+	if (logfile != NULL)
+		log_redirect_stderr_to(logfile);
+	/*
+	 * Force logging to stderr until we have loaded the private host
+	 * key (unless started from inetd)
+	 */
+	log_init(__progname,
+	    options.log_level == SYSLOG_LEVEL_NOT_SET ?
+	    SYSLOG_LEVEL_INFO : options.log_level,
+	    options.log_facility == SYSLOG_FACILITY_NOT_SET ?
+	    SYSLOG_FACILITY_AUTH : options.log_facility,
+	    log_stderr || !inetd_flag || debug_flag);
+
+	/*
+	 * Unset KRB5CCNAME, otherwise the user's session may inherit it from
+	 * root's environment
+	 */
+	if (getenv("KRB5CCNAME") != NULL)
+		(void) unsetenv("KRB5CCNAME");
+
+	sensitive_data.have_ssh2_key = 0;
+
+	/*
+	 * If we're not doing an extended test do not silently ignore connection
+	 * test params.
+	 */
+	if (test_flag < 2 && connection_info != NULL)
+		fatal("Config test connection parameter (-C) provided without "
+		   "test mode (-T)");
+
+	/* Fetch our configuration */
+	if ((cfg = sshbuf_new()) == NULL)
+		fatal_f("sshbuf_new failed");
+	if (rexeced_flag) {
+		setproctitle("%s", "[rexeced]");
+		recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg);
+		if (!debug_flag) {
+			startup_pipe = dup(REEXEC_STARTUP_PIPE_FD);
+			close(REEXEC_STARTUP_PIPE_FD);
+			/*
+			 * Signal parent that this child is at a point where
+			 * they can go away if they have a SIGHUP pending.
+			 */
+			(void)atomicio(vwrite, startup_pipe, "\0", 1);
+		}
+	} else if (strcasecmp(config_file_name, "none") != 0)
+		load_server_config(config_file_name, cfg);
+
+	parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name,
+	    cfg, &includes, NULL);
+
+	/* Fill in default values for those options not explicitly set. */
+	fill_default_server_options(&options);
+
+	/* challenge-response is implemented via keyboard interactive */
+	if (options.challenge_response_authentication)
+		options.kbd_interactive_authentication = 1;
+
+	/* Check that options are sensible */
+	if (options.authorized_keys_command_user == NULL &&
+	    (options.authorized_keys_command != NULL &&
+	    strcasecmp(options.authorized_keys_command, "none") != 0))
+		fatal("AuthorizedKeysCommand set without "
+		    "AuthorizedKeysCommandUser");
+	if (options.authorized_principals_command_user == NULL &&
+	    (options.authorized_principals_command != NULL &&
+	    strcasecmp(options.authorized_principals_command, "none") != 0))
+		fatal("AuthorizedPrincipalsCommand set without "
+		    "AuthorizedPrincipalsCommandUser");
+
+	/*
+	 * Check whether there is any path through configured auth methods.
+	 * Unfortunately it is not possible to verify this generally before
+	 * daemonisation in the presence of Match block, but this catches
+	 * and warns for trivial misconfigurations that could break login.
+	 */
+	if (options.num_auth_methods != 0) {
+		for (i = 0; i < options.num_auth_methods; i++) {
+			if (auth2_methods_valid(options.auth_methods[i],
+			    1) == 0)
+				break;
+		}
+		if (i >= options.num_auth_methods)
+			fatal("AuthenticationMethods cannot be satisfied by "
+			    "enabled authentication methods");
+	}
+
+	/* Check that there are no remaining arguments. */
+	if (optind < ac) {
+		fprintf(stderr, "Extra argument %s.\n", av[optind]);
+		exit(1);
+	}
+
+	debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION);
+
+	/* Store privilege separation user for later use if required. */
+	privsep_chroot = use_privsep && (getuid() == 0 || geteuid() == 0);
+	if ((privsep_pw = getpwnam(SSH_PRIVSEP_USER)) == NULL) {
+		if (privsep_chroot || options.kerberos_authentication)
+			fatal("Privilege separation user %s does not exist",
+			    SSH_PRIVSEP_USER);
+	} else {
+		privsep_pw = pwcopy(privsep_pw);
+		freezero(privsep_pw->pw_passwd, strlen(privsep_pw->pw_passwd));
+		privsep_pw->pw_passwd = xstrdup("*");
+	}
+	endpwent();
+
+	/* load host keys */
+	sensitive_data.host_keys = xcalloc(options.num_host_key_files,
+	    sizeof(struct sshkey *));
+	sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files,
+	    sizeof(struct sshkey *));
+
+	if (options.host_key_agent) {
+		if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME))
+			setenv(SSH_AUTHSOCKET_ENV_NAME,
+			    options.host_key_agent, 1);
+		if ((r = ssh_get_authentication_socket(NULL)) == 0)
+			have_agent = 1;
+		else
+			error_r(r, "Could not connect to agent \"%s\"",
+			    options.host_key_agent);
+	}
+
+	for (i = 0; i < options.num_host_key_files; i++) {
+		int ll = options.host_key_file_userprovided[i] ?
+		    SYSLOG_LEVEL_ERROR : SYSLOG_LEVEL_DEBUG1;
+
+		if (options.host_key_files[i] == NULL)
+			continue;
+		if ((r = sshkey_load_private(options.host_key_files[i], "",
+		    &key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
+			do_log2_r(r, ll, "Unable to load host key \"%s\"",
+			    options.host_key_files[i]);
+		if (sshkey_is_sk(key) &&
+		    key->sk_flags & SSH_SK_USER_PRESENCE_REQD) {
+			debug("host key %s requires user presence, ignoring",
+			    options.host_key_files[i]);
+			key->sk_flags &= ~SSH_SK_USER_PRESENCE_REQD;
+		}
+		if (r == 0 && key != NULL &&
+		    (r = sshkey_shield_private(key)) != 0) {
+			do_log2_r(r, ll, "Unable to shield host key \"%s\"",
+			    options.host_key_files[i]);
+			sshkey_free(key);
+			key = NULL;
+		}
+		if ((r = sshkey_load_public(options.host_key_files[i],
+		    &pubkey, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR)
+			do_log2_r(r, ll, "Unable to load host key \"%s\"",
+			    options.host_key_files[i]);
+		if (pubkey != NULL && key != NULL) {
+			if (!sshkey_equal(pubkey, key)) {
+				error("Public key for %s does not match "
+				    "private key", options.host_key_files[i]);
+				sshkey_free(pubkey);
+				pubkey = NULL;
+			}
+		}
+		if (pubkey == NULL && key != NULL) {
+			if ((r = sshkey_from_private(key, &pubkey)) != 0)
+				fatal_r(r, "Could not demote key: \"%s\"",
+				    options.host_key_files[i]);
+		}
+		sensitive_data.host_keys[i] = key;
+		sensitive_data.host_pubkeys[i] = pubkey;
+
+		if (key == NULL && pubkey != NULL && have_agent) {
+			debug("will rely on agent for hostkey %s",
+			    options.host_key_files[i]);
+			keytype = pubkey->type;
+		} else if (key != NULL) {
+			keytype = key->type;
+			accumulate_host_timing_secret(cfg, key);
+		} else {
+			do_log2(ll, "Unable to load host key: %s",
+			    options.host_key_files[i]);
+			sensitive_data.host_keys[i] = NULL;
+			sensitive_data.host_pubkeys[i] = NULL;
+			continue;
+		}
+
+		switch (keytype) {
+		case KEY_RSA:
+		case KEY_DSA:
+		case KEY_ECDSA:
+		case KEY_ED25519:
+		case KEY_ECDSA_SK:
+		case KEY_ED25519_SK:
+		case KEY_XMSS:
+			if (have_agent || key != NULL)
+				sensitive_data.have_ssh2_key = 1;
+			break;
+		}
+		if ((fp = sshkey_fingerprint(pubkey, options.fingerprint_hash,
+		    SSH_FP_DEFAULT)) == NULL)
+			fatal("sshkey_fingerprint failed");
+		debug("%s host key #%d: %s %s",
+		    key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp);
+		free(fp);
+	}
+	accumulate_host_timing_secret(cfg, NULL);
+	if (!sensitive_data.have_ssh2_key) {
+		logit("sshd: no hostkeys available -- exiting.");
+		exit(1);
+	}
+
+	/*
+	 * Load certificates. They are stored in an array at identical
+	 * indices to the public keys that they relate to.
+	 */
+	sensitive_data.host_certificates = xcalloc(options.num_host_key_files,
+	    sizeof(struct sshkey *));
+	for (i = 0; i < options.num_host_key_files; i++)
+		sensitive_data.host_certificates[i] = NULL;
+
+	for (i = 0; i < options.num_host_cert_files; i++) {
+		if (options.host_cert_files[i] == NULL)
+			continue;
+		if ((r = sshkey_load_public(options.host_cert_files[i],
+		    &key, NULL)) != 0) {
+			error_r(r, "Could not load host certificate \"%s\"",
+			    options.host_cert_files[i]);
+			continue;
+		}
+		if (!sshkey_is_cert(key)) {
+			error("Certificate file is not a certificate: %s",
+			    options.host_cert_files[i]);
+			sshkey_free(key);
+			continue;
+		}
+		/* Find matching private key */
+		for (j = 0; j < options.num_host_key_files; j++) {
+			if (sshkey_equal_public(key,
+			    sensitive_data.host_keys[j])) {
+				sensitive_data.host_certificates[j] = key;
+				break;
+			}
+		}
+		if (j >= options.num_host_key_files) {
+			error("No matching private key for certificate: %s",
+			    options.host_cert_files[i]);
+			sshkey_free(key);
+			continue;
+		}
+		sensitive_data.host_certificates[j] = key;
+		debug("host certificate: #%u type %d %s", j, key->type,
+		    sshkey_type(key));
+	}
+
+	if (privsep_chroot) {
+		struct stat st;
+
+		if ((stat(_PATH_PRIVSEP_CHROOT_DIR, &st) == -1) ||
+		    (S_ISDIR(st.st_mode) == 0))
+			fatal("Missing privilege separation directory: %s",
+			    _PATH_PRIVSEP_CHROOT_DIR);
+
+#ifdef HAVE_CYGWIN
+		if (check_ntsec(_PATH_PRIVSEP_CHROOT_DIR) &&
+		    (st.st_uid != getuid () ||
+		    (st.st_mode & (S_IWGRP|S_IWOTH)) != 0))
+#else
+		if (st.st_uid != 0 || (st.st_mode & (S_IWGRP|S_IWOTH)) != 0)
+#endif
+			fatal("%s must be owned by root and not group or "
+			    "world-writable.", _PATH_PRIVSEP_CHROOT_DIR);
+	}
+
+	if (test_flag > 1) {
+		/*
+		 * If no connection info was provided by -C then use
+		 * use a blank one that will cause no predicate to match.
+		 */
+		if (connection_info == NULL)
+			connection_info = get_connection_info(ssh, 0, 0);
+		connection_info->test = 1;
+		parse_server_match_config(&options, &includes, connection_info);
+		dump_config(&options);
+	}
+
+	/* Configuration looks good, so exit if in test mode. */
+	if (test_flag)
+		exit(0);
+
+	/*
+	 * Clear out any supplemental groups we may have inherited.  This
+	 * prevents inadvertent creation of files with bad modes (in the
+	 * portable version at least, it's certainly possible for PAM
+	 * to create a file, and we can't control the code in every
+	 * module which might be used).
+	 */
+	if (setgroups(0, NULL) < 0)
+		debug("setgroups() failed: %.200s", strerror(errno));
+
+	if (rexec_flag) {
+		if (rexec_argc < 0)
+			fatal("rexec_argc %d < 0", rexec_argc);
+		rexec_argv = xcalloc(rexec_argc + 2, sizeof(char *));
+		for (i = 0; i < (u_int)rexec_argc; i++) {
+			debug("rexec_argv[%d]='%s'", i, saved_argv[i]);
+			rexec_argv[i] = saved_argv[i];
+		}
+		rexec_argv[rexec_argc] = "-R";
+		rexec_argv[rexec_argc + 1] = NULL;
+	}
+	listener_proctitle = prepare_proctitle(ac, av);
+
+	/* Ensure that umask disallows at least group and world write */
+	new_umask = umask(0077) | 0022;
+	(void) umask(new_umask);
+
+	/* Initialize the log (it is reinitialized below in case we forked). */
+	if (debug_flag && (!inetd_flag || rexeced_flag))
+		log_stderr = 1;
+	log_init(__progname, options.log_level,
+	    options.log_facility, log_stderr);
+	for (i = 0; i < options.num_log_verbose; i++)
+		log_verbose_add(options.log_verbose[i]);
+
+	/*
+	 * If not in debugging mode, not started from inetd and not already
+	 * daemonized (eg re-exec via SIGHUP), disconnect from the controlling
+	 * terminal, and fork.  The original process exits.
+	 */
+	already_daemon = daemonized();
+	if (!(debug_flag || inetd_flag || no_daemon_flag || already_daemon)) {
+
+		if (daemon(0, 0) == -1)
+			fatal("daemon() failed: %.200s", strerror(errno));
+
+		disconnect_controlling_tty();
+	}
+	/* Reinitialize the log (because of the fork above). */
+	log_init(__progname, options.log_level, options.log_facility, log_stderr);
+
+	/* Chdir to the root directory so that the current disk can be
+	   unmounted if desired. */
+	if (chdir("/") == -1)
+		error("chdir(\"/\"): %s", strerror(errno));
+
+	/* ignore SIGPIPE */
+	ssh_signal(SIGPIPE, SIG_IGN);
+
+	/* Get a connection, either from inetd or a listening TCP socket */
+	if (inetd_flag) {
+		server_accept_inetd(&sock_in, &sock_out);
+	} else {
+		platform_pre_listen();
+		server_listen();
+
+		ssh_signal(SIGHUP, sighup_handler);
+		ssh_signal(SIGCHLD, main_sigchld_handler);
+		ssh_signal(SIGTERM, sigterm_handler);
+		ssh_signal(SIGQUIT, sigterm_handler);
+
+		/*
+		 * Write out the pid file after the sigterm handler
+		 * is setup and the listen sockets are bound
+		 */
+		if (options.pid_file != NULL && !debug_flag) {
+			FILE *f = fopen(options.pid_file, "w");
+
+			if (f == NULL) {
+				error("Couldn't create pid file \"%s\": %s",
+				    options.pid_file, strerror(errno));
+			} else {
+				fprintf(f, "%ld\n", (long) getpid());
+				fclose(f);
+			}
+		}
+
+		/* Accept a connection and return in a forked child */
+		server_accept_loop(&sock_in, &sock_out,
+		    &newsock, config_s);
+	}
+
+	/* This is the child processing a new connection. */
+	setproctitle("%s", "[accepted]");
+
+	/*
+	 * Create a new session and process group since the 4.4BSD
+	 * setlogin() affects the entire process group.  We don't
+	 * want the child to be able to affect the parent.
+	 */
+#if !defined(SSHD_ACQUIRES_CTTY)
+	/*
+	 * If setsid is called, on some platforms sshd will later acquire a
+	 * controlling terminal which will result in "could not set
+	 * controlling tty" errors.
+	 */
+	if (!debug_flag && !inetd_flag && setsid() == -1)
+		error("setsid: %.100s", strerror(errno));
+#endif
+
+	if (rexec_flag) {
+		debug("rexec start in %d out %d newsock %d pipe %d sock %d",
+		    sock_in, sock_out, newsock, startup_pipe, config_s[0]);
+		dup2(newsock, STDIN_FILENO);
+		dup2(STDIN_FILENO, STDOUT_FILENO);
+		if (startup_pipe == -1)
+			close(REEXEC_STARTUP_PIPE_FD);
+		else if (startup_pipe != REEXEC_STARTUP_PIPE_FD) {
+			dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD);
+			close(startup_pipe);
+			startup_pipe = REEXEC_STARTUP_PIPE_FD;
+		}
+
+		dup2(config_s[1], REEXEC_CONFIG_PASS_FD);
+		close(config_s[1]);
+
+		ssh_signal(SIGHUP, SIG_IGN); /* avoid reset to SIG_DFL */
+		execv(rexec_argv[0], rexec_argv);
+
+		/* Reexec has failed, fall back and continue */
+		error("rexec of %s failed: %s", rexec_argv[0], strerror(errno));
+		recv_rexec_state(REEXEC_CONFIG_PASS_FD, NULL);
+		log_init(__progname, options.log_level,
+		    options.log_facility, log_stderr);
+
+		/* Clean up fds */
+		close(REEXEC_CONFIG_PASS_FD);
+		newsock = sock_out = sock_in = dup(STDIN_FILENO);
+		if (stdfd_devnull(1, 1, 0) == -1)
+			error_f("stdfd_devnull failed");
+		debug("rexec cleanup in %d out %d newsock %d pipe %d sock %d",
+		    sock_in, sock_out, newsock, startup_pipe, config_s[0]);
+	}
+
+	/* Executed child processes don't need these. */
+	fcntl(sock_out, F_SETFD, FD_CLOEXEC);
+	fcntl(sock_in, F_SETFD, FD_CLOEXEC);
+
+	/* We will not restart on SIGHUP since it no longer makes sense. */
+	ssh_signal(SIGALRM, SIG_DFL);
+	ssh_signal(SIGHUP, SIG_DFL);
+	ssh_signal(SIGTERM, SIG_DFL);
+	ssh_signal(SIGQUIT, SIG_DFL);
+	ssh_signal(SIGCHLD, SIG_DFL);
+	ssh_signal(SIGINT, SIG_DFL);
+
+	/*
+	 * Register our connection.  This turns encryption off because we do
+	 * not have a key.
+	 */
+	if ((ssh = ssh_packet_set_connection(NULL, sock_in, sock_out)) == NULL)
+		fatal("Unable to create connection");
+	the_active_state = ssh;
+	ssh_packet_set_server(ssh);
+
+/* Moved LIBWRAP check here */
+#ifdef LIBWRAP
+        allow_severity = options.log_facility|LOG_INFO;
+        deny_severity = options.log_facility|LOG_WARNING;
+        /* Check whether logins are denied from this host. */
+        if (ssh_packet_connection_is_on_socket(ssh)) {	/* This check must be after ssh_packet_set_connection() */
+		struct request_info req;
+
+		request_init(&req, RQ_DAEMON, __progname, RQ_FILE, sock_in, 0);
+		fromhost(&req);
+
+		if (!hosts_access(&req)) {
+			debug("Connection refused by tcp wrapper");
+			refuse(&req);
+			/* NOTREACHED */
+			fatal("libwrap refuse returns");
+		}
+	}
+#endif /* LIBWRAP */
+
+	check_ip_options(ssh);
+
+	/* Prepare the channels layer */
+	channel_init_channels(ssh);
+	channel_set_af(ssh, options.address_family);
+	process_permitopen(ssh, &options);
+
+	/* Set SO_KEEPALIVE if requested. */
+	if (options.tcp_keep_alive && ssh_packet_connection_is_on_socket(ssh) &&
+	    setsockopt(sock_in, SOL_SOCKET, SO_KEEPALIVE, &on, sizeof(on)) == -1)
+		error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
+
+	if ((remote_port = ssh_remote_port(ssh)) < 0) {
+		debug("ssh_remote_port failed");
+		cleanup_exit(255);
+	}
+
+	if (options.routing_domain != NULL)
+		set_process_rdomain(ssh, options.routing_domain);
+
+	/*
+	 * The rest of the code depends on the fact that
+	 * ssh_remote_ipaddr() caches the remote ip, even if
+	 * the socket goes away.
+	 */
+	remote_ip = ssh_remote_ipaddr(ssh);
+
+#ifdef SSH_AUDIT_EVENTS
+	audit_connection_from(remote_ip, remote_port);
+#endif
+
+	rdomain = ssh_packet_rdomain_in(ssh);
+
+	/* Log the connection. */
+	laddr = get_local_ipaddr(sock_in);
+	verbose("Connection from %s port %d on %s port %d%s%s%s",
+	    remote_ip, remote_port, laddr,  ssh_local_port(ssh),
+	    rdomain == NULL ? "" : " rdomain \"",
+	    rdomain == NULL ? "" : rdomain,
+	    rdomain == NULL ? "" : "\"");
+	free(laddr);
+
+	/*
+	 * We don't want to listen forever unless the other side
+	 * successfully authenticates itself.  So we set up an alarm which is
+	 * cleared after successful authentication.  A limit of zero
+	 * indicates no limit. Note that we don't set the alarm in debugging
+	 * mode; it is just annoying to have the server exit just when you
+	 * are about to discover the bug.
+	 */
+	ssh_signal(SIGALRM, grace_alarm_handler);
+	if (!debug_flag)
+		alarm(options.login_grace_time);
+
+	if ((r = kex_exchange_identification(ssh, -1,
+	    options.version_addendum)) != 0)
+		sshpkt_fatal(ssh, r, "banner exchange");
+
+	ssh_packet_set_nonblocking(ssh);
+
+	/* allocate authentication context */
+	authctxt = xcalloc(1, sizeof(*authctxt));
+	ssh->authctxt = authctxt;
+
+	authctxt->loginmsg = loginmsg;
+
+	/* XXX global for cleanup, access from other modules */
+	the_authctxt = authctxt;
+
+	/* Set default key authentication options */
+	if ((auth_opts = sshauthopt_new_with_keys_defaults()) == NULL)
+		fatal("allocation failed");
+
+	/* prepare buffer to collect messages to display to user after login */
+	if ((loginmsg = sshbuf_new()) == NULL)
+		fatal_f("sshbuf_new failed");
+	auth_debug_reset();
+
+	if (use_privsep) {
+		if (privsep_preauth(ssh) == 1)
+			goto authenticated;
+	} else if (have_agent) {
+		if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) {
+			error_r(r, "Unable to get agent socket");
+			have_agent = 0;
+		}
+	}
+
+	/* perform the key exchange */
+	/* authenticate user and start session */
+	do_ssh2_kex(ssh);
+	do_authentication2(ssh);
+
+	/*
+	 * If we use privilege separation, the unprivileged child transfers
+	 * the current keystate and exits
+	 */
+	if (use_privsep) {
+		mm_send_keystate(ssh, pmonitor);
+		ssh_packet_clear_keys(ssh);
+		exit(0);
+	}
+
+ authenticated:
+	/*
+	 * Cancel the alarm we set to limit the time taken for
+	 * authentication.
+	 */
+	alarm(0);
+	ssh_signal(SIGALRM, SIG_DFL);
+	authctxt->authenticated = 1;
+	if (startup_pipe != -1) {
+		close(startup_pipe);
+		startup_pipe = -1;
+	}
+
+#ifdef SSH_AUDIT_EVENTS
+	audit_event(ssh, SSH_AUTH_SUCCESS);
+#endif
+
+#ifdef GSSAPI
+	if (options.gss_authentication) {
+		temporarily_use_uid(authctxt->pw);
+		ssh_gssapi_storecreds();
+		restore_uid();
+	}
+#endif
+#ifdef USE_PAM
+	if (options.use_pam) {
+		do_pam_setcred(1);
+		do_pam_session(ssh);
+	}
+#endif
+
+	/*
+	 * In privilege separation, we fork another child and prepare
+	 * file descriptor passing.
+	 */
+	if (use_privsep) {
+		privsep_postauth(ssh, authctxt);
+		/* the monitor process [priv] will not return */
+	}
+
+	ssh_packet_set_timeout(ssh, options.client_alive_interval,
+	    options.client_alive_count_max);
+
+	/* Try to send all our hostkeys to the client */
+	notify_hostkeys(ssh);
+
+	/* Start session. */
+	do_authenticated(ssh, authctxt);
+
+	/* The connection has been terminated. */
+	ssh_packet_get_bytes(ssh, &ibytes, &obytes);
+	verbose("Transferred: sent %llu, received %llu bytes",
+	    (unsigned long long)obytes, (unsigned long long)ibytes);
+
+	verbose("Closing connection to %.500s port %d", remote_ip, remote_port);
+
+#ifdef USE_PAM
+	if (options.use_pam)
+		finish_pam();
+#endif /* USE_PAM */
+
+#ifdef SSH_AUDIT_EVENTS
+	PRIVSEP(audit_event(ssh, SSH_CONNECTION_CLOSE));
+#endif
+
+	ssh_packet_close(ssh);
+
+	if (use_privsep)
+		mm_terminate();
+
+	exit(0);
+}
+
+int
+sshd_hostkey_sign(struct ssh *ssh, struct sshkey *privkey,
+    struct sshkey *pubkey, u_char **signature, size_t *slenp,
+    const u_char *data, size_t dlen, const char *alg)
+{
+	int r;
+
+	if (use_privsep) {
+		if (privkey) {
+			if (mm_sshkey_sign(ssh, privkey, signature, slenp,
+			    data, dlen, alg, options.sk_provider, NULL,
+			    ssh->compat) < 0)
+				fatal_f("privkey sign failed");
+		} else {
+			if (mm_sshkey_sign(ssh, pubkey, signature, slenp,
+			    data, dlen, alg, options.sk_provider, NULL,
+			    ssh->compat) < 0)
+				fatal_f("pubkey sign failed");
+		}
+	} else {
+		if (privkey) {
+			if (sshkey_sign(privkey, signature, slenp, data, dlen,
+			    alg, options.sk_provider, NULL, ssh->compat) < 0)
+				fatal_f("privkey sign failed");
+		} else {
+			if ((r = ssh_agent_sign(auth_sock, pubkey,
+			    signature, slenp, data, dlen, alg,
+			    ssh->compat)) != 0) {
+				fatal_fr(r, "agent sign failed");
+			}
+		}
+	}
+	return 0;
+}
+
+/* SSH2 key exchange */
+static void
+do_ssh2_kex(struct ssh *ssh)
+{
+	char *myproposal[PROPOSAL_MAX] = { KEX_SERVER };
+	struct kex *kex;
+	int r;
+
+	myproposal[PROPOSAL_KEX_ALGS] = compat_kex_proposal(ssh,
+	    options.kex_algorithms);
+	myproposal[PROPOSAL_ENC_ALGS_CTOS] = compat_cipher_proposal(ssh,
+	    options.ciphers);
+	myproposal[PROPOSAL_ENC_ALGS_STOC] = compat_cipher_proposal(ssh,
+	    options.ciphers);
+	myproposal[PROPOSAL_MAC_ALGS_CTOS] =
+	    myproposal[PROPOSAL_MAC_ALGS_STOC] = options.macs;
+
+	if (options.compression == COMP_NONE) {
+		myproposal[PROPOSAL_COMP_ALGS_CTOS] =
+		    myproposal[PROPOSAL_COMP_ALGS_STOC] = "none";
+	}
+
+	if (options.rekey_limit || options.rekey_interval)
+		ssh_packet_set_rekey_limits(ssh, options.rekey_limit,
+		    options.rekey_interval);
+
+	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = compat_pkalg_proposal(
+	    ssh, list_hostkey_types());
+
+	/* start key exchange */
+	if ((r = kex_setup(ssh, myproposal)) != 0)
+		fatal_r(r, "kex_setup");
+	kex = ssh->kex;
+#ifdef WITH_OPENSSL
+	kex->kex[KEX_DH_GRP1_SHA1] = kex_gen_server;
+	kex->kex[KEX_DH_GRP14_SHA1] = kex_gen_server;
+	kex->kex[KEX_DH_GRP14_SHA256] = kex_gen_server;
+	kex->kex[KEX_DH_GRP16_SHA512] = kex_gen_server;
+	kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server;
+	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
+	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
+# ifdef OPENSSL_HAS_ECC
+	kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
+# endif
+#endif
+	kex->kex[KEX_C25519_SHA256] = kex_gen_server;
+	kex->kex[KEX_KEM_SNTRUP761X25519_SHA512] = kex_gen_server;
+	kex->load_host_public_key=&get_hostkey_public_by_type;
+	kex->load_host_private_key=&get_hostkey_private_by_type;
+	kex->host_key_index=&get_hostkey_index;
+	kex->sign = sshd_hostkey_sign;
+
+	ssh_dispatch_run_fatal(ssh, DISPATCH_BLOCK, &kex->done);
+
+#ifdef DEBUG_KEXDH
+	/* send 1st encrypted/maced/compressed message */
+	if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
+	    (r = sshpkt_put_cstring(ssh, "markus")) != 0 ||
+	    (r = sshpkt_send(ssh)) != 0 ||
+	    (r = ssh_packet_write_wait(ssh)) != 0)
+		fatal_fr(r, "send test");
+#endif
+	debug("KEX done");
+}
+
+/* server specific fatal cleanup */
+void
+cleanup_exit(int i)
+{
+	if (the_active_state != NULL && the_authctxt != NULL) {
+		do_cleanup(the_active_state, the_authctxt);
+		if (use_privsep && privsep_is_preauth &&
+		    pmonitor != NULL && pmonitor->m_pid > 1) {
+			debug("Killing privsep child %d", pmonitor->m_pid);
+			if (kill(pmonitor->m_pid, SIGKILL) != 0 &&
+			    errno != ESRCH) {
+				error_f("kill(%d): %s", pmonitor->m_pid,
+				    strerror(errno));
+			}
+		}
+	}
+#ifdef SSH_AUDIT_EVENTS
+	/* done after do_cleanup so it can cancel the PAM auth 'thread' */
+	if (the_active_state != NULL && (!use_privsep || mm_is_monitor()))
+		audit_event(the_active_state, SSH_CONNECTION_ABANDON);
+#endif
+	_exit(i);
+}
Index: openssh-8.5p1-new
===================================================================
--- openssh-8.5p1-new	(nonexistent)
+++ openssh-8.5p1-new	(revision 5)

Property changes on: openssh-8.5p1-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: .
===================================================================
--- .	(nonexistent)
+++ .	(revision 5)

Property changes on: .
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~