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