fbf61ca4d59e73ed918bc5a23b56b6c9f2d3751e
   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        char *hp;
 418
 419        while (extra_args < end && *extra_args) {
 420                saw_extended_args = 1;
 421                if (strncasecmp("host=", extra_args, 5) == 0) {
 422                        val = extra_args + 5;
 423                        vallen = strlen(val) + 1;
 424                        if (*val) {
 425                                /* Split <host>:<port> at colon. */
 426                                char *host = val;
 427                                char *port = strrchr(host, ':');
 428                                if (port) {
 429                                        *port = 0;
 430                                        port++;
 431                                        free(tcp_port);
 432                                        tcp_port = xstrdup(port);
 433                                }
 434                                free(hostname);
 435                                hostname = xstrdup(host);
 436                        }
 437
 438                        /* On to the next one */
 439                        extra_args = val + vallen;
 440                }
 441        }
 442
 443        /*
 444         * Replace literal host with lowercase-ized hostname.
 445         */
 446        hp = hostname;
 447        if (!hp)
 448                return;
 449        for ( ; *hp; hp++)
 450                *hp = tolower(*hp);
 451
 452        /*
 453         * Locate canonical hostname and its IP address.
 454         */
 455#ifndef NO_IPV6
 456        {
 457                struct addrinfo hints;
 458                struct addrinfo *ai, *ai0;
 459                int gai;
 460                static char addrbuf[HOST_NAME_MAX + 1];
 461
 462                memset(&hints, 0, sizeof(hints));
 463                hints.ai_flags = AI_CANONNAME;
 464
 465                gai = getaddrinfo(hostname, 0, &hints, &ai0);
 466                if (!gai) {
 467                        for (ai = ai0; ai; ai = ai->ai_next) {
 468                                struct sockaddr_in *sin_addr = (void *)ai->ai_addr;
 469
 470                                inet_ntop(AF_INET, &sin_addr->sin_addr,
 471                                          addrbuf, sizeof(addrbuf));
 472                                free(canon_hostname);
 473                                canon_hostname = xstrdup(ai->ai_canonname);
 474                                free(ip_address);
 475                                ip_address = xstrdup(addrbuf);
 476                                break;
 477                        }
 478                        freeaddrinfo(ai0);
 479                }
 480        }
 481#else
 482        {
 483                struct hostent *hent;
 484                struct sockaddr_in sa;
 485                char **ap;
 486                static char addrbuf[HOST_NAME_MAX + 1];
 487
 488                hent = gethostbyname(hostname);
 489
 490                ap = hent->h_addr_list;
 491                memset(&sa, 0, sizeof sa);
 492                sa.sin_family = hent->h_addrtype;
 493                sa.sin_port = htons(0);
 494                memcpy(&sa.sin_addr, *ap, hent->h_length);
 495
 496                inet_ntop(hent->h_addrtype, &sa.sin_addr,
 497                          addrbuf, sizeof(addrbuf));
 498
 499                free(canon_hostname);
 500                canon_hostname = xstrdup(hent->h_name);
 501                free(ip_address);
 502                ip_address = xstrdup(addrbuf);
 503        }
 504#endif
 505}
 506
 507
 508static int execute(struct sockaddr *addr)
 509{
 510        static char line[1000];
 511        int pktlen, len, i;
 512
 513        if (addr) {
 514                char addrbuf[256] = "";
 515                int port = -1;
 516
 517                if (addr->sa_family == AF_INET) {
 518                        struct sockaddr_in *sin_addr = (void *) addr;
 519                        inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf, sizeof(addrbuf));
 520                        port = ntohs(sin_addr->sin_port);
 521#ifndef NO_IPV6
 522                } else if (addr && addr->sa_family == AF_INET6) {
 523                        struct sockaddr_in6 *sin6_addr = (void *) addr;
 524
 525                        char *buf = addrbuf;
 526                        *buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
 527                        inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(addrbuf) - 1);
 528                        strcat(buf, "]");
 529
 530                        port = ntohs(sin6_addr->sin6_port);
 531#endif
 532                }
 533                loginfo("Connection from %s:%d", addrbuf, port);
 534                setenv("REMOTE_ADDR", addrbuf, 1);
 535        }
 536        else {
 537                unsetenv("REMOTE_ADDR");
 538        }
 539
 540        alarm(init_timeout ? init_timeout : timeout);
 541        pktlen = packet_read_line(0, line, sizeof(line));
 542        alarm(0);
 543
 544        len = strlen(line);
 545        if (pktlen != len)
 546                loginfo("Extended attributes (%d bytes) exist <%.*s>",
 547                        (int) pktlen - len,
 548                        (int) pktlen - len, line + len + 1);
 549        if (len && line[len-1] == '\n') {
 550                line[--len] = 0;
 551                pktlen--;
 552        }
 553
 554        free(hostname);
 555        free(canon_hostname);
 556        free(ip_address);
 557        free(tcp_port);
 558        free(directory);
 559        hostname = canon_hostname = ip_address = tcp_port = directory = NULL;
 560
 561        if (len != pktlen)
 562                parse_extra_args(line + len + 1, pktlen - len - 1);
 563
 564        for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
 565                struct daemon_service *s = &(daemon_service[i]);
 566                int namelen = strlen(s->name);
 567                if (!prefixcmp(line, "git-") &&
 568                    !strncmp(s->name, line + 4, namelen) &&
 569                    line[namelen + 4] == ' ') {
 570                        /*
 571                         * Note: The directory here is probably context sensitive,
 572                         * and might depend on the actual service being performed.
 573                         */
 574                        free(directory);
 575                        directory = xstrdup(line + namelen + 5);
 576                        return run_service(s);
 577                }
 578        }
 579
 580        logerror("Protocol error: '%s'", line);
 581        return -1;
 582}
 583
 584static int max_connections = 32;
 585
 586static unsigned int live_children;
 587
 588static struct child {
 589        struct child *next;
 590        pid_t pid;
 591        struct sockaddr_storage address;
 592} *firstborn;
 593
 594static void add_child(pid_t pid, struct sockaddr *addr, int addrlen)
 595{
 596        struct child *newborn, **cradle;
 597
 598        /*
 599         * This must be xcalloc() -- we'll compare the whole sockaddr_storage
 600         * but individual address may be shorter.
 601         */
 602        newborn = xcalloc(1, sizeof(*newborn));
 603        live_children++;
 604        newborn->pid = pid;
 605        memcpy(&newborn->address, addr, addrlen);
 606        for (cradle = &firstborn; *cradle; cradle = &(*cradle)->next)
 607                if (!memcmp(&(*cradle)->address, &newborn->address,
 608                            sizeof(newborn->address)))
 609                        break;
 610        newborn->next = *cradle;
 611        *cradle = newborn;
 612}
 613
 614static void remove_child(pid_t pid)
 615{
 616        struct child **cradle, *blanket;
 617
 618        for (cradle = &firstborn; (blanket = *cradle); cradle = &blanket->next)
 619                if (blanket->pid == pid) {
 620                        *cradle = blanket->next;
 621                        live_children--;
 622                        free(blanket);
 623                        break;
 624                }
 625}
 626
 627/*
 628 * This gets called if the number of connections grows
 629 * past "max_connections".
 630 *
 631 * We kill the newest connection from a duplicate IP.
 632 */
 633static void kill_some_child(void)
 634{
 635        const struct child *blanket, *next;
 636
 637        if (!(blanket = firstborn))
 638                return;
 639
 640        for (; (next = blanket->next); blanket = next)
 641                if (!memcmp(&blanket->address, &next->address,
 642                            sizeof(next->address))) {
 643                        kill(blanket->pid, SIGTERM);
 644                        break;
 645                }
 646}
 647
 648static void check_dead_children(void)
 649{
 650        int status;
 651        pid_t pid;
 652
 653        while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
 654                const char *dead = "";
 655                remove_child(pid);
 656                if (!WIFEXITED(status) || (WEXITSTATUS(status) > 0))
 657                        dead = " (with error)";
 658                loginfo("[%"PRIuMAX"] Disconnected%s", (uintmax_t)pid, dead);
 659        }
 660}
 661
 662static void handle(int incoming, struct sockaddr *addr, int addrlen)
 663{
 664        pid_t pid;
 665
 666        if (max_connections && live_children >= max_connections) {
 667                kill_some_child();
 668                sleep(1);  /* give it some time to die */
 669                check_dead_children();
 670                if (live_children >= max_connections) {
 671                        close(incoming);
 672                        logerror("Too many children, dropping connection");
 673                        return;
 674                }
 675        }
 676
 677        if ((pid = fork())) {
 678                close(incoming);
 679                if (pid < 0) {
 680                        logerror("Couldn't fork %s", strerror(errno));
 681                        return;
 682                }
 683
 684                add_child(pid, addr, addrlen);
 685                return;
 686        }
 687
 688        dup2(incoming, 0);
 689        dup2(incoming, 1);
 690        close(incoming);
 691
 692        exit(execute(addr));
 693}
 694
 695static void child_handler(int signo)
 696{
 697        /*
 698         * Otherwise empty handler because systemcalls will get interrupted
 699         * upon signal receipt
 700         * SysV needs the handler to be rearmed
 701         */
 702        signal(SIGCHLD, child_handler);
 703}
 704
 705static int set_reuse_addr(int sockfd)
 706{
 707        int on = 1;
 708
 709        if (!reuseaddr)
 710                return 0;
 711        return setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
 712                          &on, sizeof(on));
 713}
 714
 715#ifndef NO_IPV6
 716
 717static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
 718{
 719        int socknum = 0, *socklist = NULL;
 720        int maxfd = -1;
 721        char pbuf[NI_MAXSERV];
 722        struct addrinfo hints, *ai0, *ai;
 723        int gai;
 724        long flags;
 725
 726        sprintf(pbuf, "%d", listen_port);
 727        memset(&hints, 0, sizeof(hints));
 728        hints.ai_family = AF_UNSPEC;
 729        hints.ai_socktype = SOCK_STREAM;
 730        hints.ai_protocol = IPPROTO_TCP;
 731        hints.ai_flags = AI_PASSIVE;
 732
 733        gai = getaddrinfo(listen_addr, pbuf, &hints, &ai0);
 734        if (gai)
 735                die("getaddrinfo() failed: %s\n", gai_strerror(gai));
 736
 737        for (ai = ai0; ai; ai = ai->ai_next) {
 738                int sockfd;
 739
 740                sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
 741                if (sockfd < 0)
 742                        continue;
 743                if (sockfd >= FD_SETSIZE) {
 744                        logerror("Socket descriptor too large");
 745                        close(sockfd);
 746                        continue;
 747                }
 748
 749#ifdef IPV6_V6ONLY
 750                if (ai->ai_family == AF_INET6) {
 751                        int on = 1;
 752                        setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
 753                                   &on, sizeof(on));
 754                        /* Note: error is not fatal */
 755                }
 756#endif
 757
 758                if (set_reuse_addr(sockfd)) {
 759                        close(sockfd);
 760                        continue;
 761                }
 762
 763                if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
 764                        close(sockfd);
 765                        continue;       /* not fatal */
 766                }
 767                if (listen(sockfd, 5) < 0) {
 768                        close(sockfd);
 769                        continue;       /* not fatal */
 770                }
 771
 772                flags = fcntl(sockfd, F_GETFD, 0);
 773                if (flags >= 0)
 774                        fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
 775
 776                socklist = xrealloc(socklist, sizeof(int) * (socknum + 1));
 777                socklist[socknum++] = sockfd;
 778
 779                if (maxfd < sockfd)
 780                        maxfd = sockfd;
 781        }
 782
 783        freeaddrinfo(ai0);
 784
 785        *socklist_p = socklist;
 786        return socknum;
 787}
 788
 789#else /* NO_IPV6 */
 790
 791static int socksetup(char *listen_addr, int listen_port, int **socklist_p)
 792{
 793        struct sockaddr_in sin;
 794        int sockfd;
 795        long flags;
 796
 797        memset(&sin, 0, sizeof sin);
 798        sin.sin_family = AF_INET;
 799        sin.sin_port = htons(listen_port);
 800
 801        if (listen_addr) {
 802                /* Well, host better be an IP address here. */
 803                if (inet_pton(AF_INET, listen_addr, &sin.sin_addr.s_addr) <= 0)
 804                        return 0;
 805        } else {
 806                sin.sin_addr.s_addr = htonl(INADDR_ANY);
 807        }
 808
 809        sockfd = socket(AF_INET, SOCK_STREAM, 0);
 810        if (sockfd < 0)
 811                return 0;
 812
 813        if (set_reuse_addr(sockfd)) {
 814                close(sockfd);
 815                return 0;
 816        }
 817
 818        if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) {
 819                close(sockfd);
 820                return 0;
 821        }
 822
 823        if (listen(sockfd, 5) < 0) {
 824                close(sockfd);
 825                return 0;
 826        }
 827
 828        flags = fcntl(sockfd, F_GETFD, 0);
 829        if (flags >= 0)
 830                fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);
 831
 832        *socklist_p = xmalloc(sizeof(int));
 833        **socklist_p = sockfd;
 834        return 1;
 835}
 836
 837#endif
 838
 839static int service_loop(int socknum, int *socklist)
 840{
 841        struct pollfd *pfd;
 842        int i;
 843
 844        pfd = xcalloc(socknum, sizeof(struct pollfd));
 845
 846        for (i = 0; i < socknum; i++) {
 847                pfd[i].fd = socklist[i];
 848                pfd[i].events = POLLIN;
 849        }
 850
 851        signal(SIGCHLD, child_handler);
 852
 853        for (;;) {
 854                int i;
 855
 856                check_dead_children();
 857
 858                if (poll(pfd, socknum, -1) < 0) {
 859                        if (errno != EINTR) {
 860                                logerror("Poll failed, resuming: %s",
 861                                      strerror(errno));
 862                                sleep(1);
 863                        }
 864                        continue;
 865                }
 866
 867                for (i = 0; i < socknum; i++) {
 868                        if (pfd[i].revents & POLLIN) {
 869                                struct sockaddr_storage ss;
 870                                unsigned int sslen = sizeof(ss);
 871                                int incoming = accept(pfd[i].fd, (struct sockaddr *)&ss, &sslen);
 872                                if (incoming < 0) {
 873                                        switch (errno) {
 874                                        case EAGAIN:
 875                                        case EINTR:
 876                                        case ECONNABORTED:
 877                                                continue;
 878                                        default:
 879                                                die("accept returned %s", strerror(errno));
 880                                        }
 881                                }
 882                                handle(incoming, (struct sockaddr *)&ss, sslen);
 883                        }
 884                }
 885        }
 886}
 887
 888/* if any standard file descriptor is missing open it to /dev/null */
 889static void sanitize_stdfds(void)
 890{
 891        int fd = open("/dev/null", O_RDWR, 0);
 892        while (fd != -1 && fd < 2)
 893                fd = dup(fd);
 894        if (fd == -1)
 895                die("open /dev/null or dup failed: %s", strerror(errno));
 896        if (fd > 2)
 897                close(fd);
 898}
 899
 900static void daemonize(void)
 901{
 902        switch (fork()) {
 903                case 0:
 904                        break;
 905                case -1:
 906                        die("fork failed: %s", strerror(errno));
 907                default:
 908                        exit(0);
 909        }
 910        if (setsid() == -1)
 911                die("setsid failed: %s", strerror(errno));
 912        close(0);
 913        close(1);
 914        close(2);
 915        sanitize_stdfds();
 916}
 917
 918static void store_pid(const char *path)
 919{
 920        FILE *f = fopen(path, "w");
 921        if (!f)
 922                die("cannot open pid file %s: %s", path, strerror(errno));
 923        if (fprintf(f, "%"PRIuMAX"\n", (uintmax_t) getpid()) < 0 || fclose(f) != 0)
 924                die("failed to write pid file %s: %s", path, strerror(errno));
 925}
 926
 927static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
 928{
 929        int socknum, *socklist;
 930
 931        socknum = socksetup(listen_addr, listen_port, &socklist);
 932        if (socknum == 0)
 933                die("unable to allocate any listen sockets on host %s port %u",
 934                    listen_addr, listen_port);
 935
 936        if (pass && gid &&
 937            (initgroups(pass->pw_name, gid) || setgid (gid) ||
 938             setuid(pass->pw_uid)))
 939                die("cannot drop privileges");
 940
 941        return service_loop(socknum, socklist);
 942}
 943
 944int main(int argc, char **argv)
 945{
 946        int listen_port = 0;
 947        char *listen_addr = NULL;
 948        int inetd_mode = 0;
 949        const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
 950        int detach = 0;
 951        struct passwd *pass = NULL;
 952        struct group *group;
 953        gid_t gid = 0;
 954        int i;
 955
 956        for (i = 1; i < argc; i++) {
 957                char *arg = argv[i];
 958
 959                if (!prefixcmp(arg, "--listen=")) {
 960                    char *p = arg + 9;
 961                    char *ph = listen_addr = xmalloc(strlen(arg + 9) + 1);
 962                    while (*p)
 963                        *ph++ = tolower(*p++);
 964                    *ph = 0;
 965                    continue;
 966                }
 967                if (!prefixcmp(arg, "--port=")) {
 968                        char *end;
 969                        unsigned long n;
 970                        n = strtoul(arg+7, &end, 0);
 971                        if (arg[7] && !*end) {
 972                                listen_port = n;
 973                                continue;
 974                        }
 975                }
 976                if (!strcmp(arg, "--inetd")) {
 977                        inetd_mode = 1;
 978                        log_syslog = 1;
 979                        continue;
 980                }
 981                if (!strcmp(arg, "--verbose")) {
 982                        verbose = 1;
 983                        continue;
 984                }
 985                if (!strcmp(arg, "--syslog")) {
 986                        log_syslog = 1;
 987                        continue;
 988                }
 989                if (!strcmp(arg, "--export-all")) {
 990                        export_all_trees = 1;
 991                        continue;
 992                }
 993                if (!prefixcmp(arg, "--timeout=")) {
 994                        timeout = atoi(arg+10);
 995                        continue;
 996                }
 997                if (!prefixcmp(arg, "--init-timeout=")) {
 998                        init_timeout = atoi(arg+15);
 999                        continue;
1000                }
1001                if (!prefixcmp(arg, "--max-connections=")) {
1002                        max_connections = atoi(arg+18);
1003                        if (max_connections < 0)
1004                                max_connections = 0;            /* unlimited */
1005                        continue;
1006                }
1007                if (!strcmp(arg, "--strict-paths")) {
1008                        strict_paths = 1;
1009                        continue;
1010                }
1011                if (!prefixcmp(arg, "--base-path=")) {
1012                        base_path = arg+12;
1013                        continue;
1014                }
1015                if (!strcmp(arg, "--base-path-relaxed")) {
1016                        base_path_relaxed = 1;
1017                        continue;
1018                }
1019                if (!prefixcmp(arg, "--interpolated-path=")) {
1020                        interpolated_path = arg+20;
1021                        continue;
1022                }
1023                if (!strcmp(arg, "--reuseaddr")) {
1024                        reuseaddr = 1;
1025                        continue;
1026                }
1027                if (!strcmp(arg, "--user-path")) {
1028                        user_path = "";
1029                        continue;
1030                }
1031                if (!prefixcmp(arg, "--user-path=")) {
1032                        user_path = arg + 12;
1033                        continue;
1034                }
1035                if (!prefixcmp(arg, "--pid-file=")) {
1036                        pid_file = arg + 11;
1037                        continue;
1038                }
1039                if (!strcmp(arg, "--detach")) {
1040                        detach = 1;
1041                        log_syslog = 1;
1042                        continue;
1043                }
1044                if (!prefixcmp(arg, "--user=")) {
1045                        user_name = arg + 7;
1046                        continue;
1047                }
1048                if (!prefixcmp(arg, "--group=")) {
1049                        group_name = arg + 8;
1050                        continue;
1051                }
1052                if (!prefixcmp(arg, "--enable=")) {
1053                        enable_service(arg + 9, 1);
1054                        continue;
1055                }
1056                if (!prefixcmp(arg, "--disable=")) {
1057                        enable_service(arg + 10, 0);
1058                        continue;
1059                }
1060                if (!prefixcmp(arg, "--allow-override=")) {
1061                        make_service_overridable(arg + 17, 1);
1062                        continue;
1063                }
1064                if (!prefixcmp(arg, "--forbid-override=")) {
1065                        make_service_overridable(arg + 18, 0);
1066                        continue;
1067                }
1068                if (!strcmp(arg, "--")) {
1069                        ok_paths = &argv[i+1];
1070                        break;
1071                } else if (arg[0] != '-') {
1072                        ok_paths = &argv[i];
1073                        break;
1074                }
1075
1076                usage(daemon_usage);
1077        }
1078
1079        if (log_syslog) {
1080                openlog("git-daemon", LOG_PID, LOG_DAEMON);
1081                set_die_routine(daemon_die);
1082        } else
1083                /* avoid splitting a message in the middle */
1084                setvbuf(stderr, NULL, _IOLBF, 0);
1085
1086        if (inetd_mode && (group_name || user_name))
1087                die("--user and --group are incompatible with --inetd");
1088
1089        if (inetd_mode && (listen_port || listen_addr))
1090                die("--listen= and --port= are incompatible with --inetd");
1091        else if (listen_port == 0)
1092                listen_port = DEFAULT_GIT_PORT;
1093
1094        if (group_name && !user_name)
1095                die("--group supplied without --user");
1096
1097        if (user_name) {
1098                pass = getpwnam(user_name);
1099                if (!pass)
1100                        die("user not found - %s", user_name);
1101
1102                if (!group_name)
1103                        gid = pass->pw_gid;
1104                else {
1105                        group = getgrnam(group_name);
1106                        if (!group)
1107                                die("group not found - %s", group_name);
1108
1109                        gid = group->gr_gid;
1110                }
1111        }
1112
1113        if (strict_paths && (!ok_paths || !*ok_paths))
1114                die("option --strict-paths requires a whitelist");
1115
1116        if (base_path && !is_directory(base_path))
1117                die("base-path '%s' does not exist or is not a directory",
1118                    base_path);
1119
1120        if (inetd_mode) {
1121                struct sockaddr_storage ss;
1122                struct sockaddr *peer = (struct sockaddr *)&ss;
1123                socklen_t slen = sizeof(ss);
1124
1125                freopen("/dev/null", "w", stderr);
1126
1127                if (getpeername(0, peer, &slen))
1128                        peer = NULL;
1129
1130                return execute(peer);
1131        }
1132
1133        if (detach) {
1134                daemonize();
1135                loginfo("Ready to rumble");
1136        }
1137        else
1138                sanitize_stdfds();
1139
1140        if (pid_file)
1141                store_pid(pid_file);
1142
1143        return serve(listen_addr, listen_port, pass, gid);
1144}