Mercurial > dropbear
comparison svr-main.c @ 71:ac96bc733e71
adding inetd mode back from 0.43
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 12 Aug 2004 17:18:53 +0000 |
parents | dcc43965928f |
children | 72dc22f56858 |
comparison
equal
deleted
inserted
replaced
70:b0316ce64e4b | 71:ac96bc733e71 |
---|---|
31 | 31 |
32 static int listensockets(int *sock, int sockcount, int *maxfd); | 32 static int listensockets(int *sock, int sockcount, int *maxfd); |
33 static void sigchld_handler(int dummy); | 33 static void sigchld_handler(int dummy); |
34 static void sigsegv_handler(int); | 34 static void sigsegv_handler(int); |
35 static void sigintterm_handler(int fish); | 35 static void sigintterm_handler(int fish); |
36 static void main_inetd(); | |
37 static void main_noinetd(); | |
38 static void commonsetup(); | |
36 | 39 |
37 static int childpipes[MAX_UNAUTH_CLIENTS]; | 40 static int childpipes[MAX_UNAUTH_CLIENTS]; |
38 | 41 |
39 #if defined(DBMULTI_dropbear) || !defined(DROPBEAR_MULTI) | 42 #if defined(DBMULTI_dropbear) || !defined(DROPBEAR_MULTI) |
40 #if defined(DBMULTI_dropbear) && defined(DROPBEAR_MULTI) | 43 #if defined(DBMULTI_dropbear) && defined(DROPBEAR_MULTI) |
42 #else | 45 #else |
43 int main(int argc, char ** argv) | 46 int main(int argc, char ** argv) |
44 #endif | 47 #endif |
45 { | 48 { |
46 | 49 |
50 | |
51 _dropbear_exit = svr_dropbear_exit; | |
52 _dropbear_log = svr_dropbear_log; | |
53 | |
54 /* get commandline options */ | |
55 svr_getopts(argc, argv); | |
56 | |
57 #ifdef INETD_MODE | |
58 /* service program mode */ | |
59 if (svr_opts.inetdmode) { | |
60 main_inetd(); | |
61 /* notreached */ | |
62 } | |
63 #endif | |
64 | |
65 #ifdef NON_INETD_MODE | |
66 main_noinetd(); | |
67 /* notreached */ | |
68 #endif | |
69 | |
70 dropbear_exit("Compiled without normal mode, can't run without -i\n"); | |
71 return -1; | |
72 } | |
73 #endif | |
74 | |
75 #ifdef INETD_MODE | |
76 static void main_inetd() { | |
77 | |
78 struct sockaddr_storage remoteaddr; | |
79 int remoteaddrlen; | |
80 char * addrstring = NULL; | |
81 | |
82 /* Set up handlers, syslog */ | |
83 commonsetup(); | |
84 | |
85 remoteaddrlen = sizeof(remoteaddr); | |
86 if (getpeername(0, (struct sockaddr*)&remoteaddr, &remoteaddrlen) < 0) { | |
87 dropbear_exit("Unable to getpeername: %s", strerror(errno)); | |
88 } | |
89 | |
90 /* In case our inetd was lax in logging source addresses */ | |
91 addrstring = getaddrstring(&remoteaddr, 1); | |
92 dropbear_log(LOG_INFO, "Child connection from %s", addrstring); | |
93 m_free(addrstring); | |
94 | |
95 /* Don't check the return value - it may just fail since inetd has | |
96 * already done setsid() after forking (xinetd on Darwin appears to do | |
97 * this */ | |
98 setsid(); | |
99 | |
100 /* Start service program | |
101 * -1 is a dummy childpipe, just something we can close() without | |
102 * mattering. */ | |
103 svr_session(0, -1, getaddrhostname(&remoteaddr)); | |
104 | |
105 /* notreached */ | |
106 } | |
107 #endif /* INETD_MODE */ | |
108 | |
109 #ifdef NON_INETD_MODE | |
110 void main_noinetd() { | |
47 fd_set fds; | 111 fd_set fds; |
48 struct timeval seltimeout; | 112 struct timeval seltimeout; |
49 unsigned int i, j; | 113 unsigned int i, j; |
50 int val; | 114 int val; |
51 int maxsock = -1; | 115 int maxsock = -1; |
52 struct sockaddr_storage remoteaddr; | 116 struct sockaddr_storage remoteaddr; |
53 int remoteaddrlen; | 117 int remoteaddrlen; |
54 int listensocks[MAX_LISTEN_ADDR]; | 118 int listensocks[MAX_LISTEN_ADDR]; |
55 int listensockcount = 0; | 119 int listensockcount = 0; |
56 FILE * pidfile; | 120 FILE *pidfile = NULL; |
57 | 121 |
58 int childsock; | 122 int childsock; |
59 pid_t childpid; | 123 pid_t childpid; |
60 int childpipe[2]; | 124 int childpipe[2]; |
61 | 125 |
62 struct sigaction sa_chld; | 126 struct sigaction sa_chld; |
63 | |
64 _dropbear_exit = svr_dropbear_exit; | |
65 _dropbear_log = svr_dropbear_log; | |
66 | |
67 /* get commandline options */ | |
68 svr_getopts(argc, argv); | |
69 | |
70 /* fork */ | 127 /* fork */ |
71 if (svr_opts.forkbg) { | 128 if (svr_opts.forkbg) { |
72 int closefds = 0; | 129 int closefds = 0; |
73 #ifndef DEBUG_TRACE | 130 #ifndef DEBUG_TRACE |
74 if (!svr_opts.usingsyslog) { | 131 if (!svr_opts.usingsyslog) { |
75 closefds = 1; | 132 closefds = 1; |
76 } | 133 } |
77 #endif | 134 #endif |
78 if (daemon(0, closefds) < 0) { | 135 if (daemon(0, closefds) < 0) { |
79 dropbear_exit("Failed to create background process: %s", | 136 dropbear_exit("Failed to daemonize: %s", strerror(errno)); |
80 strerror(errno)); | 137 } |
81 } | 138 } |
82 } | 139 |
83 | 140 commonsetup(); |
84 #ifndef DISABLE_SYSLOG | |
85 if (svr_opts.usingsyslog) { | |
86 startsyslog(); | |
87 } | |
88 #endif | |
89 | 141 |
90 /* should be done after syslog is working */ | 142 /* should be done after syslog is working */ |
91 if (svr_opts.forkbg) { | 143 if (svr_opts.forkbg) { |
92 dropbear_log(LOG_INFO, "Running in background"); | 144 dropbear_log(LOG_INFO, "Running in background"); |
93 } else { | 145 } else { |
97 /* create a PID file so that we can be killed easily */ | 149 /* create a PID file so that we can be killed easily */ |
98 pidfile = fopen(DROPBEAR_PIDFILE, "w"); | 150 pidfile = fopen(DROPBEAR_PIDFILE, "w"); |
99 if (pidfile) { | 151 if (pidfile) { |
100 fprintf(pidfile, "%d\n", getpid()); | 152 fprintf(pidfile, "%d\n", getpid()); |
101 fclose(pidfile); | 153 fclose(pidfile); |
102 } | |
103 | |
104 /* set up cleanup handler */ | |
105 if (signal(SIGINT, sigintterm_handler) == SIG_ERR || | |
106 #ifndef DEBUG_VALGRIND | |
107 signal(SIGTERM, sigintterm_handler) == SIG_ERR || | |
108 #endif | |
109 signal(SIGPIPE, SIG_IGN) == SIG_ERR) { | |
110 dropbear_exit("signal() error"); | |
111 } | |
112 | |
113 /* catch and reap zombie children */ | |
114 sa_chld.sa_handler = sigchld_handler; | |
115 sa_chld.sa_flags = SA_NOCLDSTOP; | |
116 if (sigaction(SIGCHLD, &sa_chld, NULL) < 0) { | |
117 dropbear_exit("signal() error"); | |
118 } | |
119 if (signal(SIGSEGV, sigsegv_handler) == SIG_ERR) { | |
120 dropbear_exit("signal() error"); | |
121 } | 154 } |
122 | 155 |
123 /* sockets to identify pre-authenticated clients */ | 156 /* sockets to identify pre-authenticated clients */ |
124 for (i = 0; i < MAX_UNAUTH_CLIENTS; i++) { | 157 for (i = 0; i < MAX_UNAUTH_CLIENTS; i++) { |
125 childpipes[i] = -1; | 158 childpipes[i] = -1; |
184 /* handle each socket which has something to say */ | 217 /* handle each socket which has something to say */ |
185 for (i = 0; i < (unsigned int)listensockcount; i++) { | 218 for (i = 0; i < (unsigned int)listensockcount; i++) { |
186 if (!FD_ISSET(listensocks[i], &fds)) | 219 if (!FD_ISSET(listensocks[i], &fds)) |
187 continue; | 220 continue; |
188 | 221 |
189 /* child connection XXX - ip6 stuff here */ | |
190 remoteaddrlen = sizeof(remoteaddr); | 222 remoteaddrlen = sizeof(remoteaddr); |
191 childsock = accept(listensocks[i], | 223 childsock = accept(listensocks[i], |
192 (struct sockaddr*)&remoteaddr, &remoteaddrlen); | 224 (struct sockaddr*)&remoteaddr, &remoteaddrlen); |
193 | 225 |
194 if (childsock < 0) { | 226 if (childsock < 0) { |
260 } | 292 } |
261 } | 293 } |
262 } /* for(;;) loop */ | 294 } /* for(;;) loop */ |
263 | 295 |
264 /* don't reach here */ | 296 /* don't reach here */ |
265 return -1; | 297 } |
266 } | 298 #endif /* NON_INETD_MODE */ |
267 #endif | 299 |
268 | 300 |
269 /* catch + reap zombie children */ | 301 /* catch + reap zombie children */ |
270 static void sigchld_handler(int fish) { | 302 static void sigchld_handler(int fish) { |
271 struct sigaction sa_chld; | 303 struct sigaction sa_chld; |
272 | 304 |
288 | 320 |
289 /* catch ctrl-c or sigterm */ | 321 /* catch ctrl-c or sigterm */ |
290 static void sigintterm_handler(int fish) { | 322 static void sigintterm_handler(int fish) { |
291 | 323 |
292 exitflag = 1; | 324 exitflag = 1; |
325 } | |
326 | |
327 /* Things used by inetd and non-inetd modes */ | |
328 static void commonsetup() { | |
329 | |
330 struct sigaction sa_chld; | |
331 #ifndef DISABLE_SYSLOG | |
332 if (svr_opts.usingsyslog) { | |
333 startsyslog(); | |
334 } | |
335 #endif | |
336 | |
337 /* set up cleanup handler */ | |
338 if (signal(SIGINT, sigintterm_handler) == SIG_ERR || | |
339 #ifndef DEBUG_VALGRIND | |
340 signal(SIGTERM, sigintterm_handler) == SIG_ERR || | |
341 #endif | |
342 signal(SIGPIPE, SIG_IGN) == SIG_ERR) { | |
343 dropbear_exit("signal() error"); | |
344 } | |
345 | |
346 /* catch and reap zombie children */ | |
347 sa_chld.sa_handler = sigchld_handler; | |
348 sa_chld.sa_flags = SA_NOCLDSTOP; | |
349 if (sigaction(SIGCHLD, &sa_chld, NULL) < 0) { | |
350 dropbear_exit("signal() error"); | |
351 } | |
352 if (signal(SIGSEGV, sigsegv_handler) == SIG_ERR) { | |
353 dropbear_exit("signal() error"); | |
354 } | |
293 } | 355 } |
294 | 356 |
295 /* Set up listening sockets for all the requested ports */ | 357 /* Set up listening sockets for all the requested ports */ |
296 static int listensockets(int *sock, int sockcount, int *maxfd) { | 358 static int listensockets(int *sock, int sockcount, int *maxfd) { |
297 | 359 |