LCOV - code coverage report
Current view: top level - src/server - main.c (source / functions) Hit Total Coverage
Test: burp-coverage-clean.info Lines: 4 450 0.9 %
Date: 2021-06-01 21:59:08 Functions: 1 22 4.5 %

          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             : }

Generated by: LCOV version 1.13