static int sent_capabilities;
static int shallow_update;
static const char *alt_shallow_file;
+static int accept_push_cert = 1;
+static struct strbuf push_cert = STRBUF_INIT;
+static unsigned char push_cert_sha1[20];
static enum deny_action parse_deny_action(const char *var, const char *value)
{
return 0;
}
+ if (strcmp(var, "receive.acceptpushcert") == 0) {
+ accept_push_cert = git_config_bool(var, value);
+ return 0;
+ }
+
return git_default_config(var, value, cb);
}
"report-status delete-refs side-band-64k quiet");
if (prefer_ofs_delta)
strbuf_addstr(&cap, " ofs-delta");
+ if (accept_push_cert)
+ strbuf_addstr(&cap, " push-cert");
strbuf_addf(&cap, " agent=%s", git_user_agent_sanitized());
packet_write(1, "%s %s%c%s\n",
sha1_to_hex(sha1), path, 0, cap.buf);
return 0;
}
+static void prepare_push_cert_sha1(struct child_process *proc)
+{
+ static int already_done;
+ struct argv_array env = ARGV_ARRAY_INIT;
+
+ if (!push_cert.len)
+ return;
+
+ if (!already_done) {
+ already_done = 1;
+ if (write_sha1_file(push_cert.buf, push_cert.len, "blob", push_cert_sha1))
+ hashclr(push_cert_sha1);
+ }
+ if (!is_null_sha1(push_cert_sha1)) {
+ argv_array_pushf(&env, "GIT_PUSH_CERT=%s", sha1_to_hex(push_cert_sha1));
+ proc->env = env.argv;
+ }
+}
+
typedef int (*feed_fn)(void *, const char **, size_t *);
static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_state)
{
proc.in = -1;
proc.stdout_to_stderr = 1;
+ prepare_push_cert_sha1(&proc);
+
if (use_sideband) {
memset(&muxer, 0, sizeof(muxer));
muxer.proc = copy_to_sideband;
quiet = 1;
}
+ if (!strcmp(line, "push-cert")) {
+ int true_flush = 0;
+ char certbuf[1024];
+
+ for (;;) {
+ len = packet_read(0, NULL, NULL,
+ certbuf, sizeof(certbuf), 0);
+ if (!len) {
+ true_flush = 1;
+ break;
+ }
+ if (!strcmp(certbuf, "push-cert-end\n"))
+ break; /* end of cert */
+ strbuf_addstr(&push_cert, certbuf);
+ }
+
+ if (true_flush)
+ break;
+ continue;
+ }
+
p = queue_command(p, line, linelen);
}
return commands;