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