{"thread":{"id":"17919","subject":"[PATCH] git-tag: don't use gpg's stdin, stdout when signing tags","startedAt":"2009-02-20T11:38:56Z","lastAt":"2009-02-23T15:23:03Z","messageCount":4,"participants":["Gerrit Pape","Todd Zullinger","Johannes Sixt"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"105602","messageId":"20090220113856.6612.qmail@0bbdb5719a4668.315fe32.mid.smarden.org","threadId":"17919","inReplyTo":null,"subject":"[PATCH] git-tag: don't use gpg's stdin, stdout when signing tags","fromName":"Gerrit Pape","fromEmail":"pape@smarden.org","sentAt":"2009-02-20T11:38:56Z","receivedAt":"2009-02-20T11:38:56Z","isPatch":true,"sender":{"key":"pape@smarden.org","avatar":"https://avatars.githubusercontent.com/u/143170252?v=4"},"body":"When using gpg with some console based gpg-agent, acquiring the\npassphrase through the agent fails if stdin and stdout of gpg are\nredirected.  With this commit, git-tag uses temporary files instead\nof standard input/output when signing a tag to support such gpg-agent\nusage.\n\nThe problem was reported by Loïc Minier through\n http://bugs.debian.org/507642\n\nSigned-off-by: Gerrit Pape <pape@smarden.org>\n---\n builtin-tag.c |   51 ++++++++++++++++++++++++++++++++++-----------------\n 1 files changed, 34 insertions(+), 17 deletions(-)\n\ndiff --git a/builtin-tag.c b/builtin-tag.c\nindex 01e7374..e350352 100644\n--- a/builtin-tag.c\n+++ b/builtin-tag.c\n@@ -159,10 +159,15 @@ static int verify_tag(const char *name, const char *ref,\n static int do_sign(struct strbuf *buffer)\n {\n \tstruct child_process gpg;\n-\tconst char *args[4];\n+\tconst char *args[7];\n \tchar *bracket;\n \tint len;\n \tint i, j;\n+\tint fd;\n+\tchar *unsignpath, *signpath;\n+\n+\tunsignpath = git_pathdup(\"TAG_UNSIGNEDMSG\");\n+\tsignpath = git_pathdup(\"TAG_SIGNEDMSG\");\n \n \tif (!*signingkey) {\n \t\tif (strlcpy(signingkey, git_committer_info(IDENT_ERROR_ON_NO_NAME),\n@@ -179,27 +184,39 @@ static int do_sign(struct strbuf *buffer)\n \n \tmemset(&gpg, 0, sizeof(gpg));\n \tgpg.argv = args;\n-\tgpg.in = -1;\n-\tgpg.out = -1;\n+\tgpg.in = 0;\n+\tgpg.out = 1;\n \targs[0] = \"gpg\";\n \targs[1] = \"-bsau\";\n \targs[2] = signingkey;\n-\targs[3] = NULL;\n-\n-\tif (start_command(&gpg))\n-\t\treturn error(\"could not run gpg.\");\n-\n-\tif (write_in_full(gpg.in, buffer->buf, buffer->len) != buffer->len) {\n-\t\tclose(gpg.in);\n-\t\tclose(gpg.out);\n-\t\tfinish_command(&gpg);\n-\t\treturn error(\"gpg did not accept the tag data\");\n+\targs[3] = \"-o\";\n+\targs[4] = signpath;\n+\targs[5] = unsignpath;\n+\targs[6] = NULL;\n+\n+\tfd = open(unsignpath, O_CREAT | O_TRUNC | O_WRONLY, 0600);\n+\tif (fd < 0)\n+\t\tdie(\"could not create file '%s': %s\",\n+\t\t\t\t\tunsignpath, strerror(errno));\n+\twrite_or_die(fd, buffer->buf, buffer->len);\n+\tclose(fd);\n+\n+\tif (run_command(&gpg)) {\n+\t\tunlink(unsignpath);\n+\t\tunlink(signpath);\n+\t\treturn error(\"gpg failed.\");\n \t}\n-\tclose(gpg.in);\n-\tlen = strbuf_read(buffer, gpg.out, 1024);\n-\tclose(gpg.out);\n+\tunlink(unsignpath);\n+\n+\tfd = open(signpath, O_RDONLY);\n+\tif (fd < 0)\n+\t\tdie (\"could not open file '%s': %s\",\n+\t\t\t\t\tsignpath, strerror(errno));\n+\tlen = strbuf_read(buffer, fd, 1024);\n+\tclose(fd);\n+\tunlink(signpath);\n \n-\tif (finish_command(&gpg) || !len || len < 0)\n+\tif (!len || len < 0)\n \t\treturn error(\"gpg failed to sign the tag\");\n \n \t/* Strip CR from the line endings, in case we are on Windows. */\n-- \n1.6.1.3\n"},{"id":"105608","messageId":"20090220134634.GJ4505@inocybe.teonanacatl.org","threadId":"17919","inReplyTo":"20090220113856.6612.qmail@0bbdb5719a4668.315fe32.mid.smarden.org","subject":"Re: [PATCH] git-tag: don't use gpg's stdin, stdout when signing tags","fromName":"Todd Zullinger","fromEmail":"tmz@pobox.com","sentAt":"2009-02-20T13:46:34Z","receivedAt":"2009-02-20T13:46:34Z","isPatch":true,"sender":{"key":"tmz@pobox.com","avatar":"https://avatars.githubusercontent.com/u/806319?v=4"},"body":"Gerrit Pape wrote:\n> When using gpg with some console based gpg-agent, acquiring the\n> passphrase through the agent fails if stdin and stdout of gpg are\n> redirected.  With this commit, git-tag uses temporary files instead\n> of standard input/output when signing a tag to support such\n> gpg-agent usage.\n>\n> The problem was reported by Loïc Minier through\n> http://bugs.debian.org/507642\n\nI sign tags using gpg-agent with the curse pinentry often and it works\nhere.  Perhaps Loïc has not set GPG_TTY as the gpg-agent documentation\nsuggests?  If I unset GPG_TTY, I get the sort of failure indicated in\nthe bug report.  With it set tag signing works as expected.\n\nQuoting the gpg-agent docs:\n\n  You should always add the following lines to your `.bashrc' or\n  whatever initialization file is used for all shell invocations:\n\n     GPG_TTY=`tty`\n     export GPG_TTY\n\n  It is important that this environment variable always reflects the\n  output of the `tty' command.  For W32 systems this option is not\n  required.\n\nNow, I'm not sure if that's a reason not to include this patch.  :)\n\nI just wanted to mention that it can and does work if you have GPG_TTY\nset.  This is often needed for other tools as well, e.g. with mutt, so\nusers of the curses pinentry are best off setting it rather than\nhoping individual apps work around it.\n\n-- \nTodd        OpenPGP -> KeyID: 0xBEAF0CE3 | URL: www.pobox.com/~tmz/pgp\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\nSome people are like Slinkies... not really good for anything, but you\nstill can't help but smile when you see one tumble down the stairs.\n\n"},{"id":"105637","messageId":"499EEEEA.2040600@kdbg.org","threadId":"17919","inReplyTo":"20090220113856.6612.qmail@0bbdb5719a4668.315fe32.mid.smarden.org","subject":"Re: [PATCH] git-tag: don't use gpg's stdin, stdout when signing tags","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2009-02-20T17:56:58Z","receivedAt":"2009-02-20T17:56:58Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Gerrit Pape schrieb:\n>  \tmemset(&gpg, 0, sizeof(gpg));\n>  \tgpg.argv = args;\n> -\tgpg.in = -1;\n> -\tgpg.out = -1;\n> +\tgpg.in = 0;\n> +\tgpg.out = 1;\n\nI assume you mean with this that gpg should read from fd 0 and write to \nfd 1, IOW, it should use the standard channels. If I am right, then the \nmemset above has initialized gpg as needed already. Then gpg.argv is the \nonly thing you are setting up in struct child_process gpg; but in this \ncase you can use a convenience function...\n\n>  \targs[0] = \"gpg\";\n>  \targs[1] = \"-bsau\";\n>  \targs[2] = signingkey;\n> -\targs[3] = NULL;\n...\n> +\targs[3] = \"-o\";\n> +\targs[4] = signpath;\n> +\targs[5] = unsignpath;\n> +\targs[6] = NULL;\n...\n> +\tif (run_command(&gpg)) {\n\n... here (note: no struct child_process needed):\n\n\tif (run_command_v_opt(args, 0)) {\n\n(Just in case this patch is required...)\n\n-- Hannes\n"},{"id":"105901","messageId":"20090223152303.9953.qmail@770db0999d0428.315fe32.mid.smarden.org","threadId":"17919","inReplyTo":"20090220134634.GJ4505@inocybe.teonanacatl.org","subject":"Re: [PATCH] git-tag: don't use gpg's stdin, stdout when signing tags","fromName":"Gerrit Pape","fromEmail":"pape@smarden.org","sentAt":"2009-02-23T15:23:03Z","receivedAt":"2009-02-23T15:23:03Z","isPatch":true,"sender":{"key":"pape@smarden.org","avatar":"https://avatars.githubusercontent.com/u/143170252?v=4"},"body":"On Fri, Feb 20, 2009 at 08:46:34AM -0500, Todd Zullinger wrote:\n> Gerrit Pape wrote:\n> > When using gpg with some console based gpg-agent, acquiring the\n> > passphrase through the agent fails if stdin and stdout of gpg are\n> > redirected.  With this commit, git-tag uses temporary files instead\n> > of standard input/output when signing a tag to support such\n> > gpg-agent usage.\n> >\n> > The problem was reported by Loïc Minier through\n> > http://bugs.debian.org/507642\n> \n> I sign tags using gpg-agent with the curse pinentry often and it works\n> here.  Perhaps Loïc has not set GPG_TTY as the gpg-agent documentation\n> suggests?  If I unset GPG_TTY, I get the sort of failure indicated in\n> the bug report.  With it set tag signing works as expected.\n\nThanks a lot Todd and Johannes for teaching me.  From my POV this patch\ncan be dropped.\n\nRegards, Gerrit.\n"}]}