connect.c 32 KB
Newer Older
Jason Riedy's avatar
Jason Riedy committed
1
#include "git-compat-util.h"
2
#include "cache.h"
3
#include "config.h"
4
#include "pkt-line.h"
5
#include "quote.h"
6
#include "refs.h"
7
#include "run-command.h"
8
#include "remote.h"
9
#include "connect.h"
10
#include "url.h"
11
#include "string-list.h"
12
#include "sha1-array.h"
13
#include "transport.h"
14
#include "strbuf.h"
15
#include "version.h"
16
#include "protocol.h"
17
#include "alias.h"
18

19 20
static char *server_capabilities_v1;
static struct argv_array server_capabilities_v2 = ARGV_ARRAY_INIT;
21
static const char *parse_feature_value(const char *, const char *, int *);
22

23
static int check_ref(const char *name, unsigned int flags)
Linus Torvalds's avatar
Linus Torvalds committed
24 25 26 27
{
	if (!flags)
		return 1;

28
	if (!skip_prefix(name, "refs/", &name))
Linus Torvalds's avatar
Linus Torvalds committed
29 30 31
		return 0;

	/* REF_NORMAL means that we don't want the magic fake tag refs */
32
	if ((flags & REF_NORMAL) && check_refname_format(name, 0))
Linus Torvalds's avatar
Linus Torvalds committed
33 34 35
		return 0;

	/* REF_HEADS means that we want regular branch heads */
36
	if ((flags & REF_HEADS) && starts_with(name, "heads/"))
Linus Torvalds's avatar
Linus Torvalds committed
37 38 39
		return 1;

	/* REF_TAGS means that we want tags */
40
	if ((flags & REF_TAGS) && starts_with(name, "tags/"))
Linus Torvalds's avatar
Linus Torvalds committed
41 42 43 44 45 46
		return 1;

	/* All type bits clear means that we are ok with anything */
	return !(flags & ~REF_NORMAL);
}

47 48
int check_ref_type(const struct ref *ref, int flags)
{
49
	return check_ref(ref->name, flags);
50 51
}

52
static NORETURN void die_initial_contact(int unexpected)
53
{
54 55 56 57 58 59
	/*
	 * A hang-up after seeing some response from the other end
	 * means that it is unexpected, as we know the other end is
	 * willing to talk to us.  A hang-up before seeing any
	 * response does not necessarily mean an ACL problem, though.
	 */
60
	if (unexpected)
61
		die(_("the remote end hung up upon initial contact"));
62
	else
63 64 65
		die(_("Could not read from remote repository.\n\n"
		      "Please make sure you have the correct access rights\n"
		      "and the repository exists."));
66 67
}

68 69 70 71 72 73 74 75 76 77 78 79 80
/* Checks if the server supports the capability 'c' */
int server_supports_v2(const char *c, int die_on_error)
{
	int i;

	for (i = 0; i < server_capabilities_v2.argc; i++) {
		const char *out;
		if (skip_prefix(server_capabilities_v2.argv[i], c, &out) &&
		    (!*out || *out == '='))
			return 1;
	}

	if (die_on_error)
81
		die(_("server doesn't support '%s'"), c);
82 83 84 85

	return 0;
}

86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
int server_supports_feature(const char *c, const char *feature,
			    int die_on_error)
{
	int i;

	for (i = 0; i < server_capabilities_v2.argc; i++) {
		const char *out;
		if (skip_prefix(server_capabilities_v2.argv[i], c, &out) &&
		    (!*out || *(out++) == '=')) {
			if (parse_feature_request(out, feature))
				return 1;
			else
				break;
		}
	}

	if (die_on_error)
103
		die(_("server doesn't support feature '%s'"), feature);
104 105 106 107

	return 0;
}

108 109 110 111 112 113
static void process_capabilities_v2(struct packet_reader *reader)
{
	while (packet_reader_read(reader) == PACKET_READ_NORMAL)
		argv_array_push(&server_capabilities_v2, reader->line);

	if (reader->status != PACKET_READ_FLUSH)
114
		die(_("expected flush after capabilities"));
115 116
}

117
enum protocol_version discover_version(struct packet_reader *reader)
118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
{
	enum protocol_version version = protocol_unknown_version;

	/*
	 * Peek the first line of the server's response to
	 * determine the protocol version the server is speaking.
	 */
	switch (packet_reader_peek(reader)) {
	case PACKET_READ_EOF:
		die_initial_contact(0);
	case PACKET_READ_FLUSH:
	case PACKET_READ_DELIM:
		version = protocol_v0;
		break;
	case PACKET_READ_NORMAL:
		version = determine_protocol_version_client(reader->line);
		break;
	}

	switch (version) {
138
	case protocol_v2:
139
		process_capabilities_v2(reader);
140
		break;
141 142 143 144 145 146 147 148 149 150 151 152 153
	case protocol_v1:
		/* Read the peeked version line */
		packet_reader_read(reader);
		break;
	case protocol_v0:
		break;
	case protocol_unknown_version:
		BUG("unknown protocol version");
	}

	return version;
}

154 155 156 157 158 159 160 161
static void parse_one_symref_info(struct string_list *symref, const char *val, int len)
{
	char *sym, *target;
	struct string_list_item *item;

	if (!len)
		return; /* just "symref" */
	/* e.g. "symref=HEAD:refs/heads/master" */
162
	sym = xmemdupz(val, len);
163 164 165 166 167 168 169 170 171
	target = strchr(sym, ':');
	if (!target)
		/* just "symref=something" */
		goto reject;
	*(target++) = '\0';
	if (check_refname_format(sym, REFNAME_ALLOW_ONELEVEL) ||
	    check_refname_format(target, REFNAME_ALLOW_ONELEVEL))
		/* "symref=bogus:pair */
		goto reject;
172
	item = string_list_append_nodup(symref, sym);
173 174 175 176 177 178 179 180 181 182
	item->util = target;
	return;
reject:
	free(sym);
	return;
}

static void annotate_refs_with_symref_info(struct ref *ref)
{
	struct string_list symref = STRING_LIST_INIT_DUP;
183
	const char *feature_list = server_capabilities_v1;
184 185 186 187 188 189 190 191 192 193 194

	while (feature_list) {
		int len;
		const char *val;

		val = parse_feature_value(feature_list, "symref", &len);
		if (!val)
			break;
		parse_one_symref_info(&symref, val, len);
		feature_list = val + 1;
	}
195
	string_list_sort(&symref);
196 197 198 199 200 201 202 203 204 205 206

	for (; ref; ref = ref->next) {
		struct string_list_item *item;
		item = string_list_lookup(&symref, ref->name);
		if (!item)
			continue;
		ref->symref = xstrdup((char *)item->util);
	}
	string_list_clear(&symref, 0);
}

207
static void process_capabilities(const char *line, int *len)
208
{
209
	int nul_location = strlen(line);
210 211
	if (nul_location == *len)
		return;
212
	server_capabilities_v1 = xstrdup(line + nul_location + 1);
213 214 215
	*len = nul_location;
}

216
static int process_dummy_ref(const char *line)
217 218 219 220
{
	struct object_id oid;
	const char *name;

221
	if (parse_oid_hex(line, &oid, &name))
222 223 224 225 226
		return 0;
	if (*name != ' ')
		return 0;
	name++;

227
	return oideq(&null_oid, &oid) && !strcmp(name, "capabilities^{}");
228 229
}

230
static void check_no_capabilities(const char *line, int len)
231
{
232
	if (strlen(line) != len)
233
		warning(_("ignoring capabilities after first line '%s'"),
234
			line + strlen(line));
235 236
}

237 238
static int process_ref(const char *line, int len, struct ref ***list,
		       unsigned int flags, struct oid_array *extra_have)
239 240 241 242
{
	struct object_id old_oid;
	const char *name;

243
	if (parse_oid_hex(line, &old_oid, &name))
244 245 246 247 248 249 250 251
		return 0;
	if (*name != ' ')
		return 0;
	name++;

	if (extra_have && !strcmp(name, ".have")) {
		oid_array_append(extra_have, &old_oid);
	} else if (!strcmp(name, "capabilities^{}")) {
252
		die(_("protocol error: unexpected capabilities^{}"));
253 254 255 256 257 258
	} else if (check_ref(name, flags)) {
		struct ref *ref = alloc_ref(name);
		oidcpy(&ref->old_oid, &old_oid);
		**list = ref;
		*list = &ref->next;
	}
259
	check_no_capabilities(line, len);
260 261 262
	return 1;
}

263 264
static int process_shallow(const char *line, int len,
			   struct oid_array *shallow_points)
265 266 267 268
{
	const char *arg;
	struct object_id old_oid;

269
	if (!skip_prefix(line, "shallow ", &arg))
270 271 272
		return 0;

	if (get_oid_hex(arg, &old_oid))
273
		die(_("protocol error: expected shallow sha-1, got '%s'"), arg);
274
	if (!shallow_points)
275
		die(_("repository on the other end cannot be shallow"));
276
	oid_array_append(shallow_points, &old_oid);
277
	check_no_capabilities(line, len);
278 279 280
	return 1;
}

281 282 283 284 285 286 287
enum get_remote_heads_state {
	EXPECTING_FIRST_REF = 0,
	EXPECTING_REF,
	EXPECTING_SHALLOW,
	EXPECTING_DONE,
};

288 289 290
/*
 * Read all the refs from the other end
 */
291
struct ref **get_remote_heads(struct packet_reader *reader,
292
			      struct ref **list, unsigned int flags,
293 294
			      struct oid_array *extra_have,
			      struct oid_array *shallow_points)
295
{
296
	struct ref **orig_list = list;
297 298
	int len = 0;
	enum get_remote_heads_state state = EXPECTING_FIRST_REF;
299

300
	*list = NULL;
301

302
	while (state != EXPECTING_DONE) {
303
		switch (packet_reader_read(reader)) {
304 305 306
		case PACKET_READ_EOF:
			die_initial_contact(1);
		case PACKET_READ_NORMAL:
307
			len = reader->pktlen;
308 309 310 311 312
			break;
		case PACKET_READ_FLUSH:
			state = EXPECTING_DONE;
			break;
		case PACKET_READ_DELIM:
313
			die(_("invalid packet"));
314 315
		}

316 317
		switch (state) {
		case EXPECTING_FIRST_REF:
318 319
			process_capabilities(reader->line, &len);
			if (process_dummy_ref(reader->line)) {
320 321 322 323 324 325
				state = EXPECTING_SHALLOW;
				break;
			}
			state = EXPECTING_REF;
			/* fallthrough */
		case EXPECTING_REF:
326
			if (process_ref(reader->line, len, &list, flags, extra_have))
327 328 329 330
				break;
			state = EXPECTING_SHALLOW;
			/* fallthrough */
		case EXPECTING_SHALLOW:
331
			if (process_shallow(reader->line, len, shallow_points))
332
				break;
333
			die(_("protocol error: unexpected '%s'"), reader->line);
334 335
		case EXPECTING_DONE:
			break;
336
		}
337
	}
338 339 340

	annotate_refs_with_symref_info(*orig_list);

341 342 343
	return list;
}

344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408
/* Returns 1 when a valid ref has been added to `list`, 0 otherwise */
static int process_ref_v2(const char *line, struct ref ***list)
{
	int ret = 1;
	int i = 0;
	struct object_id old_oid;
	struct ref *ref;
	struct string_list line_sections = STRING_LIST_INIT_DUP;
	const char *end;

	/*
	 * Ref lines have a number of fields which are space deliminated.  The
	 * first field is the OID of the ref.  The second field is the ref
	 * name.  Subsequent fields (symref-target and peeled) are optional and
	 * don't have a particular order.
	 */
	if (string_list_split(&line_sections, line, ' ', -1) < 2) {
		ret = 0;
		goto out;
	}

	if (parse_oid_hex(line_sections.items[i++].string, &old_oid, &end) ||
	    *end) {
		ret = 0;
		goto out;
	}

	ref = alloc_ref(line_sections.items[i++].string);

	oidcpy(&ref->old_oid, &old_oid);
	**list = ref;
	*list = &ref->next;

	for (; i < line_sections.nr; i++) {
		const char *arg = line_sections.items[i].string;
		if (skip_prefix(arg, "symref-target:", &arg))
			ref->symref = xstrdup(arg);

		if (skip_prefix(arg, "peeled:", &arg)) {
			struct object_id peeled_oid;
			char *peeled_name;
			struct ref *peeled;
			if (parse_oid_hex(arg, &peeled_oid, &end) || *end) {
				ret = 0;
				goto out;
			}

			peeled_name = xstrfmt("%s^{}", ref->name);
			peeled = alloc_ref(peeled_name);

			oidcpy(&peeled->old_oid, &peeled_oid);
			**list = peeled;
			*list = &peeled->next;

			free(peeled_name);
		}
	}

out:
	string_list_clear(&line_sections, 0);
	return ret;
}

struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
			     struct ref **list, int for_push,
409 410
			     const struct argv_array *ref_prefixes,
			     const struct string_list *server_options)
411 412 413 414 415 416 417 418 419 420
{
	int i;
	*list = NULL;

	if (server_supports_v2("ls-refs", 1))
		packet_write_fmt(fd_out, "command=ls-refs\n");

	if (server_supports_v2("agent", 0))
		packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized());

421 422 423 424 425 426
	if (server_options && server_options->nr &&
	    server_supports_v2("server-option", 1))
		for (i = 0; i < server_options->nr; i++)
			packet_write_fmt(fd_out, "server-option=%s",
					 server_options->items[i].string);

427 428 429 430 431 432 433 434 435 436 437 438 439 440
	packet_delim(fd_out);
	/* When pushing we don't want to request the peeled tags */
	if (!for_push)
		packet_write_fmt(fd_out, "peel\n");
	packet_write_fmt(fd_out, "symrefs\n");
	for (i = 0; ref_prefixes && i < ref_prefixes->argc; i++) {
		packet_write_fmt(fd_out, "ref-prefix %s\n",
				 ref_prefixes->argv[i]);
	}
	packet_flush(fd_out);

	/* Process response from server */
	while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
		if (!process_ref_v2(reader->line, &list))
441
			die(_("invalid ls-refs response: %s"), reader->line);
442 443 444
	}

	if (reader->status != PACKET_READ_FLUSH)
445
		die(_("expected flush after ref listing"));
446 447 448 449

	return list;
}

450
static const char *parse_feature_value(const char *feature_list, const char *feature, int *lenp)
451 452 453 454 455 456 457 458 459 460 461
{
	int len;

	if (!feature_list)
		return NULL;

	len = strlen(feature);
	while (*feature_list) {
		const char *found = strstr(feature_list, feature);
		if (!found)
			return NULL;
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
		if (feature_list == found || isspace(found[-1])) {
			const char *value = found + len;
			/* feature with no value (e.g., "thin-pack") */
			if (!*value || isspace(*value)) {
				if (lenp)
					*lenp = 0;
				return value;
			}
			/* feature with a value (e.g., "agent=git/1.2.3") */
			else if (*value == '=') {
				value++;
				if (lenp)
					*lenp = strcspn(value, " \t\n");
				return value;
			}
			/*
			 * otherwise we matched a substring of another feature;
			 * keep looking
			 */
		}
482 483 484
		feature_list = found + 1;
	}
	return NULL;
485 486
}

487 488 489 490 491 492 493
int parse_feature_request(const char *feature_list, const char *feature)
{
	return !!parse_feature_value(feature_list, feature, NULL);
}

const char *server_feature_value(const char *feature, int *len)
{
494
	return parse_feature_value(server_capabilities_v1, feature, len);
495 496 497 498 499 500 501
}

int server_supports(const char *feature)
{
	return !!server_feature_value(feature, NULL);
}

502 503
enum protocol {
	PROTO_LOCAL = 1,
504
	PROTO_FILE,
505
	PROTO_SSH,
506
	PROTO_GIT
507 508
};

509 510 511 512 513 514 515 516
int url_is_local_not_ssh(const char *url)
{
	const char *colon = strchr(url, ':');
	const char *slash = strchr(url, '/');
	return !colon || (slash && slash < colon) ||
		has_dos_drive_prefix(url);
}

517 518 519 520
static const char *prot_name(enum protocol protocol)
{
	switch (protocol) {
		case PROTO_LOCAL:
521
		case PROTO_FILE:
522 523 524 525 526 527
			return "file";
		case PROTO_SSH:
			return "ssh";
		case PROTO_GIT:
			return "git";
		default:
528
			return "unknown protocol";
529 530 531
	}
}

532 533 534 535 536 537
static enum protocol get_protocol(const char *name)
{
	if (!strcmp(name, "ssh"))
		return PROTO_SSH;
	if (!strcmp(name, "git"))
		return PROTO_GIT;
Carlos's avatar
Carlos committed
538
	if (!strcmp(name, "git+ssh")) /* deprecated - do not use */
539
		return PROTO_SSH;
Carlos's avatar
Carlos committed
540
	if (!strcmp(name, "ssh+git")) /* deprecated - do not use */
541
		return PROTO_SSH;
542
	if (!strcmp(name, "file"))
543
		return PROTO_FILE;
544
	die(_("protocol '%s' is not supported"), name);
545 546
}

547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570
static char *host_end(char **hoststart, int removebrackets)
{
	char *host = *hoststart;
	char *end;
	char *start = strstr(host, "@[");
	if (start)
		start++; /* Jump over '@' */
	else
		start = host;
	if (start[0] == '[') {
		end = strchr(start + 1, ']');
		if (end) {
			if (removebrackets) {
				*end = 0;
				memmove(start, start + 1, end - start);
				end++;
			}
		} else
			end = host;
	} else
		end = host;
	return end;
}

571 572
#define STR_(s)	# s
#define STR(s)	STR_(s)
573

574 575 576
static void get_host_and_port(char **host, const char **port)
{
	char *colon, *end;
577
	end = host_end(host, 1);
578 579
	colon = strchr(end, ':');
	if (colon) {
580 581 582 583
		long portnr = strtol(colon + 1, &end, 10);
		if (end != colon + 1 && *end == '\0' && 0 <= portnr && portnr < 65536) {
			*colon = 0;
			*port = colon + 1;
584 585
		} else if (!colon[1]) {
			*colon = 0;
586
		}
587 588 589
	}
}

590 591 592 593 594
static void enable_keepalive(int sockfd)
{
	int ka = 1;

	if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &ka, sizeof(ka)) < 0)
595
		error_errno(_("unable to set SO_KEEPALIVE on socket"));
596 597
}

598
#ifndef NO_IPV6
599

600 601
static const char *ai_name(const struct addrinfo *ai)
{
602 603 604
	static char addr[NI_MAXHOST];
	if (getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, sizeof(addr), NULL, 0,
			NI_NUMERICHOST) != 0)
605
		xsnprintf(addr, sizeof(addr), "(unknown)");
606

607 608 609
	return addr;
}

610 611 612
/*
 * Returns a connected socket() fd, or else die()s.
 */
613
static int git_tcp_connect_sock(char *host, int flags)
614
{
615 616
	struct strbuf error_message = STRBUF_INIT;
	int sockfd = -1;
Timo Hirvonen's avatar
Timo Hirvonen committed
617
	const char *port = STR(DEFAULT_GIT_PORT);
618 619
	struct addrinfo hints, *ai0, *ai;
	int gai;
620
	int cnt = 0;
621

622 623 624
	get_host_and_port(&host, &port);
	if (!*port)
		port = "<none>";
625 626

	memset(&hints, 0, sizeof(hints));
627 628 629 630
	if (flags & CONNECT_IPV4)
		hints.ai_family = AF_INET;
	else if (flags & CONNECT_IPV6)
		hints.ai_family = AF_INET6;
631 632 633
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

634
	if (flags & CONNECT_VERBOSE)
635
		fprintf(stderr, _("Looking up %s ... "), host);
636

637 638
	gai = getaddrinfo(host, port, &hints, &ai);
	if (gai)
639
		die(_("unable to look up %s (port %s) (%s)"), host, port, gai_strerror(gai));
640

641
	if (flags & CONNECT_VERBOSE)
642 643
		/* TRANSLATORS: this is the end of "Looking up %s ... " */
		fprintf(stderr, _("done.\nConnecting to %s (port %s) ... "), host, port);
644

645
	for (ai0 = ai; ai; ai = ai->ai_next, cnt++) {
646 647
		sockfd = socket(ai->ai_family,
				ai->ai_socktype, ai->ai_protocol);
648 649 650 651 652 653
		if ((sockfd < 0) ||
		    (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0)) {
			strbuf_addf(&error_message, "%s[%d: %s]: errno=%s\n",
				    host, cnt, ai_name(ai), strerror(errno));
			if (0 <= sockfd)
				close(sockfd);
654 655
			sockfd = -1;
			continue;
656
		}
657 658
		if (flags & CONNECT_VERBOSE)
			fprintf(stderr, "%s ", ai_name(ai));
659
		break;
660 661
	}

662
	freeaddrinfo(ai0);
663 664

	if (sockfd < 0)
665
		die(_("unable to connect to %s:\n%s"), host, error_message.buf);
666

667 668
	enable_keepalive(sockfd);

669
	if (flags & CONNECT_VERBOSE)
670 671
		/* TRANSLATORS: this is the end of "Connecting to %s (port %s) ... " */
		fprintf_ln(stderr, _("done."));
672

673 674
	strbuf_release(&error_message);

675
	return sockfd;
676 677
}

678
#else /* NO_IPV6 */
679

680 681 682
/*
 * Returns a connected socket() fd, or else die()s.
 */
683
static int git_tcp_connect_sock(char *host, int flags)
684
{
685 686
	struct strbuf error_message = STRBUF_INIT;
	int sockfd = -1;
687 688
	const char *port = STR(DEFAULT_GIT_PORT);
	char *ep;
689 690 691 692
	struct hostent *he;
	struct sockaddr_in sa;
	char **ap;
	unsigned int nport;
693
	int cnt;
694

695
	get_host_and_port(&host, &port);
696

697
	if (flags & CONNECT_VERBOSE)
698
		fprintf(stderr, _("Looking up %s ... "), host);
699

700 701
	he = gethostbyname(host);
	if (!he)
702
		die(_("unable to look up %s (%s)"), host, hstrerror(h_errno));
703 704 705 706 707
	nport = strtoul(port, &ep, 10);
	if ( ep == port || *ep ) {
		/* Not numeric */
		struct servent *se = getservbyname(port,"tcp");
		if ( !se )
708
			die(_("unknown port %s"), port);
709 710 711
		nport = se->s_port;
	}

712
	if (flags & CONNECT_VERBOSE)
713 714
		/* TRANSLATORS: this is the end of "Looking up %s ... " */
		fprintf(stderr, _("done.\nConnecting to %s (port %s) ... "), host, port);
715

716
	for (cnt = 0, ap = he->h_addr_list; *ap; ap++, cnt++) {
717 718
		memset(&sa, 0, sizeof sa);
		sa.sin_family = he->h_addrtype;
719
		sa.sin_port = htons(nport);
720
		memcpy(&sa.sin_addr, *ap, he->h_length);
721

722 723 724 725
		sockfd = socket(he->h_addrtype, SOCK_STREAM, 0);
		if ((sockfd < 0) ||
		    connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
			strbuf_addf(&error_message, "%s[%d: %s]: errno=%s\n",
726 727 728
				host,
				cnt,
				inet_ntoa(*(struct in_addr *)&sa.sin_addr),
729 730 731
				strerror(errno));
			if (0 <= sockfd)
				close(sockfd);
732 733 734
			sockfd = -1;
			continue;
		}
735 736 737
		if (flags & CONNECT_VERBOSE)
			fprintf(stderr, "%s ",
				inet_ntoa(*(struct in_addr *)&sa.sin_addr));
738 739 740 741
		break;
	}

	if (sockfd < 0)
742
		die(_("unable to connect to %s:\n%s"), host, error_message.buf);
743

744 745
	enable_keepalive(sockfd);

746
	if (flags & CONNECT_VERBOSE)
747 748
		/* TRANSLATORS: this is the end of "Connecting to %s (port %s) ... " */
		fprintf_ln(stderr, _("done."));
749

750 751 752 753 754 755
	return sockfd;
}

#endif /* NO_IPV6 */


756 757 758 759 760 761 762 763 764 765 766 767
/*
 * Dummy child_process returned by git_connect() if the transport protocol
 * does not need fork(2).
 */
static struct child_process no_fork = CHILD_PROCESS_INIT;

int git_connection_is_socket(struct child_process *conn)
{
	return conn == &no_fork;
}

static struct child_process *git_tcp_connect(int fd[2], char *host, int flags)
768
{
769
	int sockfd = git_tcp_connect_sock(host, flags);
770

771
	fd[0] = sockfd;
772
	fd[1] = dup(sockfd);
773 774

	return &no_fork;
775 776 777
}


778
static char *git_proxy_command;
779

780 781
static int git_proxy_command_options(const char *var, const char *value,
		void *cb)
782
{
Junio C Hamano's avatar
Junio C Hamano committed
783
	if (!strcmp(var, "core.gitproxy")) {
784 785 786
		const char *for_pos;
		int matchlen = -1;
		int hostlen;
787 788
		const char *rhost_name = cb;
		int rhost_len = strlen(rhost_name);
789

Junio C Hamano's avatar
Junio C Hamano committed
790
		if (git_proxy_command)
791
			return 0;
792 793
		if (!value)
			return config_error_nonbool(var);
Junio C Hamano's avatar
Junio C Hamano committed
794 795 796 797 798 799
		/* [core]
		 * ;# matches www.kernel.org as well
		 * gitproxy = netcatter-1 for kernel.org
		 * gitproxy = netcatter-2 for sample.xz
		 * gitproxy = netcatter-default
		 */
800
		for_pos = strstr(value, " for ");
Junio C Hamano's avatar
Junio C Hamano committed
801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818
		if (!for_pos)
			/* matches everybody */
			matchlen = strlen(value);
		else {
			hostlen = strlen(for_pos + 5);
			if (rhost_len < hostlen)
				matchlen = -1;
			else if (!strncmp(for_pos + 5,
					  rhost_name + rhost_len - hostlen,
					  hostlen) &&
				 ((rhost_len == hostlen) ||
				  rhost_name[rhost_len - hostlen -1] == '.'))
				matchlen = for_pos - value;
			else
				matchlen = -1;
		}
		if (0 <= matchlen) {
			/* core.gitproxy = none for kernel.org */
Junio C Hamano's avatar
Junio C Hamano committed
819
			if (matchlen == 4 &&
Junio C Hamano's avatar
Junio C Hamano committed
820 821
			    !memcmp(value, "none", 4))
				matchlen = 0;
822
			git_proxy_command = xmemdupz(value, matchlen);
823
		}
Junio C Hamano's avatar
Junio C Hamano committed
824
		return 0;
825 826
	}

827
	return git_default_config(var, value, cb);
828 829
}

Junio C Hamano's avatar
Junio C Hamano committed
830
static int git_use_proxy(const char *host)
831 832
{
	git_proxy_command = getenv("GIT_PROXY_COMMAND");
833
	git_config(git_proxy_command_options, (void*)host);
Junio C Hamano's avatar
Junio C Hamano committed
834
	return (git_proxy_command && *git_proxy_command);
835 836
}

837
static struct child_process *git_proxy_connect(int fd[2], char *host)
838
{
Timo Hirvonen's avatar
Timo Hirvonen committed
839
	const char *port = STR(DEFAULT_GIT_PORT);
840
	struct child_process *proxy;
841

842
	get_host_and_port(&host, &port);
843

844
	if (looks_like_command_line_option(host))
845
		die(_("strange hostname '%s' blocked"), host);
846
	if (looks_like_command_line_option(port))
847
		die(_("strange port '%s' blocked"), port);
848

849 850
	proxy = xmalloc(sizeof(*proxy));
	child_process_init(proxy);
Jeff King's avatar
Jeff King committed
851 852 853
	argv_array_push(&proxy->args, git_proxy_command);
	argv_array_push(&proxy->args, host);
	argv_array_push(&proxy->args, port);
854 855 856
	proxy->in = -1;
	proxy->out = -1;
	if (start_command(proxy))
857
		die(_("cannot start proxy %s"), git_proxy_command);
858 859 860
	fd[0] = proxy->out; /* read from proxy stdout */
	fd[1] = proxy->in;  /* write to proxy stdin */
	return proxy;
861 862
}

863
static char *get_port(char *host)
864 865
{
	char *end;
866 867
	char *p = strchr(host, ':');

868
	if (p) {
869 870
		long port = strtol(p + 1, &end, 10);
		if (end != p + 1 && *end == '\0' && 0 <= port && port < 65536) {
871 872
			*p = '\0';
			return p+1;
873 874 875 876 877 878
		}
	}

	return NULL;
}

879
/*
880 881
 * Extract protocol and relevant parts from the specified connection URL.
 * The caller must free() the returned strings.
882
 */
883
static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
884
				       char **ret_path)
885
{
886
	char *url;
887
	char *host, *path;
888
	char *end;
889
	int separator = '/';
890
	enum protocol protocol = PROTO_LOCAL;
891

892 893 894 895 896
	if (is_url(url_orig))
		url = url_decode(url_orig);
	else
		url = xstrdup(url_orig);

897
	host = strstr(url, "://");
898
	if (host) {
899 900 901
		*host = '\0';
		protocol = get_protocol(url);
		host += 3;
902
	} else {
903
		host = url;
904 905 906 907
		if (!url_is_local_not_ssh(url)) {
			protocol = PROTO_SSH;
			separator = ':';
		}
908 909
	}

910
	/*
911 912
	 * Don't do destructive transforms as protocol code does
	 * '[]' unwrapping in get_host_and_port()
913
	 */
914
	end = host_end(&host, 0);
915

916
	if (protocol == PROTO_LOCAL)
917
		path = end;
918 919 920 921
	else if (protocol == PROTO_FILE && has_dos_drive_prefix(end))
		path = end; /* "file://$(pwd)" may be "file://C:/projects/repo" */
	else
		path = strchr(end, separator);
922

923
	if (!path || !*path)
924
		die(_("no path specified; see 'git help pull' for valid url syntax"));
925 926 927 928 929

	/*
	 * null-terminate hostname and point path to ~ for URL's like this:
	 *    ssh://host.xz/~user/repo
	 */
930 931 932 933 934

	end = path; /* Need to \0 terminate host here */
	if (separator == ':')
		path++; /* path starts after ':' */
	if (protocol == PROTO_GIT || protocol == PROTO_SSH) {
935 936 937 938
		if (path[1] == '~')
			path++;
	}

939 940 941
	path = xstrdup(path);
	*end = '\0';

942
	*ret_host = xstrdup(host);
943
	*ret_path = path;
944 945 946 947
	free(url);
	return protocol;
}

948 949 950 951 952 953 954 955 956 957 958 959 960
static const char *get_ssh_command(void)
{
	const char *ssh;

	if ((ssh = getenv("GIT_SSH_COMMAND")))
		return ssh;

	if (!git_config_get_string_const("core.sshcommand", &ssh))
		return ssh;

	return NULL;
}

961
enum ssh_variant {
962
	VARIANT_AUTO,
963 964 965 966 967 968 969
	VARIANT_SIMPLE,
	VARIANT_SSH,
	VARIANT_PLINK,
	VARIANT_PUTTY,
	VARIANT_TORTOISEPLINK,
};

970
static void override_ssh_variant(enum ssh_variant *ssh_variant)
971
{
972
	const char *variant = getenv("GIT_SSH_VARIANT");
973

974
	if (!variant && git_config_get_string_const("ssh.variant", &variant))
975
		return;
976

977 978 979
	if (!strcmp(variant, "auto"))
		*ssh_variant = VARIANT_AUTO;
	else if (!strcmp(variant, "plink"))
980 981 982 983 984 985 986 987 988
		*ssh_variant = VARIANT_PLINK;
	else if (!strcmp(variant, "putty"))
		*ssh_variant = VARIANT_PUTTY;
	else if (!strcmp(variant, "tortoiseplink"))
		*ssh_variant = VARIANT_TORTOISEPLINK;
	else if (!strcmp(variant, "simple"))
		*ssh_variant = VARIANT_SIMPLE;
	else
		*ssh_variant = VARIANT_SSH;
989 990
}

991 992
static enum ssh_variant determine_ssh_variant(const char *ssh_command,
					      int is_cmdline)
993
{
994
	enum ssh_variant ssh_variant = VARIANT_AUTO;
995
	const char *variant;
996 997
	char *p = NULL;

998 999 1000
	override_ssh_variant(&ssh_variant);

	if (ssh_variant != VARIANT_AUTO)
1001
		return ssh_variant;
1002 1003

	if (!is_cmdline) {
1004 1005 1006 1007 1008 1009
		p = xstrdup(ssh_command);
		variant = basename(p);
	} else {
		const char **ssh_argv;

		p = xstrdup(ssh_command);
1010
		if (split_cmdline(p, &ssh_argv) > 0) {
1011 1012 1013 1014 1015 1016 1017
			variant = basename((char *)ssh_argv[0]);
			/*
			 * At this point, variant points into the buffer
			 * referenced by p, hence we do not need ssh_argv
			 * any longer.
			 */
			free(ssh_argv);
1018 1019
		} else {
			free(p);
1020
			return ssh_variant;
1021
		}
1022 1023
	}

1024 1025 1026 1027 1028 1029
	if (!strcasecmp(variant, "ssh") ||
	    !strcasecmp(variant, "ssh.exe"))
		ssh_variant = VARIANT_SSH;
	else if (!strcasecmp(variant, "plink") ||
		 !strcasecmp(variant, "plink.exe"))
		ssh_variant = VARIANT_PLINK;
1030
	else if (!strcasecmp(variant, "tortoiseplink") ||
1031 1032 1033
		 !strcasecmp(variant, "tortoiseplink.exe"))
		ssh_variant = VARIANT_TORTOISEPLINK;

1034
	free(p);
1035
	return ssh_variant;
1036 1037
}

1038 1039 1040 1041 1042 1043 1044 1045
/*
 * Open a connection using Git's native protocol.
 *
 * The caller is responsible for freeing hostandport, but this function may
 * modify it (for example, to truncate it to remove the port part).
 */
static struct child_process *git_connect_git(int fd[2], char *hostandport,
					     const char *path, const char *prog,
1046
					     enum protocol_version version,
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063
					     int flags)
{
	struct child_process *conn;
	struct strbuf request = STRBUF_INIT;
	/*
	 * Set up virtual host information based on where we will
	 * connect, unless the user has overridden us in
	 * the environment.
	 */
	char *target_host = getenv("GIT_OVERRIDE_VIRTUAL_HOST");
	if (target_host)
		target_host = xstrdup(target_host);
	else
		target_host = xstrdup(hostandport);

	transport_check_allowed("git");

1064 1065
	/*
	 * These underlying connection commands die() if they
1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084
	 * cannot connect.
	 */
	if (git_use_proxy(hostandport))
		conn = git_proxy_connect(fd, hostandport);
	else
		conn = git_tcp_connect(fd, hostandport, flags);
	/*
	 * Separate original protocol components prog and path
	 * from extended host header with a NUL byte.
	 *
	 * Note: Do not add any other headers here!  Doing so
	 * will cause older git-daemon servers to crash.
	 */
	strbuf_addf(&request,
		    "%s %s%chost=%s%c",
		    prog, path, 0,
		    target_host, 0);

	/* If using a new version put that stuff here after a second null byte */
1085
	if (version > 0) {
1086 1087
		strbuf_addch(&request, '\0');
		strbuf_addf(&request, "version=%d%c",
1088
			    version, '\0');
1089 1090 1091 1092 1093 1094 1095 1096 1097
	}

	packet_write(fd[1], request.buf, request.len);

	free(target_host);
	strbuf_release(&request);
	return conn;
}

1098 1099 1100 1101 1102 1103
/*
 * Append the appropriate environment variables to `env` and options to
 * `args` for running ssh in Git's SSH-tunneled transport.
 */
static void push_ssh_options(struct argv_array *args, struct argv_array *env,
			     enum ssh_variant variant, const char *port,
1104
			     enum protocol_version version, int flags)
1105 1106
{
	if (variant == VARIANT_SSH &&
1107
	    version > 0) {
1108 1109 1110
		argv_array_push(args, "-o");
		argv_array_push(args, "SendEnv=" GIT_PROTOCOL_ENVIRONMENT);
		argv_array_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=version=%d",
1111
				 version);
1112 1113
	}

1114 1115 1116 1117 1118
	if (flags & CONNECT_IPV4) {
		switch (variant) {
		case VARIANT_AUTO:
			BUG("VARIANT_AUTO passed to push_ssh_options");
		case VARIANT_SIMPLE:
1119
			die(_("ssh variant 'simple' does not support -4"));
1120 1121 1122 1123
		case VARIANT_SSH:
		case VARIANT_PLINK:
		case VARIANT_PUTTY:
		case VARIANT_TORTOISEPLINK:
1124
			argv_array_push(args, "-4");
1125 1126 1127 1128 1129 1130
		}
	} else if (flags & CONNECT_IPV6) {
		switch (variant) {
		case VARIANT_AUTO:
			BUG("VARIANT_AUTO passed to push_ssh_options");
		case VARIANT_SIMPLE:
1131
			die(_("ssh variant 'simple' does not support -6"));
1132 1133 1134 1135
		case VARIANT_SSH:
		case VARIANT_PLINK:
		case VARIANT_PUTTY:
		case VARIANT_TORTOISEPLINK:
1136
			argv_array_push(args, "-6");
1137
		}
1138 1139 1140 1141 1142
	}

	if (variant == VARIANT_TORTOISEPLINK)
		argv_array_push(args, "-batch");

1143 1144 1145 1146 1147
	if (port) {
		switch (variant) {
		case VARIANT_AUTO:
			BUG("VARIANT_AUTO passed to push_ssh_options");
		case VARIANT_SIMPLE:
1148
			die(_("ssh variant 'simple' does not support setting port"));
1149
		case VARIANT_SSH:
1150
			argv_array_push(args, "-p");
1151 1152 1153 1154
			break;
		case VARIANT_PLINK:
		case VARIANT_PUTTY:
		case VARIANT_TORTOISEPLINK:
1155
			argv_array_push(args, "-P");
1156
		}
1157 1158 1159 1160 1161

		argv_array_push(args, port);
	}
}

1162 1163
/* Prepare a child_process for use by Git's SSH-tunneled transport. */
static void fill_ssh_args(struct child_process *conn, const char *ssh_host,
1164 1165
			  const char *port, enum protocol_version version,
			  int flags)
1166 1167 1168 1169 1170
{
	const char *ssh;
	enum ssh_variant variant;

	if (looks_like_command_line_option(ssh_host))
1171
		die(_("strange hostname '%s' blocked"), ssh_host);
1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189

	ssh = get_ssh_command();
	if (ssh) {
		variant = determine_ssh_variant(ssh, 1);
	} else {
		/*
		 * GIT_SSH is the no-shell version of
		 * GIT_SSH_COMMAND (and must remain so for
		 * historical compatibility).
		 */
		conn->use_shell = 0;

		ssh = getenv("GIT_SSH");
		if (!ssh)
			ssh = "ssh";
		variant = determine_ssh_variant(ssh, 0);
	}

1190 1191 1192 1193 1194 1195 1196 1197 1198
	if (variant == VARIANT_AUTO) {
		struct child_process detect = CHILD_PROCESS_INIT;

		detect.use_shell = conn->use_shell;
		detect.no_stdin = detect.no_stdout = detect.no_stderr = 1;

		argv_array_push(&detect.args, ssh);
		argv_array_push(&detect.args, "-G");
		push_ssh_options(&detect.args, &detect.env_array,
1199
				 VARIANT_SSH, port, version, flags);
1200 1201 1202 1203 1204
		argv_array_push(&detect.args, ssh_host);

		variant = run_command(&detect) ? VARIANT_SIMPLE : VARIANT_SSH;
	}

1205
	argv_array_push(&conn->args, ssh);
1206
	push_ssh_options(&conn->args, &conn->env_array, variant, port, version, flags);
1207 1208 1209
	argv_array_push(&conn->args, ssh_host);
}

1210
/*
1211 1212 1213 1214 1215
 * This returns the dummy child_process `no_fork` if the transport protocol
 * does not need fork(2), or a struct child_process object if it does.  Once
 * done, finish the connection with finish_connect() with the value returned
 * from this function (it is safe to call finish_connect() with NULL to
 * support the former case).
1216 1217 1218 1219 1220 1221 1222 1223
 *
 * If it returns, the connect is successful; it just dies on errors (this
 * will hopefully be changed in a libification effort, to return NULL when
 * the connection failed).
 */
struct child_process *git_connect(int fd[2], const char *url,
				  const char *prog, int flags)
{
1224
	char *hostandport, *path;
1225
	struct child_process *conn;
1226
	enum protocol protocol;
1227
	enum protocol_version version = get_protocol_version_config();
1228

1229 1230 1231 1232 1233 1234 1235 1236
	/*
	 * NEEDSWORK: If we are trying to use protocol v2 and we are planning
	 * to perform a push, then fallback to v0 since the client doesn't know
	 * how to push yet using v2.
	 */
	if (version == protocol_v2 && !strcmp("git-receive-pack", prog))
		version = protocol_v0;

1237 1238
	/* Without this we cannot rely on waitpid() to tell
	 * what happened to our children.
1239
	 */
1240
	signal(SIGCHLD, SIG_DFL);
1241

1242
	protocol = parse_connect_url(url, &hostandport, &path);
1243
	if ((flags & CONNECT_DIAG_URL) && (protocol != PROTO_SSH)) {
1244 1245
		printf("Diag: url=%s\n", url ? url : "NULL");
		printf("Diag: protocol=%s\n", prot_name(protocol));
1246
		printf("Diag: hostandport=%s\n", hostandport ? hostandport : "NULL");
1247
		printf("Diag: path=%s\n", path ? path : "NULL");
1248 1249
		conn = NULL;
	} else if (protocol == PROTO_GIT) {
1250
		conn = git_connect_git(fd, hostandport, path, prog, version, flags);
1251
		conn->trace2_child_class = "transport/git";
1252
	} else {
1253
		struct strbuf cmd = STRBUF_INIT;
1254
		const char *const *var;
1255

1256 1257
		conn = xmalloc(sizeof(*conn));
		child_process_init(conn);
1258

1259
		if (looks_like_command_line_option(path))
1260
			die(_("strange pathname '%s' blocked"), path);
1261

1262 1263 1264 1265
		strbuf_addstr(&cmd, prog);
		strbuf_addch(&cmd, ' ');
		sq_quote_buf(&cmd, path);

1266
		/* remove repo-local variables from the environment */
1267 1268 1269
		for (var = local_repo_env; *var; var++)
			argv_array_push(&conn->env_array, *var);

1270
		conn->use_shell = 1;
1271 1272 1273 1274
		conn->in = conn->out = -1;
		if (protocol == PROTO_SSH) {
			char *ssh_host = hostandport;
			const char *port = NULL;
1275
			transport_check_allowed("ssh");
1276 1277
			get_host_and_port(&ssh_host, &port);

1278 1279
			if (!port)
				port = get_port(ssh_host);
1280

1281 1282 1283 1284 1285 1286
			if (flags & CONNECT_DIAG_URL) {
				printf("Diag: url=%s\n", url ? url : "NULL");
				printf("Diag: protocol=%s\n", prot_name(protocol));
				printf("Diag: userandhost=%s\n", ssh_host ? ssh_host : "NULL");
				printf("Diag: port=%s\n", port ? port : "NONE");
				printf("Diag: path=%s\n", path ? path : "NULL");
1287

1288 1289
				free(hostandport);
				free(path);
1290
				free(conn);
1291
				strbuf_release(&cmd);
1292
				return NULL;
1293
			}
1294
			conn->trace2_child_class = "transport/ssh";
1295
			fill_ssh_args(conn, ssh_host, port, version, flags);
1296
		} else {
1297
			transport_check_allowed("file");
1298
			conn->trace2_child_class = "transport/file";
1299
			if (version > 0) {
1300
				argv_array_pushf(&conn->env_array, GIT_PROTOCOL_ENVIRONMENT "=version=%d",
1301
						 version);
1302
			}
1303
		}
Jeff King's avatar
Jeff King committed
1304
		argv_array_push(&conn->args, cmd.buf);
1305

1306
		if (start_command(conn))
1307
			die(_("unable to fork"));
1308

1309 1310 1311 1312 1313
		fd[0] = conn->out; /* read from child's stdout */
		fd[1] = conn->in;  /* write to child's stdin */
		strbuf_release(&cmd);
	}
	free(hostandport);
1314
	free(path);
1315
	return conn;
1316 1317
}

1318
int finish_connect(struct child_process *conn)