Re: [PATCH 2/2] push -s: skeleton
- From
Shawn Pearce <spearce@spearce.org>
- Date
- Sep 7, 2011, 21:18 UTC
- Message-ID
- <CAJo=hJtz6fa4XfC-4ghryP_nfg3sbcrE2bKauj+F7w2Z_8Ckvw@mail.gmail.com>
- In-Reply-To
- <7vbouw2hqg.fsf@alter.siamese.dyndns.org>
On Wed, Sep 7, 2011 at 13:57, Junio C Hamano <gitster@pobox.com> wrote:
Show 14 quoted lines
> If a tag is GPG-signed, and if you trust the cryptographic robustness of > the SHA-1 and GPG, you can guarantee that all the history leading to the > signed commit is not tampered with. However, it would be both cumbersome > and cluttering to sign each and every commit. Especially if you strive to > keep your history clean by tweaking, rewriting and polishing your commits > before pushing the resulting history out, many commits you will create > locally end up not mattering at all, and it is a waste of time to sign > them. > > A better alternative could be to sign a "push certificate" (for the lack > of better name) every time you push, asserting that what commits you are > pushing to update which refs. The basic workflow goes like this: > > 1. You push out your work with "git push -s";
Yay!
> And here is a skeleton to implement it. It has all the necessary protocol > extensions implemented (although I do not know if we need separate > codepath for stateless RPC mode), but does not have subroutines to:
Yea, its broken for stateless RPC. See below.
Show 5 quoted lines
> +static char *receive_push_certificate(void)
> +{
> + struct strbuf cert = STRBUF_INIT;
> + for (;;) {
> + char line[1000];1000 isn't enough for some certificates. Imagine pushing a Gerrit Code Review managed repository with 2M worth of advertisement data at once. You can't sign that in 1000 bytes.
Show 18 quoted lines
> @@ -326,6 +366,23 @@ int send_pack(struct send_pack_args *args,
> safe_write(out, req_buf.buf, req_buf.len);
> packet_flush(out);
> }
> +
> + if (signed_push) {
> + char *cp, *ep;
> +
> + sign_push_certificate(&push_cert);
> + strbuf_reset(&req_buf);
> + for (cp = push_cert.buf; *cp; cp = ep) {
> + ep = strchrnul(cp, '\n');
> + if (*ep == '\n')
> + ep++;
> + packet_buf_write(&req_buf, "%.*s",
> + (int)(ep - cp), cp);
> + }
> + /* Do we need anything funky for stateless rpc? */Yes. Above we flushed the req_buf and send that in an HTTP request. You need to hoist this block above the "if (args->stateless_rpc)" segment.
-- Shawn.