From: Alexander 'z33ky' Hirsch <1zeeky@gmail.com>
To: git@vger.kernel.org
Cc: "brian m. carlson" <sandals@crustytoothpaste.net>
Subject: [PATCH] rebase: add --verify-signatures
Date: Thu, 10 Dec 2015 14:03:48 +0100 [thread overview]
Message-ID: <20151210130228.GA22641@netblarch.tu-darmstadt.de> (raw)
This option works analogous to --verify-signatures for git-merge by
checking that the commits, that are rebased onto, have good GPG
signatures.
Additionally, git-pull now forwards --verify-signatures to rebase as
well.
Signed-off-by: Alexander 'z33ky' Hirsch <1zeeky@gmail.com>
---
I'm unsure if the opt_verify_signatures check in builtin/pull.c should
be moved up to the "/* Shared options */" now.
The output strings from the GPG check are identical to the ones in
builtin/merge.c; I am unsure about the implications for l10n.
The test is mostly copied from t7612-merge-verify-signatures.sh.
Documentation/git-rebase.txt | 6 ++++
builtin/pull.c | 2 ++
git-rebase.sh | 44 +++++++++++++++++++++++++
t/t3427-rebase-verify-signatures.sh | 65 +++++++++++++++++++++++++++++++++++++
4 files changed, 117 insertions(+)
create mode 100755 t/t3427-rebase-verify-signatures.sh
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 6cca8bb..959b12b 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -292,6 +292,12 @@ which makes little sense.
specified, `-s recursive`. Note the reversal of 'ours' and
'theirs' as noted above for the `-m` option.
+--verify-signatures::
+--no-verify-signatures::
+ Verify that the commits in the branch the rebase is onto, but not
+ present in the working branch, have good GPG signatures and abort the
+ operation in case they do not.
+
-S[<keyid>]::
--gpg-sign[=<keyid>]::
GPG-sign commits. The `keyid` argument is optional and
diff --git a/builtin/pull.c b/builtin/pull.c
index bf3fd3f..37ec0f8 100644
--- a/builtin/pull.c
+++ b/builtin/pull.c
@@ -774,6 +774,8 @@ static int run_rebase(const unsigned char *curr_head,
argv_array_push(&args, "--preserve-merges");
if (opt_diffstat)
argv_array_push(&args, opt_diffstat);
+ if (opt_verify_signatures)
+ argv_array_push(&args, opt_verify_signatures);
argv_array_pushv(&args, opt_strategies.argv);
argv_array_pushv(&args, opt_strategy_opts.argv);
if (opt_gpg_sign)
diff --git a/git-rebase.sh b/git-rebase.sh
index af7ba5f..dcfbc3a 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -38,6 +38,7 @@ whitespace=! passed to 'git apply'
ignore-whitespace! passed to 'git apply'
C=! passed to 'git apply'
S,gpg-sign? GPG-sign commits
+verify-signatures verify that the commits of onto have valid GPG signatures
Actions:
continue! continue
abort! abort and check out the original branch
@@ -88,6 +89,7 @@ autosquash=
keep_empty=
test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
gpg_sign_opt=
+verify_signatures=
read_basic_state () {
test -f "$state_dir/head-name" &&
@@ -339,6 +341,12 @@ do
--gpg-sign=*)
gpg_sign_opt="-S${1#--gpg-sign=}"
;;
+ --verify-signatures)
+ verify_signatures=t
+ ;;
+ --no-verify-signatures)
+ verify_signatures=
+ ;;
--)
shift
break
@@ -594,6 +602,42 @@ then
fi
fi
+if test "$verify_signatures"
+then
+ if test -n "$rebase_root"
+ then
+ foreign_revisions="$orig_head..$onto"
+ else
+ foreign_revisions="$orig_head..${restrict_revision-$upstream}"
+ fi
+
+ for cmt in $(git rev-list --reverse "$foreign_revisions")
+ do
+ if ! git log -1 --pretty=format:'%G?%n%GS' "$cmt" |
+ (
+ read cmt_sig
+ read cmt_signer
+ case "$cmt_sig" in
+ 'G')
+ ;;
+ 'U')
+ die "$(gettext "Commit $cmt has an untrusted GPG signature, allegedly by $cmt_signer.")"
+ ;;
+ 'B')
+ die "$(gettext "Commit $cmt has a bad GPG signature allegedly by $cmt_signer.")"
+ ;;
+ *) #'N'
+ die "$(gettext "Commit $cmt does not have a GPG signature.")"
+ ;;
+ esac
+ test "$verbose" && test 'G' = "$cmt_sig" && echo "Commit $cmt has a good GPG signature by $cmt_signer."
+ )
+ then
+ exit 1
+ fi
+ done
+fi
+
# If a hook exists, give it a chance to interrupt
run_pre_rebase_hook "$upstream_arg" "$@"
diff --git a/t/t3427-rebase-verify-signatures.sh b/t/t3427-rebase-verify-signatures.sh
new file mode 100755
index 0000000..1bd0a4d
--- /dev/null
+++ b/t/t3427-rebase-verify-signatures.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+test_description='rebase signature verification tests'
+. ./test-lib.sh
+. "$TEST_DIRECTORY/lib-gpg.sh"
+
+test_expect_success GPG 'create signed commits' '
+ echo 1 >file && git add file &&
+ test_tick && git commit -m initial &&
+ git tag initial &&
+
+ git checkout -b side-signed &&
+ echo 3 >elif && git add elif &&
+ test_tick && git commit -S -m "signed on side" &&
+ git checkout initial &&
+
+ git checkout -b side-unsigned &&
+ echo 3 >foo && git add foo &&
+ test_tick && git commit -m "unsigned on side" &&
+ git checkout initial &&
+
+ git checkout -b side-bad &&
+ echo 3 >bar && git add bar &&
+ test_tick && git commit -S -m "bad on side" &&
+ git cat-file commit side-bad >raw &&
+ sed -e "s/bad/forged bad/" raw >forged &&
+ git hash-object -w -t commit forged >forged.commit &&
+ git checkout initial &&
+
+ git checkout -b side-untrusted &&
+ echo 3 >baz && git add baz &&
+ test_tick && git commit -SB7227189 -m "untrusted on side" &&
+
+ git checkout master
+'
+
+test_expect_success GPG 'rebase unsigned commit with verification' '
+ test_must_fail git rebase --verify-signatures side-unsigned 2>rebaseerror &&
+ test_i18ngrep "does not have a GPG signature" rebaseerror
+'
+
+test_expect_success GPG 'rebase commit with bad signature with verification' '
+ test_must_fail git rebase --verify-signatures $(cat forged.commit) 2>rebaseerror &&
+ test_i18ngrep "has a bad GPG signature" rebaseerror
+'
+
+test_expect_success GPG 'rebase commit with untrusted signature with verification' '
+ test_must_fail git rebase --verify-signatures side-untrusted 2>rebaseerror &&
+ test_i18ngrep "has an untrusted GPG signature" rebaseerror
+'
+
+test_expect_success GPG 'rebase signed commit with verification' '
+ git rebase --verbose --verify-signatures side-signed >rebaseoutput &&
+ test_i18ngrep "has a good GPG signature" rebaseoutput
+'
+
+test_expect_success GPG 'rebase commit with bad signature without verification (implicit)' '
+ git rebase $(cat forged.commit)
+'
+
+test_expect_success GPG 'rebase commit with bad signature without verification (explicit)' '
+ git rebase --no-verify-signatures $(cat forged.commit)
+'
+
+test_done
--
2.6.3
next reply other threads:[~2015-12-10 12:56 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-12-10 13:03 Alexander 'z33ky' Hirsch [this message]
2015-12-10 19:11 ` [PATCH] rebase: add --verify-signatures Junio C Hamano
2015-12-10 19:53 ` Junio C Hamano
2015-12-16 13:39 ` Alexander 'z33ky' Hirsch
2015-12-16 18:12 ` Junio C Hamano
2015-12-17 1:04 ` Alexander 'z33ky' Hirsch
2015-12-17 18:22 ` Junio C Hamano
[not found] ` <20151221140414.GA3422@netblarch.tu-darmstadt.de>
[not found] ` <xmqqvb7re55d.fsf@gitster.mtv.corp.google.com>
2015-12-22 23:12 ` Alexander 'z33ky' Hirsch
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20151210130228.GA22641@netblarch.tu-darmstadt.de \
--to=1zeeky@gmail.com \
--cc=git@vger.kernel.org \
--cc=sandals@crustytoothpaste.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).