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