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