[PATCH v2 6/6] verify-commit: add a --summary flag

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

 



The current outputs, with `--raw`, `--verbose` or by default, from
`git verify-commit` are all quite verbose and do not make it easy to
quickly assess signature status.

Let's add a new `--summary` option to `git verify-commit` that prints
a concise, one-line summary of the signature verification to standard
output.

This compact format is useful for scripts and tools that need to
quickly parse signature verification results, while still being
human-readable.

Signed-off-by: Christian Couder <chriscool@xxxxxxxxxxxxx>
---
 Documentation/git-verify-commit.adoc | 17 ++++++++++++++++-
 builtin/verify-commit.c              |  4 +++-
 gpg-interface.c                      | 11 +++++++++++
 gpg-interface.h                      |  6 ++++++
 t/t7510-signed-commit.sh             | 24 ++++++++++++++++++++++++
 t/t7528-signed-commit-ssh.sh         | 28 ++++++++++++++++++++++++++++
 6 files changed, 88 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-verify-commit.adoc b/Documentation/git-verify-commit.adoc
index 6a208a0c2a..fb038ae0cf 100644
--- a/Documentation/git-verify-commit.adoc
+++ b/Documentation/git-verify-commit.adoc
@@ -8,7 +8,7 @@ git-verify-commit - Check the signature of commits
 SYNOPSIS
 --------
 [verse]
-'git verify-commit' [-v | --verbose] [--raw] <commit>...
+'git verify-commit' [-v | --verbose] [--raw] [--summary] <commit>...
 
 DESCRIPTION
 -----------
@@ -38,6 +38,21 @@ OPTIONS
 	error instead of the normal human-readable output. The format
 	of this output is specific to the signature format being used.
 
+--summary::
+	Print a one-line human-readable summary of the signature check
+	to standard output in the format: `STATUS FORMAT ALGORITHM`.
++
+STATUS is the result character (e.g., G, B, E, U, N, ...) shown by the
+"%G?" pretty format specifier. See the "Pretty Formats" section in
+linkgit:git-log[1].
++
+FORMAT indicates the signature format (`openpgp`, `x509`, or `ssh`) or
+`?` if unknown.
++
+ALGORITHM is the hash algorithm used for GPG/GPGSM signatures
+(e.g. `sha1`, `sha256`, ...), or the key type for SSH signatures
+(`RSA`, `ECDSA`, `ED25519`, ...), or `?` if unknown.
+
 -v::
 --verbose::
 	Print the contents of the commit object before validating it.
diff --git a/builtin/verify-commit.c b/builtin/verify-commit.c
index 5f749a30da..54b5b7d360 100644
--- a/builtin/verify-commit.c
+++ b/builtin/verify-commit.c
@@ -14,7 +14,7 @@
 #include "gpg-interface.h"
 
 static const char * const verify_commit_usage[] = {
-		N_("git verify-commit [-v | --verbose] [--raw] <commit>..."),
+		N_("git verify-commit [-v | --verbose] [--raw] [--summary] <commit>..."),
 		NULL
 };
 
@@ -27,6 +27,7 @@ static int run_gpg_verify(struct commit *commit, unsigned flags)
 
 	ret = check_commit_signature(commit, &signature_check);
 	print_signature_buffer(&signature_check, flags);
+	print_signature_summary(&signature_check, flags);
 
 	signature_check_clear(&signature_check);
 	return ret;
@@ -60,6 +61,7 @@ int cmd_verify_commit(int argc,
 	const struct option verify_commit_options[] = {
 		OPT__VERBOSE(&verbose, N_("print commit contents")),
 		OPT_BIT(0, "raw", &flags, N_("print raw gpg status output"), GPG_VERIFY_RAW),
+		OPT_BIT(0, "summary", &flags, N_("print concise signature verification summary"), GPG_VERIFY_SUMMARY),
 		OPT_END()
 	};
 
diff --git a/gpg-interface.c b/gpg-interface.c
index 182e579769..fc198715c4 100644
--- a/gpg-interface.c
+++ b/gpg-interface.c
@@ -153,6 +153,7 @@ void signature_check_clear(struct signature_check *sigc)
 	FREE_AND_NULL(sigc->key);
 	FREE_AND_NULL(sigc->fingerprint);
 	FREE_AND_NULL(sigc->primary_key_fingerprint);
+	FREE_AND_NULL(sigc->format_name);
 	FREE_AND_NULL(sigc->sig_algo);
 }
 
@@ -756,6 +757,8 @@ int check_signature(struct signature_check *sigc,
 	if (!fmt)
 		die(_("bad/incompatible signature '%s'"), signature);
 
+	sigc->format_name = xstrdup(fmt->name);
+
 	if (parse_payload_metadata(sigc))
 		return 1;
 
@@ -782,6 +785,14 @@ void print_signature_buffer(const struct signature_check *sigc, unsigned flags)
 		fputs(output, stderr);
 }
 
+void print_signature_summary(const struct signature_check *sigc, unsigned flags)
+{
+	if (flags & GPG_VERIFY_SUMMARY)
+		printf("%c %s %s\n", sigc->result,
+		       sigc->format_name ? sigc->format_name : "?",
+		       sigc->sig_algo ? sigc->sig_algo : "?");
+}
+
 size_t parse_signed_buffer(const char *buf, size_t size)
 {
 	size_t len = 0;
diff --git a/gpg-interface.h b/gpg-interface.h
index 2b7701ca2c..a9565757f6 100644
--- a/gpg-interface.h
+++ b/gpg-interface.h
@@ -6,6 +6,7 @@ struct strbuf;
 #define GPG_VERIFY_VERBOSE	(1<<0)
 #define GPG_VERIFY_RAW		(1<<1)
 #define GPG_VERIFY_OMIT_STATUS	(1<<2)
+#define GPG_VERIFY_SUMMARY	(1<<3)
 
 enum signature_trust_level {
 	TRUST_UNDEFINED,
@@ -43,6 +44,9 @@ struct signature_check {
 	char *fingerprint;
 	char *primary_key_fingerprint;
 
+	/* "openpgp", "x509", "ssh" */
+	char *format_name;
+
 	/* hash algo for GPG/GPGSM, key type for SSH */
 	char *sig_algo;
 
@@ -95,5 +99,7 @@ int check_signature(struct signature_check *sigc,
 		    const char *signature, size_t slen);
 void print_signature_buffer(const struct signature_check *sigc,
 			    unsigned flags);
+void print_signature_summary(const struct signature_check *sigc,
+			     unsigned flags);
 
 #endif
diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh
index 39677e859a..47f40862f3 100755
--- a/t/t7510-signed-commit.sh
+++ b/t/t7510-signed-commit.sh
@@ -232,6 +232,30 @@ test_expect_success GPG2 'bare signature' '
 	test_cmp expect actual
 '
 
+test_expect_success GPG 'verify signatures with --summary' '
+	# GPG-signed commit
+	git verify-commit --summary sixth-signed >actual &&
+	test_grep "^G openpgp sha1" actual &&
+
+	# Non-signed commit
+	test_must_fail git verify-commit --summary seventh-unsigned >actual 2>&1 &&
+	test_grep "^N ? ?" actual &&
+
+	# Trusted signature with alternate key (hash used might depend on the OS)
+	git verify-commit --summary eighth-signed-alt >actual &&
+	test_grep -E "^G openpgp sha(256|512)" actual &&
+
+	# Bad signature
+	test_must_fail git verify-commit --summary $(cat forged1.commit) >actual 2>err &&
+	test_grep "^B openpgp ?" actual
+'
+
+test_expect_success GPG '--summary and --raw work together' '
+	git verify-commit --summary --raw sixth-signed >actual 2>err &&
+	test_grep "^G openpgp sha1" actual &&
+	test_grep "GOODSIG" err
+'
+
 test_expect_success GPG 'show good signature with custom format' '
 	cat >expect <<-\EOF &&
 	G
diff --git a/t/t7528-signed-commit-ssh.sh b/t/t7528-signed-commit-ssh.sh
index 065f780636..3d0e7d7859 100755
--- a/t/t7528-signed-commit-ssh.sh
+++ b/t/t7528-signed-commit-ssh.sh
@@ -277,6 +277,34 @@ test_expect_success GPGSSH 'detect fudged signature with NUL' '
 	! grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual2
 '
 
+test_expect_success GPGSSH 'verify-commit --summary outputs format and key type for SSH signatures' '
+	test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
+
+	# SSH-signed commit with ED25519 key
+	git verify-commit --summary sixth-signed >actual &&
+	test_grep "^G ssh ED25519" actual &&
+
+	# SSH-signed commit with ECDSA key
+	git verify-commit --summary thirteenth-signed-ecdsa >actual &&
+	test_grep "^G ssh ECDSA" actual &&
+
+	# Non-signed commit
+	test_must_fail git verify-commit --summary seventh-unsigned >actual 2>&1 &&
+	test_grep "^N ? ?" actual &&
+
+	# Bad signature
+	test_must_fail git verify-commit --summary $(cat forged1.commit) >actual 2>err &&
+	test_grep "^B ssh ?" actual
+'
+
+test_expect_success GPGSSH '--summary and --raw work together' '
+	test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
+
+	git verify-commit --summary --raw sixth-signed >actual 2>err &&
+	test_grep "^G ssh ED25519" actual &&
+	test_grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" err
+'
+
 test_expect_success GPGSSH 'amending already signed commit' '
 	test_config gpg.format ssh &&
 	test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" &&
-- 
2.49.0.609.g63c55177e5





[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