daemon: Set SO_REUSEADDR on listening sockets.
[git.git] / daemon.c
1 #include <signal.h>
2 #include <sys/wait.h>
3 #include <sys/socket.h>
4 #include <sys/time.h>
5 #include <sys/poll.h>
6 #include <netdb.h>
7 #include <netinet/in.h>
8 #include <arpa/inet.h>
9 #include <syslog.h>
10 #include "pkt-line.h"
11 #include "cache.h"
12 #include "exec_cmd.h"
13
14 static int log_syslog;
15 static int verbose;
16 static int reuseaddr;
17
18 static const char daemon_usage[] =
19 "git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n"
20 "           [--timeout=n] [--init-timeout=n] [--strict-paths]\n"
21 "           [--base-path=path] [--reuseaddr] [directory...]";
22
23 /* List of acceptable pathname prefixes */
24 static char **ok_paths = NULL;
25 static int strict_paths = 0;
26
27 /* If this is set, git-daemon-export-ok is not required */
28 static int export_all_trees = 0;
29
30 /* Take all paths relative to this one if non-NULL */
31 static char *base_path = NULL;
32
33 /* Timeout, and initial timeout */
34 static unsigned int timeout = 0;
35 static unsigned int init_timeout = 0;
36
37 static void logreport(int priority, const char *err, va_list params)
38 {
39         /* We should do a single write so that it is atomic and output
40          * of several processes do not get intermingled. */
41         char buf[1024];
42         int buflen;
43         int maxlen, msglen;
44
45         /* sizeof(buf) should be big enough for "[pid] \n" */
46         buflen = snprintf(buf, sizeof(buf), "[%ld] ", (long) getpid());
47
48         maxlen = sizeof(buf) - buflen - 1; /* -1 for our own LF */
49         msglen = vsnprintf(buf + buflen, maxlen, err, params);
50
51         if (log_syslog) {
52                 syslog(priority, "%s", buf);
53                 return;
54         }
55
56         /* maxlen counted our own LF but also counts space given to
57          * vsnprintf for the terminating NUL.  We want to make sure that
58          * we have space for our own LF and NUL after the "meat" of the
59          * message, so truncate it at maxlen - 1.
60          */
61         if (msglen > maxlen - 1)
62                 msglen = maxlen - 1;
63         else if (msglen < 0)
64                 msglen = 0; /* Protect against weird return values. */
65         buflen += msglen;
66
67         buf[buflen++] = '\n';
68         buf[buflen] = '\0';
69
70         write(2, buf, buflen);
71 }
72
73 static void logerror(const char *err, ...)
74 {
75         va_list params;
76         va_start(params, err);
77         logreport(LOG_ERR, err, params);
78         va_end(params);
79 }
80
81 static void loginfo(const char *err, ...)
82 {
83         va_list params;
84         if (!verbose)
85                 return;
86         va_start(params, err);
87         logreport(LOG_INFO, err, params);
88         va_end(params);
89 }
90
91 static int avoid_alias(char *p)
92 {
93         int sl, ndot;
94
95         /* 
96          * This resurrects the belts and suspenders paranoia check by HPA
97          * done in <435560F7.4080006@zytor.com> thread, now enter_repo()
98          * does not do getcwd() based path canonicalizations.
99          *
100          * sl becomes true immediately after seeing '/' and continues to
101          * be true as long as dots continue after that without intervening
102          * non-dot character.
103          */
104         if (!p || (*p != '/' && *p != '~'))
105                 return -1;
106         sl = 1; ndot = 0;
107         p++;
108
109         while (1) {
110                 char ch = *p++;
111                 if (sl) {
112                         if (ch == '.')
113                                 ndot++;
114                         else if (ch == '/') {
115                                 if (ndot < 3)
116                                         /* reject //, /./ and /../ */
117                                         return -1;
118                                 ndot = 0;
119                         }
120                         else if (ch == 0) {
121                                 if (0 < ndot && ndot < 3)
122                                         /* reject /.$ and /..$ */
123                                         return -1;
124                                 return 0;
125                         }
126                         else
127                                 sl = ndot = 0;
128                 }
129                 else if (ch == 0)
130                         return 0;
131                 else if (ch == '/') {
132                         sl = 1;
133                         ndot = 0;
134                 }
135         }
136 }
137
138 static char *path_ok(char *dir)
139 {
140         char *path;
141
142         if (avoid_alias(dir)) {
143                 logerror("'%s': aliased", dir);
144                 return NULL;
145         }
146
147         if (base_path) {
148                 static char rpath[PATH_MAX];
149                 if (!strict_paths && *dir == '~')
150                         ; /* allow user relative paths */
151                 else if (*dir != '/') {
152                         /* otherwise allow only absolute */
153                         logerror("'%s': Non-absolute path denied (base-path active)", dir);
154                         return NULL;
155                 }
156                 else {
157                         snprintf(rpath, PATH_MAX, "%s%s", base_path, dir);
158                         dir = rpath;
159                 }
160         }
161
162         path = enter_repo(dir, strict_paths);
163
164         if (!path) {
165                 logerror("'%s': unable to chdir or not a git archive", dir);
166                 return NULL;
167         }
168
169         if ( ok_paths && *ok_paths ) {
170                 char **pp;
171                 int pathlen = strlen(path);
172
173                 /* The validation is done on the paths after enter_repo
174                  * appends optional {.git,.git/.git} and friends, but 
175                  * it does not use getcwd().  So if your /pub is
176                  * a symlink to /mnt/pub, you can whitelist /pub and
177                  * do not have to say /mnt/pub.
178                  * Do not say /pub/.
179                  */
180                 for ( pp = ok_paths ; *pp ; pp++ ) {
181                         int len = strlen(*pp);
182                         if (len <= pathlen &&
183                             !memcmp(*pp, path, len) &&
184                             (path[len] == '\0' ||
185                              (!strict_paths && path[len] == '/')))
186                                 return path;
187                 }
188         }
189         else {
190                 /* be backwards compatible */
191                 if (!strict_paths)
192                         return path;
193         }
194
195         logerror("'%s': not in whitelist", path);
196         return NULL;            /* Fallthrough. Deny by default */
197 }
198
199 static int upload(char *dir)
200 {
201         /* Timeout as string */
202         char timeout_buf[64];
203         const char *path;
204
205         loginfo("Request for '%s'", dir);
206
207         if (!(path = path_ok(dir)))
208                 return -1;
209
210         /*
211          * Security on the cheap.
212          *
213          * We want a readable HEAD, usable "objects" directory, and
214          * a "git-daemon-export-ok" flag that says that the other side
215          * is ok with us doing this.
216          *
217          * path_ok() uses enter_repo() and does whitelist checking.
218          * We only need to make sure the repository is exported.
219          */
220
221         if (!export_all_trees && access("git-daemon-export-ok", F_OK)) {
222                 logerror("'%s': repository not exported.", path);
223                 errno = EACCES;
224                 return -1;
225         }
226
227         /*
228          * We'll ignore SIGTERM from now on, we have a
229          * good client.
230          */
231         signal(SIGTERM, SIG_IGN);
232
233         snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
234
235         /* git-upload-pack only ever reads stuff, so this is safe */
236         execl_git_cmd("upload-pack", "--strict", timeout_buf, ".", NULL);
237         return -1;
238 }
239
240 static int execute(void)
241 {
242         static char line[1000];
243         int len;
244
245         alarm(init_timeout ? init_timeout : timeout);
246         len = packet_read_line(0, line, sizeof(line));
247         alarm(0);
248
249         if (len && line[len-1] == '\n')
250                 line[--len] = 0;
251
252         if (!strncmp("git-upload-pack ", line, 16))
253                 return upload(line+16);
254
255         logerror("Protocol error: '%s'", line);
256         return -1;
257 }
258
259
260 /*
261  * We count spawned/reaped separately, just to avoid any
262  * races when updating them from signals. The SIGCHLD handler
263  * will only update children_reaped, and the fork logic will
264  * only update children_spawned.
265  *
266  * MAX_CHILDREN should be a power-of-two to make the modulus
267  * operation cheap. It should also be at least twice
268  * the maximum number of connections we will ever allow.
269  */
270 #define MAX_CHILDREN 128
271
272 static int max_connections = 25;
273
274 /* These are updated by the signal handler */
275 static volatile unsigned int children_reaped = 0;
276 static pid_t dead_child[MAX_CHILDREN];
277
278 /* These are updated by the main loop */
279 static unsigned int children_spawned = 0;
280 static unsigned int children_deleted = 0;
281
282 static struct child {
283         pid_t pid;
284         int addrlen;
285         struct sockaddr_storage address;
286 } live_child[MAX_CHILDREN];
287
288 static void add_child(int idx, pid_t pid, struct sockaddr *addr, int addrlen)
289 {
290         live_child[idx].pid = pid;
291         live_child[idx].addrlen = addrlen;
292         memcpy(&live_child[idx].address, addr, addrlen);
293 }
294
295 /*
296  * Walk from "deleted" to "spawned", and remove child "pid".
297  *
298  * We move everything up by one, since the new "deleted" will
299  * be one higher.
300  */
301 static void remove_child(pid_t pid, unsigned deleted, unsigned spawned)
302 {
303         struct child n;
304
305         deleted %= MAX_CHILDREN;
306         spawned %= MAX_CHILDREN;
307         if (live_child[deleted].pid == pid) {
308                 live_child[deleted].pid = -1;
309                 return;
310         }
311         n = live_child[deleted];
312         for (;;) {
313                 struct child m;
314                 deleted = (deleted + 1) % MAX_CHILDREN;
315                 if (deleted == spawned)
316                         die("could not find dead child %d\n", pid);
317                 m = live_child[deleted];
318                 live_child[deleted] = n;
319                 if (m.pid == pid)
320                         return;
321                 n = m;
322         }
323 }
324
325 /*
326  * This gets called if the number of connections grows
327  * past "max_connections".
328  *
329  * We _should_ start off by searching for connections
330  * from the same IP, and if there is some address wth
331  * multiple connections, we should kill that first.
332  *
333  * As it is, we just "randomly" kill 25% of the connections,
334  * and our pseudo-random generator sucks too. I have no
335  * shame.
336  *
337  * Really, this is just a place-holder for a _real_ algorithm.
338  */
339 static void kill_some_children(int signo, unsigned start, unsigned stop)
340 {
341         start %= MAX_CHILDREN;
342         stop %= MAX_CHILDREN;
343         while (start != stop) {
344                 if (!(start & 3))
345                         kill(live_child[start].pid, signo);
346                 start = (start + 1) % MAX_CHILDREN;
347         }
348 }
349
350 static void check_max_connections(void)
351 {
352         for (;;) {
353                 int active;
354                 unsigned spawned, reaped, deleted;
355
356                 spawned = children_spawned;
357                 reaped = children_reaped;
358                 deleted = children_deleted;
359
360                 while (deleted < reaped) {
361                         pid_t pid = dead_child[deleted % MAX_CHILDREN];
362                         remove_child(pid, deleted, spawned);
363                         deleted++;
364                 }
365                 children_deleted = deleted;
366
367                 active = spawned - deleted;
368                 if (active <= max_connections)
369                         break;
370
371                 /* Kill some unstarted connections with SIGTERM */
372                 kill_some_children(SIGTERM, deleted, spawned);
373                 if (active <= max_connections << 1)
374                         break;
375
376                 /* If the SIGTERM thing isn't helping use SIGKILL */
377                 kill_some_children(SIGKILL, deleted, spawned);
378                 sleep(1);
379         }
380 }
381
382 static void handle(int incoming, struct sockaddr *addr, int addrlen)
383 {
384         pid_t pid = fork();
385         char addrbuf[256] = "";
386         int port = -1;
387
388         if (pid) {
389                 unsigned idx;
390
391                 close(incoming);
392                 if (pid < 0)
393                         return;
394
395                 idx = children_spawned % MAX_CHILDREN;
396                 children_spawned++;
397                 add_child(idx, pid, addr, addrlen);
398
399                 check_max_connections();
400                 return;
401         }
402
403         dup2(incoming, 0);
404         dup2(incoming, 1);
405         close(incoming);
406
407         if (addr->sa_family == AF_INET) {
408                 struct sockaddr_in *sin_addr = (void *) addr;
409                 inet_ntop(AF_INET, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
410                 port = sin_addr->sin_port;
411
412 #ifndef NO_IPV6
413         } else if (addr->sa_family == AF_INET6) {
414                 struct sockaddr_in6 *sin6_addr = (void *) addr;
415
416                 char *buf = addrbuf;
417                 *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
418                 inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
419                 strcat(buf, "]");
420
421                 port = sin6_addr->sin6_port;
422 #endif
423         }
424         loginfo("Connection from %s:%d", addrbuf, port);
425
426         exit(execute());
427 }
428
429 static void child_handler(int signo)
430 {
431         for (;;) {
432                 int status;
433                 pid_t pid = waitpid(-1, &status, WNOHANG);
434
435                 if (pid > 0) {
436                         unsigned reaped = children_reaped;
437                         dead_child[reaped % MAX_CHILDREN] = pid;
438                         children_reaped = reaped + 1;
439                         /* XXX: Custom logging, since we don't wanna getpid() */
440                         if (verbose) {
441                                 char *dead = "";
442                                 if (!WIFEXITED(status) || WEXITSTATUS(status) > 0)
443                                         dead = " (with error)";
444                                 if (log_syslog)
445                                         syslog(LOG_INFO, "[%d] Disconnected%s", pid, dead);
446                                 else
447                                         fprintf(stderr, "[%d] Disconnected%s\n", pid, dead);
448                         }
449                         continue;
450                 }
451                 break;
452         }
453 }
454
455 static int set_reuse_addr(int sockfd)
456 {
457         int on = 1;
458
459         if (!reuseaddr)
460                 return 0;
461         return setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
462                           &on, sizeof(on));
463 }
464
465 #ifndef NO_IPV6
466
467 static int socksetup(int port, int **socklist_p)
468 {
469         int socknum = 0, *socklist = NULL;
470         int maxfd = -1;
471         char pbuf[NI_MAXSERV];
472
473         struct addrinfo hints, *ai0, *ai;
474         int gai;
475
476         sprintf(pbuf, "%d", port);
477         memset(&hints, 0, sizeof(hints));
478         hints.ai_family = AF_UNSPEC;
479         hints.ai_socktype = SOCK_STREAM;
480         hints.ai_protocol = IPPROTO_TCP;
481         hints.ai_flags = AI_PASSIVE;
482
483         gai = getaddrinfo(NULL, pbuf, &hints, &ai0);
484         if (gai)
485                 die("getaddrinfo() failed: %s\n", gai_strerror(gai));
486
487         for (ai = ai0; ai; ai = ai->ai_next) {
488                 int sockfd;
489                 int *newlist;
490
491                 sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
492                 if (sockfd < 0)
493                         continue;
494                 if (sockfd >= FD_SETSIZE) {
495                         error("too large socket descriptor.");
496                         close(sockfd);
497                         continue;
498                 }
499
500 #ifdef IPV6_V6ONLY
501                 if (ai->ai_family == AF_INET6) {
502                         int on = 1;
503                         setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
504                                    &on, sizeof(on));
505                         /* Note: error is not fatal */
506                 }
507 #endif
508
509                 if (set_reuse_addr(sockfd)) {
510                         close(sockfd);
511                         return 0;       /* not fatal */
512                 }
513
514                 if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
515                         close(sockfd);
516                         continue;       /* not fatal */
517                 }
518                 if (listen(sockfd, 5) < 0) {
519                         close(sockfd);
520                         continue;       /* not fatal */
521                 }
522
523                 newlist = realloc(socklist, sizeof(int) * (socknum + 1));
524                 if (!newlist)
525                         die("memory allocation failed: %s", strerror(errno));
526
527                 socklist = newlist;
528                 socklist[socknum++] = sockfd;
529
530                 if (maxfd < sockfd)
531                         maxfd = sockfd;
532         }
533
534         freeaddrinfo(ai0);
535
536         *socklist_p = socklist;
537         return socknum;
538 }
539
540 #else /* NO_IPV6 */
541
542 static int socksetup(int port, int **socklist_p)
543 {
544         struct sockaddr_in sin;
545         int sockfd;
546
547         sockfd = socket(AF_INET, SOCK_STREAM, 0);
548         if (sockfd < 0)
549                 return 0;
550
551         memset(&sin, 0, sizeof sin);
552         sin.sin_family = AF_INET;
553         sin.sin_addr.s_addr = htonl(INADDR_ANY);
554         sin.sin_port = htons(port);
555
556         if (set_reuse_addr(sockfd)) {
557                 close(sockfd);
558                 return 0;
559         }
560
561         if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) {
562                 close(sockfd);
563                 return 0;
564         }
565
566         if (listen(sockfd, 5) < 0) {
567                 close(sockfd);
568                 return 0;
569         }
570
571         *socklist_p = xmalloc(sizeof(int));
572         **socklist_p = sockfd;
573         return 1;
574 }
575
576 #endif
577
578 static int service_loop(int socknum, int *socklist)
579 {
580         struct pollfd *pfd;
581         int i;
582
583         pfd = xcalloc(socknum, sizeof(struct pollfd));
584
585         for (i = 0; i < socknum; i++) {
586                 pfd[i].fd = socklist[i];
587                 pfd[i].events = POLLIN;
588         }
589
590         signal(SIGCHLD, child_handler);
591
592         for (;;) {
593                 int i;
594
595                 if (poll(pfd, socknum, -1) < 0) {
596                         if (errno != EINTR) {
597                                 error("poll failed, resuming: %s",
598                                       strerror(errno));
599                                 sleep(1);
600                         }
601                         continue;
602                 }
603
604                 for (i = 0; i < socknum; i++) {
605                         if (pfd[i].revents & POLLIN) {
606                                 struct sockaddr_storage ss;
607                                 unsigned int sslen = sizeof(ss);
608                                 int incoming = accept(pfd[i].fd, (struct sockaddr *)&ss, &sslen);
609                                 if (incoming < 0) {
610                                         switch (errno) {
611                                         case EAGAIN:
612                                         case EINTR:
613                                         case ECONNABORTED:
614                                                 continue;
615                                         default:
616                                                 die("accept returned %s", strerror(errno));
617                                         }
618                                 }
619                                 handle(incoming, (struct sockaddr *)&ss, sslen);
620                         }
621                 }
622         }
623 }
624
625 static int serve(int port)
626 {
627         int socknum, *socklist;
628
629         socknum = socksetup(port, &socklist);
630         if (socknum == 0)
631                 die("unable to allocate any listen sockets on port %u", port);
632
633         return service_loop(socknum, socklist);
634 }
635
636 int main(int argc, char **argv)
637 {
638         int port = DEFAULT_GIT_PORT;
639         int inetd_mode = 0;
640         int i;
641
642         for (i = 1; i < argc; i++) {
643                 char *arg = argv[i];
644
645                 if (!strncmp(arg, "--port=", 7)) {
646                         char *end;
647                         unsigned long n;
648                         n = strtoul(arg+7, &end, 0);
649                         if (arg[7] && !*end) {
650                                 port = n;
651                                 continue;
652                         }
653                 }
654                 if (!strcmp(arg, "--inetd")) {
655                         inetd_mode = 1;
656                         log_syslog = 1;
657                         continue;
658                 }
659                 if (!strcmp(arg, "--verbose")) {
660                         verbose = 1;
661                         continue;
662                 }
663                 if (!strcmp(arg, "--syslog")) {
664                         log_syslog = 1;
665                         continue;
666                 }
667                 if (!strcmp(arg, "--export-all")) {
668                         export_all_trees = 1;
669                         continue;
670                 }
671                 if (!strncmp(arg, "--timeout=", 10)) {
672                         timeout = atoi(arg+10);
673                         continue;
674                 }
675                 if (!strncmp(arg, "--init-timeout=", 15)) {
676                         init_timeout = atoi(arg+15);
677                         continue;
678                 }
679                 if (!strcmp(arg, "--strict-paths")) {
680                         strict_paths = 1;
681                         continue;
682                 }
683                 if (!strncmp(arg, "--base-path=", 12)) {
684                         base_path = arg+12;
685                         continue;
686                 }
687                 if (!strcmp(arg, "--reuseaddr")) {
688                         reuseaddr = 1;
689                         continue;
690                 }
691                 if (!strcmp(arg, "--")) {
692                         ok_paths = &argv[i+1];
693                         break;
694                 } else if (arg[0] != '-') {
695                         ok_paths = &argv[i];
696                         break;
697                 }
698
699                 usage(daemon_usage);
700         }
701
702         if (log_syslog)
703                 openlog("git-daemon", 0, LOG_DAEMON);
704
705         if (strict_paths && (!ok_paths || !*ok_paths)) {
706                 if (!inetd_mode)
707                         die("git-daemon: option --strict-paths requires a whitelist");
708
709                 logerror("option --strict-paths requires a whitelist");
710                 exit (1);
711         }
712
713         if (inetd_mode) {
714                 fclose(stderr); //FIXME: workaround
715                 return execute();
716         }
717
718         return serve(port);
719 }