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