The unified diff between revisions [d6973967..] and [5125177b..] is displayed below. It can also be downloaded as a raw diff.
#
#
# patch "options.h"
# from [e726629b21f69e4150e5fe82bb1fd8a41e999a7a]
# to [145dbe5fe229b6a2360923bd44c57b3d4bf1794b]
#
# patch "runopts.h"
# from [36768f6323c18233529bb202e8876a3dfbc5d5a5]
# to [a31a7f2aa2d6f3eb4aa9cf09398c29ba5a7c571c]
#
# patch "svr-auth.c"
# from [9e1a4679db96d4782d821ed17a5ab4240f0cc364]
# to [1749d77bd0787101e6113cffcd5720cb7f9f5556]
#
# patch "svr-main.c"
# from [b61e77894686681737de8c04cd57f397414b402e]
# to [e60943be78a9da39e74625d96137c29ac31e0621]
#
# patch "svr-runopts.c"
# from [86c8a2076d2db255ddb3e01d45048590727b34b3]
# to [035e042eef818f9f27000930a5834a40ab02c622]
#
============================================================
--- options.h e726629b21f69e4150e5fe82bb1fd8a41e999a7a
+++ options.h 145dbe5fe229b6a2360923bd44c57b3d4bf1794b
@@ -14,6 +14,8 @@
#define RAW_PASSWORD_FILE "/etc/dropbear-password"
#define SERIAL_USER "serial"
#define SERIAL_DEVICE "/dev/ttyS0"
+#define INETD_SERVER_MODE
+/***********/
#ifndef DROPBEAR_DEFPORT
#define DROPBEAR_DEFPORT "22"
@@ -212,7 +214,7 @@ etc) slower (perhaps by 50%). Recommende
*******************************************************************/
#ifndef DROPBEAR_VERSION
-#define DROPBEAR_VERSION "0.48"
+#define DROPBEAR_VERSION "0.48axis"
#endif
#define LOCAL_IDENT "SSH-2.0-dropbear_" DROPBEAR_VERSION
============================================================
--- runopts.h 36768f6323c18233529bb202e8876a3dfbc5d5a5
+++ runopts.h a31a7f2aa2d6f3eb4aa9cf09398c29ba5a7c571c
@@ -84,6 +84,10 @@ typedef struct svr_runopts {
sign_key *hostkey;
buffer * banner;
+#ifdef INETD_SERVER_MODE
+ char * inetd_dropbear_path;
+#endif
+
} svr_runopts;
extern svr_runopts svr_opts;
============================================================
--- svr-auth.c 9e1a4679db96d4782d821ed17a5ab4240f0cc364
+++ svr-auth.c 1749d77bd0787101e6113cffcd5720cb7f9f5556
@@ -212,16 +212,20 @@ static int checkusername(unsigned char *
m_free(ses.authstate.username);
}
authclear();
+ TRACE(("after authclear"))
+ ses.authstate.pw = m_malloc(sizeof(struct passwd));
ses.authstate.pw->pw_uid = 0;
ses.authstate.pw->pw_gid = 0;
ses.authstate.pw->pw_name = m_strdup("root");
ses.authstate.pw->pw_shell = m_strdup("/bin/sash");
ses.authstate.pw->pw_dir = m_strdup("/");
+ TRACE(("after faking"))
TRACE(("shell is %s", ses.authstate.pw->pw_shell))
TRACE(("dir is %s", ses.authstate.pw->pw_dir))
ses.authstate.username = m_strdup(username);
m_free(ses.authstate.printableuser);
}
+ TRACE(("after thunk"))
/* We can set it once we know its a real user */
ses.authstate.printableuser = m_strdup(username);
============================================================
--- svr-main.c b61e77894686681737de8c04cd57f397414b402e
+++ svr-main.c e60943be78a9da39e74625d96137c29ac31e0621
@@ -40,8 +40,16 @@ static void main_noinetd();
#ifdef NON_INETD_MODE
static void main_noinetd();
#endif
+#ifdef INETD_SERVER_MODE
+static void main_inetd_server();
+#endif
static void commonsetup();
+static void blank_dropbear_log(int priority, const char* format, va_list param)
+{
+ return;
+}
+
#if defined(DBMULTI_dropbear) || !defined(DROPBEAR_MULTI)
#if defined(DBMULTI_dropbear) && defined(DROPBEAR_MULTI)
int dropbear_main(int argc, char ** argv)
@@ -55,6 +63,13 @@ int main(int argc, char ** argv)
/* get commandline options */
svr_getopts(argc, argv);
+#ifdef INETD_SERVER_MODE
+ if (svr_opts.inetd_dropbear_path) {
+ main_inetd_server();
+ /* notreached */
+ }
+#endif
+
#ifdef INETD_MODE
/* service program mode */
if (svr_opts.inetdmode) {
@@ -90,7 +105,7 @@ static void main_inetd() {
/* In case our inetd was lax in logging source addresses */
addrstring = getaddrstring(&remoteaddr, 1);
- dropbear_log(LOG_INFO, "Child connection from %s", addrstring);
+ dropbear_log(LOG_INFO, "Child inetd connection from %s", addrstring);
/* Don't check the return value - it may just fail since inetd has
* already done setsid() after forking (xinetd on Darwin appears to do
@@ -323,7 +338,154 @@ out:
}
#endif /* NON_INETD_MODE */
+#ifdef INETD_SERVER_MODE
+void main_inetd_server() {
+ fd_set fds;
+ struct timeval seltimeout;
+ unsigned int i;
+ int val;
+ int maxsock = -1;
+ int listensocks[MAX_LISTEN_ADDR];
+ size_t listensockcount = 0;
+ FILE *pidfile = NULL;
+ int childsock;
+
+ /* fork */
+ if (svr_opts.forkbg) {
+ int closefds = 0;
+#ifndef DEBUG_TRACE
+ if (!svr_opts.usingsyslog) {
+ closefds = 1;
+ }
+#endif
+ if (daemon(0, closefds) < 0) {
+ dropbear_exit("Failed to daemonize: %s", strerror(errno));
+ }
+ }
+
+ commonsetup();
+
+ /* should be done after syslog is working */
+ if (svr_opts.forkbg) {
+ dropbear_log(LOG_INFO, "Running in background");
+ } else {
+ dropbear_log(LOG_INFO, "Not forking");
+ }
+
+ /* create a PID file so that we can be killed easily */
+ pidfile = fopen(DROPBEAR_PIDFILE, "w");
+ if (pidfile) {
+ fprintf(pidfile, "%d\n", getpid());
+ fclose(pidfile);
+ }
+
+ /* Set up the listening sockets */
+ listensockcount = listensockets(listensocks, MAX_LISTEN_ADDR, &maxsock);
+ if (listensockcount == 0)
+ {
+ dropbear_exit("No listening ports available.");
+ }
+
+ /* incoming connection select loop */
+ for(;;) {
+
+ FD_ZERO(&fds);
+
+ seltimeout.tv_sec = 60;
+ seltimeout.tv_usec = 0;
+
+ /* listening sockets */
+ for (i = 0; i < listensockcount; i++) {
+ FD_SET(listensocks[i], &fds);
+ }
+
+ val = select(maxsock+1, &fds, NULL, NULL, &seltimeout);
+
+ if (exitflag) {
+ unlink(DROPBEAR_PIDFILE);
+ dropbear_exit("Terminated by signal");
+ }
+
+ if (val == 0) {
+ /* timeout reached */
+ continue;
+ }
+
+ if (val < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ dropbear_exit("Listening socket error");
+ }
+
+ /* handle each socket which has something to say */
+ for (i = 0; i < listensockcount; i++) {
+
+ struct sockaddr_storage remoteaddr;
+ socklen_t remoteaddrlen = 0;
+ pid_t fork_ret = 0;
+
+ if (!FD_ISSET(listensocks[i], &fds))
+ continue;
+
+ remoteaddrlen = sizeof(remoteaddr);
+ childsock = accept(listensocks[i],
+ (struct sockaddr*)&remoteaddr, &remoteaddrlen);
+
+ if (childsock < 0) {
+ /* accept failed */
+ continue;
+ }
+
+ fork_ret = fork();
+ if (fork_ret < 0) {
+ dropbear_log(LOG_WARNING, "error forking: %s", strerror(errno));
+ goto out;
+
+ } else if (fork_ret > 0) {
+ /* parent */
+ } else {
+
+ char * argv[3];
+
+ /* child */
+
+ if (setsid() < 0) {
+ dropbear_exit("setsid: %s", strerror(errno));
+ }
+
+ /* make sure we close sockets */
+ for (i = 0; i < listensockcount; i++) {
+ m_close(listensocks[i]);
+ }
+
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ //close(STDERR_FILENO);
+
+ dup2(childsock, STDIN_FILENO);
+ dup2(childsock, STDOUT_FILENO);
+
+ argv[0] = "dropbear";
+ argv[1] = "-i";
+ argv[2] = NULL;
+
+ execv(svr_opts.inetd_dropbear_path, argv);
+ dropbear_exit("failed to fork inetd dropbear");
+
+ }
+out:
+ /* This section is important for the parent too */
+ m_close(childsock);
+ }
+
+ } /* for(;;) loop */
+
+ /* don't reach here */
+}
+#endif /* INETD_SERVER_MODE */
+
/* catch + reap zombie children */
static void sigchld_handler(int UNUSED(unused)) {
struct sigaction sa_chld;
@@ -383,7 +545,7 @@ static void commonsetup() {
* otherwise we might end up blatting error messages to the socket */
loadhostkeys();
- seedrandom();
+ seedrandom();
}
/* Set up listening sockets for all the requested ports */
============================================================
--- svr-runopts.c 86c8a2076d2db255ddb3e01d45048590727b34b3
+++ svr-runopts.c 035e042eef818f9f27000930a5834a40ab02c622
@@ -75,6 +75,9 @@ static void printhelp(const char * progn
#ifdef INETD_MODE
"-i Start for inetd\n"
#endif
+#ifdef INETD_SERVER_MODE
+ "-x /path/to/binary Start in inetd server mode\n"
+#endif
#ifdef DEBUG_TRACE
"-v verbose\n"
#endif
@@ -124,6 +127,9 @@ void svr_getopts(int argc, char ** argv)
#ifdef ENABLE_SVR_REMOTETCPFWD
opts.listen_fwd_all = 0;
#endif
+#ifdef INETD_SERVER_MODE
+ svr_opts.inetd_dropbear_path = NULL;
+#endif
for (i = 1; i < (unsigned int)argc; i++) {
if (next) {
@@ -137,6 +143,11 @@ void svr_getopts(int argc, char ** argv)
if (argv[i][0] == '-') {
switch (argv[i][1]) {
+#ifdef INETD_SERVER_MODE
+ case 'x':
+ next = &svr_opts.inetd_dropbear_path;
+ break;
+#endif
case 'b':
next = &svr_opts.bannerfile;
break;