adding inetd mode back from 0.43

--HG--
extra : convert_revision : 8f98bb3056d06b721b437ac8d9fe0a71e40acd9a
This commit is contained in:
Matt Johnston 2004-08-12 17:18:53 +00:00
parent 8e1ec24f55
commit 084bddf1c5
4 changed files with 123 additions and 39 deletions

View File

@ -42,6 +42,19 @@
#define RSA_PRIV_FILENAME "/etc/dropbear/dropbear_rsa_host_key" #define RSA_PRIV_FILENAME "/etc/dropbear/dropbear_rsa_host_key"
#endif #endif
/* Set NON_INETD_MODE if you require daemon functionality (ie Dropbear listens
* on chosen ports and keeps accepting connections. This is the default.
*
* Set INETD_MODE if you want to be able to run Dropbear with inetd (or
* similar), where it will use stdin/stdout for connections, and each process
* lasts for a single connection. Dropbear should be invoked with the -i flag
* for inetd, and can only accept IPv4 connections.
*
* Both of these flags can be defined at once, don't compile without at least
* one of them. */
#define NON_INETD_MODE
#define INETD_MODE
/* Setting this disables the fast exptmod bignum code. It saves ~5kB, but is /* Setting this disables the fast exptmod bignum code. It saves ~5kB, but is
* perhaps 20% slower for pubkey operations (it is probably worth experimenting * perhaps 20% slower for pubkey operations (it is probably worth experimenting
* if you want to use this) */ * if you want to use this) */

View File

@ -55,6 +55,8 @@ typedef struct svr_runopts {
uint16_t *ports; uint16_t *ports;
unsigned int portcount; unsigned int portcount;
int inetdmode;
/* Flags indicating whether to use ipv4 and ipv6 */ /* Flags indicating whether to use ipv4 and ipv6 */
/* not used yet /* not used yet
int ipv4; int ipv4;

View File

@ -33,6 +33,9 @@ static int listensockets(int *sock, int sockcount, int *maxfd);
static void sigchld_handler(int dummy); static void sigchld_handler(int dummy);
static void sigsegv_handler(int); static void sigsegv_handler(int);
static void sigintterm_handler(int fish); static void sigintterm_handler(int fish);
static void main_inetd();
static void main_noinetd();
static void commonsetup();
static int childpipes[MAX_UNAUTH_CLIENTS]; static int childpipes[MAX_UNAUTH_CLIENTS];
@ -44,6 +47,67 @@ int main(int argc, char ** argv)
#endif #endif
{ {
_dropbear_exit = svr_dropbear_exit;
_dropbear_log = svr_dropbear_log;
/* get commandline options */
svr_getopts(argc, argv);
#ifdef INETD_MODE
/* service program mode */
if (svr_opts.inetdmode) {
main_inetd();
/* notreached */
}
#endif
#ifdef NON_INETD_MODE
main_noinetd();
/* notreached */
#endif
dropbear_exit("Compiled without normal mode, can't run without -i\n");
return -1;
}
#endif
#ifdef INETD_MODE
static void main_inetd() {
struct sockaddr_storage remoteaddr;
int remoteaddrlen;
char * addrstring = NULL;
/* Set up handlers, syslog */
commonsetup();
remoteaddrlen = sizeof(remoteaddr);
if (getpeername(0, (struct sockaddr*)&remoteaddr, &remoteaddrlen) < 0) {
dropbear_exit("Unable to getpeername: %s", strerror(errno));
}
/* In case our inetd was lax in logging source addresses */
addrstring = getaddrstring(&remoteaddr, 1);
dropbear_log(LOG_INFO, "Child connection from %s", addrstring);
m_free(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
* this */
setsid();
/* Start service program
* -1 is a dummy childpipe, just something we can close() without
* mattering. */
svr_session(0, -1, getaddrhostname(&remoteaddr));
/* notreached */
}
#endif /* INETD_MODE */
#ifdef NON_INETD_MODE
void main_noinetd() {
fd_set fds; fd_set fds;
struct timeval seltimeout; struct timeval seltimeout;
unsigned int i, j; unsigned int i, j;
@ -53,20 +117,13 @@ int main(int argc, char ** argv)
int remoteaddrlen; int remoteaddrlen;
int listensocks[MAX_LISTEN_ADDR]; int listensocks[MAX_LISTEN_ADDR];
int listensockcount = 0; int listensockcount = 0;
FILE * pidfile; FILE *pidfile = NULL;
int childsock; int childsock;
pid_t childpid; pid_t childpid;
int childpipe[2]; int childpipe[2];
struct sigaction sa_chld; struct sigaction sa_chld;
_dropbear_exit = svr_dropbear_exit;
_dropbear_log = svr_dropbear_log;
/* get commandline options */
svr_getopts(argc, argv);
/* fork */ /* fork */
if (svr_opts.forkbg) { if (svr_opts.forkbg) {
int closefds = 0; int closefds = 0;
@ -76,16 +133,11 @@ int main(int argc, char ** argv)
} }
#endif #endif
if (daemon(0, closefds) < 0) { if (daemon(0, closefds) < 0) {
dropbear_exit("Failed to create background process: %s", dropbear_exit("Failed to daemonize: %s", strerror(errno));
strerror(errno));
} }
} }
#ifndef DISABLE_SYSLOG commonsetup();
if (svr_opts.usingsyslog) {
startsyslog();
}
#endif
/* should be done after syslog is working */ /* should be done after syslog is working */
if (svr_opts.forkbg) { if (svr_opts.forkbg) {
@ -101,25 +153,6 @@ int main(int argc, char ** argv)
fclose(pidfile); fclose(pidfile);
} }
/* set up cleanup handler */
if (signal(SIGINT, sigintterm_handler) == SIG_ERR ||
#ifndef DEBUG_VALGRIND
signal(SIGTERM, sigintterm_handler) == SIG_ERR ||
#endif
signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
dropbear_exit("signal() error");
}
/* catch and reap zombie children */
sa_chld.sa_handler = sigchld_handler;
sa_chld.sa_flags = SA_NOCLDSTOP;
if (sigaction(SIGCHLD, &sa_chld, NULL) < 0) {
dropbear_exit("signal() error");
}
if (signal(SIGSEGV, sigsegv_handler) == SIG_ERR) {
dropbear_exit("signal() error");
}
/* sockets to identify pre-authenticated clients */ /* sockets to identify pre-authenticated clients */
for (i = 0; i < MAX_UNAUTH_CLIENTS; i++) { for (i = 0; i < MAX_UNAUTH_CLIENTS; i++) {
childpipes[i] = -1; childpipes[i] = -1;
@ -186,7 +219,6 @@ int main(int argc, char ** argv)
if (!FD_ISSET(listensocks[i], &fds)) if (!FD_ISSET(listensocks[i], &fds))
continue; continue;
/* child connection XXX - ip6 stuff here */
remoteaddrlen = sizeof(remoteaddr); remoteaddrlen = sizeof(remoteaddr);
childsock = accept(listensocks[i], childsock = accept(listensocks[i],
(struct sockaddr*)&remoteaddr, &remoteaddrlen); (struct sockaddr*)&remoteaddr, &remoteaddrlen);
@ -262,9 +294,9 @@ int main(int argc, char ** argv)
} /* for(;;) loop */ } /* for(;;) loop */
/* don't reach here */ /* don't reach here */
return -1;
} }
#endif #endif /* NON_INETD_MODE */
/* catch + reap zombie children */ /* catch + reap zombie children */
static void sigchld_handler(int fish) { static void sigchld_handler(int fish) {
@ -292,6 +324,36 @@ static void sigintterm_handler(int fish) {
exitflag = 1; exitflag = 1;
} }
/* Things used by inetd and non-inetd modes */
static void commonsetup() {
struct sigaction sa_chld;
#ifndef DISABLE_SYSLOG
if (svr_opts.usingsyslog) {
startsyslog();
}
#endif
/* set up cleanup handler */
if (signal(SIGINT, sigintterm_handler) == SIG_ERR ||
#ifndef DEBUG_VALGRIND
signal(SIGTERM, sigintterm_handler) == SIG_ERR ||
#endif
signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
dropbear_exit("signal() error");
}
/* catch and reap zombie children */
sa_chld.sa_handler = sigchld_handler;
sa_chld.sa_flags = SA_NOCLDSTOP;
if (sigaction(SIGCHLD, &sa_chld, NULL) < 0) {
dropbear_exit("signal() error");
}
if (signal(SIGSEGV, sigsegv_handler) == SIG_ERR) {
dropbear_exit("signal() error");
}
}
/* Set up listening sockets for all the requested ports */ /* Set up listening sockets for all the requested ports */
static int listensockets(int *sock, int sockcount, int *maxfd) { static int listensockets(int *sock, int sockcount, int *maxfd) {

View File

@ -73,8 +73,9 @@ static void printhelp(const char * progname) {
#endif #endif
"-p port Listen on specified tcp port, up to %d can be specified\n" "-p port Listen on specified tcp port, up to %d can be specified\n"
" (default %d if none specified)\n" " (default %d if none specified)\n"
/* "-4/-6 Disable listening on ipv4/ipv6 respectively\n"*/ #ifdef INETD_MODE
"-i Start for inetd\n"
#endif
,DROPBEAR_VERSION, progname, ,DROPBEAR_VERSION, progname,
#ifdef DROPBEAR_DSS #ifdef DROPBEAR_DSS
DSS_PRIV_FILENAME, DSS_PRIV_FILENAME,
@ -102,6 +103,7 @@ void svr_getopts(int argc, char ** argv) {
svr_opts.norootlogin = 0; svr_opts.norootlogin = 0;
svr_opts.noauthpass = 0; svr_opts.noauthpass = 0;
svr_opts.norootpass = 0; svr_opts.norootpass = 0;
svr_opts.inetdmode = 0;
opts.nolocaltcp = 0; opts.nolocaltcp = 0;
opts.noremotetcp = 0; opts.noremotetcp = 0;
/* not yet /* not yet
@ -157,6 +159,11 @@ void svr_getopts(int argc, char ** argv) {
case 'k': case 'k':
opts.noremotetcp = 1; opts.noremotetcp = 1;
break; break;
#endif
#ifdef INETD_MODE
case 'i':
svr_opts.inetdmode = 1;
break;
#endif #endif
case 'p': case 'p':
if (portnum < DROPBEAR_MAX_PORTS) { if (portnum < DROPBEAR_MAX_PORTS) {