daemon.c 29.1 KB
Newer Older
1
#include "cache.h"
2
#include "pkt-line.h"
3
#include "exec_cmd.h"
4 5
#include "run-command.h"
#include "strbuf.h"
6
#include "string-list.h"
P
Petr Baudis 已提交
7

8 9 10 11
#ifndef HOST_NAME_MAX
#define HOST_NAME_MAX 256
#endif

12 13 14 15
#ifndef NI_MAXSERV
#define NI_MAXSERV 32
#endif

16 17 18 19
#ifdef NO_INITGROUPS
#define initgroups(x, y) (0) /* nothing */
#endif

20
static int log_syslog;
P
Petr Baudis 已提交
21
static int verbose;
22
static int reuseaddr;
23
static int informative_errors;
P
Petr Baudis 已提交
24

25
static const char daemon_usage[] =
S
Stephan Beyer 已提交
26
"git daemon [--verbose] [--syslog] [--export-all]\n"
27 28 29 30
"           [--timeout=<n>] [--init-timeout=<n>] [--max-connections=<n>]\n"
"           [--strict-paths] [--base-path=<path>] [--base-path-relaxed]\n"
"           [--user-path | --user-path=<path>]\n"
"           [--interpolated-path=<path>]\n"
31
"           [--reuseaddr] [--pid-file=<file>]\n"
32 33
"           [--(enable|disable|allow-override|forbid-override)=<service>]\n"
"           [--inetd | [--listen=<host_or_ipaddr>] [--port=<n>]\n"
34
"                      [--detach] [--user=<user> [--group=<group>]]\n"
35
"           [<directory>...]";
36 37

/* List of acceptable pathname prefixes */
38 39
static char **ok_paths;
static int strict_paths;
40 41

/* If this is set, git-daemon-export-ok is not required */
42
static int export_all_trees;
P
Petr Baudis 已提交
43

P
Petr Baudis 已提交
44
/* Take all paths relative to this one if non-NULL */
45
static char *base_path;
46
static char *interpolated_path;
J
Jens Axboe 已提交
47
static int base_path_relaxed;
48 49 50

/* Flag indicating client sent extra args. */
static int saw_extended_args;
P
Petr Baudis 已提交
51

52 53 54 55
/* If defined, ~user notation is allowed and the string is inserted
 * after ~user/.  E.g. a request to git://host/~alice/frotz would
 * go to /home/alice/pub_git/frotz with --user-path=pub_git.
 */
56
static const char *user_path;
57

58
/* Timeout, and initial timeout */
59 60
static unsigned int timeout;
static unsigned int init_timeout;
P
Petr Baudis 已提交
61

62 63 64 65
static char *hostname;
static char *canon_hostname;
static char *ip_address;
static char *tcp_port;
66

67
static void logreport(int priority, const char *err, va_list params)
P
Petr Baudis 已提交
68
{
69
	if (log_syslog) {
70 71
		char buf[1024];
		vsnprintf(buf, sizeof(buf), err, params);
72
		syslog(priority, "%s", buf);
J
Junio C Hamano 已提交
73 74
	} else {
		/*
75
		 * Since stderr is set to buffered mode, the
76
		 * logging of different processes will not overlap
77
		 * unless they overflow the (rather big) buffers.
78
		 */
79
		fprintf(stderr, "[%"PRIuMAX"] ", (uintmax_t)getpid());
80 81
		vfprintf(stderr, err, params);
		fputc('\n', stderr);
82
		fflush(stderr);
83
	}
P
Petr Baudis 已提交
84 85
}

86
__attribute__((format (printf, 1, 2)))
87
static void logerror(const char *err, ...)
P
Petr Baudis 已提交
88 89 90
{
	va_list params;
	va_start(params, err);
91
	logreport(LOG_ERR, err, params);
P
Petr Baudis 已提交
92 93 94
	va_end(params);
}

95
__attribute__((format (printf, 1, 2)))
96
static void loginfo(const char *err, ...)
P
Petr Baudis 已提交
97 98 99 100 101
{
	va_list params;
	if (!verbose)
		return;
	va_start(params, err);
102
	logreport(LOG_INFO, err, params);
P
Petr Baudis 已提交
103 104
	va_end(params);
}
105

106 107 108 109 110 111
static void NORETURN daemon_die(const char *err, va_list params)
{
	logreport(LOG_ERR, err, params);
	exit(1);
}

E
Erik Faye-Lund 已提交
112
static const char *path_ok(char *directory)
113
{
114
	static char rpath[PATH_MAX];
115
	static char interp_path[PATH_MAX];
E
Erik Faye-Lund 已提交
116
	const char *path;
117 118
	char *dir;

119
	dir = directory;
120

121
	if (daemon_avoid_alias(dir)) {
122 123 124 125
		logerror("'%s': aliased", dir);
		return NULL;
	}

126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
	if (*dir == '~') {
		if (!user_path) {
			logerror("'%s': User-path not allowed", dir);
			return NULL;
		}
		if (*user_path) {
			/* Got either "~alice" or "~alice/foo";
			 * rewrite them to "~alice/%s" or
			 * "~alice/%s/foo".
			 */
			int namlen, restlen = strlen(dir);
			char *slash = strchr(dir, '/');
			if (!slash)
				slash = dir + restlen;
			namlen = slash - dir;
			restlen -= namlen;
			loginfo("userpath <%s>, request <%s>, namlen %d, restlen %d, slash <%s>", user_path, dir, namlen, restlen, slash);
			snprintf(rpath, PATH_MAX, "%.*s/%s%.*s",
				 namlen, dir, user_path, restlen, slash);
			dir = rpath;
		}
	}
148
	else if (interpolated_path && saw_extended_args) {
149
		struct strbuf expanded_path = STRBUF_INIT;
150 151 152 153 154 155 156 157
		struct strbuf_expand_dict_entry dict[6];

		dict[0].placeholder = "H"; dict[0].value = hostname;
		dict[1].placeholder = "CH"; dict[1].value = canon_hostname;
		dict[2].placeholder = "IP"; dict[2].value = ip_address;
		dict[3].placeholder = "P"; dict[3].value = tcp_port;
		dict[4].placeholder = "D"; dict[4].value = directory;
		dict[5].placeholder = NULL; dict[5].value = NULL;
158 159 160 161 162 163
		if (*dir != '/') {
			/* Allow only absolute */
			logerror("'%s': Non-absolute path denied (interpolated-path active)", dir);
			return NULL;
		}

164 165 166 167
		strbuf_expand(&expanded_path, interpolated_path,
				strbuf_expand_dict_cb, &dict);
		strlcpy(interp_path, expanded_path.buf, PATH_MAX);
		strbuf_release(&expanded_path);
168 169 170 171
		loginfo("Interpolated dir '%s'", interp_path);

		dir = interp_path;
	}
172 173 174
	else if (base_path) {
		if (*dir != '/') {
			/* Allow only absolute */
175
			logerror("'%s': Non-absolute path denied (base-path active)", dir);
P
Petr Baudis 已提交
176 177
			return NULL;
		}
178 179
		snprintf(rpath, PATH_MAX, "%s%s", base_path, dir);
		dir = rpath;
P
Petr Baudis 已提交
180 181
	}

182 183
	path = enter_repo(dir, strict_paths);
	if (!path && base_path && base_path_relaxed) {
J
Jens Axboe 已提交
184 185 186 187
		/*
		 * if we fail and base_path_relaxed is enabled, try without
		 * prefixing the base path
		 */
188 189 190
		dir = directory;
		path = enter_repo(dir, strict_paths);
	}
191

192
	if (!path) {
193
		logerror("'%s' does not appear to be a git repository", dir);
194
		return NULL;
195 196 197
	}

	if ( ok_paths && *ok_paths ) {
J
Junio C Hamano 已提交
198
		char **pp;
199
		int pathlen = strlen(path);
200

J
Junio C Hamano 已提交
201
		/* The validation is done on the paths after enter_repo
J
Junio C Hamano 已提交
202
		 * appends optional {.git,.git/.git} and friends, but
203 204 205 206
		 * it does not use getcwd().  So if your /pub is
		 * a symlink to /mnt/pub, you can whitelist /pub and
		 * do not have to say /mnt/pub.
		 * Do not say /pub/.
J
Junio C Hamano 已提交
207
		 */
208 209
		for ( pp = ok_paths ; *pp ; pp++ ) {
			int len = strlen(*pp);
J
Junio C Hamano 已提交
210 211 212 213 214
			if (len <= pathlen &&
			    !memcmp(*pp, path, len) &&
			    (path[len] == '\0' ||
			     (!strict_paths && path[len] == '/')))
				return path;
215
		}
216 217 218 219 220
	}
	else {
		/* be backwards compatible */
		if (!strict_paths)
			return path;
221 222
	}

223 224
	logerror("'%s': not in whitelist", path);
	return NULL;		/* Fallthrough. Deny by default */
225
}
226

227 228 229 230 231 232 233 234 235 236 237 238
typedef int (*daemon_service_fn)(void);
struct daemon_service {
	const char *name;
	const char *config_name;
	daemon_service_fn fn;
	int enabled;
	int overridable;
};

static struct daemon_service *service_looking_at;
static int service_enabled;

239
static int git_daemon_config(const char *var, const char *value, void *cb)
240
{
241
	if (!prefixcmp(var, "daemon.") &&
242 243 244 245 246 247 248 249 250
	    !strcmp(var + 7, service_looking_at->config_name)) {
		service_enabled = git_config_bool(var, value);
		return 0;
	}

	/* we are not interested in parsing any other configuration here */
	return 0;
}

251 252 253 254 255 256 257 258
static int daemon_error(const char *dir, const char *msg)
{
	if (!informative_errors)
		msg = "access denied or repository not exported";
	packet_write(1, "ERR %s: %s", msg, dir);
	return -1;
}

259
static int run_service(char *dir, struct daemon_service *service)
260
{
261
	const char *path;
262 263
	int enabled = service->enabled;

264
	loginfo("Request %s for '%s'", service->name, dir);
265

266 267 268
	if (!enabled && !service->overridable) {
		logerror("'%s': service not enabled.", service->name);
		errno = EACCES;
269
		return daemon_error(dir, "service not enabled");
270
	}
271

272
	if (!(path = path_ok(dir)))
273
		return daemon_error(dir, "no such repository");
H
H. Peter Anvin 已提交
274

275 276 277
	/*
	 * Security on the cheap.
	 *
278
	 * We want a readable HEAD, usable "objects" directory, and
279 280
	 * a "git-daemon-export-ok" flag that says that the other side
	 * is ok with us doing this.
281 282 283
	 *
	 * path_ok() uses enter_repo() and does whitelist checking.
	 * We only need to make sure the repository is exported.
284
	 */
285

286
	if (!export_all_trees && access("git-daemon-export-ok", F_OK)) {
287
		logerror("'%s': repository not exported.", path);
288
		errno = EACCES;
289
		return daemon_error(dir, "repository not exported");
290 291
	}

292 293 294
	if (service->overridable) {
		service_looking_at = service;
		service_enabled = -1;
295
		git_config(git_daemon_config, NULL);
296 297 298 299 300 301 302
		if (0 <= service_enabled)
			enabled = service_enabled;
	}
	if (!enabled) {
		logerror("'%s': service not enabled for '%s'",
			 service->name, path);
		errno = EACCES;
303
		return daemon_error(dir, "service not enabled");
304 305
	}

306 307 308 309 310 311
	/*
	 * We'll ignore SIGTERM from now on, we have a
	 * good client.
	 */
	signal(SIGTERM, SIG_IGN);

312 313 314
	return service->fn();
}

315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
static void copy_to_log(int fd)
{
	struct strbuf line = STRBUF_INIT;
	FILE *fp;

	fp = fdopen(fd, "r");
	if (fp == NULL) {
		logerror("fdopen of error channel failed");
		close(fd);
		return;
	}

	while (strbuf_getline(&line, fp, '\n') != EOF) {
		logerror("%s", line.buf);
		strbuf_setlen(&line, 0);
	}

	strbuf_release(&line);
	fclose(fp);
}

static int run_service_command(const char **argv)
{
	struct child_process cld;

	memset(&cld, 0, sizeof(cld));
	cld.argv = argv;
	cld.git_cmd = 1;
	cld.err = -1;
	if (start_command(&cld))
		return -1;

	close(0);
	close(1);

	copy_to_log(cld.err);

	return finish_command(&cld);
}

355 356 357 358
static int upload_pack(void)
{
	/* Timeout as string */
	char timeout_buf[64];
359 360 361
	const char *argv[] = { "upload-pack", "--strict", NULL, ".", NULL };

	argv[2] = timeout_buf;
362

363
	snprintf(timeout_buf, sizeof timeout_buf, "--timeout=%u", timeout);
364
	return run_service_command(argv);
365 366
}

F
Franck Bui-Huu 已提交
367 368
static int upload_archive(void)
{
369 370
	static const char *argv[] = { "upload-archive", ".", NULL };
	return run_service_command(argv);
F
Franck Bui-Huu 已提交
371 372
}

L
Linus Torvalds 已提交
373 374
static int receive_pack(void)
{
375 376
	static const char *argv[] = { "receive-pack", ".", NULL };
	return run_service_command(argv);
L
Linus Torvalds 已提交
377 378
}

379
static struct daemon_service daemon_service[] = {
F
Franck Bui-Huu 已提交
380
	{ "upload-archive", "uploadarch", upload_archive, 0, 1 },
381
	{ "upload-pack", "uploadpack", upload_pack, 1, 1 },
L
Linus Torvalds 已提交
382
	{ "receive-pack", "receivepack", receive_pack, 0, 1 },
383 384
};

385 386
static void enable_service(const char *name, int ena)
{
387 388 389 390 391 392 393 394 395 396
	int i;
	for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
		if (!strcmp(daemon_service[i].name, name)) {
			daemon_service[i].enabled = ena;
			return;
		}
	}
	die("No such service %s", name);
}

397 398
static void make_service_overridable(const char *name, int ena)
{
399 400 401 402 403 404 405 406 407 408
	int i;
	for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
		if (!strcmp(daemon_service[i].name, name)) {
			daemon_service[i].overridable = ena;
			return;
		}
	}
	die("No such service %s", name);
}

409 410 411 412 413 414 415 416
static char *xstrdup_tolower(const char *str)
{
	char *p, *dup = xstrdup(str);
	for (p = dup; *p; p++)
		*p = tolower(*p);
	return dup;
}

417 418 419 420 421 422 423 424
static void parse_host_and_port(char *hostport, char **host,
	char **port)
{
	if (*hostport == '[') {
		char *end;

		end = strchr(hostport, ']');
		if (!end)
425
			die("Invalid request ('[' without ']')");
426 427 428 429 430 431 432 433 434 435 436 437
		*end = '\0';
		*host = hostport + 1;
		if (!end[1])
			*port = NULL;
		else if (end[1] == ':')
			*port = end + 2;
		else
			die("Garbage after end of host part");
	} else {
		*host = hostport;
		*port = strrchr(hostport, ':');
		if (*port) {
438
			**port = '\0';
439 440 441 442 443
			++*port;
		}
	}
}

444
/*
445
 * Read the host as supplied by the client connection.
446
 */
447
static void parse_host_arg(char *extra_args, int buflen)
448 449 450 451 452
{
	char *val;
	int vallen;
	char *end = extra_args + buflen;

453
	if (extra_args < end && *extra_args) {
454 455 456 457 458
		saw_extended_args = 1;
		if (strncasecmp("host=", extra_args, 5) == 0) {
			val = extra_args + 5;
			vallen = strlen(val) + 1;
			if (*val) {
459
				/* Split <host>:<port> at colon. */
460 461 462
				char *host;
				char *port;
				parse_host_and_port(val, &host, &port);
463
				if (port) {
464 465
					free(tcp_port);
					tcp_port = xstrdup(port);
466
				}
467
				free(hostname);
468
				hostname = xstrdup_tolower(host);
469
			}
470

471 472 473
			/* On to the next one */
			extra_args = val + vallen;
		}
474 475
		if (extra_args < end && *extra_args)
			die("Invalid request");
476
	}
477 478 479 480

	/*
	 * Locate canonical hostname and its IP address.
	 */
481
	if (hostname) {
482 483
#ifndef NO_IPV6
		struct addrinfo hints;
B
Benjamin Kramer 已提交
484
		struct addrinfo *ai;
485 486 487 488 489 490
		int gai;
		static char addrbuf[HOST_NAME_MAX + 1];

		memset(&hints, 0, sizeof(hints));
		hints.ai_flags = AI_CANONNAME;

491
		gai = getaddrinfo(hostname, NULL, &hints, &ai);
492
		if (!gai) {
B
Benjamin Kramer 已提交
493 494 495 496 497 498 499 500 501 502 503 504
			struct sockaddr_in *sin_addr = (void *)ai->ai_addr;

			inet_ntop(AF_INET, &sin_addr->sin_addr,
				  addrbuf, sizeof(addrbuf));
			free(ip_address);
			ip_address = xstrdup(addrbuf);

			free(canon_hostname);
			canon_hostname = xstrdup(ai->ai_canonname ?
						 ai->ai_canonname : ip_address);

			freeaddrinfo(ai);
505 506 507 508 509 510 511
		}
#else
		struct hostent *hent;
		struct sockaddr_in sa;
		char **ap;
		static char addrbuf[HOST_NAME_MAX + 1];

512
		hent = gethostbyname(hostname);
513 514 515 516 517 518 519 520 521

		ap = hent->h_addr_list;
		memset(&sa, 0, sizeof sa);
		sa.sin_family = hent->h_addrtype;
		sa.sin_port = htons(0);
		memcpy(&sa.sin_addr, *ap, hent->h_length);

		inet_ntop(hent->h_addrtype, &sa.sin_addr,
			  addrbuf, sizeof(addrbuf));
522

523 524 525 526
		free(canon_hostname);
		canon_hostname = xstrdup(hent->h_name);
		free(ip_address);
		ip_address = xstrdup(addrbuf);
527
#endif
528
	}
529 530 531
}


532
static int execute(void)
533
{
534
	static char line[1000];
535
	int pktlen, len, i;
536
	char *addr = getenv("REMOTE_ADDR"), *port = getenv("REMOTE_PORT");
537

538 539
	if (addr)
		loginfo("Connection from %s:%s", addr, port);
540

541
	alarm(init_timeout ? init_timeout : timeout);
542
	pktlen = packet_read_line(0, line, sizeof(line));
543
	alarm(0);
544

545 546 547 548 549
	len = strlen(line);
	if (pktlen != len)
		loginfo("Extended attributes (%d bytes) exist <%.*s>",
			(int) pktlen - len,
			(int) pktlen - len, line + len + 1);
550
	if (len && line[len-1] == '\n') {
551
		line[--len] = 0;
552 553
		pktlen--;
	}
554

555 556 557 558
	free(hostname);
	free(canon_hostname);
	free(ip_address);
	free(tcp_port);
559
	hostname = canon_hostname = ip_address = tcp_port = NULL;
560

561
	if (len != pktlen)
562
		parse_host_arg(line + len + 1, pktlen - len - 1);
563

564 565 566
	for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
		struct daemon_service *s = &(daemon_service[i]);
		int namelen = strlen(s->name);
567
		if (!prefixcmp(line, "git-") &&
568
		    !strncmp(s->name, line + 4, namelen) &&
569
		    line[namelen + 4] == ' ') {
570 571 572 573
			/*
			 * Note: The directory here is probably context sensitive,
			 * and might depend on the actual service being performed.
			 */
574
			return run_service(line + namelen + 5, s);
575
		}
576
	}
577

P
Petr Baudis 已提交
578
	logerror("Protocol error: '%s'", line);
579 580 581
	return -1;
}

582 583 584
static int addrcmp(const struct sockaddr_storage *s1,
    const struct sockaddr_storage *s2)
{
585 586 587 588 589 590
	const struct sockaddr *sa1 = (const struct sockaddr*) s1;
	const struct sockaddr *sa2 = (const struct sockaddr*) s2;

	if (sa1->sa_family != sa2->sa_family)
		return sa1->sa_family - sa2->sa_family;
	if (sa1->sa_family == AF_INET)
591 592 593 594
		return memcmp(&((struct sockaddr_in *)s1)->sin_addr,
		    &((struct sockaddr_in *)s2)->sin_addr,
		    sizeof(struct in_addr));
#ifndef NO_IPV6
595
	if (sa1->sa_family == AF_INET6)
596 597 598 599 600 601 602
		return memcmp(&((struct sockaddr_in6 *)s1)->sin6_addr,
		    &((struct sockaddr_in6 *)s2)->sin6_addr,
		    sizeof(struct in6_addr));
#endif
	return 0;
}

603
static int max_connections = 32;
604

605
static unsigned int live_children;
606

L
Linus Torvalds 已提交
607
static struct child {
608
	struct child *next;
609
	struct child_process cld;
610
	struct sockaddr_storage address;
611
} *firstborn;
612

E
Erik Faye-Lund 已提交
613
static void add_child(struct child_process *cld, struct sockaddr *addr, socklen_t addrlen)
614
{
J
Junio C Hamano 已提交
615 616 617 618
	struct child *newborn, **cradle;

	newborn = xcalloc(1, sizeof(*newborn));
	live_children++;
619
	memcpy(&newborn->cld, cld, sizeof(*cld));
J
Junio C Hamano 已提交
620 621
	memcpy(&newborn->address, addr, addrlen);
	for (cradle = &firstborn; *cradle; cradle = &(*cradle)->next)
622
		if (!addrcmp(&(*cradle)->address, &newborn->address))
J
Junio C Hamano 已提交
623 624 625
			break;
	newborn->next = *cradle;
	*cradle = newborn;
626 627 628 629 630 631
}

/*
 * This gets called if the number of connections grows
 * past "max_connections".
 *
632
 * We kill the newest connection from a duplicate IP.
633
 */
634
static void kill_some_child(void)
635
{
J
Junio C Hamano 已提交
636
	const struct child *blanket, *next;
637

J
Junio C Hamano 已提交
638 639
	if (!(blanket = firstborn))
		return;
640

J
Junio C Hamano 已提交
641
	for (; (next = blanket->next); blanket = next)
642
		if (!addrcmp(&blanket->address, &next->address)) {
643
			kill(blanket->cld.pid, SIGTERM);
J
Junio C Hamano 已提交
644 645
			break;
		}
646 647
}

648
static void check_dead_children(void)
649
{
650 651
	int status;
	pid_t pid;
652

653 654 655 656 657 658 659 660 661 662 663 664 665 666
	struct child **cradle, *blanket;
	for (cradle = &firstborn; (blanket = *cradle);)
		if ((pid = waitpid(blanket->cld.pid, &status, WNOHANG)) > 1) {
			const char *dead = "";
			if (status)
				dead = " (with error)";
			loginfo("[%"PRIuMAX"] Disconnected%s", (uintmax_t)pid, dead);

			/* remove the child */
			*cradle = blanket->next;
			live_children--;
			free(blanket);
		} else
			cradle = &blanket->next;
667 668
}

669
static char **cld_argv;
E
Erik Faye-Lund 已提交
670
static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen)
671
{
S
Stephen Boyd 已提交
672
	struct child_process cld = { NULL };
673 674
	char addrbuf[300] = "REMOTE_ADDR=", portbuf[300];
	char *env[] = { addrbuf, portbuf, NULL };
675

676 677
	if (max_connections && live_children >= max_connections) {
		kill_some_child();
J
Junio C Hamano 已提交
678
		sleep(1);  /* give it some time to die */
679 680 681 682 683 684 685
		check_dead_children();
		if (live_children >= max_connections) {
			close(incoming);
			logerror("Too many children, dropping connection");
			return;
		}
	}
686

687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708
	if (addr->sa_family == AF_INET) {
		struct sockaddr_in *sin_addr = (void *) addr;
		inet_ntop(addr->sa_family, &sin_addr->sin_addr, addrbuf + 12,
		    sizeof(addrbuf) - 12);
		snprintf(portbuf, sizeof(portbuf), "REMOTE_PORT=%d",
		    ntohs(sin_addr->sin_port));
#ifndef NO_IPV6
	} else if (addr && addr->sa_family == AF_INET6) {
		struct sockaddr_in6 *sin6_addr = (void *) addr;

		char *buf = addrbuf + 12;
		*buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
		inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf,
		    sizeof(addrbuf) - 13);
		strcat(buf, "]");

		snprintf(portbuf, sizeof(portbuf), "REMOTE_PORT=%d",
		    ntohs(sin6_addr->sin6_port));
#endif
	}

	cld.env = (const char **)env;
709 710 711
	cld.argv = (const char **)cld_argv;
	cld.in = incoming;
	cld.out = dup(incoming);
712

713 714 715 716
	if (start_command(&cld))
		logerror("unable to fork");
	else
		add_child(&cld, addr, addrlen);
717 718 719
	close(incoming);
}

720 721
static void child_handler(int signo)
{
J
Junio C Hamano 已提交
722 723
	/*
	 * Otherwise empty handler because systemcalls will get interrupted
724 725 726
	 * upon signal receipt
	 * SysV needs the handler to be rearmed
	 */
727
	signal(SIGCHLD, child_handler);
728 729
}

730 731 732 733 734 735 736 737 738 739
static int set_reuse_addr(int sockfd)
{
	int on = 1;

	if (!reuseaddr)
		return 0;
	return setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
			  &on, sizeof(on));
}

740 741 742 743 744 745
struct socketlist {
	int *list;
	size_t nr;
	size_t alloc;
};

746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768
static const char *ip2str(int family, struct sockaddr *sin, socklen_t len)
{
#ifdef NO_IPV6
	static char ip[INET_ADDRSTRLEN];
#else
	static char ip[INET6_ADDRSTRLEN];
#endif

	switch (family) {
#ifndef NO_IPV6
	case AF_INET6:
		inet_ntop(family, &((struct sockaddr_in6*)sin)->sin6_addr, ip, len);
		break;
#endif
	case AF_INET:
		inet_ntop(family, &((struct sockaddr_in*)sin)->sin_addr, ip, len);
		break;
	default:
		strcpy(ip, "<unknown>");
	}
	return ip;
}

P
Peter Anvin 已提交
769 770
#ifndef NO_IPV6

771
static int setup_named_sock(char *listen_addr, int listen_port, struct socketlist *socklist)
772
{
773
	int socknum = 0;
774 775
	int maxfd = -1;
	char pbuf[NI_MAXSERV];
P
Peter Anvin 已提交
776 777
	struct addrinfo hints, *ai0, *ai;
	int gai;
778
	long flags;
779

780
	sprintf(pbuf, "%d", listen_port);
781 782 783 784 785 786
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	hints.ai_flags = AI_PASSIVE;

787
	gai = getaddrinfo(listen_addr, pbuf, &hints, &ai0);
788 789 790 791
	if (gai) {
		logerror("getaddrinfo() for %s failed: %s", listen_addr, gai_strerror(gai));
		return 0;
	}
792 793 794 795 796 797 798 799

	for (ai = ai0; ai; ai = ai->ai_next) {
		int sockfd;

		sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
		if (sockfd < 0)
			continue;
		if (sockfd >= FD_SETSIZE) {
800
			logerror("Socket descriptor too large");
801 802 803 804 805 806 807 808 809 810 811 812 813
			close(sockfd);
			continue;
		}

#ifdef IPV6_V6ONLY
		if (ai->ai_family == AF_INET6) {
			int on = 1;
			setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
				   &on, sizeof(on));
			/* Note: error is not fatal */
		}
#endif

814
		if (set_reuse_addr(sockfd)) {
815
			logerror("Could not set SO_REUSEADDR: %s", strerror(errno));
816
			close(sockfd);
817
			continue;
818 819
		}

820
		if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) {
821 822 823
			logerror("Could not bind to %s: %s",
				 ip2str(ai->ai_family, ai->ai_addr, ai->ai_addrlen),
				 strerror(errno));
824 825 826 827
			close(sockfd);
			continue;	/* not fatal */
		}
		if (listen(sockfd, 5) < 0) {
828 829 830
			logerror("Could not listen to %s: %s",
				 ip2str(ai->ai_family, ai->ai_addr, ai->ai_addrlen),
				 strerror(errno));
831 832 833 834
			close(sockfd);
			continue;	/* not fatal */
		}

835 836 837 838
		flags = fcntl(sockfd, F_GETFD, 0);
		if (flags >= 0)
			fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);

839 840 841
		ALLOC_GROW(socklist->list, socklist->nr + 1, socklist->alloc);
		socklist->list[socklist->nr++] = sockfd;
		socknum++;
842 843 844 845 846 847 848

		if (maxfd < sockfd)
			maxfd = sockfd;
	}

	freeaddrinfo(ai0);

P
Peter Anvin 已提交
849 850 851 852 853
	return socknum;
}

#else /* NO_IPV6 */

854
static int setup_named_sock(char *listen_addr, int listen_port, struct socketlist *socklist)
P
Peter Anvin 已提交
855 856 857
{
	struct sockaddr_in sin;
	int sockfd;
858
	long flags;
P
Peter Anvin 已提交
859

860 861 862 863 864 865 866 867 868 869 870 871
	memset(&sin, 0, sizeof sin);
	sin.sin_family = AF_INET;
	sin.sin_port = htons(listen_port);

	if (listen_addr) {
		/* Well, host better be an IP address here. */
		if (inet_pton(AF_INET, listen_addr, &sin.sin_addr.s_addr) <= 0)
			return 0;
	} else {
		sin.sin_addr.s_addr = htonl(INADDR_ANY);
	}

P
Peter Anvin 已提交
872 873 874 875
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd < 0)
		return 0;

876
	if (set_reuse_addr(sockfd)) {
877
		logerror("Could not set SO_REUSEADDR: %s", strerror(errno));
878 879 880 881
		close(sockfd);
		return 0;
	}

P
Peter Anvin 已提交
882
	if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) {
883 884 885
		logerror("Could not listen to %s: %s",
			 ip2str(AF_INET, (struct sockaddr *)&sin, sizeof(sin)),
			 strerror(errno));
P
Peter Anvin 已提交
886 887 888
		close(sockfd);
		return 0;
	}
889

890
	if (listen(sockfd, 5) < 0) {
891 892 893
		logerror("Could not listen to %s: %s",
			 ip2str(AF_INET, (struct sockaddr *)&sin, sizeof(sin)),
			 strerror(errno));
894 895 896 897
		close(sockfd);
		return 0;
	}

898 899 900 901
	flags = fcntl(sockfd, F_GETFD, 0);
	if (flags >= 0)
		fcntl(sockfd, F_SETFD, flags | FD_CLOEXEC);

902 903
	ALLOC_GROW(socklist->list, socklist->nr + 1, socklist->alloc);
	socklist->list[socklist->nr++] = sockfd;
904
	return 1;
P
Peter Anvin 已提交
905 906 907 908
}

#endif

909
static void socksetup(struct string_list *listen_addr, int listen_port, struct socketlist *socklist)
910
{
911 912 913 914 915 916 917 918 919 920 921 922 923
	if (!listen_addr->nr)
		setup_named_sock(NULL, listen_port, socklist);
	else {
		int i, socknum;
		for (i = 0; i < listen_addr->nr; i++) {
			socknum = setup_named_sock(listen_addr->items[i].string,
						   listen_port, socklist);

			if (socknum == 0)
				logerror("unable to allocate any listen sockets for host %s on port %u",
					 listen_addr->items[i].string, listen_port);
		}
	}
924 925 926
}

static int service_loop(struct socketlist *socklist)
P
Peter Anvin 已提交
927 928 929 930
{
	struct pollfd *pfd;
	int i;

931
	pfd = xcalloc(socklist->nr, sizeof(struct pollfd));
P
Peter Anvin 已提交
932

933 934
	for (i = 0; i < socklist->nr; i++) {
		pfd[i].fd = socklist->list[i];
P
Peter Anvin 已提交
935 936
		pfd[i].events = POLLIN;
	}
937 938

	signal(SIGCHLD, child_handler);
939 940

	for (;;) {
941
		int i;
P
Peter Anvin 已提交
942

943 944
		check_dead_children();

945
		if (poll(pfd, socklist->nr, -1) < 0) {
946
			if (errno != EINTR) {
947
				logerror("Poll failed, resuming: %s",
948 949 950
				      strerror(errno));
				sleep(1);
			}
951 952 953
			continue;
		}

954
		for (i = 0; i < socklist->nr; i++) {
P
Peter Anvin 已提交
955
			if (pfd[i].revents & POLLIN) {
956 957 958 959 960 961 962
				union {
					struct sockaddr sa;
					struct sockaddr_in sai;
#ifndef NO_IPV6
					struct sockaddr_in6 sai6;
#endif
				} ss;
E
Erik Faye-Lund 已提交
963
				socklen_t sslen = sizeof(ss);
964
				int incoming = accept(pfd[i].fd, &ss.sa, &sslen);
965 966 967 968 969 970 971
				if (incoming < 0) {
					switch (errno) {
					case EAGAIN:
					case EINTR:
					case ECONNABORTED:
						continue;
					default:
972
						die_errno("accept returned");
973 974
					}
				}
975
				handle(incoming, &ss.sa, sslen);
976 977 978 979 980
			}
		}
	}
}

981 982 983 984 985 986 987
/* if any standard file descriptor is missing open it to /dev/null */
static void sanitize_stdfds(void)
{
	int fd = open("/dev/null", O_RDWR, 0);
	while (fd != -1 && fd < 2)
		fd = dup(fd);
	if (fd == -1)
988
		die_errno("open /dev/null or dup failed");
989 990 991 992
	if (fd > 2)
		close(fd);
}

993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048
#ifdef NO_POSIX_GOODIES

struct credentials;

static void drop_privileges(struct credentials *cred)
{
	/* nothing */
}

static void daemonize(void)
{
	die("--detach not supported on this platform");
}

static struct credentials *prepare_credentials(const char *user_name,
    const char *group_name)
{
	die("--user not supported on this platform");
}

#else

struct credentials {
	struct passwd *pass;
	gid_t gid;
};

static void drop_privileges(struct credentials *cred)
{
	if (cred && (initgroups(cred->pass->pw_name, cred->gid) ||
	    setgid (cred->gid) || setuid(cred->pass->pw_uid)))
		die("cannot drop privileges");
}

static struct credentials *prepare_credentials(const char *user_name,
    const char *group_name)
{
	static struct credentials c;

	c.pass = getpwnam(user_name);
	if (!c.pass)
		die("user not found - %s", user_name);

	if (!group_name)
		c.gid = c.pass->pw_gid;
	else {
		struct group *group = getgrnam(group_name);
		if (!group)
			die("group not found - %s", group_name);

		c.gid = group->gr_gid;
	}

	return &c;
}

1049 1050 1051 1052 1053 1054
static void daemonize(void)
{
	switch (fork()) {
		case 0:
			break;
		case -1:
1055
			die_errno("fork failed");
1056 1057 1058 1059
		default:
			exit(0);
	}
	if (setsid() == -1)
1060
		die_errno("setsid failed");
1061 1062 1063 1064 1065
	close(0);
	close(1);
	close(2);
	sanitize_stdfds();
}
1066
#endif
1067

1068 1069 1070 1071
static void store_pid(const char *path)
{
	FILE *f = fopen(path, "w");
	if (!f)
1072
		die_errno("cannot open pid file '%s'", path);
1073
	if (fprintf(f, "%"PRIuMAX"\n", (uintmax_t) getpid()) < 0 || fclose(f) != 0)
1074
		die_errno("failed to write pid file '%s'", path);
1075 1076
}

1077 1078
static int serve(struct string_list *listen_addr, int listen_port,
    struct credentials *cred)
P
Peter Anvin 已提交
1079
{
1080
	struct socketlist socklist = { NULL, 0, 0 };
J
Junio C Hamano 已提交
1081

1082 1083
	socksetup(listen_addr, listen_port, &socklist);
	if (socklist.nr == 0)
1084 1085
		die("unable to allocate any listen sockets on port %u",
		    listen_port);
J
Junio C Hamano 已提交
1086

1087
	drop_privileges(cred);
1088

1089 1090
	loginfo("Ready to rumble");

1091
	return service_loop(&socklist);
J
Junio C Hamano 已提交
1092
}
P
Peter Anvin 已提交
1093

1094 1095
int main(int argc, char **argv)
{
1096
	int listen_port = 0;
1097
	struct string_list listen_addr = STRING_LIST_INIT_NODUP;
1098
	int serve_mode = 0, inetd_mode = 0;
1099
	const char *pid_file = NULL, *user_name = NULL, *group_name = NULL;
1100
	int detach = 0;
1101
	struct credentials *cred = NULL;
1102 1103
	int i;

1104 1105
	git_setup_gettext();

1106 1107
	git_extract_argv0_path(argv[0]);

1108 1109 1110
	for (i = 1; i < argc; i++) {
		char *arg = argv[i];

1111
		if (!prefixcmp(arg, "--listen=")) {
1112
			string_list_append(&listen_addr, xstrdup_tolower(arg + 9));
1113
			continue;
1114
		}
1115
		if (!prefixcmp(arg, "--port=")) {
1116 1117 1118 1119
			char *end;
			unsigned long n;
			n = strtoul(arg+7, &end, 0);
			if (arg[7] && !*end) {
1120
				listen_port = n;
1121 1122 1123
				continue;
			}
		}
1124 1125 1126 1127
		if (!strcmp(arg, "--serve")) {
			serve_mode = 1;
			continue;
		}
1128 1129
		if (!strcmp(arg, "--inetd")) {
			inetd_mode = 1;
A
Andreas Ericsson 已提交
1130
			log_syslog = 1;
1131 1132
			continue;
		}
P
Petr Baudis 已提交
1133 1134 1135 1136
		if (!strcmp(arg, "--verbose")) {
			verbose = 1;
			continue;
		}
1137 1138 1139 1140
		if (!strcmp(arg, "--syslog")) {
			log_syslog = 1;
			continue;
		}
1141 1142 1143 1144
		if (!strcmp(arg, "--export-all")) {
			export_all_trees = 1;
			continue;
		}
1145
		if (!prefixcmp(arg, "--timeout=")) {
1146
			timeout = atoi(arg+10);
A
Andreas Ericsson 已提交
1147
			continue;
1148
		}
1149
		if (!prefixcmp(arg, "--init-timeout=")) {
1150
			init_timeout = atoi(arg+15);
A
Andreas Ericsson 已提交
1151
			continue;
1152
		}
1153 1154 1155 1156 1157 1158
		if (!prefixcmp(arg, "--max-connections=")) {
			max_connections = atoi(arg+18);
			if (max_connections < 0)
				max_connections = 0;	        /* unlimited */
			continue;
		}
1159 1160 1161 1162
		if (!strcmp(arg, "--strict-paths")) {
			strict_paths = 1;
			continue;
		}
1163
		if (!prefixcmp(arg, "--base-path=")) {
P
Petr Baudis 已提交
1164 1165 1166
			base_path = arg+12;
			continue;
		}
J
Jens Axboe 已提交
1167 1168 1169 1170
		if (!strcmp(arg, "--base-path-relaxed")) {
			base_path_relaxed = 1;
			continue;
		}
1171
		if (!prefixcmp(arg, "--interpolated-path=")) {
1172 1173 1174
			interpolated_path = arg+20;
			continue;
		}
1175 1176 1177 1178
		if (!strcmp(arg, "--reuseaddr")) {
			reuseaddr = 1;
			continue;
		}
1179 1180 1181 1182
		if (!strcmp(arg, "--user-path")) {
			user_path = "";
			continue;
		}
1183
		if (!prefixcmp(arg, "--user-path=")) {
1184 1185 1186
			user_path = arg + 12;
			continue;
		}
1187
		if (!prefixcmp(arg, "--pid-file=")) {
1188 1189 1190
			pid_file = arg + 11;
			continue;
		}
1191 1192 1193 1194 1195
		if (!strcmp(arg, "--detach")) {
			detach = 1;
			log_syslog = 1;
			continue;
		}
1196
		if (!prefixcmp(arg, "--user=")) {
1197 1198 1199
			user_name = arg + 7;
			continue;
		}
1200
		if (!prefixcmp(arg, "--group=")) {
1201 1202 1203
			group_name = arg + 8;
			continue;
		}
1204
		if (!prefixcmp(arg, "--enable=")) {
1205 1206 1207
			enable_service(arg + 9, 1);
			continue;
		}
1208
		if (!prefixcmp(arg, "--disable=")) {
1209 1210 1211
			enable_service(arg + 10, 0);
			continue;
		}
1212
		if (!prefixcmp(arg, "--allow-override=")) {
J
Junio C Hamano 已提交
1213
			make_service_overridable(arg + 17, 1);
1214 1215
			continue;
		}
1216
		if (!prefixcmp(arg, "--forbid-override=")) {
J
Junio C Hamano 已提交
1217
			make_service_overridable(arg + 18, 0);
1218 1219
			continue;
		}
1220 1221 1222 1223 1224 1225 1226 1227
		if (!prefixcmp(arg, "--informative-errors")) {
			informative_errors = 1;
			continue;
		}
		if (!prefixcmp(arg, "--no-informative-errors")) {
			informative_errors = 0;
			continue;
		}
1228 1229 1230 1231 1232 1233 1234
		if (!strcmp(arg, "--")) {
			ok_paths = &argv[i+1];
			break;
		} else if (arg[0] != '-') {
			ok_paths = &argv[i];
			break;
		}
1235

1236 1237 1238
		usage(daemon_usage);
	}

1239
	if (log_syslog) {
1240
		openlog("git-daemon", LOG_PID, LOG_DAEMON);
1241
		set_die_routine(daemon_die);
J
Junio C Hamano 已提交
1242
	} else
J
Junio C Hamano 已提交
1243
		/* avoid splitting a message in the middle */
1244
		setvbuf(stderr, NULL, _IOFBF, 4096);
1245

1246 1247
	if (inetd_mode && (detach || group_name || user_name))
		die("--detach, --user and --group are incompatible with --inetd");
1248

1249
	if (inetd_mode && (listen_port || (listen_addr.nr > 0)))
1250 1251 1252 1253
		die("--listen= and --port= are incompatible with --inetd");
	else if (listen_port == 0)
		listen_port = DEFAULT_GIT_PORT;

1254 1255 1256
	if (group_name && !user_name)
		die("--group supplied without --user");

1257 1258
	if (user_name)
		cred = prepare_credentials(user_name, group_name);
1259

1260 1261 1262
	if (strict_paths && (!ok_paths || !*ok_paths))
		die("option --strict-paths requires a whitelist");

1263 1264 1265
	if (base_path && !is_directory(base_path))
		die("base-path '%s' does not exist or is not a directory",
		    base_path);
1266

1267
	if (inetd_mode) {
1268 1269 1270 1271
		if (!freopen("/dev/null", "w", stderr))
			die_errno("failed to redirect stderr to /dev/null");
	}

1272 1273
	if (inetd_mode || serve_mode)
		return execute();
1274

1275
	if (detach)
1276 1277 1278
		daemonize();
	else
		sanitize_stdfds();
1279

1280 1281 1282
	if (pid_file)
		store_pid(pid_file);

1283 1284
	/* prepare argv for serving-processes */
	cld_argv = xmalloc(sizeof (char *) * (argc + 2));
1285 1286 1287 1288
	cld_argv[0] = argv[0];	/* git-daemon */
	cld_argv[1] = "--serve";
	for (i = 1; i < argc; ++i)
		cld_argv[i+1] = argv[i];
1289 1290
	cld_argv[argc+1] = NULL;

1291
	return serve(&listen_addr, listen_port, cred);
1292
}