Index: /branches/rel_apv_10_7/tools/ustack.spec
===================================================================
--- /branches/rel_apv_10_7/tools/ustack.spec	(revision 38749)
+++ /branches/rel_apv_10_7/tools/ustack.spec	(working copy)
@@ -89,7 +89,8 @@
 install -dDm 0755 %{buildroot}/ca/health
 install -dDm 0755 %{buildroot}/ca/include
 install -dDm 0755 %{buildroot}/ca/ipregion
-install -dDm 0755 %{buildroot}/ca/lib 
+install -dDm 0755 %{buildroot}/ca/lib
+install -dDm 0755 %{buildroot}/ca/libexec
 install -dDm 0755 %{buildroot}/ca/man
 install -dDm 0755 %{buildroot}/ca/preload
 install -dDm 0755 %{buildroot}/ca/proxy
@@ -289,6 +290,7 @@
 %attr (4755,root,root)/ca/bin/ta_shell
 %attr (4755,root,root)/ca/bin/recovery
 %attr (755,root,root)/ca/lib/*
+%attr (755,root,root)/ca/libexec/*
 %attr (644,root,root)/ca/etc/*
 %attr (644,root,root)/ca/an_lighttpd/*
 %attr (644,root,root)/ca/openldap/*
@@ -346,7 +348,8 @@
 %dir /ca/health
 %dir /ca/include
 %dir /ca/ipregion
-%dir /ca/lib 
+%dir /ca/lib
+%dir /ca/libexec
 %dir /ca/man
 %dir /ca/preload
 %dir /ca/proxy
Index: /branches/rel_apv_10_7/usr/click/bin/openssh/CVE-2023-48795-mitigation.patch
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/openssh/CVE-2023-48795-mitigation.patch	(revision 38749)
+++ /branches/rel_apv_10_7/usr/click/bin/openssh/CVE-2023-48795-mitigation.patch	(working copy)
@@ -1,19 +1,21 @@
---- myproposal.h	2024-06-14 10:19:37.366799879 +0800
-+++ myproposal_edit.h	2024-06-14 10:20:19.886789628 +0800
-@@ -57,16 +57,12 @@
-	"rsa-sha2-256"
-
+diff --git a/myproposal.h b/myproposal.h
+index 3196c53..16a93d4 100644
+--- a/myproposal.h
++++ b/myproposal.h
+@@ -59,16 +59,12 @@
+ 	"rsa-sha2-256"
+ 
  #define	KEX_SERVER_ENCRYPT \
 -	"chacha20-poly1305@openssh.com," \
-	"aes128-ctr,aes192-ctr,aes256-ctr," \
-	"aes128-gcm@openssh.com,aes256-gcm@openssh.com"
-
+ 	"aes128-ctr,aes192-ctr,aes256-ctr," \
+ 	"aes128-gcm@openssh.com,aes256-gcm@openssh.com"
+ 
  #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"
+ 	"umac-128@openssh.com," \
+ 	"hmac-sha2-256," \
+ 	"hmac-sha2-512"
Index: /branches/rel_apv_10_7/usr/click/bin/openssh/Makefile
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/openssh/Makefile	(revision 38749)
+++ /branches/rel_apv_10_7/usr/click/bin/openssh/Makefile	(working copy)
@@ -16,10 +16,11 @@
 all:
 	./build.sh all
 clean:
-	rm -rf openssh-9.3p2
+	rm -rf openssh-9.9p1
 realclean:
 	git clean -dfx .
 install:
-	install -Dm 0755 -t ${ANROOT}/ca/bin/  ${.CURDIR}/openssh-9.3p2/sshd ${.CURDIR}/openssh-9.3p2/ssh ${.CURDIR}/openssh-9.3p2/ssh-keygen
+	install -Dm 0755 -t ${ANROOT}/ca/bin/  ${.CURDIR}/openssh-9.9p1/sshd ${.CURDIR}/openssh-9.9p1/ssh ${.CURDIR}/openssh-9.9p1/ssh-keygen
 	install -Dm 0755 -t ${ANROOT}/ca/etc/ ${.CURDIR}/sshd_config
+	install -Dm 0755 ${.CURDIR}/openssh-9.9p1/sshd-session ${ANROOT}/ca/libexec/sshd-session
 .endif
Index: /branches/rel_apv_10_7/usr/click/bin/openssh/array.patch
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/openssh/array.patch	(revision 0)
+++ /branches/rel_apv_10_7/usr/click/bin/openssh/array.patch	(working copy)
@@ -0,0 +1,1854 @@
+diff --git a/Makefile.in b/Makefile.in
+index 4243006..774d49d 100644
+--- a/Makefile.in
++++ b/Makefile.in
+@@ -71,7 +71,7 @@ MKDIR_P=@MKDIR_P@
+ 
+ .SUFFIXES: .lo
+ 
+-TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) sshd-session$(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)
++TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) synconfigd$(EXEEXT) sshd-session$(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)
+ 
+ XMSS_OBJS=\
+ 	ssh-xmss.o \
+@@ -167,8 +167,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' \
+@@ -193,7 +196,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
+@@ -215,10 +219,13 @@ 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 -lldap -lssl -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) -L ../../objdir/ -L../../../lib/libexauth -lexauth -L../../../lib/libuinet-atcp/lib/libuinet -luinet_lite -L../../../lib/libuinet-atcp/lib/libuinet_sysctl -luinet_sysctl -L../../../lib/libuinet-atcp/lib/libuinetnv -luinetnv -lrt -lcrypto -L../../../lib/libfastlog -lfastlog
++
++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)
++	$(LD) -o $@ $(SSHD_SESSION_OBJS) $(LDFLAGS) -lssh -lldap -lssl -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) -L ../../objdir/ -L../../../lib/libexauth -lexauth -L../../../lib/libuinet-atcp/lib/libuinet -luinet_lite -L../../../lib/libuinet-atcp/lib/libuinet_sysctl -luinet_sysctl -L../../../lib/libuinet-atcp/lib/libuinetnv -luinetnv -lrt -lcrypto -L../../../lib/libfastlog -lfastlog
+ 
+ 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 347d91e..5eb8d36 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 67dec88..65caf04 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>
+@@ -59,6 +63,9 @@
+ #include "digest.h"
+ #include "kex.h"
+ 
++#include "click/app/fastlog/fastlog.h"
++#include "click/app/fastlog/fastlog_var.h"
++
+ /* import */
+ extern ServerOptions options;
+ extern struct sshbuf *loginmsg;
+@@ -102,6 +109,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,26 +470,43 @@ 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)
+ 			mm_start_pam(ssh);
+@@ -339,6 +542,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) {
+@@ -354,9 +584,34 @@ input_userauth_request(int type, u_int32_t seq, struct ssh *ssh)
+ 	free(service);
+ 	free(user);
+ 	free(method);
++
+ 	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 +653,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 +692,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 +750,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 f68e94a..a930144 100755
+--- a/configure
++++ b/configure
+@@ -877,7 +877,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 5966b4f..b8ebe5c 100644
+--- a/monitor.c
++++ b/monitor.c
+@@ -98,6 +98,39 @@
+ #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 "click/app/fastlog/fastlog.h"
++#include "click/app/fastlog/logex_def.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
+@@ -148,6 +181,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 */
+@@ -215,6 +251,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}
+ };
+ 
+@@ -235,6 +273,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) {
++		fastlog_logex(SSHD_LOGIN_MSG_FTOK, 0);
++	}
++
++bingo:
++	if ((msg_id = msgget(msg_key, IPC_CREAT|SSHD_MSGQ_MODE)) == -1) {
++		if (errno == EINTR) {
++			goto bingo;
++		} else {
++			fastlog_logex(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 {
++			fastlog_logex(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) {
++		fastlog_logex(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);
++		fastlog_logex(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");
++
++	fastlog_logex(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)
+@@ -320,6 +500,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) {
+@@ -761,10 +943,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;
+@@ -903,17 +1092,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);
+@@ -1979,4 +2171,3 @@ mm_answer_gss_userok(struct ssh *ssh, int sock, struct sshbuf *m)
+ 	return (authenticated);
+ }
+ #endif /* GSSAPI */
+-
+diff --git a/monitor.h b/monitor.h
+index fa48fc6..547725a 100644
+--- a/monitor.h
++++ b/monitor.h
+@@ -63,6 +63,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 5358c77..dde7e71 100644
+--- a/monitor_wrap.c
++++ b/monitor_wrap.c
+@@ -466,6 +466,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);
+@@ -1162,3 +1164,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 e768036..4ef4bd5 100644
+--- a/monitor_wrap.h
++++ b/monitor_wrap.h
+@@ -95,9 +95,11 @@ int mm_bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **);
+ int mm_bsdauth_respond(void *, u_int, char **);
+ 
+ /* config / channels glue */
+-void	 server_process_permitopen(struct ssh *);
+-void	 server_process_channel_timeouts(struct ssh *ssh);
++void     server_process_permitopen(struct ssh *);
++void     server_process_channel_timeouts(struct ssh *ssh);
+ struct connection_info *
+-	 server_get_connection_info(struct ssh *, int, int);
++     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 3d9cc6d..7a9da2a 100644
+--- a/readconf.c
++++ b/readconf.c
+@@ -169,6 +169,7 @@ typedef enum {
+ 	oHashKnownHosts,
+ 	oTunnel, oTunnelDevice,
+ 	oLocalCommand, oPermitLocalCommand, oRemoteCommand,
++	oPassword, oSync,
+ 	oVisualHostKey,
+ 	oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull,
+ 	oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass,
+@@ -299,6 +300,8 @@ static struct {
+ 	{ "localcommand", oLocalCommand },
+ 	{ "permitlocalcommand", oPermitLocalCommand },
+ 	{ "remotecommand", oRemoteCommand },
++	{ "password", oPassword },
++	{ "sync", oSync },
+ 	{ "visualhostkey", oVisualHostKey },
+ 	{ "kexalgorithms", oKexAlgorithms },
+ 	{ "ipqos", oIPQoS },
+@@ -1995,6 +1998,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;
+@@ -2674,6 +2682,8 @@ initialize_options(Options * options)
+ 	options->known_hosts_command = NULL;
+ 	options->required_rsa_size = -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 9447d5d..2d9a679 100644
+--- a/readconf.h
++++ b/readconf.h
+@@ -186,6 +186,8 @@ typedef struct {
+ 	u_int	num_channel_timeouts;
+ 
+ 	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 89b8413..1207e0a 100644
+--- a/servconf.c
++++ b/servconf.c
+@@ -213,6 +213,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->refuse_connection = -1;
+ }
+@@ -549,7 +550,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,
+@@ -661,6 +662,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
+@@ -1395,6 +1398,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 5089bc9..0917792 100644
+--- a/servconf.h
++++ b/servconf.h
+@@ -247,6 +247,7 @@ typedef struct {
+ 	u_int	num_channel_timeouts;
+ 
+ 	int	unused_connection_timeout;
++	int     synconfig;
+ 
+ 	char   *sshd_session_path;
+ 
+diff --git a/session.c b/session.c
+index c941511..9dff0e9 100644
+--- a/session.c
++++ b/session.c
+@@ -114,6 +114,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' || \
+@@ -177,6 +182,34 @@ static char *auth_info_file = NULL;
+ static char *auth_sock_name = NULL;
+ static char *auth_sock_dir = 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
+@@ -715,6 +748,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);
+@@ -1010,7 +1048,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
+@@ -1558,6 +1604,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 0019281..83beb56 100644
+--- a/ssh.c
++++ b/ssh.c
+@@ -174,6 +174,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
+@@ -746,7 +748,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");
+@@ -879,6 +881,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)
+@@ -1755,8 +1760,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 7cf6b63..e08b0be 100644
+--- a/sshconnect.c
++++ b/sshconnect.c
+@@ -69,6 +69,7 @@
+ #include "ssherr.h"
+ #include "authfd.h"
+ #include "kex.h"
++#include "cipher.h"
+ 
+ struct sshkey *previous_host_key = NULL;
+ 
+@@ -1128,6 +1129,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 "
+@@ -1229,7 +1232,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) {
+@@ -1250,7 +1255,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
+@@ -1614,7 +1621,7 @@ ssh_login(struct ssh *ssh, Sensitive *sensitive, const char *orighost,
+ 	/* authenticate user */
+ 	debug("Authenticating to %s:%d as '%s'", host, port, server_user);
+ 	ssh_kex2(ssh, host, hostaddr, port, cinfo);
+-	ssh_userauth2(ssh, local_user, server_user, host, sensitive);
++	ssh_userauth2(ssh, local_user, server_user, host, sensitive, NULL);
+ 	free(local_user);
+ 	free(host);
+ }
+@@ -1759,3 +1766,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 8b0466f..33c282d 100644
+--- a/sshconnect.h
++++ b/sshconnect.h
+@@ -86,7 +86,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 11fcdea..bdcd1b9 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 */
+@@ -1043,8 +1045,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 ||
+@@ -1055,7 +1062,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 4b79b9b..3a69164 100644
+--- a/sshd-session.c
++++ b/sshd-session.c
+@@ -110,6 +110,40 @@
+ #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 "click/app/fastlog/fastlog.h"
++#include "click/app/fastlog/logex_def.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_STARTUP_PIPE_FD		(STDERR_FILENO + 2)
+@@ -862,6 +896,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) {
++		fastlog_logex(SSHD_LOGIN_GETPID, 0);
++	}
++	if ((msg_key = ftok(SSHD_LOGIN_MSGQ_PATH, 0x02)) == -1) {
++		fastlog_logex(SSHD_LOGIN_MSG_FTOK, 0);
++	}
++
++bingo:
++	if ((msg_id = msgget(msg_key, 0))== -1) {
++		if (errno == EINTR) {
++			goto bingo;
++		} else {
++			fastlog_logex(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 */
++	fastlog_logex(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.
+  */
+@@ -913,7 +1114,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;
+@@ -950,6 +1151,9 @@ main(int ac, char **av)
+ 		case 'r':
+ 			/* ignore */
+ 			break;
++		case 's':
++			options.synconfig = 1;
++			break;
+ 		case 'R':
+ 			rexeced_flag = 1;
+ 			break;
+@@ -1061,6 +1265,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);
++	}
++
+ 	debug("sshd version %s, %s", SSH_VERSION, SSH_OPENSSL_VERSION);
+ 
+ 	/* Fetch our configuration */
+@@ -1347,6 +1557,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
+@@ -1393,6 +1610,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 df76dc7..fcd6b6c 100644
+--- a/sshd.c
++++ b/sshd.c
+@@ -91,6 +91,14 @@
+ #include "sk-api.h"
+ #include "addr.h"
+ #include "srclimit.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)
+@@ -138,6 +146,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;
+@@ -843,6 +872,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.
+@@ -862,6 +1008,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));
+@@ -1010,6 +1164,13 @@ 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);
++				close(startup_p[0]);
++				close(startup_p[1]);
++				continue;
++			}
+ 			if (unset_nonblock(*newsock) == -1) {
+ 				close(*newsock);
+ 				continue;
+@@ -1236,7 +1397,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;
+@@ -1276,6 +1437,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;
Index: /branches/rel_apv_10_7/usr/click/bin/openssh/array_patch
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/openssh/array_patch	(revision 38749)
+++ /branches/rel_apv_10_7/usr/click/bin/openssh/array_patch	(working copy)
@@ -1,1483 +0,0 @@
-diff -ru1 openssh-9.3p2/Makefile.in openssh-9.3p2-patch/Makefile.in
---- openssh-9.3p2/Makefile.in	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/Makefile.in	2024-08-05 17:00:44.124383461 +0800
-@@ -71,3 +71,3 @@
-
--TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) ssh-add$(EXEEXT) ssh-keygen$(EXEEXT) ssh-keyscan${EXEEXT} ssh-keysign${EXEEXT} ssh-pkcs11-helper$(EXEEXT) ssh-agent$(EXEEXT) scp$(EXEEXT) sftp-server$(EXEEXT) sftp$(EXEEXT) ssh-sk-helper$(EXEEXT)
-+TARGETS=ssh$(EXEEXT) sshd$(EXEEXT) synconfigd$(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)
-
-@@ -161,4 +161,7 @@
-
--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
-
-@@ -187,3 +190,4 @@
-
--all: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
-+#all: $(CONFIGFILES) $(MANPAGES) $(TARGETS)
-+all: $(CONFIGFILES) $(TARGETS)
-
-@@ -209,3 +213,6 @@
- sshd$(EXEEXT): libssh.a	$(LIBCOMPAT) $(SSHDOBJS)
--	$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS)
-+	$(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lldap -lssl -lopenbsd-compat $(SSHDLIBS) $(LIBS) $(GSSLIBS) $(K5LIBS) $(CHANNELLIBS) -L ../../objdir/ -L../../../lib/libexauth -lexauth -L../../../lib/libuinet-atcp/lib/libuinet -luinet_lite -L../../../lib/libuinet-atcp/lib/libuinet_sysctl -luinet_sysctl -L../../../lib/libuinet-atcp/lib/libuinetnv -luinetnv -lrt -lcrypto -L../../../lib/libfastlog -lfastlog
-+
-+synconfigd$(EXEEXT): sshd$(EXEEXT)
-+	/bin/cp sshd$(EXEEXT) $@
-
-diff -ru1 openssh-9.3p2/auth.c openssh-9.3p2-patch/auth.c
---- openssh-9.3p2/auth.c	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/auth.c	2024-08-05 17:00:44.124383461 +0800
-@@ -78,2 +78,33 @@
-
-+#include <syslog.h>
-+#include <unistd.h>
-+#include <sys/msg.h>
-+#include <sys/ipc.h>
-+#if defined(__linux__)
-+#define __printflike(x, y)
-+#endif
-+#include "click/app/fastlog/fastlog.h"
-+#include "click/app/fastlog/logex_def.h"
-+
-+#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;
-+
-+
-+
- /* import */
-@@ -856 +887,88 @@
- }
-+
-+void
-+array_auth_log(struct ssh *ssh, int authenticated, char *method, char *info)
-+{
-+	Authctxt *authctxt = ssh->authctxt;
-+	/* info is ssh2 */
-+	if (!strncmp(method,"none",4)) {
-+		return;
-+	}
-+
-+	fastlog_logex(AUTH_SSH_LOGIN, 6,
-+			authctxt->user,
-+			ssh_remote_ipaddr(ssh),
-+			ssh_remote_port(ssh),
-+			ssh_local_ipaddr(ssh),
-+			ssh_local_port(ssh),
-+			info);
-+}
-+
-+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) {
-+		fastlog_logex(SSHD_LOGIN_MSG_FTOK, 0);
-+	}
-+
-+bingo:
-+	if ((msg_id = msgget(msg_key, IPC_CREAT|SSHD_MSGQ_MODE)) == -1) {
-+		if (errno == EINTR) {
-+			goto bingo;
-+		} else {
-+			fastlog_logex(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 {
-+			fastlog_logex(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"
-+int
-+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 0;
-+		}
-+		passwd = getpwent();
-+	}
-+	endpwent();
-+
-+	return -1;
-+}
-+
-diff -ru1 openssh-9.3p2/auth.h openssh-9.3p2-patch/auth.h
---- openssh-9.3p2/auth.h	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/auth.h	2024-08-05 17:00:44.124383461 +0800
-@@ -240,2 +240,4 @@
-
-+#define MAX_USER_NAME_SIZE 256
-+
- int	 sys_auth_passwd(struct ssh *, const char *);
-diff -ru1 openssh-9.3p2/auth2-passwd.c openssh-9.3p2-patch/auth2-passwd.c
---- openssh-9.3p2/auth2-passwd.c	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/auth2-passwd.c	2024-08-05 17:00:44.124383461 +0800
-@@ -46,2 +46,28 @@
- #include "servconf.h"
-+#include <pwd.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
-+
-+extern char ext_user[32];
-+extern int     do_exauth;
-+extern char ext_ssh_client_IP[32];
-+
-+struct passwd *local_auth_pw = NULL;
-+struct passwd *ext_auth_pw = NULL;
-+int local_auth_valid = 0;
-+int ext_auth_valid = 0;
-+int ext_authorize_level = 0; /* 0: enable, 1: config */
-+int ext_authenticated = 0;
-+
-+
-
-@@ -55,4 +81,9 @@
-	int authenticated = 0, r;
-+	int local_authenticated = 0;
-	u_char change;
-	size_t len = 0;
-+	char method_str[80];
-+	Authctxt *authctxt = ssh->authctxt;
-+
-+	ext_authenticated = 0;
-
-@@ -66,6 +97,58 @@
-
--	if (change)
--		logit("password change not supported");
--	else if (PRIVSEP(auth_password(ssh, password)) == 1)
--		authenticated = 1;
-+	/*really do external authentication*/
-+	if (do_exauth) {
-+		int ret_value = EXT_AUTH_FAILED;
-+		/*
-+		 *  the pw is a mapped user,EX_LOG_ON_MAPPED_USER
-+		 */
-+
-+		/*get exauth conf from the shared mem*/
-+		memset(method_str, 0, 80);
-+		get_aaa_method(method_str);
-+
-+		ret_value = external_auth(ext_user, password);
-+		if(ret_value == EXT_AUTH_PASS_CONFIG ) {
-+			ext_authenticated = 1;
-+			ext_authorize_level = 1;
-+		} else if (ret_value == EXT_AUTH_PASS_ENABLE) {
-+			ext_authenticated = 1;
-+			ext_authorize_level = 0;
-+		}
-+
-+		if(!ext_authenticated){
-+			/*exauth failed*/
-+			if(exauth_priority() == EXAUTH_PRIORITY_HIGH){
-+				/*exauth High priority, check local database*/
-+				if(local_auth_valid){
-+					authctxt->pw = local_auth_pw;
-+				} else {
-+					/*user not found in local database*/
-+					authctxt->pw = fakepw();
-+					authctxt->valid = 0;
-+				}
-+				if (change){
-+					logit("password change not supported");
-+				}
-+				else if (PRIVSEP(auth_password(ssh, password)) == 1){
-+					local_authenticated = 1;
-+				}
-+				if(!local_authenticated){
-+					/*local also failed, switch back to external*/
-+					authctxt->pw = ext_auth_pw;
-+					authctxt->valid = 1;
-+				}
-+			}
-+		}
-+	} else {
-+		/*not do exauth, just check local database*/
-+		if (change){
-+			logit("password change not supported");
-+		}
-+		else if (PRIVSEP(auth_password(ssh, password)) == 1){
-+			local_authenticated = 1;
-+		}
-+
-+	}
-+	authenticated = ext_authenticated || local_authenticated;
-+
-	freezero(password, len);
-diff -ru1 openssh-9.3p2/auth2.c openssh-9.3p2-patch/auth2.c
---- openssh-9.3p2/auth2.c	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/auth2.c	2024-08-05 17:00:44.124383461 +0800
-@@ -60,2 +60,26 @@
-
-+/* ArrayOS external auth support */
-+#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
-+
-+#include <sys/ipc.h>
-+#include <sys/shm.h>
-+#include <sys/time.h>
-+
-+extern char ext_user[32];
-+extern int do_exauth;
-+extern char ext_ssh_client_IP[32];
-+
-+extern struct passwd *local_auth_pw;
-+extern struct passwd *ext_auth_pw;
-+extern int local_auth_valid;
-+extern int ext_auth_valid;
-+
-+
- /* import */
-@@ -103,2 +127,28 @@
-
-+#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 int login_info_shm_attach(void);
-+static void login_info_shm_detach(void);
-+static int user_login_info_add(char *name);
-+static int get_user_index(char *name);
-+static int check_user_locked(int index);
-+static int lock_user(struct ssh *ssh, int index);
-+static user_login_info_t *user_login_p;
-+static int user_index;
-+
- char *
-@@ -264,2 +314,3 @@
-	double tstart = monotime_double();
-+	char array_user[MAX_USER_NAME_SIZE] = {'\0'};
-
-@@ -275,2 +326,8 @@
-
-+	/* External auth */
-+	set_ext_user(user);
-+	logit("set_ext_user");
-+
-+	login_info_shm_attach();
-+
- 	if ((style = strchr(user, ':')) != NULL)
-@@ -281,16 +338,102 @@
- 	if (authctxt->attempt++ == 0) {
-+		local_auth_valid = 0;
-+		ext_auth_valid = 0;
-+		local_auth_pw = NULL;
-+		ext_auth_pw = NULL;
-+		do_exauth = 0;
-+
- 		/* setup auth context */
--		authctxt->pw = PRIVSEP(getpwnamallow(ssh, user));
-+		local_auth_pw = PRIVSEP(getpwnamallow(ssh, user));
- 		authctxt->user = xstrdup(user);
--		if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
-+		if (local_auth_pw && strcmp(service, "ssh-connection")==0) {
- 			authctxt->valid = 1;
- 			debug2_f("setting up authctxt for %s", user);
-+			local_auth_valid = 1;
-+		}
-+
-+		if (is_external_auth_on() && options.synconfig == 0) {
-+			if (get_array_user(array_user) != 0) {
-+				strcpy(array_user, EX_LOG_ON_MAPPED_USER);
-+			}
-+			ext_auth_pw = PRIVSEP(getpwnamallow(ssh, array_user));
-+			if (ext_auth_pw && strcmp(service, "ssh-connection")==0 &&
-+					strcmp(ext_user, "root") != 0) {
-+					ext_auth_valid = 1;
-+			}
-+			if(exauth_priority() == EXAUTH_PRIORITY_HIGH){
-+				if(ext_auth_valid){
-+					authctxt->pw = ext_auth_pw;
-+					authctxt->valid = 1;
-+					do_exauth = 1;
-+					debug2("input_userauth_request: setting up authctxt for "
-+						"the external mapped user %s", user);
-+#ifdef USE_PAM
-+					if (options.use_pam){
-+						PRIVSEP(start_pam(ssh));
-+					}
-+#endif
-+					exau_log("SSH 2: %s %d, the mapped user [%s] found",
-+						CLI_EXAUTH_ON,EXAUTH_PRIORITY_HIGH, array_user);
-+					} else {
-+						/*the mapped user not found or is not allowed to log in, use local auth*/
-+						if(local_auth_valid){
-+							authctxt->pw = local_auth_pw;
-+							authctxt->valid = 1;
-+							debug2("input_userauth_request: setting up authctxt for %s", user);
-+						} else {
-+							logit("input_userauth_request: illegal user %s", user);
-+							authctxt->pw = fakepw();
-+							exau_log("SSH 2: system user [%s] not found, %s %d, the mapped user [%s] NOT found",
-+								ext_user, CLI_EXAUTH_ON, EXAUTH_PRIORITY_HIGH, array_user);
-+						}
-+					}
-+				} else {
-+					/*exauth_priority is LOW
-+					*check local database first
-+					*/
-+					if(local_auth_valid){
-+						authctxt->pw = local_auth_pw;
-+						authctxt->valid = 1;
-+						debug2("input_userauth_request: setting up authctxt for %s", user);
-+					} else {
-+						if(ext_auth_valid){
-+							authctxt->pw = ext_auth_pw;
-+							authctxt->valid = 1;
-+							do_exauth = 1;
-+							debug2("input_userauth_request: setting up authctxt for "
-+								 "the external mapped user %s", user);
-+#ifdef USE_PAM
-+							if (options.use_pam){
-+								PRIVSEP(start_pam(ssh));
-+							}
-+#endif
-+							exau_log("SSH 2: system user [%s] not found, %s %d, the mapped user [%s] found",
-+								ext_user, CLI_EXAUTH_ON, EXAUTH_PRIORITY_LOW, array_user);
-+						} else {
-+							logit("input_userauth_request: illegal user %s", user);
-+							authctxt->pw = fakepw();
-+							exau_log("SSH 2: system user [%s] not found, %s %d, the mapped user [%s] NOT found",
-+								ext_user, CLI_EXAUTH_ON, EXAUTH_PRIORITY_LOW, array_user);
-+						}
-+					}
-+				}
- 		} else {
- 			authctxt->valid = 0;
--			/* Invalid user, fake password information */
--			authctxt->pw = fakepw();
-+			/*
-+			*exauth is off, use local auth
-+			*note: when exauth is off, if local auth failed, won't do external authentication
-+			*/
-+			if(local_auth_valid){
-+				authctxt->pw = local_auth_pw;
-+				authctxt->valid = 1;
-+				debug2("input_userauth_request: setting up authctxt for %s", user);
-+			} else {
-+				/* Invalid user, fake password information */
-+				authctxt->pw = fakepw();
- #ifdef SSH_AUDIT_EVENTS
--			PRIVSEP(audit_event(ssh, SSH_INVALID_USER));
-+				PRIVSEP(audit_event(ssh, SSH_INVALID_USER));
- #endif
-+			}
-		}
-+
- #ifdef USE_PAM
-@@ -330,2 +473,26 @@
-
-+	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);
-+
-+			/* 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 */
-@@ -348,2 +515,27 @@
-
-+/*
-+ * 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
-@@ -389,2 +581,3 @@
-	auth_log(ssh, authenticated, partial, method, submethod);
-+	defend_dos_attack();
-
-@@ -427,2 +620,16 @@
-			fatal_fr(r, "send success packet");
-+
-+		/* Log logout information for ArrayOS */
-+		array_auth_log(ssh, authenticated, method, " passed");
-+		/*Bug 21899, chenhb, 20090409*/
-+		array_send_addr_info(ssh);
-+		/*Bug 21899, end*/
-+
-+		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 */
-@@ -433,4 +640,35 @@
- 		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);
-+						array_auth_log(ssh, authenticated, method, " failed");
-+						array_send_addr_info(ssh);
-+						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) {
-@@ -450,2 +688,4 @@
-			fatal_fr(r, "send failure packet");
-+		array_auth_log(ssh, authenticated, method, " failed");
-+		array_send_addr_info(ssh);
-		free(methods);
-@@ -844 +1084,160 @@
-
-+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 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
-+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;
-+
-+	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;
-+}
-+
-+
-diff -ru1 openssh-9.3p2/configure openssh-9.3p2-patch/configure
---- openssh-9.3p2/configure	2023-07-19 14:32:53.000000000 +0800
-+++ openssh-9.3p2-patch/configure	2024-08-05 17:00:44.134383458 +0800
-@@ -869,3 +869,3 @@
- datadir='${datarootdir}'
--sysconfdir='${prefix}/etc'
-+sysconfdir='${prefix}/conf'
- sharedstatedir='${prefix}/com'
-diff -ru1 openssh-9.3p2/readconf.c openssh-9.3p2-patch/readconf.c
---- openssh-9.3p2/readconf.c	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/readconf.c	2024-08-05 17:00:44.134383458 +0800
-@@ -167,2 +167,3 @@
-	oLocalCommand, oPermitLocalCommand, oRemoteCommand,
-+	oPassword, oSync,
-	oVisualHostKey,
-@@ -296,2 +297,4 @@
-	{ "remotecommand", oRemoteCommand },
-+	{ "password", oPassword },
-+	{ "sync", oSync },
-	{ "visualhostkey", oVisualHostKey },
-@@ -1847,2 +1850,7 @@
-
-+	case oPassword:
-+	case oSync:
-+		charptr=&options->xpassword;
-+		goto parse_string;
-+
-	case oVisualHostKey:
-@@ -2440,2 +2448,4 @@
-	options->enable_escape_commandline = -1;
-+	options->xpassword = NULL;
-+	options->knownhost = 0;
- }
-diff -ru1 openssh-9.3p2/readconf.h openssh-9.3p2-patch/readconf.h
---- openssh-9.3p2/readconf.h	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/readconf.h	2024-08-05 17:00:44.134383458 +0800
-@@ -183,2 +183,4 @@
-	char	*ignored_unknown; /* Pattern list of unknown tokens to ignore */
-+	char    *xpassword;
-+	int     knownhost;
- }       Options;
-diff -ru1 openssh-9.3p2/servconf.c openssh-9.3p2-patch/servconf.c
---- openssh-9.3p2/servconf.c	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/servconf.c	2024-08-05 17:00:44.134383458 +0800
-@@ -200,2 +200,3 @@
-	options->unused_connection_timeout = -1;
-+	options->synconfig = 0;
- }
-@@ -455,3 +456,3 @@
-	if (use_privsep == -1)
--		use_privsep = PRIVSEP_ON;
-+		use_privsep = PRIVSEP_OFF;
-
-@@ -507,3 +508,3 @@
-	sKerberosGetAFSToken, sPasswordAuthentication,
--	sKbdInteractiveAuthentication, sListenAddress, sAddressFamily,
-+	sKbdInteractiveAuthentication, sListenAddress, sListenSyncAddress, sListenSdnsAddress, sAddressFamily,
-	sPrintMotd, sPrintLastLog, sIgnoreRhosts,
-@@ -615,2 +616,4 @@
-	{ "listenaddress", sListenAddress, SSHCFG_GLOBAL },
-+	{ "listensyncaddress", sListenSyncAddress, SSHCFG_GLOBAL },
-+	{ "listensdnsaddress", sListenSdnsAddress, SSHCFG_GLOBAL },
-	{ "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
-@@ -1440,2 +1443,4 @@
-	case sListenAddress:
-+	case sListenSdnsAddress:
-+	case sListenSyncAddress:
-		arg = argv_next(&ac, &av);
-diff -ru1 openssh-9.3p2/servconf.h openssh-9.3p2-patch/servconf.h
---- openssh-9.3p2/servconf.h	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/servconf.h	2024-08-05 17:00:44.134383458 +0800
-@@ -237,2 +237,3 @@
-	int	unused_connection_timeout;
-+	int     synconfig;
- }       ServerOptions;
-diff -ru1 openssh-9.3p2/serverloop.c openssh-9.3p2-patch/serverloop.c
---- openssh-9.3p2/serverloop.c	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/serverloop.c	2024-08-05 17:00:44.134383458 +0800
-@@ -793,3 +793,3 @@
-		    !auth_opts->permit_port_forwarding_flag ||
--		    options.disable_forwarding ||
-+			options.disable_forwarding || !use_privsep ||
-		    (!want_reply && fwd.listen_port == 0) ||
-diff -ru1 openssh-9.3p2/session.c openssh-9.3p2-patch/session.c
---- openssh-9.3p2/session.c	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/session.c	2024-08-05 17:00:44.134383458 +0800
-@@ -105,2 +105,8 @@
-
-+#if defined(__linux__)
-+#include <uinet_api.h>
-+#endif
-+#include <click/netinet6/click6_utils.h>
-+
-+
- #define IS_INTERNAL_SFTP(c) \
-@@ -168,2 +174,30 @@
-
-+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 */
-@@ -706,2 +740,8 @@
-
-+#ifndef DEBUG
-+		if (arrayos_command_verify(s->pw->pw_name, command) == -1)
-+			fatal("Login failed.");
-+#endif
-+
-+
- #ifdef SSH_AUDIT_EVENTS
-@@ -1023,3 +1063,12 @@
-	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
-@@ -1571,2 +1620,7 @@
-
-+	/* XXX sync use /bin/sh, discard /etc/passwd */
-+	if (strcmp(pw->pw_name, "ansync") == 0) {
-+	        shell = _PATH_BSHELL;
-+	}
-+
-	/*
-diff -ru1 openssh-9.3p2/ssh.c openssh-9.3p2-patch/ssh.c
---- openssh-9.3p2/ssh.c	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/ssh.c	2024-08-05 17:00:44.134383458 +0800
-@@ -175,2 +175,5 @@
-
-+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. */
-@@ -710,3 +713,3 @@
- 	while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx"
--	    "AB:CD:E:F:GI:J:KL:MNO:PQ: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) {
-@@ -839,2 +842,5 @@
- 			break;
-+		case 'H':
-+			options.knownhost = 1;
-+			break;
- 		case 'i':
-@@ -1681,4 +1687,9 @@
- 	/* 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);
-+	}
-+
-
-diff -ru1 openssh-9.3p2/sshconnect.c openssh-9.3p2-patch/sshconnect.c
---- openssh-9.3p2/sshconnect.c	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/sshconnect.c	2024-08-05 17:00:44.134383458 +0800
-@@ -71,2 +71,4 @@
-
-+#include "cipher.h"
-+
- struct sshkey *previous_host_key = NULL;
-@@ -1092,2 +1094,4 @@
-				    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,
-@@ -1193,3 +1197,5 @@
- 		 */
--		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);
-@@ -1214,3 +1220,5 @@
-
--		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 "
-@@ -1578,3 +1586,3 @@
- 	ssh_kex2(ssh, host, hostaddr, port, cinfo);
--	ssh_userauth2(ssh, local_user, server_user, host, sensitive);
-+	ssh_userauth2(ssh, local_user, server_user, host, sensitive, NULL);
- 	free(local_user);
-@@ -1582,2 +1590,28 @@
- }
-+
-+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;
-+}
-
-diff -ru1 openssh-9.3p2/sshconnect.h openssh-9.3p2-patch/sshconnect.h
---- openssh-9.3p2/sshconnect.h	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/sshconnect.h	2024-08-05 17:00:44.134383458 +0800
-@@ -84,3 +84,3 @@
- void	 ssh_userauth2(struct ssh *ssh, const char *, const char *,
--    char *, Sensitive *);
-+    char *, Sensitive *, char *);
-
-diff -ru1 openssh-9.3p2/sshconnect2.c openssh-9.3p2-patch/sshconnect2.c
---- openssh-9.3p2/sshconnect2.c	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/sshconnect2.c	2024-08-05 17:00:44.134383458 +0800
-@@ -349,2 +349,3 @@
-	void *methoddata;
-+	char *password;
- };
-@@ -397,2 +398,12 @@
- Authmethod authmethods[] = {
-+	{"publickey",
-+		userauth_pubkey,
-+		NULL,
-+		&options.pubkey_authentication,
-+		NULL},
-+	{"password",
-+		userauth_passwd,
-+		NULL,
-+		&options.password_authentication,
-+		&options.batch_mode},
- #ifdef GSSAPI
-@@ -409,7 +420,2 @@
- 		NULL},
--	{"publickey",
--		userauth_pubkey,
--		NULL,
--		&options.pubkey_authentication,
--		NULL},
- 	{"keyboard-interactive",
-@@ -419,7 +425,2 @@
- 		&options.batch_mode},
--	{"password",
--		userauth_passwd,
--		NULL,
--		&options.password_authentication,
--		&options.batch_mode},
- 	{"none",
-@@ -434,3 +435,3 @@
- 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)
- {
-@@ -462,2 +463,4 @@
- 	authctxt.agent_fd = -1;
-+	authctxt.password = pass ? pass : NULL;
-+
- 	pubkey_prepare(ssh, &authctxt);
-@@ -550,4 +553,3 @@
-		if (method == NULL)
--			fatal("%s@%s: Permission denied (%s).",
--			    authctxt->server_user, authctxt->host, authlist);
-+			fatal("Permission denied.");
-		authctxt->method = method;
-@@ -1056,4 +1058,9 @@
-
--	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 ||
-@@ -1068,3 +1075,4 @@
-
--	free(prompt);
-+	if(prompt)
-+		free(prompt);
-	if (password != NULL)
-diff -ru1 openssh-9.3p2/sshd.c openssh-9.3p2-patch/sshd.c
---- openssh-9.3p2/sshd.c	2023-07-19 14:31:34.000000000 +0800
-+++ openssh-9.3p2-patch/sshd.c	2024-08-05 17:02:40.384342193 +0800
-@@ -130,2 +130,17 @@
-
-+#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/app/fastlog/fastlog.h"
-+#include "click/app/fastlog/logex_def.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 */
-@@ -136,2 +151,17 @@
-
-+#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;
-+
- extern char *__progname;
-@@ -206,2 +236,25 @@
-
-+/*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. */
-@@ -266,2 +319,44 @@
-
-+/* 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) {
-+               fastlog_logex(SSHD_LOGIN_GETPID, 0);
-+       }
-+       if ((msg_key = ftok(SSHD_LOGIN_MSGQ_PATH, 0x02)) == -1) {
-+               fastlog_logex(SSHD_LOGIN_MSG_FTOK, 0);
-+       }
-+
-+bingo:
-+       if ((msg_id = msgget(msg_key, 0))== -1) {
-+               if (errno == EINTR) {
-+                       goto bingo;
-+               } else {
-+                       fastlog_logex(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;
-+		} else {
-+			fastlog_logex(SSHD_LOGIN_MSG_RCV, 0);
-+		}
-+	}
-+
-+	/* fastlog the sshd logout info */
-+	fastlog_logex(AUTH_SSH_LOGOUT, 5,
-+                     authctxt->user,
-+                     ssh_remote_ipaddr(ssh),
-+                     ssh_remote_port(ssh),
-+                     ssh_local_ipaddr(ssh),
-+		     ssh_local_port(ssh));
-+}
-+
- /*
-@@ -1110,2 +1205,121 @@
-
-+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;
-+}
-+
-+
-+
- /*
-@@ -1128,2 +1342,11 @@
-
-+	/*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 */
-@@ -1256,2 +1479,11 @@
- 			}
-+
-+			if (options.synconfig == 0 && !is_permit_source((struct sockaddr *)&from)) {
-+				printf("deny connection #%d", startups);
-+				close(*newsock);
-+				close(startup_p[0]);
-+				close(startup_p[1]);
-+				continue;
-+			}
-+
-			if (unset_nonblock(*newsock) == -1) {
-@@ -1510,2 +1742,130 @@
-
-+#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);
-+}
-+
-+
- static char *
-@@ -1593,3 +1953,3 @@
-	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) {
-@@ -1633,2 +1993,5 @@
-			break;
-+		case 's':
-+			options.synconfig = 1;
-+			break;
-		case 'R':
-@@ -1731,2 +2094,8 @@
-
-+	/*fastlog init need shm memory*/
-+	if (uhi_shared_mem_attach() != 0) {
-+		debug("uhi_shared_mem_attach() failed. ");
-+		exit(1);
-+	}
-+
-	/*
-@@ -2287,2 +2656,10 @@
-
-+#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
-@@ -2335,2 +2712,6 @@
-
-+	/* Log the logout informantion */
-+	sshd_logout_info_detatch(ssh, authctxt);
-+
-+
- #ifdef SSH_AUDIT_EVENTS
Index: /branches/rel_apv_10_7/usr/click/bin/openssh/build.sh
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/openssh/build.sh	(revision 38749)
+++ /branches/rel_apv_10_7/usr/click/bin/openssh/build.sh	(working copy)
@@ -1,34 +1,34 @@
 #!/usr/bin/env bash
 
-if [ ! -d openssh-9.3p2 ]
+if [ ! -d openssh-9.9p1 ]
 then
-	if [ -f openssh-9.3p2.tar.gz ]
+	if [ -f openssh-9.9p1.tar.gz ]
 	then
-		tar -zxvf openssh-9.3p2.tar.gz
-		cd openssh-9.3p2
+		tar -zxvf openssh-9.9p1.tar.gz
+		cd openssh-9.9p1
 	else
 		echo "source tar.gz file not exist!"
 		exit 1
 	fi
 else
-	cd openssh-9.3p2
+	cd openssh-9.9p1
 fi
 
 if [ Makefile -nt configure ]
 then 
 	echo "Configure have been done!"
 else
-	patch -p1 < ../array_patch
-	patch -p0 < ../weak_mac.patch
-	patch -p0 < ../CVE-2023-48795-mitigation.patch
-	patch -p0 < ../log_user_login_failure.patch
+	patch -p1 < ../array.patch
+	patch -p1 < ../weak_mac.patch
+	patch -p1 < ../CVE-2023-48795-mitigation.patch
 	if [ $? -ne 0 ]
 	then
 		echo "array_patch failed!"
 		exit 1
 	fi
 
-	./configure --prefix=/ca CC='gcc' CFLAGS='-g -idirafter ../../../../src/sys -idirafter ../../../../../src/sys -idirafter ../../../lib/libuinet-atcp/lib/libuinet/api_include -idirafter ../../../lib/libexauth' --with-sandbox=no
+	export LD_LIBRARY_PATH=../../../lib/libopenssl-1.1.1:$LD_LIBRARY_PATH
+	./configure --with-ssl-dir=../../../lib/libopenssl-1.1.1 --prefix=/ca --with-sandbox=no CC='gcc' LDFLAGS='-Wl,-rpath=/ca/lib' CFLAGS='-g -idirafter ../../../../src/sys -idirafter ../../../../../src/sys -idirafter ../../../lib/libuinet-atcp/lib/libuinet/api_include -idirafter ../../../lib/libexauth'
 	if [ $? -ne 0 ]
 	then
 		echo "Configure failed!"
Index: /branches/rel_apv_10_7/usr/click/bin/openssh/log_user_login_failure.patch
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/openssh/log_user_login_failure.patch	(revision 38749)
+++ /branches/rel_apv_10_7/usr/click/bin/openssh/log_user_login_failure.patch	(working copy)
@@ -1,57 +0,0 @@
---- auth2.c	2024-09-17 23:13:42.913486717 -0400
-+++ auth2-patch.c	2024-09-17 23:15:44.157798683 -0400
-@@ -68,6 +68,8 @@
- #include "../../ui/exauth/auth_ext_ipc.h"
- #endif
- 
-+#include "click/app/fastlog/fastlog_var.h"
-+
- #include <sys/ipc.h>
- #include <sys/shm.h>
- #include <sys/time.h>
-@@ -487,6 +489,8 @@
- 			bzero(&tv, sizeof(tv));
- 			gettimeofday(&tv, NULL);
- 
-+			fastlog_logex(AUTH_USER_LOCK, 3, 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",
-@@ -547,6 +551,7 @@
- 	const char *method = packet_method;
- 	char *methods;
- 	int r, partial = 0;
-+	char info[256] = {0};
- 
- 	if (authenticated) {
- 		if (!authctxt->valid) {
-@@ -653,7 +658,8 @@
- 						methods = authmethods_get(authctxt);
- 						debug3("%s: failure partial=%d next methods=\"%s\"", __func__,
- 							partial, methods);
--						array_auth_log(ssh, authenticated, method, " failed");
-+						snprintf(info, sizeof(info), " failed, incorrect %s login", method);
-+						array_auth_log(ssh, authenticated, method, info);
- 						array_send_addr_info(ssh);
- 						free(methods);
- 
-@@ -686,7 +692,8 @@
- 		    (r = sshpkt_send(ssh)) != 0 ||
- 		    (r = ssh_packet_write_wait(ssh)) != 0)
- 			fatal_fr(r, "send failure packet");
--		array_auth_log(ssh, authenticated, method, " failed");
-+		snprintf(info, sizeof(info), " failed, incorrect %s login", method);
-+		array_auth_log(ssh, authenticated, method, info);
- 		array_send_addr_info(ssh);
- 		free(methods);
- 	}
-@@ -1233,6 +1240,8 @@
- 	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;
- 
-+	fastlog_logex(AUTH_USER_LOCK, 3, p->user[index].name, user_login_p->max_login_retry, (uint32_t)(p->user[index].next_login_time - tv.tv_sec));
-+
- 	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));
Index: /branches/rel_apv_10_7/usr/click/bin/openssh/openssh-9.3p2.tar.gz
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Index: /branches/rel_apv_10_7/usr/click/bin/openssh/openssh-9.9p1.tar.gz
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/x-gzip
Index: /branches/rel_apv_10_7/usr/click/bin/openssh/openssh-9.9p1.tar.gz
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/openssh/openssh-9.9p1.tar.gz	(revision 0)
+++ /branches/rel_apv_10_7/usr/click/bin/openssh/openssh-9.9p1.tar.gz	(working copy)

Property changes on: usr/click/bin/openssh/openssh-9.9p1.tar.gz
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/x-gzip
\ No newline at end of property
Index: /branches/rel_apv_10_7/usr/click/bin/openssh/weak_mac.patch
===================================================================
--- /branches/rel_apv_10_7/usr/click/bin/openssh/weak_mac.patch	(revision 38749)
+++ /branches/rel_apv_10_7/usr/click/bin/openssh/weak_mac.patch	(working copy)
@@ -1,6 +1,8 @@
---- myproposal.h	2021-09-26 22:03:19.000000000 +0800
-+++ myproposal_edit.h	2024-05-13 09:51:39.203280773 +0800
-@@ -63,16 +63,12 @@
+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 \
Index: /branches/rel_apv_10_7/usr/click/lib/libexauth/Makefile
===================================================================
--- /branches/rel_apv_10_7/usr/click/lib/libexauth/Makefile	(revision 38749)
+++ /branches/rel_apv_10_7/usr/click/lib/libexauth/Makefile	(working copy)
@@ -6,13 +6,15 @@
 
 CFLAGS+=-I${.CURDIR} \
 	-I${.CURDIR}/../../lib/libfastlog \
-        -I${.CURDIR}/../../lib/libbsd
+        -I${.CURDIR}/../../lib/libbsd \
+        -I${.OBJDIR}/../../lib/libopenssl-1.1.1/include
 
 .if defined(USTACK)
 CFLAGS += -fPIC
 .endif
 
 LDADD=-L${.OBJDIR}/../../lib/libbsd -lbsd \
-      -lmd -lcrypt -lcrypto -lpthread -lldap -llber -lssl -lcrypto -lhiredis -lutil
+      -lmd -lcrypt -lcrypto -lpthread -lldap -llber -lhiredis -lutil \
+      -L${.OBJDIR}/../../lib/libopenssl-1.1.1 -lcrypto-tls13 -lssl-tls13 
 
 .include <bsd.libauth.mk>
Index: /branches/rel_apv_10_7/usr/click/lib/libexauth/auth_ext.c
===================================================================
--- /branches/rel_apv_10_7/usr/click/lib/libexauth/auth_ext.c	(revision 38749)
+++ /branches/rel_apv_10_7/usr/click/lib/libexauth/auth_ext.c	(working copy)
@@ -35,6 +35,7 @@
 #include <ldap.h>
 #include <openssl/ssl.h>
 #include <openssl/err.h>
+#include <openssl/opensslv.h>
 
 #include "auth_ext.h"
 #include "auth_ext_cli.h"
@@ -49,6 +50,7 @@
 #define LDAPS_CLIENT_CERT_FILE        "/ca/ssl/vhost/ldaps_client_cert.pem"
 #define LDAPS_CLIENT_KEY_FILE         "/ca/ssl/vhost/ldaps_client_key.pem"
 #define LDAPS_ROOTCA_FILE             "/ca/ssl/vhost/ldaps_root_cert.pem"
+
 /*if really do external authentication*/
 int do_exauth = 0;
 
@@ -248,11 +250,13 @@
 
     sprintf(ldap_uri,"ldaps://%s:%d",g_exauth_conf.exauth_servers[i].host,
                                    g_exauth_conf.exauth_servers[i].port);
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
     // Initialize OpenSSL
     SSL_library_init();
     ERR_load_BIO_strings();
     OpenSSL_add_all_algorithms();
     SSL_load_error_strings();
+#endif
     exau_log("ldap_uri %s\n", ldap_uri);
     // Initialize LDAP connection
     rc = ldap_initialize(&ld, ldap_uri);
@@ -373,9 +377,11 @@
     }
     ldap_msgfree(answer);
     ldap_unbind(ld);
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
     ERR_free_strings();
     EVP_cleanup();
     CRYPTO_cleanup_all_ex_data();
+#endif
     return ret_value;
 }
 
@@ -1034,7 +1040,6 @@
 	strlcpy(ext_user, user, sizeof(ext_user));
 }
 
-
 /*copy the client IP to ext_ssh_client_IP*/
 void
 set_ext_ip(char *ip)
@@ -1243,5 +1248,4 @@
 	}
 
 	return method;
-}
-
+}
\ No newline at end of file
Index: /branches/rel_apv_10_7/usr/click/lib/libopenssl-1.1.1/build.sh
===================================================================
--- /branches/rel_apv_10_7/usr/click/lib/libopenssl-1.1.1/build.sh	(revision 38749)
+++ /branches/rel_apv_10_7/usr/click/lib/libopenssl-1.1.1/build.sh	(working copy)
@@ -59,7 +59,7 @@
 	exit 0
 else
 	echo "Start to configure openssl"
-	./config -d enable-ssl3 enable-ssl3-method enable-weak-ssl-ciphers
+	./config -fPIC -d enable-ssl3 enable-ssl3-method enable-weak-ssl-ciphers
 	if [ $? -ne 0 ]
 	then
 		echo "Configure openssl failed!"
@@ -82,8 +82,8 @@
 cp -rf ${OPENSSL_NAME}/e_os.h include/openssl/
 find ${OPENSSL_NAME}/crypto -name "*.h" -exec cp -f {} include/openssl/internal/ \;
 find ${OPENSSL_NAME}/ssl -name "*.h" -exec cp -f {} include/openssl/internal/ \;
-cp -f ${OPENSSL_NAME}/libcrypto.so.1.1 ./
-cp -f ${OPENSSL_NAME}/libssl.so.1.1 ./
+cp -f ${OPENSSL_NAME}/libcrypto.so* ./
+cp -f ${OPENSSL_NAME}/libssl.so* ./
 cp -f ${OPENSSL_NAME}/apps/openssl ./
 ln -sf libcrypto.so.1.1 libcrypto-tls13.so
 ln -sf libssl.so.1.1 libssl-tls13.so
