From: Brandon Williams <bmwill@google.com>
To: git@vger.kernel.org
Cc: peff@peff.net, jrnieder@gmail.com, sbeller@google.com,
gitster@pobox.com, jonathantanmy@google.com,
Brandon Williams <bmwill@google.com>
Subject: [RFC 3/7] protocol: tell server that the client understands v2
Date: Thu, 24 Aug 2017 15:53:24 -0700 [thread overview]
Message-ID: <20170824225328.8174-4-bmwill@google.com> (raw)
In-Reply-To: <20170824225328.8174-1-bmwill@google.com>
Teach the connection logic to tell a serve that it understands protocol
v2. This is done in 2 different ways for the built in protocols.
1. git://
A normal request is structured as "command path/to/repo\0host=..\0"
and due to a bug in an old version of git-daemon 73bb33a94 (daemon:
Strictly parse the "extra arg" part of the command, 2009-06-04) we
aren't able to place any extra args (separated by NULs) besides the
host. In order to get around this limitation put protocol version
information after a second NUL byte so the request is structured
like: "command path/to/repo\0host=..\0\0version=2\0". git-daemon can
then parse out the version number and set GIT_PROTOCOL.
2. ssh://, file://
Set GIT_PROTOCOL envvar with the desired protocol version. The
envvar can be sent across ssh by using '-o SendEnv=GIT_PROTOCOL' and
having the server whitelist this envvar.
Signed-off-by: Brandon Williams <bmwill@google.com>
---
connect.c | 31 ++++++++++++++++++++++++++-----
daemon.c | 28 +++++++++++++++++++++++++---
2 files changed, 51 insertions(+), 8 deletions(-)
diff --git a/connect.c b/connect.c
index 49b28b83b..d609267be 100644
--- a/connect.c
+++ b/connect.c
@@ -793,6 +793,7 @@ struct child_process *git_connect(int fd[2], const char *url,
printf("Diag: path=%s\n", path ? path : "NULL");
conn = NULL;
} else if (protocol == PROTO_GIT) {
+ struct strbuf request = STRBUF_INIT;
/*
* Set up virtual host information based on where we will
* connect, unless the user has overridden us in
@@ -820,12 +821,23 @@ struct child_process *git_connect(int fd[2], const char *url,
* Note: Do not add any other headers here! Doing so
* will cause older git-daemon servers to crash.
*/
- packet_write_fmt(fd[1],
- "%s %s%chost=%s%c",
- prog, path, 0,
- target_host, 0);
+ 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 */
+ strbuf_addch(&request, '\0');
+ strbuf_addf(&request, "version=%d%c", 2, '\0');
+ /* subsequent supported versions can also be added */
+ strbuf_addf(&request, "version=%d%c", 3, '\0');
+
+ packet_write(fd[1], request.buf, request.len);
+
free(target_host);
+ strbuf_release(&request);
} else {
+ const char *const *var;
conn = xmalloc(sizeof(*conn));
child_process_init(conn);
@@ -837,7 +849,9 @@ struct child_process *git_connect(int fd[2], const char *url,
sq_quote_buf(&cmd, path);
/* remove repo-local variables from the environment */
- conn->env = local_repo_env;
+ for (var = local_repo_env; *var; var++)
+ argv_array_push(&conn->env_array, *var);
+
conn->use_shell = 1;
conn->in = conn->out = -1;
if (protocol == PROTO_SSH) {
@@ -890,6 +904,12 @@ struct child_process *git_connect(int fd[2], const char *url,
}
argv_array_push(&conn->args, ssh);
+
+ /* protocol v2! */
+ argv_array_push(&conn->args, "-o");
+ argv_array_push(&conn->args, "SendEnv=GIT_PROTOCOL");
+ argv_array_push(&conn->env_array, "GIT_PROTOCOL=2");
+
if (flags & CONNECT_IPV4)
argv_array_push(&conn->args, "-4");
else if (flags & CONNECT_IPV6)
@@ -904,6 +924,7 @@ struct child_process *git_connect(int fd[2], const char *url,
argv_array_push(&conn->args, ssh_host);
} else {
transport_check_allowed("file");
+ argv_array_push(&conn->env_array, "GIT_PROTOCOL=2");
}
argv_array_push(&conn->args, cmd.buf);
diff --git a/daemon.c b/daemon.c
index 30747075f..76a7b2d64 100644
--- a/daemon.c
+++ b/daemon.c
@@ -574,7 +574,7 @@ static void canonicalize_client(struct strbuf *out, const char *in)
/*
* Read the host as supplied by the client connection.
*/
-static void parse_host_arg(struct hostinfo *hi, char *extra_args, int buflen)
+static char *parse_host_arg(struct hostinfo *hi, char *extra_args, int buflen)
{
char *val;
int vallen;
@@ -602,6 +602,22 @@ static void parse_host_arg(struct hostinfo *hi, char *extra_args, int buflen)
if (extra_args < end && *extra_args)
die("Invalid request");
}
+
+ return extra_args;
+}
+
+static void parse_extra_args(const char *extra_args, int buflen)
+{
+ const char *end = extra_args + buflen;
+
+ for (; extra_args < end; extra_args += strlen(extra_args) + 1) {
+ const char *arg = extra_args;
+ if (skip_prefix(arg, "version=", &arg))
+ fprintf(stderr, "VERSION=%s\n", arg);
+
+ fprintf(stderr, "%s\n", extra_args);
+
+ }
}
/*
@@ -716,8 +732,14 @@ static int execute(void)
pktlen--;
}
- if (len != pktlen)
- parse_host_arg(&hi, line + len + 1, pktlen - len - 1);
+ if (len != pktlen) {
+ const char *extra_args;
+ /* retreive host */
+ extra_args = parse_host_arg(&hi, line + len + 1, pktlen - len - 1);
+
+ /* determine version */
+ parse_extra_args(extra_args + 1, pktlen - (extra_args - line) - 1);
+ }
for (i = 0; i < ARRAY_SIZE(daemon_service); i++) {
struct daemon_service *s = &(daemon_service[i]);
--
2.14.1.342.g6490525c54-goog
next prev parent reply other threads:[~2017-08-24 22:54 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-24 22:53 [RFC 0/7] transitioning to protocol v2 Brandon Williams
2017-08-24 22:53 ` [RFC 1/7] pkt-line: add packet_write function Brandon Williams
2017-08-24 22:53 ` [RFC 2/7] pkt-line: add strbuf_packet_read Brandon Williams
2017-08-24 22:53 ` Brandon Williams [this message]
2017-08-25 17:45 ` [RFC 3/7] protocol: tell server that the client understands v2 Junio C Hamano
2017-08-25 18:53 ` Brandon Williams
2017-08-25 18:55 ` Brandon Williams
2017-08-24 22:53 ` [RFC 4/7] t: fix ssh tests to cope with using '-o SendEnv=GIT_PROTOCOL' Brandon Williams
2017-08-24 22:53 ` [RFC 5/7] http: send Git-Protocol-Version header Brandon Williams
2017-08-30 10:55 ` Kevin Daudt
2017-08-24 22:53 ` [RFC 6/7] transport: teach client to recognize v2 server response Brandon Williams
2017-08-24 22:53 ` [RFC 7/7] upload-pack: ack version 2 Brandon Williams
2017-09-01 22:02 ` Bryan Turner
2017-09-01 23:20 ` Brandon Williams
2017-08-25 1:19 ` [RFC 0/7] transitioning to protocol v2 Junio C Hamano
2017-08-25 17:07 ` Stefan Beller
2017-08-25 17:14 ` Junio C Hamano
2017-08-25 17:36 ` Jeff King
2017-08-25 17:29 ` Jeff King
2017-08-25 17:35 ` Jonathan Nieder
2017-08-25 17:41 ` Jeff King
2017-08-25 18:50 ` Brandon Williams
2017-08-29 20:08 ` Jeff Hostetler
2017-08-29 21:10 ` Brandon Williams
2017-08-30 3:06 ` Jeff King
2017-08-30 13:30 ` Jeff Hostetler
2017-08-30 16:54 ` Brandon Williams
2017-08-25 17:48 ` Junio C Hamano
2017-08-30 20:38 ` Bryan Turner
2017-08-30 21:12 ` Brandon Williams
2017-09-01 23:06 ` Bryan Turner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170824225328.8174-4-bmwill@google.com \
--to=bmwill@google.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jonathantanmy@google.com \
--cc=jrnieder@gmail.com \
--cc=peff@peff.net \
--cc=sbeller@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).