Git fork
at reftables-rust 1471 lines 36 kB view raw
1#define USE_THE_REPOSITORY_VARIABLE 2 3#include "git-compat-util.h" 4#include "abspath.h" 5#include "config.h" 6#include "environment.h" 7#include "gettext.h" 8#include "path.h" 9#include "pkt-line.h" 10#include "protocol.h" 11#include "run-command.h" 12#include "setup.h" 13#include "strbuf.h" 14#include "string-list.h" 15 16#ifdef NO_INITGROUPS 17#define initgroups(x, y) (0) /* nothing */ 18#endif 19 20static enum log_destination { 21 LOG_DESTINATION_UNSET = -1, 22 LOG_DESTINATION_NONE = 0, 23 LOG_DESTINATION_STDERR = 1, 24 LOG_DESTINATION_SYSLOG = 2, 25} log_destination = LOG_DESTINATION_UNSET; 26static int verbose; 27static int reuseaddr; 28static int informative_errors; 29 30static const char daemon_usage[] = 31"git daemon [--verbose] [--syslog] [--export-all]\n" 32" [--timeout=<n>] [--init-timeout=<n>] [--max-connections=<n>]\n" 33" [--strict-paths] [--base-path=<path>] [--base-path-relaxed]\n" 34" [--user-path | --user-path=<path>]\n" 35" [--interpolated-path=<path>]\n" 36" [--reuseaddr] [--pid-file=<file>]\n" 37" [--(enable|disable|allow-override|forbid-override)=<service>]\n" 38" [--access-hook=<path>]\n" 39" [--inetd | [--listen=<host_or_ipaddr>] [--port=<n>]\n" 40" [--detach] [--user=<user> [--group=<group>]]\n" 41" [--log-destination=(stderr|syslog|none)]\n" 42" [<directory>...]"; 43 44/* List of acceptable pathname prefixes */ 45static const char **ok_paths; 46static int strict_paths; 47 48/* If this is set, git-daemon-export-ok is not required */ 49static int export_all_trees; 50 51/* Take all paths relative to this one if non-NULL */ 52static const char *base_path; 53static const char *interpolated_path; 54static int base_path_relaxed; 55 56/* If defined, ~user notation is allowed and the string is inserted 57 * after ~user/. E.g. a request to git://host/~alice/frotz would 58 * go to /home/alice/pub_git/frotz with --user-path=pub_git. 59 */ 60static const char *user_path; 61 62/* Timeout, and initial timeout */ 63static unsigned int timeout; 64static unsigned int init_timeout; 65 66struct hostinfo { 67 struct strbuf hostname; 68 struct strbuf canon_hostname; 69 struct strbuf ip_address; 70 struct strbuf tcp_port; 71 unsigned int hostname_lookup_done:1; 72 unsigned int saw_extended_args:1; 73}; 74#define HOSTINFO_INIT { \ 75 .hostname = STRBUF_INIT, \ 76 .canon_hostname = STRBUF_INIT, \ 77 .ip_address = STRBUF_INIT, \ 78 .tcp_port = STRBUF_INIT, \ 79} 80 81static void lookup_hostname(struct hostinfo *hi); 82 83static const char *get_canon_hostname(struct hostinfo *hi) 84{ 85 lookup_hostname(hi); 86 return hi->canon_hostname.buf; 87} 88 89static const char *get_ip_address(struct hostinfo *hi) 90{ 91 lookup_hostname(hi); 92 return hi->ip_address.buf; 93} 94 95static void logreport(int priority, const char *err, va_list params) 96{ 97 switch (log_destination) { 98 case LOG_DESTINATION_SYSLOG: { 99 char buf[1024]; 100 vsnprintf(buf, sizeof(buf), err, params); 101 syslog(priority, "%s", buf); 102 break; 103 } 104 case LOG_DESTINATION_STDERR: 105 /* 106 * Since stderr is set to buffered mode, the 107 * logging of different processes will not overlap 108 * unless they overflow the (rather big) buffers. 109 */ 110 fprintf(stderr, "[%"PRIuMAX"] ", (uintmax_t)getpid()); 111 vfprintf(stderr, err, params); 112 fputc('\n', stderr); 113 fflush(stderr); 114 break; 115 case LOG_DESTINATION_NONE: 116 break; 117 case LOG_DESTINATION_UNSET: 118 BUG("log destination not initialized correctly"); 119 } 120} 121 122__attribute__((format (printf, 1, 2))) 123static void logerror(const char *err, ...) 124{ 125 va_list params; 126 va_start(params, err); 127 logreport(LOG_ERR, err, params); 128 va_end(params); 129} 130 131__attribute__((format (printf, 1, 2))) 132static void loginfo(const char *err, ...) 133{ 134 va_list params; 135 if (!verbose) 136 return; 137 va_start(params, err); 138 logreport(LOG_INFO, err, params); 139 va_end(params); 140} 141 142static void NORETURN daemon_die(const char *err, va_list params) 143{ 144 logreport(LOG_ERR, err, params); 145 exit(1); 146} 147 148static const char *path_ok(const char *directory, struct hostinfo *hi) 149{ 150 static char rpath[PATH_MAX]; 151 static char interp_path[PATH_MAX]; 152 size_t rlen; 153 const char *path; 154 const char *dir; 155 unsigned enter_repo_flags; 156 157 dir = directory; 158 159 if (daemon_avoid_alias(dir)) { 160 logerror("'%s': aliased", dir); 161 return NULL; 162 } 163 164 if (*dir == '~') { 165 if (!user_path) { 166 logerror("'%s': User-path not allowed", dir); 167 return NULL; 168 } 169 if (*user_path) { 170 /* Got either "~alice" or "~alice/foo"; 171 * rewrite them to "~alice/%s" or 172 * "~alice/%s/foo". 173 */ 174 int namlen, restlen = strlen(dir); 175 const char *slash = strchr(dir, '/'); 176 if (!slash) 177 slash = dir + restlen; 178 namlen = slash - dir; 179 restlen -= namlen; 180 loginfo("userpath <%s>, request <%s>, namlen %d, restlen %d, slash <%s>", user_path, dir, namlen, restlen, slash); 181 rlen = snprintf(rpath, sizeof(rpath), "%.*s/%s%.*s", 182 namlen, dir, user_path, restlen, slash); 183 if (rlen >= sizeof(rpath)) { 184 logerror("user-path too large: %s", rpath); 185 return NULL; 186 } 187 dir = rpath; 188 } 189 } 190 else if (interpolated_path && hi->saw_extended_args) { 191 struct strbuf expanded_path = STRBUF_INIT; 192 const char *format = interpolated_path; 193 194 if (*dir != '/') { 195 /* Allow only absolute */ 196 logerror("'%s': Non-absolute path denied (interpolated-path active)", dir); 197 return NULL; 198 } 199 200 while (strbuf_expand_step(&expanded_path, &format)) { 201 if (skip_prefix(format, "%", &format)) 202 strbuf_addch(&expanded_path, '%'); 203 else if (skip_prefix(format, "H", &format)) 204 strbuf_addbuf(&expanded_path, &hi->hostname); 205 else if (skip_prefix(format, "CH", &format)) 206 strbuf_addstr(&expanded_path, 207 get_canon_hostname(hi)); 208 else if (skip_prefix(format, "IP", &format)) 209 strbuf_addstr(&expanded_path, 210 get_ip_address(hi)); 211 else if (skip_prefix(format, "P", &format)) 212 strbuf_addbuf(&expanded_path, &hi->tcp_port); 213 else if (skip_prefix(format, "D", &format)) 214 strbuf_addstr(&expanded_path, directory); 215 else 216 strbuf_addch(&expanded_path, '%'); 217 } 218 219 rlen = strlcpy(interp_path, expanded_path.buf, 220 sizeof(interp_path)); 221 strbuf_release(&expanded_path); 222 if (rlen >= sizeof(interp_path)) { 223 logerror("interpolated path too large: %s", 224 interp_path); 225 return NULL; 226 } 227 228 loginfo("Interpolated dir '%s'", interp_path); 229 230 dir = interp_path; 231 } 232 else if (base_path) { 233 if (*dir != '/') { 234 /* Allow only absolute */ 235 logerror("'%s': Non-absolute path denied (base-path active)", dir); 236 return NULL; 237 } 238 rlen = snprintf(rpath, sizeof(rpath), "%s%s", base_path, dir); 239 if (rlen >= sizeof(rpath)) { 240 logerror("base-path too large: %s", rpath); 241 return NULL; 242 } 243 dir = rpath; 244 } 245 246 enter_repo_flags = strict_paths ? ENTER_REPO_STRICT : 0; 247 path = enter_repo(dir, enter_repo_flags); 248 if (!path && base_path && base_path_relaxed) { 249 /* 250 * if we fail and base_path_relaxed is enabled, try without 251 * prefixing the base path 252 */ 253 dir = directory; 254 path = enter_repo(dir, enter_repo_flags); 255 } 256 257 if (!path) { 258 logerror("'%s' does not appear to be a git repository", dir); 259 return NULL; 260 } 261 262 if ( ok_paths && *ok_paths ) { 263 const char **pp; 264 int pathlen = strlen(path); 265 266 /* The validation is done on the paths after enter_repo 267 * appends optional {.git,.git/.git} and friends, but 268 * it does not use getcwd(). So if your /pub is 269 * a symlink to /mnt/pub, you can include /pub and 270 * do not have to say /mnt/pub. 271 * Do not say /pub/. 272 */ 273 for ( pp = ok_paths ; *pp ; pp++ ) { 274 int len = strlen(*pp); 275 if (len <= pathlen && 276 !memcmp(*pp, path, len) && 277 (path[len] == '\0' || 278 (!strict_paths && path[len] == '/'))) 279 return path; 280 } 281 } 282 else { 283 /* be backwards compatible */ 284 if (!strict_paths) 285 return path; 286 } 287 288 logerror("'%s': not in directory list", path); 289 return NULL; /* Fallthrough. Deny by default */ 290} 291 292typedef int (*daemon_service_fn)(const struct strvec *env); 293struct daemon_service { 294 const char *name; 295 const char *config_name; 296 daemon_service_fn fn; 297 int enabled; 298 int overridable; 299}; 300 301static int daemon_error(const char *dir, const char *msg) 302{ 303 if (!informative_errors) 304 msg = "access denied or repository not exported"; 305 packet_write_fmt(1, "ERR %s: %s", msg, dir); 306 return -1; 307} 308 309static const char *access_hook; 310 311static int run_access_hook(struct daemon_service *service, const char *dir, 312 const char *path, struct hostinfo *hi) 313{ 314 struct child_process child = CHILD_PROCESS_INIT; 315 struct strbuf buf = STRBUF_INIT; 316 char *eol; 317 int seen_errors = 0; 318 319 strvec_push(&child.args, access_hook); 320 strvec_push(&child.args, service->name); 321 strvec_push(&child.args, path); 322 strvec_push(&child.args, hi->hostname.buf); 323 strvec_push(&child.args, get_canon_hostname(hi)); 324 strvec_push(&child.args, get_ip_address(hi)); 325 strvec_push(&child.args, hi->tcp_port.buf); 326 327 child.use_shell = 1; 328 child.no_stdin = 1; 329 child.no_stderr = 1; 330 child.out = -1; 331 if (start_command(&child)) { 332 logerror("daemon access hook '%s' failed to start", 333 access_hook); 334 goto error_return; 335 } 336 if (strbuf_read(&buf, child.out, 0) < 0) { 337 logerror("failed to read from pipe to daemon access hook '%s'", 338 access_hook); 339 strbuf_reset(&buf); 340 seen_errors = 1; 341 } 342 if (close(child.out) < 0) { 343 logerror("failed to close pipe to daemon access hook '%s'", 344 access_hook); 345 seen_errors = 1; 346 } 347 if (finish_command(&child)) 348 seen_errors = 1; 349 350 if (!seen_errors) { 351 strbuf_release(&buf); 352 return 0; 353 } 354 355error_return: 356 strbuf_ltrim(&buf); 357 if (!buf.len) 358 strbuf_addstr(&buf, "service rejected"); 359 eol = strchr(buf.buf, '\n'); 360 if (eol) 361 *eol = '\0'; 362 errno = EACCES; 363 daemon_error(dir, buf.buf); 364 strbuf_release(&buf); 365 return -1; 366} 367 368static int run_service(const char *dir, struct daemon_service *service, 369 struct hostinfo *hi, const struct strvec *env) 370{ 371 const char *path; 372 int enabled = service->enabled; 373 struct strbuf var = STRBUF_INIT; 374 375 loginfo("Request %s for '%s'", service->name, dir); 376 377 if (!enabled && !service->overridable) { 378 logerror("'%s': service not enabled.", service->name); 379 errno = EACCES; 380 return daemon_error(dir, "service not enabled"); 381 } 382 383 if (!(path = path_ok(dir, hi))) 384 return daemon_error(dir, "no such repository"); 385 386 /* 387 * Security on the cheap. 388 * 389 * We want a readable HEAD, usable "objects" directory, and 390 * a "git-daemon-export-ok" flag that says that the other side 391 * is ok with us doing this. 392 * 393 * path_ok() uses enter_repo() and checks for included directories. 394 * We only need to make sure the repository is exported. 395 */ 396 397 if (!export_all_trees && access("git-daemon-export-ok", F_OK)) { 398 logerror("'%s': repository not exported.", path); 399 errno = EACCES; 400 return daemon_error(dir, "repository not exported"); 401 } 402 403 if (service->overridable) { 404 strbuf_addf(&var, "daemon.%s", service->config_name); 405 repo_config_get_bool(the_repository, var.buf, &enabled); 406 strbuf_release(&var); 407 } 408 if (!enabled) { 409 logerror("'%s': service not enabled for '%s'", 410 service->name, path); 411 errno = EACCES; 412 return daemon_error(dir, "service not enabled"); 413 } 414 415 /* 416 * Optionally, a hook can choose to deny access to the 417 * repository depending on the phase of the moon. 418 */ 419 if (access_hook && run_access_hook(service, dir, path, hi)) 420 return -1; 421 422 /* 423 * We'll ignore SIGTERM from now on, we have a 424 * good client. 425 */ 426 signal(SIGTERM, SIG_IGN); 427 428 return service->fn(env); 429} 430 431static void copy_to_log(int fd) 432{ 433 struct strbuf line = STRBUF_INIT; 434 FILE *fp; 435 436 fp = fdopen(fd, "r"); 437 if (!fp) { 438 logerror("fdopen of error channel failed"); 439 close(fd); 440 return; 441 } 442 443 while (strbuf_getline_lf(&line, fp) != EOF) { 444 logerror("%s", line.buf); 445 strbuf_setlen(&line, 0); 446 } 447 448 strbuf_release(&line); 449 fclose(fp); 450} 451 452static int run_service_command(struct child_process *cld) 453{ 454 strvec_push(&cld->args, "."); 455 cld->git_cmd = 1; 456 cld->err = -1; 457 if (start_command(cld)) 458 return -1; 459 460 close(0); 461 close(1); 462 463 copy_to_log(cld->err); 464 465 return finish_command(cld); 466} 467 468static int upload_pack(const struct strvec *env) 469{ 470 struct child_process cld = CHILD_PROCESS_INIT; 471 strvec_pushl(&cld.args, "upload-pack", "--strict", NULL); 472 strvec_pushf(&cld.args, "--timeout=%u", timeout); 473 474 strvec_pushv(&cld.env, env->v); 475 476 return run_service_command(&cld); 477} 478 479static int upload_archive(const struct strvec *env) 480{ 481 struct child_process cld = CHILD_PROCESS_INIT; 482 strvec_push(&cld.args, "upload-archive"); 483 484 strvec_pushv(&cld.env, env->v); 485 486 return run_service_command(&cld); 487} 488 489static int receive_pack(const struct strvec *env) 490{ 491 struct child_process cld = CHILD_PROCESS_INIT; 492 strvec_push(&cld.args, "receive-pack"); 493 494 strvec_pushv(&cld.env, env->v); 495 496 return run_service_command(&cld); 497} 498 499static struct daemon_service daemon_service[] = { 500 { "upload-archive", "uploadarch", upload_archive, 0, 1 }, 501 { "upload-pack", "uploadpack", upload_pack, 1, 1 }, 502 { "receive-pack", "receivepack", receive_pack, 0, 1 }, 503}; 504 505static void enable_service(const char *name, int ena) 506{ 507 for (size_t i = 0; i < ARRAY_SIZE(daemon_service); i++) { 508 if (!strcmp(daemon_service[i].name, name)) { 509 daemon_service[i].enabled = ena; 510 return; 511 } 512 } 513 die("No such service %s", name); 514} 515 516static void make_service_overridable(const char *name, int ena) 517{ 518 for (size_t i = 0; i < ARRAY_SIZE(daemon_service); i++) { 519 if (!strcmp(daemon_service[i].name, name)) { 520 daemon_service[i].overridable = ena; 521 return; 522 } 523 } 524 die("No such service %s", name); 525} 526 527static void parse_host_and_port(char *hostport, char **host, 528 char **port) 529{ 530 if (*hostport == '[') { 531 char *end; 532 533 end = strchr(hostport, ']'); 534 if (!end) 535 die("Invalid request ('[' without ']')"); 536 *end = '\0'; 537 *host = hostport + 1; 538 if (!end[1]) 539 *port = NULL; 540 else if (end[1] == ':') 541 *port = end + 2; 542 else 543 die("Garbage after end of host part"); 544 } else { 545 *host = hostport; 546 *port = strrchr(hostport, ':'); 547 if (*port) { 548 **port = '\0'; 549 ++*port; 550 } 551 } 552} 553 554/* 555 * Sanitize a string from the client so that it's OK to be inserted into a 556 * filesystem path. Specifically, we disallow directory separators, runs 557 * of "..", and trailing and leading dots, which means that the client 558 * cannot escape our base path via ".." traversal. 559 */ 560static void sanitize_client(struct strbuf *out, const char *in) 561{ 562 for (; *in; in++) { 563 if (is_dir_sep(*in)) 564 continue; 565 if (*in == '.' && (!out->len || out->buf[out->len - 1] == '.')) 566 continue; 567 strbuf_addch(out, *in); 568 } 569 570 while (out->len && out->buf[out->len - 1] == '.') 571 strbuf_setlen(out, out->len - 1); 572} 573 574/* 575 * Like sanitize_client, but we also perform any canonicalization 576 * to make life easier on the admin. 577 */ 578static void canonicalize_client(struct strbuf *out, const char *in) 579{ 580 sanitize_client(out, in); 581 strbuf_tolower(out); 582} 583 584/* 585 * Read the host as supplied by the client connection. 586 * 587 * Returns a pointer to the character after the NUL byte terminating the host 588 * argument, or 'extra_args' if there is no host argument. 589 */ 590static char *parse_host_arg(struct hostinfo *hi, char *extra_args, int buflen) 591{ 592 char *val; 593 int vallen; 594 char *end = extra_args + buflen; 595 596 if (extra_args < end && *extra_args) { 597 hi->saw_extended_args = 1; 598 if (strncasecmp("host=", extra_args, 5) == 0) { 599 val = extra_args + 5; 600 vallen = strlen(val) + 1; 601 loginfo("Extended attribute \"host\": %s", val); 602 if (*val) { 603 /* Split <host>:<port> at colon. */ 604 char *host; 605 char *port; 606 parse_host_and_port(val, &host, &port); 607 if (port) 608 sanitize_client(&hi->tcp_port, port); 609 canonicalize_client(&hi->hostname, host); 610 hi->hostname_lookup_done = 0; 611 } 612 613 /* On to the next one */ 614 extra_args = val + vallen; 615 } 616 if (extra_args < end && *extra_args) 617 die("Invalid request"); 618 } 619 620 return extra_args; 621} 622 623static void parse_extra_args(struct hostinfo *hi, struct strvec *env, 624 char *extra_args, int buflen) 625{ 626 const char *end = extra_args + buflen; 627 struct strbuf git_protocol = STRBUF_INIT; 628 629 /* First look for the host argument */ 630 extra_args = parse_host_arg(hi, extra_args, buflen); 631 632 /* Look for additional arguments places after a second NUL byte */ 633 for (; extra_args < end; extra_args += strlen(extra_args) + 1) { 634 const char *arg = extra_args; 635 636 /* 637 * Parse the extra arguments, adding most to 'git_protocol' 638 * which will be used to set the 'GIT_PROTOCOL' envvar in the 639 * service that will be run. 640 * 641 * If there ends up being a particular arg in the future that 642 * git-daemon needs to parse specifically (like the 'host' arg) 643 * then it can be parsed here and not added to 'git_protocol'. 644 */ 645 if (*arg) { 646 if (git_protocol.len > 0) 647 strbuf_addch(&git_protocol, ':'); 648 strbuf_addstr(&git_protocol, arg); 649 } 650 } 651 652 if (git_protocol.len > 0) { 653 loginfo("Extended attribute \"protocol\": %s", git_protocol.buf); 654 strvec_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=%s", 655 git_protocol.buf); 656 } 657 strbuf_release(&git_protocol); 658} 659 660/* 661 * Locate canonical hostname and its IP address. 662 */ 663static void lookup_hostname(struct hostinfo *hi) 664{ 665 if (!hi->hostname_lookup_done && hi->hostname.len) { 666#ifndef NO_IPV6 667 struct addrinfo hints; 668 struct addrinfo *ai; 669 int gai; 670 static char addrbuf[HOST_NAME_MAX + 1]; 671 672 memset(&hints, 0, sizeof(hints)); 673 hints.ai_flags = AI_CANONNAME; 674 675 gai = getaddrinfo(hi->hostname.buf, NULL, &hints, &ai); 676 if (!gai) { 677 struct sockaddr_in *sin_addr = (void *)ai->ai_addr; 678 679 inet_ntop(AF_INET, &sin_addr->sin_addr, 680 addrbuf, sizeof(addrbuf)); 681 strbuf_addstr(&hi->ip_address, addrbuf); 682 683 if (ai->ai_canonname) 684 sanitize_client(&hi->canon_hostname, 685 ai->ai_canonname); 686 else 687 strbuf_addbuf(&hi->canon_hostname, 688 &hi->ip_address); 689 690 freeaddrinfo(ai); 691 } 692#else 693 struct hostent *hent; 694 struct sockaddr_in sa; 695 char **ap; 696 static char addrbuf[HOST_NAME_MAX + 1]; 697 698 hent = gethostbyname(hi->hostname.buf); 699 if (hent) { 700 ap = hent->h_addr_list; 701 memset(&sa, 0, sizeof sa); 702 sa.sin_family = hent->h_addrtype; 703 sa.sin_port = htons(0); 704 memcpy(&sa.sin_addr, *ap, hent->h_length); 705 706 inet_ntop(hent->h_addrtype, &sa.sin_addr, 707 addrbuf, sizeof(addrbuf)); 708 709 sanitize_client(&hi->canon_hostname, hent->h_name); 710 strbuf_addstr(&hi->ip_address, addrbuf); 711 } 712#endif 713 hi->hostname_lookup_done = 1; 714 } 715} 716 717static void hostinfo_clear(struct hostinfo *hi) 718{ 719 strbuf_release(&hi->hostname); 720 strbuf_release(&hi->canon_hostname); 721 strbuf_release(&hi->ip_address); 722 strbuf_release(&hi->tcp_port); 723} 724 725static void set_keep_alive(int sockfd) 726{ 727 int ka = 1; 728 729 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &ka, sizeof(ka)) < 0) { 730 if (errno != ENOTSOCK) 731 logerror("unable to set SO_KEEPALIVE on socket: %s", 732 strerror(errno)); 733 } 734} 735 736static int execute(void) 737{ 738 char *line = packet_buffer; 739 int pktlen, len; 740 char *addr = getenv("REMOTE_ADDR"), *port = getenv("REMOTE_PORT"); 741 struct hostinfo hi = HOSTINFO_INIT; 742 struct strvec env = STRVEC_INIT; 743 744 if (addr) 745 loginfo("Connection from %s:%s", addr, port); 746 747 set_keep_alive(0); 748 alarm(init_timeout ? init_timeout : timeout); 749 pktlen = packet_read(0, packet_buffer, sizeof(packet_buffer), 0); 750 alarm(0); 751 752 len = strlen(line); 753 if (len && line[len-1] == '\n') 754 line[len-1] = 0; 755 756 /* parse additional args hidden behind a NUL byte */ 757 if (len != pktlen) 758 parse_extra_args(&hi, &env, line + len + 1, pktlen - len - 1); 759 760 for (size_t i = 0; i < ARRAY_SIZE(daemon_service); i++) { 761 struct daemon_service *s = &(daemon_service[i]); 762 const char *arg; 763 764 if (skip_prefix(line, "git-", &arg) && 765 skip_prefix(arg, s->name, &arg) && 766 *arg++ == ' ') { 767 /* 768 * Note: The directory here is probably context sensitive, 769 * and might depend on the actual service being performed. 770 */ 771 int rc = run_service(arg, s, &hi, &env); 772 hostinfo_clear(&hi); 773 strvec_clear(&env); 774 return rc; 775 } 776 } 777 778 hostinfo_clear(&hi); 779 strvec_clear(&env); 780 logerror("Protocol error: '%s'", line); 781 return -1; 782} 783 784static int addrcmp(const struct sockaddr_storage *s1, 785 const struct sockaddr_storage *s2) 786{ 787 const struct sockaddr *sa1 = (const struct sockaddr*) s1; 788 const struct sockaddr *sa2 = (const struct sockaddr*) s2; 789 790 if (sa1->sa_family != sa2->sa_family) 791 return sa1->sa_family - sa2->sa_family; 792 if (sa1->sa_family == AF_INET) 793 return memcmp(&((struct sockaddr_in *)s1)->sin_addr, 794 &((struct sockaddr_in *)s2)->sin_addr, 795 sizeof(struct in_addr)); 796#ifndef NO_IPV6 797 if (sa1->sa_family == AF_INET6) 798 return memcmp(&((struct sockaddr_in6 *)s1)->sin6_addr, 799 &((struct sockaddr_in6 *)s2)->sin6_addr, 800 sizeof(struct in6_addr)); 801#endif 802 return 0; 803} 804 805static unsigned int max_connections = 32; 806static unsigned int live_children; 807 808static struct child { 809 struct child *next; 810 struct child_process cld; 811 struct sockaddr_storage address; 812} *firstborn; 813 814static void add_child(struct child_process *cld, struct sockaddr *addr, socklen_t addrlen) 815{ 816 struct child *newborn, **cradle; 817 818 CALLOC_ARRAY(newborn, 1); 819 live_children++; 820 memcpy(&newborn->cld, cld, sizeof(*cld)); 821 memcpy(&newborn->address, addr, addrlen); 822 for (cradle = &firstborn; *cradle; cradle = &(*cradle)->next) 823 if (!addrcmp(&(*cradle)->address, &newborn->address)) 824 break; 825 newborn->next = *cradle; 826 *cradle = newborn; 827} 828 829/* 830 * This gets called if the number of connections grows 831 * past "max_connections". 832 * 833 * We kill the newest connection from a duplicate IP. 834 */ 835static void kill_some_child(void) 836{ 837 const struct child *blanket, *next; 838 839 if (!(blanket = firstborn)) 840 return; 841 842 for (; (next = blanket->next); blanket = next) 843 if (!addrcmp(&blanket->address, &next->address)) { 844 kill(blanket->cld.pid, SIGTERM); 845 break; 846 } 847} 848 849static void check_dead_children(void) 850{ 851 int status; 852 pid_t pid; 853 854 struct child **cradle, *blanket; 855 for (cradle = &firstborn; (blanket = *cradle);) 856 if ((pid = waitpid(blanket->cld.pid, &status, WNOHANG)) > 1) { 857 const char *dead = ""; 858 if (status) 859 dead = " (with error)"; 860 loginfo("[%"PRIuMAX"] Disconnected%s", (uintmax_t)pid, dead); 861 862 /* remove the child */ 863 *cradle = blanket->next; 864 live_children--; 865 child_process_clear(&blanket->cld); 866 free(blanket); 867 } else 868 cradle = &blanket->next; 869} 870 871static struct strvec cld_argv = STRVEC_INIT; 872static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen) 873{ 874 struct child_process cld = CHILD_PROCESS_INIT; 875 876 if (max_connections && live_children >= max_connections) { 877 kill_some_child(); 878 sleep(1); /* give it some time to die */ 879 check_dead_children(); 880 if (live_children >= max_connections) { 881 close(incoming); 882 logerror("Too many children, dropping connection"); 883 return; 884 } 885 } 886 887 if (addr->sa_family == AF_INET) { 888 char buf[128] = ""; 889 struct sockaddr_in *sin_addr = (void *) addr; 890 inet_ntop(addr->sa_family, &sin_addr->sin_addr, buf, sizeof(buf)); 891 strvec_pushf(&cld.env, "REMOTE_ADDR=%s", buf); 892 strvec_pushf(&cld.env, "REMOTE_PORT=%d", 893 ntohs(sin_addr->sin_port)); 894#ifndef NO_IPV6 895 } else if (addr->sa_family == AF_INET6) { 896 char buf[128] = ""; 897 struct sockaddr_in6 *sin6_addr = (void *) addr; 898 inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(buf)); 899 strvec_pushf(&cld.env, "REMOTE_ADDR=[%s]", buf); 900 strvec_pushf(&cld.env, "REMOTE_PORT=%d", 901 ntohs(sin6_addr->sin6_port)); 902#endif 903 } 904 905 strvec_pushv(&cld.args, cld_argv.v); 906 cld.in = incoming; 907 cld.out = dup(incoming); 908 909 if (start_command(&cld)) 910 logerror("unable to fork"); 911 else 912 add_child(&cld, addr, addrlen); 913} 914 915static void child_handler(int signo UNUSED) 916{ 917 /* 918 * Otherwise empty handler because systemcalls should get interrupted 919 * upon signal receipt. 920 */ 921} 922 923static int set_reuse_addr(int sockfd) 924{ 925 int on = 1; 926 927 if (!reuseaddr) 928 return 0; 929 return setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, 930 &on, sizeof(on)); 931} 932 933struct socketlist { 934 int *list; 935 size_t nr; 936 size_t alloc; 937}; 938 939static const char *ip2str(int family, struct sockaddr *sin, socklen_t len) 940{ 941#ifdef NO_IPV6 942 static char ip[INET_ADDRSTRLEN]; 943#else 944 static char ip[INET6_ADDRSTRLEN]; 945#endif 946 947 switch (family) { 948#ifndef NO_IPV6 949 case AF_INET6: 950 inet_ntop(family, &((struct sockaddr_in6*)sin)->sin6_addr, ip, len); 951 break; 952#endif 953 case AF_INET: 954 inet_ntop(family, &((struct sockaddr_in*)sin)->sin_addr, ip, len); 955 break; 956 default: 957 xsnprintf(ip, sizeof(ip), "<unknown>"); 958 } 959 return ip; 960} 961 962#ifndef NO_IPV6 963 964static int setup_named_sock(char *listen_addr, int listen_port, struct socketlist *socklist) 965{ 966 int socknum = 0; 967 char pbuf[NI_MAXSERV]; 968 struct addrinfo hints, *ai0, *ai; 969 int gai; 970 long flags; 971 972 xsnprintf(pbuf, sizeof(pbuf), "%d", listen_port); 973 memset(&hints, 0, sizeof(hints)); 974 hints.ai_family = AF_UNSPEC; 975 hints.ai_socktype = SOCK_STREAM; 976 hints.ai_protocol = IPPROTO_TCP; 977 hints.ai_flags = AI_PASSIVE; 978 979 gai = getaddrinfo(listen_addr, pbuf, &hints, &ai0); 980 if (gai) { 981 logerror("getaddrinfo() for %s failed: %s", listen_addr, gai_strerror(gai)); 982 return 0; 983 } 984 985 for (ai = ai0; ai; ai = ai->ai_next) { 986 int sockfd; 987 988 sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); 989 if (sockfd < 0) 990 continue; 991 992#ifdef IPV6_V6ONLY 993 if (ai->ai_family == AF_INET6) { 994 int on = 1; 995 setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, 996 &on, sizeof(on)); 997 /* Note: error is not fatal */ 998 } 999#endif 1000 1001 if (set_reuse_addr(sockfd)) { 1002 logerror("Could not set SO_REUSEADDR: %s", strerror(errno)); 1003 close(sockfd); 1004 continue; 1005 } 1006 1007 set_keep_alive(sockfd); 1008 1009 if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) { 1010 logerror("Could not bind to %s: %s", 1011 ip2str(ai->ai_family, ai->ai_addr, ai->ai_addrlen), 1012 strerror(errno)); 1013 close(sockfd); 1014 continue; /* not fatal */ 1015 } 1016 if (listen(sockfd, 5) < 0) { 1017 logerror("Could not listen to %s: %s", 1018 ip2str(ai->ai_family, ai->ai_addr, ai->ai_addrlen), 1019 strerror(errno)); 1020 close(sockfd); 1021 continue; /* not fatal */ 1022 } 1023 1024 flags = fcntl(sockfd, F_GETFD, 0); 1025 if (flags >= 0) 1026 fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC); 1027 1028 ALLOC_GROW(socklist->list, socklist->nr + 1, socklist->alloc); 1029 socklist->list[socklist->nr++] = sockfd; 1030 socknum++; 1031 } 1032 1033 freeaddrinfo(ai0); 1034 1035 return socknum; 1036} 1037 1038#else /* NO_IPV6 */ 1039 1040static int setup_named_sock(char *listen_addr, int listen_port, struct socketlist *socklist) 1041{ 1042 struct sockaddr_in sin; 1043 int sockfd; 1044 long flags; 1045 1046 memset(&sin, 0, sizeof sin); 1047 sin.sin_family = AF_INET; 1048 sin.sin_port = htons(listen_port); 1049 1050 if (listen_addr) { 1051 /* Well, host better be an IP address here. */ 1052 if (inet_pton(AF_INET, listen_addr, &sin.sin_addr.s_addr) <= 0) 1053 return 0; 1054 } else { 1055 sin.sin_addr.s_addr = htonl(INADDR_ANY); 1056 } 1057 1058 sockfd = socket(AF_INET, SOCK_STREAM, 0); 1059 if (sockfd < 0) 1060 return 0; 1061 1062 if (set_reuse_addr(sockfd)) { 1063 logerror("Could not set SO_REUSEADDR: %s", strerror(errno)); 1064 close(sockfd); 1065 return 0; 1066 } 1067 1068 set_keep_alive(sockfd); 1069 1070 if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) { 1071 logerror("Could not bind to %s: %s", 1072 ip2str(AF_INET, (struct sockaddr *)&sin, sizeof(sin)), 1073 strerror(errno)); 1074 close(sockfd); 1075 return 0; 1076 } 1077 1078 if (listen(sockfd, 5) < 0) { 1079 logerror("Could not listen to %s: %s", 1080 ip2str(AF_INET, (struct sockaddr *)&sin, sizeof(sin)), 1081 strerror(errno)); 1082 close(sockfd); 1083 return 0; 1084 } 1085 1086 flags = fcntl(sockfd, F_GETFD, 0); 1087 if (flags >= 0) 1088 fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC); 1089 1090 ALLOC_GROW(socklist->list, socklist->nr + 1, socklist->alloc); 1091 socklist->list[socklist->nr++] = sockfd; 1092 return 1; 1093} 1094 1095#endif 1096 1097static void socksetup(struct string_list *listen_addr, int listen_port, struct socketlist *socklist) 1098{ 1099 if (!listen_addr->nr) 1100 setup_named_sock(NULL, listen_port, socklist); 1101 else { 1102 int socknum; 1103 for (size_t i = 0; i < listen_addr->nr; i++) { 1104 socknum = setup_named_sock(listen_addr->items[i].string, 1105 listen_port, socklist); 1106 1107 if (socknum == 0) 1108 logerror("unable to allocate any listen sockets for host %s on port %u", 1109 listen_addr->items[i].string, listen_port); 1110 } 1111 } 1112} 1113 1114static int service_loop(struct socketlist *socklist) 1115{ 1116 struct sigaction sa; 1117 struct pollfd *pfd; 1118 1119 CALLOC_ARRAY(pfd, socklist->nr); 1120 1121 for (size_t i = 0; i < socklist->nr; i++) { 1122 pfd[i].fd = socklist->list[i]; 1123 pfd[i].events = POLLIN; 1124 } 1125 1126 sigemptyset(&sa.sa_mask); 1127 sa.sa_flags = SA_NOCLDSTOP; 1128 sa.sa_handler = child_handler; 1129 sigaction(SIGCHLD, &sa, NULL); 1130 1131 for (;;) { 1132 check_dead_children(); 1133 1134 if (poll(pfd, socklist->nr, -1) < 0) { 1135 if (errno != EINTR) { 1136 logerror("Poll failed, resuming: %s", 1137 strerror(errno)); 1138 sleep(1); 1139 } 1140 continue; 1141 } 1142 1143 for (size_t i = 0; i < socklist->nr; i++) { 1144 if (pfd[i].revents & POLLIN) { 1145 union { 1146 struct sockaddr sa; 1147 struct sockaddr_in sai; 1148#ifndef NO_IPV6 1149 struct sockaddr_in6 sai6; 1150#endif 1151 } ss; 1152 socklen_t sslen = sizeof(ss); 1153 int incoming; 1154 int retry = 3; 1155 1156 redo: 1157 incoming = accept(pfd[i].fd, &ss.sa, &sslen); 1158 if (incoming < 0) { 1159 switch (errno) { 1160 case EINTR: 1161 if (--retry) 1162 goto redo; 1163 1164 /* fallthrough */ 1165 case EAGAIN: 1166 case ECONNABORTED: 1167 continue; 1168 default: 1169 die_errno("accept returned"); 1170 } 1171 } 1172 handle(incoming, &ss.sa, sslen); 1173 } 1174 } 1175 } 1176} 1177 1178#ifdef NO_POSIX_GOODIES 1179 1180struct credentials; 1181 1182static void drop_privileges(struct credentials *cred UNUSED) 1183{ 1184 /* nothing */ 1185} 1186 1187static struct credentials *prepare_credentials(const char *user_name UNUSED, 1188 const char *group_name UNUSED) 1189{ 1190 die("--user not supported on this platform"); 1191} 1192 1193#else 1194 1195struct credentials { 1196 struct passwd *pass; 1197 gid_t gid; 1198}; 1199 1200static void drop_privileges(struct credentials *cred) 1201{ 1202 if (cred && (initgroups(cred->pass->pw_name, cred->gid) || 1203 setgid (cred->gid) || setuid(cred->pass->pw_uid))) 1204 die("cannot drop privileges"); 1205} 1206 1207static struct credentials *prepare_credentials(const char *user_name, 1208 const char *group_name) 1209{ 1210 static struct credentials c; 1211 1212 c.pass = getpwnam(user_name); 1213 if (!c.pass) 1214 die("user not found - %s", user_name); 1215 1216 if (!group_name) 1217 c.gid = c.pass->pw_gid; 1218 else { 1219 struct group *group = getgrnam(group_name); 1220 if (!group) 1221 die("group not found - %s", group_name); 1222 1223 c.gid = group->gr_gid; 1224 } 1225 1226 return &c; 1227} 1228#endif 1229 1230static int serve(struct string_list *listen_addr, int listen_port, 1231 struct credentials *cred) 1232{ 1233 struct socketlist socklist = { NULL, 0, 0 }; 1234 1235 socksetup(listen_addr, listen_port, &socklist); 1236 if (socklist.nr == 0) 1237 die("unable to allocate any listen sockets on port %u", 1238 listen_port); 1239 1240 drop_privileges(cred); 1241 1242 loginfo("Ready to rumble"); 1243 1244 return service_loop(&socklist); 1245} 1246 1247int cmd_main(int argc, const char **argv) 1248{ 1249 int listen_port = 0; 1250 struct string_list listen_addr = STRING_LIST_INIT_DUP; 1251 int serve_mode = 0, inetd_mode = 0; 1252 const char *pid_file = NULL, *user_name = NULL, *group_name = NULL; 1253 int detach = 0; 1254 struct credentials *cred = NULL; 1255 int i; 1256 int ret; 1257 1258 for (i = 1; i < argc; i++) { 1259 const char *arg = argv[i]; 1260 const char *v; 1261 1262 if (skip_prefix(arg, "--listen=", &v)) { 1263 string_list_append_nodup(&listen_addr, xstrdup_tolower(v)); 1264 continue; 1265 } 1266 if (skip_prefix(arg, "--port=", &v)) { 1267 char *end; 1268 unsigned long n; 1269 n = strtoul(v, &end, 0); 1270 if (*v && !*end) { 1271 listen_port = n; 1272 continue; 1273 } 1274 } 1275 if (!strcmp(arg, "--serve")) { 1276 serve_mode = 1; 1277 continue; 1278 } 1279 if (!strcmp(arg, "--inetd")) { 1280 inetd_mode = 1; 1281 continue; 1282 } 1283 if (!strcmp(arg, "--verbose")) { 1284 verbose = 1; 1285 continue; 1286 } 1287 if (!strcmp(arg, "--syslog")) { 1288 log_destination = LOG_DESTINATION_SYSLOG; 1289 continue; 1290 } 1291 if (skip_prefix(arg, "--log-destination=", &v)) { 1292 if (!strcmp(v, "syslog")) { 1293 log_destination = LOG_DESTINATION_SYSLOG; 1294 continue; 1295 } else if (!strcmp(v, "stderr")) { 1296 log_destination = LOG_DESTINATION_STDERR; 1297 continue; 1298 } else if (!strcmp(v, "none")) { 1299 log_destination = LOG_DESTINATION_NONE; 1300 continue; 1301 } else 1302 die("unknown log destination '%s'", v); 1303 } 1304 if (!strcmp(arg, "--export-all")) { 1305 export_all_trees = 1; 1306 continue; 1307 } 1308 if (skip_prefix(arg, "--access-hook=", &v)) { 1309 access_hook = v; 1310 continue; 1311 } 1312 if (skip_prefix(arg, "--timeout=", &v)) { 1313 if (strtoul_ui(v, 10, &timeout)) 1314 die(_("invalid timeout '%s', expecting a non-negative integer"), v); 1315 continue; 1316 } 1317 if (skip_prefix(arg, "--init-timeout=", &v)) { 1318 if (strtoul_ui(v, 10, &init_timeout)) 1319 die(_("invalid init-timeout '%s', expecting a non-negative integer"), v); 1320 continue; 1321 } 1322 if (skip_prefix(arg, "--max-connections=", &v)) { 1323 int parsed_value; 1324 if (strtol_i(v, 10, &parsed_value)) 1325 die(_("invalid max-connections '%s', expecting an integer"), v); 1326 /* A negative value indicates unlimited children. */ 1327 max_connections = parsed_value < 0 ? 0 : parsed_value; 1328 continue; 1329 } 1330 if (!strcmp(arg, "--strict-paths")) { 1331 strict_paths = 1; 1332 continue; 1333 } 1334 if (skip_prefix(arg, "--base-path=", &v)) { 1335 base_path = v; 1336 continue; 1337 } 1338 if (!strcmp(arg, "--base-path-relaxed")) { 1339 base_path_relaxed = 1; 1340 continue; 1341 } 1342 if (skip_prefix(arg, "--interpolated-path=", &v)) { 1343 interpolated_path = v; 1344 continue; 1345 } 1346 if (!strcmp(arg, "--reuseaddr")) { 1347 reuseaddr = 1; 1348 continue; 1349 } 1350 if (!strcmp(arg, "--user-path")) { 1351 user_path = ""; 1352 continue; 1353 } 1354 if (skip_prefix(arg, "--user-path=", &v)) { 1355 user_path = v; 1356 continue; 1357 } 1358 if (skip_prefix(arg, "--pid-file=", &v)) { 1359 pid_file = v; 1360 continue; 1361 } 1362 if (!strcmp(arg, "--detach")) { 1363 detach = 1; 1364 continue; 1365 } 1366 if (skip_prefix(arg, "--user=", &v)) { 1367 user_name = v; 1368 continue; 1369 } 1370 if (skip_prefix(arg, "--group=", &v)) { 1371 group_name = v; 1372 continue; 1373 } 1374 if (skip_prefix(arg, "--enable=", &v)) { 1375 enable_service(v, 1); 1376 continue; 1377 } 1378 if (skip_prefix(arg, "--disable=", &v)) { 1379 enable_service(v, 0); 1380 continue; 1381 } 1382 if (skip_prefix(arg, "--allow-override=", &v)) { 1383 make_service_overridable(v, 1); 1384 continue; 1385 } 1386 if (skip_prefix(arg, "--forbid-override=", &v)) { 1387 make_service_overridable(v, 0); 1388 continue; 1389 } 1390 if (!strcmp(arg, "--informative-errors")) { 1391 informative_errors = 1; 1392 continue; 1393 } 1394 if (!strcmp(arg, "--no-informative-errors")) { 1395 informative_errors = 0; 1396 continue; 1397 } 1398 if (!strcmp(arg, "--")) { 1399 ok_paths = &argv[i+1]; 1400 break; 1401 } else if (arg[0] != '-') { 1402 ok_paths = &argv[i]; 1403 break; 1404 } 1405 1406 usage(daemon_usage); 1407 } 1408 1409 if (log_destination == LOG_DESTINATION_UNSET) { 1410 if (inetd_mode || detach) 1411 log_destination = LOG_DESTINATION_SYSLOG; 1412 else 1413 log_destination = LOG_DESTINATION_STDERR; 1414 } 1415 1416 if (log_destination == LOG_DESTINATION_SYSLOG) { 1417 openlog("git-daemon", LOG_PID, LOG_DAEMON); 1418 set_die_routine(daemon_die); 1419 } else 1420 /* avoid splitting a message in the middle */ 1421 setvbuf(stderr, NULL, _IOFBF, 4096); 1422 1423 if (inetd_mode && (detach || group_name || user_name)) 1424 die("--detach, --user and --group are incompatible with --inetd"); 1425 1426 if (inetd_mode && (listen_port || (listen_addr.nr > 0))) 1427 die("--listen= and --port= are incompatible with --inetd"); 1428 else if (listen_port == 0) 1429 listen_port = DEFAULT_GIT_PORT; 1430 1431 if (group_name && !user_name) 1432 die("--group supplied without --user"); 1433 1434 if (user_name) 1435 cred = prepare_credentials(user_name, group_name); 1436 1437 if (strict_paths && (!ok_paths || !*ok_paths)) 1438 die("option --strict-paths requires '<directory>' arguments"); 1439 1440 if (base_path && !is_directory(base_path)) 1441 die("base-path '%s' does not exist or is not a directory", 1442 base_path); 1443 1444 if (log_destination != LOG_DESTINATION_STDERR) { 1445 if (!freopen("/dev/null", "w", stderr)) 1446 die_errno("failed to redirect stderr to /dev/null"); 1447 } 1448 1449 if (inetd_mode || serve_mode) { 1450 ret = execute(); 1451 } else { 1452 if (detach) { 1453 if (daemonize()) 1454 die("--detach not supported on this platform"); 1455 } 1456 1457 if (pid_file) 1458 write_file(pid_file, "%"PRIuMAX, (uintmax_t) getpid()); 1459 1460 /* prepare argv for serving-processes */ 1461 strvec_push(&cld_argv, argv[0]); /* git-daemon */ 1462 strvec_push(&cld_argv, "--serve"); 1463 for (i = 1; i < argc; ++i) 1464 strvec_push(&cld_argv, argv[i]); 1465 1466 ret = serve(&listen_addr, listen_port, cred); 1467 } 1468 1469 string_list_clear(&listen_addr, 0); 1470 return ret; 1471}