{"thread":{"id":"29295","subject":"[PATCH 1/3] verify_signed_buffer: fix stale comment","startedAt":"2012-01-04T22:10:55Z","lastAt":"2012-01-05T00:30:43Z","messageCount":7,"participants":["Junio C Hamano","Linus Torvalds"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"181944","messageId":"1325715058-11984-1-git-send-email-gitster@pobox.com","threadId":"29295","inReplyTo":null,"subject":"[PATCH 0/3] More on pulling signed tags","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-01-04T22:10:55Z","receivedAt":"2012-01-04T22:10:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This extends on the earlier topic to pull and merge signed tags. So far,\nwe did record them for later auditing, but did not have an easy way to\nperform the auditing, other than manually extracting the information from\nthe commit object.\n\nApplies on top of the merge between the current 'master' and the\n'jc/signed-commit' topic still in 'next', as the latter topic already has\nnecessary infrastructure to hook into the \"log\" machinery to show the\nsignatures embedded in commit objects with the \"--show-signature\" option.\n\nHelp on adding tests, docs and tying loose ends are very much appreciated.\n\nA sample workflow with the command may look like this:\n\n  $ git checkout v1.7.8^0\n  $ git pull $elsewhere v1.7.8.2\n  $ git show -s --show-signature\n  commit e00ee29c760ae27c177ec16adb8c94b85909f464\n  parent #2, tagged 'v1.7.8.2'\n  gpg: Signature made Wed 28 Dec 2011 12:03:39 PM PST using RSA key ID 96AFE6CB\n  gpg: Good signature from \"Junio C Hamano <gitster@pobox.com>\"\n  gpg:                 aka \"Junio C Hamano <junio@pobox.com>\"\n  gpg:                 aka \"Junio C Hamano <jch@google.com>\"\n  Merge: 406da78 f3f778d\n  Author: Junio C Hamano <gitster@pobox.com>\n  Date:   Wed Jan 4 14:05:03 2012 -0800\n\n      Merge tag 'v1.7.8.2' of ../git into HEAD\n\n      Git 1.7.8.2\n  $ git commit -S --amend --no-edit\n  commit df409f0d0b1f3f521dd0fd2baf6ecf01495c0191\n  gpg: Signature made Wed 04 Jan 2012 02:05:26 PM PST using RSA key ID 96AFE6CB\n  gpg: Good signature from \"Junio C Hamano <gitster@pobox.com>\"\n  gpg:                 aka \"Junio C Hamano <junio@pobox.com>\"\n  gpg:                 aka \"Junio C Hamano <jch@google.com>\"\n  parent #2, tagged 'v1.7.8.2'\n  gpg: Signature made Wed 28 Dec 2011 12:03:39 PM PST using RSA key ID 96AFE6CB\n  gpg: Good signature from \"Junio C Hamano <gitster@pobox.com>\"\n  gpg:                 aka \"Junio C Hamano <junio@pobox.com>\"\n  gpg:                 aka \"Junio C Hamano <jch@google.com>\"\n  Merge: 406da78 f3f778d\n  Author: Junio C Hamano <gitster@pobox.com>\n  Date:   Wed Jan 4 14:05:03 2012 -0800\n\n      Merge tag 'v1.7.8.2' of ../git into HEAD\n\n      Git 1.7.8.2\n\nJunio C Hamano (3):\n  verify_signed_buffer: fix stale comment\n  log-tree.c: small refactor in show_signature()\n  log-tree: show mergetag in log --show-signature output\n\n gpg-interface.c |    5 +--\n log-tree.c      |  104 ++++++++++++++++++++++++++++++++++++++++++++++++-------\n 2 files changed, 92 insertions(+), 17 deletions(-)\n\n-- \n1.7.8.2.340.gd18f0f\n"},{"id":"181942","messageId":"1325715058-11984-2-git-send-email-gitster@pobox.com","threadId":"29295","inReplyTo":"1325715058-11984-1-git-send-email-gitster@pobox.com","subject":"[PATCH 1/3] verify_signed_buffer: fix stale comment","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-01-04T22:10:56Z","receivedAt":"2012-01-04T22:10:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The function used to take an integer flag to specify where the output\nshould go, but these days we supply a strbuf to receive it.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n gpg-interface.c |    5 +----\n 1 files changed, 1 insertions(+), 4 deletions(-)\n\ndiff --git a/gpg-interface.c b/gpg-interface.c\nindex 18630ff..09ab64a 100644\n--- a/gpg-interface.c\n+++ b/gpg-interface.c\n@@ -95,10 +95,7 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig\n \n /*\n  * Run \"gpg\" to see if the payload matches the detached signature.\n- * gpg_output_to tells where the output from \"gpg\" should go:\n- *   < 0: /dev/null\n- *   = 0: standard error of the calling process\n- *   > 0: the specified file descriptor\n+ * gpg_output, when set, receives the diagnostic output from GPG.\n  */\n int verify_signed_buffer(const char *payload, size_t payload_size,\n \t\t\t const char *signature, size_t signature_size,\n-- \n1.7.8.2.340.gd18f0f\n"},{"id":"181943","messageId":"1325715058-11984-3-git-send-email-gitster@pobox.com","threadId":"29295","inReplyTo":"1325715058-11984-1-git-send-email-gitster@pobox.com","subject":"[PATCH 2/3] log-tree.c: small refactor in show_signature()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-01-04T22:10:57Z","receivedAt":"2012-01-04T22:10:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"The next patch needs to show the result of signature verification on a\nmergetag extended header in a way similar to how embedded signature for\nthe commit object itself is shown. Separate out the logic to go through\nthe message lines and show them in the \"error\" color (highlighted) or the\n\"correct\" color (dim).\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n log-tree.c |   28 ++++++++++++++++------------\n 1 files changed, 16 insertions(+), 12 deletions(-)\n\ndiff --git a/log-tree.c b/log-tree.c\nindex 142ba51..005c5a5 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -404,13 +404,27 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,\n \t*extra_headers_p = extra_headers;\n }\n \n+static void show_sig_lines(struct rev_info *opt, int status, const char *bol)\n+{\n+\tconst char *color, *reset, *eol;\n+\n+\tcolor = diff_get_color_opt(&opt->diffopt,\n+\t\t\t\t   status ? DIFF_WHITESPACE : DIFF_FRAGINFO);\n+\treset = diff_get_color_opt(&opt->diffopt, DIFF_RESET);\n+\twhile (*bol) {\n+\t\teol = strchrnul(bol, '\\n');\n+\t\tprintf(\"%s%.*s%s%s\", color, (int)(eol - bol), bol, reset,\n+\t\t       *eol ? \"\\n\" : \"\");\n+\t\tbol = (*eol) ? (eol + 1) : eol;\n+\t}\n+}\n+\n static void show_signature(struct rev_info *opt, struct commit *commit)\n {\n \tstruct strbuf payload = STRBUF_INIT;\n \tstruct strbuf signature = STRBUF_INIT;\n \tstruct strbuf gpg_output = STRBUF_INIT;\n \tint status;\n-\tconst char *color, *reset, *bol, *eol;\n \n \tif (parse_signed_commit(commit->object.sha1, &payload, &signature) <= 0)\n \t\tgoto out;\n@@ -421,17 +435,7 @@ static void show_signature(struct rev_info *opt, struct commit *commit)\n \tif (status && !gpg_output.len)\n \t\tstrbuf_addstr(&gpg_output, \"No signature\\n\");\n \n-\tcolor = diff_get_color_opt(&opt->diffopt,\n-\t\t\t\t   status ? DIFF_WHITESPACE : DIFF_FRAGINFO);\n-\treset = diff_get_color_opt(&opt->diffopt, DIFF_RESET);\n-\n-\tbol = gpg_output.buf;\n-\twhile (*bol) {\n-\t\teol = strchrnul(bol, '\\n');\n-\t\tprintf(\"%s%.*s%s%s\", color, (int)(eol - bol), bol, reset,\n-\t\t       *eol ? \"\\n\" : \"\");\n-\t\tbol = (*eol) ? (eol + 1) : eol;\n-\t}\n+\tshow_sig_lines(opt, status, gpg_output.buf);\n \n  out:\n \tstrbuf_release(&gpg_output);\n-- \n1.7.8.2.340.gd18f0f\n"},{"id":"181945","messageId":"1325715058-11984-4-git-send-email-gitster@pobox.com","threadId":"29295","inReplyTo":"1325715058-11984-1-git-send-email-gitster@pobox.com","subject":"[PATCH 3/3] log-tree: show mergetag in log --show-signature output","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-01-04T22:10:58Z","receivedAt":"2012-01-04T22:10:58Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"A commit object that merges a signed tag records the \"mergetag\" extended\nheader. Check the validity of the GPG signature on it, and show it in a\nway similar to how \"gpgsig\" extended header is shown.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n log-tree.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n 1 files changed, 75 insertions(+), 1 deletions(-)\n\ndiff --git a/log-tree.c b/log-tree.c\nindex 005c5a5..b87dd53 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -443,6 +443,78 @@ static void show_signature(struct rev_info *opt, struct commit *commit)\n \tstrbuf_release(&signature);\n }\n \n+static int which_parent(const unsigned char *sha1, const struct commit *commit)\n+{\n+\tint nth;\n+\tconst struct commit_list *parent;\n+\n+\tfor (nth = 0, parent = commit->parents; parent; parent = parent->next) {\n+\t\tif (!hashcmp(parent->item->object.sha1, sha1))\n+\t\t\treturn nth;\n+\t\tnth++;\n+\t}\n+\treturn -1;\n+}\n+\n+static void show_one_mergetag(struct rev_info *opt,\n+\t\t\t      struct commit_extra_header *extra,\n+\t\t\t      struct commit *commit)\n+{\n+\tunsigned char sha1[20];\n+\tstruct tag *tag;\n+\tstruct strbuf verify_message;\n+\tint status, nth;\n+\tsize_t payload_size, gpg_message_offset;\n+\n+\thash_sha1_file(extra->value, extra->len, typename(OBJ_TAG), sha1);\n+\ttag = lookup_tag(sha1);\n+\tif (!tag)\n+\t\treturn; /* error message already given */\n+\n+\tstrbuf_init(&verify_message, 256);\n+\tif (parse_tag_buffer(tag, extra->value, extra->len))\n+\t\tstrbuf_addstr(&verify_message, \"malformed mergetag\\n\");\n+\telse if ((nth = which_parent(tag->tagged->sha1, commit)) < 0)\n+\t\tstrbuf_addf(&verify_message, \"tag %s names a non-parent %s\\n\",\n+\t\t\t\t    tag->tag, tag->tagged->sha1);\n+\telse\n+\t\tstrbuf_addf(&verify_message,\n+\t\t\t    \"parent #%d, tagged '%s'\\n\", nth + 1, tag->tag);\n+\tgpg_message_offset = verify_message.len;\n+\n+\tpayload_size = parse_signature(extra->value, extra->len);\n+\tif ((extra->len <= payload_size) ||\n+\t    (verify_signed_buffer(extra->value, payload_size,\n+\t\t\t\t  extra->value + payload_size,\n+\t\t\t\t  extra->len - payload_size,\n+\t\t\t\t  &verify_message) &&\n+\t     verify_message.len <= gpg_message_offset)) {\n+\t\tstrbuf_addstr(&verify_message, \"No signature\\n\");\n+\t\tstatus = -1;\n+\t}\n+\telse if (strstr(verify_message.buf + gpg_message_offset,\n+\t\t\t\": Good signature from \"))\n+\t\tstatus = 0;\n+\telse\n+\t\tstatus = -1;\n+\n+\tshow_sig_lines(opt, status, verify_message.buf);\n+\tstrbuf_release(&verify_message);\n+}\n+\n+static void show_mergetag(struct rev_info *opt, struct commit *commit)\n+{\n+\tstruct commit_extra_header *extra, *to_free;\n+\n+\tto_free = read_commit_extra_headers(commit);\n+\tfor (extra = to_free; extra; extra = extra->next) {\n+\t\tif (strcmp(extra->key, \"mergetag\"))\n+\t\t\tcontinue; /* not a merge tag */\n+\t\tshow_one_mergetag(opt, extra, commit);\n+\t}\n+\tfree_commit_extra_headers(to_free);\n+}\n+\n void show_log(struct rev_info *opt)\n {\n \tstruct strbuf msgbuf = STRBUF_INIT;\n@@ -554,8 +626,10 @@ void show_log(struct rev_info *opt)\n \t\t}\n \t}\n \n-\tif (opt->show_signature)\n+\tif (opt->show_signature) {\n \t\tshow_signature(opt, commit);\n+\t\tshow_mergetag(opt, commit);\n+\t}\n \n \tif (!commit->buffer)\n \t\treturn;\n-- \n1.7.8.2.340.gd18f0f\n"},{"id":"181952","messageId":"7vsjjvnh4e.fsf@alter.siamese.dyndns.org","threadId":"29295","inReplyTo":"1325715058-11984-1-git-send-email-gitster@pobox.com","subject":"Re: [PATCH 0/3] More on pulling signed tags","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-01-05T00:10:57Z","receivedAt":"2012-01-05T00:10:57Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> A sample workflow with the command may look like this:\n> ...\n>   $ git show -s --show-signature\n\nWith this, in the Linux kernel repository, you could do this.\n\n    $ git show -s --show-signature 2240a7bb47\n    commit 2240a7bb479c38434bd636da9ce6afbd3f49447a\n    parent #2, tagged 'tytso-for-linus-20111214'\n    gpg: Signature made Wed 14 Dec 2011 11:15:13 AM PST using RSA key ID C11804F0\n    gpg: Good signature from \"Theodore Ts'o <tytso@mit.edu>\"\n    gpg:                 aka \"Theodore Ts'o <tytso@debian.org>\"\n    gpg:                 aka \"Theodore Ts'o <tytso@google.com>\"\n    Merge: 30aaca4 5a0dc73\n    Author: Linus Torvalds <torvalds@linux-foundation.org>\n    Date:   Wed Dec 14 18:25:58 2011 -0800\n\n        Merge tag 'tytso-for-linus-20111214' of git://git.kernel.org/pub/scm/linu...\n\n        * tag 'tytso-for-linus-20111214' of git://git.kernel.org/pub/scm/linux/ke...\n\n      8< snip 8<\n\n        .. using the new signed tag merge of git that now verifies the gpg\n        signature automatically.  Yay.  The branchname was just 'dev', which is\n        prettier.  I'll tell Ted to use nicer tag names for future cases.\n\nWe might want to reword \"parent #2\", by the way. The code was designed to\napply even to an Octopus, but I suspect 99.9% of the mergetag will be on\nthe second parent of a two-parent commit. You will never see \"parent #1\"\n(i.e. direct parent you pulled into) unless you hand-craft the merge\ncommit object, and you are not likely to create an Octopus that pulls\nmultiple signed tags into one commit.\n"},{"id":"181954","messageId":"7vobujngl3.fsf@alter.siamese.dyndns.org","threadId":"29295","inReplyTo":"7vsjjvnh4e.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 0/3] More on pulling signed tags","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-01-05T00:22:32Z","receivedAt":"2012-01-05T00:22:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> We might want to reword \"parent #2\", by the way. The code was designed to\n> apply even to an Octopus, but I suspect 99.9% of the mergetag will be on\n> the second parent of a two-parent commit. You will never see \"parent #1\"\n> (i.e. direct parent you pulled into) unless you hand-craft the merge\n> commit object, and you are not likely to create an Octopus that pulls\n> multiple signed tags into one commit.\n\n... and this is a fix-up patch on top of the series. With this, the output\nbecomes like this:\n\n  commit 2240a7bb479c38434bd636da9ce6afbd3f49447a\n  merged tag 'tytso-for-linus-20111214'\n  gpg: Signature made Wed 14 Dec 2011 11:15:13 AM PST using RSA key ID C11804F0\n  gpg: Good signature from \"Theodore Ts'o <tytso@mit.edu>\"\n  gpg:                 aka \"Theodore Ts'o <tytso@debian.org>\"\n  gpg:                 aka \"Theodore Ts'o <tytso@google.com>\"\n  Merge: 30aaca4 5a0dc73\n  Author: Linus Torvalds <torvalds@linux-foundation.org>\n  Date:   Wed Dec 14 18:25:58 2011 -0800\n\n      Merge tag 'tytso-for-linus-20111214' of git://git.kernel.org/pub/scm/l...\n\n      * tag 'tytso-for-linus-20111214' of git://git.kernel.org/pub/scm/linux...\n        ext4: handle EOF correctly in ext4_bio_write_page()\n       ...\n\n\n log-tree.c |   12 ++++++++++++\n 1 files changed, 12 insertions(+), 0 deletions(-)\n\ndiff --git a/log-tree.c b/log-tree.c\nindex b87dd53..37510da 100644\n--- a/log-tree.c\n+++ b/log-tree.c\n@@ -456,6 +456,13 @@ static int which_parent(const unsigned char *sha1, const struct commit *commit)\n \treturn -1;\n }\n \n+static int is_common_merge(const struct commit *commit)\n+{\n+\treturn (commit->parents\n+\t\t&& commit->parents->next\n+\t\t&& !commit->parents->next->next);\n+}\n+\n static void show_one_mergetag(struct rev_info *opt,\n \t\t\t      struct commit_extra_header *extra,\n \t\t\t      struct commit *commit)\n@@ -474,6 +481,11 @@ static void show_one_mergetag(struct rev_info *opt,\n \tstrbuf_init(&verify_message, 256);\n \tif (parse_tag_buffer(tag, extra->value, extra->len))\n \t\tstrbuf_addstr(&verify_message, \"malformed mergetag\\n\");\n+\telse if (is_common_merge(commit) &&\n+\t\t !hashcmp(tag->tagged->sha1,\n+\t\t\t  commit->parents->next->item->object.sha1))\n+\t\tstrbuf_addf(&verify_message,\n+\t\t\t    \"merged tag '%s'\\n\", tag->tag);\n \telse if ((nth = which_parent(tag->tagged->sha1, commit)) < 0)\n \t\tstrbuf_addf(&verify_message, \"tag %s names a non-parent %s\\n\",\n \t\t\t\t    tag->tag, tag->tagged->sha1);\n"},{"id":"181956","messageId":"CA+55aFxuHjADrnT4METD=JRqhO0L1tKv=_pB9aOODbokM7rd-g@mail.gmail.com","threadId":"29295","inReplyTo":"7vobujngl3.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH 0/3] More on pulling signed tags","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2012-01-05T00:30:43Z","receivedAt":"2012-01-05T00:30:43Z","isPatch":true,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"On Wed, Jan 4, 2012 at 4:22 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>\n> ... and this is a fix-up patch on top of the series. With this, the output\n> becomes like this:\n\nLooking good, this is very useful. The hacks to extract the signatures\nwith 'git cat-file' were pretty ugly.\n\nThis is also nice for the case where the person doing the merge\ndoesn't yet have the pgp key something was signed with, so when you do\nthe \"git pull\", you get the \"unknown key\" thing instead of a \"good\nsignature\" message in the editor buffer.\n\nIt *used* to be the case that you had to abort the merge, fetch the\nkey, and re-pull in order to verify the key.\n\nNow you can just say \"ok, I'll commit the merge\" and finish up, then\nfetch the key, do \"git show --show-signature\", and if it doesn't show\nup as good (which would be very rare) you can then 'git reset'\ninstead.  Which while less anal, is a lot more convenient.\n\n                    Linus\n"}]}