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