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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.