Is there any way to hook the point when channel port listener accepts a new connection?

yingyuan cheng yingyuan.cheng at gmail.com
Sun Mar 14 19:48:10 EST 2010


I think one system account for hundreds of virtual users maybe useful,
so I made some modifications to source code, now it seems working. To
setup it up, add the following line to your sshd_config:

AuthUserFile /path/to/virtual/user/file

Then in the file /path/to/virtual/user/file, add your favorite users:

virtual_username_1:sys_username_1:md5_hashed_password
virtual_username_2:sys_username_1:md5_hashed_password
virtual_username_3:sys_username_1:md5_hashed_password
...

What about my idea?


2010/1/22 Alex Bligh <alex at alex.org.uk>:
> I think the easiest way to do this is to give them all the same
> system account (UID), but to give them all different public


My modifications:

diff -ru openssh-5.3p1/auth-passwd.c openssh-5.3p1.new/auth-passwd.c
--- openssh-5.3p1/auth-passwd.c	2009-03-08 08:40:28.000000000 +0800
+++ openssh-5.3p1.new/auth-passwd.c	2010-03-14 14:51:09.000000000 +0800
@@ -44,6 +44,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdarg.h>
+#include <openssl/md5.h>

 #include "packet.h"
 #include "buffer.h"
@@ -86,6 +87,21 @@
 	static int expire_checked = 0;
 #endif

+	if (authctxt->ruser) { /* auth from user file */
+		const char *hexes = "0123456789abcdef";
+		unsigned char digest[16];
+		char md5str[32];
+		int i;
+
+		MD5(password, strlen(password), digest);
+		for (i = 0; i < 16; i++) {
+			md5str[2*i] = hexes[digest[i]>>4];
+			md5str[2*i+1] = hexes[digest[i]&0xF];
+		}
+		md5str[2*i] = '\0';
+		return (0 == strcmp(md5str, pw->pw_passwd));
+	}
+
 #ifndef HAVE_CYGWIN
 	if (pw->pw_uid == 0 && options.permit_root_login != PERMIT_YES)
 		ok = 0;
diff -ru openssh-5.3p1/auth.c openssh-5.3p1.new/auth.c
--- openssh-5.3p1/auth.c	2008-11-05 13:12:54.000000000 +0800
+++ openssh-5.3p1.new/auth.c	2010-03-14 13:13:18.000000000 +0800
@@ -81,6 +81,8 @@
 Buffer auth_debug;
 int auth_debug_init;

+static struct passwd* getpwnam_from_file(const char *user, const char *file);
+
 /*
  * Check if the user is allowed to log in via ssh. If user is listed
  * in DenyUsers or one of user's groups is listed in DenyGroups, false
@@ -526,6 +528,8 @@
 	    get_canonical_hostname(options.use_dns), get_remote_ipaddr());

 	pw = getpwnam(user);
+	if (pw == NULL && options.auth_user_file)
+		pw = getpwnam_from_file(user, options.auth_user_file);
 	if (pw == NULL) {
 		logit("Invalid user %.100s from %.100s",
 		    user, get_remote_ipaddr());
@@ -620,3 +624,55 @@

 	return (&fake);
 }
+
+static struct passwd* getpwnam_from_file(const char *user, const char *file)
+{
+#define LINELEN	1024
+	char line[LINELEN];
+	char *u, *ru, *p, *ptr;
+	int s, lineno;
+	FILE *fp;
+	struct passwd *pw = NULL;
+
+	if ((fp = fopen(file, "rb")) == NULL) {
+		logit("cannot open auth user file '%s'", file);
+		return 0;
+	}
+	s = strlen(user);
+	lineno = 0;
+	while (fgets(line, LINELEN, fp)) {
+		lineno++;
+
+		/* ruser:user:passwd */
+		ru = line;
+		while (*ru && isspace(*ru)) ru++;
+		if (0 == strncmp(ru,user,s) && *(ru+s) == ':')
+		{
+			u = ru + s;
+			*u++ = '\0';
+			p = u;
+			while (*p && *p!=':') p++;
+			if (*p != ':') {
+				logit("cannot get user delim in '%s' line %d",file,lineno);
+				break;
+			}
+			*p++ = '\0';
+			ptr = p;
+			while (*ptr && !isspace(*ptr)) ptr++;
+			*ptr = '\0';
+
+			pw = getpwnam(u);
+			if (!pw) {
+				logit("cannot get pw of user '%s'", u);
+				break;
+			}
+			debug("ruser '%s',user '%s',passwd '%s'", ru, u, p);
+			break;
+		}
+	}
+	fclose(fp);
+	if (pw) {
+		pw->pw_passwd = xstrdup(p);
+	}
+	return pw;
+}
diff -ru openssh-5.3p1/auth.h openssh-5.3p1.new/auth.h
--- openssh-5.3p1/auth.h	2008-11-05 13:20:46.000000000 +0800
+++ openssh-5.3p1.new/auth.h	2010-03-13 12:30:07.000000000 +0800
@@ -55,6 +55,7 @@
 	int		 failures;
 	int		 force_pwchange;
 	char		*user;		/* username sent by the client */
+	char        *ruser;     /* real username */
 	char		*service;
 	struct passwd	*pw;		/* set if 'valid' */
 	char		*style;
diff -ru openssh-5.3p1/auth2.c openssh-5.3p1.new/auth2.c
--- openssh-5.3p1/auth2.c	2009-06-22 14:11:07.000000000 +0800
+++ openssh-5.3p1.new/auth2.c	2010-03-14 13:05:59.000000000 +0800
@@ -233,7 +233,13 @@
 	if (authctxt->attempt++ == 0) {
 		/* setup auth context */
 		authctxt->pw = PRIVSEP(getpwnamallow(user));
-		authctxt->user = xstrdup(user);
+		if (authctxt->pw && 0 != strcmp(user, authctxt->pw->pw_name)) {
+			authctxt->user = xstrdup(authctxt->pw->pw_name);
+			authctxt->ruser = xstrdup(user);
+		} else {
+			authctxt->user = xstrdup(user);
+		}
+
 		if (authctxt->pw && strcmp(service, "ssh-connection")==0) {
 			authctxt->valid = 1;
 			debug2("input_userauth_request: setting up authctxt for %s", user);
@@ -255,7 +261,8 @@
 		if (use_privsep)
 			mm_inform_authserv(service, style);
 		userauth_banner();
-	} else if (strcmp(user, authctxt->user) != 0 ||
+	} else if ((strcmp(user, authctxt->user) != 0 && authctxt->ruser &&
+		strcmp(user, authctxt->ruser) != 0) ||
 	    strcmp(service, authctxt->service) != 0) {
 		packet_disconnect("Change of username or service not allowed: "
 		    "(%s,%s) -> (%s,%s)",
@@ -279,6 +286,7 @@
 	m = authmethod_lookup(method);
 	if (m != NULL && authctxt->failures < options.max_authtries) {
 		debug2("input_userauth_request: try method %s", method);
+		debug2("pw %s", authctxt->pw->pw_passwd);
 		authenticated =	m->userauth(authctxt);
 	}
 	userauth_finish(authctxt, authenticated, method);
@@ -404,4 +412,3 @@
 	    name ? name : "NULL");
 	return NULL;
 }
-
diff -ru openssh-5.3p1/monitor.c openssh-5.3p1.new/monitor.c
--- openssh-5.3p1/monitor.c	2009-06-21 16:58:46.000000000 +0800
+++ openssh-5.3p1.new/monitor.c	2010-03-14 12:58:37.000000000 +0800
@@ -641,8 +641,13 @@
 	username = buffer_get_string(m, NULL);

 	pwent = getpwnamallow(username);
+	if (pwent && 0 != strcmp(username,pwent->pw_name)) {
+		authctxt->user = xstrdup(pwent->pw_name);
+		authctxt->ruser = xstrdup(username);
+	} else {
+		authctxt->user = xstrdup(username);
+	}

-	authctxt->user = xstrdup(username);
 	setproctitle("%s [priv]", pwent ? username : "unknown");
 	xfree(username);

diff -ru openssh-5.3p1/servconf.c openssh-5.3p1.new/servconf.c
--- openssh-5.3p1/servconf.c	2009-06-21 18:26:17.000000000 +0800
+++ openssh-5.3p1.new/servconf.c	2010-03-14 09:09:18.000000000 +0800
@@ -60,6 +60,7 @@
 	options->use_pam = -1;

 	/* Standard Options */
+	options->auth_user_file = NULL;
 	options->num_ports = 0;
 	options->ports_from_cmdline = 0;
 	options->listen_addrs = NULL;
@@ -283,6 +284,7 @@
 	/* Portable-specific options */
 	sUsePAM,
 	/* Standard Options */
+	sAuthUserFile,
 	sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
 	sPermitRootLogin, sLogFacility, sLogLevel,
 	sRhostsRSAAuthentication, sRSAAuthentication,
@@ -327,6 +329,7 @@
 #endif
 	{ "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
 	/* Standard Options */
+	{ "authuserfile", sAuthUserFile, SSHCFG_GLOBAL },
 	{ "port", sPort, SSHCFG_GLOBAL },
 	{ "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
 	{ "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },		/* alias */
@@ -684,6 +687,11 @@
 	/* Standard Options */
 	case sBadOption:
 		return -1;
+
+	case sAuthUserFile:
+		charptr = &options->auth_user_file;
+		goto parse_filename;
+
 	case sPort:
 		/* ignore ports from configfile if cmdline specifies ports */
 		if (options->ports_from_cmdline)
diff -ru openssh-5.3p1/servconf.h openssh-5.3p1.new/servconf.h
--- openssh-5.3p1/servconf.h	2009-01-28 13:31:23.000000000 +0800
+++ openssh-5.3p1.new/servconf.h	2010-03-13 12:36:11.000000000 +0800
@@ -151,6 +151,9 @@
 	int	num_permitted_opens;

 	char   *chroot_directory;
+
+	char *auth_user_file;
+
 }       ServerOptions;

 void	 initialize_server_options(ServerOptions *);
diff -ru openssh-5.3p1/sshd.c openssh-5.3p1.new/sshd.c
--- openssh-5.3p1/sshd.c	2009-06-21 18:26:17.000000000 +0800
+++ openssh-5.3p1.new/sshd.c	2010-03-14 11:43:26.000000000 +0800
@@ -1728,6 +1728,7 @@
 		if (startup_pipe != -1)
 			close(startup_pipe);

+		debug("rexec '%s'", rexec_argv[0]);
 		execv(rexec_argv[0], rexec_argv);

 		/* Reexec has failed, fall back and continue */


More information about the openssh-unix-dev mailing list