Line data Source code
1 : #include "../burp.h"
2 : #include "../asfd.h"
3 : #include "../async.h"
4 : #include "../cntr.h"
5 : #include "../conf.h"
6 : #include "../conffile.h"
7 : #include "../cstat.h"
8 : #include "../fsops.h"
9 : #include "../handy.h"
10 : #include "../iobuf.h"
11 : #include "../lock.h"
12 : #include "../log.h"
13 : #include "auth.h"
14 : #include "ca.h"
15 : #include "child.h"
16 : #include "main.h"
17 : #include "monitor/status_server.h"
18 :
19 : static int hupreload=0;
20 : static int hupreload_logged=0;
21 : static int gentleshutdown=0;
22 : static int gentleshutdown_logged=0;
23 :
24 : // These will also be used as the exit codes of the program and are therefore
25 : // unsigned integers.
26 : // Remember to update the man page if you update these.
27 : enum serret
28 : {
29 : SERVER_OK=0,
30 : SERVER_ERROR=1
31 : };
32 :
33 0 : static void huphandler(__attribute__ ((unused)) int sig)
34 : {
35 0 : hupreload=1;
36 : // Be careful about not logging inside a signal handler.
37 0 : hupreload_logged=0;
38 0 : }
39 :
40 0 : static void usr2handler(__attribute__ ((unused)) int sig)
41 : {
42 0 : gentleshutdown=1;
43 : // Be careful about not logging inside a signal handler.
44 0 : gentleshutdown_logged=0;
45 0 : }
46 :
47 : // Remove any exiting child pids from our list.
48 0 : static void chld_check_for_exiting(struct async *mainas)
49 : {
50 : pid_t p;
51 : int status;
52 : struct asfd *asfd;
53 :
54 0 : while((p=waitpid(-1, &status, WNOHANG))>0)
55 : {
56 : // Logging a message here appeared to occasionally lock burp up
57 : // on a Ubuntu server that I used to use.
58 0 : for(asfd=mainas->asfd; asfd; asfd=asfd->next)
59 : {
60 0 : if(p!=asfd->pid) continue;
61 0 : mainas->asfd_remove(mainas, asfd);
62 0 : asfd_free(&asfd);
63 0 : break;
64 : }
65 : }
66 0 : }
67 :
68 : static void *get_in_addr(struct sockaddr *sa)
69 : {
70 : #ifdef HAVE_IPV6
71 0 : if(sa->sa_family==AF_INET6)
72 0 : return &(((struct sockaddr_in6*)sa)->sin6_addr);
73 : #endif
74 0 : return &(((struct sockaddr_in*)sa)->sin_addr);
75 : }
76 :
77 0 : static void log_listen_socket(const char *desc,
78 : struct addrinfo *rp, const char *port, int max_children)
79 : {
80 : #ifdef HAVE_IPV6
81 0 : char addr[INET6_ADDRSTRLEN]="";
82 : #else
83 : char addr[INET_ADDRSTRLEN]="";
84 : #endif
85 0 : inet_ntop(rp->ai_family, get_in_addr((struct sockaddr *)rp->ai_addr),
86 : addr, sizeof(addr));
87 0 : logp("%s %s:%s (max %d)\n",
88 : desc, addr, port, max_children);
89 0 : }
90 :
91 0 : static int init_listen_socket(struct strlist *address,
92 : struct async *mainas, enum asfd_fdtype fdtype, const char *desc)
93 : {
94 0 : int fd=-1;
95 : int gai_ret;
96 : struct addrinfo hints;
97 0 : struct addrinfo *info=NULL;
98 0 : struct asfd *newfd=NULL;
99 0 : char *a=NULL;
100 0 : char *port=NULL;
101 :
102 0 : if(!(a=strdup_w(address->path, __func__)))
103 : goto error;
104 0 : if(!(port=strrchr(a, ':')))
105 : {
106 0 : logp("Could not parse '%s'\n", address->path);
107 : goto error;
108 : }
109 0 : *port='\0';
110 0 : port++;
111 :
112 0 : memset(&hints, 0, sizeof(struct addrinfo));
113 : hints.ai_family=AF_UNSPEC;
114 0 : hints.ai_socktype=SOCK_STREAM;
115 0 : hints.ai_protocol=IPPROTO_TCP;
116 : hints.ai_flags=AI_NUMERICHOST;
117 0 : hints.ai_flags|=AI_PASSIVE;
118 :
119 0 : if((gai_ret=getaddrinfo(a, port, &hints, &info)))
120 : {
121 0 : logp("unable to getaddrinfo on %s: %s\n",
122 : address->path, gai_strerror(gai_ret));
123 : goto error;
124 : }
125 :
126 : // Just try to use the first one in info, it should be good enough.
127 0 : fd=socket(info->ai_family, info->ai_socktype, info->ai_protocol);
128 0 : if(fd<0)
129 : {
130 0 : logp("unable to create socket on %s: %s\n",
131 0 : address->path, strerror(errno));
132 : goto error;
133 : }
134 0 : set_keepalive(fd, 1);
135 : #ifdef HAVE_IPV6
136 0 : if(info->ai_family==AF_INET6)
137 : {
138 : // Attempt to say that it should not listen on IPv6
139 : // only.
140 0 : int optval=0;
141 0 : setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
142 : &optval, sizeof(optval));
143 : }
144 : #endif
145 0 : reuseaddr(fd);
146 0 : if(bind(fd, info->ai_addr, info->ai_addrlen))
147 : {
148 0 : logp("unable to bind socket on %s: %s\n",
149 0 : address->path, strerror(errno));
150 : goto error;
151 : }
152 :
153 : // Say that we are happy to accept connections.
154 0 : if(listen(fd, 5)<0)
155 : {
156 0 : logp("could not listen on address %s: %s\n",
157 0 : address->path, strerror(errno));
158 : goto error;
159 : }
160 :
161 0 : log_listen_socket(desc, info, port, address->flag);
162 0 : if(!(newfd=setup_asfd(mainas, desc, &fd, address->path)))
163 : goto end;
164 0 : newfd->fdtype=fdtype;
165 :
166 : goto end;
167 : error:
168 0 : free_w(&a);
169 0 : if(info)
170 0 : freeaddrinfo(info);
171 : return -1;
172 : end:
173 0 : free_w(&a);
174 0 : if(info)
175 0 : freeaddrinfo(info);
176 : return 0;
177 : }
178 :
179 : static int init_listen_sockets(struct strlist *addresses,
180 : struct async *mainas, enum asfd_fdtype fdtype, const char *desc)
181 : {
182 : struct strlist *a;
183 0 : for(a=addresses; a; a=a->next)
184 0 : if(init_listen_socket(a, mainas, fdtype, desc))
185 : return -1;
186 : return 0;
187 : }
188 :
189 0 : void setup_signals(void)
190 : {
191 : // Ignore SIGPIPE - we are careful with read and write return values.
192 0 : signal(SIGPIPE, SIG_IGN);
193 :
194 0 : setup_signal(SIGHUP, huphandler);
195 0 : setup_signal(SIGUSR2, usr2handler);
196 0 : }
197 :
198 0 : static int run_child(int *cfd, SSL_CTX *ctx, struct sockaddr_storage *addr,
199 : int status_wfd, int status_rfd, const char *conffile, int forking)
200 : {
201 0 : int ret=-1;
202 0 : int ca_ret=0;
203 0 : SSL *ssl=NULL;
204 0 : BIO *sbio=NULL;
205 0 : struct conf **confs=NULL;
206 0 : struct conf **cconfs=NULL;
207 0 : struct cntr *cntr=NULL;
208 0 : struct async *as=NULL;
209 0 : const char *cname=NULL;
210 0 : struct asfd *asfd=NULL;
211 0 : int is_status_server=0;
212 :
213 0 : if(!(confs=confs_alloc())
214 0 : || !(cconfs=confs_alloc()))
215 : goto end;
216 :
217 0 : set_peer_env_vars(addr);
218 :
219 : // Reload global config, in case things have changed. This means that
220 : // the server does not need to be restarted for most conf changes.
221 0 : confs_init(confs);
222 0 : confs_init(cconfs);
223 0 : if(conf_load_global_only(conffile, confs)) goto end;
224 :
225 : // Hack to keep forking turned off if it was specified as off on the
226 : // command line.
227 0 : if(!forking) set_int(confs[OPT_FORK], 0);
228 :
229 0 : if(!(sbio=BIO_new_socket(*cfd, BIO_NOCLOSE))
230 0 : || !(ssl=SSL_new(ctx)))
231 : {
232 0 : logp("There was a problem joining ssl to the socket\n");
233 0 : goto end;
234 : }
235 0 : SSL_set_bio(ssl, sbio, sbio);
236 :
237 : /* Check peer certificate straight away if the "verify_peer_early"
238 : option is enabled. Otherwise clients may send a certificate signing
239 : request when they have no certificate. */
240 0 : SSL_set_verify(ssl, SSL_VERIFY_PEER |
241 0 : (get_int(confs[OPT_SSL_VERIFY_PEER_EARLY])?SSL_VERIFY_FAIL_IF_NO_PEER_CERT:0),
242 : 0);
243 :
244 0 : if(ssl_do_accept(ssl))
245 : goto end;
246 0 : if(!(as=async_alloc())
247 0 : || as->init(as, 0)
248 0 : || !(asfd=setup_asfd_ssl(as, "main socket", cfd, ssl)))
249 : goto end;
250 0 : asfd->set_timeout(asfd, get_int(confs[OPT_NETWORK_TIMEOUT]));
251 0 : asfd->ratelimit=get_float(confs[OPT_RATELIMIT]);
252 :
253 0 : if(authorise_server(as->asfd, confs, cconfs)
254 0 : || !(cname=get_string(cconfs[OPT_CNAME])) || !*cname)
255 : {
256 : // Add an annoying delay in case they are tempted to
257 : // try repeatedly.
258 0 : sleep(1);
259 0 : log_and_send(as->asfd, "unable to authorise on server");
260 0 : goto end;
261 : }
262 :
263 0 : if(!get_int(cconfs[OPT_ENABLED]))
264 : {
265 0 : sleep(1);
266 0 : log_and_send(as->asfd, "client not enabled on server");
267 0 : goto end;
268 : }
269 :
270 : // Set up counters. Have to wait until here to get cname.
271 0 : if(!(cntr=cntr_alloc())
272 0 : || cntr_init(cntr, cname, getpid()))
273 : goto end;
274 0 : set_cntr(confs[OPT_CNTR], cntr);
275 0 : set_cntr(cconfs[OPT_CNTR], cntr);
276 :
277 : /* At this point, the client might want to get a new certificate
278 : signed. Clients on 1.3.2 or newer can do this. */
279 0 : if((ca_ret=ca_server_maybe_sign_client_cert(as->asfd, confs, cconfs))<0)
280 : {
281 0 : logp("Error signing client certificate request for %s\n",
282 : cname);
283 0 : goto end;
284 : }
285 0 : else if(ca_ret>0)
286 : {
287 : // Certificate signed and sent back.
288 : // Everything is OK, but we will close this instance
289 : // so that the client can start again with a new
290 : // connection and its new certificates.
291 0 : logp("Signed and returned client certificate request for %s\n",
292 : cname);
293 0 : ret=0;
294 0 : goto end;
295 : }
296 :
297 : /* Now it is time to check the certificate. */
298 0 : if(ssl_check_cert(ssl, confs, cconfs))
299 : {
300 0 : log_and_send(as->asfd, "check cert failed on server");
301 0 : goto end;
302 : }
303 0 : if(status_rfd>=0)
304 : {
305 0 : is_status_server=1;
306 0 : if(!setup_asfd(as, "status server parent socket", &status_rfd,
307 : /*listen*/""))
308 : goto end;
309 : }
310 :
311 0 : ret=child(as, is_status_server, status_wfd, confs, cconfs);
312 : end:
313 0 : *cfd=-1;
314 0 : if(as && asfd_flush_asio(as->asfd))
315 0 : ret=-1;
316 0 : async_asfd_free_all(&as); // This closes cfd for us.
317 0 : logp("exit child\n");
318 0 : if(cntr) cntr_free(&cntr);
319 0 : if(confs)
320 : {
321 0 : set_cntr(confs[OPT_CNTR], NULL);
322 0 : confs_free(&confs);
323 : }
324 0 : if(cconfs)
325 : {
326 0 : set_cntr(cconfs[OPT_CNTR], NULL);
327 0 : confs_free(&cconfs);
328 : }
329 0 : return ret;
330 : }
331 :
332 0 : static struct strlist *find_listen_in_conf(struct conf **confs,
333 : enum conf_opt listen_opt, const char *listen)
334 : {
335 : struct strlist *l;
336 0 : for(l=get_strlist(confs[listen_opt]); l; l=l->next)
337 0 : if(!strcmp(listen, l->path))
338 : return l;
339 0 : logp("Could not find %s in %s confs\n",
340 0 : listen, confs[listen_opt]->field);
341 0 : return NULL;
342 : }
343 :
344 0 : static int chld_check_counts(struct conf **confs, struct asfd *asfd)
345 : {
346 0 : long count=0;
347 : struct asfd *a;
348 : struct strlist *listen;
349 : enum conf_opt listen_opt;
350 :
351 0 : switch(asfd->fdtype)
352 : {
353 : case ASFD_FD_SERVER_LISTEN_MAIN:
354 0 : listen_opt=OPT_LISTEN;
355 0 : if(!(listen=find_listen_in_conf(confs,
356 0 : listen_opt, asfd->listen)))
357 : return -1;
358 : break;
359 : case ASFD_FD_SERVER_LISTEN_STATUS:
360 0 : listen_opt=OPT_LISTEN_STATUS;
361 0 : if(!(listen=find_listen_in_conf(confs,
362 0 : listen_opt, asfd->listen)))
363 : return -1;
364 : break;
365 : default:
366 0 : logp("Unexpected fdtype in %s: %d.\n",
367 : __func__, asfd->fdtype);
368 0 : return -1;
369 : }
370 :
371 0 : for(a=asfd->as->asfd; a; a=a->next)
372 0 : if(a!=asfd
373 0 : && !strcmp(asfd->listen, a->listen))
374 0 : count++;
375 :
376 0 : logp("%d/%d child processes running on %s %s\n",
377 0 : (int)count, (int)listen->flag,
378 0 : confs[listen_opt]->field, asfd->listen);
379 0 : if(count<listen->flag)
380 0 : logp("Child %d available\n", (int)count+1);
381 : else
382 : {
383 0 : logp("No spare children available.\n");
384 0 : return -1;
385 : }
386 :
387 0 : return 0;
388 : }
389 :
390 : static struct asfd *setup_parent_child_pipe(struct async *as,
391 : const char *desc,
392 : int *fd_to_use, int *fd_to_close, pid_t childpid, const char *listen,
393 : enum asfd_fdtype fdtype)
394 : {
395 : struct asfd *newfd;
396 0 : close_fd(fd_to_close);
397 0 : if(!(newfd=setup_asfd(as, desc, fd_to_use, listen)))
398 : return NULL;
399 0 : newfd->pid=childpid;
400 0 : newfd->fdtype=fdtype;
401 : return newfd;
402 : }
403 :
404 0 : static int setup_parent_child_pipes(struct asfd *asfd,
405 : pid_t childpid, int *rfd, int *wfd)
406 : {
407 : struct asfd *newfd;
408 0 : struct async *as=asfd->as;
409 0 : switch(asfd->fdtype)
410 : {
411 : case ASFD_FD_SERVER_LISTEN_MAIN:
412 0 : logp("forked child on %s: %d\n",
413 : asfd->listen, childpid);
414 0 : if(!(newfd=setup_parent_child_pipe(as,
415 : "pipe from child",
416 0 : rfd, wfd, childpid, asfd->listen,
417 : ASFD_FD_SERVER_PIPE_READ)))
418 : return -1;
419 0 : return 0;
420 : case ASFD_FD_SERVER_LISTEN_STATUS:
421 0 : logp("forked status child on %s: %d\n",
422 : asfd->listen, childpid);
423 0 : if(!(newfd=setup_parent_child_pipe(as,
424 : "pipe to status child",
425 0 : wfd, rfd, childpid, asfd->listen,
426 : ASFD_FD_SERVER_PIPE_WRITE)))
427 : return -1;
428 0 : newfd->attempt_reads=0;
429 0 : return 0;
430 : default:
431 0 : logp("Strange fdtype after fork: %d\n",
432 : asfd->fdtype);
433 0 : return -1;
434 : }
435 :
436 : return 0;
437 : }
438 :
439 0 : static int process_incoming_client(struct asfd *asfd, SSL_CTX *ctx,
440 : const char *conffile, struct conf **confs)
441 : {
442 0 : int cfd=-1;
443 : pid_t childpid;
444 : int pipe_rfd[2];
445 : int pipe_wfd[2];
446 0 : socklen_t client_length=0;
447 : struct sockaddr_storage client_name;
448 0 : enum asfd_fdtype fdtype=asfd->fdtype;
449 0 : int forking=get_int(confs[OPT_FORK]);
450 :
451 0 : client_length=sizeof(client_name);
452 0 : if((cfd=accept(asfd->fd,
453 : (struct sockaddr *)&client_name, &client_length))==-1)
454 : {
455 : // Look out, accept will get interrupted by SIGCHLDs.
456 0 : if(errno==EINTR) return 0;
457 0 : logp("accept failed on %s (%d) in %s: %s\n", asfd->desc,
458 : asfd->fd, __func__, strerror(errno));
459 0 : return -1;
460 : }
461 0 : reuseaddr(cfd);
462 0 : if(log_peer_address(&client_name))
463 : return -1;
464 :
465 0 : if(!forking)
466 0 : return run_child(&cfd, ctx,
467 : &client_name, -1, -1, conffile, forking);
468 :
469 0 : if(chld_check_counts(confs, asfd))
470 : {
471 0 : logp("Closing new connection.\n");
472 0 : close_fd(&cfd);
473 0 : return 0;
474 : }
475 :
476 0 : if(pipe(pipe_rfd)<0 || pipe(pipe_wfd)<0)
477 : {
478 0 : logp("pipe failed: %s", strerror(errno));
479 0 : close_fd(&cfd);
480 0 : return -1;
481 : }
482 :
483 0 : switch((childpid=fork()))
484 : {
485 : case -1:
486 0 : logp("fork failed: %s\n", strerror(errno));
487 0 : return -1;
488 : case 0:
489 : {
490 : // Child.
491 : int p;
492 : int ret;
493 : struct sigaction sa;
494 0 : struct async *as=asfd->as;
495 0 : async_asfd_free_all(&as);
496 :
497 : // Close unnecessary file descriptors.
498 : // Go up to FD_SETSIZE and hope for the best.
499 : // FIX THIS: Now that async_asfd_free_all() is doing
500 : // everything, double check whether this is needed.
501 0 : for(p=3; p<(int)FD_SETSIZE; p++)
502 : {
503 0 : if(p!=pipe_rfd[1]
504 0 : && p!=pipe_wfd[0]
505 0 : && p!=cfd)
506 0 : close(p);
507 : }
508 :
509 : // Set SIGCHLD back to default, so that I
510 : // can get sensible returns from waitpid.
511 0 : memset(&sa, 0, sizeof(sa));
512 : sa.sa_handler=SIG_DFL;
513 0 : sigaction(SIGCHLD, &sa, NULL);
514 :
515 0 : close(pipe_rfd[0]); // close read end
516 0 : close(pipe_wfd[1]); // close write end
517 :
518 0 : confs_free_content(confs);
519 0 : confs_init(confs);
520 :
521 0 : ret=run_child(&cfd, ctx, &client_name, pipe_rfd[1],
522 : fdtype==ASFD_FD_SERVER_LISTEN_STATUS?pipe_wfd[0]:-1,
523 : conffile, forking);
524 :
525 0 : close(pipe_rfd[1]);
526 0 : close(pipe_wfd[0]);
527 0 : close_fd(&cfd);
528 0 : exit(ret);
529 : }
530 : default:
531 : // Parent.
532 0 : close(pipe_rfd[1]); // close write end
533 0 : close(pipe_wfd[0]); // close read end
534 0 : close_fd(&cfd);
535 :
536 0 : return setup_parent_child_pipes(asfd, childpid,
537 : &pipe_rfd[0], &pipe_wfd[1]);
538 : }
539 : }
540 :
541 0 : static int daemonise(void)
542 : {
543 : /* process ID */
544 : pid_t pid;
545 :
546 : /* session ID */
547 : pid_t sid;
548 :
549 : /* fork new child and end parent */
550 0 : pid=fork();
551 :
552 : /* did we fork? */
553 0 : if(pid<0)
554 : {
555 0 : logp("error forking\n");
556 0 : return -1;
557 : }
558 :
559 : /* parent? */
560 0 : if(pid>0)
561 0 : exit(EXIT_SUCCESS);
562 :
563 : /* now we are in the child process */
564 :
565 : /* create a session and set the process group ID */
566 0 : sid=setsid();
567 0 : if(sid<0)
568 : {
569 0 : logp("error setting sid\n");
570 0 : return -1;
571 : }
572 :
573 : /* leave and unblock current working dir */
574 0 : if(chdir("/")<0)
575 : {
576 0 : logp("error changing working dir\n");
577 0 : return -1;
578 : }
579 :
580 : /* close std* */
581 0 : close(STDIN_FILENO);
582 0 : close(STDOUT_FILENO);
583 0 : close(STDERR_FILENO);
584 :
585 0 : return 0;
586 : }
587 :
588 0 : static int extract_client_name(struct asfd *asfd)
589 : {
590 : size_t l;
591 0 : const char *cp=NULL;
592 0 : const char *dp=NULL;
593 :
594 0 : if(asfd->client)
595 : return 0;
596 0 : if(!(dp=strchr(asfd->rbuf->buf, '\t')))
597 : return 0;
598 0 : dp++;
599 0 : if(!(cp=strchr(dp, '\t')))
600 : return 0;
601 0 : cp++;
602 0 : l=cp-dp;
603 0 : if(!(asfd->client=malloc_w(l+1, __func__)))
604 : return -1;
605 0 : snprintf(asfd->client, l, "%s", dp);
606 : return 0;
607 : }
608 :
609 0 : static int write_to_status_children(struct async *mainas, struct iobuf *iobuf)
610 : {
611 : size_t wlen;
612 0 : struct asfd *scfd=NULL;
613 :
614 : // One of the child processes is giving us information.
615 : // Try to append it to any of the status child pipes.
616 0 : for(scfd=mainas->asfd; scfd; scfd=scfd->next)
617 : {
618 0 : if(scfd->fdtype!=ASFD_FD_SERVER_PIPE_WRITE)
619 0 : continue;
620 0 : wlen=iobuf->len;
621 0 : switch(scfd->append_all_to_write_buffer(scfd, iobuf))
622 : {
623 : case APPEND_OK:
624 : // Hack - the append function
625 : // will set the length to zero
626 : // on success. Set it back for
627 : // the next status child pipe.
628 0 : iobuf->len=wlen;
629 : break;
630 : case APPEND_BLOCKED:
631 : break;
632 : default:
633 : return -1;
634 : }
635 : }
636 : // Free the information, even if we did not manage to append it. That
637 : // should be OK, more will be along soon.
638 0 : iobuf_free_content(iobuf);
639 : return 0;
640 : }
641 :
642 0 : static int update_status_child_client_lists(struct async *mainas)
643 : {
644 0 : int ret=-1;
645 0 : char *buf=NULL;
646 0 : struct asfd *a=NULL;
647 : struct iobuf wbuf;
648 :
649 0 : if(!(buf=strdup_w("clients", __func__)))
650 : goto end;
651 0 : for(a=mainas->asfd; a; a=a->next)
652 : {
653 0 : if(a->fdtype!=ASFD_FD_SERVER_PIPE_READ
654 0 : || !a->client)
655 0 : continue;
656 0 : if(astrcat(&buf, "\t", __func__))
657 : goto end;
658 0 : if(astrcat(&buf, a->client, __func__))
659 : goto end;
660 : }
661 :
662 0 : iobuf_set(&wbuf, CMD_GEN, buf, strlen(buf));
663 :
664 0 : ret=write_to_status_children(mainas, &wbuf);
665 : end:
666 0 : return ret;
667 : }
668 :
669 0 : static int maybe_update_status_child_client_lists(struct async *mainas)
670 : {
671 0 : time_t now=0;
672 0 : time_t diff=0;
673 : static time_t lasttime=0;
674 0 : struct asfd *asfd=NULL;
675 :
676 : // If we have no status server child processes, do not bother.
677 0 : for(asfd=mainas->asfd; asfd; asfd=asfd->next)
678 0 : if(asfd->fdtype==ASFD_FD_SERVER_PIPE_WRITE)
679 : break;
680 0 : if(!asfd)
681 : return 0;
682 :
683 : // Only update every 5 seconds.
684 0 : now=time(NULL);
685 0 : diff=now-lasttime;
686 0 : if(diff<5)
687 : {
688 : // Might as well do this in case they fiddled their
689 : // clock back in time.
690 0 : if(diff<0) lasttime=now;
691 : return 0;
692 : }
693 0 : lasttime=now;
694 :
695 0 : return update_status_child_client_lists(mainas);
696 : }
697 :
698 0 : static int run_server(struct conf **confs, const char *conffile)
699 : {
700 0 : int ret=-1;
701 0 : SSL_CTX *ctx=NULL;
702 0 : int found_normal_child=0;
703 0 : struct asfd *asfd=NULL;
704 0 : struct async *mainas=NULL;
705 0 : struct strlist *addresses=get_strlist(confs[OPT_LISTEN]);
706 0 : struct strlist *addresses_status=get_strlist(confs[OPT_LISTEN_STATUS]);
707 :
708 0 : if(!(ctx=ssl_initialise_ctx(confs)))
709 : {
710 0 : logp("error initialising ssl ctx\n");
711 0 : goto end;
712 : }
713 0 : if((ssl_load_dh_params(ctx, confs)))
714 : {
715 0 : logp("error loading dh params\n");
716 0 : goto end;
717 : }
718 :
719 0 : if(!(mainas=async_alloc())
720 0 : || mainas->init(mainas, 0))
721 : goto end;
722 :
723 0 : if(init_listen_sockets(addresses, mainas,
724 : ASFD_FD_SERVER_LISTEN_MAIN, "server")
725 0 : || init_listen_sockets(addresses_status, mainas,
726 : ASFD_FD_SERVER_LISTEN_STATUS, "server status"))
727 : goto end;
728 :
729 0 : while(!hupreload)
730 : {
731 : int removed;
732 0 : switch(mainas->read_write(mainas))
733 : {
734 : case 0:
735 0 : for(asfd=mainas->asfd; asfd; asfd=asfd->next)
736 : {
737 0 : if(asfd->new_client)
738 : {
739 : // Incoming client.
740 0 : asfd->new_client=0;
741 0 : if(process_incoming_client(asfd,
742 : ctx, conffile, confs))
743 : goto end;
744 0 : if(!get_int(confs[OPT_FORK]))
745 : {
746 0 : gentleshutdown++;
747 0 : ret=1;
748 0 : goto end;
749 : }
750 0 : continue;
751 : }
752 : }
753 : break;
754 : default:
755 0 : removed=0;
756 : // Maybe one of the fds had a problem.
757 : // Find and remove it and carry on if possible.
758 0 : for(asfd=mainas->asfd; asfd; )
759 : {
760 : struct asfd *a;
761 0 : if(!asfd->want_to_remove)
762 : {
763 0 : asfd=asfd->next;
764 0 : continue;
765 : }
766 0 : mainas->asfd_remove(mainas, asfd);
767 0 : logp("%s: disconnected fd %d\n",
768 0 : asfd->desc, asfd->fd);
769 0 : a=asfd->next;
770 0 : asfd_free(&asfd);
771 0 : asfd=a;
772 0 : removed++;
773 : }
774 0 : if(removed) break;
775 : // If we got here, there was no fd to remove.
776 : // It is a fatal error.
777 : goto end;
778 : }
779 :
780 0 : for(asfd=mainas->asfd; asfd; asfd=asfd->next)
781 : {
782 0 : if(asfd->fdtype!=ASFD_FD_SERVER_PIPE_READ
783 0 : || !asfd->rbuf->buf)
784 0 : continue;
785 :
786 : //printf("got info from child: %s\n", asfd->rbuf->buf);
787 0 : if(extract_client_name(asfd))
788 : goto end;
789 :
790 0 : if(write_to_status_children(mainas, asfd->rbuf))
791 : goto end;
792 : }
793 :
794 0 : if(maybe_update_status_child_client_lists(mainas))
795 : goto end;
796 :
797 0 : chld_check_for_exiting(mainas);
798 :
799 : // Leave if we had a SIGUSR1 and there are no children running.
800 0 : if(gentleshutdown)
801 : {
802 0 : if(!gentleshutdown_logged)
803 : {
804 0 : logp("got SIGUSR2 gentle reload signal\n");
805 0 : logp("will shut down once children have exited\n");
806 0 : gentleshutdown_logged++;
807 : }
808 : // FIX THIS:
809 : // found_normal_child=chld_add_fd_to_normal_sets(confs, &fsr, &fse, &mfd);
810 : else if(!found_normal_child)
811 : {
812 0 : logp("all children have exited - shutting down\n");
813 0 : break;
814 : }
815 : }
816 : }
817 :
818 0 : if(hupreload) logp("got SIGHUP reload signal\n");
819 :
820 : ret=0;
821 : end:
822 0 : async_asfd_free_all(&mainas);
823 0 : if(ctx) ssl_destroy_ctx(ctx);
824 0 : return ret;
825 : }
826 :
827 0 : int server(struct conf **confs, const char *conffile,
828 : struct lock *lock, int generate_ca_only)
829 : {
830 0 : enum serret ret=SERVER_ERROR;
831 :
832 : //return champ_test(confs);
833 :
834 0 : if(ca_server_setup(confs)) goto error;
835 0 : if(generate_ca_only)
836 : {
837 0 : logp("The '-g' command line option was given. Exiting now.\n");
838 0 : goto end;
839 : }
840 :
841 0 : if(get_int(confs[OPT_FORK]) && get_int(confs[OPT_DAEMON]))
842 : {
843 0 : if(daemonise()
844 : // Need to write the new pid to the already open lock fd.
845 0 : || lock_write_pid_and_prog(lock))
846 : goto error;
847 : }
848 :
849 0 : ssl_load_globals();
850 :
851 0 : while(!gentleshutdown)
852 : {
853 0 : if(run_server(confs, conffile))
854 : goto error;
855 :
856 0 : if(hupreload && !gentleshutdown)
857 : {
858 0 : if(reload(confs, conffile,
859 : 0 // Not first time.
860 : ))
861 : goto error;
862 : }
863 0 : hupreload=0;
864 : }
865 :
866 : end:
867 : ret=SERVER_OK;
868 : error:
869 :
870 : // FIX THIS: Have an enum for a return value, so that it is more obvious what
871 : // is happening, like client.c does.
872 0 : return ret;
873 : }
|