]> git.ipfire.org Git - thirdparty/git.git/blame - connect.c
Merge branch 'ab/remove-implicit-use-of-the-repository' into en/header-split-cache-h
[thirdparty/git.git] / connect.c
CommitLineData
731043fd 1#include "git-compat-util.h"
f7192598 2#include "cache.h"
b2141fc1 3#include "config.h"
32a8f510 4#include "environment.h"
f394e093 5#include "gettext.h"
41771fa4 6#include "hex.h"
41cb7488 7#include "pkt-line.h"
b10d0ec7 8#include "quote.h"
6abf5c0c 9#include "refs.h"
15a1c012 10#include "run-command.h"
6b62816c 11#include "remote.h"
47a59185 12#include "connect.h"
9d2e9420 13#include "url.h"
a45b5f05 14#include "string-list.h"
fe299ec5 15#include "oid-array.h"
a5adaced 16#include "transport.h"
0cd83283 17#include "strbuf.h"
e52449b6 18#include "version.h"
2609043d 19#include "protocol.h"
65b5f948 20#include "alias.h"
0cfde740 21#include "bundle-uri.h"
f7192598 22
e52449b6 23static char *server_capabilities_v1;
ef8d7ac4 24static struct strvec server_capabilities_v2 = STRVEC_INIT;
2c6a403d 25static const char *next_server_feature_value(const char *feature, int *len, int *offset);
211b5f9e 26
be0b3f82 27static int check_ref(const char *name, unsigned int flags)
2718ff09
LT
28{
29 if (!flags)
30 return 1;
31
be0b3f82 32 if (!skip_prefix(name, "refs/", &name))
2718ff09
LT
33 return 0;
34
2718ff09 35 /* REF_NORMAL means that we don't want the magic fake tag refs */
7c3c5502
ZH
36 if ((flags & REF_NORMAL) && check_refname_format(name,
37 REFNAME_ALLOW_ONELEVEL))
2718ff09
LT
38 return 0;
39
40 /* REF_HEADS means that we want regular branch heads */
be0b3f82 41 if ((flags & REF_HEADS) && starts_with(name, "heads/"))
2718ff09
LT
42 return 1;
43
44 /* REF_TAGS means that we want tags */
be0b3f82 45 if ((flags & REF_TAGS) && starts_with(name, "tags/"))
2718ff09
LT
46 return 1;
47
48 /* All type bits clear means that we are ok with anything */
49 return !(flags & ~REF_NORMAL);
50}
51
4577370e
DB
52int check_ref_type(const struct ref *ref, int flags)
53{
be0b3f82 54 return check_ref(ref->name, flags);
4577370e
DB
55}
56
d2bff22c 57static NORETURN void die_initial_contact(int unexpected)
46284dd1 58{
7e3e479b
BW
59 /*
60 * A hang-up after seeing some response from the other end
61 * means that it is unexpected, as we know the other end is
62 * willing to talk to us. A hang-up before seeing any
63 * response does not necessarily mean an ACL problem, though.
64 */
55e4f936 65 if (unexpected)
1a07e59c 66 die(_("the remote end hung up upon initial contact"));
46284dd1 67 else
f2b93b38
VA
68 die(_("Could not read from remote repository.\n\n"
69 "Please make sure you have the correct access rights\n"
70 "and the repository exists."));
46284dd1
HV
71}
72
e52449b6 73/* Checks if the server supports the capability 'c' */
a31cfe32 74int server_supports_v2(const char *c)
e52449b6
BW
75{
76 int i;
77
d70a9eb6 78 for (i = 0; i < server_capabilities_v2.nr; i++) {
e52449b6 79 const char *out;
d70a9eb6 80 if (skip_prefix(server_capabilities_v2.v[i], c, &out) &&
e52449b6
BW
81 (!*out || *out == '='))
82 return 1;
83 }
a31cfe32
JK
84 return 0;
85}
e52449b6 86
a31cfe32
JK
87void ensure_server_supports_v2(const char *c)
88{
89 if (!server_supports_v2(c))
aad6fddb 90 die(_("server doesn't support '%s'"), c);
e52449b6
BW
91}
92
1349ffed 93int server_feature_v2(const char *c, const char **v)
94{
95 int i;
96
d70a9eb6 97 for (i = 0; i < server_capabilities_v2.nr; i++) {
1349ffed 98 const char *out;
d70a9eb6 99 if (skip_prefix(server_capabilities_v2.v[i], c, &out) &&
1349ffed 100 (*out == '=')) {
101 *v = out + 1;
102 return 1;
103 }
104 }
105 return 0;
106}
107
f7e20501
BW
108int server_supports_feature(const char *c, const char *feature,
109 int die_on_error)
110{
111 int i;
112
d70a9eb6 113 for (i = 0; i < server_capabilities_v2.nr; i++) {
f7e20501 114 const char *out;
d70a9eb6 115 if (skip_prefix(server_capabilities_v2.v[i], c, &out) &&
f7e20501
BW
116 (!*out || *(out++) == '=')) {
117 if (parse_feature_request(out, feature))
118 return 1;
119 else
120 break;
121 }
122 }
123
124 if (die_on_error)
aad6fddb 125 die(_("server doesn't support feature '%s'"), feature);
f7e20501
BW
126
127 return 0;
128}
129
e52449b6
BW
130static void process_capabilities_v2(struct packet_reader *reader)
131{
132 while (packet_reader_read(reader) == PACKET_READ_NORMAL)
ef8d7ac4 133 strvec_push(&server_capabilities_v2, reader->line);
e52449b6
BW
134
135 if (reader->status != PACKET_READ_FLUSH)
aad6fddb 136 die(_("expected flush after capabilities"));
e52449b6
BW
137}
138
ad6ac124 139enum protocol_version discover_version(struct packet_reader *reader)
7e3e479b
BW
140{
141 enum protocol_version version = protocol_unknown_version;
142
143 /*
144 * Peek the first line of the server's response to
145 * determine the protocol version the server is speaking.
146 */
147 switch (packet_reader_peek(reader)) {
148 case PACKET_READ_EOF:
149 die_initial_contact(0);
150 case PACKET_READ_FLUSH:
151 case PACKET_READ_DELIM:
0181b600 152 case PACKET_READ_RESPONSE_END:
7e3e479b
BW
153 version = protocol_v0;
154 break;
155 case PACKET_READ_NORMAL:
156 version = determine_protocol_version_client(reader->line);
157 break;
158 }
159
160 switch (version) {
8f6982b4 161 case protocol_v2:
e52449b6 162 process_capabilities_v2(reader);
8f6982b4 163 break;
7e3e479b
BW
164 case protocol_v1:
165 /* Read the peeked version line */
166 packet_reader_read(reader);
167 break;
168 case protocol_v0:
169 break;
170 case protocol_unknown_version:
171 BUG("unknown protocol version");
172 }
173
626beebd
JS
174 trace2_data_intmax("transfer", NULL, "negotiated-version", version);
175
7e3e479b
BW
176 return version;
177}
178
a45b5f05
JH
179static void parse_one_symref_info(struct string_list *symref, const char *val, int len)
180{
181 char *sym, *target;
182 struct string_list_item *item;
183
184 if (!len)
185 return; /* just "symref" */
186 /* e.g. "symref=HEAD:refs/heads/master" */
5c0b13f8 187 sym = xmemdupz(val, len);
a45b5f05
JH
188 target = strchr(sym, ':');
189 if (!target)
190 /* just "symref=something" */
191 goto reject;
192 *(target++) = '\0';
193 if (check_refname_format(sym, REFNAME_ALLOW_ONELEVEL) ||
194 check_refname_format(target, REFNAME_ALLOW_ONELEVEL))
195 /* "symref=bogus:pair */
196 goto reject;
ef4fe561 197 item = string_list_append_nodup(symref, sym);
a45b5f05
JH
198 item->util = target;
199 return;
200reject:
201 free(sym);
202 return;
203}
204
205static void annotate_refs_with_symref_info(struct ref *ref)
206{
207 struct string_list symref = STRING_LIST_INIT_DUP;
2c6a403d 208 int offset = 0;
a45b5f05 209
2c6a403d 210 while (1) {
a45b5f05
JH
211 int len;
212 const char *val;
213
2c6a403d 214 val = next_server_feature_value("symref", &len, &offset);
a45b5f05
JH
215 if (!val)
216 break;
217 parse_one_symref_info(&symref, val, len);
a45b5f05 218 }
3383e199 219 string_list_sort(&symref);
a45b5f05
JH
220
221 for (; ref; ref = ref->next) {
222 struct string_list_item *item;
223 item = string_list_lookup(&symref, ref->name);
224 if (!item)
225 continue;
226 ref->symref = xstrdup((char *)item->util);
227 }
228 string_list_clear(&symref, 0);
229}
230
92315e50 231static void process_capabilities(struct packet_reader *reader, int *linelen)
2609043d 232{
7c601dc3 233 const char *feat_val;
234 int feat_len;
92315e50 235 const char *line = reader->line;
7e3e479b 236 int nul_location = strlen(line);
92315e50 237 if (nul_location == *linelen)
0cd83283 238 return;
e52449b6 239 server_capabilities_v1 = xstrdup(line + nul_location + 1);
92315e50 240 *linelen = nul_location;
7c601dc3 241
242 feat_val = server_feature_value("object-format", &feat_len);
243 if (feat_val) {
244 char *hash_name = xstrndup(feat_val, feat_len);
245 int hash_algo = hash_algo_by_name(hash_name);
246 if (hash_algo != GIT_HASH_UNKNOWN)
247 reader->hash_algo = &hash_algos[hash_algo];
248 free(hash_name);
249 } else {
250 reader->hash_algo = &hash_algos[GIT_HASH_SHA1];
251 }
0cd83283
JT
252}
253
92315e50 254static int process_dummy_ref(const struct packet_reader *reader)
0cd83283 255{
92315e50 256 const char *line = reader->line;
0cd83283
JT
257 struct object_id oid;
258 const char *name;
259
7c601dc3 260 if (parse_oid_hex_algop(line, &oid, &name, reader->hash_algo))
0cd83283
JT
261 return 0;
262 if (*name != ' ')
263 return 0;
264 name++;
265
14228447 266 return oideq(null_oid(), &oid) && !strcmp(name, "capabilities^{}");
0cd83283
JT
267}
268
7e3e479b 269static void check_no_capabilities(const char *line, int len)
0cd83283 270{
7e3e479b 271 if (strlen(line) != len)
aad6fddb 272 warning(_("ignoring capabilities after first line '%s'"),
7e3e479b 273 line + strlen(line));
0cd83283
JT
274}
275
92315e50 276static int process_ref(const struct packet_reader *reader, int len,
277 struct ref ***list, unsigned int flags,
278 struct oid_array *extra_have)
0cd83283 279{
92315e50 280 const char *line = reader->line;
0cd83283
JT
281 struct object_id old_oid;
282 const char *name;
283
7c601dc3 284 if (parse_oid_hex_algop(line, &old_oid, &name, reader->hash_algo))
0cd83283
JT
285 return 0;
286 if (*name != ' ')
287 return 0;
288 name++;
289
290 if (extra_have && !strcmp(name, ".have")) {
291 oid_array_append(extra_have, &old_oid);
292 } else if (!strcmp(name, "capabilities^{}")) {
aad6fddb 293 die(_("protocol error: unexpected capabilities^{}"));
0cd83283
JT
294 } else if (check_ref(name, flags)) {
295 struct ref *ref = alloc_ref(name);
296 oidcpy(&ref->old_oid, &old_oid);
297 **list = ref;
298 *list = &ref->next;
299 }
7e3e479b 300 check_no_capabilities(line, len);
0cd83283
JT
301 return 1;
302}
303
92315e50 304static int process_shallow(const struct packet_reader *reader, int len,
7e3e479b 305 struct oid_array *shallow_points)
0cd83283 306{
92315e50 307 const char *line = reader->line;
0cd83283
JT
308 const char *arg;
309 struct object_id old_oid;
310
7e3e479b 311 if (!skip_prefix(line, "shallow ", &arg))
0cd83283
JT
312 return 0;
313
7c601dc3 314 if (get_oid_hex_algop(arg, &old_oid, reader->hash_algo))
aad6fddb 315 die(_("protocol error: expected shallow sha-1, got '%s'"), arg);
0cd83283 316 if (!shallow_points)
aad6fddb 317 die(_("repository on the other end cannot be shallow"));
0cd83283 318 oid_array_append(shallow_points, &old_oid);
7e3e479b 319 check_no_capabilities(line, len);
0cd83283
JT
320 return 1;
321}
322
7e3e479b
BW
323enum get_remote_heads_state {
324 EXPECTING_FIRST_REF = 0,
325 EXPECTING_REF,
326 EXPECTING_SHALLOW,
327 EXPECTING_DONE,
328};
329
d1c133f5
LT
330/*
331 * Read all the refs from the other end
332 */
ad6ac124 333struct ref **get_remote_heads(struct packet_reader *reader,
85edf4f5 334 struct ref **list, unsigned int flags,
910650d2 335 struct oid_array *extra_have,
336 struct oid_array *shallow_points)
d1c133f5 337{
a45b5f05 338 struct ref **orig_list = list;
7e3e479b
BW
339 int len = 0;
340 enum get_remote_heads_state state = EXPECTING_FIRST_REF;
55e4f936 341
d1c133f5 342 *list = NULL;
1a7141ff 343
7e3e479b 344 while (state != EXPECTING_DONE) {
ad6ac124 345 switch (packet_reader_read(reader)) {
7e3e479b
BW
346 case PACKET_READ_EOF:
347 die_initial_contact(1);
348 case PACKET_READ_NORMAL:
ad6ac124 349 len = reader->pktlen;
7e3e479b
BW
350 break;
351 case PACKET_READ_FLUSH:
352 state = EXPECTING_DONE;
353 break;
354 case PACKET_READ_DELIM:
0181b600 355 case PACKET_READ_RESPONSE_END:
aad6fddb 356 die(_("invalid packet"));
7e3e479b
BW
357 }
358
0cd83283
JT
359 switch (state) {
360 case EXPECTING_FIRST_REF:
92315e50 361 process_capabilities(reader, &len);
362 if (process_dummy_ref(reader)) {
0cd83283
JT
363 state = EXPECTING_SHALLOW;
364 break;
365 }
366 state = EXPECTING_REF;
367 /* fallthrough */
368 case EXPECTING_REF:
92315e50 369 if (process_ref(reader, len, &list, flags, extra_have))
0cd83283
JT
370 break;
371 state = EXPECTING_SHALLOW;
372 /* fallthrough */
373 case EXPECTING_SHALLOW:
92315e50 374 if (process_shallow(reader, len, shallow_points))
0cd83283 375 break;
aad6fddb 376 die(_("protocol error: unexpected '%s'"), reader->line);
7e3e479b
BW
377 case EXPECTING_DONE:
378 break;
211b5f9e 379 }
d1c133f5 380 }
a45b5f05
JH
381
382 annotate_refs_with_symref_info(*orig_list);
383
d1c133f5
LT
384 return list;
385}
386
e52449b6 387/* Returns 1 when a valid ref has been added to `list`, 0 otherwise */
4f37d457 388static int process_ref_v2(struct packet_reader *reader, struct ref ***list,
f36d4f83 389 const char **unborn_head_target)
e52449b6
BW
390{
391 int ret = 1;
392 int i = 0;
393 struct object_id old_oid;
394 struct ref *ref;
395 struct string_list line_sections = STRING_LIST_INIT_DUP;
396 const char *end;
67e9a707 397 const char *line = reader->line;
e52449b6
BW
398
399 /*
400 * Ref lines have a number of fields which are space deliminated. The
401 * first field is the OID of the ref. The second field is the ref
402 * name. Subsequent fields (symref-target and peeled) are optional and
403 * don't have a particular order.
404 */
405 if (string_list_split(&line_sections, line, ' ', -1) < 2) {
406 ret = 0;
407 goto out;
408 }
409
4f37d457
JT
410 if (!strcmp("unborn", line_sections.items[i].string)) {
411 i++;
412 if (unborn_head_target &&
413 !strcmp("HEAD", line_sections.items[i++].string)) {
414 /*
415 * Look for the symref target (if any). If found,
416 * return it to the caller.
417 */
418 for (; i < line_sections.nr; i++) {
419 const char *arg = line_sections.items[i].string;
420
421 if (skip_prefix(arg, "symref-target:", &arg)) {
422 *unborn_head_target = xstrdup(arg);
423 break;
424 }
425 }
426 }
427 goto out;
428 }
ab67235b 429 if (parse_oid_hex_algop(line_sections.items[i++].string, &old_oid, &end, reader->hash_algo) ||
e52449b6
BW
430 *end) {
431 ret = 0;
432 goto out;
433 }
434
435 ref = alloc_ref(line_sections.items[i++].string);
436
ab67235b 437 memcpy(ref->old_oid.hash, old_oid.hash, reader->hash_algo->rawsz);
e52449b6
BW
438 **list = ref;
439 *list = &ref->next;
440
441 for (; i < line_sections.nr; i++) {
442 const char *arg = line_sections.items[i].string;
443 if (skip_prefix(arg, "symref-target:", &arg))
444 ref->symref = xstrdup(arg);
445
446 if (skip_prefix(arg, "peeled:", &arg)) {
447 struct object_id peeled_oid;
448 char *peeled_name;
449 struct ref *peeled;
ab67235b 450 if (parse_oid_hex_algop(arg, &peeled_oid, &end,
451 reader->hash_algo) || *end) {
e52449b6
BW
452 ret = 0;
453 goto out;
454 }
455
456 peeled_name = xstrfmt("%s^{}", ref->name);
457 peeled = alloc_ref(peeled_name);
458
ab67235b 459 memcpy(peeled->old_oid.hash, peeled_oid.hash,
460 reader->hash_algo->rawsz);
e52449b6
BW
461 **list = peeled;
462 *list = &peeled->next;
463
464 free(peeled_name);
465 }
466 }
467
468out:
469 string_list_clear(&line_sections, 0);
470 return ret;
471}
472
b0df0c16
DL
473void check_stateless_delimiter(int stateless_rpc,
474 struct packet_reader *reader,
475 const char *error)
476{
477 if (!stateless_rpc)
478 return; /* not in stateless mode, no delimiter expected */
479 if (packet_reader_read(reader) != PACKET_READ_RESPONSE_END)
480 die("%s", error);
481}
482
86f4e312
ÆAB
483static void send_capabilities(int fd_out, struct packet_reader *reader)
484{
485 const char *hash_name;
486
a31cfe32 487 if (server_supports_v2("agent"))
86f4e312
ÆAB
488 packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized());
489
490 if (server_feature_v2("object-format", &hash_name)) {
491 int hash_algo = hash_algo_by_name(hash_name);
492 if (hash_algo == GIT_HASH_UNKNOWN)
493 die(_("unknown object format '%s' specified by server"), hash_name);
494 reader->hash_algo = &hash_algos[hash_algo];
495 packet_write_fmt(fd_out, "object-format=%s", reader->hash_algo->name);
496 } else {
497 reader->hash_algo = &hash_algos[GIT_HASH_SHA1];
498 }
499}
500
0cfde740
ÆAB
501int get_remote_bundle_uri(int fd_out, struct packet_reader *reader,
502 struct bundle_list *bundles, int stateless_rpc)
503{
504 int line_nr = 1;
505
506 /* Assert bundle-uri support */
0903d8bb 507 ensure_server_supports_v2("bundle-uri");
0cfde740
ÆAB
508
509 /* (Re-)send capabilities */
510 send_capabilities(fd_out, reader);
511
512 /* Send command */
513 packet_write_fmt(fd_out, "command=bundle-uri\n");
514 packet_delim(fd_out);
515
516 packet_flush(fd_out);
517
518 /* Process response from server */
519 while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
520 const char *line = reader->line;
521 line_nr++;
522
523 if (!bundle_uri_parse_line(bundles, line))
524 continue;
525
526 return error(_("error on bundle-uri response line %d: %s"),
527 line_nr, line);
528 }
529
530 if (reader->status != PACKET_READ_FLUSH)
531 return error(_("expected flush after bundle-uri listing"));
532
533 /*
534 * Might die(), but obscure enough that that's OK, e.g. in
535 * serve.c we'll call BUG() on its equivalent (the
536 * PACKET_READ_RESPONSE_END check).
537 */
538 check_stateless_delimiter(stateless_rpc, reader,
539 _("expected response end packet after ref listing"));
540
541 return 0;
542}
543
e52449b6
BW
544struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
545 struct ref **list, int for_push,
39835409 546 struct transport_ls_refs_options *transport_options,
b0df0c16
DL
547 const struct string_list *server_options,
548 int stateless_rpc)
e52449b6
BW
549{
550 int i;
39835409
JT
551 struct strvec *ref_prefixes = transport_options ?
552 &transport_options->ref_prefixes : NULL;
f36d4f83 553 const char **unborn_head_target = transport_options ?
4f37d457 554 &transport_options->unborn_head_target : NULL;
e52449b6
BW
555 *list = NULL;
556
a31cfe32
JK
557 ensure_server_supports_v2("ls-refs");
558 packet_write_fmt(fd_out, "command=ls-refs\n");
e52449b6 559
86f4e312
ÆAB
560 /* Send capabilities */
561 send_capabilities(fd_out, reader);
ab67235b 562
a31cfe32
JK
563 if (server_options && server_options->nr) {
564 ensure_server_supports_v2("server-option");
ff473221
BW
565 for (i = 0; i < server_options->nr; i++)
566 packet_write_fmt(fd_out, "server-option=%s",
567 server_options->items[i].string);
a31cfe32 568 }
ff473221 569
e52449b6
BW
570 packet_delim(fd_out);
571 /* When pushing we don't want to request the peeled tags */
572 if (!for_push)
573 packet_write_fmt(fd_out, "peel\n");
574 packet_write_fmt(fd_out, "symrefs\n");
4f37d457
JT
575 if (server_supports_feature("ls-refs", "unborn", 0))
576 packet_write_fmt(fd_out, "unborn\n");
d70a9eb6 577 for (i = 0; ref_prefixes && i < ref_prefixes->nr; i++) {
e52449b6 578 packet_write_fmt(fd_out, "ref-prefix %s\n",
d70a9eb6 579 ref_prefixes->v[i]);
e52449b6
BW
580 }
581 packet_flush(fd_out);
582
583 /* Process response from server */
584 while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
4f37d457 585 if (!process_ref_v2(reader, &list, unborn_head_target))
aad6fddb 586 die(_("invalid ls-refs response: %s"), reader->line);
e52449b6
BW
587 }
588
589 if (reader->status != PACKET_READ_FLUSH)
aad6fddb 590 die(_("expected flush after ref listing"));
e52449b6 591
b0df0c16
DL
592 check_stateless_delimiter(stateless_rpc, reader,
593 _("expected response end packet after ref listing"));
594
e52449b6
BW
595 return list;
596}
597
84eca27a 598const char *parse_feature_value(const char *feature_list, const char *feature, int *lenp, int *offset)
f47182c8
JH
599{
600 int len;
601
602 if (!feature_list)
603 return NULL;
604
605 len = strlen(feature);
2c6a403d 606 if (offset)
607 feature_list += *offset;
f47182c8
JH
608 while (*feature_list) {
609 const char *found = strstr(feature_list, feature);
610 if (!found)
611 return NULL;
94427108
JK
612 if (feature_list == found || isspace(found[-1])) {
613 const char *value = found + len;
614 /* feature with no value (e.g., "thin-pack") */
615 if (!*value || isspace(*value)) {
616 if (lenp)
617 *lenp = 0;
44d2aec6
AH
618 if (offset)
619 *offset = found + len - feature_list;
94427108
JK
620 return value;
621 }
622 /* feature with a value (e.g., "agent=git/1.2.3") */
623 else if (*value == '=') {
2c6a403d 624 int end;
625
94427108 626 value++;
2c6a403d 627 end = strcspn(value, " \t\n");
94427108 628 if (lenp)
2c6a403d 629 *lenp = end;
630 if (offset)
631 *offset = value + end - feature_list;
94427108
JK
632 return value;
633 }
634 /*
635 * otherwise we matched a substring of another feature;
636 * keep looking
637 */
638 }
f47182c8
JH
639 feature_list = found + 1;
640 }
641 return NULL;
211b5f9e
JS
642}
643
122037c2 644int server_supports_hash(const char *desired, int *feature_supported)
645{
646 int offset = 0;
647 int len;
648 const char *hash;
649
650 hash = next_server_feature_value("object-format", &len, &offset);
651 if (feature_supported)
652 *feature_supported = !!hash;
653 if (!hash) {
654 hash = hash_algos[GIT_HASH_SHA1].name;
655 len = strlen(hash);
656 }
657 while (hash) {
658 if (!xstrncmpz(desired, hash, len))
659 return 1;
660
661 hash = next_server_feature_value("object-format", &len, &offset);
662 }
663 return 0;
664}
665
94427108
JK
666int parse_feature_request(const char *feature_list, const char *feature)
667{
2c6a403d 668 return !!parse_feature_value(feature_list, feature, NULL, NULL);
669}
670
671static const char *next_server_feature_value(const char *feature, int *len, int *offset)
672{
673 return parse_feature_value(server_capabilities_v1, feature, len, offset);
94427108
JK
674}
675
676const char *server_feature_value(const char *feature, int *len)
677{
2c6a403d 678 return parse_feature_value(server_capabilities_v1, feature, len, NULL);
94427108
JK
679}
680
681int server_supports(const char *feature)
682{
683 return !!server_feature_value(feature, NULL);
684}
685
2386d658
LT
686enum protocol {
687 PROTO_LOCAL = 1,
c59ab2e5 688 PROTO_FILE,
2386d658 689 PROTO_SSH,
4b05548f 690 PROTO_GIT
2386d658
LT
691};
692
c59ab2e5
TB
693int url_is_local_not_ssh(const char *url)
694{
695 const char *colon = strchr(url, ':');
696 const char *slash = strchr(url, '/');
697 return !colon || (slash && slash < colon) ||
f82a97eb 698 (has_dos_drive_prefix(url) && is_valid_path(url));
c59ab2e5
TB
699}
700
5610b7c0
TB
701static const char *prot_name(enum protocol protocol)
702{
703 switch (protocol) {
704 case PROTO_LOCAL:
c59ab2e5 705 case PROTO_FILE:
5610b7c0
TB
706 return "file";
707 case PROTO_SSH:
708 return "ssh";
709 case PROTO_GIT:
710 return "git";
711 default:
83e6bda3 712 return "unknown protocol";
5610b7c0
TB
713 }
714}
715
2386d658
LT
716static enum protocol get_protocol(const char *name)
717{
718 if (!strcmp(name, "ssh"))
719 return PROTO_SSH;
720 if (!strcmp(name, "git"))
721 return PROTO_GIT;
07c7782c 722 if (!strcmp(name, "git+ssh")) /* deprecated - do not use */
c05186cc 723 return PROTO_SSH;
07c7782c 724 if (!strcmp(name, "ssh+git")) /* deprecated - do not use */
c05186cc 725 return PROTO_SSH;
72a4f4b6 726 if (!strcmp(name, "file"))
c59ab2e5 727 return PROTO_FILE;
aad6fddb 728 die(_("protocol '%s' is not supported"), name);
2386d658
LT
729}
730
86ceb337
TB
731static char *host_end(char **hoststart, int removebrackets)
732{
733 char *host = *hoststart;
734 char *end;
735 char *start = strstr(host, "@[");
736 if (start)
737 start++; /* Jump over '@' */
738 else
739 start = host;
740 if (start[0] == '[') {
741 end = strchr(start + 1, ']');
742 if (end) {
743 if (removebrackets) {
744 *end = 0;
745 memmove(start, start + 1, end - start);
746 end++;
747 }
748 } else
749 end = host;
750 } else
751 end = host;
752 return end;
753}
754
5ba88448
YH
755#define STR_(s) # s
756#define STR(s) STR_(s)
2386d658 757
72a534da
ML
758static void get_host_and_port(char **host, const char **port)
759{
760 char *colon, *end;
86ceb337 761 end = host_end(host, 1);
72a534da 762 colon = strchr(end, ':');
72a534da 763 if (colon) {
86ceb337
TB
764 long portnr = strtol(colon + 1, &end, 10);
765 if (end != colon + 1 && *end == '\0' && 0 <= portnr && portnr < 65536) {
766 *colon = 0;
767 *port = colon + 1;
6b6c5f7a
TB
768 } else if (!colon[1]) {
769 *colon = 0;
86ceb337 770 }
72a534da
ML
771 }
772}
773
e47a8583
EW
774static void enable_keepalive(int sockfd)
775{
776 int ka = 1;
777
778 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &ka, sizeof(ka)) < 0)
aad6fddb 779 error_errno(_("unable to set SO_KEEPALIVE on socket"));
e47a8583
EW
780}
781
49744d63 782#ifndef NO_IPV6
4c505f71 783
ba505322
AR
784static const char *ai_name(const struct addrinfo *ai)
785{
785a9857
BK
786 static char addr[NI_MAXHOST];
787 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, addr, sizeof(addr), NULL, 0,
788 NI_NUMERICHOST) != 0)
5096d490 789 xsnprintf(addr, sizeof(addr), "(unknown)");
785a9857 790
ba505322
AR
791 return addr;
792}
793
5ad312be
JL
794/*
795 * Returns a connected socket() fd, or else die()s.
796 */
7841ce79 797static int git_tcp_connect_sock(char *host, int flags)
2386d658 798{
63a995b6
DZ
799 struct strbuf error_message = STRBUF_INIT;
800 int sockfd = -1;
554fe20d 801 const char *port = STR(DEFAULT_GIT_PORT);
5ba88448
YH
802 struct addrinfo hints, *ai0, *ai;
803 int gai;
ba505322 804 int cnt = 0;
5ba88448 805
72a534da
ML
806 get_host_and_port(&host, &port);
807 if (!*port)
808 port = "<none>";
5ba88448
YH
809
810 memset(&hints, 0, sizeof(hints));
c915f11e
EW
811 if (flags & CONNECT_IPV4)
812 hints.ai_family = AF_INET;
813 else if (flags & CONNECT_IPV6)
814 hints.ai_family = AF_INET6;
5ba88448
YH
815 hints.ai_socktype = SOCK_STREAM;
816 hints.ai_protocol = IPPROTO_TCP;
817
7841ce79 818 if (flags & CONNECT_VERBOSE)
aad6fddb 819 fprintf(stderr, _("Looking up %s ... "), host);
7841ce79 820
5ba88448
YH
821 gai = getaddrinfo(host, port, &hints, &ai);
822 if (gai)
aad6fddb 823 die(_("unable to look up %s (port %s) (%s)"), host, port, gai_strerror(gai));
5ba88448 824
7841ce79 825 if (flags & CONNECT_VERBOSE)
aad6fddb
NTND
826 /* TRANSLATORS: this is the end of "Looking up %s ... " */
827 fprintf(stderr, _("done.\nConnecting to %s (port %s) ... "), host, port);
7841ce79 828
e08afecd 829 for (ai0 = ai; ai; ai = ai->ai_next, cnt++) {
5ad312be
JL
830 sockfd = socket(ai->ai_family,
831 ai->ai_socktype, ai->ai_protocol);
63a995b6
DZ
832 if ((sockfd < 0) ||
833 (connect(sockfd, ai->ai_addr, ai->ai_addrlen) < 0)) {
834 strbuf_addf(&error_message, "%s[%d: %s]: errno=%s\n",
835 host, cnt, ai_name(ai), strerror(errno));
836 if (0 <= sockfd)
837 close(sockfd);
5ba88448
YH
838 sockfd = -1;
839 continue;
2386d658 840 }
ba505322
AR
841 if (flags & CONNECT_VERBOSE)
842 fprintf(stderr, "%s ", ai_name(ai));
5ba88448 843 break;
2386d658
LT
844 }
845
5ba88448 846 freeaddrinfo(ai0);
2386d658 847
2386d658 848 if (sockfd < 0)
aad6fddb 849 die(_("unable to connect to %s:\n%s"), host, error_message.buf);
5ba88448 850
e47a8583
EW
851 enable_keepalive(sockfd);
852
7841ce79 853 if (flags & CONNECT_VERBOSE)
aad6fddb
NTND
854 /* TRANSLATORS: this is the end of "Connecting to %s (port %s) ... " */
855 fprintf_ln(stderr, _("done."));
7841ce79 856
63a995b6
DZ
857 strbuf_release(&error_message);
858
5ad312be 859 return sockfd;
2386d658
LT
860}
861
49744d63 862#else /* NO_IPV6 */
4c505f71 863
5ad312be
JL
864/*
865 * Returns a connected socket() fd, or else die()s.
866 */
7841ce79 867static int git_tcp_connect_sock(char *host, int flags)
4c505f71 868{
7203a2d1
EFL
869 struct strbuf error_message = STRBUF_INIT;
870 int sockfd = -1;
72a534da
ML
871 const char *port = STR(DEFAULT_GIT_PORT);
872 char *ep;
4c505f71
PA
873 struct hostent *he;
874 struct sockaddr_in sa;
875 char **ap;
876 unsigned int nport;
ba505322 877 int cnt;
4c505f71 878
72a534da 879 get_host_and_port(&host, &port);
4c505f71 880
7841ce79 881 if (flags & CONNECT_VERBOSE)
aad6fddb 882 fprintf(stderr, _("Looking up %s ... "), host);
7841ce79 883
4c505f71
PA
884 he = gethostbyname(host);
885 if (!he)
aad6fddb 886 die(_("unable to look up %s (%s)"), host, hstrerror(h_errno));
4c505f71
PA
887 nport = strtoul(port, &ep, 10);
888 if ( ep == port || *ep ) {
889 /* Not numeric */
890 struct servent *se = getservbyname(port,"tcp");
891 if ( !se )
aad6fddb 892 die(_("unknown port %s"), port);
4c505f71
PA
893 nport = se->s_port;
894 }
895
7841ce79 896 if (flags & CONNECT_VERBOSE)
aad6fddb
NTND
897 /* TRANSLATORS: this is the end of "Looking up %s ... " */
898 fprintf(stderr, _("done.\nConnecting to %s (port %s) ... "), host, port);
7841ce79 899
ba505322 900 for (cnt = 0, ap = he->h_addr_list; *ap; ap++, cnt++) {
4c505f71
PA
901 memset(&sa, 0, sizeof sa);
902 sa.sin_family = he->h_addrtype;
6573faff 903 sa.sin_port = htons(nport);
c6164218 904 memcpy(&sa.sin_addr, *ap, he->h_length);
4c505f71 905
7203a2d1
EFL
906 sockfd = socket(he->h_addrtype, SOCK_STREAM, 0);
907 if ((sockfd < 0) ||
908 connect(sockfd, (struct sockaddr *)&sa, sizeof sa) < 0) {
909 strbuf_addf(&error_message, "%s[%d: %s]: errno=%s\n",
ba505322
AR
910 host,
911 cnt,
912 inet_ntoa(*(struct in_addr *)&sa.sin_addr),
7203a2d1
EFL
913 strerror(errno));
914 if (0 <= sockfd)
915 close(sockfd);
4c505f71
PA
916 sockfd = -1;
917 continue;
918 }
ba505322
AR
919 if (flags & CONNECT_VERBOSE)
920 fprintf(stderr, "%s ",
921 inet_ntoa(*(struct in_addr *)&sa.sin_addr));
4c505f71
PA
922 break;
923 }
924
925 if (sockfd < 0)
aad6fddb 926 die(_("unable to connect to %s:\n%s"), host, error_message.buf);
4c505f71 927
e47a8583
EW
928 enable_keepalive(sockfd);
929
7841ce79 930 if (flags & CONNECT_VERBOSE)
aad6fddb
NTND
931 /* TRANSLATORS: this is the end of "Connecting to %s (port %s) ... " */
932 fprintf_ln(stderr, _("done."));
7841ce79 933
5ad312be
JL
934 return sockfd;
935}
936
937#endif /* NO_IPV6 */
938
939
8e349780
JN
940/*
941 * Dummy child_process returned by git_connect() if the transport protocol
942 * does not need fork(2).
943 */
944static struct child_process no_fork = CHILD_PROCESS_INIT;
945
946int git_connection_is_socket(struct child_process *conn)
947{
948 return conn == &no_fork;
949}
950
951static struct child_process *git_tcp_connect(int fd[2], char *host, int flags)
5ad312be 952{
7841ce79 953 int sockfd = git_tcp_connect_sock(host, flags);
5ad312be 954
4c505f71 955 fd[0] = sockfd;
ec587fde 956 fd[1] = dup(sockfd);
8e349780
JN
957
958 return &no_fork;
4c505f71
PA
959}
960
4c505f71 961
96f1e58f 962static char *git_proxy_command;
f8014776 963
ef90d6d4
JS
964static int git_proxy_command_options(const char *var, const char *value,
965 void *cb)
f8014776 966{
e814bc4d 967 if (!strcmp(var, "core.gitproxy")) {
c3df8568
YH
968 const char *for_pos;
969 int matchlen = -1;
970 int hostlen;
15112c95
EFL
971 const char *rhost_name = cb;
972 int rhost_len = strlen(rhost_name);
c3df8568 973
e814bc4d 974 if (git_proxy_command)
f8014776 975 return 0;
c64b9ad0
JH
976 if (!value)
977 return config_error_nonbool(var);
e814bc4d
JH
978 /* [core]
979 * ;# matches www.kernel.org as well
980 * gitproxy = netcatter-1 for kernel.org
981 * gitproxy = netcatter-2 for sample.xz
982 * gitproxy = netcatter-default
983 */
c3df8568 984 for_pos = strstr(value, " for ");
e814bc4d
JH
985 if (!for_pos)
986 /* matches everybody */
987 matchlen = strlen(value);
988 else {
989 hostlen = strlen(for_pos + 5);
990 if (rhost_len < hostlen)
991 matchlen = -1;
992 else if (!strncmp(for_pos + 5,
993 rhost_name + rhost_len - hostlen,
994 hostlen) &&
995 ((rhost_len == hostlen) ||
996 rhost_name[rhost_len - hostlen -1] == '.'))
997 matchlen = for_pos - value;
998 else
999 matchlen = -1;
1000 }
1001 if (0 <= matchlen) {
1002 /* core.gitproxy = none for kernel.org */
a6080a0a 1003 if (matchlen == 4 &&
e814bc4d
JH
1004 !memcmp(value, "none", 4))
1005 matchlen = 0;
182af834 1006 git_proxy_command = xmemdupz(value, matchlen);
f8014776 1007 }
e814bc4d 1008 return 0;
f8014776
PC
1009 }
1010
ef90d6d4 1011 return git_default_config(var, value, cb);
f8014776
PC
1012}
1013
e814bc4d 1014static int git_use_proxy(const char *host)
f8014776
PC
1015{
1016 git_proxy_command = getenv("GIT_PROXY_COMMAND");
15112c95 1017 git_config(git_proxy_command_options, (void*)host);
e814bc4d 1018 return (git_proxy_command && *git_proxy_command);
f8014776
PC
1019}
1020
5cbf8246 1021static struct child_process *git_proxy_connect(int fd[2], char *host)
f8014776 1022{
554fe20d 1023 const char *port = STR(DEFAULT_GIT_PORT);
5cbf8246 1024 struct child_process *proxy;
f8014776 1025
72a534da 1026 get_host_and_port(&host, &port);
f8014776 1027
3be4cf09 1028 if (looks_like_command_line_option(host))
aad6fddb 1029 die(_("strange hostname '%s' blocked"), host);
3be4cf09 1030 if (looks_like_command_line_option(port))
aad6fddb 1031 die(_("strange port '%s' blocked"), port);
3be4cf09 1032
483bbd4e
RS
1033 proxy = xmalloc(sizeof(*proxy));
1034 child_process_init(proxy);
ef8d7ac4
JK
1035 strvec_push(&proxy->args, git_proxy_command);
1036 strvec_push(&proxy->args, host);
1037 strvec_push(&proxy->args, port);
5cbf8246
JK
1038 proxy->in = -1;
1039 proxy->out = -1;
1040 if (start_command(proxy))
aad6fddb 1041 die(_("cannot start proxy %s"), git_proxy_command);
5cbf8246
JK
1042 fd[0] = proxy->out; /* read from proxy stdout */
1043 fd[1] = proxy->in; /* write to proxy stdin */
1044 return proxy;
f8014776
PC
1045}
1046
86ceb337 1047static char *get_port(char *host)
2e776665
LT
1048{
1049 char *end;
86ceb337
TB
1050 char *p = strchr(host, ':');
1051
2e776665 1052 if (p) {
8f148253
RS
1053 long port = strtol(p + 1, &end, 10);
1054 if (end != p + 1 && *end == '\0' && 0 <= port && port < 65536) {
86ceb337
TB
1055 *p = '\0';
1056 return p+1;
2e776665
LT
1057 }
1058 }
1059
1060 return NULL;
1061}
1062
f7192598 1063/*
cabc3c12
JS
1064 * Extract protocol and relevant parts from the specified connection URL.
1065 * The caller must free() the returned strings.
f7192598 1066 */
cabc3c12 1067static enum protocol parse_connect_url(const char *url_orig, char **ret_host,
83b05875 1068 char **ret_path)
f7192598 1069{
9d2e9420 1070 char *url;
8e76bf3f 1071 char *host, *path;
356bece0 1072 char *end;
c59ab2e5 1073 int separator = '/';
faea9ccb 1074 enum protocol protocol = PROTO_LOCAL;
f0b7367c 1075
9d2e9420
JK
1076 if (is_url(url_orig))
1077 url = url_decode(url_orig);
1078 else
1079 url = xstrdup(url_orig);
1080
faea9ccb 1081 host = strstr(url, "://");
eeefa7c9 1082 if (host) {
faea9ccb
AE
1083 *host = '\0';
1084 protocol = get_protocol(url);
1085 host += 3;
356bece0 1086 } else {
f7192598 1087 host = url;
c59ab2e5
TB
1088 if (!url_is_local_not_ssh(url)) {
1089 protocol = PROTO_SSH;
1090 separator = ':';
1091 }
356bece0
YH
1092 }
1093
9aa5053d 1094 /*
83b05875
TB
1095 * Don't do destructive transforms as protocol code does
1096 * '[]' unwrapping in get_host_and_port()
9aa5053d 1097 */
86ceb337 1098 end = host_end(&host, 0);
356bece0 1099
c59ab2e5 1100 if (protocol == PROTO_LOCAL)
72a4f4b6 1101 path = end;
ebb8d2c9
TB
1102 else if (protocol == PROTO_FILE && *host != '/' &&
1103 !has_dos_drive_prefix(host) &&
1104 offset_1st_component(host - 2) > 1)
1105 path = host - 2; /* include the leading "//" */
c59ab2e5
TB
1106 else if (protocol == PROTO_FILE && has_dos_drive_prefix(end))
1107 path = end; /* "file://$(pwd)" may be "file://C:/projects/repo" */
1108 else
1109 path = strchr(end, separator);
2386d658 1110
faea9ccb 1111 if (!path || !*path)
aad6fddb 1112 die(_("no path specified; see 'git help pull' for valid url syntax"));
faea9ccb
AE
1113
1114 /*
1115 * null-terminate hostname and point path to ~ for URL's like this:
1116 * ssh://host.xz/~user/repo
1117 */
c59ab2e5
TB
1118
1119 end = path; /* Need to \0 terminate host here */
1120 if (separator == ':')
1121 path++; /* path starts after ':' */
1122 if (protocol == PROTO_GIT || protocol == PROTO_SSH) {
faea9ccb
AE
1123 if (path[1] == '~')
1124 path++;
faea9ccb
AE
1125 }
1126
c59ab2e5
TB
1127 path = xstrdup(path);
1128 *end = '\0';
1129
cabc3c12 1130 *ret_host = xstrdup(host);
c59ab2e5 1131 *ret_path = path;
cabc3c12
JS
1132 free(url);
1133 return protocol;
1134}
1135
3c8ede3f
NTND
1136static const char *get_ssh_command(void)
1137{
1138 const char *ssh;
1139
1140 if ((ssh = getenv("GIT_SSH_COMMAND")))
1141 return ssh;
1142
f1de981e 1143 if (!git_config_get_string_tmp("core.sshcommand", &ssh))
3c8ede3f
NTND
1144 return ssh;
1145
1146 return NULL;
1147}
1148
94b8ae5a 1149enum ssh_variant {
0da0e49b 1150 VARIANT_AUTO,
94b8ae5a
BW
1151 VARIANT_SIMPLE,
1152 VARIANT_SSH,
1153 VARIANT_PLINK,
1154 VARIANT_PUTTY,
1155 VARIANT_TORTOISEPLINK,
1156};
1157
0da0e49b 1158static void override_ssh_variant(enum ssh_variant *ssh_variant)
e2824e47 1159{
94b8ae5a 1160 const char *variant = getenv("GIT_SSH_VARIANT");
486c8e8c 1161
f1de981e 1162 if (!variant && git_config_get_string_tmp("ssh.variant", &variant))
0da0e49b 1163 return;
486c8e8c 1164
0da0e49b
JN
1165 if (!strcmp(variant, "auto"))
1166 *ssh_variant = VARIANT_AUTO;
1167 else if (!strcmp(variant, "plink"))
94b8ae5a
BW
1168 *ssh_variant = VARIANT_PLINK;
1169 else if (!strcmp(variant, "putty"))
1170 *ssh_variant = VARIANT_PUTTY;
1171 else if (!strcmp(variant, "tortoiseplink"))
1172 *ssh_variant = VARIANT_TORTOISEPLINK;
1173 else if (!strcmp(variant, "simple"))
1174 *ssh_variant = VARIANT_SIMPLE;
1175 else
1176 *ssh_variant = VARIANT_SSH;
486c8e8c
JH
1177}
1178
94b8ae5a
BW
1179static enum ssh_variant determine_ssh_variant(const char *ssh_command,
1180 int is_cmdline)
486c8e8c 1181{
0da0e49b 1182 enum ssh_variant ssh_variant = VARIANT_AUTO;
486c8e8c 1183 const char *variant;
e2824e47
JS
1184 char *p = NULL;
1185
0da0e49b
JN
1186 override_ssh_variant(&ssh_variant);
1187
1188 if (ssh_variant != VARIANT_AUTO)
94b8ae5a 1189 return ssh_variant;
486c8e8c
JH
1190
1191 if (!is_cmdline) {
e2824e47
JS
1192 p = xstrdup(ssh_command);
1193 variant = basename(p);
1194 } else {
1195 const char **ssh_argv;
1196
1197 p = xstrdup(ssh_command);
22e5ae5c 1198 if (split_cmdline(p, &ssh_argv) > 0) {
e2824e47
JS
1199 variant = basename((char *)ssh_argv[0]);
1200 /*
1201 * At this point, variant points into the buffer
1202 * referenced by p, hence we do not need ssh_argv
1203 * any longer.
1204 */
1205 free(ssh_argv);
5d2993b6
JK
1206 } else {
1207 free(p);
94b8ae5a 1208 return ssh_variant;
5d2993b6 1209 }
e2824e47
JS
1210 }
1211
94b8ae5a
BW
1212 if (!strcasecmp(variant, "ssh") ||
1213 !strcasecmp(variant, "ssh.exe"))
1214 ssh_variant = VARIANT_SSH;
1215 else if (!strcasecmp(variant, "plink") ||
1216 !strcasecmp(variant, "plink.exe"))
1217 ssh_variant = VARIANT_PLINK;
e2824e47 1218 else if (!strcasecmp(variant, "tortoiseplink") ||
94b8ae5a
BW
1219 !strcasecmp(variant, "tortoiseplink.exe"))
1220 ssh_variant = VARIANT_TORTOISEPLINK;
1221
e2824e47 1222 free(p);
94b8ae5a 1223 return ssh_variant;
e2824e47
JS
1224}
1225
2ac67cb6
JN
1226/*
1227 * Open a connection using Git's native protocol.
1228 *
1229 * The caller is responsible for freeing hostandport, but this function may
1230 * modify it (for example, to truncate it to remove the port part).
1231 */
1232static struct child_process *git_connect_git(int fd[2], char *hostandport,
1233 const char *path, const char *prog,
40fc51e3 1234 enum protocol_version version,
2ac67cb6
JN
1235 int flags)
1236{
1237 struct child_process *conn;
1238 struct strbuf request = STRBUF_INIT;
1239 /*
1240 * Set up virtual host information based on where we will
1241 * connect, unless the user has overridden us in
1242 * the environment.
1243 */
1244 char *target_host = getenv("GIT_OVERRIDE_VIRTUAL_HOST");
1245 if (target_host)
1246 target_host = xstrdup(target_host);
1247 else
1248 target_host = xstrdup(hostandport);
1249
1250 transport_check_allowed("git");
a02ea577
JK
1251 if (strchr(target_host, '\n') || strchr(path, '\n'))
1252 die(_("newline is forbidden in git:// hosts and repo paths"));
2ac67cb6 1253
233cd282
JN
1254 /*
1255 * These underlying connection commands die() if they
2ac67cb6
JN
1256 * cannot connect.
1257 */
1258 if (git_use_proxy(hostandport))
1259 conn = git_proxy_connect(fd, hostandport);
1260 else
1261 conn = git_tcp_connect(fd, hostandport, flags);
1262 /*
1263 * Separate original protocol components prog and path
1264 * from extended host header with a NUL byte.
1265 *
1266 * Note: Do not add any other headers here! Doing so
1267 * will cause older git-daemon servers to crash.
1268 */
1269 strbuf_addf(&request,
1270 "%s %s%chost=%s%c",
1271 prog, path, 0,
1272 target_host, 0);
1273
1274 /* If using a new version put that stuff here after a second null byte */
40fc51e3 1275 if (version > 0) {
2ac67cb6
JN
1276 strbuf_addch(&request, '\0');
1277 strbuf_addf(&request, "version=%d%c",
40fc51e3 1278 version, '\0');
2ac67cb6
JN
1279 }
1280
1281 packet_write(fd[1], request.buf, request.len);
1282
1283 free(target_host);
1284 strbuf_release(&request);
1285 return conn;
1286}
1287
957e2ad2
JN
1288/*
1289 * Append the appropriate environment variables to `env` and options to
1290 * `args` for running ssh in Git's SSH-tunneled transport.
1291 */
ef8d7ac4 1292static void push_ssh_options(struct strvec *args, struct strvec *env,
957e2ad2 1293 enum ssh_variant variant, const char *port,
40fc51e3 1294 enum protocol_version version, int flags)
957e2ad2
JN
1295{
1296 if (variant == VARIANT_SSH &&
40fc51e3 1297 version > 0) {
ef8d7ac4
JK
1298 strvec_push(args, "-o");
1299 strvec_push(args, "SendEnv=" GIT_PROTOCOL_ENVIRONMENT);
1300 strvec_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=version=%d",
f6d8942b 1301 version);
957e2ad2
JN
1302 }
1303
a3f5b66f
JN
1304 if (flags & CONNECT_IPV4) {
1305 switch (variant) {
1306 case VARIANT_AUTO:
1307 BUG("VARIANT_AUTO passed to push_ssh_options");
1308 case VARIANT_SIMPLE:
aad6fddb 1309 die(_("ssh variant 'simple' does not support -4"));
a3f5b66f
JN
1310 case VARIANT_SSH:
1311 case VARIANT_PLINK:
1312 case VARIANT_PUTTY:
1313 case VARIANT_TORTOISEPLINK:
ef8d7ac4 1314 strvec_push(args, "-4");
a3f5b66f
JN
1315 }
1316 } else if (flags & CONNECT_IPV6) {
1317 switch (variant) {
1318 case VARIANT_AUTO:
1319 BUG("VARIANT_AUTO passed to push_ssh_options");
1320 case VARIANT_SIMPLE:
aad6fddb 1321 die(_("ssh variant 'simple' does not support -6"));
a3f5b66f
JN
1322 case VARIANT_SSH:
1323 case VARIANT_PLINK:
1324 case VARIANT_PUTTY:
1325 case VARIANT_TORTOISEPLINK:
ef8d7ac4 1326 strvec_push(args, "-6");
a3f5b66f 1327 }
957e2ad2
JN
1328 }
1329
1330 if (variant == VARIANT_TORTOISEPLINK)
ef8d7ac4 1331 strvec_push(args, "-batch");
957e2ad2 1332
3fa5e0d0
JN
1333 if (port) {
1334 switch (variant) {
1335 case VARIANT_AUTO:
1336 BUG("VARIANT_AUTO passed to push_ssh_options");
1337 case VARIANT_SIMPLE:
aad6fddb 1338 die(_("ssh variant 'simple' does not support setting port"));
3fa5e0d0 1339 case VARIANT_SSH:
ef8d7ac4 1340 strvec_push(args, "-p");
3fa5e0d0
JN
1341 break;
1342 case VARIANT_PLINK:
1343 case VARIANT_PUTTY:
1344 case VARIANT_TORTOISEPLINK:
ef8d7ac4 1345 strvec_push(args, "-P");
3fa5e0d0 1346 }
957e2ad2 1347
ef8d7ac4 1348 strvec_push(args, port);
957e2ad2
JN
1349 }
1350}
1351
fce54ce4
JN
1352/* Prepare a child_process for use by Git's SSH-tunneled transport. */
1353static void fill_ssh_args(struct child_process *conn, const char *ssh_host,
40fc51e3
BW
1354 const char *port, enum protocol_version version,
1355 int flags)
fce54ce4
JN
1356{
1357 const char *ssh;
1358 enum ssh_variant variant;
1359
1360 if (looks_like_command_line_option(ssh_host))
aad6fddb 1361 die(_("strange hostname '%s' blocked"), ssh_host);
fce54ce4
JN
1362
1363 ssh = get_ssh_command();
1364 if (ssh) {
1365 variant = determine_ssh_variant(ssh, 1);
1366 } else {
1367 /*
1368 * GIT_SSH is the no-shell version of
1369 * GIT_SSH_COMMAND (and must remain so for
1370 * historical compatibility).
1371 */
1372 conn->use_shell = 0;
1373
1374 ssh = getenv("GIT_SSH");
1375 if (!ssh)
1376 ssh = "ssh";
1377 variant = determine_ssh_variant(ssh, 0);
1378 }
1379
0da0e49b
JN
1380 if (variant == VARIANT_AUTO) {
1381 struct child_process detect = CHILD_PROCESS_INIT;
1382
1383 detect.use_shell = conn->use_shell;
1384 detect.no_stdin = detect.no_stdout = detect.no_stderr = 1;
1385
ef8d7ac4
JK
1386 strvec_push(&detect.args, ssh);
1387 strvec_push(&detect.args, "-G");
29fda24d 1388 push_ssh_options(&detect.args, &detect.env,
40fc51e3 1389 VARIANT_SSH, port, version, flags);
ef8d7ac4 1390 strvec_push(&detect.args, ssh_host);
0da0e49b
JN
1391
1392 variant = run_command(&detect) ? VARIANT_SIMPLE : VARIANT_SSH;
1393 }
1394
ef8d7ac4 1395 strvec_push(&conn->args, ssh);
29fda24d
ÆAB
1396 push_ssh_options(&conn->args, &conn->env, variant, port, version,
1397 flags);
ef8d7ac4 1398 strvec_push(&conn->args, ssh_host);
fce54ce4
JN
1399}
1400
cabc3c12 1401/*
8e349780
JN
1402 * This returns the dummy child_process `no_fork` if the transport protocol
1403 * does not need fork(2), or a struct child_process object if it does. Once
1404 * done, finish the connection with finish_connect() with the value returned
1405 * from this function (it is safe to call finish_connect() with NULL to
1406 * support the former case).
cabc3c12
JS
1407 *
1408 * If it returns, the connect is successful; it just dies on errors (this
1409 * will hopefully be changed in a libification effort, to return NULL when
1410 * the connection failed).
1411 */
1412struct child_process *git_connect(int fd[2], const char *url,
1413 const char *prog, int flags)
1414{
a2036d7e 1415 char *hostandport, *path;
8e349780 1416 struct child_process *conn;
cabc3c12 1417 enum protocol protocol;
40fc51e3 1418 enum protocol_version version = get_protocol_version_config();
cabc3c12 1419
1aa8dded
BW
1420 /*
1421 * NEEDSWORK: If we are trying to use protocol v2 and we are planning
1422 * to perform a push, then fallback to v0 since the client doesn't know
1423 * how to push yet using v2.
1424 */
1425 if (version == protocol_v2 && !strcmp("git-receive-pack", prog))
1426 version = protocol_v0;
1427
cabc3c12
JS
1428 /* Without this we cannot rely on waitpid() to tell
1429 * what happened to our children.
2e776665 1430 */
cabc3c12 1431 signal(SIGCHLD, SIG_DFL);
2e776665 1432
a2036d7e 1433 protocol = parse_connect_url(url, &hostandport, &path);
3f55ccab 1434 if ((flags & CONNECT_DIAG_URL) && (protocol != PROTO_SSH)) {
5610b7c0
TB
1435 printf("Diag: url=%s\n", url ? url : "NULL");
1436 printf("Diag: protocol=%s\n", prot_name(protocol));
a2036d7e 1437 printf("Diag: hostandport=%s\n", hostandport ? hostandport : "NULL");
5610b7c0 1438 printf("Diag: path=%s\n", path ? path : "NULL");
a2036d7e
TB
1439 conn = NULL;
1440 } else if (protocol == PROTO_GIT) {
40fc51e3 1441 conn = git_connect_git(fd, hostandport, path, prog, version, flags);
abd81a3d 1442 conn->trace2_child_class = "transport/git";
a2036d7e 1443 } else {
f1399291 1444 struct strbuf cmd = STRBUF_INIT;
0c2f0d27 1445 const char *const *var;
f1399291 1446
483bbd4e
RS
1447 conn = xmalloc(sizeof(*conn));
1448 child_process_init(conn);
a2036d7e 1449
aeeb2d49 1450 if (looks_like_command_line_option(path))
aad6fddb 1451 die(_("strange pathname '%s' blocked"), path);
aeeb2d49 1452
a2036d7e
TB
1453 strbuf_addstr(&cmd, prog);
1454 strbuf_addch(&cmd, ' ');
1455 sq_quote_buf(&cmd, path);
1456
aab40438 1457 /* remove repo-local variables from the environment */
0c2f0d27 1458 for (var = local_repo_env; *var; var++)
29fda24d 1459 strvec_push(&conn->env, *var);
0c2f0d27 1460
a48b409f 1461 conn->use_shell = 1;
a2036d7e 1462 conn->in = conn->out = -1;
a2036d7e 1463 if (protocol == PROTO_SSH) {
a2036d7e
TB
1464 char *ssh_host = hostandport;
1465 const char *port = NULL;
a5adaced 1466 transport_check_allowed("ssh");
a2036d7e 1467 get_host_and_port(&ssh_host, &port);
a2036d7e 1468
86ceb337
TB
1469 if (!port)
1470 port = get_port(ssh_host);
42da4840 1471
3f55ccab
TB
1472 if (flags & CONNECT_DIAG_URL) {
1473 printf("Diag: url=%s\n", url ? url : "NULL");
1474 printf("Diag: protocol=%s\n", prot_name(protocol));
1475 printf("Diag: userandhost=%s\n", ssh_host ? ssh_host : "NULL");
1476 printf("Diag: port=%s\n", port ? port : "NONE");
1477 printf("Diag: path=%s\n", path ? path : "NULL");
a2036d7e 1478
3f55ccab
TB
1479 free(hostandport);
1480 free(path);
04f20c04 1481 free(conn);
f1399291 1482 strbuf_release(&cmd);
3f55ccab 1483 return NULL;
37ee646e 1484 }
abd81a3d 1485 conn->trace2_child_class = "transport/ssh";
40fc51e3 1486 fill_ssh_args(conn, ssh_host, port, version, flags);
c049b61d 1487 } else {
a5adaced 1488 transport_check_allowed("file");
abd81a3d 1489 conn->trace2_child_class = "transport/file";
40fc51e3 1490 if (version > 0) {
29fda24d 1491 strvec_pushf(&conn->env,
f6d8942b
JK
1492 GIT_PROTOCOL_ENVIRONMENT "=version=%d",
1493 version);
0c2f0d27 1494 }
4852f723 1495 }
ef8d7ac4 1496 strvec_push(&conn->args, cmd.buf);
f364cb88 1497
a2036d7e 1498 if (start_command(conn))
aad6fddb 1499 die(_("unable to fork"));
f364cb88 1500
a2036d7e
TB
1501 fd[0] = conn->out; /* read from child's stdout */
1502 fd[1] = conn->in; /* write to child's stdin */
1503 strbuf_release(&cmd);
1504 }
1505 free(hostandport);
cabc3c12 1506 free(path);
98158e9c 1507 return conn;
f7192598
LT
1508}
1509
98158e9c 1510int finish_connect(struct child_process *conn)
f7192598 1511{
f364cb88 1512 int code;
7ffe853b 1513 if (!conn || git_connection_is_socket(conn))
f42a5c4e
FBH
1514 return 0;
1515
f364cb88 1516 code = finish_command(conn);
98158e9c 1517 free(conn);
f364cb88 1518 return code;
f7192598 1519}