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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxxx>
---
 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

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux