summaryrefslogtreecommitdiff
path: root/builtin/receive-pack.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2014-08-18 14:38:45 -0700
committerJunio C Hamano <gitster@pobox.com>2014-09-15 13:23:28 -0700
commit4adf569dea052dac88121d822e11c249986b3398 (patch)
tree5394494825d8283628dce7efa1b07320b8db1e25 /builtin/receive-pack.c
parent20a7558f31e44e26ddbb8aa55bfd9316a6b67f82 (diff)
downloadgit-4adf569dea052dac88121d822e11c249986b3398.tar.gz
signed push: remove duplicated protocol info
With the interim protocol, we used to send the update commands even though we already send a signed copy of the same information when push certificate is in use. Update the send-pack/receive-pack pair not to do so. The notable thing on the receive-pack side is that it makes sure that there is no command sent over the traditional protocol packet outside the push certificate. Otherwise a pusher can claim to be pushing one set of ref updates in the signed certificate while issuing commands to update unrelated refs, and such an update will evade later audits. Finally, start documenting the protocol. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin/receive-pack.c')
-rw-r--r--builtin/receive-pack.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
index c0a3189943..431af39335 100644
--- a/builtin/receive-pack.c
+++ b/builtin/receive-pack.c
@@ -926,6 +926,28 @@ static struct command **queue_command(struct command **tail,
return &cmd->next;
}
+static void queue_commands_from_cert(struct command **tail,
+ struct strbuf *push_cert)
+{
+ const char *boc, *eoc;
+
+ if (*tail)
+ die("protocol error: got both push certificate and unsigned commands");
+
+ boc = strstr(push_cert->buf, "\n\n");
+ if (!boc)
+ die("malformed push certificate %.*s", 100, push_cert->buf);
+ else
+ boc += 2;
+ eoc = push_cert->buf + parse_signature(push_cert->buf, push_cert->len);
+
+ while (boc < eoc) {
+ const char *eol = memchr(boc, '\n', eoc - boc);
+ tail = queue_command(tail, boc, eol ? eol - boc : eoc - eol);
+ boc = eol ? eol + 1 : eoc;
+ }
+}
+
static struct command *read_head_info(struct sha1_array *shallow)
{
struct command *commands = NULL;
@@ -981,6 +1003,10 @@ static struct command *read_head_info(struct sha1_array *shallow)
p = queue_command(p, line, linelen);
}
+
+ if (push_cert.len)
+ queue_commands_from_cert(p, &push_cert);
+
return commands;
}