Index: /branches/amp_3_7_2/amp.spec
===================================================================
--- /branches/amp_3_7_2/amp.spec	(revision 2981)
+++ /branches/amp_3_7_2/amp.spec	(working copy)
@@ -1,3 +1,4 @@
+%define __brp_check_rpaths %{nil}
 Name:           amp
 Version:        3.7.2.34
 Release:        1%{?dist}
@@ -132,6 +133,8 @@
 install -dDm 0755 %{buildroot}/ca/conf/system/
 install -dDm 0755 %{buildroot}/ca/etc/
 install -dDm 0755 %{buildroot}/ca/webui/
+install -dDm 0755 %{buildroot}/ca/lib/
+install -dDm 0755 %{buildroot}/ca/libexec/
 install -dDm 0755 %{buildroot}/var/www/cgi-bin/
 install -dDm 0755 %{buildroot}/etc/logrotate.d/
 install -dDm 0755 %{buildroot}/etc/modprobe.d/
@@ -195,10 +198,18 @@
 install -Dm 0755 src/webui_agent/webui_agent %{buildroot}/ca/bin/
 install -Dm 0755 src/webui_monitor/webui_monitor %{buildroot}/ca/bin/
 cp -r src/webui/webui/* %{buildroot}/ca/webui
-install -Dm 0755 src/openssh/openssh-6.6p1/sshd %{buildroot}/ca/bin/
-install -Dm 0755 src/openssh/openssh-6.6p1/ssh %{buildroot}/ca/bin/
+install -Dm 0755 src/openssh/openssh-10.1p1/sshd %{buildroot}/ca/bin/
+install -Dm 0755 src/openssh/openssh-10.1p1/ssh %{buildroot}/ca/bin/
 install -Dm 0644 src/openssh/sshd_config %{buildroot}/ca/etc/
+install -Dm 0755 src/openssh/openssh-10.1p1/sshd-session %{buildroot}/ca/libexec/sshd-session
+install -Dm 0755 src/openssh/openssh-10.1p1/sshd-auth %{buildroot}/ca/libexec/sshd-auth
 install -Dm 0755 src/openssh/ssh-regenkey.sh %{buildroot}/ca/bin/
+# install openssl-1.1.1
+install -Dm 0755 -t %{buildroot}/ca/lib \
+	 src/openssh/*.so.1.1
+# install openssl-1.1.1's openssl app
+install -Dm 0755 -t %{buildroot}/ca/bin \
+	 src/openssh/openssl
 install -Dm 0755 src/webui/tftp/pulltftp %{buildroot}/ca/bin/
 install -Dm 0755 src/library/libpyexauth/_pyexauth.so %{buildroot}/usr/lib64/python2.7/site-packages/
 install -Dm 0755 src/library/libpyexauth/_cffi_backend.so %{buildroot}/usr/lib64/python2.7/site-packages/
@@ -278,6 +289,10 @@
 %attr (755,root,root)/ca/bin/ssh
 %attr (755,root,root)/ca/bin/ssh-regenkey.sh
 %attr (644,root,root)/ca/etc/sshd_config
+%attr (755,root,root)/ca/libexec/sshd-session
+%attr (755,root,root)/ca/libexec/sshd-auth
+%attr (644,root,root)/ca/lib/*
+%attr (644,root,root)/ca/bin/openssl
 %attr (755,root,root)/ca/bin/pulltftp
 %attr (755,root,root)/usr/lib64/python2.7/site-packages/_pyexauth.so
 %attr (755,root,root)/usr/lib64/python2.7/site-packages/_cffi_backend.so
Index: /branches/amp_3_7_2/init/cassh.service
===================================================================
--- /branches/amp_3_7_2/init/cassh.service	(revision 2981)
+++ /branches/amp_3_7_2/init/cassh.service	(working copy)
@@ -3,11 +3,10 @@
 After=network.service
 
 [Service]
-Type=forking
-PIDFile=/var/run/sshd.pid
+Type=simple
 ExecStartPre=/ca/bin/cassh_init.sh
-ExecStart=/ca/bin/sshd -f /ca/etc/sshd_config
+ExecStart=/ca/bin/sshd -f /ca/etc/sshd_config -D
 KillMode=process
 
 [Install]
-WantedBy=multi-user.target
\ No newline at end of file
+WantedBy=multi-user.target
Index: /branches/amp_3_7_2/src/library/Makefile
===================================================================
--- /branches/amp_3_7_2/src/library/Makefile	(revision 2981)
+++ /branches/amp_3_7_2/src/library/Makefile	(working copy)
@@ -11,12 +11,42 @@
 # lets not fail the entire build, but still be noise about failing to
 # build the UI
 
-all:
+build-all:
 	@for i in ${SDIRS} ; do echo `/bin/pwd`/$${i}; cd $${i}; \
 	make all || exit "$$?"; cd ..; done
 
 # Clean doesnt require a bison check, install and all do
-clean :
+clean-all :
 	@for i in ${SDIRS} ; do echo `/bin/pwd`/$${i}; cd $${i}; \
 	make clean || exit "$$?"; cd ..; done
 	$(RM) -f include/gen.h
+OPENSSL_TAR = openssl-1.1.1d.tar.gz
+OPENSSL_DIR = openssl-1.1.1d
+INSTALL_DIR = $(CURDIR)/../openssh/libopenssl-1.1.1
+
+# The target that build.sh will check for
+TARGET = $(INSTALL_DIR)/lib/libssl.so
+
+all: build-all $(TARGET)
+
+$(TARGET):
+	@echo "Configuring and building OpenSSL..."
+	# Extract
+	tar -xf $(OPENSSL_TAR)
+	# Configure with 'shared' (required for dynamic linking)
+	cd $(OPENSSL_DIR) && ./config --prefix=$(INSTALL_DIR) --openssldir=$(INSTALL_DIR)/ssl shared
+	# Build and Install
+	cd $(OPENSSL_DIR) && make -j$(shell nproc)
+	cd $(OPENSSL_DIR) && make install
+	cp $(OPENSSL_DIR)/libcrypto.so* $(INSTALL_DIR)/../
+	cp $(OPENSSL_DIR)/libssl.so* $(INSTALL_DIR)/../
+	cp $(OPENSSL_DIR)/apps/openssl $(INSTALL_DIR)/../
+	# Cleanup source to keep directory clean
+	rm -rf $(OPENSSL_DIR)
+
+clean-openssl:
+	rm -rf $(OPENSSL_DIR) $(INSTALL_DIR)
+
+clean: clean-all clean-openssl
+
+.PHONY: all build-all $(TARGET) clean clean-all clean-openssl
Index: /branches/amp_3_7_2/src/library/avx_log/avx_log.h
===================================================================
--- /branches/amp_3_7_2/src/library/avx_log/avx_log.h	(revision 2981)
+++ /branches/amp_3_7_2/src/library/avx_log/avx_log.h	(working copy)
@@ -69,6 +69,7 @@
 	WEBUI_MESSAGE,
 	AUTH_SSH_LOGIN,
 	AUTH_SSH_LOGOUT,
+	AUTH_USER_LOCK,
 	SSHD_LOGIN_MSG_FTOK,
 	SSHD_LOGIN_MSG_GET,
 	SSHD_LOGIN_MSG_SEND,
Index: /branches/amp_3_7_2/src/library/avx_log/avx_log.c
===================================================================
--- /branches/amp_3_7_2/src/library/avx_log/avx_log.c	(revision 2981)
+++ /branches/amp_3_7_2/src/library/avx_log/avx_log.c	(working copy)
@@ -104,6 +104,7 @@
 	{WEBUI_MESSAGE, AVXLOG_INFO, 1, "%s", NULL, NULL},
     {AUTH_SSH_LOGIN, AVXLOG_INFO, 6,"user %.100s log in by SSH from ip %.200s port %d to ip %.200s port %d%s", NULL,NULL},
     {AUTH_SSH_LOGOUT, AVXLOG_INFO, 5,"user %.100s log out by SSH from ip %.200s port %d to ip %.200s port %d", NULL,NULL},
+ { AUTH_USER_LOCK, AVXLOG_INFO, 3,"The user \"%s\" has failed to log in more than %d consecutive times and will be locked %d seconds.",NULL,NULL},
     {SSHD_LOGIN_MSG_FTOK, AVXLOG_ERR, 0, "sshd login msgq ftok error", NULL, "nternal error: Failed to get the user account login message key in sshd."},
     {SSHD_LOGIN_MSG_GET, AVXLOG_ERR, 0, "sshd login msgq get error", NULL, "Internal error: Failed to get the user account login message."}, 
     {SSHD_LOGIN_MSG_SEND, AVXLOG_ERR, 0, "sshd login msgq send error", NULL,NULL},
Index: /branches/amp_3_7_2/src/library/openssl-1.1.1d.tar.gz
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/x-gzip
Index: /branches/amp_3_7_2/src/library/openssl-1.1.1d.tar.gz
===================================================================
--- /branches/amp_3_7_2/src/library/openssl-1.1.1d.tar.gz	(revision 2981)
+++ /branches/amp_3_7_2/src/library/openssl-1.1.1d.tar.gz	(working copy)

Property changes on: src/library/openssl-1.1.1d.tar.gz
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Added: svn:mime-type
## -0,0 +1 ##
+application/x-gzip
\ No newline at end of property
Index: /branches/amp_3_7_2/src/openssh/CVE-2023-48795-mitigation.patch
===================================================================
--- /branches/amp_3_7_2/src/openssh/CVE-2023-48795-mitigation.patch	(revision 0)
+++ /branches/amp_3_7_2/src/openssh/CVE-2023-48795-mitigation.patch	(working copy)
@@ -0,0 +1,21 @@
+diff --git a/myproposal.h.orig b/myproposal.h
+index 3d30ce1..3f83359 100644
+--- a/myproposal.h.orig
++++ b/myproposal.h
+@@ -59,16 +59,12 @@
+ 	"rsa-sha2-256"
+ 
+ #define	KEX_SERVER_ENCRYPT \
+-	"chacha20-poly1305@openssh.com," \
+ 	"aes128-gcm@openssh.com,aes256-gcm@openssh.com," \
+ 	"aes128-ctr,aes192-ctr,aes256-ctr"
+ 
+ #define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT
+ 
+ #define	KEX_SERVER_MAC \
+-	"umac-128-etm@openssh.com," \
+-	"hmac-sha2-256-etm@openssh.com," \
+-	"hmac-sha2-512-etm@openssh.com," \
+ 	"umac-128@openssh.com," \
+ 	"hmac-sha2-256," \
+ 	"hmac-sha2-512"
Index: /branches/amp_3_7_2/src/openssh/Makefile
===================================================================
--- /branches/amp_3_7_2/src/openssh/Makefile	(revision 2981)
+++ /branches/amp_3_7_2/src/openssh/Makefile	(working copy)
@@ -2,12 +2,17 @@
 
 include $(TOP)/Makefile.master
 
+OPENSSH_FOLDER=openssh-10.1p1
+
+
 all:
 	./build.sh all
 clean:
-	rm -rf openssh-6.6p1
+	rm -rf ${OPENSSH_FOLDER}
 realclean:
 	git clean -dfx .
 install:
-	install -Dm 0755 -t ${ANROOT}/ca/bin/  ${.CURDIR}/openssh-6.6p1/sshd ${.CURDIR}/openssh-6.6p1/ssh
-	install -Dm 0755 -t ${ANROOT}/ca/etc/ ${.CURDIR}/sshd_config
+	install -Dm 0755 -t ${ANROOT}/ca/bin/  ${.CURDIR}/${OPENSSH_FOLDER}/sshd ${.CURDIR}/${OPENSSH_FOLDER}/ssh ${.CURDIR}/${OPENSSH_FOLDER}/ssh-keygen
+	install -Dm 0755 -t ${.CURDIR}/sshd_config  ${ANROOT}/ca/etc/
+	install -Dm 0755 ${.CURDIR}/${OPENSSH_FOLDER}/sshd-session ${ANROOT}/ca/libexec/sshd-session
+	install -Dm 0755 ${.CURDIR}/${OPENSSH_FOLDER}/sshd-auth ${ANROOT}/ca/libexec/sshd-auth
Index: /branches/amp_3_7_2/src/openssh/array.patch
===================================================================
--- /branches/amp_3_7_2/src/openssh/array.patch	(revision 0)
+++ /branches/amp_3_7_2/src/openssh/array.patch	(working copy)
@@ -0,0 +1,5590 @@
+From 04d0501ee881608cb6c2ded7d94f65e469611db8 Mon Sep 17 00:00:00 2001
+From: Li Wang <wli@arraynetworks.net>
+Date: Wed, 29 Apr 2026 15:54:02 +0800
+Subject: [PATCH] array
+
+---
+ 0001-array.patch | 1858 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ Makefile.in      |   21 +-
+ array.patch      | 1858 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ auth-passwd.c    |   55 +-
+ auth.h           |    2 +-
+ auth2.c          |  307 ++++++++-
+ configure        |    2 +-
+ monitor.c        |  205 +++++-
+ monitor.h        |    2 +
+ monitor_wrap.c   |   34 +
+ monitor_wrap.h   |    2 +
+ readconf.c       |   10 +
+ readconf.h       |    2 +
+ servconf.c       |    7 +-
+ servconf.h       |    3 +-
+ session.c        |   53 +-
+ ssh.c            |   15 +-
+ sshconnect.c     |   39 +-
+ sshconnect.h     |    2 +-
+ sshconnect2.c    |   40 +-
+ sshd-session.c   |  221 ++++++-
+ sshd.c           |  165 ++++-
+ 22 files changed, 4845 insertions(+), 58 deletions(-)
+ create mode 100644 0001-array.patch
+ create mode 100644 array.patch
+
+diff --git a/0001-array.patch b/0001-array.patch
+new file mode 100644
+index 0000000..85a37ff
+--- /dev/null
++++ b/0001-array.patch
+@@ -0,0 +1,1858 @@
++From 2dc9e5d92283c1cc110b9a82d79840f87c66a916 Mon Sep 17 00:00:00 2001
++From: Li Wang <wli@arraynetworks.net>
++Date: Wed, 29 Apr 2026 15:54:02 +0800
++Subject: [PATCH] array
++
++---
++ Makefile.in    |  21 ++--
++ auth-passwd.c  |  55 ++++++++++-
++ auth.h         |   2 +-
++ auth2.c        | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
++ configure      |   2 +-
++ monitor.c      | 205 ++++++++++++++++++++++++++++++++++++--
++ monitor.h      |   2 +
++ monitor_wrap.c |  34 +++++++
++ monitor_wrap.h |   2 +
++ readconf.c     |  10 ++
++ readconf.h     |   2 +
++ servconf.c     |   7 +-
++ servconf.h     |   3 +-
++ session.c      |  53 +++++++++-
++ ssh.c          |  15 ++-
++ sshconnect.c   |  39 +++++++-
++ sshconnect.h   |   2 +-
++ sshconnect2.c  |  40 +++++---
++ sshd-session.c | 221 ++++++++++++++++++++++++++++++++++++++++-
++ sshd.c         | 165 ++++++++++++++++++++++++++++++-
++ 20 files changed, 1129 insertions(+), 58 deletions(-)
++
++diff --git a/Makefile.in b/Makefile.in
++index 760fbaa..e8b0d65 100644
++--- a/Makefile.in
+++++ b/Makefile.in
++@@ -75,7 +75,7 @@ MKDIR_P=@MKDIR_P@
++ 
++ .SUFFIXES: .lo
++ 
++-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) $(SK_STANDALONE)
+++TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) synconfigd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) $(SK_STANDALONE)
++ 
++ LIBOPENSSH_OBJS=\
++ 	ssh_api.o \
++@@ -176,8 +176,11 @@ MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out
++ MANPAGES_IN	= moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-sk-helper.8 sshd_config.5 ssh_config.5
++ MANTYPE		= @MANTYPE@
++ 
++-CONFIGFILES=sshd_config.out ssh_config.out moduli.out
++-CONFIGFILES_IN=sshd_config ssh_config moduli
+++# CONFIGFILES=sshd_config.out ssh_config.out moduli.out
+++# CONFIGFILES_IN=sshd_config ssh_config moduli
+++
+++INST_BIN=${TARGETS}
+++INST_CONF=ssh_config sshd_config moduli
++ 
++ PATHSUBS	= \
++ 	-e 's|/etc/ssh/ssh_config|$(sysconfdir)/ssh_config|g' \
++@@ -201,7 +204,8 @@ FIXPATHSCMD	= $(SED) $(PATHSUBS)
++ FIXALGORITHMSCMD= $(SHELL) $(srcdir)/fixalgorithms $(SED) \
++ 		     @UNSUPPORTED_ALGORITHMS@
++ 
++-all: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
+++#all: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
+++all: $(CONFIGFILES) $(TARGETS)
++ 
++ $(LIBSSH_OBJS): Makefile.in config.h
++ $(SSHOBJS): Makefile.in config.h
++@@ -223,13 +227,16 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
++ 	$(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(GSSLIBS) $(CHANNELLIBS)
++ 
++ sshd$(EXEEXT): libssh.a	$(LIBCOMPAT) $(SSHDOBJS)
++-	$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS)
+++	$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lssl -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) -L ../../objdir/ -L../../library/libexauth -lexauth -lrt -lcrypto -L../../library/avx_log -lavxlog
+++
+++synconfigd$(EXEEXT): sshd$(EXEEXT)
+++	/bin/cp sshd$(EXEEXT) $@
++ 
++ sshd-session$(EXEEXT): libssh.a	$(LIBCOMPAT) $(SSHD_SESSION_OBJS)
++-	$(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB)
+++	$(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lssl -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) -L ../../objdir/ -L../../library/libexauth -lexauth  -lrt -lcrypto -L../../library/avx_log -lavxlog
++ 
++ sshd-auth$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_AUTH_OBJS)
++-	$(LD) -o $@ $(SSHD_AUTH_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB)
+++	$(LD) -o $@ $(SSHD_AUTH_OBJS) $(LDFLAGS) -lssh -lssl -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) -L ../../objdir/ -L../../library/libexauth -lexauth -lrt -lcrypto -L../../library/avx_log -lavxlog
++ 
++ scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS)
++ 	$(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
++diff --git a/auth-passwd.c b/auth-passwd.c
++index a9d7688..88e5b05 100644
++--- a/auth-passwd.c
+++++ b/auth-passwd.c
++@@ -56,6 +56,21 @@
++ #include "auth.h"
++ #include "auth-options.h"
++ 
+++/*
+++ * authenticate with external server
+++ */
+++#include "auth_ext.h"
+++#if defined(__linux__)
+++#include "auth_ext_cli.h"
+++#include "auth_ext_ipc.h"
+++#else
+++#include "../../ui/exauth/auth_ext_cli.h"
+++#include "../../ui/exauth/auth_ext_ipc.h"
+++#endif
+++
+++int ext_authorize_level = 0; /* 0: enable, 1: config */
+++int ext_authenticated = 0;
+++
++ extern struct sshbuf *loginmsg;
++ extern ServerOptions options;
++ 
++@@ -74,7 +89,7 @@ extern login_cap_t *lc;
++  * authentication succeeds.
++  */
++ int
++-auth_password(struct ssh *ssh, const char *password)
+++auth_password(struct ssh *ssh, const char *user, const char *password)
++ {
++ 	Authctxt *authctxt = ssh->authctxt;
++ 	struct passwd *pw = authctxt->pw;
++@@ -122,9 +137,41 @@ auth_password(struct ssh *ssh, const char *password)
++ 			authctxt->force_pwchange = 1;
++ 	}
++ #endif
++-	result = sys_auth_passwd(ssh, password);
++-	if (authctxt->force_pwchange)
++-		auth_restrict_session(ssh);
+++
+++	/* admin aaa on */
+++	if (is_external_auth_on()) {
+++		/* check user exist in local database */
+++		int local_exist = 0;
+++		if (getpwnam(user)) {
+++			local_exist = 1;
+++		}
+++
+++		/* do external auth if user not exist or exauth high priority */
+++		if (exauth_priority() == EXAUTH_PRIORITY_HIGH || !local_exist) {
+++			int ret_value = external_auth(user, password);
+++			if (ret_value == EXT_AUTH_PASS_CONFIG ) {
+++				ext_authenticated = 1;
+++				ext_authorize_level = 1;
+++				result = 1;
+++			} else if (ret_value == EXT_AUTH_PASS_ENABLE) {
+++				ext_authenticated = 1;
+++				ext_authorize_level = 0;
+++				result = 1;
+++			} else {
+++				result = 0;
+++			}
+++		}
+++
+++		/* check local database */
+++		if(local_exist && !ext_authenticated)
+++			result = sys_auth_passwd(ssh, password);
+++	/* admin aaa off */
+++	} else {
+++		result = sys_auth_passwd(ssh, password);
+++		if (authctxt->force_pwchange)
+++			auth_restrict_session(ssh);
+++	}
+++
++ 	return (result && ok);
++ }
++ 
++diff --git a/auth.h b/auth.h
++index 98bb23d..1ae19ec 100644
++--- a/auth.h
+++++ b/auth.h
++@@ -135,7 +135,7 @@ struct KbdintDevice
++ int
++ auth_rhosts2(struct passwd *, const char *, const char *, const char *);
++ 
++-int      auth_password(struct ssh *, const char *);
+++int      auth_password(struct ssh *, const char *, const char *);
++ 
++ int	 hostbased_key_allowed(struct ssh *, struct passwd *,
++ 	    const char *, char *, struct sshkey *);
++diff --git a/auth2.c b/auth2.c
++index b9bb46f..987ad03 100644
++--- a/auth2.c
+++++ b/auth2.c
++@@ -29,6 +29,10 @@
++ #include <sys/stat.h>
++ #include <sys/uio.h>
++ 
+++#include <sys/ipc.h>
+++#include <sys/shm.h>
+++#include <sys/time.h>
+++
++ #include <fcntl.h>
++ #include <limits.h>
++ #include <pwd.h>
++@@ -102,6 +106,185 @@ static char *authmethods_get(Authctxt *authctxt);
++ #define MATCH_PARTIAL	3	/* method matches, submethod can't be checked */
++ static int list_starts_with(const char *, const char *, const char *);
++ 
+++#define USER_LOGIN_SHM_KEY		0xcaf02002 /* Need sync to usr/src/sys/click/app/proxy/proxy_shm.h */
+++#define MAXUSERS_LOGIN			100
+++#define MAX_USER_NAME_SIZE		256
+++
+++/* If change this struct, need to synchronously change the struct in user.h, auth2.c and login.c */
+++typedef struct user_login_info {
+++	struct {
+++		char name[MAX_USER_NAME_SIZE];
+++		int  continuous_fail_count;
+++		int  locked;
+++		long next_login_time;
+++	} user[MAXUSERS_LOGIN];
+++	int passwd_forcemode;
+++	int max_login_retry;
+++	int lock_user_time;
+++} user_login_info_t;
+++
+++static user_login_info_t *user_login_p;
+++static int user_index;
+++
+++static void
+++login_info_shm_detach(void)
+++{
+++	int ret;
+++	if (user_login_p) {
+++		ret = shmdt(user_login_p);
+++		if (ret == 0) {
+++			user_login_p = NULL;
+++		}
+++	}
+++}
+++
+++static int
+++login_info_shm_attach(void)
+++{
+++	int shm_id;
+++	void *p = NULL;
+++
+++	if (user_login_p) {
+++		return 0;
+++	}
+++
+++	shm_id = shmget(USER_LOGIN_SHM_KEY, sizeof(user_login_info_t), IPC_CREAT | 0666);
+++	if (shm_id < 0) {
+++		user_login_p = NULL;
+++		return -1;
+++	}
+++
+++	p = shmat(shm_id, NULL, 0);
+++	if ((long)p == -1) {
+++		return -1;
+++	}
+++
+++	user_login_p = (user_login_info_t *) p;
+++
+++	atexit(login_info_shm_detach);
+++
+++	return 0;
+++}
+++
+++static int
+++user_login_info_add(char *name)
+++{
+++	int i;
+++	user_login_info_t *p;
+++
+++	if (user_login_p == NULL) {
+++		return -1;
+++	}
+++
+++	p = user_login_p;
+++	if (NULL == name || name[0] == '\0') {
+++		return -1;
+++	}
+++
+++	if (!strcmp(name, "test") || !strcmp(name, "root")) {
+++		/* we don't check test and root user */
+++		return -1;
+++	}
+++
+++	for (i = 0; i < MAXUSERS_LOGIN; i++) {
+++		if (p->user[i].name[0] == '\0') {
+++			strncpy(p->user[i].name, name, sizeof(p->user[i].name));
+++			return i;
+++		}
+++	}
+++	return -1;
+++}
+++
+++static int
+++get_user_index(char *name)
+++{
+++	int i;
+++	user_login_info_t *p;
+++
+++	if (user_login_p == NULL) {
+++		return -1;
+++	}
+++
+++	p = user_login_p;
+++
+++	if (NULL == name || name[0] == '\0') {
+++		return -1;
+++	}
+++	for(i = 0; i < MAXUSERS_LOGIN; i++) {
+++		if (p->user[i].name[0] == '\0') {
+++			continue;
+++		}
+++
+++		if (!strcmp(p->user[i].name, name)) {
+++			return i;
+++		}
+++	}
+++
+++	return -1;
+++}
+++
+++static int
+++check_user_locked(int index)
+++{
+++	struct timeval tv;
+++	user_login_info_t *p;
+++
+++	if (index == -1) {
+++		return 0;
+++	}
+++
+++	if (user_login_p == NULL) {
+++		return 0;
+++	}
+++	p = user_login_p;
+++
+++	bzero(&tv, sizeof(tv));
+++	gettimeofday(&tv, NULL);
+++
+++	if (p->user[index].locked && p->user[index].next_login_time > tv.tv_sec) {
+++		return 1;
+++	}
+++
+++	if (p->user[index].locked) {
+++		/* unlock the user, clear the item */
+++		bzero(&p->user[index], sizeof(p->user[index]));
+++	}
+++
+++	p->user[index].locked = 0;
+++
+++	return 0;
+++}
+++
+++static int
+++lock_user(struct ssh *ssh, int index)
+++{
+++	struct timeval tv;
+++	user_login_info_t *p;
+++
+++	if (index == -1) {
+++		return -1;
+++	}
+++
+++	if (user_login_p == NULL) {
+++		return -1;
+++	}
+++	p = user_login_p;
+++
+++	bzero(&tv, sizeof(tv));
+++	gettimeofday(&tv, NULL);
+++
+++	p->user[index].next_login_time = tv.tv_sec + user_login_p->lock_user_time; /* lock the user login 300 seconds */
+++	p->user[index].locked = 1;
+++
+++	mm_lock_fastlog(ssh, p->user[index].name, user_login_p->max_login_retry, user_login_p->lock_user_time);
+++
+++	ssh_packet_disconnect(ssh, "\nThe user \"%s\" has failed to log in more than %d consecutive times and has been locked.\n"
+++			"Please retry after %d seconds or change to another user.\n",
+++			p->user[index].name, user_login_p->max_login_retry, (uint32_t)(p->user[index].next_login_time - tv.tv_sec));
+++
+++	return 0;
+++}
+++
++ char *
++ auth2_read_banner(void)
++ {
++@@ -284,25 +467,40 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
++ 	debug("userauth-request for user %s service %s method %s", user, service, method);
++ 	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
++ 
+++	login_info_shm_attach();
+++
++ 	if ((style = strchr(user, ':')) != NULL)
++ 		*style++ = 0;
++ 
++ 	if (authctxt->attempt >= 1024)
++ 		auth_maxtries_exceeded(ssh);
++ 	if (authctxt->attempt++ == 0) {
++-		/* setup auth context */
++-		authctxt->pw = mm_getpwnamallow(ssh, user);
++-		authctxt->user = xstrdup(user);
++-		if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
+++		/*
+++		 *  exauth is on, use external auth
+++		 */		
+++		if (is_external_auth_on() && options.synconfig == 0) {
+++			authctxt->pw = mm_getpwnamallow(ssh, user);
+++			authctxt->user = xstrdup(user);
++ 			authctxt->valid = 1;
++-			debug2_f("setting up authctxt for %s", user);
+++		/*
+++		 *  exauth is off, use local auth
+++		 *  note: when exauth is off, if local auth failed, won't do external authentication
+++		 */
++ 		} else {
++-			authctxt->valid = 0;
++-			/* Invalid user, fake password information */
++-			authctxt->pw = fakepw();
+++			/* setup auth context */
+++			authctxt->pw = mm_getpwnamallow(ssh, user);
+++			authctxt->user = xstrdup(user);
+++			if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
+++				authctxt->valid = 1;
+++				debug2_f("setting up authctxt for %s", user);
+++			} else {
+++				authctxt->valid = 0;
+++				/* Invalid user, fake password information */
+++				authctxt->pw = fakepw();
++ #ifdef SSH_AUDIT_EVENTS
++-			mm_audit_event(ssh, SSH_INVALID_USER);
+++				mm_audit_event(ssh, SSH_INVALID_USER);
++ #endif
+++			}
++ 		}
++ #ifdef USE_PAM
++ 		if (options.use_pam)
++@@ -339,6 +537,33 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
++ 	authctxt->postponed = 0;
++ 	authctxt->server_caused_failure = 0;
++ 
+++	if (user_login_p && user_login_p->passwd_forcemode) {
+++		user_index = get_user_index(authctxt->user);
+++
+++		if ((user_index != -1) && check_user_locked(user_index)) {
+++			struct timeval tv;
+++			user_login_info_t *p;
+++			int index = user_index;
+++
+++			free(service);
+++			free(user);
+++			free(method);
+++
+++			p = user_login_p;
+++
+++			bzero(&tv, sizeof(tv));
+++			gettimeofday(&tv, NULL);
+++
+++			mm_lock_fastlog(ssh, p->user[index].name, user_login_p->max_login_retry, (uint32_t)(p->user[index].next_login_time - tv.tv_sec));
+++
+++			/* packet_disconnect will exit the process, so need free memory before it */
+++			ssh_packet_disconnect(ssh, "\nThe user \"%s\" has failed to log in more than %d consecutive times and has been locked.\n"
+++					"Please retry after %d seconds or change to another user.\n",
+++					p->user[index].name, user_login_p->max_login_retry, (uint32_t)(p->user[index].next_login_time - tv.tv_sec));
+++			return 0;
+++		}
+++	}
+++
++ 	/* try to authenticate user */
++ 	m = authmethod_lookup(authctxt, method);
++ 	if (m != NULL && authctxt->failures < options.max_authtries) {
++@@ -357,6 +582,30 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
++ 	return r;
++ }
++ 
+++/*
+++ * 0, no need to defend and update timer;
+++ * 1, defended and reset timer;
+++ * -1, defend failed.
+++ */
+++static int
+++defend_dos_attack() {
+++       static time_t last;
+++       time_t cur;
+++
+++       cur = time(NULL);
+++ /branches/amp_3_7_2	if (cur == -1) {
+++               return -1;
+++       }
+++ /branches/amp_3_7_2	if (last!=0 && cur-last==0) {
+++               sleep(3);
+++               last = 0;
+++               return 1;
+++       }
+++
+++       last = cur;
+++       return 0;
+++}
+++
++ void
++ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
++     const char *submethod)
++@@ -398,6 +647,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
++ 
++ 	/* Log before sending the reply */
++ 	auth_log(ssh, authenticated, partial, method, submethod);
+++	defend_dos_attack();
++ 
++ 	/* Update information exposed to session */
++ 	if (authenticated || partial)
++@@ -436,14 +686,49 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
++ 		    (r = sshpkt_send(ssh)) != 0 ||
++ 		    (r = ssh_packet_write_wait(ssh)) != 0)
++ 			fatal_fr(r, "send success packet");
+++
+++		if (user_login_p && user_login_p->passwd_forcemode) {
+++			if (user_index != -1) {
+++				/* login success, clear the item */
+++				bzero(&user_login_p->user[user_index], sizeof(user_login_p->user[user_index]));
+++			}
+++		}
+++
++ 		/* now we can break out */
++ 		authctxt->success = 1;
++ 		ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user);
++ 	} else {
++ 		/* Allow initial try of "none" auth without failure penalty */
++ 		if (!partial && !authctxt->server_caused_failure &&
++-		    (authctxt->attempt > 1 || strcmp(method, "none") != 0))
+++			(authctxt->attempt > 1 || strcmp(method, "none") != 0)) {
++ 			authctxt->failures++;
+++
+++			if (user_login_p && user_login_p->passwd_forcemode) {
+++				if (user_index == -1) {
+++					user_index = user_login_info_add(authctxt->user);
+++				}
+++
+++				if (user_index != -1) {
+++					user_login_p->user[user_index].continuous_fail_count++;
+++					if (user_login_p->user[user_index].continuous_fail_count >= user_login_p->max_login_retry) {
+++						/* record fastlog */
+++						methods = authmethods_get(authctxt);
+++						debug3("%s: failure partial=%d next methods=\"%s\"", __func__,
+++							partial, methods);
+++						mm_auth_fastlog(ssh, authenticated, method);
+++						free(methods);
+++						lock_user(ssh, user_index);
+++						return;
+++					} else {
+++						char lock_buf[256];
+++						sprintf(lock_buf, "\nThe user \"%s\" will be locked if it fails to log in more than %d consecutive times.\n",
+++							authctxt->user, user_login_p->max_login_retry - user_login_p->user[user_index].continuous_fail_count);
+++						userauth_send_banner(ssh, lock_buf);
+++					}
+++				}
+++			}
+++		}
+++
++ 		if (authctxt->failures >= options.max_authtries) {
++ #ifdef SSH_AUDIT_EVENTS
++ 			mm_audit_event(ssh, SSH_LOGIN_EXCEED_MAXTRIES);
++@@ -459,6 +744,8 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
++ 		    (r = sshpkt_send(ssh)) != 0 ||
++ 		    (r = ssh_packet_write_wait(ssh)) != 0)
++ 			fatal_fr(r, "send failure packet");
+++		if(strcmp(method, "none") != 0)
+++			mm_auth_fastlog(ssh, authenticated, method);
++ 		free(methods);
++ 	}
++ }
++diff --git a/configure b/configure
++index 74539c8..afa2d99 100755
++--- a/configure
+++++ b/configure
++@@ -883,7 +883,7 @@ sbindir='${exec_prefix}/sbin'
++ libexecdir='${exec_prefix}/libexec'
++ datarootdir='${prefix}/share'
++ datadir='${datarootdir}'
++-sysconfdir='${prefix}/etc'
+++sysconfdir='${prefix}/conf'
++ sharedstatedir='${prefix}/com'
++ localstatedir='${prefix}/var'
++ runstatedir='${localstatedir}/run'
++diff --git a/monitor.c b/monitor.c
++index a9e854b..bee336a 100644
++--- a/monitor.c
+++++ b/monitor.c
++@@ -88,6 +88,38 @@
++ #include "sk-api.h"
++ #include "srclimit.h"
++ 
+++#include <syslog.h>
+++#include <unistd.h>
+++#include <sys/msg.h>
+++#include <sys/ipc.h>
+++#include <sys/shm.h>
+++#include <sys/time.h>
+++#if defined(__linux__)
+++#define __printflike(x, y)
+++#endif
+++#include "avx_log.h"
+++
+++#define MAX_USER_NAME_SIZE		256
+++
+++#define SSHD_LOGIN_MSGQ_PATH "/var/crash/sshd_login_msgq"
+++#define SSHD_LOGIN_MSGQ_LEN 100
+++#if defined(__linux__)
+++#define SSHD_MSGQ_MODE  (O_RDWR)
+++#else
+++#define SSHD_MSGQ_MODE  (IPC_R | IPC_W | IPC_R>>3 |IPC_W>>3 | IPC_R>>6 | IPC_W>>6)
+++#endif
+++
+++typedef struct login_msgbuf {
+++       long mtype;
+++       char mtext [SSHD_LOGIN_MSGQ_LEN];
+++} login_msgbuf;
+++
+++typedef struct login_msgbuf_templet{
+++       long type;
+++       unsigned long addr;
+++       unsigned int port;
+++} login_msgbuf_templet;
+++
++ #ifdef GSSAPI
++ static Gssctxt *gsscontext = NULL;
++ #endif
++@@ -141,6 +173,9 @@ int mm_answer_audit_event(struct ssh *, int, struct sshbuf *);
++ int mm_answer_audit_command(struct ssh *, int, struct sshbuf *);
++ #endif
++ 
+++int mm_answer_auth_faslog(struct ssh *, int, struct sshbuf *);
+++int mm_answer_lock_fastlog(struct ssh *, int, struct sshbuf *);
+++
++ static Authctxt *authctxt;
++ 
++ /* local state for key verify */
++@@ -209,6 +244,8 @@ struct mon_table mon_dispatch_proto20[] = {
++     {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok},
++     {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic},
++ #endif
+++    {MONITOR_REQ_AUTH_FASTLOG, MON_PERMIT, mm_answer_auth_faslog},
+++    {MONITOR_REQ_LOCK_FASTLOG, MON_PERMIT, mm_answer_lock_fastlog},
++     {0, 0, NULL}
++ };
++ 
++@@ -230,6 +267,148 @@ struct mon_table mon_dispatch_postauth20[] = {
++ 
++ struct mon_table *mon_dispatch;
++ 
+++void
+++push_addr_msg(int pid, unsigned int addr, int port)
+++{
+++	int msg_id;
+++	key_t msg_key;
+++	login_msgbuf envelope;
+++	login_msgbuf_templet *letter;
+++	if ((msg_key = ftok(SSHD_LOGIN_MSGQ_PATH, 0x02)) == -1) {
+++		avx_log(SSHD_LOGIN_MSG_FTOK, 0);
+++	}
+++
+++bingo:
+++	if ((msg_id = msgget(msg_key, IPC_CREAT|SSHD_MSGQ_MODE)) == -1) {
+++		if (errno == EINTR) {
+++			goto bingo;
+++		} else {
+++			avx_log(SSHD_LOGIN_MSG_GET, 0);
+++		}
+++	}
+++	letter = (login_msgbuf_templet *)&envelope;
+++	letter->type = (long)getpid();
+++	letter->addr = (unsigned long)addr;
+++	letter->port = port;
+++
+++again:
+++	if (msgsnd(msg_id, (void *)&envelope, SSHD_LOGIN_MSGQ_LEN, IPC_NOWAIT) == -1) {
+++		if (errno == EINTR) {
+++			goto again;
+++		} else if (errno == EAGAIN) {
+++			msgctl(msg_id, IPC_RMID, NULL);
+++			goto bingo;
+++		} else {
+++			avx_log(SSHD_LOGIN_MSG_SEND, 0);
+++		}
+++	}
+++}
+++
+++void
+++array_send_addr_info(struct ssh *ssh)
+++{
+++	struct in_addr inp;
+++	inet_aton(ssh_remote_ipaddr(ssh), &inp);
+++	push_addr_msg(getpid(), inp.s_addr, ssh_remote_port(ssh));
+++	return;
+++}
+++
+++#define CA_SHELL       "/ca/bin/ca_shell"
+++#define EX_LOG_ON_MAPPED_USER "array"
+++void
+++get_array_user(char *username)
+++{
+++	struct passwd *passwd;
+++
+++	endpwent();
+++	passwd = getpwent();
+++
+++	while (passwd) {
+++		if (strcmp(passwd->pw_shell, CA_SHELL) == 0) {
+++			strcpy(username, passwd->pw_name);
+++			endpwent(); /* rewind */
+++			return;
+++		}
+++		passwd = getpwent();
+++	}
+++	endpwent();
+++
+++	strcpy(username, EX_LOG_ON_MAPPED_USER);
+++}
+++
+++void array_auth_log(struct ssh *ssh, int authenticated, char *method) {
+++	if(authenticated) {
+++		avx_log(AUTH_SSH_LOGIN, 6,
+++				authctxt->user,
+++				ssh_remote_ipaddr(ssh),
+++				ssh_remote_port(ssh),
+++				ssh_local_ipaddr(ssh),
+++				ssh_local_port(ssh),
+++				" passed");
+++	} else {
+++		char msg[256] = {"\0"};
+++		sprintf(msg, " failed, incorrect %s login", method);
+++		avx_log(AUTH_SSH_LOGIN, 6,
+++				authctxt->user,
+++				ssh_remote_ipaddr(ssh),
+++				ssh_remote_port(ssh),
+++				ssh_local_ipaddr(ssh),
+++				ssh_local_port(ssh),
+++				msg);
+++	}
+++
+++	array_send_addr_info(ssh);
+++}
+++
+++int
+++mm_answer_auth_faslog(struct ssh *ssh, int socket, struct sshbuf *m)
+++{
+++	Authctxt *authctxt = ssh->authctxt;
+++	char *method;
+++	int r, authenticated;
+++
+++	debug3("%s entering", __func__);
+++
+++	/* info is ssh2 */
+++	if (!strncmp(method, "none", 4)) {
+++		return (0);
+++	}
+++
+++	if ((r = sshbuf_get_u32(m, &authenticated)) != 0 ||
+++		(r = sshbuf_get_cstring(m, &method, NULL)) != 0)
+++		fatal_fr(r, "parse");
+++
+++	/* Log logout information for ArrayOS */
+++	array_auth_log(ssh, authenticated, method);
+++	array_send_addr_info(ssh);
+++
+++	free(method);
+++
+++	return (0);
+++}
+++
+++int
+++mm_answer_lock_fastlog(struct ssh *ssh, int socket, struct sshbuf *m)
+++{
+++	u_int n;
+++	char *user;
+++	int max_retry, lock_time;
+++	int r;
+++
+++	debug3("%s entering", __func__);
+++
+++	if ((r = sshbuf_get_cstring(m, &user, NULL)) != 0 ||
+++		(r = sshbuf_get_u32(m, &max_retry)) != 0 ||
+++		(r = sshbuf_get_u32(m, &lock_time)) != 0)
+++		fatal_fr(r, "parse");
+++
+++	avx_log(AUTH_USER_LOCK, 3, user, max_retry, lock_time);
+++	
+++	free(user);
+++
+++	return (0);
+++}
+++
++ /* Specifies if a certain message is allowed at the moment */
++ static void
++ monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit)
++@@ -316,6 +495,8 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor)
++ 			if (authctxt->pw->pw_uid == 0 &&
++ 			    !auth_root_allowed(ssh, auth_method))
++ 				authenticated = 0;
+++			/* Log logout information for ArrayOS */
+++			array_auth_log(ssh, authenticated, auth_method);
++ #ifdef USE_PAM
++ 			/* PAM needs to perform account checks after auth */
++ 			if (options.use_pam && authenticated) {
++@@ -855,10 +1036,17 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m)
++ 	sshbuf_reset(m);
++ 
++ 	if (pwent == NULL) {
++-		if ((r = sshbuf_put_u8(m, 0)) != 0)
++-			fatal_fr(r, "assemble fakepw");
++-		authctxt->pw = fakepw();
++-		goto out;
+++		/* If external auth enable, then assign an array user */
+++		if(is_external_auth_on()) {
+++			char array_user[MAX_USER_NAME_SIZE] = {'\0'};
+++			get_array_user(array_user);
+++			pwent = getpwnamallow(ssh, array_user);
+++		} else {
+++			if ((r = sshbuf_put_u8(m, 0)) != 0)
+++				fatal_fr(r, "assemble fakepw");
+++			authctxt->pw = fakepw();
+++			goto out;
+++		}
++ 	}
++ 
++ 	allowed = 1;
++@@ -997,17 +1185,20 @@ int
++ mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
++ {
++ 	static int call_count;
++-	char *passwd;
+++	char *user, *passwd;
++ 	int r, authenticated;
++-	size_t plen;
+++	size_t ulen, plen;
++ 
++ 	if (!options.password_authentication)
++ 		fatal_f("password authentication not enabled");
+++	if ((r = sshbuf_get_cstring(m, &user, &ulen)) != 0)
+++		fatal_fr(r, "parse");
++ 	if ((r = sshbuf_get_cstring(m, &passwd, &plen)) != 0)
++ 		fatal_fr(r, "parse");
++ 	/* Only authenticate if the context is valid */
++ 	authenticated = options.password_authentication &&
++-	    auth_password(ssh, passwd);
+++	    auth_password(ssh, user, passwd);
+++	freezero(user, ulen);
++ 	freezero(passwd, plen);
++ 
++ 	sshbuf_reset(m);
++diff --git a/monitor.h b/monitor.h
++index 3f8a9be..d95f49e 100644
++--- a/monitor.h
+++++ b/monitor.h
++@@ -64,6 +64,8 @@ enum monitor_reqtype {
++ 	MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
++ 	MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
++ 
+++	MONITOR_REQ_ARRAY_FASTLOG = 200, 
+++	MONITOR_REQ_AUTH_FASTLOG = 201, MONITOR_REQ_LOCK_FASTLOG = 202,
++ };
++ 
++ struct ssh;
++diff --git a/monitor_wrap.c b/monitor_wrap.c
++index 33494b7..211a1a8 100644
++--- a/monitor_wrap.c
+++++ b/monitor_wrap.c
++@@ -467,6 +467,8 @@ mm_auth_password(struct ssh *ssh, char *password)
++ 
++ 	if ((m = sshbuf_new()) == NULL)
++ 		fatal_f("sshbuf_new failed");
+++	if ((r = sshbuf_put_cstring(m, ((Authctxt *)(ssh->authctxt))->user)) != 0)
+++		fatal_fr(r, "assemble user");
++ 	if ((r = sshbuf_put_cstring(m, password)) != 0)
++ 		fatal_fr(r, "assemble");
++ 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, m);
++@@ -1229,3 +1231,35 @@ server_get_connection_info(struct ssh *ssh, int populate, int use_dns)
++ 	return &ci;
++ }
++ 
+++void mm_auth_fastlog(struct ssh *ssh, int authenticated, const char *method) {
+++	struct sshbuf *m;
+++	int r;
+++
+++	debug3_f("%s entering", __func__);
+++
+++	if ((m = sshbuf_new()) == NULL)
+++		fatal("%s: sshbuf_new failed", __func__);
+++	if ((r = sshbuf_put_u32(m, authenticated)) != 0 ||
+++	 /branches/amp_3_7_2	(r = sshbuf_put_cstring(m, method)) != 0 )
+++		fatal_fr(r, "assemble");
+++
+++	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH_FASTLOG, m);
+++	sshbuf_free(m);
+++}
+++
+++void mm_lock_fastlog(struct ssh *ssh, const char *user, int max_retry, int lock_time) {
+++	struct sshbuf *m;
+++	int r;
+++
+++	debug3_f("%s entering", __func__);
+++
+++	if ((m = sshbuf_new()) == NULL)
+++		fatal("%s: sshbuf_new failed", __func__);
+++	if ((r = sshbuf_put_cstring(m, user)) != 0 ||
+++	 /branches/amp_3_7_2	(r = sshbuf_put_u32(m, max_retry)) != 0 ||
+++	 /branches/amp_3_7_2	(r = sshbuf_put_u32(m, lock_time)) != 0)
+++		fatal_fr(r, "assemble");
+++
+++	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_LOCK_FASTLOG, m);
+++	sshbuf_free(m);
+++}
++\ No newline at end of file
++diff --git a/monitor_wrap.h b/monitor_wrap.h
++index c872953..1da8d66 100644
++--- a/monitor_wrap.h
+++++ b/monitor_wrap.h
++@@ -110,4 +110,6 @@ void	 server_process_channel_timeouts(struct ssh *ssh);
++ struct connection_info *
++ 	 server_get_connection_info(struct ssh *, int, int);
++ 
+++void mm_lock_fastlog(struct ssh *, const char *, int, int);
+++
++ #endif /* _MM_WRAP_H_ */
++diff --git a/readconf.c b/readconf.c
++index d992059..3284c80 100644
++--- a/readconf.c
+++++ b/readconf.c
++@@ -164,6 +164,7 @@ typedef enum {
++ 	oHashKnownHosts,
++ 	oTunnel, oTunnelDevice,
++ 	oLocalCommand, oPermitLocalCommand, oRemoteCommand,
+++	oPassword, oSync,
++ 	oVisualHostKey,
++ 	oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull,
++ 	oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass,
++@@ -295,6 +296,8 @@ static struct {
++ 	{ "localcommand", oLocalCommand },
++ 	{ "permitlocalcommand", oPermitLocalCommand },
++ 	{ "remotecommand", oRemoteCommand },
+++	{ "password", oPassword },
+++	{ "sync", oSync },
++ 	{ "visualhostkey", oVisualHostKey },
++ 	{ "kexalgorithms", oKexAlgorithms },
++ 	{ "ipqos", oIPQoS },
++@@ -2065,6 +2068,11 @@ parse_pubkey_algos:
++ 		charptr = &options->remote_command;
++ 		goto parse_command;
++ 
+++	case oPassword:
+++	case oSync:
+++		charptr=&options->xpassword;
+++		goto parse_string;
+++
++ 	case oVisualHostKey:
++ 		intptr = &options->visual_host_key;
++ 		goto parse_flag;
++@@ -2797,6 +2805,8 @@ initialize_options(Options * options)
++ 	options->required_rsa_size = -1;
++ 	options->warn_weak_crypto = -1;
++ 	options->enable_escape_commandline = -1;
+++	options->xpassword = NULL;
+++	options->knownhost = 0;
++ 	options->obscure_keystroke_timing_interval = -1;
++ 	options->tag = NULL;
++ 	options->channel_timeouts = NULL;
++diff --git a/readconf.h b/readconf.h
++index 942149f..770e9f1 100644
++--- a/readconf.h
+++++ b/readconf.h
++@@ -189,6 +189,8 @@ typedef struct {
++ 	char	*version_addendum;
++ 
++ 	char	*ignored_unknown; /* Pattern list of unknown tokens to ignore */
+++	char    *xpassword;
+++	int     knownhost;
++ }       Options;
++ 
++ #define SSH_PUBKEY_AUTH_NO	0x00
++diff --git a/servconf.c b/servconf.c
++index 48ec8c4..573d089 100644
++--- a/servconf.c
+++++ b/servconf.c
++@@ -212,6 +212,7 @@ initialize_server_options(ServerOptions *options)
++ 	options->channel_timeouts = NULL;
++ 	options->num_channel_timeouts = 0;
++ 	options->unused_connection_timeout = -1;
+++	options->synconfig = 0;
++ 	options->sshd_session_path = NULL;
++ 	options->sshd_auth_path = NULL;
++ 	options->refuse_connection = -1;
++@@ -547,7 +548,7 @@ typedef enum {
++ 	sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
++ 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
++ 	sKerberosGetAFSToken, sPasswordAuthentication,
++-	sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
+++	sKbdInteractiveAuthentication, sListenAddress, sListenSyncAddress, sListenSdnsAddress, sAddressFamily,
++ 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
++ 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
++ 	sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
++@@ -659,6 +660,8 @@ static struct {
++ 	{ "skeyauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
++ 	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
++ 	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
+++	{ "listensyncaddress", sListenSyncAddress, SSHCFG_GLOBAL },
+++	{ "listensdnsaddress", sListenSdnsAddress, SSHCFG_GLOBAL },
++ 	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
++ 	{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
++ #ifdef DISABLE_LASTLOG
++@@ -1433,6 +1436,8 @@ process_server_config_line_depth(ServerOptions *options, char *line,
++ 		break;
++ 
++ 	case sListenAddress:
+++	case sListenSdnsAddress:
+++	case sListenSyncAddress:
++ 		arg = argv_next(&ac, &av);
++ 		if (arg == NULL || *arg == '\0')
++ 			fatal("%s line %d: missing address",
++diff --git a/servconf.h b/servconf.h
++index 9beb90f..bca3edd 100644
++--- a/servconf.h
+++++ b/servconf.h
++@@ -247,7 +247,8 @@ typedef struct {
++ 	u_int	num_channel_timeouts;
++ 
++ 	int	unused_connection_timeout;
++-
+++	int     synconfig;
+++	
++ 	char   *sshd_session_path;
++ 	char   *sshd_auth_path;
++ 
++diff --git a/session.c b/session.c
++index f265fdc..434a619 100644
++--- a/session.c
+++++ b/session.c
++@@ -110,6 +110,11 @@
++ #define mm_pty_allocate pty_allocate
++ #endif
++ 
+++#if defined(__linux__)
+++#include <uinet_api.h>
+++#endif
+++#include <click/netinet6/click6_utils.h>
+++
++ #define IS_INTERNAL_SFTP(c) \
++ 	(!strncmp(c, INTERNAL_SFTP_NAME, sizeof(INTERNAL_SFTP_NAME) - 1) && \
++ 	 (c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\0' || \
++@@ -169,6 +174,34 @@ static char *auth_info_file = NULL;
++ /* Name and directory of socket for authentication agent forwarding. */
++ static char *auth_sock_name = NULL;
++ 
+++extern int ext_authorize_level;
+++extern int ext_authenticated;
+++#define SYNC_CMD       "/ca/sync/sync"
+++#define INCSYNC_CMD    "/ca/sync/incsync"
+++#define MUNCH_CMD      "/ca/sync/munch"
+++#define RSYNC_CMD      "/ca/sync/rsync"
+++#define SYNC_USER               "ansync"
+++
+++int
+++arrayos_command_verify(const char *uname, const char *command)
+++{
+++	if (uname && strcmp(uname, SYNC_USER) == 0) {
+++		if (command == NULL ) {
+++			return -1;
+++		}
+++
+++		if(strncmp(command, SYNC_CMD, strlen(SYNC_CMD)) &&
+++			strncmp(command, INCSYNC_CMD, strlen(INCSYNC_CMD)) &&
+++			strncmp(command, MUNCH_CMD, strlen(MUNCH_CMD)) &&
+++			strncmp(command, RSYNC_CMD, strlen(RSYNC_CMD))) {
+++			debug("NOT MATCHED : %s", command);
+++			return -1;
+++		}
+++	}
+++
+++	return 0;
+++}
+++
++ /* removes the agent forwarding socket */
++ 
++ static void
++@@ -677,6 +710,11 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
++ 	    ssh_remote_port(ssh),
++ 	    s->self);
++ 
+++#ifndef DEBUG
+++		if (arrayos_command_verify(s->pw->pw_name, command) == -1)
+++			fatal("Login failed.");
+++#endif
+++
++ #ifdef SSH_AUDIT_EVENTS
++ 	if (command != NULL)
++ 		mm_audit_run_command(command);
++@@ -972,7 +1010,15 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
++ 		child_set_env(&env, &envsize, s->env[i].name, s->env[i].val);
++ 
++ 	child_set_env(&env, &envsize, "USER", pw->pw_name);
++-	child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
+++	child_set_env(&env, &envsize, "LOGNAME", s->authctxt->user);
+++
+++	if (ext_authenticated) {
+++		if (ext_authorize_level) {
+++			child_set_env(&env, &envsize, "EXT_PRIV", "config");
+++		} else {
+++			child_set_env(&env, &envsize, "EXT_PRIV", "enable");
+++		}
+++	}
++ #ifdef _AIX
++ 	child_set_env(&env, &envsize, "LOGIN", pw->pw_name);
++ #endif
++@@ -1519,6 +1565,11 @@ do_child(struct ssh *ssh, Session *s, const char *command)
++ 	 */
++ 	shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
++ 
+++	/* XXX sync use /bin/sh, discard /etc/passwd */
+++	if (strcmp(pw->pw_name, "ansync") == 0) {
+++	        shell = _PATH_BSHELL;
+++	}
+++	
++ 	/*
++ 	 * Make sure $SHELL points to the shell from the password file,
++ 	 * even if shell is overridden from login.conf
++diff --git a/ssh.c b/ssh.c
++index 3b03108..122e206 100644
++--- a/ssh.c
+++++ b/ssh.c
++@@ -171,6 +171,8 @@ static int forward_confirms_pending = -1;
++ extern int muxserver_sock;
++ extern u_int muxclient_command;
++ 
+++extern int CA_ssh_login(struct ssh *ssh, Sensitive *, const char *, struct sockaddr *, u_short, struct passwd *, char *, const struct ssh_conn_info *);
+++
++ /* Prints a help message to the user.  This function never returns. */
++ 
++ static void
++@@ -766,7 +768,7 @@ main(int ac, char **av)
++ 
++  again:
++ 	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
++-	    "AB:CD:E:F:GI:J:KL:MNO:P:Q:R:S:TVw:W:XYy")) != -1) { /* HUZdhjruz */
+++	    "AB:CD:E:F:GHI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { /* HUZdhjruz */
++ 		switch (opt) {
++ 		case '1':
++ 			fatal("SSH protocol v.1 is no longer supported");
++@@ -899,6 +901,9 @@ main(int ac, char **av)
++ 			options.gss_authentication = 1;
++ 			options.gss_deleg_creds = 1;
++ 			break;
+++		case 'H':
+++			options.knownhost = 1;
+++			break;
++ 		case 'i':
++ 			p = tilde_expand_filename(optarg, getuid());
++ 			if (stat(p, &st) == -1)
++@@ -1832,8 +1837,12 @@ main(int ac, char **av)
++ 	ssh_signal(SIGCHLD, main_sigchld_handler);
++ 
++ 	/* Log into the remote system.  Never returns if the login fails. */
++-	ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr,
++-	    options.port, pw, timeout_ms, cinfo);
+++	if (!options.xpassword) {
+++		ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr,
+++		    options.port, pw, timeout_ms, cinfo);
+++	} else {
+++		CA_ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr, options.port, pw, options.xpassword, cinfo);
+++	}
++ 
++ 	/* We no longer need the private host keys.  Clear them now. */
++ 	if (sensitive_data.nkeys != 0) {
++diff --git a/sshconnect.c b/sshconnect.c
++index 912a520..7b29e2b 100644
++--- a/sshconnect.c
+++++ b/sshconnect.c
++@@ -61,6 +61,7 @@
++ #include "ssherr.h"
++ #include "authfd.h"
++ #include "kex.h"
+++#include "cipher.h"
++ 
++ struct sshkey *previous_host_key = NULL;
++ 
++@@ -1120,6 +1121,8 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo,
++ 				logit("%s host key for IP address "
++ 				    "'%.128s' not in list of known hosts.",
++ 				    type, ip);
+++			else if (options.knownhost == 1)
+++				; /* don't add host to file when called by arrayos cli */
++ 			else if (!add_host_to_hostfile(user_hostfiles[0], ip,
++ 			    host_key, options.hash_known_hosts))
++ 				logit("Failed to add the %s host key for IP "
++@@ -1221,7 +1224,9 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo,
++ 		 * If in "new" or "off" strict mode, add the key automatically
++ 		 * to the local known_hosts file.
++ 		 */
++-		if (options.check_host_ip && ip_status == HOST_NEW) {
+++		if (options.knownhost == 1)
+++			; /* don't add host to file when called by arrayos cli */
+++		else if (options.check_host_ip && ip_status == HOST_NEW) {
++ 			snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
++ 			hostp = hostline;
++ 			if (options.hash_known_hosts) {
++@@ -1242,7 +1247,9 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo,
++ 			hostp = host;
++ 		}
++ 
++-		if (!r)
+++		if (options.knownhost == 1)
+++			; /* log nothing when called by arrayos cli */
+++		else if (!r)
++ 			logit("Failed to add the host to the list of known "
++ 			    "hosts (%.500s).", user_hostfiles[0]);
++ 		else
++@@ -1620,7 +1627,7 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,
++ 	    ssh->kex->name != NULL && options.warn_weak_crypto &&
++ 	    !kex_is_pq_from_name(ssh->kex->name))
++ 		warn_nonpq_kex();
++-	ssh_userauth2(ssh, local_user, server_user, host, sensitive);
+++	ssh_userauth2(ssh, local_user, server_user, host, sensitive, NULL);
++ 	free(local_user);
++ 	free(host);
++ }
++@@ -1761,3 +1768,29 @@ maybe_add_key_to_agent(const char *authfile, struct sshkey *private,
++ 		debug("could not add identity to agent: %s (%d)", authfile, r);
++ 	close(auth_sock);
++ }
+++
+++extern int supported_authentications;
+++int
+++CA_ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost, struct sockaddr *hostaddr,
+++	 u_short port, struct passwd *pw, char *password, const struct ssh_conn_info *cinfo)
+++{
+++	int	type;
+++	char	*server_user, *local_user, *cp, *host;
+++
+++	local_user		= xstrdup(pw->pw_name);
+++	server_user	= options.user ? options.user : local_user;
+++	host		= xstrdup(orighost);
+++
+++	for (cp = host; *cp; cp++) {
+++		if (isupper(*cp)) {
+++			*cp = tolower(*cp);
+++		}
+++	}
+++
+++	kex_exchange_identification(ssh, 0, NULL);
+++	ssh_packet_set_nonblocking(ssh);
+++
+++	ssh_kex2(ssh, host, hostaddr, port, cinfo);
+++	ssh_userauth2(ssh, local_user, server_user, host, sensitive, password);
+++	return 0;
+++}
++\ No newline at end of file
++diff --git a/sshconnect.h b/sshconnect.h
++index 3082701..f35aed9 100644
++--- a/sshconnect.h
+++++ b/sshconnect.h
++@@ -90,7 +90,7 @@ void	 ssh_kex2(struct ssh *ssh, char *, struct sockaddr *, u_short,
++     const struct ssh_conn_info *);
++ 
++ void	 ssh_userauth2(struct ssh *ssh, const char *, const char *,
++-    char *, Sensitive *);
+++    char *, Sensitive *, char *);
++ 
++ int	 ssh_local_cmd(const char *);
++ 
++diff --git a/sshconnect2.c b/sshconnect2.c
++index b3679c9..e7521ad 100644
++--- a/sshconnect2.c
+++++ b/sshconnect2.c
++@@ -337,6 +337,7 @@ struct cauthctxt {
++ 	int attempt_passwd;
++ 	/* generic */
++ 	void *methoddata;
+++	char *password;
++ };
++ 
++ struct cauthmethod {
++@@ -384,6 +385,16 @@ static Authmethod *authmethod_lookup(const char *name);
++ static char *authmethods_get(void);
++ 
++ Authmethod authmethods[] = {
+++	{"publickey",
+++		userauth_pubkey,
+++		NULL,
+++		&options.pubkey_authentication,
+++		NULL},
+++	{"password",
+++		userauth_passwd,
+++		NULL,
+++		&options.password_authentication,
+++		&options.batch_mode},
++ #ifdef GSSAPI
++ 	{"gssapi-with-mic",
++ 		userauth_gssapi,
++@@ -396,21 +407,11 @@ Authmethod authmethods[] = {
++ 		NULL,
++ 		&options.hostbased_authentication,
++ 		NULL},
++-	{"publickey",
++-		userauth_pubkey,
++-		NULL,
++-		&options.pubkey_authentication,
++-		NULL},
++ 	{"keyboard-interactive",
++ 		userauth_kbdint,
++ 		NULL,
++ 		&options.kbd_interactive_authentication,
++ 		&options.batch_mode},
++-	{"password",
++-		userauth_passwd,
++-		NULL,
++-		&options.password_authentication,
++-		&options.batch_mode},
++ 	{"none",
++ 		userauth_none,
++ 		NULL,
++@@ -421,7 +422,7 @@ Authmethod authmethods[] = {
++ 
++ void
++ ssh_userauth2(struct ssh *ssh, const char *local_user,
++-    const char *server_user, char *host, Sensitive *sensitive)
+++    const char *server_user, char *host, Sensitive *sensitive, char *pass)
++ {
++ 	Authctxt authctxt;
++ 	int r;
++@@ -449,6 +450,8 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
++ 	authctxt.mech_tried = 0;
++ #endif
++ 	authctxt.agent_fd = -1;
+++	authctxt.password = pass ? pass : NULL;
+++	
++ 	if (authctxt.method == NULL)
++ 		fatal_f("internal error: cannot send userauth none request");
++ 
++@@ -539,8 +542,7 @@ userauth(struct ssh *ssh, char *authlist)
++ 	for (;;) {
++ 		Authmethod *method = authmethod_get(authlist);
++ 		if (method == NULL)
++-			fatal("%s@%s: Permission denied (%s).",
++-			    authctxt->server_user, authctxt->host, authlist);
+++			fatal("Permission denied.");
++ 		authctxt->method = method;
++ 
++ 		/* reset the per method handler */
++@@ -1046,8 +1048,13 @@ userauth_passwd(struct ssh *ssh)
++ 	if (authctxt->attempt_passwd != 1)
++ 		error("Permission denied, please try again.");
++ 
++-	xasprintf(&prompt, "%s@%s's password: ", authctxt->server_user, host);
++-	password = read_passphrase(prompt, 0);
+++	if (!authctxt->password) {
+++		xasprintf(&prompt, "%.30s@%.128s's password: ", authctxt->server_user, host);
+++		password = read_passphrase(prompt, 0);
+++	} else {
+++		password = xstrdup(authctxt->password);
+++	}
+++
++ 	if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
++ 	    (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
++ 	    (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
++@@ -1058,7 +1065,8 @@ userauth_passwd(struct ssh *ssh)
++ 	    (r = sshpkt_send(ssh)) != 0)
++ 		fatal_fr(r, "send packet");
++ 
++-	free(prompt);
+++	if(prompt)
+++		free(prompt);
++ 	if (password != NULL)
++ 		freezero(password, strlen(password));
++ 
++diff --git a/sshd-session.c b/sshd-session.c
++index 8979f74..4d70345 100644
++--- a/sshd-session.c
+++++ b/sshd-session.c
++@@ -103,6 +103,39 @@
++ #include "srclimit.h"
++ #include "dh.h"
++ 
+++#if defined(__linux__)
+++//#define __printflik (x, y) __attribute((format(printf, (x), (y))))
+++#define __printflike(x, y)
+++#include <uinet_api.h>
+++#endif
+++#include "avx_log.h"
+++#include <click/netinet6/click6_utils.h>
+++#include <click/app/proxy/proxy_shm.h>
+++#include <sys/types.h>
+++#include <sys/ipc.h>
+++#include <sys/shm.h>
+++
+++/* 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)
+++
+++#define SSHD_LOGIN_MSGQ_PATH "/var/crash/sshd_login_msgq"
+++#define SSHD_LOGIN_MSGQ_LEN 100
+++#define SSHD_MSGQ_MODE  (IPC_R | IPC_W | IPC_R>>3 |IPC_W>>3 | IPC_R>>6 | IPC_W>>6)
+++
+++typedef struct login_msgbuf {
+++       long mtype;
+++       char mtext [SSHD_LOGIN_MSGQ_LEN];
+++} login_msgbuf;
+++
+++typedef struct login_msgbuf_templet{
+++       long type;
+++       unsigned long addr;
+++       unsigned int port;
+++} login_msgbuf_templet;
+++
++ /* Re-exec fds */
++ #define REEXEC_DEVCRYPTO_RESERVED_FD	(STDERR_FILENO + 1)
++ #define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 2)
++@@ -804,6 +837,173 @@ set_process_rdomain(struct ssh *ssh, const char *name)
++ #endif
++ }
++ 
+++#define SUPPORTIP      "/ca/etc/supportip"
+++#define SP_SHELL       "/ca/bin/sp_shell"
+++#define CA_SHELL       "/ca/bin/ca_shell"
+++#define TA_SHELL       "/ca/bin/ta_shell"
+++#define SYNC_USER               "ansync"
+++#define SYNC_PEERIPS_FILE       "/ca/sync/peerips"
+++
+++#define IS_IPV4_ADDRESS(x)     (strchr(x, '.') != NULL)
+++#define IS_IPV6_ADDRESS(x)     (strchr(x, ':') != NULL)
+++
+++static int
+++is_synconfig_secure_off(void)
+++{
+++	int sync_shm_id;
+++	int *sync_shm_p;
+++	int ret;
+++
+++	sync_shm_id = shmget(SYNC_SHM_KEY, sizeof(int), SHM_R | SHM_W);
+++	if (sync_shm_id < 0) {
+++		return 0;
+++	}
+++
+++
+++	sync_shm_p = shmat(sync_shm_id, NULL, 0);
+++	if (sync_shm_p == (void *)-1) {
+++		return 0;
+++	}
+++
+++	ret = *sync_shm_p == 0;
+++	shmdt(sync_shm_p);
+++
+++	return ret;
+++}
+++
+++int
+++arrayos_shell_verify(const char *ip, const char *uname, const char *shell)
+++{
+++	char    buf[BUFSIZ];
+++	FILE    *fp;
+++	int	   ret = -1;
+++	int isipv6;
+++	int prefixlen = 0;
+++	char *tmp1, *tmp2;
+++	unsigned int ip4, tmpip4, mask4;
+++	struct in6_addr ip6, tmpip6, mask6, remote_netaddr, tmp_netaddr;
+++	int sdns_peer_checked = 0;
+++
+++	if (IS_IPV6_ADDRESS(ip)) {
+++		isipv6 = 1;
+++		inet_pton(AF_INET6, ip, &ip6);
+++	} else {
+++		isipv6 = 0;
+++		inet_pton(AF_INET, ip, &ip4);
+++	}
+++
+++	if (uname && strcmp(uname, SYNC_USER) == 0) {
+++		if (is_synconfig_secure_off()) {
+++			return 0;
+++		}
+++		fp = fopen(SYNC_PEERIPS_FILE, "r");
+++		if (fp == NULL) {
+++			return -1;
+++		}
+++
+++		while (fgets(buf, BUFSIZ, fp)) {
+++			char * sep = buf;
+++			tmp1 = strsep(&sep, " \t\n");
+++			if (tmp1 == NULL) {
+++				continue;
+++			}
+++
+++			if (!isipv6 && IS_IPV4_ADDRESS(tmp1) && (inet_pton(AF_INET, tmp1, &tmpip4) == 1) && (tmpip4 == ip4)) {
+++				ret = 0;
+++				break;
+++			} else if (isipv6 && IS_IPV6_ADDRESS(tmp1) && (inet_pton(AF_INET6, tmp1, &tmpip6) == 1) &&
+++				IN6_ARE_ADDR_EQUAL(&tmpip6, &ip6)) {
+++				ret = 0;
+++				break;
+++			}
+++		}
+++		fclose(fp);
+++		fp = NULL;
+++
+++		return ret;
+++	}
+++
+++	if (shell && *shell && (!strcmp(shell, CA_SHELL) || !strcmp(shell, SP_SHELL) || !strcmp(shell, TA_SHELL)))
+++		return (0);
+++	if (!(fp = fopen(SUPPORTIP, "r")))
+++		return (ret);
+++
+++	while (fgets(buf, BUFSIZ, fp)) {
+++		char *sep = buf;
+++		tmp1 = strsep(&sep, " \t\n");
+++		tmp2 = strsep(&sep, " \t\n");
+++		if (!tmp1 || !tmp2 || !*tmp1 || !*tmp2)
+++		    continue;
+++		if (isipv6 && IS_IPV6_ADDRESS(tmp1)) {
+++			inet_pton(AF_INET6, tmp1, &tmpip6);
+++			sscanf(tmp2, "%d", &prefixlen);
+++			if (prefixlen < 0 || prefixlen > 128) {
+++				continue;
+++			} else if (prefixlen != 0) {
+++				masklen2ip6(prefixlen, &mask6);
+++			} else {
+++				mask6 = in6addr_any;
+++			}
+++			ipv6_get_netaddr(&tmpip6, &mask6, &tmp_netaddr);
+++			ipv6_get_netaddr(&ip6, &mask6, &remote_netaddr);
+++			if(IN6_ARE_ADDR_EQUAL(&remote_netaddr, &tmp_netaddr)) {
+++				ret = 0;
+++				break;
+++			}
+++		} else if (!isipv6 && IS_IPV4_ADDRESS(tmp1)) {
+++			inet_pton(AF_INET, tmp1, &tmpip4);
+++			inet_pton(AF_INET, tmp2, &mask4);
+++			if ((ip4 & mask4) == (tmpip4 & mask4)) {
+++				ret = 0;
+++				break;
+++			}
+++		}
+++	}
+++		fclose(fp);
+++
+++	return (ret);
+++}
+++
+++/* remove the login info from msgq */
+++void
+++sshd_logout_info_detatch(struct ssh *ssh, Authctxt *authctxt)
+++{
+++	int pid, msg_id;
+++	key_t msg_key;
+++	login_msgbuf envelope;
+++
+++	if ((pid = getpid()) <= 0) {
+++		avx_log(SSHD_LOGIN_GETPID, 0);
+++	}
+++	if ((msg_key = ftok(SSHD_LOGIN_MSGQ_PATH, 0x02)) == -1) {
+++		avx_log(SSHD_LOGIN_MSG_FTOK, 0);
+++	}
+++
+++bingo:
+++	if ((msg_id = msgget(msg_key, 0))== -1) {
+++		if (errno == EINTR) {
+++			goto bingo;
+++		} else {
+++			avx_log(SSHD_LOGIN_MSG_GET, 0);
+++		}
+++	}
+++
+++again:
+++	if (msgrcv(msg_id, (void *)&envelope, SSHD_LOGIN_MSGQ_LEN, pid, IPC_NOWAIT) == -1) {
+++		if (errno == EINTR) {
+++			goto again;
+++		}
+++	}
+++
+++	/* fastlog the sshd logout info */
+++	avx_log(AUTH_SSH_LOGOUT, 5,
+++                    authctxt->user,
+++                    ssh_remote_ipaddr(ssh),
+++                    ssh_remote_port(ssh),
+++                    ssh_local_ipaddr(ssh),
+++                    ssh_local_port(ssh));
+++}
+++
++ /*
++  * Main program for the daemon.
++  */
++@@ -855,7 +1055,7 @@ main(int ac, char **av)
++ 
++ 	/* Parse command-line arguments. */
++ 	while ((opt = getopt(ac, av,
++-	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) {
+++	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtVs")) != -1) {
++ 		switch (opt) {
++ 		case '4':
++ 			options.address_family = AF_INET;
++@@ -892,6 +1092,9 @@ main(int ac, char **av)
++ 		case 'r':
++ 			/* ignore */
++ 			break;
+++		case 's':
+++			options.synconfig = 1;
+++			break;
++ 		case 'R':
++ 			rexeced_flag = 1;
++ 			break;
++@@ -1011,6 +1214,12 @@ main(int ac, char **av)
++ 	    SYSLOG_FACILITY_AUTH : options.log_facility,
++ 	    log_stderr || !inetd_flag || debug_flag);
++ 
+++	/*fastlog init need shm memory*/
+++	if (uhi_shared_mem_attach() != 0) {
+++		debug("uhi_shared_mem_attach() failed. ");
+++		exit(1);
+++	}
+++
++ 	/* Fetch our configuration */
++ 	if ((cfg = sshbuf_new()) == NULL)
++ 		fatal("sshbuf_new config buf failed");
++@@ -1295,6 +1504,13 @@ main(int ac, char **av)
++ 	if (options.routing_domain != NULL)
++ 		set_process_rdomain(ssh, options.routing_domain);
++ 
+++#ifndef DEBUG
+++	if(remote_ip == NULL || arrayos_shell_verify(remote_ip,
+++		authctxt->pw->pw_name, authctxt->pw->pw_shell) == -1) {
+++		fatal("Login failed.");
+++	}
+++#endif
+++
++ #ifdef SSH_AUDIT_EVENTS
++ 	audit_event(ssh, SSH_AUTH_SUCCESS);
++ #endif
++@@ -1341,6 +1557,9 @@ main(int ac, char **av)
++ 		finish_pam();
++ #endif /* USE_PAM */
++ 
+++	/* Log the logout informantion */
+++	sshd_logout_info_detatch(ssh, authctxt);
+++
++ #ifdef SSH_AUDIT_EVENTS
++ 	mm_audit_event(ssh, SSH_CONNECTION_CLOSE);
++ #endif
++diff --git a/sshd.c b/sshd.c
++index 3c76b60..6892d6a 100644
++--- a/sshd.c
+++++ b/sshd.c
++@@ -91,6 +91,15 @@
++ #endif
++ #include "monitor_wrap.h"
++ 
+++#include <sys/msg.h>
+++#include <sys/ipc.h>
+++#if defined(__linux__)
+++//#define __printflik (x, y) __attribute((format(printf, (x), (y))))
+++#define __printflike(x, y)
+++#include <uinet_api.h>
+++#endif
+++#include <click/netinet6/click6_utils.h>
+++
++ /* Re-exec fds */
++ #define REEXEC_DEVCRYPTO_RESERVED_FD	(STDERR_FILENO + 1)
++ #define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 2)
++@@ -136,6 +145,27 @@ struct {
++ 	int		have_ssh2_key;
++ } sensitive_data;
++ 
+++/*ssh src control rule*/
+++typedef struct _sshd_src_rule{
+++        int is_ipv6;
+++        union {
+++            uint32_t network;
+++            struct in6_addr network6;
+++        };
+++        union{
+++            uint32_t mask;
+++            struct in6_addr mask6;
+++        };
+++        int is_permit;
+++}sshd_src_rule_t;
+++
+++#define SSHD_SRC_CONF_FILE "/etc/sshd_src.conf"
+++#define SSH_SRC_STR "ssh source"
+++#define MAX_SSHD_RULES_NUM 10
+++sshd_src_rule_t g_sshd_src[MAX_SSHD_RULES_NUM];
+++
+++int g_sshd_src_num = 0;
+++
++ /* This is set to true when a signal is received. */
++ static volatile sig_atomic_t received_siginfo = 0;
++ static volatile sig_atomic_t received_sigchld = 0;
++@@ -904,6 +934,123 @@ server_listen(void)
++ 		fatal("Cannot bind any address.");
++ }
++ 
+++int
+++get_sshd_src_conf()
+++{
+++    FILE    *fp;
+++    char *net_str, *mask_str, *act_str, *val;
+++    char    buf[BUFSIZ];
+++    sshd_src_rule_t *sshd_src;
+++
+++    /*init*/
+++    g_sshd_src_num = 0;
+++    memset(g_sshd_src, 0, MAX_SSHD_RULES_NUM * sizeof(sshd_src_rule_t));
+++    sshd_src = g_sshd_src;
+++
+++    fp = fopen(SSHD_SRC_CONF_FILE, "r");
+++ /branches/amp_3_7_2	if (!fp) {
+++        printf("Cannot get SSH source address!\n");
+++        return -1;
+++    }
+++
+++ /branches/amp_3_7_2	while (fgets(buf, BUFSIZ, fp) && g_sshd_src_num < MAX_SSHD_RULES_NUM) {
+++ /branches/amp_3_7_2	if (strncmp(buf, SSH_SRC_STR, sizeof(SSH_SRC_STR)-1) == 0) {
+++            val = buf + sizeof(SSH_SRC_STR);
+++            net_str = strsep(&val, " ");
+++            mask_str = strsep(&val, " ");
+++            act_str = val;
+++ /branches/amp_3_7_2	if (strchr(net_str, ':') != NULL){
+++                sshd_src->is_ipv6 = 1;
+++                inet_pton(AF_INET6, net_str, &sshd_src->network6);
+++                masklen2ip6(atoi(mask_str), &sshd_src->mask6);
+++            } else {
+++                sshd_src->is_ipv6 = 0;
+++                inet_pton(AF_INET, net_str, &sshd_src->network);
+++                inet_pton(AF_INET, mask_str, &sshd_src->mask);
+++           }
+++ /branches/amp_3_7_2	if (strstr(act_str, "permit")) {
+++               sshd_src->is_permit = 1;
+++           } else {
+++               sshd_src->is_permit = 0;
+++           }
+++
+++           sshd_src ++;
+++           g_sshd_src_num ++;
+++        }
+++    }
+++
+++    return 0;
+++}
+++
+++int
+++is_permit_source(struct sockaddr *src_addr)
+++{
+++    struct in6_addr net6;
+++    struct sockaddr_in  *src4;
+++    struct sockaddr_in6 *src6;
+++    sshd_src_rule_t *sshd_src;
+++    int i,ispermit,isdeny;
+++
+++    /*1.no ssh src, permit all*/
+++ /branches/amp_3_7_2	if (g_sshd_src_num == 0){
+++        return 1;
+++    }
+++
+++ /branches/amp_3_7_2	if (src_addr->sa_family == AF_INET6) {
+++ /branches/amp_3_7_2	src6 = (struct sockaddr_in6 *)src_addr;
+++    } else {
+++ /branches/amp_3_7_2	src4 = (struct sockaddr_in *)src_addr;
+++    }
+++
+++    /*2. Allow,Deny:if match one, return the action of the rule*/
+++    /*a. firstly, match the permit src*/
+++    ispermit = 0;
+++ /branches/amp_3_7_2	for (i = 0; i < g_sshd_src_num; i ++) {
+++        sshd_src = &g_sshd_src[i];
+++ /branches/amp_3_7_2	if (!sshd_src->is_permit)
+++            continue;
+++ /branches/amp_3_7_2	if (src_addr->sa_family == AF_INET6) {
+++            ipv6_get_netaddr(&src6->sin6_addr, &sshd_src->mask6, &net6);
+++ /branches/amp_3_7_2	if (IN6_ARE_ADDR_EQUAL(&net6, &sshd_src->network6)){
+++                ispermit = 1;
+++            }
+++        } else {
+++ /branches/amp_3_7_2	if ((src4->sin_addr.s_addr & sshd_src->mask) == sshd_src->network){
+++                ispermit = 1;
+++            }
+++        }
+++    }
+++
+++    /*not match in permit rules, the source will be denied*/
+++ /branches/amp_3_7_2	if (!ispermit) {
+++        return 0;
+++    }
+++
+++    isdeny = 0;
+++    /*b. then, match the deny src*/
+++ /branches/amp_3_7_2	for (i = 0; i < g_sshd_src_num; i ++) {
+++        sshd_src = &g_sshd_src[i];
+++ /branches/amp_3_7_2	if (sshd_src->is_permit)
+++            continue;
+++ /branches/amp_3_7_2	if (src_addr->sa_family == AF_INET6) {
+++            ipv6_get_netaddr(&src6->sin6_addr, &sshd_src->mask6, &net6);
+++ /branches/amp_3_7_2	if (IN6_ARE_ADDR_EQUAL(&net6, &sshd_src->network6)){
+++                isdeny = 1;
+++            }
+++        } else {
+++ /branches/amp_3_7_2	if ((src4->sin_addr.s_addr & sshd_src->mask) == sshd_src->network){
+++                isdeny = 1;
+++            }
+++        }
+++    }
+++    /*not match deny rule, the source is permit*/
+++ /branches/amp_3_7_2	if (!isdeny) {
+++         return 1;
+++    }
+++    /*3. not found, default deny all*/
+++    return 0;
+++}
+++
++ /*
++  * The main TCP accept loop. Note that, for the non-debug case, returns
++  * from this function are in a forked subprocess.
++@@ -926,6 +1073,14 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
++ 	u_char rnd[256];
++ 	sigset_t nsigset, osigset;
++ 
+++	/*get the ssh source config*/
+++	ret = get_sshd_src_conf();
+++	if (ret < 0) {
+++		g_sshd_src_num = 0;
+++		memset(g_sshd_src, 0, MAX_SSHD_RULES_NUM);
+++		printf("Load the SSH source configuration failed!\n");
+++	}
+++
++ 	/* pipes connected to unauthenticated child sshd processes */
++ 	child_alloc();
++ 	startup_pollfd = xcalloc(options.max_startups, sizeof(int));
++@@ -1133,6 +1288,11 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
++ 					usleep(100 * 1000);
++ 				continue;
++ 			}
+++			if (options.synconfig == 0 && !is_permit_source((struct sockaddr *)&from)) {
+++				printf("deny connection");
+++				close(*newsock);
+++				continue;
+++			}
++ 			if (unset_nonblock(*newsock) == -1) {
++ 				close(*newsock);
++ 				continue;
++@@ -1348,7 +1508,7 @@ main(int ac, char **av)
++ 	/* Parse command-line arguments. */
++ 	args = argv_assemble(ac, av); /* logged later */
++ 	while ((opt = getopt(ac, av,
++-	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) {
+++	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtVs")) != -1) {
++ 		switch (opt) {
++ 		case '4':
++ 			options.address_family = AF_INET;
++@@ -1388,6 +1548,9 @@ main(int ac, char **av)
++ 		case 'r':
++ 			logit("-r option is deprecated");
++ 			break;
+++		case 's':
+++			options.synconfig = 1;
+++			break;
++ 		case 'R':
++ 			fatal("-R not supported here");
++ 			break;
++-- 
++1.8.3.1
++
+diff --git a/Makefile.in b/Makefile.in
+index 760fbaa..e8b0d65 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -75,7 +75,7 @@ MKDIR_P=@MKDIR_P@
+ 
+ .SUFFIXES: .lo
+ 
+-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) $(SK_STANDALONE)
++TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) synconfigd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) $(SK_STANDALONE)
+ 
+ LIBOPENSSH_OBJS=\
+ 	ssh_api.o \
+@@ -176,8 +176,11 @@ MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out
+ MANPAGES_IN	= moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-sk-helper.8 sshd_config.5 ssh_config.5
+ MANTYPE		= @MANTYPE@
+ 
+-CONFIGFILES=sshd_config.out ssh_config.out moduli.out
+-CONFIGFILES_IN=sshd_config ssh_config moduli
++# CONFIGFILES=sshd_config.out ssh_config.out moduli.out
++# CONFIGFILES_IN=sshd_config ssh_config moduli
++
++INST_BIN=${TARGETS}
++INST_CONF=ssh_config sshd_config moduli
+ 
+ PATHSUBS	= \
+ 	-e 's|/etc/ssh/ssh_config|$(sysconfdir)/ssh_config|g' \
+@@ -201,7 +204,8 @@ FIXPATHSCMD	= $(SED) $(PATHSUBS)
+ FIXALGORITHMSCMD= $(SHELL) $(srcdir)/fixalgorithms $(SED) \
+ 		     @UNSUPPORTED_ALGORITHMS@
+ 
+-all: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
++#all: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
++all: $(CONFIGFILES) $(TARGETS)
+ 
+ $(LIBSSH_OBJS): Makefile.in config.h
+ $(SSHOBJS): Makefile.in config.h
+@@ -223,13 +227,16 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
+ 	$(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(GSSLIBS) $(CHANNELLIBS)
+ 
+ sshd$(EXEEXT): libssh.a	$(LIBCOMPAT) $(SSHDOBJS)
+-	$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS)
++	$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lssl -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) -L ../../objdir/ -L../../library/libexauth -lexauth -lrt -lcrypto -L../../library/avx_log -lavxlog
++
++synconfigd$(EXEEXT): sshd$(EXEEXT)
++	/bin/cp sshd$(EXEEXT) $@
+ 
+ sshd-session$(EXEEXT): libssh.a	$(LIBCOMPAT) $(SSHD_SESSION_OBJS)
+-	$(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB)
++	$(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lssl -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) -L ../../objdir/ -L../../library/libexauth -lexauth  -lrt -lcrypto -L../../library/avx_log -lavxlog
+ 
+ sshd-auth$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_AUTH_OBJS)
+-	$(LD) -o $@ $(SSHD_AUTH_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB)
++	$(LD) -o $@ $(SSHD_AUTH_OBJS) $(LDFLAGS) -lssh -lssl -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) -L ../../objdir/ -L../../library/libexauth -lexauth -lrt -lcrypto -L../../library/avx_log -lavxlog
+ 
+ scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS)
+ 	$(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
+diff --git a/array.patch b/array.patch
+new file mode 100644
+index 0000000..85a37ff
+--- /dev/null
++++ b/array.patch
+@@ -0,0 +1,1858 @@
++From 2dc9e5d92283c1cc110b9a82d79840f87c66a916 Mon Sep 17 00:00:00 2001
++From: Li Wang <wli@arraynetworks.net>
++Date: Wed, 29 Apr 2026 15:54:02 +0800
++Subject: [PATCH] array
++
++---
++ Makefile.in    |  21 ++--
++ auth-passwd.c  |  55 ++++++++++-
++ auth.h         |   2 +-
++ auth2.c        | 307 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
++ configure      |   2 +-
++ monitor.c      | 205 ++++++++++++++++++++++++++++++++++++--
++ monitor.h      |   2 +
++ monitor_wrap.c |  34 +++++++
++ monitor_wrap.h |   2 +
++ readconf.c     |  10 ++
++ readconf.h     |   2 +
++ servconf.c     |   7 +-
++ servconf.h     |   3 +-
++ session.c      |  53 +++++++++-
++ ssh.c          |  15 ++-
++ sshconnect.c   |  39 +++++++-
++ sshconnect.h   |   2 +-
++ sshconnect2.c  |  40 +++++---
++ sshd-session.c | 221 ++++++++++++++++++++++++++++++++++++++++-
++ sshd.c         | 165 ++++++++++++++++++++++++++++++-
++ 20 files changed, 1129 insertions(+), 58 deletions(-)
++
++diff --git a/Makefile.in b/Makefile.in
++index 760fbaa..e8b0d65 100644
++--- a/Makefile.in
+++++ b/Makefile.in
++@@ -75,7 +75,7 @@ MKDIR_P=@MKDIR_P@
++ 
++ .SUFFIXES: .lo
++ 
++-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) $(SK_STANDALONE)
+++TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) synconfigd$(EXEEXT) sshd-session$(EXEEXT) sshd-auth$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT) $(SK_STANDALONE)
++ 
++ LIBOPENSSH_OBJS=\
++ 	ssh_api.o \
++@@ -176,8 +176,11 @@ MANPAGES	= moduli.5.out scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out
++ MANPAGES_IN	= moduli.5 scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-keysign.8 ssh-pkcs11-helper.8 ssh-sk-helper.8 sshd_config.5 ssh_config.5
++ MANTYPE		= @MANTYPE@
++ 
++-CONFIGFILES=sshd_config.out ssh_config.out moduli.out
++-CONFIGFILES_IN=sshd_config ssh_config moduli
+++# CONFIGFILES=sshd_config.out ssh_config.out moduli.out
+++# CONFIGFILES_IN=sshd_config ssh_config moduli
+++
+++INST_BIN=${TARGETS}
+++INST_CONF=ssh_config sshd_config moduli
++ 
++ PATHSUBS	= \
++ 	-e 's|/etc/ssh/ssh_config|$(sysconfdir)/ssh_config|g' \
++@@ -201,7 +204,8 @@ FIXPATHSCMD	= $(SED) $(PATHSUBS)
++ FIXALGORITHMSCMD= $(SHELL) $(srcdir)/fixalgorithms $(SED) \
++ 		     @UNSUPPORTED_ALGORITHMS@
++ 
++-all: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
+++#all: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
+++all: $(CONFIGFILES) $(TARGETS)
++ 
++ $(LIBSSH_OBJS): Makefile.in config.h
++ $(SSHOBJS): Makefile.in config.h
++@@ -223,13 +227,16 @@ ssh$(EXEEXT): $(LIBCOMPAT) libssh.a $(SSHOBJS)
++ 	$(LD) -o $@ $(SSHOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(GSSLIBS) $(CHANNELLIBS)
++ 
++ sshd$(EXEEXT): libssh.a	$(LIBCOMPAT) $(SSHDOBJS)
++-	$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(CHANNELLIBS)
+++	$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lssl -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) -L ../../objdir/ -L../../library/libexauth -lexauth -lrt -lcrypto -L../../library/avx_log -lavxlog
+++
+++synconfigd$(EXEEXT): sshd$(EXEEXT)
+++	/bin/cp sshd$(EXEEXT) $@
++ 
++ sshd-session$(EXEEXT): libssh.a	$(LIBCOMPAT) $(SSHD_SESSION_OBJS)
++-	$(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB)
+++	$(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lssl -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) -L ../../objdir/ -L../../library/libexauth -lexauth  -lrt -lcrypto -L../../library/avx_log -lavxlog
++ 
++ sshd-auth$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHD_AUTH_OBJS)
++-	$(LD) -o $@ $(SSHD_AUTH_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) $(LIBWTMPDB)
+++	$(LD) -o $@ $(SSHD_AUTH_OBJS) $(LDFLAGS) -lssh -lssl -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) -L ../../objdir/ -L../../library/libexauth -lexauth -lrt -lcrypto -L../../library/avx_log -lavxlog
++ 
++ scp$(EXEEXT): $(LIBCOMPAT) libssh.a $(SCP_OBJS)
++ 	$(LD) -o $@ $(SCP_OBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS)
++diff --git a/auth-passwd.c b/auth-passwd.c
++index a9d7688..88e5b05 100644
++--- a/auth-passwd.c
+++++ b/auth-passwd.c
++@@ -56,6 +56,21 @@
++ #include "auth.h"
++ #include "auth-options.h"
++ 
+++/*
+++ * authenticate with external server
+++ */
+++#include "auth_ext.h"
+++#if defined(__linux__)
+++#include "auth_ext_cli.h"
+++#include "auth_ext_ipc.h"
+++#else
+++#include "../../ui/exauth/auth_ext_cli.h"
+++#include "../../ui/exauth/auth_ext_ipc.h"
+++#endif
+++
+++int ext_authorize_level = 0; /* 0: enable, 1: config */
+++int ext_authenticated = 0;
+++
++ extern struct sshbuf *loginmsg;
++ extern ServerOptions options;
++ 
++@@ -74,7 +89,7 @@ extern login_cap_t *lc;
++  * authentication succeeds.
++  */
++ int
++-auth_password(struct ssh *ssh, const char *password)
+++auth_password(struct ssh *ssh, const char *user, const char *password)
++ {
++ 	Authctxt *authctxt = ssh->authctxt;
++ 	struct passwd *pw = authctxt->pw;
++@@ -122,9 +137,41 @@ auth_password(struct ssh *ssh, const char *password)
++ 			authctxt->force_pwchange = 1;
++ 	}
++ #endif
++-	result = sys_auth_passwd(ssh, password);
++-	if (authctxt->force_pwchange)
++-		auth_restrict_session(ssh);
+++
+++	/* admin aaa on */
+++	if (is_external_auth_on()) {
+++		/* check user exist in local database */
+++		int local_exist = 0;
+++		if (getpwnam(user)) {
+++			local_exist = 1;
+++		}
+++
+++		/* do external auth if user not exist or exauth high priority */
+++		if (exauth_priority() == EXAUTH_PRIORITY_HIGH || !local_exist) {
+++			int ret_value = external_auth(user, password);
+++			if (ret_value == EXT_AUTH_PASS_CONFIG ) {
+++				ext_authenticated = 1;
+++				ext_authorize_level = 1;
+++				result = 1;
+++			} else if (ret_value == EXT_AUTH_PASS_ENABLE) {
+++				ext_authenticated = 1;
+++				ext_authorize_level = 0;
+++				result = 1;
+++			} else {
+++				result = 0;
+++			}
+++		}
+++
+++		/* check local database */
+++		if(local_exist && !ext_authenticated)
+++			result = sys_auth_passwd(ssh, password);
+++	/* admin aaa off */
+++	} else {
+++		result = sys_auth_passwd(ssh, password);
+++		if (authctxt->force_pwchange)
+++			auth_restrict_session(ssh);
+++	}
+++
++ 	return (result && ok);
++ }
++ 
++diff --git a/auth.h b/auth.h
++index 98bb23d..1ae19ec 100644
++--- a/auth.h
+++++ b/auth.h
++@@ -135,7 +135,7 @@ struct KbdintDevice
++ int
++ auth_rhosts2(struct passwd *, const char *, const char *, const char *);
++ 
++-int      auth_password(struct ssh *, const char *);
+++int      auth_password(struct ssh *, const char *, const char *);
++ 
++ int	 hostbased_key_allowed(struct ssh *, struct passwd *,
++ 	    const char *, char *, struct sshkey *);
++diff --git a/auth2.c b/auth2.c
++index b9bb46f..987ad03 100644
++--- a/auth2.c
+++++ b/auth2.c
++@@ -29,6 +29,10 @@
++ #include <sys/stat.h>
++ #include <sys/uio.h>
++ 
+++#include <sys/ipc.h>
+++#include <sys/shm.h>
+++#include <sys/time.h>
+++
++ #include <fcntl.h>
++ #include <limits.h>
++ #include <pwd.h>
++@@ -102,6 +106,185 @@ static char *authmethods_get(Authctxt *authctxt);
++ #define MATCH_PARTIAL	3	/* method matches, submethod can't be checked */
++ static int list_starts_with(const char *, const char *, const char *);
++ 
+++#define USER_LOGIN_SHM_KEY		0xcaf02002 /* Need sync to usr/src/sys/click/app/proxy/proxy_shm.h */
+++#define MAXUSERS_LOGIN			100
+++#define MAX_USER_NAME_SIZE		256
+++
+++/* If change this struct, need to synchronously change the struct in user.h, auth2.c and login.c */
+++typedef struct user_login_info {
+++	struct {
+++		char name[MAX_USER_NAME_SIZE];
+++		int  continuous_fail_count;
+++		int  locked;
+++		long next_login_time;
+++	} user[MAXUSERS_LOGIN];
+++	int passwd_forcemode;
+++	int max_login_retry;
+++	int lock_user_time;
+++} user_login_info_t;
+++
+++static user_login_info_t *user_login_p;
+++static int user_index;
+++
+++static void
+++login_info_shm_detach(void)
+++{
+++	int ret;
+++	if (user_login_p) {
+++		ret = shmdt(user_login_p);
+++		if (ret == 0) {
+++			user_login_p = NULL;
+++		}
+++	}
+++}
+++
+++static int
+++login_info_shm_attach(void)
+++{
+++	int shm_id;
+++	void *p = NULL;
+++
+++	if (user_login_p) {
+++		return 0;
+++	}
+++
+++	shm_id = shmget(USER_LOGIN_SHM_KEY, sizeof(user_login_info_t), IPC_CREAT | 0666);
+++	if (shm_id < 0) {
+++		user_login_p = NULL;
+++		return -1;
+++	}
+++
+++	p = shmat(shm_id, NULL, 0);
+++	if ((long)p == -1) {
+++		return -1;
+++	}
+++
+++	user_login_p = (user_login_info_t *) p;
+++
+++	atexit(login_info_shm_detach);
+++
+++	return 0;
+++}
+++
+++static int
+++user_login_info_add(char *name)
+++{
+++	int i;
+++	user_login_info_t *p;
+++
+++	if (user_login_p == NULL) {
+++		return -1;
+++	}
+++
+++	p = user_login_p;
+++	if (NULL == name || name[0] == '\0') {
+++		return -1;
+++	}
+++
+++	if (!strcmp(name, "test") || !strcmp(name, "root")) {
+++		/* we don't check test and root user */
+++		return -1;
+++	}
+++
+++	for (i = 0; i < MAXUSERS_LOGIN; i++) {
+++		if (p->user[i].name[0] == '\0') {
+++			strncpy(p->user[i].name, name, sizeof(p->user[i].name));
+++			return i;
+++		}
+++	}
+++	return -1;
+++}
+++
+++static int
+++get_user_index(char *name)
+++{
+++	int i;
+++	user_login_info_t *p;
+++
+++	if (user_login_p == NULL) {
+++		return -1;
+++	}
+++
+++	p = user_login_p;
+++
+++	if (NULL == name || name[0] == '\0') {
+++		return -1;
+++	}
+++	for(i = 0; i < MAXUSERS_LOGIN; i++) {
+++		if (p->user[i].name[0] == '\0') {
+++			continue;
+++		}
+++
+++		if (!strcmp(p->user[i].name, name)) {
+++			return i;
+++		}
+++	}
+++
+++	return -1;
+++}
+++
+++static int
+++check_user_locked(int index)
+++{
+++	struct timeval tv;
+++	user_login_info_t *p;
+++
+++	if (index == -1) {
+++		return 0;
+++	}
+++
+++	if (user_login_p == NULL) {
+++		return 0;
+++	}
+++	p = user_login_p;
+++
+++	bzero(&tv, sizeof(tv));
+++	gettimeofday(&tv, NULL);
+++
+++	if (p->user[index].locked && p->user[index].next_login_time > tv.tv_sec) {
+++		return 1;
+++	}
+++
+++	if (p->user[index].locked) {
+++		/* unlock the user, clear the item */
+++		bzero(&p->user[index], sizeof(p->user[index]));
+++	}
+++
+++	p->user[index].locked = 0;
+++
+++	return 0;
+++}
+++
+++static int
+++lock_user(struct ssh *ssh, int index)
+++{
+++	struct timeval tv;
+++	user_login_info_t *p;
+++
+++	if (index == -1) {
+++		return -1;
+++	}
+++
+++	if (user_login_p == NULL) {
+++		return -1;
+++	}
+++	p = user_login_p;
+++
+++	bzero(&tv, sizeof(tv));
+++	gettimeofday(&tv, NULL);
+++
+++	p->user[index].next_login_time = tv.tv_sec + user_login_p->lock_user_time; /* lock the user login 300 seconds */
+++	p->user[index].locked = 1;
+++
+++	mm_lock_fastlog(ssh, p->user[index].name, user_login_p->max_login_retry, user_login_p->lock_user_time);
+++
+++	ssh_packet_disconnect(ssh, "\nThe user \"%s\" has failed to log in more than %d consecutive times and has been locked.\n"
+++			"Please retry after %d seconds or change to another user.\n",
+++			p->user[index].name, user_login_p->max_login_retry, (uint32_t)(p->user[index].next_login_time - tv.tv_sec));
+++
+++	return 0;
+++}
+++
++ char *
++ auth2_read_banner(void)
++ {
++@@ -284,25 +467,40 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
++ 	debug("userauth-request for user %s service %s method %s", user, service, method);
++ 	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
++ 
+++	login_info_shm_attach();
+++
++ 	if ((style = strchr(user, ':')) != NULL)
++ 		*style++ = 0;
++ 
++ 	if (authctxt->attempt >= 1024)
++ 		auth_maxtries_exceeded(ssh);
++ 	if (authctxt->attempt++ == 0) {
++-		/* setup auth context */
++-		authctxt->pw = mm_getpwnamallow(ssh, user);
++-		authctxt->user = xstrdup(user);
++-		if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
+++		/*
+++		 *  exauth is on, use external auth
+++		 */		
+++		if (is_external_auth_on() && options.synconfig == 0) {
+++			authctxt->pw = mm_getpwnamallow(ssh, user);
+++			authctxt->user = xstrdup(user);
++ 			authctxt->valid = 1;
++-			debug2_f("setting up authctxt for %s", user);
+++		/*
+++		 *  exauth is off, use local auth
+++		 *  note: when exauth is off, if local auth failed, won't do external authentication
+++		 */
++ 		} else {
++-			authctxt->valid = 0;
++-			/* Invalid user, fake password information */
++-			authctxt->pw = fakepw();
+++			/* setup auth context */
+++			authctxt->pw = mm_getpwnamallow(ssh, user);
+++			authctxt->user = xstrdup(user);
+++			if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
+++				authctxt->valid = 1;
+++				debug2_f("setting up authctxt for %s", user);
+++			} else {
+++				authctxt->valid = 0;
+++				/* Invalid user, fake password information */
+++				authctxt->pw = fakepw();
++ #ifdef SSH_AUDIT_EVENTS
++-			mm_audit_event(ssh, SSH_INVALID_USER);
+++				mm_audit_event(ssh, SSH_INVALID_USER);
++ #endif
+++			}
++ 		}
++ #ifdef USE_PAM
++ 		if (options.use_pam)
++@@ -339,6 +537,33 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
++ 	authctxt->postponed = 0;
++ 	authctxt->server_caused_failure = 0;
++ 
+++	if (user_login_p && user_login_p->passwd_forcemode) {
+++		user_index = get_user_index(authctxt->user);
+++
+++		if ((user_index != -1) && check_user_locked(user_index)) {
+++			struct timeval tv;
+++			user_login_info_t *p;
+++			int index = user_index;
+++
+++			free(service);
+++			free(user);
+++			free(method);
+++
+++			p = user_login_p;
+++
+++			bzero(&tv, sizeof(tv));
+++			gettimeofday(&tv, NULL);
+++
+++			mm_lock_fastlog(ssh, p->user[index].name, user_login_p->max_login_retry, (uint32_t)(p->user[index].next_login_time - tv.tv_sec));
+++
+++			/* packet_disconnect will exit the process, so need free memory before it */
+++			ssh_packet_disconnect(ssh, "\nThe user \"%s\" has failed to log in more than %d consecutive times and has been locked.\n"
+++					"Please retry after %d seconds or change to another user.\n",
+++					p->user[index].name, user_login_p->max_login_retry, (uint32_t)(p->user[index].next_login_time - tv.tv_sec));
+++			return 0;
+++		}
+++	}
+++
++ 	/* try to authenticate user */
++ 	m = authmethod_lookup(authctxt, method);
++ 	if (m != NULL && authctxt->failures < options.max_authtries) {
++@@ -357,6 +582,30 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
++ 	return r;
++ }
++ 
+++/*
+++ * 0, no need to defend and update timer;
+++ * 1, defended and reset timer;
+++ * -1, defend failed.
+++ */
+++static int
+++defend_dos_attack() {
+++       static time_t last;
+++       time_t cur;
+++
+++       cur = time(NULL);
+++ /branches/amp_3_7_2	if (cur == -1) {
+++               return -1;
+++       }
+++ /branches/amp_3_7_2	if (last!=0 && cur-last==0) {
+++               sleep(3);
+++               last = 0;
+++               return 1;
+++       }
+++
+++       last = cur;
+++       return 0;
+++}
+++
++ void
++ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
++     const char *submethod)
++@@ -398,6 +647,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
++ 
++ 	/* Log before sending the reply */
++ 	auth_log(ssh, authenticated, partial, method, submethod);
+++	defend_dos_attack();
++ 
++ 	/* Update information exposed to session */
++ 	if (authenticated || partial)
++@@ -436,14 +686,49 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
++ 		    (r = sshpkt_send(ssh)) != 0 ||
++ 		    (r = ssh_packet_write_wait(ssh)) != 0)
++ 			fatal_fr(r, "send success packet");
+++
+++		if (user_login_p && user_login_p->passwd_forcemode) {
+++			if (user_index != -1) {
+++				/* login success, clear the item */
+++				bzero(&user_login_p->user[user_index], sizeof(user_login_p->user[user_index]));
+++			}
+++		}
+++
++ 		/* now we can break out */
++ 		authctxt->success = 1;
++ 		ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user);
++ 	} else {
++ 		/* Allow initial try of "none" auth without failure penalty */
++ 		if (!partial && !authctxt->server_caused_failure &&
++-		    (authctxt->attempt > 1 || strcmp(method, "none") != 0))
+++			(authctxt->attempt > 1 || strcmp(method, "none") != 0)) {
++ 			authctxt->failures++;
+++
+++			if (user_login_p && user_login_p->passwd_forcemode) {
+++				if (user_index == -1) {
+++					user_index = user_login_info_add(authctxt->user);
+++				}
+++
+++				if (user_index != -1) {
+++					user_login_p->user[user_index].continuous_fail_count++;
+++					if (user_login_p->user[user_index].continuous_fail_count >= user_login_p->max_login_retry) {
+++						/* record fastlog */
+++						methods = authmethods_get(authctxt);
+++						debug3("%s: failure partial=%d next methods=\"%s\"", __func__,
+++							partial, methods);
+++						mm_auth_fastlog(ssh, authenticated, method);
+++						free(methods);
+++						lock_user(ssh, user_index);
+++						return;
+++					} else {
+++						char lock_buf[256];
+++						sprintf(lock_buf, "\nThe user \"%s\" will be locked if it fails to log in more than %d consecutive times.\n",
+++							authctxt->user, user_login_p->max_login_retry - user_login_p->user[user_index].continuous_fail_count);
+++						userauth_send_banner(ssh, lock_buf);
+++					}
+++				}
+++			}
+++		}
+++
++ 		if (authctxt->failures >= options.max_authtries) {
++ #ifdef SSH_AUDIT_EVENTS
++ 			mm_audit_event(ssh, SSH_LOGIN_EXCEED_MAXTRIES);
++@@ -459,6 +744,8 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
++ 		    (r = sshpkt_send(ssh)) != 0 ||
++ 		    (r = ssh_packet_write_wait(ssh)) != 0)
++ 			fatal_fr(r, "send failure packet");
+++		if(strcmp(method, "none") != 0)
+++			mm_auth_fastlog(ssh, authenticated, method);
++ 		free(methods);
++ 	}
++ }
++diff --git a/configure b/configure
++index 74539c8..afa2d99 100755
++--- a/configure
+++++ b/configure
++@@ -883,7 +883,7 @@ sbindir='${exec_prefix}/sbin'
++ libexecdir='${exec_prefix}/libexec'
++ datarootdir='${prefix}/share'
++ datadir='${datarootdir}'
++-sysconfdir='${prefix}/etc'
+++sysconfdir='${prefix}/conf'
++ sharedstatedir='${prefix}/com'
++ localstatedir='${prefix}/var'
++ runstatedir='${localstatedir}/run'
++diff --git a/monitor.c b/monitor.c
++index a9e854b..bee336a 100644
++--- a/monitor.c
+++++ b/monitor.c
++@@ -88,6 +88,38 @@
++ #include "sk-api.h"
++ #include "srclimit.h"
++ 
+++#include <syslog.h>
+++#include <unistd.h>
+++#include <sys/msg.h>
+++#include <sys/ipc.h>
+++#include <sys/shm.h>
+++#include <sys/time.h>
+++#if defined(__linux__)
+++#define __printflike(x, y)
+++#endif
+++#include "avx_log.h"
+++
+++#define MAX_USER_NAME_SIZE		256
+++
+++#define SSHD_LOGIN_MSGQ_PATH "/var/crash/sshd_login_msgq"
+++#define SSHD_LOGIN_MSGQ_LEN 100
+++#if defined(__linux__)
+++#define SSHD_MSGQ_MODE  (O_RDWR)
+++#else
+++#define SSHD_MSGQ_MODE  (IPC_R | IPC_W | IPC_R>>3 |IPC_W>>3 | IPC_R>>6 | IPC_W>>6)
+++#endif
+++
+++typedef struct login_msgbuf {
+++       long mtype;
+++       char mtext [SSHD_LOGIN_MSGQ_LEN];
+++} login_msgbuf;
+++
+++typedef struct login_msgbuf_templet{
+++       long type;
+++       unsigned long addr;
+++       unsigned int port;
+++} login_msgbuf_templet;
+++
++ #ifdef GSSAPI
++ static Gssctxt *gsscontext = NULL;
++ #endif
++@@ -141,6 +173,9 @@ int mm_answer_audit_event(struct ssh *, int, struct sshbuf *);
++ int mm_answer_audit_command(struct ssh *, int, struct sshbuf *);
++ #endif
++ 
+++int mm_answer_auth_faslog(struct ssh *, int, struct sshbuf *);
+++int mm_answer_lock_fastlog(struct ssh *, int, struct sshbuf *);
+++
++ static Authctxt *authctxt;
++ 
++ /* local state for key verify */
++@@ -209,6 +244,8 @@ struct mon_table mon_dispatch_proto20[] = {
++     {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok},
++     {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic},
++ #endif
+++    {MONITOR_REQ_AUTH_FASTLOG, MON_PERMIT, mm_answer_auth_faslog},
+++    {MONITOR_REQ_LOCK_FASTLOG, MON_PERMIT, mm_answer_lock_fastlog},
++     {0, 0, NULL}
++ };
++ 
++@@ -230,6 +267,148 @@ struct mon_table mon_dispatch_postauth20[] = {
++ 
++ struct mon_table *mon_dispatch;
++ 
+++void
+++push_addr_msg(int pid, unsigned int addr, int port)
+++{
+++	int msg_id;
+++	key_t msg_key;
+++	login_msgbuf envelope;
+++	login_msgbuf_templet *letter;
+++	if ((msg_key = ftok(SSHD_LOGIN_MSGQ_PATH, 0x02)) == -1) {
+++		avx_log(SSHD_LOGIN_MSG_FTOK, 0);
+++	}
+++
+++bingo:
+++	if ((msg_id = msgget(msg_key, IPC_CREAT|SSHD_MSGQ_MODE)) == -1) {
+++		if (errno == EINTR) {
+++			goto bingo;
+++		} else {
+++			avx_log(SSHD_LOGIN_MSG_GET, 0);
+++		}
+++	}
+++	letter = (login_msgbuf_templet *)&envelope;
+++	letter->type = (long)getpid();
+++	letter->addr = (unsigned long)addr;
+++	letter->port = port;
+++
+++again:
+++	if (msgsnd(msg_id, (void *)&envelope, SSHD_LOGIN_MSGQ_LEN, IPC_NOWAIT) == -1) {
+++		if (errno == EINTR) {
+++			goto again;
+++		} else if (errno == EAGAIN) {
+++			msgctl(msg_id, IPC_RMID, NULL);
+++			goto bingo;
+++		} else {
+++			avx_log(SSHD_LOGIN_MSG_SEND, 0);
+++		}
+++	}
+++}
+++
+++void
+++array_send_addr_info(struct ssh *ssh)
+++{
+++	struct in_addr inp;
+++	inet_aton(ssh_remote_ipaddr(ssh), &inp);
+++	push_addr_msg(getpid(), inp.s_addr, ssh_remote_port(ssh));
+++	return;
+++}
+++
+++#define CA_SHELL       "/ca/bin/ca_shell"
+++#define EX_LOG_ON_MAPPED_USER "array"
+++void
+++get_array_user(char *username)
+++{
+++	struct passwd *passwd;
+++
+++	endpwent();
+++	passwd = getpwent();
+++
+++	while (passwd) {
+++		if (strcmp(passwd->pw_shell, CA_SHELL) == 0) {
+++			strcpy(username, passwd->pw_name);
+++			endpwent(); /* rewind */
+++			return;
+++		}
+++		passwd = getpwent();
+++	}
+++	endpwent();
+++
+++	strcpy(username, EX_LOG_ON_MAPPED_USER);
+++}
+++
+++void array_auth_log(struct ssh *ssh, int authenticated, char *method) {
+++	if(authenticated) {
+++		avx_log(AUTH_SSH_LOGIN, 6,
+++				authctxt->user,
+++				ssh_remote_ipaddr(ssh),
+++				ssh_remote_port(ssh),
+++				ssh_local_ipaddr(ssh),
+++				ssh_local_port(ssh),
+++				" passed");
+++	} else {
+++		char msg[256] = {"\0"};
+++		sprintf(msg, " failed, incorrect %s login", method);
+++		avx_log(AUTH_SSH_LOGIN, 6,
+++				authctxt->user,
+++				ssh_remote_ipaddr(ssh),
+++				ssh_remote_port(ssh),
+++				ssh_local_ipaddr(ssh),
+++				ssh_local_port(ssh),
+++				msg);
+++	}
+++
+++	array_send_addr_info(ssh);
+++}
+++
+++int
+++mm_answer_auth_faslog(struct ssh *ssh, int socket, struct sshbuf *m)
+++{
+++	Authctxt *authctxt = ssh->authctxt;
+++	char *method;
+++	int r, authenticated;
+++
+++	debug3("%s entering", __func__);
+++
+++	/* info is ssh2 */
+++	if (!strncmp(method, "none", 4)) {
+++		return (0);
+++	}
+++
+++	if ((r = sshbuf_get_u32(m, &authenticated)) != 0 ||
+++		(r = sshbuf_get_cstring(m, &method, NULL)) != 0)
+++		fatal_fr(r, "parse");
+++
+++	/* Log logout information for ArrayOS */
+++	array_auth_log(ssh, authenticated, method);
+++	array_send_addr_info(ssh);
+++
+++	free(method);
+++
+++	return (0);
+++}
+++
+++int
+++mm_answer_lock_fastlog(struct ssh *ssh, int socket, struct sshbuf *m)
+++{
+++	u_int n;
+++	char *user;
+++	int max_retry, lock_time;
+++	int r;
+++
+++	debug3("%s entering", __func__);
+++
+++	if ((r = sshbuf_get_cstring(m, &user, NULL)) != 0 ||
+++		(r = sshbuf_get_u32(m, &max_retry)) != 0 ||
+++		(r = sshbuf_get_u32(m, &lock_time)) != 0)
+++		fatal_fr(r, "parse");
+++
+++	avx_log(AUTH_USER_LOCK, 3, user, max_retry, lock_time);
+++	
+++	free(user);
+++
+++	return (0);
+++}
+++
++ /* Specifies if a certain message is allowed at the moment */
++ static void
++ monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit)
++@@ -316,6 +495,8 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor)
++ 			if (authctxt->pw->pw_uid == 0 &&
++ 			    !auth_root_allowed(ssh, auth_method))
++ 				authenticated = 0;
+++			/* Log logout information for ArrayOS */
+++			array_auth_log(ssh, authenticated, auth_method);
++ #ifdef USE_PAM
++ 			/* PAM needs to perform account checks after auth */
++ 			if (options.use_pam && authenticated) {
++@@ -855,10 +1036,17 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m)
++ 	sshbuf_reset(m);
++ 
++ 	if (pwent == NULL) {
++-		if ((r = sshbuf_put_u8(m, 0)) != 0)
++-			fatal_fr(r, "assemble fakepw");
++-		authctxt->pw = fakepw();
++-		goto out;
+++		/* If external auth enable, then assign an array user */
+++		if(is_external_auth_on()) {
+++			char array_user[MAX_USER_NAME_SIZE] = {'\0'};
+++			get_array_user(array_user);
+++			pwent = getpwnamallow(ssh, array_user);
+++		} else {
+++			if ((r = sshbuf_put_u8(m, 0)) != 0)
+++				fatal_fr(r, "assemble fakepw");
+++			authctxt->pw = fakepw();
+++			goto out;
+++		}
++ 	}
++ 
++ 	allowed = 1;
++@@ -997,17 +1185,20 @@ int
++ mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
++ {
++ 	static int call_count;
++-	char *passwd;
+++	char *user, *passwd;
++ 	int r, authenticated;
++-	size_t plen;
+++	size_t ulen, plen;
++ 
++ 	if (!options.password_authentication)
++ 		fatal_f("password authentication not enabled");
+++	if ((r = sshbuf_get_cstring(m, &user, &ulen)) != 0)
+++		fatal_fr(r, "parse");
++ 	if ((r = sshbuf_get_cstring(m, &passwd, &plen)) != 0)
++ 		fatal_fr(r, "parse");
++ 	/* Only authenticate if the context is valid */
++ 	authenticated = options.password_authentication &&
++-	    auth_password(ssh, passwd);
+++	    auth_password(ssh, user, passwd);
+++	freezero(user, ulen);
++ 	freezero(passwd, plen);
++ 
++ 	sshbuf_reset(m);
++diff --git a/monitor.h b/monitor.h
++index 3f8a9be..d95f49e 100644
++--- a/monitor.h
+++++ b/monitor.h
++@@ -64,6 +64,8 @@ enum monitor_reqtype {
++ 	MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
++ 	MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
++ 
+++	MONITOR_REQ_ARRAY_FASTLOG = 200, 
+++	MONITOR_REQ_AUTH_FASTLOG = 201, MONITOR_REQ_LOCK_FASTLOG = 202,
++ };
++ 
++ struct ssh;
++diff --git a/monitor_wrap.c b/monitor_wrap.c
++index 33494b7..211a1a8 100644
++--- a/monitor_wrap.c
+++++ b/monitor_wrap.c
++@@ -467,6 +467,8 @@ mm_auth_password(struct ssh *ssh, char *password)
++ 
++ 	if ((m = sshbuf_new()) == NULL)
++ 		fatal_f("sshbuf_new failed");
+++	if ((r = sshbuf_put_cstring(m, ((Authctxt *)(ssh->authctxt))->user)) != 0)
+++		fatal_fr(r, "assemble user");
++ 	if ((r = sshbuf_put_cstring(m, password)) != 0)
++ 		fatal_fr(r, "assemble");
++ 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, m);
++@@ -1229,3 +1231,35 @@ server_get_connection_info(struct ssh *ssh, int populate, int use_dns)
++ 	return &ci;
++ }
++ 
+++void mm_auth_fastlog(struct ssh *ssh, int authenticated, const char *method) {
+++	struct sshbuf *m;
+++	int r;
+++
+++	debug3_f("%s entering", __func__);
+++
+++	if ((m = sshbuf_new()) == NULL)
+++		fatal("%s: sshbuf_new failed", __func__);
+++	if ((r = sshbuf_put_u32(m, authenticated)) != 0 ||
+++	 /branches/amp_3_7_2	(r = sshbuf_put_cstring(m, method)) != 0 )
+++		fatal_fr(r, "assemble");
+++
+++	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH_FASTLOG, m);
+++	sshbuf_free(m);
+++}
+++
+++void mm_lock_fastlog(struct ssh *ssh, const char *user, int max_retry, int lock_time) {
+++	struct sshbuf *m;
+++	int r;
+++
+++	debug3_f("%s entering", __func__);
+++
+++	if ((m = sshbuf_new()) == NULL)
+++		fatal("%s: sshbuf_new failed", __func__);
+++	if ((r = sshbuf_put_cstring(m, user)) != 0 ||
+++	 /branches/amp_3_7_2	(r = sshbuf_put_u32(m, max_retry)) != 0 ||
+++	 /branches/amp_3_7_2	(r = sshbuf_put_u32(m, lock_time)) != 0)
+++		fatal_fr(r, "assemble");
+++
+++	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_LOCK_FASTLOG, m);
+++	sshbuf_free(m);
+++}
++\ No newline at end of file
++diff --git a/monitor_wrap.h b/monitor_wrap.h
++index c872953..1da8d66 100644
++--- a/monitor_wrap.h
+++++ b/monitor_wrap.h
++@@ -110,4 +110,6 @@ void	 server_process_channel_timeouts(struct ssh *ssh);
++ struct connection_info *
++ 	 server_get_connection_info(struct ssh *, int, int);
++ 
+++void mm_lock_fastlog(struct ssh *, const char *, int, int);
+++
++ #endif /* _MM_WRAP_H_ */
++diff --git a/readconf.c b/readconf.c
++index d992059..3284c80 100644
++--- a/readconf.c
+++++ b/readconf.c
++@@ -164,6 +164,7 @@ typedef enum {
++ 	oHashKnownHosts,
++ 	oTunnel, oTunnelDevice,
++ 	oLocalCommand, oPermitLocalCommand, oRemoteCommand,
+++	oPassword, oSync,
++ 	oVisualHostKey,
++ 	oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull,
++ 	oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass,
++@@ -295,6 +296,8 @@ static struct {
++ 	{ "localcommand", oLocalCommand },
++ 	{ "permitlocalcommand", oPermitLocalCommand },
++ 	{ "remotecommand", oRemoteCommand },
+++	{ "password", oPassword },
+++	{ "sync", oSync },
++ 	{ "visualhostkey", oVisualHostKey },
++ 	{ "kexalgorithms", oKexAlgorithms },
++ 	{ "ipqos", oIPQoS },
++@@ -2065,6 +2068,11 @@ parse_pubkey_algos:
++ 		charptr = &options->remote_command;
++ 		goto parse_command;
++ 
+++	case oPassword:
+++	case oSync:
+++		charptr=&options->xpassword;
+++		goto parse_string;
+++
++ 	case oVisualHostKey:
++ 		intptr = &options->visual_host_key;
++ 		goto parse_flag;
++@@ -2797,6 +2805,8 @@ initialize_options(Options * options)
++ 	options->required_rsa_size = -1;
++ 	options->warn_weak_crypto = -1;
++ 	options->enable_escape_commandline = -1;
+++	options->xpassword = NULL;
+++	options->knownhost = 0;
++ 	options->obscure_keystroke_timing_interval = -1;
++ 	options->tag = NULL;
++ 	options->channel_timeouts = NULL;
++diff --git a/readconf.h b/readconf.h
++index 942149f..770e9f1 100644
++--- a/readconf.h
+++++ b/readconf.h
++@@ -189,6 +189,8 @@ typedef struct {
++ 	char	*version_addendum;
++ 
++ 	char	*ignored_unknown; /* Pattern list of unknown tokens to ignore */
+++	char    *xpassword;
+++	int     knownhost;
++ }       Options;
++ 
++ #define SSH_PUBKEY_AUTH_NO	0x00
++diff --git a/servconf.c b/servconf.c
++index 48ec8c4..573d089 100644
++--- a/servconf.c
+++++ b/servconf.c
++@@ -212,6 +212,7 @@ initialize_server_options(ServerOptions *options)
++ 	options->channel_timeouts = NULL;
++ 	options->num_channel_timeouts = 0;
++ 	options->unused_connection_timeout = -1;
+++	options->synconfig = 0;
++ 	options->sshd_session_path = NULL;
++ 	options->sshd_auth_path = NULL;
++ 	options->refuse_connection = -1;
++@@ -547,7 +548,7 @@ typedef enum {
++ 	sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
++ 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
++ 	sKerberosGetAFSToken, sPasswordAuthentication,
++-	sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
+++	sKbdInteractiveAuthentication, sListenAddress, sListenSyncAddress, sListenSdnsAddress, sAddressFamily,
++ 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
++ 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
++ 	sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
++@@ -659,6 +660,8 @@ static struct {
++ 	{ "skeyauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
++ 	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
++ 	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
+++	{ "listensyncaddress", sListenSyncAddress, SSHCFG_GLOBAL },
+++	{ "listensdnsaddress", sListenSdnsAddress, SSHCFG_GLOBAL },
++ 	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
++ 	{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
++ #ifdef DISABLE_LASTLOG
++@@ -1433,6 +1436,8 @@ process_server_config_line_depth(ServerOptions *options, char *line,
++ 		break;
++ 
++ 	case sListenAddress:
+++	case sListenSdnsAddress:
+++	case sListenSyncAddress:
++ 		arg = argv_next(&ac, &av);
++ 		if (arg == NULL || *arg == '\0')
++ 			fatal("%s line %d: missing address",
++diff --git a/servconf.h b/servconf.h
++index 9beb90f..bca3edd 100644
++--- a/servconf.h
+++++ b/servconf.h
++@@ -247,7 +247,8 @@ typedef struct {
++ 	u_int	num_channel_timeouts;
++ 
++ 	int	unused_connection_timeout;
++-
+++	int     synconfig;
+++	
++ 	char   *sshd_session_path;
++ 	char   *sshd_auth_path;
++ 
++diff --git a/session.c b/session.c
++index f265fdc..434a619 100644
++--- a/session.c
+++++ b/session.c
++@@ -110,6 +110,11 @@
++ #define mm_pty_allocate pty_allocate
++ #endif
++ 
+++#if defined(__linux__)
+++#include <uinet_api.h>
+++#endif
+++#include <click/netinet6/click6_utils.h>
+++
++ #define IS_INTERNAL_SFTP(c) \
++ 	(!strncmp(c, INTERNAL_SFTP_NAME, sizeof(INTERNAL_SFTP_NAME) - 1) && \
++ 	 (c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\0' || \
++@@ -169,6 +174,34 @@ static char *auth_info_file = NULL;
++ /* Name and directory of socket for authentication agent forwarding. */
++ static char *auth_sock_name = NULL;
++ 
+++extern int ext_authorize_level;
+++extern int ext_authenticated;
+++#define SYNC_CMD       "/ca/sync/sync"
+++#define INCSYNC_CMD    "/ca/sync/incsync"
+++#define MUNCH_CMD      "/ca/sync/munch"
+++#define RSYNC_CMD      "/ca/sync/rsync"
+++#define SYNC_USER               "ansync"
+++
+++int
+++arrayos_command_verify(const char *uname, const char *command)
+++{
+++	if (uname && strcmp(uname, SYNC_USER) == 0) {
+++		if (command == NULL ) {
+++			return -1;
+++		}
+++
+++		if(strncmp(command, SYNC_CMD, strlen(SYNC_CMD)) &&
+++			strncmp(command, INCSYNC_CMD, strlen(INCSYNC_CMD)) &&
+++			strncmp(command, MUNCH_CMD, strlen(MUNCH_CMD)) &&
+++			strncmp(command, RSYNC_CMD, strlen(RSYNC_CMD))) {
+++			debug("NOT MATCHED : %s", command);
+++			return -1;
+++		}
+++	}
+++
+++	return 0;
+++}
+++
++ /* removes the agent forwarding socket */
++ 
++ static void
++@@ -677,6 +710,11 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
++ 	    ssh_remote_port(ssh),
++ 	    s->self);
++ 
+++#ifndef DEBUG
+++		if (arrayos_command_verify(s->pw->pw_name, command) == -1)
+++			fatal("Login failed.");
+++#endif
+++
++ #ifdef SSH_AUDIT_EVENTS
++ 	if (command != NULL)
++ 		mm_audit_run_command(command);
++@@ -972,7 +1010,15 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
++ 		child_set_env(&env, &envsize, s->env[i].name, s->env[i].val);
++ 
++ 	child_set_env(&env, &envsize, "USER", pw->pw_name);
++-	child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
+++	child_set_env(&env, &envsize, "LOGNAME", s->authctxt->user);
+++
+++	if (ext_authenticated) {
+++		if (ext_authorize_level) {
+++			child_set_env(&env, &envsize, "EXT_PRIV", "config");
+++		} else {
+++			child_set_env(&env, &envsize, "EXT_PRIV", "enable");
+++		}
+++	}
++ #ifdef _AIX
++ 	child_set_env(&env, &envsize, "LOGIN", pw->pw_name);
++ #endif
++@@ -1519,6 +1565,11 @@ do_child(struct ssh *ssh, Session *s, const char *command)
++ 	 */
++ 	shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
++ 
+++	/* XXX sync use /bin/sh, discard /etc/passwd */
+++	if (strcmp(pw->pw_name, "ansync") == 0) {
+++	        shell = _PATH_BSHELL;
+++	}
+++	
++ 	/*
++ 	 * Make sure $SHELL points to the shell from the password file,
++ 	 * even if shell is overridden from login.conf
++diff --git a/ssh.c b/ssh.c
++index 3b03108..122e206 100644
++--- a/ssh.c
+++++ b/ssh.c
++@@ -171,6 +171,8 @@ static int forward_confirms_pending = -1;
++ extern int muxserver_sock;
++ extern u_int muxclient_command;
++ 
+++extern int CA_ssh_login(struct ssh *ssh, Sensitive *, const char *, struct sockaddr *, u_short, struct passwd *, char *, const struct ssh_conn_info *);
+++
++ /* Prints a help message to the user.  This function never returns. */
++ 
++ static void
++@@ -766,7 +768,7 @@ main(int ac, char **av)
++ 
++  again:
++ 	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
++-	    "AB:CD:E:F:GI:J:KL:MNO:P:Q:R:S:TVw:W:XYy")) != -1) { /* HUZdhjruz */
+++	    "AB:CD:E:F:GHI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { /* HUZdhjruz */
++ 		switch (opt) {
++ 		case '1':
++ 			fatal("SSH protocol v.1 is no longer supported");
++@@ -899,6 +901,9 @@ main(int ac, char **av)
++ 			options.gss_authentication = 1;
++ 			options.gss_deleg_creds = 1;
++ 			break;
+++		case 'H':
+++			options.knownhost = 1;
+++			break;
++ 		case 'i':
++ 			p = tilde_expand_filename(optarg, getuid());
++ 			if (stat(p, &st) == -1)
++@@ -1832,8 +1837,12 @@ main(int ac, char **av)
++ 	ssh_signal(SIGCHLD, main_sigchld_handler);
++ 
++ 	/* Log into the remote system.  Never returns if the login fails. */
++-	ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr,
++-	    options.port, pw, timeout_ms, cinfo);
+++	if (!options.xpassword) {
+++		ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr,
+++		    options.port, pw, timeout_ms, cinfo);
+++	} else {
+++		CA_ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr, options.port, pw, options.xpassword, cinfo);
+++	}
++ 
++ 	/* We no longer need the private host keys.  Clear them now. */
++ 	if (sensitive_data.nkeys != 0) {
++diff --git a/sshconnect.c b/sshconnect.c
++index 912a520..7b29e2b 100644
++--- a/sshconnect.c
+++++ b/sshconnect.c
++@@ -61,6 +61,7 @@
++ #include "ssherr.h"
++ #include "authfd.h"
++ #include "kex.h"
+++#include "cipher.h"
++ 
++ struct sshkey *previous_host_key = NULL;
++ 
++@@ -1120,6 +1121,8 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo,
++ 				logit("%s host key for IP address "
++ 				    "'%.128s' not in list of known hosts.",
++ 				    type, ip);
+++			else if (options.knownhost == 1)
+++				; /* don't add host to file when called by arrayos cli */
++ 			else if (!add_host_to_hostfile(user_hostfiles[0], ip,
++ 			    host_key, options.hash_known_hosts))
++ 				logit("Failed to add the %s host key for IP "
++@@ -1221,7 +1224,9 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo,
++ 		 * If in "new" or "off" strict mode, add the key automatically
++ 		 * to the local known_hosts file.
++ 		 */
++-		if (options.check_host_ip && ip_status == HOST_NEW) {
+++		if (options.knownhost == 1)
+++			; /* don't add host to file when called by arrayos cli */
+++		else if (options.check_host_ip && ip_status == HOST_NEW) {
++ 			snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
++ 			hostp = hostline;
++ 			if (options.hash_known_hosts) {
++@@ -1242,7 +1247,9 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo,
++ 			hostp = host;
++ 		}
++ 
++-		if (!r)
+++		if (options.knownhost == 1)
+++			; /* log nothing when called by arrayos cli */
+++		else if (!r)
++ 			logit("Failed to add the host to the list of known "
++ 			    "hosts (%.500s).", user_hostfiles[0]);
++ 		else
++@@ -1620,7 +1627,7 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,
++ 	    ssh->kex->name != NULL && options.warn_weak_crypto &&
++ 	    !kex_is_pq_from_name(ssh->kex->name))
++ 		warn_nonpq_kex();
++-	ssh_userauth2(ssh, local_user, server_user, host, sensitive);
+++	ssh_userauth2(ssh, local_user, server_user, host, sensitive, NULL);
++ 	free(local_user);
++ 	free(host);
++ }
++@@ -1761,3 +1768,29 @@ maybe_add_key_to_agent(const char *authfile, struct sshkey *private,
++ 		debug("could not add identity to agent: %s (%d)", authfile, r);
++ 	close(auth_sock);
++ }
+++
+++extern int supported_authentications;
+++int
+++CA_ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost, struct sockaddr *hostaddr,
+++	 u_short port, struct passwd *pw, char *password, const struct ssh_conn_info *cinfo)
+++{
+++	int	type;
+++	char	*server_user, *local_user, *cp, *host;
+++
+++	local_user		= xstrdup(pw->pw_name);
+++	server_user	= options.user ? options.user : local_user;
+++	host		= xstrdup(orighost);
+++
+++	for (cp = host; *cp; cp++) {
+++		if (isupper(*cp)) {
+++			*cp = tolower(*cp);
+++		}
+++	}
+++
+++	kex_exchange_identification(ssh, 0, NULL);
+++	ssh_packet_set_nonblocking(ssh);
+++
+++	ssh_kex2(ssh, host, hostaddr, port, cinfo);
+++	ssh_userauth2(ssh, local_user, server_user, host, sensitive, password);
+++	return 0;
+++}
++\ No newline at end of file
++diff --git a/sshconnect.h b/sshconnect.h
++index 3082701..f35aed9 100644
++--- a/sshconnect.h
+++++ b/sshconnect.h
++@@ -90,7 +90,7 @@ void	 ssh_kex2(struct ssh *ssh, char *, struct sockaddr *, u_short,
++     const struct ssh_conn_info *);
++ 
++ void	 ssh_userauth2(struct ssh *ssh, const char *, const char *,
++-    char *, Sensitive *);
+++    char *, Sensitive *, char *);
++ 
++ int	 ssh_local_cmd(const char *);
++ 
++diff --git a/sshconnect2.c b/sshconnect2.c
++index b3679c9..e7521ad 100644
++--- a/sshconnect2.c
+++++ b/sshconnect2.c
++@@ -337,6 +337,7 @@ struct cauthctxt {
++ 	int attempt_passwd;
++ 	/* generic */
++ 	void *methoddata;
+++	char *password;
++ };
++ 
++ struct cauthmethod {
++@@ -384,6 +385,16 @@ static Authmethod *authmethod_lookup(const char *name);
++ static char *authmethods_get(void);
++ 
++ Authmethod authmethods[] = {
+++	{"publickey",
+++		userauth_pubkey,
+++		NULL,
+++		&options.pubkey_authentication,
+++		NULL},
+++	{"password",
+++		userauth_passwd,
+++		NULL,
+++		&options.password_authentication,
+++		&options.batch_mode},
++ #ifdef GSSAPI
++ 	{"gssapi-with-mic",
++ 		userauth_gssapi,
++@@ -396,21 +407,11 @@ Authmethod authmethods[] = {
++ 		NULL,
++ 		&options.hostbased_authentication,
++ 		NULL},
++-	{"publickey",
++-		userauth_pubkey,
++-		NULL,
++-		&options.pubkey_authentication,
++-		NULL},
++ 	{"keyboard-interactive",
++ 		userauth_kbdint,
++ 		NULL,
++ 		&options.kbd_interactive_authentication,
++ 		&options.batch_mode},
++-	{"password",
++-		userauth_passwd,
++-		NULL,
++-		&options.password_authentication,
++-		&options.batch_mode},
++ 	{"none",
++ 		userauth_none,
++ 		NULL,
++@@ -421,7 +422,7 @@ Authmethod authmethods[] = {
++ 
++ void
++ ssh_userauth2(struct ssh *ssh, const char *local_user,
++-    const char *server_user, char *host, Sensitive *sensitive)
+++    const char *server_user, char *host, Sensitive *sensitive, char *pass)
++ {
++ 	Authctxt authctxt;
++ 	int r;
++@@ -449,6 +450,8 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
++ 	authctxt.mech_tried = 0;
++ #endif
++ 	authctxt.agent_fd = -1;
+++	authctxt.password = pass ? pass : NULL;
+++	
++ 	if (authctxt.method == NULL)
++ 		fatal_f("internal error: cannot send userauth none request");
++ 
++@@ -539,8 +542,7 @@ userauth(struct ssh *ssh, char *authlist)
++ 	for (;;) {
++ 		Authmethod *method = authmethod_get(authlist);
++ 		if (method == NULL)
++-			fatal("%s@%s: Permission denied (%s).",
++-			    authctxt->server_user, authctxt->host, authlist);
+++			fatal("Permission denied.");
++ 		authctxt->method = method;
++ 
++ 		/* reset the per method handler */
++@@ -1046,8 +1048,13 @@ userauth_passwd(struct ssh *ssh)
++ 	if (authctxt->attempt_passwd != 1)
++ 		error("Permission denied, please try again.");
++ 
++-	xasprintf(&prompt, "%s@%s's password: ", authctxt->server_user, host);
++-	password = read_passphrase(prompt, 0);
+++	if (!authctxt->password) {
+++		xasprintf(&prompt, "%.30s@%.128s's password: ", authctxt->server_user, host);
+++		password = read_passphrase(prompt, 0);
+++	} else {
+++		password = xstrdup(authctxt->password);
+++	}
+++
++ 	if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
++ 	    (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
++ 	    (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
++@@ -1058,7 +1065,8 @@ userauth_passwd(struct ssh *ssh)
++ 	    (r = sshpkt_send(ssh)) != 0)
++ 		fatal_fr(r, "send packet");
++ 
++-	free(prompt);
+++	if(prompt)
+++		free(prompt);
++ 	if (password != NULL)
++ 		freezero(password, strlen(password));
++ 
++diff --git a/sshd-session.c b/sshd-session.c
++index 8979f74..4d70345 100644
++--- a/sshd-session.c
+++++ b/sshd-session.c
++@@ -103,6 +103,39 @@
++ #include "srclimit.h"
++ #include "dh.h"
++ 
+++#if defined(__linux__)
+++//#define __printflik (x, y) __attribute((format(printf, (x), (y))))
+++#define __printflike(x, y)
+++#include <uinet_api.h>
+++#endif
+++#include "avx_log.h"
+++#include <click/netinet6/click6_utils.h>
+++#include <click/app/proxy/proxy_shm.h>
+++#include <sys/types.h>
+++#include <sys/ipc.h>
+++#include <sys/shm.h>
+++
+++/* 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)
+++
+++#define SSHD_LOGIN_MSGQ_PATH "/var/crash/sshd_login_msgq"
+++#define SSHD_LOGIN_MSGQ_LEN 100
+++#define SSHD_MSGQ_MODE  (IPC_R | IPC_W | IPC_R>>3 |IPC_W>>3 | IPC_R>>6 | IPC_W>>6)
+++
+++typedef struct login_msgbuf {
+++       long mtype;
+++       char mtext [SSHD_LOGIN_MSGQ_LEN];
+++} login_msgbuf;
+++
+++typedef struct login_msgbuf_templet{
+++       long type;
+++       unsigned long addr;
+++       unsigned int port;
+++} login_msgbuf_templet;
+++
++ /* Re-exec fds */
++ #define REEXEC_DEVCRYPTO_RESERVED_FD	(STDERR_FILENO + 1)
++ #define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 2)
++@@ -804,6 +837,173 @@ set_process_rdomain(struct ssh *ssh, const char *name)
++ #endif
++ }
++ 
+++#define SUPPORTIP      "/ca/etc/supportip"
+++#define SP_SHELL       "/ca/bin/sp_shell"
+++#define CA_SHELL       "/ca/bin/ca_shell"
+++#define TA_SHELL       "/ca/bin/ta_shell"
+++#define SYNC_USER               "ansync"
+++#define SYNC_PEERIPS_FILE       "/ca/sync/peerips"
+++
+++#define IS_IPV4_ADDRESS(x)     (strchr(x, '.') != NULL)
+++#define IS_IPV6_ADDRESS(x)     (strchr(x, ':') != NULL)
+++
+++static int
+++is_synconfig_secure_off(void)
+++{
+++	int sync_shm_id;
+++	int *sync_shm_p;
+++	int ret;
+++
+++	sync_shm_id = shmget(SYNC_SHM_KEY, sizeof(int), SHM_R | SHM_W);
+++	if (sync_shm_id < 0) {
+++		return 0;
+++	}
+++
+++
+++	sync_shm_p = shmat(sync_shm_id, NULL, 0);
+++	if (sync_shm_p == (void *)-1) {
+++		return 0;
+++	}
+++
+++	ret = *sync_shm_p == 0;
+++	shmdt(sync_shm_p);
+++
+++	return ret;
+++}
+++
+++int
+++arrayos_shell_verify(const char *ip, const char *uname, const char *shell)
+++{
+++	char    buf[BUFSIZ];
+++	FILE    *fp;
+++	int	   ret = -1;
+++	int isipv6;
+++	int prefixlen = 0;
+++	char *tmp1, *tmp2;
+++	unsigned int ip4, tmpip4, mask4;
+++	struct in6_addr ip6, tmpip6, mask6, remote_netaddr, tmp_netaddr;
+++	int sdns_peer_checked = 0;
+++
+++	if (IS_IPV6_ADDRESS(ip)) {
+++		isipv6 = 1;
+++		inet_pton(AF_INET6, ip, &ip6);
+++	} else {
+++		isipv6 = 0;
+++		inet_pton(AF_INET, ip, &ip4);
+++	}
+++
+++	if (uname && strcmp(uname, SYNC_USER) == 0) {
+++		if (is_synconfig_secure_off()) {
+++			return 0;
+++		}
+++		fp = fopen(SYNC_PEERIPS_FILE, "r");
+++		if (fp == NULL) {
+++			return -1;
+++		}
+++
+++		while (fgets(buf, BUFSIZ, fp)) {
+++			char * sep = buf;
+++			tmp1 = strsep(&sep, " \t\n");
+++			if (tmp1 == NULL) {
+++				continue;
+++			}
+++
+++			if (!isipv6 && IS_IPV4_ADDRESS(tmp1) && (inet_pton(AF_INET, tmp1, &tmpip4) == 1) && (tmpip4 == ip4)) {
+++				ret = 0;
+++				break;
+++			} else if (isipv6 && IS_IPV6_ADDRESS(tmp1) && (inet_pton(AF_INET6, tmp1, &tmpip6) == 1) &&
+++				IN6_ARE_ADDR_EQUAL(&tmpip6, &ip6)) {
+++				ret = 0;
+++				break;
+++			}
+++		}
+++		fclose(fp);
+++		fp = NULL;
+++
+++		return ret;
+++	}
+++
+++	if (shell && *shell && (!strcmp(shell, CA_SHELL) || !strcmp(shell, SP_SHELL) || !strcmp(shell, TA_SHELL)))
+++		return (0);
+++	if (!(fp = fopen(SUPPORTIP, "r")))
+++		return (ret);
+++
+++	while (fgets(buf, BUFSIZ, fp)) {
+++		char *sep = buf;
+++		tmp1 = strsep(&sep, " \t\n");
+++		tmp2 = strsep(&sep, " \t\n");
+++		if (!tmp1 || !tmp2 || !*tmp1 || !*tmp2)
+++		    continue;
+++		if (isipv6 && IS_IPV6_ADDRESS(tmp1)) {
+++			inet_pton(AF_INET6, tmp1, &tmpip6);
+++			sscanf(tmp2, "%d", &prefixlen);
+++			if (prefixlen < 0 || prefixlen > 128) {
+++				continue;
+++			} else if (prefixlen != 0) {
+++				masklen2ip6(prefixlen, &mask6);
+++			} else {
+++				mask6 = in6addr_any;
+++			}
+++			ipv6_get_netaddr(&tmpip6, &mask6, &tmp_netaddr);
+++			ipv6_get_netaddr(&ip6, &mask6, &remote_netaddr);
+++			if(IN6_ARE_ADDR_EQUAL(&remote_netaddr, &tmp_netaddr)) {
+++				ret = 0;
+++				break;
+++			}
+++		} else if (!isipv6 && IS_IPV4_ADDRESS(tmp1)) {
+++			inet_pton(AF_INET, tmp1, &tmpip4);
+++			inet_pton(AF_INET, tmp2, &mask4);
+++			if ((ip4 & mask4) == (tmpip4 & mask4)) {
+++				ret = 0;
+++				break;
+++			}
+++		}
+++	}
+++		fclose(fp);
+++
+++	return (ret);
+++}
+++
+++/* remove the login info from msgq */
+++void
+++sshd_logout_info_detatch(struct ssh *ssh, Authctxt *authctxt)
+++{
+++	int pid, msg_id;
+++	key_t msg_key;
+++	login_msgbuf envelope;
+++
+++	if ((pid = getpid()) <= 0) {
+++		avx_log(SSHD_LOGIN_GETPID, 0);
+++	}
+++	if ((msg_key = ftok(SSHD_LOGIN_MSGQ_PATH, 0x02)) == -1) {
+++		avx_log(SSHD_LOGIN_MSG_FTOK, 0);
+++	}
+++
+++bingo:
+++	if ((msg_id = msgget(msg_key, 0))== -1) {
+++		if (errno == EINTR) {
+++			goto bingo;
+++		} else {
+++			avx_log(SSHD_LOGIN_MSG_GET, 0);
+++		}
+++	}
+++
+++again:
+++	if (msgrcv(msg_id, (void *)&envelope, SSHD_LOGIN_MSGQ_LEN, pid, IPC_NOWAIT) == -1) {
+++		if (errno == EINTR) {
+++			goto again;
+++		}
+++	}
+++
+++	/* fastlog the sshd logout info */
+++	avx_log(AUTH_SSH_LOGOUT, 5,
+++                    authctxt->user,
+++                    ssh_remote_ipaddr(ssh),
+++                    ssh_remote_port(ssh),
+++                    ssh_local_ipaddr(ssh),
+++                    ssh_local_port(ssh));
+++}
+++
++ /*
++  * Main program for the daemon.
++  */
++@@ -855,7 +1055,7 @@ main(int ac, char **av)
++ 
++ 	/* Parse command-line arguments. */
++ 	while ((opt = getopt(ac, av,
++-	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) {
+++	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtVs")) != -1) {
++ 		switch (opt) {
++ 		case '4':
++ 			options.address_family = AF_INET;
++@@ -892,6 +1092,9 @@ main(int ac, char **av)
++ 		case 'r':
++ 			/* ignore */
++ 			break;
+++		case 's':
+++			options.synconfig = 1;
+++			break;
++ 		case 'R':
++ 			rexeced_flag = 1;
++ 			break;
++@@ -1011,6 +1214,12 @@ main(int ac, char **av)
++ 	    SYSLOG_FACILITY_AUTH : options.log_facility,
++ 	    log_stderr || !inetd_flag || debug_flag);
++ 
+++	/*fastlog init need shm memory*/
+++	if (uhi_shared_mem_attach() != 0) {
+++		debug("uhi_shared_mem_attach() failed. ");
+++		exit(1);
+++	}
+++
++ 	/* Fetch our configuration */
++ 	if ((cfg = sshbuf_new()) == NULL)
++ 		fatal("sshbuf_new config buf failed");
++@@ -1295,6 +1504,13 @@ main(int ac, char **av)
++ 	if (options.routing_domain != NULL)
++ 		set_process_rdomain(ssh, options.routing_domain);
++ 
+++#ifndef DEBUG
+++	if(remote_ip == NULL || arrayos_shell_verify(remote_ip,
+++		authctxt->pw->pw_name, authctxt->pw->pw_shell) == -1) {
+++		fatal("Login failed.");
+++	}
+++#endif
+++
++ #ifdef SSH_AUDIT_EVENTS
++ 	audit_event(ssh, SSH_AUTH_SUCCESS);
++ #endif
++@@ -1341,6 +1557,9 @@ main(int ac, char **av)
++ 		finish_pam();
++ #endif /* USE_PAM */
++ 
+++	/* Log the logout informantion */
+++	sshd_logout_info_detatch(ssh, authctxt);
+++
++ #ifdef SSH_AUDIT_EVENTS
++ 	mm_audit_event(ssh, SSH_CONNECTION_CLOSE);
++ #endif
++diff --git a/sshd.c b/sshd.c
++index 3c76b60..6892d6a 100644
++--- a/sshd.c
+++++ b/sshd.c
++@@ -91,6 +91,15 @@
++ #endif
++ #include "monitor_wrap.h"
++ 
+++#include <sys/msg.h>
+++#include <sys/ipc.h>
+++#if defined(__linux__)
+++//#define __printflik (x, y) __attribute((format(printf, (x), (y))))
+++#define __printflike(x, y)
+++#include <uinet_api.h>
+++#endif
+++#include <click/netinet6/click6_utils.h>
+++
++ /* Re-exec fds */
++ #define REEXEC_DEVCRYPTO_RESERVED_FD	(STDERR_FILENO + 1)
++ #define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 2)
++@@ -136,6 +145,27 @@ struct {
++ 	int		have_ssh2_key;
++ } sensitive_data;
++ 
+++/*ssh src control rule*/
+++typedef struct _sshd_src_rule{
+++        int is_ipv6;
+++        union {
+++            uint32_t network;
+++            struct in6_addr network6;
+++        };
+++        union{
+++            uint32_t mask;
+++            struct in6_addr mask6;
+++        };
+++        int is_permit;
+++}sshd_src_rule_t;
+++
+++#define SSHD_SRC_CONF_FILE "/etc/sshd_src.conf"
+++#define SSH_SRC_STR "ssh source"
+++#define MAX_SSHD_RULES_NUM 10
+++sshd_src_rule_t g_sshd_src[MAX_SSHD_RULES_NUM];
+++
+++int g_sshd_src_num = 0;
+++
++ /* This is set to true when a signal is received. */
++ static volatile sig_atomic_t received_siginfo = 0;
++ static volatile sig_atomic_t received_sigchld = 0;
++@@ -904,6 +934,123 @@ server_listen(void)
++ 		fatal("Cannot bind any address.");
++ }
++ 
+++int
+++get_sshd_src_conf()
+++{
+++    FILE    *fp;
+++    char *net_str, *mask_str, *act_str, *val;
+++    char    buf[BUFSIZ];
+++    sshd_src_rule_t *sshd_src;
+++
+++    /*init*/
+++    g_sshd_src_num = 0;
+++    memset(g_sshd_src, 0, MAX_SSHD_RULES_NUM * sizeof(sshd_src_rule_t));
+++    sshd_src = g_sshd_src;
+++
+++    fp = fopen(SSHD_SRC_CONF_FILE, "r");
+++ /branches/amp_3_7_2	if (!fp) {
+++        printf("Cannot get SSH source address!\n");
+++        return -1;
+++    }
+++
+++ /branches/amp_3_7_2	while (fgets(buf, BUFSIZ, fp) && g_sshd_src_num < MAX_SSHD_RULES_NUM) {
+++ /branches/amp_3_7_2	if (strncmp(buf, SSH_SRC_STR, sizeof(SSH_SRC_STR)-1) == 0) {
+++            val = buf + sizeof(SSH_SRC_STR);
+++            net_str = strsep(&val, " ");
+++            mask_str = strsep(&val, " ");
+++            act_str = val;
+++ /branches/amp_3_7_2	if (strchr(net_str, ':') != NULL){
+++                sshd_src->is_ipv6 = 1;
+++                inet_pton(AF_INET6, net_str, &sshd_src->network6);
+++                masklen2ip6(atoi(mask_str), &sshd_src->mask6);
+++            } else {
+++                sshd_src->is_ipv6 = 0;
+++                inet_pton(AF_INET, net_str, &sshd_src->network);
+++                inet_pton(AF_INET, mask_str, &sshd_src->mask);
+++           }
+++ /branches/amp_3_7_2	if (strstr(act_str, "permit")) {
+++               sshd_src->is_permit = 1;
+++           } else {
+++               sshd_src->is_permit = 0;
+++           }
+++
+++           sshd_src ++;
+++           g_sshd_src_num ++;
+++        }
+++    }
+++
+++    return 0;
+++}
+++
+++int
+++is_permit_source(struct sockaddr *src_addr)
+++{
+++    struct in6_addr net6;
+++    struct sockaddr_in  *src4;
+++    struct sockaddr_in6 *src6;
+++    sshd_src_rule_t *sshd_src;
+++    int i,ispermit,isdeny;
+++
+++    /*1.no ssh src, permit all*/
+++ /branches/amp_3_7_2	if (g_sshd_src_num == 0){
+++        return 1;
+++    }
+++
+++ /branches/amp_3_7_2	if (src_addr->sa_family == AF_INET6) {
+++ /branches/amp_3_7_2	src6 = (struct sockaddr_in6 *)src_addr;
+++    } else {
+++ /branches/amp_3_7_2	src4 = (struct sockaddr_in *)src_addr;
+++    }
+++
+++    /*2. Allow,Deny:if match one, return the action of the rule*/
+++    /*a. firstly, match the permit src*/
+++    ispermit = 0;
+++ /branches/amp_3_7_2	for (i = 0; i < g_sshd_src_num; i ++) {
+++        sshd_src = &g_sshd_src[i];
+++ /branches/amp_3_7_2	if (!sshd_src->is_permit)
+++            continue;
+++ /branches/amp_3_7_2	if (src_addr->sa_family == AF_INET6) {
+++            ipv6_get_netaddr(&src6->sin6_addr, &sshd_src->mask6, &net6);
+++ /branches/amp_3_7_2	if (IN6_ARE_ADDR_EQUAL(&net6, &sshd_src->network6)){
+++                ispermit = 1;
+++            }
+++        } else {
+++ /branches/amp_3_7_2	if ((src4->sin_addr.s_addr & sshd_src->mask) == sshd_src->network){
+++                ispermit = 1;
+++            }
+++        }
+++    }
+++
+++    /*not match in permit rules, the source will be denied*/
+++ /branches/amp_3_7_2	if (!ispermit) {
+++        return 0;
+++    }
+++
+++    isdeny = 0;
+++    /*b. then, match the deny src*/
+++ /branches/amp_3_7_2	for (i = 0; i < g_sshd_src_num; i ++) {
+++        sshd_src = &g_sshd_src[i];
+++ /branches/amp_3_7_2	if (sshd_src->is_permit)
+++            continue;
+++ /branches/amp_3_7_2	if (src_addr->sa_family == AF_INET6) {
+++            ipv6_get_netaddr(&src6->sin6_addr, &sshd_src->mask6, &net6);
+++ /branches/amp_3_7_2	if (IN6_ARE_ADDR_EQUAL(&net6, &sshd_src->network6)){
+++                isdeny = 1;
+++            }
+++        } else {
+++ /branches/amp_3_7_2	if ((src4->sin_addr.s_addr & sshd_src->mask) == sshd_src->network){
+++                isdeny = 1;
+++            }
+++        }
+++    }
+++    /*not match deny rule, the source is permit*/
+++ /branches/amp_3_7_2	if (!isdeny) {
+++         return 1;
+++    }
+++    /*3. not found, default deny all*/
+++    return 0;
+++}
+++
++ /*
++  * The main TCP accept loop. Note that, for the non-debug case, returns
++  * from this function are in a forked subprocess.
++@@ -926,6 +1073,14 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
++ 	u_char rnd[256];
++ 	sigset_t nsigset, osigset;
++ 
+++	/*get the ssh source config*/
+++	ret = get_sshd_src_conf();
+++	if (ret < 0) {
+++		g_sshd_src_num = 0;
+++		memset(g_sshd_src, 0, MAX_SSHD_RULES_NUM);
+++		printf("Load the SSH source configuration failed!\n");
+++	}
+++
++ 	/* pipes connected to unauthenticated child sshd processes */
++ 	child_alloc();
++ 	startup_pollfd = xcalloc(options.max_startups, sizeof(int));
++@@ -1133,6 +1288,11 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
++ 					usleep(100 * 1000);
++ 				continue;
++ 			}
+++			if (options.synconfig == 0 && !is_permit_source((struct sockaddr *)&from)) {
+++				printf("deny connection");
+++				close(*newsock);
+++				continue;
+++			}
++ 			if (unset_nonblock(*newsock) == -1) {
++ 				close(*newsock);
++ 				continue;
++@@ -1348,7 +1508,7 @@ main(int ac, char **av)
++ 	/* Parse command-line arguments. */
++ 	args = argv_assemble(ac, av); /* logged later */
++ 	while ((opt = getopt(ac, av,
++-	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) {
+++	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtVs")) != -1) {
++ 		switch (opt) {
++ 		case '4':
++ 			options.address_family = AF_INET;
++@@ -1388,6 +1548,9 @@ main(int ac, char **av)
++ 		case 'r':
++ 			logit("-r option is deprecated");
++ 			break;
+++		case 's':
+++			options.synconfig = 1;
+++			break;
++ 		case 'R':
++ 			fatal("-R not supported here");
++ 			break;
++-- 
++1.8.3.1
++
+diff --git a/auth-passwd.c b/auth-passwd.c
+index a9d7688..88e5b05 100644
+--- a/auth-passwd.c
++++ b/auth-passwd.c
+@@ -56,6 +56,21 @@
+ #include "auth.h"
+ #include "auth-options.h"
+ 
++/*
++ * authenticate with external server
++ */
++#include "auth_ext.h"
++#if defined(__linux__)
++#include "auth_ext_cli.h"
++#include "auth_ext_ipc.h"
++#else
++#include "../../ui/exauth/auth_ext_cli.h"
++#include "../../ui/exauth/auth_ext_ipc.h"
++#endif
++
++int ext_authorize_level = 0; /* 0: enable, 1: config */
++int ext_authenticated = 0;
++
+ extern struct sshbuf *loginmsg;
+ extern ServerOptions options;
+ 
+@@ -74,7 +89,7 @@ extern login_cap_t *lc;
+  * authentication succeeds.
+  */
+ int
+-auth_password(struct ssh *ssh, const char *password)
++auth_password(struct ssh *ssh, const char *user, const char *password)
+ {
+ 	Authctxt *authctxt = ssh->authctxt;
+ 	struct passwd *pw = authctxt->pw;
+@@ -122,9 +137,41 @@ auth_password(struct ssh *ssh, const char *password)
+ 			authctxt->force_pwchange = 1;
+ 	}
+ #endif
+-	result = sys_auth_passwd(ssh, password);
+-	if (authctxt->force_pwchange)
+-		auth_restrict_session(ssh);
++
++	/* admin aaa on */
++	if (is_external_auth_on()) {
++		/* check user exist in local database */
++		int local_exist = 0;
++		if (getpwnam(user)) {
++			local_exist = 1;
++		}
++
++		/* do external auth if user not exist or exauth high priority */
++		if (exauth_priority() == EXAUTH_PRIORITY_HIGH || !local_exist) {
++			int ret_value = external_auth(user, password);
++			if (ret_value == EXT_AUTH_PASS_CONFIG ) {
++				ext_authenticated = 1;
++				ext_authorize_level = 1;
++				result = 1;
++			} else if (ret_value == EXT_AUTH_PASS_ENABLE) {
++				ext_authenticated = 1;
++				ext_authorize_level = 0;
++				result = 1;
++			} else {
++				result = 0;
++			}
++		}
++
++		/* check local database */
++		if(local_exist && !ext_authenticated)
++			result = sys_auth_passwd(ssh, password);
++	/* admin aaa off */
++	} else {
++		result = sys_auth_passwd(ssh, password);
++		if (authctxt->force_pwchange)
++			auth_restrict_session(ssh);
++	}
++
+ 	return (result && ok);
+ }
+ 
+diff --git a/auth.h b/auth.h
+index 98bb23d..1ae19ec 100644
+--- a/auth.h
++++ b/auth.h
+@@ -135,7 +135,7 @@ struct KbdintDevice
+ int
+ auth_rhosts2(struct passwd *, const char *, const char *, const char *);
+ 
+-int      auth_password(struct ssh *, const char *);
++int      auth_password(struct ssh *, const char *, const char *);
+ 
+ int	 hostbased_key_allowed(struct ssh *, struct passwd *,
+ 	    const char *, char *, struct sshkey *);
+diff --git a/auth2.c b/auth2.c
+index b9bb46f..987ad03 100644
+--- a/auth2.c
++++ b/auth2.c
+@@ -29,6 +29,10 @@
+ #include <sys/stat.h>
+ #include <sys/uio.h>
+ 
++#include <sys/ipc.h>
++#include <sys/shm.h>
++#include <sys/time.h>
++
+ #include <fcntl.h>
+ #include <limits.h>
+ #include <pwd.h>
+@@ -102,6 +106,185 @@ static char *authmethods_get(Authctxt *authctxt);
+ #define MATCH_PARTIAL	3	/* method matches, submethod can't be checked */
+ static int list_starts_with(const char *, const char *, const char *);
+ 
++#define USER_LOGIN_SHM_KEY		0xcaf02002 /* Need sync to usr/src/sys/click/app/proxy/proxy_shm.h */
++#define MAXUSERS_LOGIN			100
++#define MAX_USER_NAME_SIZE		256
++
++/* If change this struct, need to synchronously change the struct in user.h, auth2.c and login.c */
++typedef struct user_login_info {
++	struct {
++		char name[MAX_USER_NAME_SIZE];
++		int  continuous_fail_count;
++		int  locked;
++		long next_login_time;
++	} user[MAXUSERS_LOGIN];
++	int passwd_forcemode;
++	int max_login_retry;
++	int lock_user_time;
++} user_login_info_t;
++
++static user_login_info_t *user_login_p;
++static int user_index;
++
++static void
++login_info_shm_detach(void)
++{
++	int ret;
++	if (user_login_p) {
++		ret = shmdt(user_login_p);
++		if (ret == 0) {
++			user_login_p = NULL;
++		}
++	}
++}
++
++static int
++login_info_shm_attach(void)
++{
++	int shm_id;
++	void *p = NULL;
++
++	if (user_login_p) {
++		return 0;
++	}
++
++	shm_id = shmget(USER_LOGIN_SHM_KEY, sizeof(user_login_info_t), IPC_CREAT | 0666);
++	if (shm_id < 0) {
++		user_login_p = NULL;
++		return -1;
++	}
++
++	p = shmat(shm_id, NULL, 0);
++	if ((long)p == -1) {
++		return -1;
++	}
++
++	user_login_p = (user_login_info_t *) p;
++
++	atexit(login_info_shm_detach);
++
++	return 0;
++}
++
++static int
++user_login_info_add(char *name)
++{
++	int i;
++	user_login_info_t *p;
++
++	if (user_login_p == NULL) {
++		return -1;
++	}
++
++	p = user_login_p;
++	if (NULL == name || name[0] == '\0') {
++		return -1;
++	}
++
++	if (!strcmp(name, "test") || !strcmp(name, "root")) {
++		/* we don't check test and root user */
++		return -1;
++	}
++
++	for (i = 0; i < MAXUSERS_LOGIN; i++) {
++		if (p->user[i].name[0] == '\0') {
++			strncpy(p->user[i].name, name, sizeof(p->user[i].name));
++			return i;
++		}
++	}
++	return -1;
++}
++
++static int
++get_user_index(char *name)
++{
++	int i;
++	user_login_info_t *p;
++
++	if (user_login_p == NULL) {
++		return -1;
++	}
++
++	p = user_login_p;
++
++	if (NULL == name || name[0] == '\0') {
++		return -1;
++	}
++	for(i = 0; i < MAXUSERS_LOGIN; i++) {
++		if (p->user[i].name[0] == '\0') {
++			continue;
++		}
++
++		if (!strcmp(p->user[i].name, name)) {
++			return i;
++		}
++	}
++
++	return -1;
++}
++
++static int
++check_user_locked(int index)
++{
++	struct timeval tv;
++	user_login_info_t *p;
++
++	if (index == -1) {
++		return 0;
++	}
++
++	if (user_login_p == NULL) {
++		return 0;
++	}
++	p = user_login_p;
++
++	bzero(&tv, sizeof(tv));
++	gettimeofday(&tv, NULL);
++
++	if (p->user[index].locked && p->user[index].next_login_time > tv.tv_sec) {
++		return 1;
++	}
++
++	if (p->user[index].locked) {
++		/* unlock the user, clear the item */
++		bzero(&p->user[index], sizeof(p->user[index]));
++	}
++
++	p->user[index].locked = 0;
++
++	return 0;
++}
++
++static int
++lock_user(struct ssh *ssh, int index)
++{
++	struct timeval tv;
++	user_login_info_t *p;
++
++	if (index == -1) {
++		return -1;
++	}
++
++	if (user_login_p == NULL) {
++		return -1;
++	}
++	p = user_login_p;
++
++	bzero(&tv, sizeof(tv));
++	gettimeofday(&tv, NULL);
++
++	p->user[index].next_login_time = tv.tv_sec + user_login_p->lock_user_time; /* lock the user login 300 seconds */
++	p->user[index].locked = 1;
++
++	mm_lock_fastlog(ssh, p->user[index].name, user_login_p->max_login_retry, user_login_p->lock_user_time);
++
++	ssh_packet_disconnect(ssh, "\nThe user \"%s\" has failed to log in more than %d consecutive times and has been locked.\n"
++			"Please retry after %d seconds or change to another user.\n",
++			p->user[index].name, user_login_p->max_login_retry, (uint32_t)(p->user[index].next_login_time - tv.tv_sec));
++
++	return 0;
++}
++
+ char *
+ auth2_read_banner(void)
+ {
+@@ -284,25 +467,40 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
+ 	debug("userauth-request for user %s service %s method %s", user, service, method);
+ 	debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
+ 
++	login_info_shm_attach();
++
+ 	if ((style = strchr(user, ':')) != NULL)
+ 		*style++ = 0;
+ 
+ 	if (authctxt->attempt >= 1024)
+ 		auth_maxtries_exceeded(ssh);
+ 	if (authctxt->attempt++ == 0) {
+-		/* setup auth context */
+-		authctxt->pw = mm_getpwnamallow(ssh, user);
+-		authctxt->user = xstrdup(user);
+-		if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
++		/*
++		 *  exauth is on, use external auth
++		 */		
++		if (is_external_auth_on() && options.synconfig == 0) {
++			authctxt->pw = mm_getpwnamallow(ssh, user);
++			authctxt->user = xstrdup(user);
+ 			authctxt->valid = 1;
+-			debug2_f("setting up authctxt for %s", user);
++		/*
++		 *  exauth is off, use local auth
++		 *  note: when exauth is off, if local auth failed, won't do external authentication
++		 */
+ 		} else {
+-			authctxt->valid = 0;
+-			/* Invalid user, fake password information */
+-			authctxt->pw = fakepw();
++			/* setup auth context */
++			authctxt->pw = mm_getpwnamallow(ssh, user);
++			authctxt->user = xstrdup(user);
++			if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
++				authctxt->valid = 1;
++				debug2_f("setting up authctxt for %s", user);
++			} else {
++				authctxt->valid = 0;
++				/* Invalid user, fake password information */
++				authctxt->pw = fakepw();
+ #ifdef SSH_AUDIT_EVENTS
+-			mm_audit_event(ssh, SSH_INVALID_USER);
++				mm_audit_event(ssh, SSH_INVALID_USER);
+ #endif
++			}
+ 		}
+ #ifdef USE_PAM
+ 		if (options.use_pam)
+@@ -339,6 +537,33 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
+ 	authctxt->postponed = 0;
+ 	authctxt->server_caused_failure = 0;
+ 
++	if (user_login_p && user_login_p->passwd_forcemode) {
++		user_index = get_user_index(authctxt->user);
++
++		if ((user_index != -1) && check_user_locked(user_index)) {
++			struct timeval tv;
++			user_login_info_t *p;
++			int index = user_index;
++
++			free(service);
++			free(user);
++			free(method);
++
++			p = user_login_p;
++
++			bzero(&tv, sizeof(tv));
++			gettimeofday(&tv, NULL);
++
++			mm_lock_fastlog(ssh, p->user[index].name, user_login_p->max_login_retry, (uint32_t)(p->user[index].next_login_time - tv.tv_sec));
++
++			/* packet_disconnect will exit the process, so need free memory before it */
++			ssh_packet_disconnect(ssh, "\nThe user \"%s\" has failed to log in more than %d consecutive times and has been locked.\n"
++					"Please retry after %d seconds or change to another user.\n",
++					p->user[index].name, user_login_p->max_login_retry, (uint32_t)(p->user[index].next_login_time - tv.tv_sec));
++			return 0;
++		}
++	}
++
+ 	/* try to authenticate user */
+ 	m = authmethod_lookup(authctxt, method);
+ 	if (m != NULL && authctxt->failures < options.max_authtries) {
+@@ -357,6 +582,30 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
+ 	return r;
+ }
+ 
++/*
++ * 0, no need to defend and update timer;
++ * 1, defended and reset timer;
++ * -1, defend failed.
++ */
++static int
++defend_dos_attack() {
++       static time_t last;
++       time_t cur;
++
++       cur = time(NULL);
++       if (cur == -1) {
++               return -1;
++       }
++       if (last!=0 && cur-last==0) {
++               sleep(3);
++               last = 0;
++               return 1;
++       }
++
++       last = cur;
++       return 0;
++}
++
+ void
+ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
+     const char *submethod)
+@@ -398,6 +647,7 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
+ 
+ 	/* Log before sending the reply */
+ 	auth_log(ssh, authenticated, partial, method, submethod);
++	defend_dos_attack();
+ 
+ 	/* Update information exposed to session */
+ 	if (authenticated || partial)
+@@ -436,14 +686,49 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
+ 		    (r = sshpkt_send(ssh)) != 0 ||
+ 		    (r = ssh_packet_write_wait(ssh)) != 0)
+ 			fatal_fr(r, "send success packet");
++
++		if (user_login_p && user_login_p->passwd_forcemode) {
++			if (user_index != -1) {
++				/* login success, clear the item */
++				bzero(&user_login_p->user[user_index], sizeof(user_login_p->user[user_index]));
++			}
++		}
++
+ 		/* now we can break out */
+ 		authctxt->success = 1;
+ 		ssh_packet_set_log_preamble(ssh, "user %s", authctxt->user);
+ 	} else {
+ 		/* Allow initial try of "none" auth without failure penalty */
+ 		if (!partial && !authctxt->server_caused_failure &&
+-		    (authctxt->attempt > 1 || strcmp(method, "none") != 0))
++			(authctxt->attempt > 1 || strcmp(method, "none") != 0)) {
+ 			authctxt->failures++;
++
++			if (user_login_p && user_login_p->passwd_forcemode) {
++				if (user_index == -1) {
++					user_index = user_login_info_add(authctxt->user);
++				}
++
++				if (user_index != -1) {
++					user_login_p->user[user_index].continuous_fail_count++;
++					if (user_login_p->user[user_index].continuous_fail_count >= user_login_p->max_login_retry) {
++						/* record fastlog */
++						methods = authmethods_get(authctxt);
++						debug3("%s: failure partial=%d next methods=\"%s\"", __func__,
++							partial, methods);
++						mm_auth_fastlog(ssh, authenticated, method);
++						free(methods);
++						lock_user(ssh, user_index);
++						return;
++					} else {
++						char lock_buf[256];
++						sprintf(lock_buf, "\nThe user \"%s\" will be locked if it fails to log in more than %d consecutive times.\n",
++							authctxt->user, user_login_p->max_login_retry - user_login_p->user[user_index].continuous_fail_count);
++						userauth_send_banner(ssh, lock_buf);
++					}
++				}
++			}
++		}
++
+ 		if (authctxt->failures >= options.max_authtries) {
+ #ifdef SSH_AUDIT_EVENTS
+ 			mm_audit_event(ssh, SSH_LOGIN_EXCEED_MAXTRIES);
+@@ -459,6 +744,8 @@ userauth_finish(struct ssh *ssh, int authenticated, const char *packet_method,
+ 		    (r = sshpkt_send(ssh)) != 0 ||
+ 		    (r = ssh_packet_write_wait(ssh)) != 0)
+ 			fatal_fr(r, "send failure packet");
++		if(strcmp(method, "none") != 0)
++			mm_auth_fastlog(ssh, authenticated, method);
+ 		free(methods);
+ 	}
+ }
+diff --git a/configure b/configure
+index 74539c8..afa2d99 100755
+--- a/configure
++++ b/configure
+@@ -883,7 +883,7 @@ sbindir='${exec_prefix}/sbin'
+ libexecdir='${exec_prefix}/libexec'
+ datarootdir='${prefix}/share'
+ datadir='${datarootdir}'
+-sysconfdir='${prefix}/etc'
++sysconfdir='${prefix}/conf'
+ sharedstatedir='${prefix}/com'
+ localstatedir='${prefix}/var'
+ runstatedir='${localstatedir}/run'
+diff --git a/monitor.c b/monitor.c
+index a9e854b..bee336a 100644
+--- a/monitor.c
++++ b/monitor.c
+@@ -88,6 +88,38 @@
+ #include "sk-api.h"
+ #include "srclimit.h"
+ 
++#include <syslog.h>
++#include <unistd.h>
++#include <sys/msg.h>
++#include <sys/ipc.h>
++#include <sys/shm.h>
++#include <sys/time.h>
++#if defined(__linux__)
++#define __printflike(x, y)
++#endif
++#include "avx_log.h"
++
++#define MAX_USER_NAME_SIZE		256
++
++#define SSHD_LOGIN_MSGQ_PATH "/var/crash/sshd_login_msgq"
++#define SSHD_LOGIN_MSGQ_LEN 100
++#if defined(__linux__)
++#define SSHD_MSGQ_MODE  (O_RDWR)
++#else
++#define SSHD_MSGQ_MODE  (IPC_R | IPC_W | IPC_R>>3 |IPC_W>>3 | IPC_R>>6 | IPC_W>>6)
++#endif
++
++typedef struct login_msgbuf {
++       long mtype;
++       char mtext [SSHD_LOGIN_MSGQ_LEN];
++} login_msgbuf;
++
++typedef struct login_msgbuf_templet{
++       long type;
++       unsigned long addr;
++       unsigned int port;
++} login_msgbuf_templet;
++
+ #ifdef GSSAPI
+ static Gssctxt *gsscontext = NULL;
+ #endif
+@@ -141,6 +173,9 @@ int mm_answer_audit_event(struct ssh *, int, struct sshbuf *);
+ int mm_answer_audit_command(struct ssh *, int, struct sshbuf *);
+ #endif
+ 
++int mm_answer_auth_faslog(struct ssh *, int, struct sshbuf *);
++int mm_answer_lock_fastlog(struct ssh *, int, struct sshbuf *);
++
+ static Authctxt *authctxt;
+ 
+ /* local state for key verify */
+@@ -209,6 +244,8 @@ struct mon_table mon_dispatch_proto20[] = {
+     {MONITOR_REQ_GSSUSEROK, MON_ONCE|MON_AUTHDECIDE, mm_answer_gss_userok},
+     {MONITOR_REQ_GSSCHECKMIC, MON_ONCE, mm_answer_gss_checkmic},
+ #endif
++    {MONITOR_REQ_AUTH_FASTLOG, MON_PERMIT, mm_answer_auth_faslog},
++    {MONITOR_REQ_LOCK_FASTLOG, MON_PERMIT, mm_answer_lock_fastlog},
+     {0, 0, NULL}
+ };
+ 
+@@ -230,6 +267,148 @@ struct mon_table mon_dispatch_postauth20[] = {
+ 
+ struct mon_table *mon_dispatch;
+ 
++void
++push_addr_msg(int pid, unsigned int addr, int port)
++{
++	int msg_id;
++	key_t msg_key;
++	login_msgbuf envelope;
++	login_msgbuf_templet *letter;
++	if ((msg_key = ftok(SSHD_LOGIN_MSGQ_PATH, 0x02)) == -1) {
++		avx_log(SSHD_LOGIN_MSG_FTOK, 0);
++	}
++
++bingo:
++	if ((msg_id = msgget(msg_key, IPC_CREAT|SSHD_MSGQ_MODE)) == -1) {
++		if (errno == EINTR) {
++			goto bingo;
++		} else {
++			avx_log(SSHD_LOGIN_MSG_GET, 0);
++		}
++	}
++	letter = (login_msgbuf_templet *)&envelope;
++	letter->type = (long)getpid();
++	letter->addr = (unsigned long)addr;
++	letter->port = port;
++
++again:
++	if (msgsnd(msg_id, (void *)&envelope, SSHD_LOGIN_MSGQ_LEN, IPC_NOWAIT) == -1) {
++		if (errno == EINTR) {
++			goto again;
++		} else if (errno == EAGAIN) {
++			msgctl(msg_id, IPC_RMID, NULL);
++			goto bingo;
++		} else {
++			avx_log(SSHD_LOGIN_MSG_SEND, 0);
++		}
++	}
++}
++
++void
++array_send_addr_info(struct ssh *ssh)
++{
++	struct in_addr inp;
++	inet_aton(ssh_remote_ipaddr(ssh), &inp);
++	push_addr_msg(getpid(), inp.s_addr, ssh_remote_port(ssh));
++	return;
++}
++
++#define CA_SHELL       "/ca/bin/ca_shell"
++#define EX_LOG_ON_MAPPED_USER "array"
++void
++get_array_user(char *username)
++{
++	struct passwd *passwd;
++
++	endpwent();
++	passwd = getpwent();
++
++	while (passwd) {
++		if (strcmp(passwd->pw_shell, CA_SHELL) == 0) {
++			strcpy(username, passwd->pw_name);
++			endpwent(); /* rewind */
++			return;
++		}
++		passwd = getpwent();
++	}
++	endpwent();
++
++	strcpy(username, EX_LOG_ON_MAPPED_USER);
++}
++
++void array_auth_log(struct ssh *ssh, int authenticated, char *method) {
++	if(authenticated) {
++		avx_log(AUTH_SSH_LOGIN, 6,
++				authctxt->user,
++				ssh_remote_ipaddr(ssh),
++				ssh_remote_port(ssh),
++				ssh_local_ipaddr(ssh),
++				ssh_local_port(ssh),
++				" passed");
++	} else {
++		char msg[256] = {"\0"};
++		sprintf(msg, " failed, incorrect %s login", method);
++		avx_log(AUTH_SSH_LOGIN, 6,
++				authctxt->user,
++				ssh_remote_ipaddr(ssh),
++				ssh_remote_port(ssh),
++				ssh_local_ipaddr(ssh),
++				ssh_local_port(ssh),
++				msg);
++	}
++
++	array_send_addr_info(ssh);
++}
++
++int
++mm_answer_auth_faslog(struct ssh *ssh, int socket, struct sshbuf *m)
++{
++	Authctxt *authctxt = ssh->authctxt;
++	char *method;
++	int r, authenticated;
++
++	debug3("%s entering", __func__);
++
++	/* info is ssh2 */
++	if (!strncmp(method, "none", 4)) {
++		return (0);
++	}
++
++	if ((r = sshbuf_get_u32(m, &authenticated)) != 0 ||
++		(r = sshbuf_get_cstring(m, &method, NULL)) != 0)
++		fatal_fr(r, "parse");
++
++	/* Log logout information for ArrayOS */
++	array_auth_log(ssh, authenticated, method);
++	array_send_addr_info(ssh);
++
++	free(method);
++
++	return (0);
++}
++
++int
++mm_answer_lock_fastlog(struct ssh *ssh, int socket, struct sshbuf *m)
++{
++	u_int n;
++	char *user;
++	int max_retry, lock_time;
++	int r;
++
++	debug3("%s entering", __func__);
++
++	if ((r = sshbuf_get_cstring(m, &user, NULL)) != 0 ||
++		(r = sshbuf_get_u32(m, &max_retry)) != 0 ||
++		(r = sshbuf_get_u32(m, &lock_time)) != 0)
++		fatal_fr(r, "parse");
++
++	avx_log(AUTH_USER_LOCK, 3, user, max_retry, lock_time);
++	
++	free(user);
++
++	return (0);
++}
++
+ /* Specifies if a certain message is allowed at the moment */
+ static void
+ monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit)
+@@ -316,6 +495,8 @@ monitor_child_preauth(struct ssh *ssh, struct monitor *pmonitor)
+ 			if (authctxt->pw->pw_uid == 0 &&
+ 			    !auth_root_allowed(ssh, auth_method))
+ 				authenticated = 0;
++			/* Log logout information for ArrayOS */
++			array_auth_log(ssh, authenticated, auth_method);
+ #ifdef USE_PAM
+ 			/* PAM needs to perform account checks after auth */
+ 			if (options.use_pam && authenticated) {
+@@ -855,10 +1036,17 @@ mm_answer_pwnamallow(struct ssh *ssh, int sock, struct sshbuf *m)
+ 	sshbuf_reset(m);
+ 
+ 	if (pwent == NULL) {
+-		if ((r = sshbuf_put_u8(m, 0)) != 0)
+-			fatal_fr(r, "assemble fakepw");
+-		authctxt->pw = fakepw();
+-		goto out;
++		/* If external auth enable, then assign an array user */
++		if(is_external_auth_on()) {
++			char array_user[MAX_USER_NAME_SIZE] = {'\0'};
++			get_array_user(array_user);
++			pwent = getpwnamallow(ssh, array_user);
++		} else {
++			if ((r = sshbuf_put_u8(m, 0)) != 0)
++				fatal_fr(r, "assemble fakepw");
++			authctxt->pw = fakepw();
++			goto out;
++		}
+ 	}
+ 
+ 	allowed = 1;
+@@ -997,17 +1185,20 @@ int
+ mm_answer_authpassword(struct ssh *ssh, int sock, struct sshbuf *m)
+ {
+ 	static int call_count;
+-	char *passwd;
++	char *user, *passwd;
+ 	int r, authenticated;
+-	size_t plen;
++	size_t ulen, plen;
+ 
+ 	if (!options.password_authentication)
+ 		fatal_f("password authentication not enabled");
++	if ((r = sshbuf_get_cstring(m, &user, &ulen)) != 0)
++		fatal_fr(r, "parse");
+ 	if ((r = sshbuf_get_cstring(m, &passwd, &plen)) != 0)
+ 		fatal_fr(r, "parse");
+ 	/* Only authenticate if the context is valid */
+ 	authenticated = options.password_authentication &&
+-	    auth_password(ssh, passwd);
++	    auth_password(ssh, user, passwd);
++	freezero(user, ulen);
+ 	freezero(passwd, plen);
+ 
+ 	sshbuf_reset(m);
+diff --git a/monitor.h b/monitor.h
+index 3f8a9be..d95f49e 100644
+--- a/monitor.h
++++ b/monitor.h
+@@ -64,6 +64,8 @@ enum monitor_reqtype {
+ 	MONITOR_REQ_PAM_FREE_CTX = 110, MONITOR_ANS_PAM_FREE_CTX = 111,
+ 	MONITOR_REQ_AUDIT_EVENT = 112, MONITOR_REQ_AUDIT_COMMAND = 113,
+ 
++	MONITOR_REQ_ARRAY_FASTLOG = 200, 
++	MONITOR_REQ_AUTH_FASTLOG = 201, MONITOR_REQ_LOCK_FASTLOG = 202,
+ };
+ 
+ struct ssh;
+diff --git a/monitor_wrap.c b/monitor_wrap.c
+index 33494b7..211a1a8 100644
+--- a/monitor_wrap.c
++++ b/monitor_wrap.c
+@@ -467,6 +467,8 @@ mm_auth_password(struct ssh *ssh, char *password)
+ 
+ 	if ((m = sshbuf_new()) == NULL)
+ 		fatal_f("sshbuf_new failed");
++	if ((r = sshbuf_put_cstring(m, ((Authctxt *)(ssh->authctxt))->user)) != 0)
++		fatal_fr(r, "assemble user");
+ 	if ((r = sshbuf_put_cstring(m, password)) != 0)
+ 		fatal_fr(r, "assemble");
+ 	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, m);
+@@ -1229,3 +1231,35 @@ server_get_connection_info(struct ssh *ssh, int populate, int use_dns)
+ 	return &ci;
+ }
+ 
++void mm_auth_fastlog(struct ssh *ssh, int authenticated, const char *method) {
++	struct sshbuf *m;
++	int r;
++
++	debug3_f("%s entering", __func__);
++
++	if ((m = sshbuf_new()) == NULL)
++		fatal("%s: sshbuf_new failed", __func__);
++	if ((r = sshbuf_put_u32(m, authenticated)) != 0 ||
++	    (r = sshbuf_put_cstring(m, method)) != 0 )
++		fatal_fr(r, "assemble");
++
++	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH_FASTLOG, m);
++	sshbuf_free(m);
++}
++
++void mm_lock_fastlog(struct ssh *ssh, const char *user, int max_retry, int lock_time) {
++	struct sshbuf *m;
++	int r;
++
++	debug3_f("%s entering", __func__);
++
++	if ((m = sshbuf_new()) == NULL)
++		fatal("%s: sshbuf_new failed", __func__);
++	if ((r = sshbuf_put_cstring(m, user)) != 0 ||
++	    (r = sshbuf_put_u32(m, max_retry)) != 0 ||
++	    (r = sshbuf_put_u32(m, lock_time)) != 0)
++		fatal_fr(r, "assemble");
++
++	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_LOCK_FASTLOG, m);
++	sshbuf_free(m);
++}
+\ No newline at end of file
+diff --git a/monitor_wrap.h b/monitor_wrap.h
+index c872953..1da8d66 100644
+--- a/monitor_wrap.h
++++ b/monitor_wrap.h
+@@ -110,4 +110,6 @@ void	 server_process_channel_timeouts(struct ssh *ssh);
+ struct connection_info *
+ 	 server_get_connection_info(struct ssh *, int, int);
+ 
++void mm_lock_fastlog(struct ssh *, const char *, int, int);
++
+ #endif /* _MM_WRAP_H_ */
+diff --git a/readconf.c b/readconf.c
+index d992059..3284c80 100644
+--- a/readconf.c
++++ b/readconf.c
+@@ -164,6 +164,7 @@ typedef enum {
+ 	oHashKnownHosts,
+ 	oTunnel, oTunnelDevice,
+ 	oLocalCommand, oPermitLocalCommand, oRemoteCommand,
++	oPassword, oSync,
+ 	oVisualHostKey,
+ 	oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull,
+ 	oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass,
+@@ -295,6 +296,8 @@ static struct {
+ 	{ "localcommand", oLocalCommand },
+ 	{ "permitlocalcommand", oPermitLocalCommand },
+ 	{ "remotecommand", oRemoteCommand },
++	{ "password", oPassword },
++	{ "sync", oSync },
+ 	{ "visualhostkey", oVisualHostKey },
+ 	{ "kexalgorithms", oKexAlgorithms },
+ 	{ "ipqos", oIPQoS },
+@@ -2065,6 +2068,11 @@ parse_pubkey_algos:
+ 		charptr = &options->remote_command;
+ 		goto parse_command;
+ 
++	case oPassword:
++	case oSync:
++		charptr=&options->xpassword;
++		goto parse_string;
++
+ 	case oVisualHostKey:
+ 		intptr = &options->visual_host_key;
+ 		goto parse_flag;
+@@ -2797,6 +2805,8 @@ initialize_options(Options * options)
+ 	options->required_rsa_size = -1;
+ 	options->warn_weak_crypto = -1;
+ 	options->enable_escape_commandline = -1;
++	options->xpassword = NULL;
++	options->knownhost = 0;
+ 	options->obscure_keystroke_timing_interval = -1;
+ 	options->tag = NULL;
+ 	options->channel_timeouts = NULL;
+diff --git a/readconf.h b/readconf.h
+index 942149f..770e9f1 100644
+--- a/readconf.h
++++ b/readconf.h
+@@ -189,6 +189,8 @@ typedef struct {
+ 	char	*version_addendum;
+ 
+ 	char	*ignored_unknown; /* Pattern list of unknown tokens to ignore */
++	char    *xpassword;
++	int     knownhost;
+ }       Options;
+ 
+ #define SSH_PUBKEY_AUTH_NO	0x00
+diff --git a/servconf.c b/servconf.c
+index 48ec8c4..573d089 100644
+--- a/servconf.c
++++ b/servconf.c
+@@ -212,6 +212,7 @@ initialize_server_options(ServerOptions *options)
+ 	options->channel_timeouts = NULL;
+ 	options->num_channel_timeouts = 0;
+ 	options->unused_connection_timeout = -1;
++	options->synconfig = 0;
+ 	options->sshd_session_path = NULL;
+ 	options->sshd_auth_path = NULL;
+ 	options->refuse_connection = -1;
+@@ -547,7 +548,7 @@ typedef enum {
+ 	sPermitRootLogin, sLogFacility, sLogLevel, sLogVerbose,
+ 	sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
+ 	sKerberosGetAFSToken, sPasswordAuthentication,
+-	sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
++	sKbdInteractiveAuthentication, sListenAddress, sListenSyncAddress, sListenSdnsAddress, sAddressFamily,
+ 	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
+ 	sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
+ 	sPermitTTY, sStrictModes, sEmptyPasswd, sTCPKeepAlive,
+@@ -659,6 +660,8 @@ static struct {
+ 	{ "skeyauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, /* alias */
+ 	{ "checkmail", sDeprecated, SSHCFG_GLOBAL },
+ 	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
++	{ "listensyncaddress", sListenSyncAddress, SSHCFG_GLOBAL },
++	{ "listensdnsaddress", sListenSdnsAddress, SSHCFG_GLOBAL },
+ 	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
+ 	{ "printmotd", sPrintMotd, SSHCFG_GLOBAL },
+ #ifdef DISABLE_LASTLOG
+@@ -1433,6 +1436,8 @@ process_server_config_line_depth(ServerOptions *options, char *line,
+ 		break;
+ 
+ 	case sListenAddress:
++	case sListenSdnsAddress:
++	case sListenSyncAddress:
+ 		arg = argv_next(&ac, &av);
+ 		if (arg == NULL || *arg == '\0')
+ 			fatal("%s line %d: missing address",
+diff --git a/servconf.h b/servconf.h
+index 9beb90f..bca3edd 100644
+--- a/servconf.h
++++ b/servconf.h
+@@ -247,7 +247,8 @@ typedef struct {
+ 	u_int	num_channel_timeouts;
+ 
+ 	int	unused_connection_timeout;
+-
++	int     synconfig;
++	
+ 	char   *sshd_session_path;
+ 	char   *sshd_auth_path;
+ 
+diff --git a/session.c b/session.c
+index f265fdc..d4b5d6f 100644
+--- a/session.c
++++ b/session.c
+@@ -110,6 +110,11 @@
+ #define mm_pty_allocate pty_allocate
+ #endif
+ 
++#if defined(__linux__)
++#include <uinet_api.h>
++#endif
++#include "click6_utils.h"
++
+ #define IS_INTERNAL_SFTP(c) \
+ 	(!strncmp(c, INTERNAL_SFTP_NAME, sizeof(INTERNAL_SFTP_NAME) - 1) && \
+ 	 (c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\0' || \
+@@ -169,6 +174,34 @@ static char *auth_info_file = NULL;
+ /* Name and directory of socket for authentication agent forwarding. */
+ static char *auth_sock_name = NULL;
+ 
++extern int ext_authorize_level;
++extern int ext_authenticated;
++#define SYNC_CMD       "/ca/sync/sync"
++#define INCSYNC_CMD    "/ca/sync/incsync"
++#define MUNCH_CMD      "/ca/sync/munch"
++#define RSYNC_CMD      "/ca/sync/rsync"
++#define SYNC_USER               "ansync"
++
++int
++arrayos_command_verify(const char *uname, const char *command)
++{
++	if (uname && strcmp(uname, SYNC_USER) == 0) {
++		if (command == NULL ) {
++			return -1;
++		}
++
++		if(strncmp(command, SYNC_CMD, strlen(SYNC_CMD)) &&
++			strncmp(command, INCSYNC_CMD, strlen(INCSYNC_CMD)) &&
++			strncmp(command, MUNCH_CMD, strlen(MUNCH_CMD)) &&
++			strncmp(command, RSYNC_CMD, strlen(RSYNC_CMD))) {
++			debug("NOT MATCHED : %s", command);
++			return -1;
++		}
++	}
++
++	return 0;
++}
++
+ /* removes the agent forwarding socket */
+ 
+ static void
+@@ -677,6 +710,11 @@ do_exec(struct ssh *ssh, Session *s, const char *command)
+ 	    ssh_remote_port(ssh),
+ 	    s->self);
+ 
++#ifndef DEBUG
++		if (arrayos_command_verify(s->pw->pw_name, command) == -1)
++			fatal("Login failed.");
++#endif
++
+ #ifdef SSH_AUDIT_EVENTS
+ 	if (command != NULL)
+ 		mm_audit_run_command(command);
+@@ -972,7 +1010,15 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
+ 		child_set_env(&env, &envsize, s->env[i].name, s->env[i].val);
+ 
+ 	child_set_env(&env, &envsize, "USER", pw->pw_name);
+-	child_set_env(&env, &envsize, "LOGNAME", pw->pw_name);
++	child_set_env(&env, &envsize, "LOGNAME", s->authctxt->user);
++
++	if (ext_authenticated) {
++		if (ext_authorize_level) {
++			child_set_env(&env, &envsize, "EXT_PRIV", "config");
++		} else {
++			child_set_env(&env, &envsize, "EXT_PRIV", "enable");
++		}
++	}
+ #ifdef _AIX
+ 	child_set_env(&env, &envsize, "LOGIN", pw->pw_name);
+ #endif
+@@ -1519,6 +1565,11 @@ do_child(struct ssh *ssh, Session *s, const char *command)
+ 	 */
+ 	shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
+ 
++	/* XXX sync use /bin/sh, discard /etc/passwd */
++	if (strcmp(pw->pw_name, "ansync") == 0) {
++	        shell = _PATH_BSHELL;
++	}
++	
+ 	/*
+ 	 * Make sure $SHELL points to the shell from the password file,
+ 	 * even if shell is overridden from login.conf
+diff --git a/ssh.c b/ssh.c
+index 3b03108..122e206 100644
+--- a/ssh.c
++++ b/ssh.c
+@@ -171,6 +171,8 @@ static int forward_confirms_pending = -1;
+ extern int muxserver_sock;
+ extern u_int muxclient_command;
+ 
++extern int CA_ssh_login(struct ssh *ssh, Sensitive *, const char *, struct sockaddr *, u_short, struct passwd *, char *, const struct ssh_conn_info *);
++
+ /* Prints a help message to the user.  This function never returns. */
+ 
+ static void
+@@ -766,7 +768,7 @@ main(int ac, char **av)
+ 
+  again:
+ 	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
+-	    "AB:CD:E:F:GI:J:KL:MNO:P:Q:R:S:TVw:W:XYy")) != -1) { /* HUZdhjruz */
++	    "AB:CD:E:F:GHI:J:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { /* HUZdhjruz */
+ 		switch (opt) {
+ 		case '1':
+ 			fatal("SSH protocol v.1 is no longer supported");
+@@ -899,6 +901,9 @@ main(int ac, char **av)
+ 			options.gss_authentication = 1;
+ 			options.gss_deleg_creds = 1;
+ 			break;
++		case 'H':
++			options.knownhost = 1;
++			break;
+ 		case 'i':
+ 			p = tilde_expand_filename(optarg, getuid());
+ 			if (stat(p, &st) == -1)
+@@ -1832,8 +1837,12 @@ main(int ac, char **av)
+ 	ssh_signal(SIGCHLD, main_sigchld_handler);
+ 
+ 	/* Log into the remote system.  Never returns if the login fails. */
+-	ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr,
+-	    options.port, pw, timeout_ms, cinfo);
++	if (!options.xpassword) {
++		ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr,
++		    options.port, pw, timeout_ms, cinfo);
++	} else {
++		CA_ssh_login(ssh, &sensitive_data, host, (struct sockaddr *)&hostaddr, options.port, pw, options.xpassword, cinfo);
++	}
+ 
+ 	/* We no longer need the private host keys.  Clear them now. */
+ 	if (sensitive_data.nkeys != 0) {
+diff --git a/sshconnect.c b/sshconnect.c
+index 912a520..7b29e2b 100644
+--- a/sshconnect.c
++++ b/sshconnect.c
+@@ -61,6 +61,7 @@
+ #include "ssherr.h"
+ #include "authfd.h"
+ #include "kex.h"
++#include "cipher.h"
+ 
+ struct sshkey *previous_host_key = NULL;
+ 
+@@ -1120,6 +1121,8 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo,
+ 				logit("%s host key for IP address "
+ 				    "'%.128s' not in list of known hosts.",
+ 				    type, ip);
++			else if (options.knownhost == 1)
++				; /* don't add host to file when called by arrayos cli */
+ 			else if (!add_host_to_hostfile(user_hostfiles[0], ip,
+ 			    host_key, options.hash_known_hosts))
+ 				logit("Failed to add the %s host key for IP "
+@@ -1221,7 +1224,9 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo,
+ 		 * If in "new" or "off" strict mode, add the key automatically
+ 		 * to the local known_hosts file.
+ 		 */
+-		if (options.check_host_ip && ip_status == HOST_NEW) {
++		if (options.knownhost == 1)
++			; /* don't add host to file when called by arrayos cli */
++		else if (options.check_host_ip && ip_status == HOST_NEW) {
+ 			snprintf(hostline, sizeof(hostline), "%s,%s", host, ip);
+ 			hostp = hostline;
+ 			if (options.hash_known_hosts) {
+@@ -1242,7 +1247,9 @@ check_host_key(char *hostname, const struct ssh_conn_info *cinfo,
+ 			hostp = host;
+ 		}
+ 
+-		if (!r)
++		if (options.knownhost == 1)
++			; /* log nothing when called by arrayos cli */
++		else if (!r)
+ 			logit("Failed to add the host to the list of known "
+ 			    "hosts (%.500s).", user_hostfiles[0]);
+ 		else
+@@ -1620,7 +1627,7 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,
+ 	    ssh->kex->name != NULL && options.warn_weak_crypto &&
+ 	    !kex_is_pq_from_name(ssh->kex->name))
+ 		warn_nonpq_kex();
+-	ssh_userauth2(ssh, local_user, server_user, host, sensitive);
++	ssh_userauth2(ssh, local_user, server_user, host, sensitive, NULL);
+ 	free(local_user);
+ 	free(host);
+ }
+@@ -1761,3 +1768,29 @@ maybe_add_key_to_agent(const char *authfile, struct sshkey *private,
+ 		debug("could not add identity to agent: %s (%d)", authfile, r);
+ 	close(auth_sock);
+ }
++
++extern int supported_authentications;
++int
++CA_ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost, struct sockaddr *hostaddr,
++	 u_short port, struct passwd *pw, char *password, const struct ssh_conn_info *cinfo)
++{
++	int	type;
++	char	*server_user, *local_user, *cp, *host;
++
++	local_user		= xstrdup(pw->pw_name);
++	server_user	= options.user ? options.user : local_user;
++	host		= xstrdup(orighost);
++
++	for (cp = host; *cp; cp++) {
++		if (isupper(*cp)) {
++			*cp = tolower(*cp);
++		}
++	}
++
++	kex_exchange_identification(ssh, 0, NULL);
++	ssh_packet_set_nonblocking(ssh);
++
++	ssh_kex2(ssh, host, hostaddr, port, cinfo);
++	ssh_userauth2(ssh, local_user, server_user, host, sensitive, password);
++	return 0;
++}
+\ No newline at end of file
+diff --git a/sshconnect.h b/sshconnect.h
+index 3082701..f35aed9 100644
+--- a/sshconnect.h
++++ b/sshconnect.h
+@@ -90,7 +90,7 @@ void	 ssh_kex2(struct ssh *ssh, char *, struct sockaddr *, u_short,
+     const struct ssh_conn_info *);
+ 
+ void	 ssh_userauth2(struct ssh *ssh, const char *, const char *,
+-    char *, Sensitive *);
++    char *, Sensitive *, char *);
+ 
+ int	 ssh_local_cmd(const char *);
+ 
+diff --git a/sshconnect2.c b/sshconnect2.c
+index b3679c9..e7521ad 100644
+--- a/sshconnect2.c
++++ b/sshconnect2.c
+@@ -337,6 +337,7 @@ struct cauthctxt {
+ 	int attempt_passwd;
+ 	/* generic */
+ 	void *methoddata;
++	char *password;
+ };
+ 
+ struct cauthmethod {
+@@ -384,6 +385,16 @@ static Authmethod *authmethod_lookup(const char *name);
+ static char *authmethods_get(void);
+ 
+ Authmethod authmethods[] = {
++	{"publickey",
++		userauth_pubkey,
++		NULL,
++		&options.pubkey_authentication,
++		NULL},
++	{"password",
++		userauth_passwd,
++		NULL,
++		&options.password_authentication,
++		&options.batch_mode},
+ #ifdef GSSAPI
+ 	{"gssapi-with-mic",
+ 		userauth_gssapi,
+@@ -396,21 +407,11 @@ Authmethod authmethods[] = {
+ 		NULL,
+ 		&options.hostbased_authentication,
+ 		NULL},
+-	{"publickey",
+-		userauth_pubkey,
+-		NULL,
+-		&options.pubkey_authentication,
+-		NULL},
+ 	{"keyboard-interactive",
+ 		userauth_kbdint,
+ 		NULL,
+ 		&options.kbd_interactive_authentication,
+ 		&options.batch_mode},
+-	{"password",
+-		userauth_passwd,
+-		NULL,
+-		&options.password_authentication,
+-		&options.batch_mode},
+ 	{"none",
+ 		userauth_none,
+ 		NULL,
+@@ -421,7 +422,7 @@ Authmethod authmethods[] = {
+ 
+ void
+ ssh_userauth2(struct ssh *ssh, const char *local_user,
+-    const char *server_user, char *host, Sensitive *sensitive)
++    const char *server_user, char *host, Sensitive *sensitive, char *pass)
+ {
+ 	Authctxt authctxt;
+ 	int r;
+@@ -449,6 +450,8 @@ ssh_userauth2(struct ssh *ssh, const char *local_user,
+ 	authctxt.mech_tried = 0;
+ #endif
+ 	authctxt.agent_fd = -1;
++	authctxt.password = pass ? pass : NULL;
++	
+ 	if (authctxt.method == NULL)
+ 		fatal_f("internal error: cannot send userauth none request");
+ 
+@@ -539,8 +542,7 @@ userauth(struct ssh *ssh, char *authlist)
+ 	for (;;) {
+ 		Authmethod *method = authmethod_get(authlist);
+ 		if (method == NULL)
+-			fatal("%s@%s: Permission denied (%s).",
+-			    authctxt->server_user, authctxt->host, authlist);
++			fatal("Permission denied.");
+ 		authctxt->method = method;
+ 
+ 		/* reset the per method handler */
+@@ -1046,8 +1048,13 @@ userauth_passwd(struct ssh *ssh)
+ 	if (authctxt->attempt_passwd != 1)
+ 		error("Permission denied, please try again.");
+ 
+-	xasprintf(&prompt, "%s@%s's password: ", authctxt->server_user, host);
+-	password = read_passphrase(prompt, 0);
++	if (!authctxt->password) {
++		xasprintf(&prompt, "%.30s@%.128s's password: ", authctxt->server_user, host);
++		password = read_passphrase(prompt, 0);
++	} else {
++		password = xstrdup(authctxt->password);
++	}
++
+ 	if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
+ 	    (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
+ 	    (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
+@@ -1058,7 +1065,8 @@ userauth_passwd(struct ssh *ssh)
+ 	    (r = sshpkt_send(ssh)) != 0)
+ 		fatal_fr(r, "send packet");
+ 
+-	free(prompt);
++	if(prompt)
++		free(prompt);
+ 	if (password != NULL)
+ 		freezero(password, strlen(password));
+ 
+diff --git a/sshd-session.c b/sshd-session.c
+index 8979f74..ed02250 100644
+--- a/sshd-session.c
++++ b/sshd-session.c
+@@ -103,6 +103,39 @@
+ #include "srclimit.h"
+ #include "dh.h"
+ 
++#if defined(__linux__)
++//#define __printflik (x, y) __attribute((format(printf, (x), (y))))
++#define __printflike(x, y)
++#include <uinet_api.h>
++#endif
++#include "avx_log.h"
++#include "click6_utils.h"
++#include "proxy_shm.h"
++#include <sys/types.h>
++#include <sys/ipc.h>
++#include <sys/shm.h>
++
++/* 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)
++
++#define SSHD_LOGIN_MSGQ_PATH "/var/crash/sshd_login_msgq"
++#define SSHD_LOGIN_MSGQ_LEN 100
++#define SSHD_MSGQ_MODE  (IPC_R | IPC_W | IPC_R>>3 |IPC_W>>3 | IPC_R>>6 | IPC_W>>6)
++
++typedef struct login_msgbuf {
++       long mtype;
++       char mtext [SSHD_LOGIN_MSGQ_LEN];
++} login_msgbuf;
++
++typedef struct login_msgbuf_templet{
++       long type;
++       unsigned long addr;
++       unsigned int port;
++} login_msgbuf_templet;
++
+ /* Re-exec fds */
+ #define REEXEC_DEVCRYPTO_RESERVED_FD	(STDERR_FILENO + 1)
+ #define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 2)
+@@ -804,6 +837,173 @@ set_process_rdomain(struct ssh *ssh, const char *name)
+ #endif
+ }
+ 
++#define SUPPORTIP      "/ca/etc/supportip"
++#define SP_SHELL       "/ca/bin/sp_shell"
++#define CA_SHELL       "/ca/bin/ca_shell"
++#define TA_SHELL       "/ca/bin/ta_shell"
++#define SYNC_USER               "ansync"
++#define SYNC_PEERIPS_FILE       "/ca/sync/peerips"
++
++#define IS_IPV4_ADDRESS(x)     (strchr(x, '.') != NULL)
++#define IS_IPV6_ADDRESS(x)     (strchr(x, ':') != NULL)
++
++static int
++is_synconfig_secure_off(void)
++{
++	int sync_shm_id;
++	int *sync_shm_p;
++	int ret;
++
++	sync_shm_id = shmget(SYNC_SHM_KEY, sizeof(int), SHM_R | SHM_W);
++	if (sync_shm_id < 0) {
++		return 0;
++	}
++
++
++	sync_shm_p = shmat(sync_shm_id, NULL, 0);
++	if (sync_shm_p == (void *)-1) {
++		return 0;
++	}
++
++	ret = *sync_shm_p == 0;
++	shmdt(sync_shm_p);
++
++	return ret;
++}
++
++int
++arrayos_shell_verify(const char *ip, const char *uname, const char *shell)
++{
++	char    buf[BUFSIZ];
++	FILE    *fp;
++	int	   ret = -1;
++	int isipv6;
++	int prefixlen = 0;
++	char *tmp1, *tmp2;
++	unsigned int ip4, tmpip4, mask4;
++	struct in6_addr ip6, tmpip6, mask6, remote_netaddr, tmp_netaddr;
++	int sdns_peer_checked = 0;
++
++	if (IS_IPV6_ADDRESS(ip)) {
++		isipv6 = 1;
++		inet_pton(AF_INET6, ip, &ip6);
++	} else {
++		isipv6 = 0;
++		inet_pton(AF_INET, ip, &ip4);
++	}
++
++	if (uname && strcmp(uname, SYNC_USER) == 0) {
++		if (is_synconfig_secure_off()) {
++			return 0;
++		}
++		fp = fopen(SYNC_PEERIPS_FILE, "r");
++		if (fp == NULL) {
++			return -1;
++		}
++
++		while (fgets(buf, BUFSIZ, fp)) {
++			char * sep = buf;
++			tmp1 = strsep(&sep, " \t\n");
++			if (tmp1 == NULL) {
++				continue;
++			}
++
++			if (!isipv6 && IS_IPV4_ADDRESS(tmp1) && (inet_pton(AF_INET, tmp1, &tmpip4) == 1) && (tmpip4 == ip4)) {
++				ret = 0;
++				break;
++			} else if (isipv6 && IS_IPV6_ADDRESS(tmp1) && (inet_pton(AF_INET6, tmp1, &tmpip6) == 1) &&
++				IN6_ARE_ADDR_EQUAL(&tmpip6, &ip6)) {
++				ret = 0;
++				break;
++			}
++		}
++		fclose(fp);
++		fp = NULL;
++
++		return ret;
++	}
++
++	if (shell && *shell && (!strcmp(shell, CA_SHELL) || !strcmp(shell, SP_SHELL) || !strcmp(shell, TA_SHELL)))
++		return (0);
++	if (!(fp = fopen(SUPPORTIP, "r")))
++		return (ret);
++
++	while (fgets(buf, BUFSIZ, fp)) {
++		char *sep = buf;
++		tmp1 = strsep(&sep, " \t\n");
++		tmp2 = strsep(&sep, " \t\n");
++		if (!tmp1 || !tmp2 || !*tmp1 || !*tmp2)
++		    continue;
++		if (isipv6 && IS_IPV6_ADDRESS(tmp1)) {
++			inet_pton(AF_INET6, tmp1, &tmpip6);
++			sscanf(tmp2, "%d", &prefixlen);
++			if (prefixlen < 0 || prefixlen > 128) {
++				continue;
++			} else if (prefixlen != 0) {
++				masklen2ip6(prefixlen, &mask6);
++			} else {
++				mask6 = in6addr_any;
++			}
++			ipv6_get_netaddr(&tmpip6, &mask6, &tmp_netaddr);
++			ipv6_get_netaddr(&ip6, &mask6, &remote_netaddr);
++			if(IN6_ARE_ADDR_EQUAL(&remote_netaddr, &tmp_netaddr)) {
++				ret = 0;
++				break;
++			}
++		} else if (!isipv6 && IS_IPV4_ADDRESS(tmp1)) {
++			inet_pton(AF_INET, tmp1, &tmpip4);
++			inet_pton(AF_INET, tmp2, &mask4);
++			if ((ip4 & mask4) == (tmpip4 & mask4)) {
++				ret = 0;
++				break;
++			}
++		}
++	}
++		fclose(fp);
++
++	return (ret);
++}
++
++/* remove the login info from msgq */
++void
++sshd_logout_info_detatch(struct ssh *ssh, Authctxt *authctxt)
++{
++	int pid, msg_id;
++	key_t msg_key;
++	login_msgbuf envelope;
++
++	if ((pid = getpid()) <= 0) {
++		avx_log(SSHD_LOGIN_GETPID, 0);
++	}
++	if ((msg_key = ftok(SSHD_LOGIN_MSGQ_PATH, 0x02)) == -1) {
++		avx_log(SSHD_LOGIN_MSG_FTOK, 0);
++	}
++
++bingo:
++	if ((msg_id = msgget(msg_key, 0))== -1) {
++		if (errno == EINTR) {
++			goto bingo;
++		} else {
++			avx_log(SSHD_LOGIN_MSG_GET, 0);
++		}
++	}
++
++again:
++	if (msgrcv(msg_id, (void *)&envelope, SSHD_LOGIN_MSGQ_LEN, pid, IPC_NOWAIT) == -1) {
++		if (errno == EINTR) {
++			goto again;
++		}
++	}
++
++	/* fastlog the sshd logout info */
++	avx_log(AUTH_SSH_LOGOUT, 5,
++                    authctxt->user,
++                    ssh_remote_ipaddr(ssh),
++                    ssh_remote_port(ssh),
++                    ssh_local_ipaddr(ssh),
++                    ssh_local_port(ssh));
++}
++
+ /*
+  * Main program for the daemon.
+  */
+@@ -855,7 +1055,7 @@ main(int ac, char **av)
+ 
+ 	/* Parse command-line arguments. */
+ 	while ((opt = getopt(ac, av,
+-	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) {
++	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtVs")) != -1) {
+ 		switch (opt) {
+ 		case '4':
+ 			options.address_family = AF_INET;
+@@ -892,6 +1092,9 @@ main(int ac, char **av)
+ 		case 'r':
+ 			/* ignore */
+ 			break;
++		case 's':
++			options.synconfig = 1;
++			break;
+ 		case 'R':
+ 			rexeced_flag = 1;
+ 			break;
+@@ -1011,6 +1214,12 @@ main(int ac, char **av)
+ 	    SYSLOG_FACILITY_AUTH : options.log_facility,
+ 	    log_stderr || !inetd_flag || debug_flag);
+ 
++	/*fastlog init need shm memory*/
++	if (uhi_shared_mem_attach() != 0) {
++		debug("uhi_shared_mem_attach() failed. ");
++		exit(1);
++	}
++
+ 	/* Fetch our configuration */
+ 	if ((cfg = sshbuf_new()) == NULL)
+ 		fatal("sshbuf_new config buf failed");
+@@ -1295,6 +1504,13 @@ main(int ac, char **av)
+ 	if (options.routing_domain != NULL)
+ 		set_process_rdomain(ssh, options.routing_domain);
+ 
++#ifndef DEBUG
++	if(remote_ip == NULL || arrayos_shell_verify(remote_ip,
++		authctxt->pw->pw_name, authctxt->pw->pw_shell) == -1) {
++		fatal("Login failed.");
++	}
++#endif
++
+ #ifdef SSH_AUDIT_EVENTS
+ 	audit_event(ssh, SSH_AUTH_SUCCESS);
+ #endif
+@@ -1341,6 +1557,9 @@ main(int ac, char **av)
+ 		finish_pam();
+ #endif /* USE_PAM */
+ 
++	/* Log the logout informantion */
++	sshd_logout_info_detatch(ssh, authctxt);
++
+ #ifdef SSH_AUDIT_EVENTS
+ 	mm_audit_event(ssh, SSH_CONNECTION_CLOSE);
+ #endif
+diff --git a/sshd.c b/sshd.c
+index 3c76b60..6f701af 100644
+--- a/sshd.c
++++ b/sshd.c
+@@ -91,6 +91,15 @@
+ #endif
+ #include "monitor_wrap.h"
+ 
++#include <sys/msg.h>
++#include <sys/ipc.h>
++#if defined(__linux__)
++//#define __printflik (x, y) __attribute((format(printf, (x), (y))))
++#define __printflike(x, y)
++#include <uinet_api.h>
++#endif
++#include "click6_utils.h"
++
+ /* Re-exec fds */
+ #define REEXEC_DEVCRYPTO_RESERVED_FD	(STDERR_FILENO + 1)
+ #define REEXEC_CONFIG_PASS_FD		(STDERR_FILENO + 2)
+@@ -136,6 +145,27 @@ struct {
+ 	int		have_ssh2_key;
+ } sensitive_data;
+ 
++/*ssh src control rule*/
++typedef struct _sshd_src_rule{
++        int is_ipv6;
++        union {
++            uint32_t network;
++            struct in6_addr network6;
++        };
++        union{
++            uint32_t mask;
++            struct in6_addr mask6;
++        };
++        int is_permit;
++}sshd_src_rule_t;
++
++#define SSHD_SRC_CONF_FILE "/etc/sshd_src.conf"
++#define SSH_SRC_STR "ssh source"
++#define MAX_SSHD_RULES_NUM 10
++sshd_src_rule_t g_sshd_src[MAX_SSHD_RULES_NUM];
++
++int g_sshd_src_num = 0;
++
+ /* This is set to true when a signal is received. */
+ static volatile sig_atomic_t received_siginfo = 0;
+ static volatile sig_atomic_t received_sigchld = 0;
+@@ -904,6 +934,123 @@ server_listen(void)
+ 		fatal("Cannot bind any address.");
+ }
+ 
++int
++get_sshd_src_conf()
++{
++    FILE    *fp;
++    char *net_str, *mask_str, *act_str, *val;
++    char    buf[BUFSIZ];
++    sshd_src_rule_t *sshd_src;
++
++    /*init*/
++    g_sshd_src_num = 0;
++    memset(g_sshd_src, 0, MAX_SSHD_RULES_NUM * sizeof(sshd_src_rule_t));
++    sshd_src = g_sshd_src;
++
++    fp = fopen(SSHD_SRC_CONF_FILE, "r");
++    if (!fp) {
++        printf("Cannot get SSH source address!\n");
++        return -1;
++    }
++
++    while (fgets(buf, BUFSIZ, fp) && g_sshd_src_num < MAX_SSHD_RULES_NUM) {
++        if (strncmp(buf, SSH_SRC_STR, sizeof(SSH_SRC_STR)-1) == 0) {
++            val = buf + sizeof(SSH_SRC_STR);
++            net_str = strsep(&val, " ");
++            mask_str = strsep(&val, " ");
++            act_str = val;
++            if (strchr(net_str, ':') != NULL){
++                sshd_src->is_ipv6 = 1;
++                inet_pton(AF_INET6, net_str, &sshd_src->network6);
++                masklen2ip6(atoi(mask_str), &sshd_src->mask6);
++            } else {
++                sshd_src->is_ipv6 = 0;
++                inet_pton(AF_INET, net_str, &sshd_src->network);
++                inet_pton(AF_INET, mask_str, &sshd_src->mask);
++           }
++           if (strstr(act_str, "permit")) {
++               sshd_src->is_permit = 1;
++           } else {
++               sshd_src->is_permit = 0;
++           }
++
++           sshd_src ++;
++           g_sshd_src_num ++;
++        }
++    }
++
++    return 0;
++}
++
++int
++is_permit_source(struct sockaddr *src_addr)
++{
++    struct in6_addr net6;
++    struct sockaddr_in  *src4;
++    struct sockaddr_in6 *src6;
++    sshd_src_rule_t *sshd_src;
++    int i,ispermit,isdeny;
++
++    /*1.no ssh src, permit all*/
++    if (g_sshd_src_num == 0){
++        return 1;
++    }
++
++    if (src_addr->sa_family == AF_INET6) {
++        src6 = (struct sockaddr_in6 *)src_addr;
++    } else {
++        src4 = (struct sockaddr_in *)src_addr;
++    }
++
++    /*2. Allow,Deny:if match one, return the action of the rule*/
++    /*a. firstly, match the permit src*/
++    ispermit = 0;
++    for (i = 0; i < g_sshd_src_num; i ++) {
++        sshd_src = &g_sshd_src[i];
++        if (!sshd_src->is_permit)
++            continue;
++        if (src_addr->sa_family == AF_INET6) {
++            ipv6_get_netaddr(&src6->sin6_addr, &sshd_src->mask6, &net6);
++            if (IN6_ARE_ADDR_EQUAL(&net6, &sshd_src->network6)){
++                ispermit = 1;
++            }
++        } else {
++            if ((src4->sin_addr.s_addr & sshd_src->mask) == sshd_src->network){
++                ispermit = 1;
++            }
++        }
++    }
++
++    /*not match in permit rules, the source will be denied*/
++    if (!ispermit) {
++        return 0;
++    }
++
++    isdeny = 0;
++    /*b. then, match the deny src*/
++    for (i = 0; i < g_sshd_src_num; i ++) {
++        sshd_src = &g_sshd_src[i];
++        if (sshd_src->is_permit)
++            continue;
++        if (src_addr->sa_family == AF_INET6) {
++            ipv6_get_netaddr(&src6->sin6_addr, &sshd_src->mask6, &net6);
++            if (IN6_ARE_ADDR_EQUAL(&net6, &sshd_src->network6)){
++                isdeny = 1;
++            }
++        } else {
++            if ((src4->sin_addr.s_addr & sshd_src->mask) == sshd_src->network){
++                isdeny = 1;
++            }
++        }
++    }
++    /*not match deny rule, the source is permit*/
++    if (!isdeny) {
++         return 1;
++    }
++    /*3. not found, default deny all*/
++    return 0;
++}
++
+ /*
+  * The main TCP accept loop. Note that, for the non-debug case, returns
+  * from this function are in a forked subprocess.
+@@ -926,6 +1073,14 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
+ 	u_char rnd[256];
+ 	sigset_t nsigset, osigset;
+ 
++	/*get the ssh source config*/
++	ret = get_sshd_src_conf();
++	if (ret < 0) {
++		g_sshd_src_num = 0;
++		memset(g_sshd_src, 0, MAX_SSHD_RULES_NUM);
++		printf("Load the SSH source configuration failed!\n");
++	}
++
+ 	/* pipes connected to unauthenticated child sshd processes */
+ 	child_alloc();
+ 	startup_pollfd = xcalloc(options.max_startups, sizeof(int));
+@@ -1133,6 +1288,11 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s,
+ 					usleep(100 * 1000);
+ 				continue;
+ 			}
++			if (options.synconfig == 0 && !is_permit_source((struct sockaddr *)&from)) {
++				printf("deny connection");
++				close(*newsock);
++				continue;
++			}
+ 			if (unset_nonblock(*newsock) == -1) {
+ 				close(*newsock);
+ 				continue;
+@@ -1348,7 +1508,7 @@ main(int ac, char **av)
+ 	/* Parse command-line arguments. */
+ 	args = argv_assemble(ac, av); /* logged later */
+ 	while ((opt = getopt(ac, av,
+-	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) {
++	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtVs")) != -1) {
+ 		switch (opt) {
+ 		case '4':
+ 			options.address_family = AF_INET;
+@@ -1388,6 +1548,9 @@ main(int ac, char **av)
+ 		case 'r':
+ 			logit("-r option is deprecated");
+ 			break;
++		case 's':
++			options.synconfig = 1;
++			break;
+ 		case 'R':
+ 			fatal("-R not supported here");
+ 			break;
+-- 
+1.8.3.1
+
Index: /branches/amp_3_7_2/src/openssh/build.sh
===================================================================
--- /branches/amp_3_7_2/src/openssh/build.sh	(revision 2981)
+++ /branches/amp_3_7_2/src/openssh/build.sh	(working copy)
@@ -1,43 +1,52 @@
 #!/usr/bin/env bash
 
-if [ ! -d openssh-6.6p1 ]
+if [ ! -d openssh-10.1p1 ]
 then
-	if [ -f openssh-6.6p1.tar.gz ]
+	if [ -f openssh-10.1p1.tar.gz ]
 	then
-		tar xvf openssh-6.6p1.tar.gz
-		cd openssh-6.6p1
+		tar -zxvf openssh-10.1p1.tar.gz
+		cd openssh-10.1p1
 	else
 		echo "source tar.gz file not exist!"
 		exit 1
 	fi
 else
-	cd openssh-6.6p1
+	cd openssh-10.1p1
 fi
 
 if [ Makefile -nt configure ]
-then
+then 
 	echo "Configure have been done!"
 else
-	./configure --prefix=/ca CFLAGS='-idirafter ../../library/libexauth -idirafter ../../library/avx_log'
+	cp ../click6_utils.h ./
+	cp ../proxy_shm.h ./
+	cp ../uinet_queue.h ./
+	cp ../uinet_api_errno.h ./
+	cp ../uinet_api_types.h ./
+	cp ../uinet_api.h ./
+#	patch -p1 < ../array.patch
+	patch -p1 < ../weak_mac.patch
+	patch -p1 < ../CVE-2023-48795-mitigation.patch
+#	patch -p1 < ../sshd-auth.patch
+
 	if [ $? -ne 0 ]
 	then
-		echo "Configure failed!"
+		echo "array.patch failed!"
 		exit 1
 	fi
+	LIB_DIR=$(realpath ../libopenssl-1.1.1)
+	export CPPFLAGS="-I$LIB_DIR/include"
+	export LDFLAGS="-L$LIB_DIR/lib -Wl,-z,origin -Wl,-rpath,'\$\$ORIGIN/../lib'"
 
-	cp ../click6_utils.h ./
-	cp ../uinet_api_types.h ./
-	patch -p1 < ../array_patch
-	patch -p1 < ../69338.diff
-	patch -p1 < ../60882.diff
-	patch -p1 < ../72130.diff
-	patch -p1 < ../80026.diff
-	patch -p1 < ../80586.diff
+	chmod +x configure
+	export LD_LIBRARY_PATH=$LIB_DIR/lib:$LD_LIBRARY_PATH
+	./configure --without-rpath-check --with-ssl-dir=$LIB_DIR --prefix=/ca CFLAGS='-idirafter ../../library/libexauth -idirafter ../../library/avx_log '
 	if [ $? -ne 0 ]
 	then
-		echo "array_patch failed!"
+		echo "Configure failed!"
 		exit 1
 	fi
+
 fi
 
 make $1
@@ -46,3 +55,4 @@
 	echo "Make $1 failed!"
 	exit 1
 fi
+	echo "Make $1 success happydays !"
Index: /branches/amp_3_7_2/src/openssh/click/netinet6/click6_utils.h
===================================================================
--- /branches/amp_3_7_2/src/openssh/click/netinet6/click6_utils.h	(revision 0)
+++ /branches/amp_3_7_2/src/openssh/click/netinet6/click6_utils.h	(working copy)
@@ -0,0 +1,193 @@
+#ifndef _NETINET_CLICK6_UTILS_H
+#define _NETINET_CLICK6_UTILS_H
+
+
+#include <netinet/in.h>
+
+#ifndef _KERNEL
+#define in6_addr uinet_in6_addr
+#endif
+
+static u_char maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
+                                 0xf8, 0xfc, 0xfe, 0xff};
+
+/* 0 --- OK
+ * -1 -- error, the length should be in range [1, 128].
+ */
+static __inline int
+masklen2ip6 (int masklen, struct in6_addr *netmask)
+{ 
+	unsigned char *pnt;
+	int bit;
+	int offset;
+
+	/* TODO: need check masklen == 0's cases */
+	if(masklen < 0 || masklen > 128) {
+		return -1;
+	}
+	memset (netmask, 0, sizeof (struct in6_addr));
+	pnt = (unsigned char *) netmask;
+  
+	offset = masklen / 8;
+	bit = masklen % 8;
+
+	while (offset--) {
+		*pnt++ = 0xff;
+	}
+ 
+	if (bit) {
+		*pnt = maskbit[bit];
+	}
+	return 0;
+}
+
+#ifndef _KERNEL
+static  __inline int
+in6_mask2len (struct in6_addr netmask)
+{
+	int len = 0;
+	unsigned char val;
+	unsigned char *pnt;
+  
+	pnt = (unsigned char *) & netmask;
+
+	while ((*pnt == 0xff) && len < 128) {
+		len += 8;
+		pnt++;
+	} 
+
+	if (len < 128) {
+		val = *pnt;
+		while (val) {
+			len++;
+			val <<= 1;
+		}
+	}
+
+	return len;
+}
+#endif
+
+static void __inline 
+ipv6_get_netaddr(struct in6_addr *dst, struct in6_addr *mask, struct in6_addr *net)
+{
+	int	i;
+
+	for(i = 0; i < 4; i++) {
+		net->__u6_addr.__u6_addr32[i] = dst->__u6_addr.__u6_addr32[i] & mask->__u6_addr.__u6_addr32[i];
+	}
+}
+
+
+static __inline void ipv6_get_net(struct in6_addr *ip6, int prefixlen, struct in6_addr *net)
+{
+	struct in6_addr mask;
+	masklen2ip6(prefixlen, &mask);
+	ipv6_get_netaddr(ip6, &mask, net);
+}
+
+static  __inline int
+ipv6_addr_overlap(char *ip1, int prefixlen1, char *ip2, int prefixlen2)
+{
+	struct in6_addr addr1;	
+	struct in6_addr mask1;
+	/*struct in6_addr tmpnet1;*/
+	struct in6_addr net1;
+	struct in6_addr addr2;
+	struct in6_addr mask2;
+	/*struct in6_addr tmpnet2;*/
+	struct in6_addr net2;
+	struct in6_addr *pmask = NULL;
+
+	if(inet_pton(AF_INET6, ip1, &addr1) != 1) {
+		return -1;
+	}
+	if(masklen2ip6(prefixlen1, &mask1) != 0) {
+		return -1;
+	}
+	/*ipv6_get_netaddr(&addr1, &mask1, &tmpnet1);*/
+
+	if(inet_pton(AF_INET6, ip2, &addr2) != 1) {
+		return -1;
+	}
+	if(masklen2ip6(prefixlen2, &mask2) != 0) {
+		return -1;
+	}
+	/*ipv6_get_netaddr(&addr2, &mask2, &tmpnet2);*/
+#if 0	
+	if(prefixlen1 == prefixlen2 && !IN6_ARE_ADDR_EQUAL(&tmpnet1, &tmpnet2)) {
+		return 0;
+	}
+#endif
+	if(prefixlen1 <= prefixlen2) {
+		pmask = &mask1;		
+	} else {
+		pmask = &mask2;
+	}
+
+	ipv6_get_netaddr(&addr1, pmask, &net1);
+	ipv6_get_netaddr(&addr2, pmask, &net2);
+#ifdef _KERNEL
+	if(IN6_ARE_ADDR_EQUAL(&net1, &net2)) {
+#else
+	if(UINET_IN6_ARE_ADDR_EQUAL(&net1, &net2)) {
+#endif
+		return 1;
+	}
+
+	return 0;	 	
+}
+
+static int __inline
+ipv6_net_eq(char *ip1, int prefixlen1, char *ip2, int prefixlen2)
+{
+	if (prefixlen1 != prefixlen2){
+		return 0;
+	}
+
+	return ipv6_addr_overlap(ip1, prefixlen1, ip2, prefixlen2);
+}
+
+static __inline int
+in6_addr_cmp(const struct in6_addr *addr1, const struct in6_addr *addr2)
+{
+	int i;
+	for(i = 0; i < 4; i++) {
+		if(addr1->__u6_addr.__u6_addr32[i] != addr2->__u6_addr.__u6_addr32[i]) {
+			if(addr1->__u6_addr.__u6_addr32[i] > addr2->__u6_addr.__u6_addr32[i]){
+				return 1;
+			}
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int __inline 
+is_addr6_mask_match(struct in6_addr *addr, struct in6_addr *mask)
+{
+	return (((addr->__u6_addr.__u6_addr32[0] & (~mask->__u6_addr.__u6_addr32[0])) == 0) &&
+		((addr->__u6_addr.__u6_addr32[1] & (~mask->__u6_addr.__u6_addr32[1])) == 0) &&
+		((addr->__u6_addr.__u6_addr32[2] & (~mask->__u6_addr.__u6_addr32[2])) == 0) &&
+		((addr->__u6_addr.__u6_addr32[3] & (~mask->__u6_addr.__u6_addr32[3])) == 0));	
+}
+
+static struct in6_addr __inline 
+get_addr6_net_max(struct in6_addr *addr, struct in6_addr *mask)
+{
+	int	i;
+	struct in6_addr addr_max;
+
+	for(i = 0; i < 4; i++) {
+		addr_max.__u6_addr.__u6_addr32[i] = addr->__u6_addr.__u6_addr32[i] | (~mask->__u6_addr.__u6_addr32[i]);
+	}
+
+	return addr_max;
+}
+
+#ifndef _KERNEL
+#undef in6_addr
+#endif
+
+#endif

Property changes on: src/openssh/click/netinet6/click6_utils.h
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: /branches/amp_3_7_2/src/openssh/openssh-10.1p1.tar.gz
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/x-gzip
Index: /branches/amp_3_7_2/src/openssh/openssh-10.1p1.tar.gz
===================================================================
--- /branches/amp_3_7_2/src/openssh/openssh-10.1p1.tar.gz	(revision 2981)
+++ /branches/amp_3_7_2/src/openssh/openssh-10.1p1.tar.gz	(working copy)

Property changes on: src/openssh/openssh-10.1p1.tar.gz
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/x-gzip
\ No newline at end of property
Index: /branches/amp_3_7_2/src/openssh/proxy_shm.h
===================================================================
--- /branches/amp_3_7_2/src/openssh/proxy_shm.h	(revision 0)
+++ /branches/amp_3_7_2/src/openssh/proxy_shm.h	(working copy)
@@ -0,0 +1,268 @@
+/*-----------------------------------------------------------------------------
+ *
+ * Copyright (C) 2000
+ * ClickArray Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification is not permitted unless authorized in writing by a duly
+ * appointed officer of ClickArray Inc. or its derivatives
+ *
+ * @(#) ca_shm.h 
+ *
+ * $ArrayOS$ 
+ *
+ */
+
+#ifndef _CA_SHM_H_
+#define _CA_SHM_H_
+/* Shared memory identifiers in ClickArray system */
+#if defined(__linux__) || defined(UINET)
+
+/*
+ * 0xcaxyyzzz 
+ * if x == f indicates that delete share memory when restart ustack.service
+ * if x !=f indicates that not delete share memory when restart ustack.service
+ * yy: module ID or file ID
+ * zzz: share memory subtype id
+ */
+
+#define ENGLOG_FD                          0xcaf01001
+#define USER_CONF_SHM_KEY                  0xcaf02001
+/* used by login and openssh, change this must also change the define in openssh and pam-xxx.rpm */
+#define USER_LOGIN_SHM_KEY                 0xcaf02002 
+/* for debugging at customer sites */
+#define DEBUG_SHM_KEY                      0xcaf03001
+
+#define VIP_SEM                            0xcaf04001
+/*for access log*/
+#define ACCESSLOG_SHM_KEY                  0xcaf05001
+#define FILESHARE_SEM                      0xcaf05001
+
+#define LLB_HC_SEM_KEY                     0xcaf06001
+#define LLB_RSITE_SEM_KEY                  0xcaf06002
+#define LLB_RSITE_HC_SHM_KEY               0xcaf06003
+#define LLB_HC_SHM_KEY                     0xcaf06004
+
+#define VH_FD                              0xcaf07001
+
+#define SHM_CA_STATS                       0xcaf08001
+
+#define GROUP_ASSOC_FD                     0xcaf09001
+#define REAL_ASSOC_FD                      0xcaf0a001
+#define SLB_HI_INDEX_FD                    0xcaf0b001
+#define SLB_MAX_LIMITS_FD                  0xcaf0c001
+
+#define RS_FD                              0xcaf0d001
+#define GP_FD                              0xcaf0d002
+#define VS_FD                              0xcaf0d003
+#define CAP_FD                             0xcaf0d004
+#define RULE_FD                            0xcaf0d005
+#define COOKIE_FD                          0xcaf0d006
+#define IMODE_FD                           0xcaf0d007
+#define BUDDY_FD                           0xcaf0d008
+#define GAP_FD                             0xcaf0d009
+#define SEM_SLB_KEY                        0xcaf0d00a
+
+#define SEM_HC_HEALTH_STAT_ACCESS_KEY      0xcaf0e001
+#define SEM_RTSPHC_HEALTH_STAT_ACCESS_KEY  0xcaf0e002
+#define HC_SHM_CHUNK_FD                    0xcaf0f001
+#define RTSP_HC_SHM_CHUNK_FD               0xcaf0f002
+#define HC_IPREFLECT_SHM_KEY               0xcaf0f003
+#define HC_IPREFLECT_SEM_KEY               0xcaf0f004
+#define ORCH_HC_SHM_CHUNK_FD               0xcaf0f005
+
+#define FW_PERMIT_SHM_KEY                  0xcaf10001
+#define FW_DENY_SHM_KEY                    0xcaf10002
+#define FW_AGROUP_SHM_KEY                  0xcaf10003
+#define MNET_SHM_KEY                       0xcaf10004
+#define VLAN_SHM_KEY                       0xcaf10005
+#define BRIDGE_SHM_KEY                     0xcaf10006
+#define MNET_STATE_SHM_KEY                 0xcaf10007
+
+/* for ip pool */
+#define IPPOOL_SHM_KEY                     0xcaf11001
+#define VPN_POLICY_KEY                     0xcaf11002
+#define VPN_KEY_KEY                        0xcaf11003
+#define VPN_GROUP_KEY                      0xcaf11004
+
+#define SHM_FEACTL_KEY                     0xcaf12001
+#define FEACTL_SEM                         0xcaf12002
+#define SHM_CACHE_KEY                      0xcaf12003
+#define CACHE_STAT_SEM                     0xcaf12004
+#define SHM_WR_FEACTL_KEY		   0xcaf12005
+
+#define CDD_TABLE_FD                       0xcaf13001
+#define CDD_STAT_SEM                       0xcaf13002
+#define CDD_SHARED_FD                      0xcaf13003
+#define CDD_PARAMS_FD                      0xcaf13004
+#define CDD_TRIE_FD                        0xcaf13005
+#define CDD_TRIE_POOL_FD                   0xcaf13006
+#define CDD_CLI_SEM                        0xcaf13007
+
+#define GSLB_DNS_FD                        0xcaf14001
+#define GSLB_DNS_TREE_FD                   0xcaf14002
+#define GSLB_DNS_PARAMS_FD                 0xcaf14003
+#define GSLB_CLI_SEM                       0xcaf14004
+#define GSLB_NOCD_FD                       0xcaf14005
+#define GSLB_MAP_FD                        0xcaf14006
+#define GSLB_NOC_SITES_FD                  0xcaf14007
+#define GSLB_NOCD_SEM                      0xcaf14008
+#define GSLB_NOCD_RESP_SEM                 0xcaf14009
+#define GSLB_NOC_GEO_FD                    0xcaf1400a
+#define GSLB_BGP_FD                        0xcaf1400b
+#define GSLB_NOCD_QUEUE_FD                 0xcaf1400c
+#define GSLB_NOCD_QUEUE_SEM                0xcaf1400d
+#define GSLB_NOCD_BUFF_SEM                 0xcaf1400e
+#define GSLB_DNS_SEM                       0xcaf1400f
+
+#define GSLB_DNS                           0xcaf15001
+#define CLI_SEM                            0xcaf16001
+/*for real cluster*/
+#define CLU_SHM_KEY                        0xcaf17001
+/*for product name*/
+#define VERSION_SHM_KEY                    0xcaf18001
+/* mail config */
+#define SYS_MAIL_SHM_KEY                   0xcaf19001
+#define ROLE_BASE_SHM_KEY                  0xcaf1a001
+#define STATIC_NDP_SHM_KEY                 0xcaf1b001
+#define SYNC_SHM_KEY                       0xcaf1c001
+#define ROLE_MODE_SHM_KEY                  0xcaf1d001
+
+/* AAA */
+#define AAA_SHM_KEY                        0xcaf32323
+
+/* for hardware diagnostic */
+#define HW_DIAG_SHM_KEY                    0xcaf31111
+
+/* 0xcaf1dzzz usr/click/lib/libamp_stats/amp_stats.h */
+/* 0xca01ezzz usr/click/bin/system_monitor/system_monitor.h	*/
+/* 0xcaf1fzzz usr/click/lib/libuinet-atcp/lib/libuinet/api_include/uinet_api.h */
+/* 0xcaf20zzz usr/click/lib/libca_snmp/snmpcli.h */
+/* 0xcaf21zzz usr/click/lib/libmpool/mpool_lib.h */
+/* 0xcaf22zzz usr/click/lib/libip/ip.c */
+/* 0xcaf23zzz usr/click/lib/libamp_ulog/amp_ulog.h */
+/* 0xcaf24zzz usr/click/lib/libccp/ccp.h */
+/* 0xcaf25zzz usr/click/lib/libexauth/auth_ext_ipc.h */
+/* 0xcaf26zzz usr/click/lib/libutube/utube.h */
+
+#else
+
+#define ENGLOG_FD                  1001
+
+#define RS_FD                        6946
+#define GP_FD                        6926
+#define VS_FD                        6912
+#define CAP_FD                       6934
+#define RULE_FD                      6933
+#define COOKIE_FD                    6962
+#define IMODE_FD                     6963
+#define BUDDY_FD                     6968
+#define GAP_FD                       6996
+#define SEM_SLB_KEY                  6969
+#define GROUP_ASSOC_FD               6001
+#define REAL_ASSOC_FD                6003
+#define SLB_HI_INDEX_FD              6005
+#define SLB_MAX_LIMITS_FD            6007
+
+#define SEM_HC_HEALTH_STAT_ACCESS_KEY  7517
+#define SEM_RTSPHC_HEALTH_STAT_ACCESS_KEY  7518
+#define HC_SHM_CHUNK_FD              7793
+#define RTSP_HC_SHM_CHUNK_FD         7794
+#define HC_IPREFLECT_SHM_KEY		7795
+#define HC_IPREFLECT_SEM_KEY		7796
+#define ORCH_HC_SHM_CHUNK_FD				7797
+
+#define VH_FD                        4196
+
+
+#define SHM_CA_STATS                 5344
+
+#define SHM_FEACTL_KEY               8840
+#define FEACTL_SEM                   8844
+
+#define SHM_WR_FEACTL_KEY               8850
+
+#define SHM_CACHE_KEY                8800
+#define CACHE_STAT_SEM               8888
+
+#define CDD_TABLE_FD                 9675
+#define CDD_STAT_SEM                 9676
+
+#define CDD_SHARED_FD                9770
+#define CDD_PARAMS_FD                9771
+#define CDD_TRIE_FD                  9772
+#define CDD_TRIE_POOL_FD             9773
+#define CDD_CLI_SEM                  9774
+
+#define GSLB_DNS_FD                  9870
+#define GSLB_DNS_TREE_FD             9871
+#define GSLB_DNS_PARAMS_FD           9872
+#define GSLB_CLI_SEM                 9873
+#define GSLB_DNS      	             12345
+#define GSLB_NOCD_FD                 9874
+#define GSLB_MAP_FD                  9875
+#define GSLB_NOC_SITES_FD            9876
+#define GSLB_NOCD_SEM                9877
+#define GSLB_NOCD_RESP_SEM           9878
+#define GSLB_NOC_GEO_FD              9879
+#define GSLB_BGP_FD                  9880
+#define GSLB_NOCD_QUEUE_FD           9881
+#define GSLB_NOCD_QUEUE_SEM          9882
+#define GSLB_NOCD_BUFF_SEM           9883
+#define GSLB_DNS_SEM                 9884
+
+#define VIP_SEM                      2100
+
+#define CLI_SEM                      31337
+
+#define FILESHARE_SEM                2900
+
+#define LLB_HC_SEM_KEY              2901
+#define LLB_RSITE_SEM_KEY              2902
+
+#define FW_PERMIT_SHM_KEY            8123
+#define FW_DENY_SHM_KEY              8124
+#define FW_AGROUP_SHM_KEY            8125
+#define MNET_SHM_KEY                 8128
+#define VLAN_SHM_KEY                 8129
+
+/* for ip pool */
+#define IPPOOL_SHM_KEY			8200
+
+#define VPN_POLICY_KEY               8222
+#define VPN_KEY_KEY                  8223
+#define VPN_GROUP_KEY                8224
+
+
+/*for real cluster*/
+#define CLU_SHM_KEY                  38714
+
+/*for product name*/
+#define VERSION_SHM_KEY              39735
+
+/* for debugging at customer sites */
+#define DEBUG_SHM_KEY		     1111
+
+/*for access log*/
+#define ACCESSLOG_SHM_KEY            2764
+
+/* mail config */
+#define SYS_MAIL_SHM_KEY             40000
+
+#define LLB_HC_SHM_KEY               40001
+#define ROLE_BASE_SHM_KEY            40002
+#define LLB_RSITE_HC_SHM_KEY         40003 
+#define USER_CONF_SHM_KEY		1002
+#define USER_LOGIN_SHM_KEY		1003 /* used by login and openssh */
+
+
+#define STATIC_NDP_SHM_KEY              42000
+#define SYNC_SHM_KEY			43000
+
+#endif
+
+/*vxlan_support*/
+#define VXLAN_SHM_KEY		8132
+#define VXLAN_TUN_SHM_KEY	8131
+
+#endif				/* ifndef (_CA_SHM_H_) */
Index: /branches/amp_3_7_2/src/openssh/sshd-auth.patch
===================================================================
--- /branches/amp_3_7_2/src/openssh/sshd-auth.patch	(revision 0)
+++ /branches/amp_3_7_2/src/openssh/sshd-auth.patch	(working copy)
@@ -0,0 +1,22 @@
+diff --git a/sshd-auth.c b/sshd-auth.c
+--- a/sshd-auth.c
++++ b/sshd-auth.c
+@@ -488,7 +488,7 @@
+ 
+ 	/* Parse command-line arguments. */
+ 	while ((opt = getopt(ac, av,
+-	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtV")) != -1) {
++	    "C:E:b:c:f:g:h:k:o:p:u:46DGQRTdeiqrtVs")) != -1) {
+ 		switch (opt) {
+ 		case '4':
+ 			options.address_family = AF_INET;
+@@ -525,6 +525,9 @@
+ 		case 'r':
+ 			/* ignore */
+ 			break;
++		case 's':
++			options.synconfig = 1;
++			break;
+ 		case 'R':
+ 			rexeced_flag = 1;
+ 			break;
Index: /branches/amp_3_7_2/src/openssh/sshd_config
===================================================================
--- /branches/amp_3_7_2/src/openssh/sshd_config	(revision 2981)
+++ /branches/amp_3_7_2/src/openssh/sshd_config	(working copy)
@@ -23,10 +23,10 @@
 #Protocol 2
 
 # HostKey for protocol version 1
-HostKey /ca/etc/key/ssh_host_key
+#HostKey /ca/etc/key/ssh_host_key
 # HostKeys for protocol version 2
 HostKey /ca/etc/key/ssh_host_rsa_key
-HostKey /ca/etc/key/ssh_host_dsa_key
+#HostKey /ca/etc/key/ssh_host_dsa_key
 HostKey /ca/etc/key/ssh_host_ecdsa_key
 HostKey /ca/etc/key/ssh_host_ed25519_key
 
@@ -44,7 +44,7 @@
 
 # Authentication:
 
-#LoginGraceTime 2m
+LoginGraceTime 0
 PermitRootLogin no
 #StrictModes yes
 #MaxAuthTries 6
@@ -110,7 +110,7 @@
 #PrintLastLog yes
 #TCPKeepAlive yes
 #UseLogin no
-UsePrivilegeSeparation no
+#UsePrivilegeSeparation no
 #PermitUserEnvironment no
 #Compression delayed
 #ClientAliveInterval 0
@@ -126,7 +126,7 @@
 #Banner none
 
 # override default of no subsystems
-Subsystem	sftp	/usr/libexec/sftp-server
+Subsystem	sftp	/usr/libexec/openssh/sftp-server
 
 # Disable HPN tuning improvements.
 #HPNDisabled no
@@ -146,3 +146,4 @@
 #	AllowTcpForwarding no
 #	PermitTTY no
 #	ForceCommand cvs server
+KexAlgorithms curve25519-sha256@libssh.org,curve25519-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521
Index: /branches/amp_3_7_2/src/openssh/uinet_api.h
===================================================================
--- /branches/amp_3_7_2/src/openssh/uinet_api.h	(revision 0)
+++ /branches/amp_3_7_2/src/openssh/uinet_api.h	(working copy)
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2014 Patrick Kelsey. 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#ifndef	_UINET_API_H_
+#define	_UINET_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if __GNUC__ >= 7 && !defined(__LIBUINET__)
+#include <stdint.h>
+#endif
+
+#include "uinet_api_errno.h"
+#include "uinet_api_types.h"
+#include "uinet_queue.h"
+#include <sys/types.h>
+#include <sys/shm.h>
+void  uinet_finalize_thread(void);
+int   uinet_getl2info(struct uinet_socket *so, struct uinet_in_l2info *l2i);
+int   uinet_getifstat(uinet_instance_t uinst, const char *name, struct uinet_ifistat *stat);
+//void  uinet_gettcpstat(uinet_instance_t uinst, struct uinet_tcpstat *stat);
+char *uinet_inet_ntoa(struct uinet_in_addr in);
+int uinet_inet_aton(const char *cp, struct uinet_in_addr *inp);
+char *uinet_inet_ntop(int af, const void *src, char *dst, unsigned int size);
+int   uinet_inet_pton(int af, const char *src, void *dst);
+void uinet_link_addr(const char *addr, struct uinet_sockaddr_dl *sdl);
+char *uinet_link_ntoa(struct uinet_sockaddr_dl *sdl);
+int   uinet_inet6_enabled(void);
+int   uinet_dpdk_init(void);
+intptr_t uinet_get_sighandle_thread(void);
+int   uinet_init(unsigned int ncpus, unsigned int nmbclusters, struct uinet_instance_cfg *inst_cfg);
+int   uinet_initialize_thread(void);
+void  uinet_install_sighandlers(void);
+int   uinet_soioctl(struct uinet_socket* so, unsigned long what, void *req);
+int   uinet_interface_add_alias(uinet_instance_t uinst, const char *name, const char *addr, const char *braddr, const char *mask);
+int   uinet_interface_create(uinet_instance_t uinst, const char *name);
+int   uinet_interface_up(uinet_instance_t uinst, const char *name, unsigned int promisc, unsigned int promiscinet);
+int   uinet_l2tagstack_cmp(const struct uinet_in_l2tagstack *ts1, const struct uinet_in_l2tagstack *ts2);
+uint32_t uinet_l2tagstack_hash(const struct uinet_in_l2tagstack *ts);
+int   uinet_mac_aton(const char *macstr, uint8_t *macout);
+int   uinet_make_socket_passive(struct uinet_socket *so);
+int   uinet_make_socket_promiscuous(struct uinet_socket *so, unsigned int fib);
+uinet_pool_t uinet_pool_create(char *name, int size, uinet_pool_ctor ctor, uinet_pool_dtor dtor,
+			       uinet_pool_init init, uinet_pool_fini fini, int align, uint16_t flags);
+void *uinet_pool_alloc_arg(uinet_pool_t pool, void *arg, int flags);
+static inline void *uinet_pool_alloc(uinet_pool_t pool, int flags);
+static inline void *
+uinet_pool_alloc(uinet_pool_t pool, int flags)
+{
+	return uinet_pool_alloc_arg(pool, NULL, flags);
+}
+void  uinet_pool_free_arg(uinet_pool_t pool, void *item, void *arg);
+static inline void  uinet_pool_free(uinet_pool_t pool, void *item);
+static inline void
+uinet_pool_free(uinet_pool_t pool, void *item)
+{
+	uinet_pool_free_arg(pool, item, NULL);
+}
+void  uinet_pool_destroy(uinet_pool_t pool);
+int   uinet_pool_set_max(uinet_pool_t pool, int nitems);
+int   uinet_pool_get_max(uinet_pool_t pool);
+int   uinet_pool_get_cur(uinet_pool_t pool);
+int   uinet_setl2info(struct uinet_socket *so, const struct uinet_in_l2info *l2i);
+int   uinet_setl2info2(struct uinet_socket *so, const uint8_t *local_addr, const uint8_t *foreign_addr,
+		       uint16_t flags, const struct uinet_in_l2tagstack *tagstack);
+void  uinet_shutdown(unsigned int signo);
+int   uinet_soaccept(struct uinet_socket *listener, struct uinet_sockaddr **nam, struct uinet_socket **aso);
+int   uinet_soallocuserctx(struct uinet_socket *so);
+int   uinet_sobind(struct uinet_socket *so, struct uinet_sockaddr *nam);
+int   uinet_soclose(struct uinet_socket *so);
+int   uinet_soconnect(struct uinet_socket *so, struct uinet_sockaddr *nam);
+int   uinet_socreate(uinet_instance_t uinst, int dom, struct uinet_socket **aso, int type, int proto);
+void  uinet_sogetconninfo(struct uinet_socket *so, struct uinet_in_conninfo *inc);
+int   uinet_sogeterror(struct uinet_socket *so);
+uinet_instance_t uinet_sogetinstance(struct uinet_socket *so);
+struct uinet_socket *uinet_sogetpassivepeer(struct uinet_socket *so);
+int   uinet_sogetsockopt(struct uinet_socket *so, int level, int optname, void *optval, unsigned int *optlen);
+int   uinet_sogetstate(struct uinet_socket *so);
+void *uinet_sogetuserctx(struct uinet_socket *so, int key);
+int   uinet_solisten(struct uinet_socket *so, int backlog);
+int   uinet_soreadable(struct uinet_socket *so, unsigned int in_upcall);
+int   uinet_sowritable(struct uinet_socket *so, unsigned int in_upcall);
+int   uinet_soreceive(struct uinet_socket *so, struct uinet_sockaddr **psa, struct uinet_uio *uio, int *flagsp);
+int   uinet_soreceive_more(struct uinet_socket *so, struct uinet_uio *uio, int *flagsp, struct uinet_sockaddr *addr, int *addrlen, void *control_info, int *controllen);
+ssize_t uinet_soread(struct uinet_socket *so, void *buf, size_t count);
+void  uinet_sosetnonblocking(struct uinet_socket *so, unsigned int nonblocking);
+int   uinet_sosetsockopt(struct uinet_socket *so, int level, int optname, void *optval, unsigned int optlen);
+void  uinet_sosetupcallprep(struct uinet_socket *so,
+			    void (*soup_accept)(struct uinet_socket *, void *), void *soup_accept_arg,
+			    void (*soup_receive)(struct uinet_socket *, void *, int64_t, int64_t), void *soup_receive_arg,
+			    void (*soup_send)(struct uinet_socket *, void *, int64_t), void *soup_send_arg);
+void  uinet_sosetuserctx(struct uinet_socket *so, int key, void *ctx);
+int   uinet_sosend(struct uinet_socket *so, struct uinet_sockaddr *addr, struct uinet_uio *uio, int flags);
+ssize_t uinet_sowrite(struct uinet_socket *so, const void *buf, size_t count);
+int   uinet_soshutdown(struct uinet_socket *so, int how);
+int   uinet_sogetpeeraddr(struct uinet_socket *so, struct uinet_sockaddr **sa);
+int   uinet_sogetsockaddr(struct uinet_socket *so, struct uinet_sockaddr **sa);
+void  uinet_free_sockaddr(struct uinet_sockaddr *sa);
+void  uinet_soupcall_lock(struct uinet_socket *so, int which);
+void  uinet_soupcall_clear(struct uinet_socket *so, int which);
+void  uinet_soupcall_clear_locked(struct uinet_socket *so, int which);
+void  uinet_soupcall_set(struct uinet_socket *so, int which, int (*func)(struct uinet_socket *, void *, int), void *arg);
+void  uinet_soupcall_set_locked(struct uinet_socket *so, int which, int (*func)(struct uinet_socket *, void *, int), void *arg);
+void  uinet_soupcall_unlock(struct uinet_socket *so, int which);
+int   uinet_sysctlbyname(uinet_instance_t uinst, char *name, char *oldp, size_t *oldplen,
+			 char *newp, size_t newplen, size_t *retval, int flags);
+int   uinet_sysctl(uinet_instance_t uinst, int *name, unsigned int namelen, void *oldp, size_t *oldplen,
+		   void *newp, size_t newplen, size_t *retval, int flags);
+void  uinet_synfilter_getconninfo(uinet_api_synfilter_cookie_t cookie, struct uinet_in_conninfo *inc);
+void  uinet_synfilter_getl2info(uinet_api_synfilter_cookie_t cookie, struct uinet_in_l2info *l2i);
+void  uinet_synfilter_setl2info(uinet_api_synfilter_cookie_t cookie, struct uinet_in_l2info *l2i);
+void  uinet_synfilter_setaltfib(uinet_api_synfilter_cookie_t cookie, unsigned int altfib);
+void  uinet_synfilter_go_active_on_timeout(uinet_api_synfilter_cookie_t cookie, unsigned int ms);
+int   uinet_synfilter_install(struct uinet_socket *so, uinet_api_synfilter_callback_t callback, void *arg);
+uinet_synf_deferral_t uinet_synfilter_deferral_alloc(struct uinet_socket *so, uinet_api_synfilter_cookie_t cookie);
+int   uinet_synfilter_deferral_deliver(struct uinet_socket *so, uinet_synf_deferral_t deferral, int decision);
+void  uinet_synfilter_deferral_free(uinet_synf_deferral_t deferral);
+uinet_api_synfilter_cookie_t uinet_synfilter_deferral_get_cookie(uinet_synf_deferral_t deferral);
+int uinet_register_pfil_in(uinet_instance_t uinst, uinet_pfil_cb_t cb, void *arg, const char *ifname);
+
+const char * uinet_mbuf_data(const struct uinet_mbuf *);
+size_t uinet_mbuf_len(const struct uinet_mbuf *);
+int uinet_if_xmit(uinet_if_t uif, const char *buf, int len);
+
+int uinet_lock_log_set_file(const char *file);
+int uinet_lock_log_enable(void);
+int uinet_lock_log_disable(void);
+
+/*
+ *  Create a network interface with the given name, of the given type, in
+ *  the given connection domain, and bound to the given cpu.
+ *
+ *  type	is the type of interface to create.  This determines the
+ *		interface driver that will attach to the given configstr.
+ *
+ *  configstr	is a driver-specific configuration string.
+ *
+ *  		UINET_IFTYPE_NETMAP - vale<n>:<m> or <hostifname> or
+ *  		    <hostifname>:<qno>, where queue 0 is implied by
+ *		    a configstr of <hostifname>
+ *
+ *  alias	is any user-supplied string, or NULL.  If a string is supplied,
+ *	        it must be unique among all the other aliases and driver-assigned
+ *		names.  Passing an empty string is the same as passing NULL.
+ *
+ *  cdom	is the connection domain for ifname.  When looking up an
+ *		inbound packet on ifname, only protocol control blocks in
+ *		the same connection domain will be searched.
+ *
+ *  cpu		is the cpu number on which to perform stack processing on
+ *		packets received on ifname.  -1 means leave it up to the
+ *		scheduler.
+ *
+ *  cookie	is a pointer to an opaque reference that, if not NULL, will be
+ *		set to something that corresponds to the interface that is
+ *		created, or NULL if creation fails.
+ *
+ *
+ *  Return values:
+ *
+ *  0			Interface created successfully
+ *
+ *  UINET_ENXIO		Unable to configure the inteface
+ *
+ *  UINET_ENOMEM	No memory available for interface creation
+ *
+ *  UINET_EEXIST	An interface with the given name or cdom already exists
+ *
+ *  UINET_EINVAL	Malformed ifname, or cpu not in range [-1, num_cpu-1]
+ */
+int uinet_ifcreate(uinet_instance_t uinst, uinet_iftype_t type, const char *configstr,
+		   const char *alias, unsigned int cdom, int cpu, uinet_if_t *uif);
+
+
+/*
+ *  Destroy the network interface specified by the cookie.
+ *
+ *
+ *  Return values:
+ *
+ *  0			Interface destroyed successfully
+ *
+ *  UINET_ENXIO		Unable to destroy the interface
+ *
+ *  UINET_EINVAL	Invalid cookie
+ */
+int uinet_ifdestroy(uinet_if_t uif);
+
+
+/*
+ *  Destroy the network interface with the given name.
+ *
+ *  name	can be either the user-specified alias, or the driver-assigned
+ *		name returned by uinet_ifgenericname().
+ *
+ *  Return values:
+ *
+ *  0			Interface destroyed successfully
+ *
+ *  UINET_ENXIO		Unable to destroy the interface
+ *
+ *  UINET_EINVAL	No interface with the given name found
+ */
+int uinet_ifdestroy_byname(uinet_instance_t uinst, const char *ifname);
+
+
+/*
+ *  Retrieve the user-assigned alias or driver-assigned generic name for the
+ *  interface specified by cookie.
+ *
+ *
+ *  Return values:
+ *
+ *  ""			No alias was assigned or cookie was invalid.
+ *
+ *  <non-empty string>	The alias or driver-assigned name
+ *
+ */
+const char *uinet_ifaliasname(uinet_if_t uif);
+const char *uinet_ifgenericname(uinet_if_t uif);
+
+
+/*
+ *  Configure UDP and TCP blackholing.
+ */
+int uinet_config_blackhole(uinet_instance_t uinst, uinet_blackhole_t action);
+
+
+void uinet_instance_default_cfg(struct uinet_instance_cfg *cfg);
+uinet_instance_t uinet_instance_create(struct uinet_instance_cfg *cfg);
+uinet_instance_t uinet_instance_default(void);
+void uinet_instance_destroy(uinet_instance_t uinst);
+
+#define UINET_BATCH_EVENT_START  0
+#define UINET_BATCH_EVENT_FINISH 1
+
+int uinet_if_set_batch_event_handler(uinet_if_t uif,
+				     void (*handler)(void *arg, int event),
+				     void *arg);
+
+int uinet_slb_license_init(uint32_t l4_licensed, uint32_t l7_licensed, uint32_t limit, uint32_t ssl_ae_licensed);
+int uinet_fasttcp_on(void);
+int uinet_eroute_add(char *pol_name, uint32_t priority, char* sip_str, uint32_t smask, uint16_t src_start_port, uint16_t src_end_port, 
+	char* dip_str, uint32_t dmask, uint16_t dst_start_port, uint16_t dst_end_port, uint32_t proto, char* gwip_str, uint32_t weight);
+int uinet_eroute_delete(char *pol_name);
+int uinet_slb_virtual_generic(char *name, char *ipaddr, uint16_t port,
+        uint32_t max_conns, char *optarg, char *gw_ip, uint16_t proto);
+int uinet_slb_real(char *real_name, char * ipaddr, uint16_t port, char *mac,
+              char *usrif_name, char *sysif_name, uint32_t maxconns,
+              char *health_type, uint32_t up, uint32_t down, uint32_t protocol,
+              uint32_t timeout);
+
+int uinet_slb_policy_static(char *name, char *rsname);
+int uinet_slb_tcpoption_wscale(char *vs_name, char *on_off, uint16_t shift_count);
+
+#define UHI_SHM_KEY_CONF	0xcaf1f001
+#define UHI_SHM_KEY_KERN	0xcaf1f002
+
+enum {
+	BOOTTIME_INVALID = 0,
+	BOOTTIME_VALID,
+};
+
+typedef struct boottime_var {
+	uint64_t boottimebin_sec;
+	uint64_t boottimebin_frac;
+	uint64_t boottime_tv_sec;
+	uint64_t boottime_tv_usec;
+} boottime_var_t;
+
+typedef struct __uhi_shm_config {
+	uint32_t key;
+	uint64_t total;
+	uint64_t offset;
+	void * vaddr;
+	void * vaddr_end;
+	/* record atcp boot time */
+	uint8_t boottime_valid;
+	boottime_var_t boottime;
+	/* record atcp boot time - end */
+} uhi_shm_config_t;
+
+extern void *shmat(int shmid, const void *shmaddr, int shmflg);
+
+static inline void *
+uhi_shm_get(key_t key, size_t size, const void * vaddr)
+{
+	void *p;
+	int shm_id;
+
+	shm_id = shmget(key, size, 0666 | IPC_CREAT);
+	if (shm_id == -1) {
+		perror("uhi_shm_get: Shared memory get");
+		return NULL;
+	}
+
+	p = shmat(shm_id, vaddr, 0);
+	if (p == (void *)-1) {
+		perror("uhi_shm_get: Shared memory attach");
+		printf("%s, %d\n", __FILE__, __LINE__);
+		printf("key:%x, vaddr:%p\n", (unsigned int)key, vaddr);
+		return NULL;
+	}
+	return p;
+}
+
+static inline int
+uhi_shared_mem_attach(void)
+{
+	void *p;
+	uhi_shm_config_t * shm_confp;
+
+	shm_confp = (uhi_shm_config_t *)uhi_shm_get(UHI_SHM_KEY_CONF, sizeof(*shm_confp), NULL);
+	if (shm_confp == NULL || shm_confp->total == 0) {
+		return 1;
+	}
+
+	p = uhi_shm_get(shm_confp->key, 0, shm_confp->vaddr);
+	if (p == NULL) {
+		return -1;
+	}
+	
+	return 0;
+}
+
+int uhi_read_boottime(boottime_var_t *boottime);
+void uhi_write_boottime(uint64_t boottimebin_sec, uint64_t boottimebin_frac, uint64_t boottime_tv_sec, uint64_t boottime_tv_usec);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _UINET_API_H_ */

Property changes on: src/openssh/uinet_api.h
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: /branches/amp_3_7_2/src/openssh/uinet_api_errno.h
===================================================================
--- /branches/amp_3_7_2/src/openssh/uinet_api_errno.h	(revision 0)
+++ /branches/amp_3_7_2/src/openssh/uinet_api_errno.h	(working copy)
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2013 Patrick Kelsey. 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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+
+#ifndef	_UINET_API_ERRNO_H_
+#define	_UINET_API_ERRNO_H_
+
+#define	UINET_EPERM		1		/* Operation not permitted */
+#define	UINET_ENOENT		2		/* No such file or directory */
+#define	UINET_ESRCH		3		/* No such process */
+#define	UINET_EINTR		4		/* Interrupted system call */
+#define	UINET_EIO		5		/* Input/output error */
+#define	UINET_ENXIO		6		/* Device not configured */
+#define	UINET_E2BIG		7		/* Argument list too long */
+#define	UINET_ENOEXEC		8		/* Exec format error */
+#define	UINET_EBADF		9		/* Bad file descriptor */
+#define	UINET_ECHILD		10		/* No child processes */
+#define	UINET_EDEADLK		11		/* Resource deadlock avoided */
+						/* 11 was EAGAIN */
+#define	UINET_ENOMEM		12		/* Cannot allocate memory */
+#define	UINET_EACCES		13		/* Permission denied */
+#define	UINET_EFAULT		14		/* Bad address */
+#define	UINET_ENOTBLK		15		/* Block device required */
+#define	UINET_EBUSY		16		/* Device busy */
+#define	UINET_EEXIST		17		/* File exists */
+#define	UINET_EXDEV		18		/* Cross-device link */
+#define	UINET_ENODEV		19		/* Operation not supported by device */
+#define	UINET_ENOTDIR		20		/* Not a directory */
+#define	UINET_EISDIR		21		/* Is a directory */
+#define	UINET_EINVAL		22		/* Invalid argument */
+#define	UINET_ENFILE		23		/* Too many open files in system */
+#define	UINET_EMFILE		24		/* Too many open files */
+#define	UINET_ENOTTY		25		/* Inappropriate ioctl for device */
+#define	UINET_ETXTBSY		26		/* Text file busy */
+#define	UINET_EFBIG		27		/* File too large */
+#define	UINET_ENOSPC		28		/* No space left on device */
+#define	UINET_ESPIPE		29		/* Illegal seek */
+#define	UINET_EROFS		30		/* Read-only filesystem */
+#define	UINET_EMLINK		31		/* Too many links */
+#define	UINET_EPIPE		32		/* Broken pipe */
+
+/* math software */
+#define	UINET_EDOM		33		/* Numerical argument out of domain */
+#define	UINET_ERANGE		34		/* Result too large */
+
+/* non-blocking and interrupt i/o */
+#define	UINET_EAGAIN		35		/* Resource temporarily unavailable */
+#define	UINET_EWOULDBLOCK	UINET_EAGAIN		/* Operation would block */
+#define	UINET_EINPROGRESS	36		/* Operation now in progress */
+#define	UINET_EALREADY		37		/* Operation already in progress */
+
+/* ipc/network software -- argument errors */
+#define	UINET_ENOTSOCK		38		/* Socket operation on non-socket */
+#define	UINET_EDESTADDRREQ	39		/* Destination address required */
+#define	UINET_EMSGSIZE		40		/* Message too long */
+#define	UINET_EPROTOTYPE	41		/* Protocol wrong type for socket */
+#define	UINET_ENOPROTOOPT	42		/* Protocol not available */
+#define	UINET_EPROTONOSUPPORT	43		/* Protocol not supported */
+#define	UINET_ESOCKTNOSUPPORT	44		/* Socket type not supported */
+#define	UINET_EOPNOTSUPP	45		/* Operation not supported */
+#define	UINET_ENOTSUP		UINET_EOPNOTSUPP	/* Operation not supported */
+#define	UINET_EPFNOSUPPORT	46		/* Protocol family not supported */
+#define	UINET_EAFNOSUPPORT	47		/* Address family not supported by protocol family */
+#define	UINET_EADDRINUSE	48		/* Address already in use */
+#define	UINET_EADDRNOTAVAIL	49		/* Can't assign requested address */
+
+/* ipc/network software -- operational errors */
+#define	UINET_ENETDOWN		50		/* Network is down */
+#define	UINET_ENETUNREACH	51		/* Network is unreachable */
+#define	UINET_ENETRESET		52		/* Network dropped connection on reset */
+#define	UINET_ECONNABORTED	53		/* Software caused connection abort */
+#define	UINET_ECONNRESET	54		/* Connection reset by peer */
+#define	UINET_ENOBUFS		55		/* No buffer space available */
+#define	UINET_EISCONN		56		/* Socket is already connected */
+#define	UINET_ENOTCONN		57		/* Socket is not connected */
+#define	UINET_ESHUTDOWN		58		/* Can't send after socket shutdown */
+#define	UINET_ETOOMANYREFS	59		/* Too many references: can't splice */
+#define	UINET_ETIMEDOUT		60		/* Operation timed out */
+#define	UINET_ECONNREFUSED	61		/* Connection refused */
+
+#define	UINET_ELOOP		62		/* Too many levels of symbolic links */
+#define	UINET_ENAMETOOLONG	63		/* File name too long */
+
+/* should be rearranged */
+#define	UINET_EHOSTDOWN		64		/* Host is down */
+#define	UINET_EHOSTUNREACH	65		/* No route to host */
+#define	UINET_ENOTEMPTY		66		/* Directory not empty */
+
+/* quotas & mush */
+#define	UINET_EPROCLIM		67		/* Too many processes */
+#define	UINET_EUSERS		68		/* Too many users */
+#define	UINET_EDQUOT		69		/* Disc quota exceeded */
+
+/* Network File System */
+#define	UINET_ESTALE		70		/* Stale NFS file handle */
+#define	UINET_EREMOTE		71		/* Too many levels of remote in path */
+#define	UINET_EBADRPC		72		/* RPC struct is bad */
+#define	UINET_ERPCMISMATCH	73		/* RPC version wrong */
+#define	UINET_EPROGUNAVAIL	74		/* RPC prog. not avail */
+#define	UINET_EPROGMISMATCH	75		/* Program version wrong */
+#define	UINET_EPROCUNAVAIL	76		/* Bad procedure for program */
+
+#define	UINET_ENOLCK		77		/* No locks available */
+#define	UINET_ENOSYS		78		/* Function not implemented */
+
+#define	UINET_EFTYPE		79		/* Inappropriate file type or format */
+#define	UINET_EAUTH		80		/* Authentication error */
+#define	UINET_ENEEDAUTH		81		/* Need authenticator */
+#define	UINET_EIDRM		82		/* Identifier removed */
+#define	UINET_ENOMSG		83		/* No message of desired type */
+#define	UINET_EOVERFLOW		84		/* Value too large to be stored in data type */
+#define	UINET_ECANCELED		85		/* Operation canceled */
+#define	UINET_EILSEQ		86		/* Illegal byte sequence */
+#define	UINET_ENOATTR		87		/* Attribute not found */
+
+#define	UINET_EDOOFUS		88		/* Programming error */
+
+#define	UINET_EBADMSG		89		/* Bad message */
+#define	UINET_EMULTIHOP		90		/* Multihop attempted */
+#define	UINET_ENOLINK		91		/* Link has been severed */
+#define	UINET_EPROTO		92		/* Protocol error */
+
+#define	UINET_ENOTCAPABLE	93		/* Capabilities insufficient */
+#define	UINET_ECAPMODE		94		/* Not permitted in capability mode */
+
+#define	UINET_ELAST		94		/* Must be equal largest errno */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int uinet_errno_to_os(int uinet_errno);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _UINET_API_ERRNO_H_ */
Index: /branches/amp_3_7_2/src/openssh/uinet_queue.h
===================================================================
--- /branches/amp_3_7_2/src/openssh/uinet_queue.h	(revision 0)
+++ /branches/amp_3_7_2/src/openssh/uinet_queue.h	(working copy)
@@ -0,0 +1,742 @@
+/*-
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  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.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	@(#)queue.h	8.5 (Berkeley) 8/20/94
+ * $FreeBSD: releng/10.0/sys/sys/queue.h 251887 2013-06-18 02:57:56Z lstewart $
+ */
+
+#ifndef _UINET_QUEUE_H_
+#define	_UINET_QUEUE_H_
+
+
+/*
+ * Macro to test if we're using a specific version of gcc or later.
+ */
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+#define __UINET_GNUC_PREREQ__(ma, mi) \
+        (__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi))
+#else
+#define __UINET_GNUC_PREREQ__(ma, mi) 0
+#endif
+
+#ifndef __UINET_DEQUALIFY
+#define __UINET_DEQUALIFY(type, var)  ((type)(uintptr_t)(const volatile void *)(var))
+#endif
+
+/*
+ * We define this here since <stddef.h>, <sys/queue.h>, and <sys/types.h>
+ * require it.
+ */
+#if __UINET_GNUC_PREREQ__(4, 1)
+#define __uinet_offsetof(type, field)  __builtin_offsetof(type, field)
+#else
+#ifndef __cplusplus
+#define __uinet_offsetof(type, field) \
+        ((__size_t)(__uintptr_t)((const volatile void *)&((type *)0)->field))
+#else
+#define __uinet_offsetof(type, field)                           \
+  (__offsetof__ (reinterpret_cast <__size_t>                    \
+                 (&reinterpret_cast <const volatile char &>     \
+                  (static_cast<type *> (0)->field))))
+#endif
+#endif
+
+/*
+ * Given the pointer x to the member m of the struct s, return
+ * a pointer to the containing structure.  When using GCC, we first
+ * assign pointer x to a local variable, to check that its type is
+ * compatible with member m.
+ */
+#if __UINET_GNUC_PREREQ__(3, 1)
+#define __uinet_containerof(x, s, m) ({                                 \
+        const volatile __typeof(((s *)0)->m) *__x = (x);                \
+        __UINET_DEQUALIFY(s *, (const volatile char *)__x - __uinet_offsetof(s, m));\
+})
+#else
+#define __uinet_containerof(x, s, m)                                     \
+        __UINET_DEQUALIFY(s *, (const volatile char *)(x) - __uinet_offsetof(s, m))
+#endif
+
+
+/*
+ * This file defines four types of data structures: singly-linked lists,
+ * singly-linked tail queues, lists and tail queues.
+ *
+ * A singly-linked list is headed by a single forward pointer. The elements
+ * are singly linked for minimum space and pointer manipulation overhead at
+ * the expense of O(n) removal for arbitrary elements. New elements can be
+ * added to the list after an existing element or at the head of the list.
+ * Elements being removed from the head of the list should use the explicit
+ * macro for this purpose for optimum efficiency. A singly-linked list may
+ * only be traversed in the forward direction.  Singly-linked lists are ideal
+ * for applications with large datasets and few or no removals or for
+ * implementing a LIFO queue.
+ *
+ * A singly-linked tail queue is headed by a pair of pointers, one to the
+ * head of the list and the other to the tail of the list. The elements are
+ * singly linked for minimum space and pointer manipulation overhead at the
+ * expense of O(n) removal for arbitrary elements. New elements can be added
+ * to the list after an existing element, at the head of the list, or at the
+ * end of the list. Elements being removed from the head of the tail queue
+ * should use the explicit macro for this purpose for optimum efficiency.
+ * A singly-linked tail queue may only be traversed in the forward direction.
+ * Singly-linked tail queues are ideal for applications with large datasets
+ * and few or no removals or for implementing a FIFO queue.
+ *
+ * A list is headed by a single forward pointer (or an array of forward
+ * pointers for a hash table header). The elements are doubly linked
+ * so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before
+ * or after an existing element or at the head of the list. A list
+ * may be traversed in either direction.
+ *
+ * A tail queue is headed by a pair of pointers, one to the head of the
+ * list and the other to the tail of the list. The elements are doubly
+ * linked so that an arbitrary element can be removed without a need to
+ * traverse the list. New elements can be added to the list before or
+ * after an existing element, at the head of the list, or at the end of
+ * the list. A tail queue may be traversed in either direction.
+ *
+ * For details on the use of these macros, see the queue(3) manual page.
+ *
+ *
+ *				SLIST	LIST	STAILQ	TAILQ
+ * _HEAD			+	+	+	+
+ * _HEAD_INITIALIZER		+	+	+	+
+ * _ENTRY			+	+	+	+
+ * _INIT			+	+	+	+
+ * _EMPTY			+	+	+	+
+ * _FIRST			+	+	+	+
+ * _NEXT			+	+	+	+
+ * _PREV			-	+	-	+
+ * _LAST			-	-	+	+
+ * _FOREACH			+	+	+	+
+ * _FOREACH_FROM		+	+	+	+
+ * _FOREACH_SAFE		+	+	+	+
+ * _FOREACH_FROM_SAFE		+	+	+	+
+ * _FOREACH_REVERSE		-	-	-	+
+ * _FOREACH_REVERSE_FROM	-	-	-	+
+ * _FOREACH_REVERSE_SAFE	-	-	-	+
+ * _FOREACH_REVERSE_FROM_SAFE	-	-	-	+
+ * _INSERT_HEAD			+	+	+	+
+ * _INSERT_BEFORE		-	+	-	+
+ * _INSERT_AFTER		+	+	+	+
+ * _INSERT_TAIL			-	-	+	+
+ * _CONCAT			-	-	+	+
+ * _REMOVE_AFTER		+	-	+	-
+ * _REMOVE_HEAD			+	-	+	-
+ * _REMOVE			+	+	+	+
+ * _SWAP			+	+	+	+
+ *
+ */
+#ifdef UINET_QUEUE_MACRO_DEBUG
+/* Store the last 2 places the queue element or head was altered */
+struct uinet_qm_trace {
+	unsigned long	 lastline;
+	unsigned long	 prevline;
+	const char	*lastfile;
+	const char	*prevfile;
+};
+
+#define	UINET_TRACEBUF	struct uinet_qm_trace trace;
+#define	UINET_TRACEBUF_INITIALIZER	{ __FILE__, __LINE__, NULL, 0 } ,
+#define	UINET_TRASHIT(x)	do {(x) = (void *)-1;} while (0)
+#define	UINET_QMD_SAVELINK(name, link)	void **name = (void *)&(link)
+
+#define	UINET_QMD_TRACE_HEAD(head) do {					\
+	(head)->trace.prevline = (head)->trace.lastline;		\
+	(head)->trace.prevfile = (head)->trace.lastfile;		\
+	(head)->trace.lastline = __LINE__;				\
+	(head)->trace.lastfile = __FILE__;				\
+} while (0)
+
+#define	UINET_QMD_TRACE_ELEM(elem) do {					\
+	(elem)->trace.prevline = (elem)->trace.lastline;		\
+	(elem)->trace.prevfile = (elem)->trace.lastfile;		\
+	(elem)->trace.lastline = __LINE__;				\
+	(elem)->trace.lastfile = __FILE__;				\
+} while (0)
+
+#else
+#define	UINET_QMD_TRACE_ELEM(elem)
+#define	UINET_QMD_TRACE_HEAD(head)
+#define	UINET_QMD_SAVELINK(name, link)
+#define	UINET_TRACEBUF
+#define	UINET_TRACEBUF_INITIALIZER
+#define	UINET_TRASHIT(x)
+#endif	/* UINET_QUEUE_MACRO_DEBUG */
+
+/*
+ * Singly-linked List declarations.
+ */
+#define	UINET_SLIST_HEAD(name, type)					\
+struct name {								\
+	struct type *slh_first;	/* first element */			\
+}
+
+#define	UINET_SLIST_HEAD_INITIALIZER(head)				\
+	{ NULL }
+
+#define	UINET_SLIST_ENTRY(type)						\
+struct {								\
+	struct type *sle_next;	/* next element */			\
+}
+
+/*
+ * Singly-linked List functions.
+ */
+#define	UINET_SLIST_EMPTY(head)	((head)->slh_first == NULL)
+
+#define	UINET_SLIST_FIRST(head)	((head)->slh_first)
+
+#define	UINET_SLIST_FOREACH(var, head, field)				\
+	for ((var) = UINET_SLIST_FIRST((head));				\
+	    (var);							\
+	    (var) = UINET_SLIST_NEXT((var), field))
+
+#define	UINET_SLIST_FOREACH_FROM(var, head, field)			\
+	for ((var) = ((var) ? (var) : UINET_SLIST_FIRST((head)));	\
+	    (var);							\
+	    (var) = UINET_SLIST_NEXT((var), field))
+
+#define	UINET_SLIST_FOREACH_SAFE(var, head, field, tvar)		\
+	for ((var) = UINET_SLIST_FIRST((head));				\
+	    (var) && ((tvar) = UINET_SLIST_NEXT((var), field), 1);	\
+	    (var) = (tvar))
+
+#define	UINET_SLIST_FOREACH_FROM_SAFE(var, head, field, tvar)		\
+	for ((var) = ((var) ? (var) : UINET_SLIST_FIRST((head)));	\
+	    (var) && ((tvar) = UINET_SLIST_NEXT((var), field), 1);	\
+	    (var) = (tvar))
+
+#define	UINET_SLIST_FOREACH_PREVPTR(var, varp, head, field)		\
+	for ((varp) = &UINET_SLIST_FIRST((head));			\
+	    ((var) = *(varp)) != NULL;					\
+	    (varp) = &UINET_SLIST_NEXT((var), field))
+
+#define	UINET_SLIST_INIT(head) do {					\
+	UINET_SLIST_FIRST((head)) = NULL;				\
+} while (0)
+
+#define	UINET_SLIST_INSERT_AFTER(slistelm, elm, field) do {		\
+	UINET_SLIST_NEXT((elm), field) = UINET_SLIST_NEXT((slistelm), field);	\
+	UINET_SLIST_NEXT((slistelm), field) = (elm);			\
+} while (0)
+
+#define	UINET_SLIST_INSERT_HEAD(head, elm, field) do {			\
+	UINET_SLIST_NEXT((elm), field) = UINET_SLIST_FIRST((head));	\
+	UINET_SLIST_FIRST((head)) = (elm);				\
+} while (0)
+
+#define	UINET_SLIST_NEXT(elm, field)	((elm)->field.sle_next)
+
+#define	UINET_SLIST_REMOVE(head, elm, type, field) do {			\
+	UINET_QMD_SAVELINK(oldnext, (elm)->field.sle_next);		\
+	if (UINET_SLIST_FIRST((head)) == (elm)) {			\
+		UINET_SLIST_REMOVE_HEAD((head), field);			\
+	}								\
+	else {								\
+		struct type *curelm = UINET_SLIST_FIRST((head));	\
+		while (UINET_SLIST_NEXT(curelm, field) != (elm))	\
+			curelm = UINET_SLIST_NEXT(curelm, field);	\
+		UINET_SLIST_REMOVE_AFTER(curelm, field);		\
+	}								\
+	UINET_TRASHIT(*oldnext);					\
+} while (0)
+
+#define UINET_SLIST_REMOVE_AFTER(elm, field) do {			\
+	UINET_SLIST_NEXT(elm, field) =					\
+	    UINET_SLIST_NEXT(UINET_SLIST_NEXT(elm, field), field);	\
+} while (0)
+
+#define	UINET_SLIST_REMOVE_HEAD(head, field) do {			\
+	UINET_SLIST_FIRST((head)) = UINET_SLIST_NEXT(UINET_SLIST_FIRST((head)), field);	\
+} while (0)
+
+#define UINET_SLIST_SWAP(head1, head2, type) do {			\
+	struct type *swap_first = UINET_SLIST_FIRST(head1);		\
+	UINET_SLIST_FIRST(head1) = UINET_SLIST_FIRST(head2);		\
+	UINET_SLIST_FIRST(head2) = swap_first;				\
+} while (0)
+
+/*
+ * Singly-linked Tail queue declarations.
+ */
+#define	UINET_STAILQ_HEAD(name, type)					\
+struct name {								\
+	struct type *stqh_first;/* first element */			\
+	struct type **stqh_last;/* addr of last next element */		\
+}
+
+#define	UINET_STAILQ_HEAD_INITIALIZER(head)				\
+	{ NULL, &(head).stqh_first }
+
+#define	UINET_STAILQ_ENTRY(type)					\
+struct {								\
+	struct type *stqe_next;	/* next element */			\
+}
+
+/*
+ * Singly-linked Tail queue functions.
+ */
+#define	UINET_STAILQ_CONCAT(head1, head2) do {				\
+	if (!UINET_STAILQ_EMPTY((head2))) {				\
+		*(head1)->stqh_last = (head2)->stqh_first;		\
+		(head1)->stqh_last = (head2)->stqh_last;		\
+		UINET_STAILQ_INIT((head2));				\
+	}								\
+} while (0)
+
+#define	UINET_STAILQ_EMPTY(head)	((head)->stqh_first == NULL)
+
+#define	UINET_STAILQ_FIRST(head)	((head)->stqh_first)
+
+#define	UINET_STAILQ_FOREACH(var, head, field)				\
+	for((var) = UINET_STAILQ_FIRST((head));				\
+	   (var);							\
+	   (var) = UINET_STAILQ_NEXT((var), field))
+
+#define	UINET_STAILQ_FOREACH_FROM(var, head, field)			\
+	for ((var) = ((var) ? (var) : UINET_STAILQ_FIRST((head)));	\
+	   (var);							\
+	   (var) = UINET_STAILQ_NEXT((var), field))
+
+#define	UINET_STAILQ_FOREACH_SAFE(var, head, field, tvar)		\
+	for ((var) = UINET_STAILQ_FIRST((head));			\
+	    (var) && ((tvar) = UINET_STAILQ_NEXT((var), field), 1);	\
+	    (var) = (tvar))
+
+#define	UINET_STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)		\
+	for ((var) = ((var) ? (var) : UINET_STAILQ_FIRST((head)));	\
+	    (var) && ((tvar) = UINET_STAILQ_NEXT((var), field), 1);	\
+	    (var) = (tvar))
+
+#define	UINET_STAILQ_INIT(head) do {					\
+	UINET_STAILQ_FIRST((head)) = NULL;				\
+	(head)->stqh_last = &UINET_STAILQ_FIRST((head));		\
+} while (0)
+
+#define	UINET_STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {		\
+	if ((UINET_STAILQ_NEXT((elm), field) = UINET_STAILQ_NEXT((tqelm), field)) == NULL)\
+		(head)->stqh_last = &UINET_STAILQ_NEXT((elm), field);	\
+	UINET_STAILQ_NEXT((tqelm), field) = (elm);			\
+} while (0)
+
+#define	UINET_STAILQ_INSERT_HEAD(head, elm, field) do {			\
+	if ((UINET_STAILQ_NEXT((elm), field) = UINET_STAILQ_FIRST((head))) == NULL)	\
+		(head)->stqh_last = &UINET_STAILQ_NEXT((elm), field);	\
+	UINET_STAILQ_FIRST((head)) = (elm);				\
+} while (0)
+
+#define	UINET_STAILQ_INSERT_TAIL(head, elm, field) do {			\
+	UINET_STAILQ_NEXT((elm), field) = NULL;				\
+	*(head)->stqh_last = (elm);					\
+	(head)->stqh_last = &UINET_STAILQ_NEXT((elm), field);		\
+} while (0)
+
+#define	UINET_STAILQ_LAST(head, type, field)				\
+	(UINET_STAILQ_EMPTY((head)) ? NULL :				\
+	    __uinet_containerof((head)->stqh_last, struct type, field.stqe_next))
+
+#define	UINET_STAILQ_NEXT(elm, field)	((elm)->field.stqe_next)
+
+#define	UINET_STAILQ_REMOVE(head, elm, type, field) do {		\
+	UINET_QMD_SAVELINK(oldnext, (elm)->field.stqe_next);		\
+	if (UINET_STAILQ_FIRST((head)) == (elm)) {			\
+		UINET_STAILQ_REMOVE_HEAD((head), field);		\
+	}								\
+	else {								\
+		struct type *curelm = UINET_STAILQ_FIRST((head));	\
+		while (UINET_STAILQ_NEXT(curelm, field) != (elm))	\
+			curelm = UINET_STAILQ_NEXT(curelm, field);	\
+		UINET_STAILQ_REMOVE_AFTER(head, curelm, field);		\
+	}								\
+	UINET_TRASHIT(*oldnext);					\
+} while (0)
+
+#define UINET_STAILQ_REMOVE_AFTER(head, elm, field) do {		\
+	if ((UINET_STAILQ_NEXT(elm, field) =				\
+	     UINET_STAILQ_NEXT(UINET_STAILQ_NEXT(elm, field), field)) == NULL)	\
+		(head)->stqh_last = &UINET_STAILQ_NEXT((elm), field);	\
+} while (0)
+
+#define	UINET_STAILQ_REMOVE_HEAD(head, field) do {			\
+	if ((UINET_STAILQ_FIRST((head)) =				\
+	     UINET_STAILQ_NEXT(UINET_STAILQ_FIRST((head)), field)) == NULL)	\
+		(head)->stqh_last = &UINET_STAILQ_FIRST((head));	\
+} while (0)
+
+#define UINET_STAILQ_SWAP(head1, head2, type) do {			\
+	struct type *swap_first = UINET_STAILQ_FIRST(head1);		\
+	struct type **swap_last = (head1)->stqh_last;			\
+	UINET_STAILQ_FIRST(head1) = UINET_STAILQ_FIRST(head2);		\
+	(head1)->stqh_last = (head2)->stqh_last;			\
+	UINET_STAILQ_FIRST(head2) = swap_first;				\
+	(head2)->stqh_last = swap_last;					\
+	if (UINET_STAILQ_EMPTY(head1))					\
+		(head1)->stqh_last = &UINET_STAILQ_FIRST(head1);	\
+	if (UINET_STAILQ_EMPTY(head2))					\
+		(head2)->stqh_last = &UINET_STAILQ_FIRST(head2);	\
+} while (0)
+
+
+/*
+ * List declarations.
+ */
+#define	UINET_LIST_HEAD(name, type)					\
+struct name {								\
+	struct type *lh_first;	/* first element */			\
+}
+
+#define	UINET_LIST_HEAD_INITIALIZER(head)				\
+	{ NULL }
+
+#define	UINET_LIST_ENTRY(type)						\
+struct {								\
+	struct type *le_next;	/* next element */			\
+	struct type **le_prev;	/* address of previous next element */	\
+}
+
+/*
+ * List functions.
+ */
+
+#if (defined(_KERNEL) && defined(INVARIANTS))
+#define	UINET_QMD_LIST_CHECK_HEAD(head, field) do {			\
+	if (UINET_LIST_FIRST((head)) != NULL &&				\
+	    UINET_LIST_FIRST((head))->field.le_prev !=			\
+	     &UINET_LIST_FIRST((head)))					\
+		panic("Bad list head %p first->prev != head", (head));	\
+} while (0)
+
+#define	UINET_QMD_LIST_CHECK_NEXT(elm, field) do {			\
+	if (UINET_LIST_NEXT((elm), field) != NULL &&			\
+	    UINET_LIST_NEXT((elm), field)->field.le_prev !=		\
+	     &((elm)->field.le_next))					\
+	     	panic("Bad link elm %p next->prev != elm", (elm));	\
+} while (0)
+
+#define	UINET_QMD_LIST_CHECK_PREV(elm, field) do {			\
+	if (*(elm)->field.le_prev != (elm))				\
+		panic("Bad link elm %p prev->next != elm", (elm));	\
+} while (0)
+#else
+#define	UINET_QMD_LIST_CHECK_HEAD(head, field)
+#define	UINET_QMD_LIST_CHECK_NEXT(elm, field)
+#define	UINET_QMD_LIST_CHECK_PREV(elm, field)
+#endif /* (_KERNEL && INVARIANTS) */
+
+#define	UINET_LIST_EMPTY(head)	((head)->lh_first == NULL)
+
+#define	UINET_LIST_FIRST(head)	((head)->lh_first)
+
+#define	UINET_LIST_FOREACH(var, head, field)				\
+	for ((var) = UINET_LIST_FIRST((head));				\
+	    (var);							\
+	    (var) = UINET_LIST_NEXT((var), field))
+
+#define	UINET_LIST_FOREACH_FROM(var, head, field)			\
+	for ((var) = ((var) ? (var) : UINET_LIST_FIRST((head)));	\
+	    (var);							\
+	    (var) = UINET_LIST_NEXT((var), field))
+
+#define	UINET_LIST_FOREACH_SAFE(var, head, field, tvar)			\
+	for ((var) = UINET_LIST_FIRST((head));				\
+	    (var) && ((tvar) = UINET_LIST_NEXT((var), field), 1);	\
+	    (var) = (tvar))
+
+#define	UINET_LIST_FOREACH_FROM_SAFE(var, head, field, tvar)		\
+	for ((var) = ((var) ? (var) : UINET_LIST_FIRST((head)));	\
+	    (var) && ((tvar) = UINET_LIST_NEXT((var), field), 1);	\
+	    (var) = (tvar))
+
+#define	UINET_LIST_INIT(head) do {					\
+	UINET_LIST_FIRST((head)) = NULL;				\
+} while (0)
+
+#define	UINET_LIST_INSERT_AFTER(listelm, elm, field) do {		\
+	UINET_QMD_LIST_CHECK_NEXT(listelm, field);			\
+	if ((UINET_LIST_NEXT((elm), field) = UINET_LIST_NEXT((listelm), field)) != NULL)\
+		UINET_LIST_NEXT((listelm), field)->field.le_prev =	\
+		    &UINET_LIST_NEXT((elm), field);			\
+	UINET_LIST_NEXT((listelm), field) = (elm);			\
+	(elm)->field.le_prev = &UINET_LIST_NEXT((listelm), field);	\
+} while (0)
+
+#define	UINET_LIST_INSERT_BEFORE(listelm, elm, field) do {		\
+	UINET_QMD_LIST_CHECK_PREV(listelm, field);			\
+	(elm)->field.le_prev = (listelm)->field.le_prev;		\
+	UINET_LIST_NEXT((elm), field) = (listelm);			\
+	*(listelm)->field.le_prev = (elm);				\
+	(listelm)->field.le_prev = &UINET_LIST_NEXT((elm), field);	\
+} while (0)
+
+#define	UINET_LIST_INSERT_HEAD(head, elm, field) do {			\
+	UINET_QMD_LIST_CHECK_HEAD((head), field);			\
+	if ((UINET_LIST_NEXT((elm), field) = UINET_LIST_FIRST((head))) != NULL)	\
+		UINET_LIST_FIRST((head))->field.le_prev = &UINET_LIST_NEXT((elm), field);\
+	UINET_LIST_FIRST((head)) = (elm);				\
+	(elm)->field.le_prev = &UINET_LIST_FIRST((head));		\
+} while (0)
+
+#define	UINET_LIST_NEXT(elm, field)	((elm)->field.le_next)
+
+#define	UINET_LIST_PREV(elm, head, type, field)				\
+	((elm)->field.le_prev == &UINET_LIST_FIRST((head)) ? NULL :	\
+	    __uinet_containerof((elm)->field.le_prev, struct type, field.le_next))
+
+#define	UINET_LIST_REMOVE(elm, field) do {				\
+	UINET_QMD_SAVELINK(oldnext, (elm)->field.le_next);		\
+	UINET_QMD_SAVELINK(oldprev, (elm)->field.le_prev);		\
+	UINET_QMD_LIST_CHECK_NEXT(elm, field);				\
+	UINET_QMD_LIST_CHECK_PREV(elm, field);				\
+	if (UINET_LIST_NEXT((elm), field) != NULL)			\
+		UINET_LIST_NEXT((elm), field)->field.le_prev = 		\
+		    (elm)->field.le_prev;				\
+	*(elm)->field.le_prev = UINET_LIST_NEXT((elm), field);		\
+	UINET_TRASHIT(*oldnext);					\
+	UINET_TRASHIT(*oldprev);					\
+} while (0)
+
+#define UINET_LIST_SWAP(head1, head2, type, field) do {			\
+	struct type *swap_tmp = UINET_LIST_FIRST((head1));		\
+	UINET_LIST_FIRST((head1)) = UINET_LIST_FIRST((head2));		\
+	UINET_LIST_FIRST((head2)) = swap_tmp;				\
+	if ((swap_tmp = UINET_LIST_FIRST((head1))) != NULL)		\
+		swap_tmp->field.le_prev = &UINET_LIST_FIRST((head1));	\
+	if ((swap_tmp = UINET_LIST_FIRST((head2))) != NULL)		\
+		swap_tmp->field.le_prev = &UINET_LIST_FIRST((head2));	\
+} while (0)
+
+/*
+ * Tail queue declarations.
+ */
+#define	UINET_TAILQ_HEAD(name, type)					\
+struct name {								\
+	struct type *tqh_first;	/* first element */			\
+	struct type **tqh_last;	/* addr of last next element */		\
+	UINET_TRACEBUF							\
+}
+
+#define	UINET_TAILQ_HEAD_INITIALIZER(head)				\
+	{ NULL, &(head).tqh_first, UINET_TRACEBUF_INITIALIZER }
+
+#define	UINET_TAILQ_ENTRY(type)						\
+struct {								\
+	struct type *tqe_next;	/* next element */			\
+	struct type **tqe_prev;	/* address of previous next element */	\
+	UINET_TRACEBUF							\
+}
+
+/*
+ * Tail queue functions.
+ */
+#if (defined(_KERNEL) && defined(INVARIANTS))
+#define	UINET_QMD_TAILQ_CHECK_HEAD(head, field) do {			\
+	if (!UINET_TAILQ_EMPTY(head) &&					\
+	    UINET_TAILQ_FIRST((head))->field.tqe_prev !=		\
+	     &UINET_TAILQ_FIRST((head)))				\
+		panic("Bad tailq head %p first->prev != head", (head));	\
+} while (0)
+
+#define	UINET_QMD_TAILQ_CHECK_TAIL(head, field) do {			\
+	if (*(head)->tqh_last != NULL)					\
+	    	panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); 	\
+} while (0)
+
+#define	UINET_QMD_TAILQ_CHECK_NEXT(elm, field) do {			\
+	if (UINET_TAILQ_NEXT((elm), field) != NULL &&			\
+	    UINET_TAILQ_NEXT((elm), field)->field.tqe_prev !=		\
+	     &((elm)->field.tqe_next))					\
+		panic("Bad link elm %p next->prev != elm", (elm));	\
+} while (0)
+
+#define	UINET_QMD_TAILQ_CHECK_PREV(elm, field) do {			\
+	if (*(elm)->field.tqe_prev != (elm))				\
+		panic("Bad link elm %p prev->next != elm", (elm));	\
+} while (0)
+#else
+#define	UINET_QMD_TAILQ_CHECK_HEAD(head, field)
+#define	UINET_QMD_TAILQ_CHECK_TAIL(head, headname)
+#define	UINET_QMD_TAILQ_CHECK_NEXT(elm, field)
+#define	UINET_QMD_TAILQ_CHECK_PREV(elm, field)
+#endif /* (_KERNEL && INVARIANTS) */
+
+#define	UINET_TAILQ_CONCAT(head1, head2, field) do {			\
+	if (!UINET_TAILQ_EMPTY(head2)) {				\
+		*(head1)->tqh_last = (head2)->tqh_first;		\
+		(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last;	\
+		(head1)->tqh_last = (head2)->tqh_last;			\
+		UINET_TAILQ_INIT((head2));				\
+		UINET_QMD_TRACE_HEAD(head1);				\
+		UINET_QMD_TRACE_HEAD(head2);				\
+	}								\
+} while (0)
+
+#define	UINET_TAILQ_EMPTY(head)	((head)->tqh_first == NULL)
+
+#define	UINET_TAILQ_FIRST(head)	((head)->tqh_first)
+
+#define	UINET_TAILQ_FOREACH(var, head, field)				\
+	for ((var) = UINET_TAILQ_FIRST((head));				\
+	    (var);							\
+	    (var) = UINET_TAILQ_NEXT((var), field))
+
+#define	UINET_TAILQ_FOREACH_FROM(var, head, field)			\
+	for ((var) = ((var) ? (var) : UINET_TAILQ_FIRST((head)));	\
+	    (var);							\
+	    (var) = UINET_TAILQ_NEXT((var), field))
+
+#define	UINET_TAILQ_FOREACH_SAFE(var, head, field, tvar)		\
+	for ((var) = UINET_TAILQ_FIRST((head));				\
+	    (var) && ((tvar) = UINET_TAILQ_NEXT((var), field), 1);	\
+	    (var) = (tvar))
+
+#define	UINET_TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar)		\
+	for ((var) = ((var) ? (var) : UINET_TAILQ_FIRST((head)));	\
+	    (var) && ((tvar) = UINET_TAILQ_NEXT((var), field), 1);	\
+	    (var) = (tvar))
+
+#define	UINET_TAILQ_FOREACH_REVERSE(var, head, headname, field)		\
+	for ((var) = UINET_TAILQ_LAST((head), headname);		\
+	    (var);							\
+	    (var) = UINET_TAILQ_PREV((var), headname, field))
+
+#define	UINET_TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field)	\
+	for ((var) = ((var) ? (var) : UINET_TAILQ_LAST((head), headname));	\
+	    (var);							\
+	    (var) = UINET_TAILQ_PREV((var), headname, field))
+
+#define	UINET_TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar)	\
+	for ((var) = UINET_TAILQ_LAST((head), headname);			\
+	    (var) && ((tvar) = UINET_TAILQ_PREV((var), headname, field), 1);	\
+	    (var) = (tvar))
+
+#define	UINET_TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \
+	for ((var) = ((var) ? (var) : UINET_TAILQ_LAST((head), headname));	\
+	    (var) && ((tvar) = UINET_TAILQ_PREV((var), headname, field), 1);	\
+	    (var) = (tvar))
+
+#define	UINET_TAILQ_INIT(head) do {					\
+	UINET_TAILQ_FIRST((head)) = NULL;				\
+	(head)->tqh_last = &UINET_TAILQ_FIRST((head));			\
+	UINET_QMD_TRACE_HEAD(head);					\
+} while (0)
+
+#define	UINET_TAILQ_INSERT_AFTER(head, listelm, elm, field) do {	\
+	UINET_QMD_TAILQ_CHECK_NEXT(listelm, field);			\
+	if ((UINET_TAILQ_NEXT((elm), field) = UINET_TAILQ_NEXT((listelm), field)) != NULL)\
+		UINET_TAILQ_NEXT((elm), field)->field.tqe_prev = 	\
+		    &UINET_TAILQ_NEXT((elm), field);			\
+	else {								\
+		(head)->tqh_last = &UINET_TAILQ_NEXT((elm), field);	\
+		UINET_QMD_TRACE_HEAD(head);				\
+	}								\
+	UINET_TAILQ_NEXT((listelm), field) = (elm);			\
+	(elm)->field.tqe_prev = &UINET_TAILQ_NEXT((listelm), field);	\
+	UINET_QMD_TRACE_ELEM(&(elm)->field);				\
+	UINET_QMD_TRACE_ELEM(&listelm->field);				\
+} while (0)
+
+#define	UINET_TAILQ_INSERT_BEFORE(listelm, elm, field) do {		\
+	UINET_QMD_TAILQ_CHECK_PREV(listelm, field);			\
+	(elm)->field.tqe_prev = (listelm)->field.tqe_prev;		\
+	UINET_TAILQ_NEXT((elm), field) = (listelm);			\
+	*(listelm)->field.tqe_prev = (elm);				\
+	(listelm)->field.tqe_prev = &UINET_TAILQ_NEXT((elm), field);	\
+	UINET_QMD_TRACE_ELEM(&(elm)->field);				\
+	UINET_QMD_TRACE_ELEM(&listelm->field);				\
+} while (0)
+
+#define	UINET_TAILQ_INSERT_HEAD(head, elm, field) do {			\
+	UINET_QMD_TAILQ_CHECK_HEAD(head, field);			\
+	if ((UINET_TAILQ_NEXT((elm), field) = UINET_TAILQ_FIRST((head))) != NULL)	\
+		UINET_TAILQ_FIRST((head))->field.tqe_prev =		\
+		    &UINET_TAILQ_NEXT((elm), field);			\
+	else								\
+		(head)->tqh_last = &UINET_TAILQ_NEXT((elm), field);	\
+	UINET_TAILQ_FIRST((head)) = (elm);				\
+	(elm)->field.tqe_prev = &UINET_TAILQ_FIRST((head));		\
+	UINET_QMD_TRACE_HEAD(head);					\
+	UINET_QMD_TRACE_ELEM(&(elm)->field);				\
+} while (0)
+
+#define	UINET_TAILQ_INSERT_TAIL(head, elm, field) do {			\
+	UINET_QMD_TAILQ_CHECK_TAIL(head, field);			\
+	UINET_TAILQ_NEXT((elm), field) = NULL;				\
+	(elm)->field.tqe_prev = (head)->tqh_last;			\
+	*(head)->tqh_last = (elm);					\
+	(head)->tqh_last = &UINET_TAILQ_NEXT((elm), field);		\
+	UINET_QMD_TRACE_HEAD(head);					\
+	UINET_QMD_TRACE_ELEM(&(elm)->field);				\
+} while (0)
+
+#define	UINET_TAILQ_LAST(head, headname)				\
+	(*(((struct headname *)((head)->tqh_last))->tqh_last))
+
+#define	UINET_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+
+#define	UINET_TAILQ_PREV(elm, headname, field)				\
+	(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
+
+#define	UINET_TAILQ_REMOVE(head, elm, field) do {			\
+	UINET_QMD_SAVELINK(oldnext, (elm)->field.tqe_next);		\
+	UINET_QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);		\
+	UINET_QMD_TAILQ_CHECK_NEXT(elm, field);				\
+	UINET_QMD_TAILQ_CHECK_PREV(elm, field);				\
+	if ((UINET_TAILQ_NEXT((elm), field)) != NULL)			\
+		UINET_TAILQ_NEXT((elm), field)->field.tqe_prev = 	\
+		    (elm)->field.tqe_prev;				\
+	else {								\
+		(head)->tqh_last = (elm)->field.tqe_prev;		\
+		UINET_QMD_TRACE_HEAD(head);				\
+	}								\
+	*(elm)->field.tqe_prev = UINET_TAILQ_NEXT((elm), field);	\
+	UINET_TRASHIT(*oldnext);					\
+	UINET_TRASHIT(*oldprev);					\
+	UINET_QMD_TRACE_ELEM(&(elm)->field);				\
+} while (0)
+
+#define UINET_TAILQ_SWAP(head1, head2, type, field) do {		\
+	struct type *swap_first = (head1)->tqh_first;			\
+	struct type **swap_last = (head1)->tqh_last;			\
+	(head1)->tqh_first = (head2)->tqh_first;			\
+	(head1)->tqh_last = (head2)->tqh_last;				\
+	(head2)->tqh_first = swap_first;				\
+	(head2)->tqh_last = swap_last;					\
+	if ((swap_first = (head1)->tqh_first) != NULL)			\
+		swap_first->field.tqe_prev = &(head1)->tqh_first;	\
+	else								\
+		(head1)->tqh_last = &(head1)->tqh_first;		\
+	if ((swap_first = (head2)->tqh_first) != NULL)			\
+		swap_first->field.tqe_prev = &(head2)->tqh_first;	\
+	else								\
+		(head2)->tqh_last = &(head2)->tqh_first;		\
+} while (0)
+
+#endif /* !_UINET_QUEUE_H_ */
Index: /branches/amp_3_7_2/src/openssh/weak_mac.patch
===================================================================
--- /branches/amp_3_7_2/src/openssh/weak_mac.patch	(revision 0)
+++ /branches/amp_3_7_2/src/openssh/weak_mac.patch	(working copy)
@@ -0,0 +1,22 @@
+diff --git a/myproposal.h b/myproposal.h
+index 3bdc2e9..3196c53 100644
+--- a/myproposal.h
++++ b/myproposal.h
+@@ -66,16 +66,12 @@
+ #define KEX_CLIENT_ENCRYPT KEX_SERVER_ENCRYPT
+ 
+ #define	KEX_SERVER_MAC \
+-	"umac-64-etm@openssh.com," \
+ 	"umac-128-etm@openssh.com," \
+ 	"hmac-sha2-256-etm@openssh.com," \
+ 	"hmac-sha2-512-etm@openssh.com," \
+-	"hmac-sha1-etm@openssh.com," \
+-	"umac-64@openssh.com," \
+ 	"umac-128@openssh.com," \
+ 	"hmac-sha2-256," \
+-	"hmac-sha2-512," \
+-	"hmac-sha1"
++	"hmac-sha2-512"
+ 
+ #define KEX_CLIENT_MAC KEX_SERVER_MAC
+ 
