From: Junio C Hamano Date: Mon, 27 Apr 2015 19:23:47 +0000 (-0700) Subject: Merge branch 'jc/push-cert' into maint X-Git-Tag: v2.3.7~3 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/631f6f1d47cc51a46c8ab48ea1178ea04cff0b8a?ds=inline;hp=-c Merge branch 'jc/push-cert' into maint The "git push --signed" protocol extension did not limit what the "nonce" that is a server-chosen string can contain or how long it can be, which was unnecessarily lax. Limit both the length and the alphabet to a reasonably small space that can still have enough entropy. * jc/push-cert: push --signed: tighten what the receiving end can ask to sign --- 631f6f1d47cc51a46c8ab48ea1178ea04cff0b8a diff --combined send-pack.c index 25947d7df9,2249808027..677bac3193 --- a/send-pack.c +++ b/send-pack.c @@@ -47,9 -47,8 +47,9 @@@ static int pack_objects(int fd, struct NULL, NULL, NULL, + NULL, }; - struct child_process po; + struct child_process po = CHILD_PROCESS_INIT; int i; i = 4; @@@ -61,8 -60,7 +61,8 @@@ argv[i++] = "-q"; if (args->progress) argv[i++] = "--progress"; - memset(&po, 0, sizeof(po)); + if (is_repository_shallow()) + argv[i++] = "--shallow"; po.argv = argv; po.in = -1; po.out = args->stateless_rpc ? -1 : fd; @@@ -234,15 -232,15 +234,15 @@@ static int generate_push_cert(struct st const char *push_cert_nonce) { const struct ref *ref; - char stamp[60]; char *signing_key = xstrdup(get_signing_key()); const char *cp, *np; struct strbuf cert = STRBUF_INIT; int update_seen = 0; - datestamp(stamp, sizeof(stamp)); strbuf_addf(&cert, "certificate version 0.1\n"); - strbuf_addf(&cert, "pusher %s %s\n", signing_key, stamp); + strbuf_addf(&cert, "pusher %s ", signing_key); + datestamp(&cert); + strbuf_addch(&cert, '\n'); if (args->url && *args->url) { char *anon_url = transport_anonymize_url(args->url); strbuf_addf(&cert, "pushee %s\n", anon_url); @@@ -281,6 -279,28 +281,28 @@@ free_return return update_seen; } + #define NONCE_LEN_LIMIT 256 + + static void reject_invalid_nonce(const char *nonce, int len) + { + int i = 0; + + if (NONCE_LEN_LIMIT <= len) + die("the receiving end asked to sign an invalid nonce <%.*s>", + len, nonce); + + for (i = 0; i < len; i++) { + int ch = nonce[i] & 0xFF; + if (isalnum(ch) || + ch == '-' || ch == '.' || + ch == '/' || ch == '+' || + ch == '=' || ch == '_') + continue; + die("the receiving end asked to sign an invalid nonce <%.*s>", + len, nonce); + } + } + int send_pack(struct send_pack_args *args, int fd[], struct child_process *conn, struct ref *remote_refs, @@@ -323,6 -343,7 +345,7 @@@ push_cert_nonce = server_feature_value("push-cert", &len); if (!push_cert_nonce) die(_("the receiving end does not support --signed push")); + reject_invalid_nonce(push_cert_nonce, len); push_cert_nonce = xmemdupz(push_cert_nonce, len); }