daemon.con commit Windows: avoid the "dup dance" when spawning a child process (75301f9)
   1#include "cache.h"
   2#include "pkt-line.h"
   3#include "exec_cmd.h"
   4#include "run-command.h"
   5#include "strbuf.h"
   6
   7#include <syslog.h>
   8
   9#ifndef HOST_NAME_MAX
  10#define HOST_NAME_MAX 256
  11#endif
  12
  13#ifndef NI_MAXSERV
  14#define NI_MAXSERV 32
  15#endif
  16
  17static int log_syslog;
  18static int verbose;
  19static int reuseaddr;
  20
  21static const char daemon_usage[] =
  22"git daemon [--verbose] [--syslog] [--export-all]\n"
  23"           [--timeout=n] [--init-timeout=n] [--max-connections=n]\n"
  24"           [--strict-paths] [--base-path=path] [--base-path-relaxed]\n"
  25"           [--user-path | --user-path=path]\n"
  26"           [--interpolated-path=path]\n"
  27"           [--reuseaddr] [--detach] [--pid-file=file]\n"
  28"           [--[enable|disable|allow-override|forbid-override]=service]\n"
  29"           [--inetd | [--listen=host_or_ipaddr] [--port=n]\n"
  30"                      [--user=user [--group=group]]\n"
  31"           [directory...]";
  32
  33/* List of acceptable pathname prefixes */
  34static char **ok_paths;
  35static int strict_paths;
  36
  37/* If this is set, git-daemon-export-ok is not required */
  38static int export_all_trees;
  39
  40/* Take all paths relative to this one if non-NULL */
  41static char *base_path;
  42static char *interpolated_path;
  43static int base_path_relaxed;
  44
  45/* Flag indicating client sent extra args. */
  46static int saw_extended_args;
  47
  48/* If defined, ~user notation is allowed and the string is inserted
  49 * after ~user/.  E.g. a request to git://host/~alice/frotz would
  50 * go to /home/alice/pub_git/frotz with --user-path=pub_git.
  51 */
  52static const char *user_path;
  53
  54/* Timeout, and initial timeout */
  55static unsigned int timeout;
  56static unsigned int init_timeout;
  57
  58static char *hostname;
  59static char *canon_hostname;
  60static char *ip_address;
  61static char *tcp_port;
  62
  63static void logreport(int priority, const char *err, va_list params)
  64{
  65        if (log_syslog) {
  66                char buf[1024];
  67                vsnprintf(buf, sizeof(buf), err, params);
  68                syslog(priority, "%s", buf);
  69        } else {
  70                /*
  71                 * Since stderr is set to linebuffered mode, the
  72                 * logging of different processes will not overlap
  73                 */
  74                fprintf(stderr, "[%"PRIuMAX"] ", (uintmax_t)getpid());
  75                vfprintf(stderr, err, params);
  76                fputc('\n', stderr);
  77        }
  78}
  79
  80__attribute__((format (printf, 1, 2)))
  81static void logerror(const char *err, ...)
  82{
  83        va_list params;
  84        va_start(params, err);
  85        logreport(LOG_ERR, err, params);
  86        va_end(params);
  87}
  88
  89__attribute__((format (printf, 1, 2)))
  90static void loginfo(const char *err, ...)
  91{
  92        va_list params;
  93        if (!verbose)
  94                return;
  95        va_start(params, err);
  96        logreport(LOG_INFO, err, params);
  97        va_end(params);
  98}
  99
 100static void NORETURN daemon_die(const char *err, va_list params)
 101{
 102        logreport(LOG_ERR, err, params);
 103        exit(1);
 104}
 105
 106static char *path_ok(char *directory)
 107{
 108        static char rpath[PATH_MAX];
 109        static char interp_path[PATH_MAX];
 110        char *path;
 111        char *dir;
 112
 113        dir = directory;
 114
 115        if (daemon_avoid_alias(dir)) {
 116                logerror("'%s': aliased", dir);
 117                return NULL;
 118        }
 119
 120        if (*dir == '~') {
 121                if (!user_path) {
 122                        logerror("'%s': User-path not allowed", dir);
 123                        return NULL;
 124                }
 125                if (*user_path) {
 126                        /* Got either "~alice" or "~alice/foo";
 127                         * rewrite them to "~alice/%s" or
 128                         * "~alice/%s/foo".
 129                         */
 130                        int namlen, restlen = strlen(dir);
 131                        char *slash = strchr(dir, '/');
 132                        if (!slash)
 133                                slash = dir + restlen;
 134                        namlen = slash - dir;
 135                        restlen -= namlen;
 136                        loginfo("userpath <%s>, request <%s>, namlen %d, restlen %d, slash <%s>", user_path, dir, namlen, restlen, slash);
 137                        snprintf(rpath, PATH_MAX, "%.*s/%s%.*s",
 138                                 namlen, dir, user_path, restlen, slash);
 139                        dir = rpath;
 140                }
 141        }
 142        else if (interpolated_path && saw_extended_args) {
 143                struct strbuf expanded_path = STRBUF_INIT;
 144                struct strbuf_expand_dict_entry dict[] = {
 145                        { "H", hostname },
 146                        { "CH", canon_hostname },
 147                        { "IP", ip_address },
 148                        { "P", tcp_port },
 149                        { "D", directory },
 150                        { "%", "%" },
 151                        { NULL }
 152                };
 153
 154                if (*dir != '/') {
 155                        /* Allow only absolute */
 156                        logerror("'%s': Non-absolute path denied (interpolated-path active)", dir);
 157                        return NULL;
 158                }
 159
 160                strbuf_expand(&expanded_path, interpolated_path,
 161                                strbuf_expand_dict_cb, &dict);
 162                strlcpy(interp_path, expanded_path.buf, PATH_MAX);
 163                strbuf_release(&expanded_path);
 164                loginfo("Interpolated dir '%s'", interp_path);
 165
 166                dir = interp_path;
 167        }
 168        else if (base_path) {
 169                if (*dir != '/') {
 170                        /* Allow only absolute */
 171                        logerror("'%s': Non-absolute path denied (base-path active)", dir);
 172                        return NULL;
 173                }
 174                snprintf(rpath, PATH_MAX, "%s%s", base_path, dir);
 175                dir = rpath;
 176        }
 177
 178        path = enter_repo(dir, strict_paths);
 179        if (!path && base_path && base_path_relaxed) {
 180                /*
 181                 * if we fail and base_path_relaxed is enabled, try without
 182                 * prefixing the base path
 183                 */
 184                dir = directory;
 185                path = enter_repo(dir, strict_paths);
 186        }
 187
 188        if (!path) {
 189                logerror("'%s' does not appear to be a git repository", dir);
 190                return NULL;
 191        }
 192
 193        if ( ok_paths && *ok_paths ) {
 194                char **pp;
 195                int pathlen = strlen(path);
 196
 197                /* The validation is done on the paths after enter_repo
 198                 * appends optional {.git,.git/.git} and friends, but
 199                 * it does not use getcwd().  So if your /pub is
 200                 * a symlink to /mnt/pub, you can whitelist /pub and
 201                 * do not have to say /mnt/pub.
 202                 * Do not say /pub/.
 203                 */
 204                for ( pp = ok_paths ; *pp ; pp++ ) {
 205                        int len = strlen(*pp);
 206                        if (len <= pathlen &&
 207                            !memcmp(*pp, path, len) &&
 208                            (path[len] == '\0' ||
 209                             (!strict_paths && path[len] == '/')))
 210                                return path;
 211                }
 212        }
 213        else {
 214                /* be backwards compatible */
 215                if (!strict_paths)
 216                        return path;
 217        }
 218
 219        logerror("'%s': not in whitelist", path);
 220        return NULL;            /* Fallthrough. Deny by default */
 221}
 222
 223typedef int (*daemon_service_fn)(void);
 224struct daemon_service {
 225        const char *name;
 226        const char *config_name;
 227        daemon_service_fn fn;
 228        int enabled;
 229        int overridable;
 230};
 231
 232static struct daemon_service *service_looking_at;
 233static int service_enabled;
 234
 235static int git_daemon_config(const char *var, const char *value, void *cb)
 236{
 237        if (!prefixcmp(var, "daemon.") &&
 238            !strcmp(var + 7, service_looking_at->config_name)) {
 239                service_enabled = git_config_bool(var, value);
 240                return 0;
 241        }
 242
 243        /* we are not interested in parsing any other configuration here */
 244        return 0;
 245}
 246
 247static int run_service(char *dir, struct daemon_service *service)
 248{
 249        const char *path;
 250        int enabled = service->enabled;
 251
 252        loginfo("Request %s for '%s'", service->name, dir);
 253
 254        if (!enabled && !service->overridable) {
 255                logerror("'%s': service not enabled.", service->name);
 256                errno = EACCES;
 257                return -1;
 258        }
 259
 260        if (!(path = path_ok(dir)))
 261                return -1;
 262
 263        /*
 264         * Security on the cheap.
 265         *
 266         * We want a readable HEAD, usable "objects" directory, and
 267         * a "git-daemon-export-ok" flag that says that the other side
 268         * is ok with us doing this.
 269         *
 270         * path_ok() uses enter_repo() and does whitelist checking.
 271         * We only need to make sure the repository is exported.
 272         */
 273
 274        if (!export_all_trees && access("git-daemon-export-ok", F_OK)) {
 275                logerror("'%s': repository not exported.", path);
 276                errno = EACCES;
 277                return -1;
 278        }
 279
 280        if (service->overridable) {
 281                service_looking_at = service;
 282                service_enabled = -1;
 283                git_config(git_daemon_config, NULL);
 284                if (0 <= service_enabled)
 285                        enabled = service_enabled;
 286        }
 287        if (!enabled) {
 288                logerror("'%s': service not enabled for '%s'",
 289                         service->name, path);
 290                errno = EACCES;
 291                return -1;
 292        }
 293
 294        /*
 295         * We'll ignore SIGTERM from now on, we have a
 296         * good client.
 297         */
 298        signal(SIGTERM, SIG_IGN);
 299
 300        return service->fn();
 301}
 302
 303static void copy_to_log(int fd)
 304{
 305        struct strbuf line = STRBUF_INIT;
 306        FILE *fp;
 307
 308        fp = fdopen(fd, "r");
 309        if (fp == NULL) {
 310                logerror("fdopen of error channel failed");
 311                close(fd);
 312                return;
 313        }
 314
 315        while (strbuf_getline(&line, fp, '\n') != EOF) {
 316                logerror("%s", line.buf);
 317                strbuf_setlen(&line, 0);
 318        }
 319
 320        strbuf_release(&line);
 321        fclose(fp);
 322}
 323
 324static int run_service_command(const char **argv)
 325{
 326        struct child_process cld;
 327
 328        memset(&cld, 0, sizeof(cld));
 329        cld.argv = argv;
 330        cld.git_cmd = 1;
 331        cld.err = -1;
 332        if (start_command(&cld))
 333                return -1;
 334
 335        close(0);
 336        close(1);
 337
 338        copy_to_log(cld.err);
 339
 340        return finish_command(&cld);
 341}
 342
 343static int upload_pack(void)
 344{
 345        /* Timeout as string */
 346        char timeout_buf[64];
 347        const char *argv[] = { "upload-pack", "--strict", timeout_buf, ".", NULL };
 348
 349        snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
 350        return run_service_command(argv);
 351}
 352
 353static int upload_archive(void)
 354{
 355        static const char *argv[] = { "upload-archive", ".", NULL };
 356        return run_service_command(argv);
 357}
 358
 359static int receive_pack(void)
 360{
 361        static const char *argv[] = { "receive-pack", ".", NULL };
 362        return run_service_command(argv);
 363}
 364
 365static struct daemon_service daemon_service[] = {
 366        { "upload-archive", "uploadarch", upload_archive, 0, 1 },
 367        { "upload-pack", "uploadpack", upload_pack, 1, 1 },
 368        { "receive-pack", "receivepack", receive_pack, 0, 1 },
 369};
 370
 371static void enable_service(const char *name, int ena)
 372{
 373        int i;
 374        for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
 375                if (!strcmp(daemon_service[i].name, name)) {
 376                        daemon_service[i].enabled = ena;
 377                        return;
 378                }
 379        }
 380        die("No such service %s", name);
 381}
 382
 383static void make_service_overridable(const char *name, int ena)
 384{
 385        int i;
 386        for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
 387                if (!strcmp(daemon_service[i].name, name)) {
 388                        daemon_service[i].overridable = ena;
 389                        return;
 390                }
 391        }
 392        die("No such service %s", name);
 393}
 394
 395static char *xstrdup_tolower(const char *str)
 396{
 397        char *p, *dup = xstrdup(str);
 398        for (p = dup; *p; p++)
 399                *p = tolower(*p);
 400        return dup;
 401}
 402
 403/*
 404 * Read the host as supplied by the client connection.
 405 */
 406static void parse_host_arg(char *extra_args, int buflen)
 407{
 408        char *val;
 409        int vallen;
 410        char *end = extra_args + buflen;
 411
 412        if (extra_args < end && *extra_args) {
 413                saw_extended_args = 1;
 414                if (strncasecmp("host=", extra_args, 5) == 0) {
 415                        val = extra_args + 5;
 416                        vallen = strlen(val) + 1;
 417                        if (*val) {
 418                                /* Split <host>:<port> at colon. */
 419                                char *host = val;
 420                                char *port = strrchr(host, ':');
 421                                if (port) {
 422                                        *port = 0;
 423                                        port++;
 424                                        free(tcp_port);
 425                                        tcp_port = xstrdup(port);
 426                                }
 427                                free(hostname);
 428                                hostname = xstrdup_tolower(host);
 429                        }
 430
 431                        /* On to the next one */
 432                        extra_args = val + vallen;
 433                }
 434                if (extra_args < end && *extra_args)
 435                        die("Invalid request");
 436        }
 437
 438        /*
 439         * Locate canonical hostname and its IP address.
 440         */
 441        if (hostname) {
 442#ifndef NO_IPV6
 443                struct addrinfo hints;
 444                struct addrinfo *ai;
 445                int gai;
 446                static char addrbuf[HOST_NAME_MAX + 1];
 447
 448                memset(&hints, 0, sizeof(hints));
 449                hints.ai_flags = AI_CANONNAME;
 450
 451                gai = getaddrinfo(hostname, NULL, &hints, &ai);
 452                if (!gai) {
 453                        struct sockaddr_in *sin_addr = (void *)ai->ai_addr;
 454
 455                        inet_ntop(AF_INET, &sin_addr->sin_addr,
 456                                  addrbuf, sizeof(addrbuf));
 457                        free(ip_address);
 458                        ip_address = xstrdup(addrbuf);
 459
 460                        free(canon_hostname);
 461                        canon_hostname = xstrdup(ai->ai_canonname ?
 462                                                 ai->ai_canonname : ip_address);
 463
 464                        freeaddrinfo(ai);
 465                }
 466#else
 467                struct hostent *hent;
 468                struct sockaddr_in sa;
 469                char **ap;
 470                static char addrbuf[HOST_NAME_MAX + 1];
 471
 472                hent = gethostbyname(hostname);
 473
 474                ap = hent->h_addr_list;
 475                memset(&sa, 0, sizeof sa);
 476                sa.sin_family = hent->h_addrtype;
 477                sa.sin_port = htons(0);
 478                memcpy(&sa.sin_addr, *ap, hent->h_length);
 479
 480                inet_ntop(hent->h_addrtype, &sa.sin_addr,
 481                          addrbuf, sizeof(addrbuf));
 482
 483                free(canon_hostname);
 484                canon_hostname = xstrdup(hent->h_name);
 485                free(ip_address);
 486                ip_address = xstrdup(addrbuf);
 487#endif
 488        }
 489}
 490
 491
 492static int execute(struct sockaddr *addr)
 493{
 494        static char line[1000];
 495        int pktlen, len, i;
 496
 497        if (addr) {
 498                char addrbuf[256] = "";
 499                int port = -1;
 500
 501                if (addr->sa_family == AF_INET) {
 502                        struct sockaddr_in *sin_addr = (void *) addr;
 503                        inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
 504                        port = ntohs(sin_addr->sin_port);
 505#ifndef NO_IPV6
 506                } else if (addr && addr->sa_family == AF_INET6) {
 507                        struct sockaddr_in6 *sin6_addr = (void *) addr;
 508
 509                        char *buf = addrbuf;
 510                        *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
 511                        inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
 512                        strcat(buf, "]");
 513
 514                        port = ntohs(sin6_addr->sin6_port);
 515#endif
 516                }
 517                loginfo("Connection from %s:%d", addrbuf, port);
 518                setenv("REMOTE_ADDR", addrbuf, 1);
 519        }
 520        else {
 521                unsetenv("REMOTE_ADDR");
 522        }
 523
 524        alarm(init_timeout ? init_timeout : timeout);
 525        pktlen = packet_read_line(0, line, sizeof(line));
 526        alarm(0);
 527
 528        len = strlen(line);
 529        if (pktlen != len)
 530                loginfo("Extended attributes (%d bytes) exist <%.*s>",
 531                        (int) pktlen - len,
 532                        (int) pktlen - len, line + len + 1);
 533        if (len && line[len-1] == '\n') {
 534                line[--len] = 0;
 535                pktlen--;
 536        }
 537
 538        free(hostname);
 539        free(canon_hostname);
 540        free(ip_address);
 541        free(tcp_port);
 542        hostname = canon_hostname = ip_address = tcp_port = NULL;
 543
 544        if (len != pktlen)
 545                parse_host_arg(line + len + 1, pktlen - len - 1);
 546
 547        for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
 548                struct daemon_service *s = &(daemon_service[i]);
 549                int namelen = strlen(s->name);
 550                if (!prefixcmp(line, "git-") &&
 551                    !strncmp(s->name, line + 4, namelen) &&
 552                    line[namelen + 4] == ' ') {
 553                        /*
 554                         * Note: The directory here is probably context sensitive,
 555                         * and might depend on the actual service being performed.
 556                         */
 557                        return run_service(line + namelen + 5, s);
 558                }
 559        }
 560
 561        logerror("Protocol error: '%s'", line);
 562        return -1;
 563}
 564
 565static int addrcmp(const struct sockaddr_storage *s1,
 566    const struct sockaddr_storage *s2)
 567{
 568        if (s1->ss_family != s2->ss_family)
 569                return s1->ss_family - s2->ss_family;
 570        if (s1->ss_family == AF_INET)
 571                return memcmp(&((struct sockaddr_in *)s1)->sin_addr,
 572                    &((struct sockaddr_in *)s2)->sin_addr,
 573                    sizeof(struct in_addr));
 574#ifndef NO_IPV6
 575        if (s1->ss_family == AF_INET6)
 576                return memcmp(&((struct sockaddr_in6 *)s1)->sin6_addr,
 577                    &((struct sockaddr_in6 *)s2)->sin6_addr,
 578                    sizeof(struct in6_addr));
 579#endif
 580        return 0;
 581}
 582
 583static int max_connections = 32;
 584
 585static unsigned int live_children;
 586
 587static struct child {
 588        struct child *next;
 589        pid_t pid;
 590        struct sockaddr_storage address;
 591} *firstborn;
 592
 593static void add_child(pid_t pid, struct sockaddr *addr, int addrlen)
 594{
 595        struct child *newborn, **cradle;
 596
 597        newborn = xcalloc(1, sizeof(*newborn));
 598        live_children++;
 599        newborn->pid = pid;
 600        memcpy(&newborn->address, addr, addrlen);
 601        for (cradle = &firstborn; *cradle; cradle = &(*cradle)->next)
 602                if (!addrcmp(&(*cradle)->address, &newborn->address))
 603                        break;
 604        newborn->next = *cradle;
 605        *cradle = newborn;
 606}
 607
 608static void remove_child(pid_t pid)
 609{
 610        struct child **cradle, *blanket;
 611
 612        for (cradle = &firstborn; (blanket = *cradle); cradle = &blanket->next)
 613                if (blanket->pid == pid) {
 614                        *cradle = blanket->next;
 615                        live_children--;
 616                        free(blanket);
 617                        break;
 618                }
 619}
 620
 621/*
 622 * This gets called if the number of connections grows
 623 * past "max_connections".
 624 *
 625 * We kill the newest connection from a duplicate IP.
 626 */
 627static void kill_some_child(void)
 628{
 629        const struct child *blanket, *next;
 630
 631        if (!(blanket = firstborn))
 632                return;
 633
 634        for (; (next = blanket->next); blanket = next)
 635                if (!addrcmp(&blanket->address, &next->address)) {
 636                        kill(blanket->pid, SIGTERM);
 637                        break;
 638                }
 639}
 640
 641static void check_dead_children(void)
 642{
 643        int status;
 644        pid_t pid;
 645
 646        while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
 647                const char *dead = "";
 648                remove_child(pid);
 649                if (!WIFEXITED(status) || (WEXITSTATUS(status) > 0))
 650                        dead = " (with error)";
 651                loginfo("[%"PRIuMAX"] Disconnected%s", (uintmax_t)pid, dead);
 652        }
 653}
 654
 655static void handle(int incoming, struct sockaddr *addr, int addrlen)
 656{
 657        pid_t pid;
 658
 659        if (max_connections && live_children >= max_connections) {
 660                kill_some_child();
 661                sleep(1);  /* give it some time to die */
 662                check_dead_children();
 663                if (live_children >= max_connections) {
 664                        close(incoming);
 665                        logerror("Too many children, dropping connection");
 666                        return;
 667                }
 668        }
 669
 670        if ((pid = fork())) {
 671                close(incoming);
 672                if (pid < 0) {
 673                        logerror("Couldn't fork %s", strerror(errno));
 674                        return;
 675                }
 676
 677                add_child(pid, addr, addrlen);
 678                return;
 679        }
 680
 681        dup2(incoming, 0);
 682        dup2(incoming, 1);
 683        close(incoming);
 684
 685        exit(execute(addr));
 686}
 687
 688static void child_handler(int signo)
 689{
 690        /*
 691         * Otherwise empty handler because systemcalls will get interrupted
 692         * upon signal receipt
 693         * SysV needs the handler to be rearmed
 694         */
 695        signal(SIGCHLD, child_handler);
 696}
 697
 698static int set_reuse_addr(int sockfd)
 699{
 700        int on = 1;
 701
 702        if (!reuseaddr)
 703                return 0;
 704        return setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
 705                          &on, sizeof(on));
 706}
 707
 708#ifndef NO_IPV6
 709
 710static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
 711{
 712        int socknum = 0, *socklist = NULL;
 713        int maxfd = -1;
 714        char pbuf[NI_MAXSERV];
 715        struct addrinfo hints, *ai0, *ai;
 716        int gai;
 717        long flags;
 718
 719        sprintf(pbuf, "%d", listen_port);
 720        memset(&hints, 0, sizeof(hints));
 721        hints.ai_family = AF_UNSPEC;
 722        hints.ai_socktype = SOCK_STREAM;
 723        hints.ai_protocol = IPPROTO_TCP;
 724        hints.ai_flags = AI_PASSIVE;
 725
 726        gai = getaddrinfo(listen_addr, pbuf, &hints, &ai0);
 727        if (gai)
 728                die("getaddrinfo() failed: %s", gai_strerror(gai));
 729
 730        for (ai = ai0; ai; ai = ai->ai_next) {
 731                int sockfd;
 732
 733                sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
 734                if (sockfd < 0)
 735                        continue;
 736                if (sockfd >= FD_SETSIZE) {
 737                        logerror("Socket descriptor too large");
 738                        close(sockfd);
 739                        continue;
 740                }
 741
 742#ifdef IPV6_V6ONLY
 743                if (ai->ai_family == AF_INET6) {
 744                        int on = 1;
 745                        setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
 746                                   &on, sizeof(on));
 747                        /* Note: error is not fatal */
 748                }
 749#endif
 750
 751                if (set_reuse_addr(sockfd)) {
 752                        close(sockfd);
 753                        continue;
 754                }
 755
 756                if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
 757                        close(sockfd);
 758                        continue;       /* not fatal */
 759                }
 760                if (listen(sockfd, 5) < 0) {
 761                        close(sockfd);
 762                        continue;       /* not fatal */
 763                }
 764
 765                flags = fcntl(sockfd, F_GETFD, 0);
 766                if (flags >= 0)
 767                        fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
 768
 769                socklist = xrealloc(socklist, sizeof(int) * (socknum + 1));
 770                socklist[socknum++] = sockfd;
 771
 772                if (maxfd < sockfd)
 773                        maxfd = sockfd;
 774        }
 775
 776        freeaddrinfo(ai0);
 777
 778        *socklist_p = socklist;
 779        return socknum;
 780}
 781
 782#else /* NO_IPV6 */
 783
 784static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
 785{
 786        struct sockaddr_in sin;
 787        int sockfd;
 788        long flags;
 789
 790        memset(&sin, 0, sizeof sin);
 791        sin.sin_family = AF_INET;
 792        sin.sin_port = htons(listen_port);
 793
 794        if (listen_addr) {
 795                /* Well, host better be an IP address here. */
 796                if (inet_pton(AF_INET, listen_addr, &sin.sin_addr.s_addr) <= 0)
 797                        return 0;
 798        } else {
 799                sin.sin_addr.s_addr = htonl(INADDR_ANY);
 800        }
 801
 802        sockfd = socket(AF_INET, SOCK_STREAM, 0);
 803        if (sockfd < 0)
 804                return 0;
 805
 806        if (set_reuse_addr(sockfd)) {
 807                close(sockfd);
 808                return 0;
 809        }
 810
 811        if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) {
 812                close(sockfd);
 813                return 0;
 814        }
 815
 816        if (listen(sockfd, 5) < 0) {
 817                close(sockfd);
 818                return 0;
 819        }
 820
 821        flags = fcntl(sockfd, F_GETFD, 0);
 822        if (flags >= 0)
 823                fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
 824
 825        *socklist_p = xmalloc(sizeof(int));
 826        **socklist_p = sockfd;
 827        return 1;
 828}
 829
 830#endif
 831
 832static int service_loop(int socknum, int *socklist)
 833{
 834        struct pollfd *pfd;
 835        int i;
 836
 837        pfd = xcalloc(socknum, sizeof(struct pollfd));
 838
 839        for (i = 0; i < socknum; i++) {
 840                pfd[i].fd = socklist[i];
 841                pfd[i].events = POLLIN;
 842        }
 843
 844        signal(SIGCHLD, child_handler);
 845
 846        for (;;) {
 847                int i;
 848
 849                check_dead_children();
 850
 851                if (poll(pfd, socknum, -1) < 0) {
 852                        if (errno != EINTR) {
 853                                logerror("Poll failed, resuming: %s",
 854                                      strerror(errno));
 855                                sleep(1);
 856                        }
 857                        continue;
 858                }
 859
 860                for (i = 0; i < socknum; i++) {
 861                        if (pfd[i].revents & POLLIN) {
 862                                struct sockaddr_storage ss;
 863                                unsigned int sslen = sizeof(ss);
 864                                int incoming = accept(pfd[i].fd, (struct sockaddr *)&ss, &sslen);
 865                                if (incoming < 0) {
 866                                        switch (errno) {
 867                                        case EAGAIN:
 868                                        case EINTR:
 869                                        case ECONNABORTED:
 870                                                continue;
 871                                        default:
 872                                                die_errno("accept returned");
 873                                        }
 874                                }
 875                                handle(incoming, (struct sockaddr *)&ss, sslen);
 876                        }
 877                }
 878        }
 879}
 880
 881/* if any standard file descriptor is missing open it to /dev/null */
 882static void sanitize_stdfds(void)
 883{
 884        int fd = open("/dev/null", O_RDWR, 0);
 885        while (fd != -1 && fd < 2)
 886                fd = dup(fd);
 887        if (fd == -1)
 888                die_errno("open /dev/null or dup failed");
 889        if (fd > 2)
 890                close(fd);
 891}
 892
 893static void daemonize(void)
 894{
 895        switch (fork()) {
 896                case 0:
 897                        break;
 898                case -1:
 899                        die_errno("fork failed");
 900                default:
 901                        exit(0);
 902        }
 903        if (setsid() == -1)
 904                die_errno("setsid failed");
 905        close(0);
 906        close(1);
 907        close(2);
 908        sanitize_stdfds();
 909}
 910
 911static void store_pid(const char *path)
 912{
 913        FILE *f = fopen(path, "w");
 914        if (!f)
 915                die_errno("cannot open pid file '%s'", path);
 916        if (fprintf(f, "%"PRIuMAX"\n", (uintmax_t) getpid()) < 0 || fclose(f) != 0)
 917                die_errno("failed to write pid file '%s'", path);
 918}
 919
 920static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
 921{
 922        int socknum, *socklist;
 923
 924        socknum = socksetup(listen_addr, listen_port, &socklist);
 925        if (socknum == 0)
 926                die("unable to allocate any listen sockets on host %s port %u",
 927                    listen_addr, listen_port);
 928
 929        if (pass && gid &&
 930            (initgroups(pass->pw_name, gid) || setgid (gid) ||
 931             setuid(pass->pw_uid)))
 932                die("cannot drop privileges");
 933
 934        return service_loop(socknum, socklist);
 935}
 936
 937int main(int argc, char **argv)
 938{
 939        int listen_port = 0;
 940        char *listen_addr = NULL;
 941        int inetd_mode = 0;
 942        const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
 943        int detach = 0;
 944        struct passwd *pass = NULL;
 945        struct group *group;
 946        gid_t gid = 0;
 947        int i;
 948
 949        git_extract_argv0_path(argv[0]);
 950
 951        for (i = 1; i < argc; i++) {
 952                char *arg = argv[i];
 953
 954                if (!prefixcmp(arg, "--listen=")) {
 955                        listen_addr = xstrdup_tolower(arg + 9);
 956                        continue;
 957                }
 958                if (!prefixcmp(arg, "--port=")) {
 959                        char *end;
 960                        unsigned long n;
 961                        n = strtoul(arg+7, &end, 0);
 962                        if (arg[7] && !*end) {
 963                                listen_port = n;
 964                                continue;
 965                        }
 966                }
 967                if (!strcmp(arg, "--inetd")) {
 968                        inetd_mode = 1;
 969                        log_syslog = 1;
 970                        continue;
 971                }
 972                if (!strcmp(arg, "--verbose")) {
 973                        verbose = 1;
 974                        continue;
 975                }
 976                if (!strcmp(arg, "--syslog")) {
 977                        log_syslog = 1;
 978                        continue;
 979                }
 980                if (!strcmp(arg, "--export-all")) {
 981                        export_all_trees = 1;
 982                        continue;
 983                }
 984                if (!prefixcmp(arg, "--timeout=")) {
 985                        timeout = atoi(arg+10);
 986                        continue;
 987                }
 988                if (!prefixcmp(arg, "--init-timeout=")) {
 989                        init_timeout = atoi(arg+15);
 990                        continue;
 991                }
 992                if (!prefixcmp(arg, "--max-connections=")) {
 993                        max_connections = atoi(arg+18);
 994                        if (max_connections < 0)
 995                                max_connections = 0;            /* unlimited */
 996                        continue;
 997                }
 998                if (!strcmp(arg, "--strict-paths")) {
 999                        strict_paths = 1;
1000                        continue;
1001                }
1002                if (!prefixcmp(arg, "--base-path=")) {
1003                        base_path = arg+12;
1004                        continue;
1005                }
1006                if (!strcmp(arg, "--base-path-relaxed")) {
1007                        base_path_relaxed = 1;
1008                        continue;
1009                }
1010                if (!prefixcmp(arg, "--interpolated-path=")) {
1011                        interpolated_path = arg+20;
1012                        continue;
1013                }
1014                if (!strcmp(arg, "--reuseaddr")) {
1015                        reuseaddr = 1;
1016                        continue;
1017                }
1018                if (!strcmp(arg, "--user-path")) {
1019                        user_path = "";
1020                        continue;
1021                }
1022                if (!prefixcmp(arg, "--user-path=")) {
1023                        user_path = arg + 12;
1024                        continue;
1025                }
1026                if (!prefixcmp(arg, "--pid-file=")) {
1027                        pid_file = arg + 11;
1028                        continue;
1029                }
1030                if (!strcmp(arg, "--detach")) {
1031                        detach = 1;
1032                        log_syslog = 1;
1033                        continue;
1034                }
1035                if (!prefixcmp(arg, "--user=")) {
1036                        user_name = arg + 7;
1037                        continue;
1038                }
1039                if (!prefixcmp(arg, "--group=")) {
1040                        group_name = arg + 8;
1041                        continue;
1042                }
1043                if (!prefixcmp(arg, "--enable=")) {
1044                        enable_service(arg + 9, 1);
1045                        continue;
1046                }
1047                if (!prefixcmp(arg, "--disable=")) {
1048                        enable_service(arg + 10, 0);
1049                        continue;
1050                }
1051                if (!prefixcmp(arg, "--allow-override=")) {
1052                        make_service_overridable(arg + 17, 1);
1053                        continue;
1054                }
1055                if (!prefixcmp(arg, "--forbid-override=")) {
1056                        make_service_overridable(arg + 18, 0);
1057                        continue;
1058                }
1059                if (!strcmp(arg, "--")) {
1060                        ok_paths = &argv[i+1];
1061                        break;
1062                } else if (arg[0] != '-') {
1063                        ok_paths = &argv[i];
1064                        break;
1065                }
1066
1067                usage(daemon_usage);
1068        }
1069
1070        if (log_syslog) {
1071                openlog("git-daemon", LOG_PID, LOG_DAEMON);
1072                set_die_routine(daemon_die);
1073        } else
1074                /* avoid splitting a message in the middle */
1075                setvbuf(stderr, NULL, _IOLBF, 0);
1076
1077        if (inetd_mode && (group_name || user_name))
1078                die("--user and --group are incompatible with --inetd");
1079
1080        if (inetd_mode && (listen_port || listen_addr))
1081                die("--listen= and --port= are incompatible with --inetd");
1082        else if (listen_port == 0)
1083                listen_port = DEFAULT_GIT_PORT;
1084
1085        if (group_name && !user_name)
1086                die("--group supplied without --user");
1087
1088        if (user_name) {
1089                pass = getpwnam(user_name);
1090                if (!pass)
1091                        die("user not found - %s", user_name);
1092
1093                if (!group_name)
1094                        gid = pass->pw_gid;
1095                else {
1096                        group = getgrnam(group_name);
1097                        if (!group)
1098                                die("group not found - %s", group_name);
1099
1100                        gid = group->gr_gid;
1101                }
1102        }
1103
1104        if (strict_paths && (!ok_paths || !*ok_paths))
1105                die("option --strict-paths requires a whitelist");
1106
1107        if (base_path && !is_directory(base_path))
1108                die("base-path '%s' does not exist or is not a directory",
1109                    base_path);
1110
1111        if (inetd_mode) {
1112                struct sockaddr_storage ss;
1113                struct sockaddr *peer = (struct sockaddr *)&ss;
1114                socklen_t slen = sizeof(ss);
1115
1116                if (!freopen("/dev/null", "w", stderr))
1117                        die_errno("failed to redirect stderr to /dev/null");
1118
1119                if (getpeername(0, peer, &slen))
1120                        peer = NULL;
1121
1122                return execute(peer);
1123        }
1124
1125        if (detach) {
1126                daemonize();
1127                loginfo("Ready to rumble");
1128        }
1129        else
1130                sanitize_stdfds();
1131
1132        if (pid_file)
1133                store_pid(pid_file);
1134
1135        return serve(listen_addr, listen_port, pass, gid);
1136}