git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] git-tag: don't use gpg's stdin, stdout when signing tags

From
Gerrit Pape <pape@smarden.org>
Date
Feb 20, 2009, 11:38 UTC
Message-ID
<20090220113856.6612.qmail@0bbdb5719a4668.315fe32.mid.smarden.org>

When using gpg with some console based gpg-agent, acquiring the passphrase through the agent fails if stdin and stdout of gpg are redirected. With this commit, git-tag uses temporary files instead of standard input/output when signing a tag to support such gpg-agent usage.

The problem was reported by Loïc Minier through
 http://bugs.debian.org/507642
Signed-off-by: Gerrit Pape <pape@smarden.org>
---
 builtin-tag.c |   51 ++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 34 insertions(+), 17 deletions(-)
diff --git a/builtin-tag.c b/builtin-tag.c
index 01e7374..e350352 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -159,10 +159,15 @@ static int verify_tag(const char *name, const char *ref,
 static int do_sign(struct strbuf *buffer)
 {
 	struct child_process gpg;
-	const char *args[4];
+	const char *args[7];
 	char *bracket;
 	int len;
 	int i, j;
+	int fd;
+	char *unsignpath, *signpath;
+
+	unsignpath = git_pathdup("TAG_UNSIGNEDMSG");
+	signpath = git_pathdup("TAG_SIGNEDMSG");
 
 	if (!*signingkey) {
 		if (strlcpy(signingkey, git_committer_info(IDENT_ERROR_ON_NO_NAME),
@@ -179,27 +184,39 @@ static int do_sign(struct strbuf *buffer)
 
 	memset(&gpg, 0, sizeof(gpg));
 	gpg.argv = args;
-	gpg.in = -1;
-	gpg.out = -1;
+	gpg.in = 0;
+	gpg.out = 1;
 	args[0] = "gpg";
 	args[1] = "-bsau";
 	args[2] = signingkey;
-	args[3] = NULL;
-
-	if (start_command(&gpg))
-		return error("could not run gpg.");
-
-	if (write_in_full(gpg.in, buffer->buf, buffer->len) != buffer->len) {
-		close(gpg.in);
-		close(gpg.out);
-		finish_command(&gpg);
-		return error("gpg did not accept the tag data");
+	args[3] = "-o";
+	args[4] = signpath;
+	args[5] = unsignpath;
+	args[6] = NULL;
+
+	fd = open(unsignpath, O_CREAT | O_TRUNC | O_WRONLY, 0600);
+	if (fd < 0)
+		die("could not create file '%s': %s",
+					unsignpath, strerror(errno));
+	write_or_die(fd, buffer->buf, buffer->len);
+	close(fd);
+
+	if (run_command(&gpg)) {
+		unlink(unsignpath);
+		unlink(signpath);
+		return error("gpg failed.");
 	}
-	close(gpg.in);
-	len = strbuf_read(buffer, gpg.out, 1024);
-	close(gpg.out);
+	unlink(unsignpath);
+
+	fd = open(signpath, O_RDONLY);
+	if (fd < 0)
+		die ("could not open file '%s': %s",
+					signpath, strerror(errno));
+	len = strbuf_read(buffer, fd, 1024);
+	close(fd);
+	unlink(signpath);
 
-	if (finish_command(&gpg) || !len || len < 0)
+	if (!len || len < 0)
 		return error("gpg failed to sign the tag");
 
 	/* Strip CR from the line endings, in case we are on Windows. */
-- 
1.6.1.3
Next: Todd Zullinger
Message 1 of 4 in “git-tag: don't use gpg's stdin, stdout when signing tags”
  1. git-tag: don't use gpg's stdin, stdout when signing tagsGerrit Pape, Feb 20, 2009
  2. Todd ZullingerFeb 20, 2009
  3. Gerrit PapeFeb 23, 2009
  4. Johannes SixtFeb 20, 2009

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.