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