Skip to content

Commit eb307ae

Browse files
Sebastian Göttegitster
authored andcommitted
merge/pull Check for untrusted good GPG signatures
When --verify-signatures is specified, abort the merge in case a good GPG signature from an untrusted key is encountered. Signed-off-by: Sebastian Götte <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent efed002 commit eb307ae

File tree

10 files changed

+29
-12
lines changed

10 files changed

+29
-12
lines changed

Documentation/merge-options.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ option can be used to override --squash.
8585

8686
--verify-signatures::
8787
--no-verify-signatures::
88-
Verify that the commits being merged have good GPG signatures and abort the
89-
merge in case they do not.
88+
Verify that the commits being merged have good and trusted GPG signatures
89+
and abort the merge in case they do not.
9090

9191
--summary::
9292
--no-summary::

builtin/merge.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1248,6 +1248,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
12481248
switch (signature_check.result) {
12491249
case 'G':
12501250
break;
1251+
case 'U':
1252+
die(_("Commit %s has an untrusted GPG signature, "
1253+
"allegedly by %s."), hex, signature_check.signer);
12511254
case 'B':
12521255
die(_("Commit %s has a bad GPG signature "
12531256
"allegedly by %s."), hex, signature_check.signer);

commit.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,8 @@ static struct {
10471047
} sigcheck_gpg_status[] = {
10481048
{ 'G', "\n[GNUPG:] GOODSIG " },
10491049
{ 'B', "\n[GNUPG:] BADSIG " },
1050+
{ 'U', "\n[GNUPG:] TRUST_NEVER" },
1051+
{ 'U', "\n[GNUPG:] TRUST_UNDEFINED" },
10501052
};
10511053

10521054
static void parse_gpg_output(struct signature_check *sigc)
@@ -1068,11 +1070,13 @@ static void parse_gpg_output(struct signature_check *sigc)
10681070
found += strlen(sigcheck_gpg_status[i].check);
10691071
}
10701072
sigc->result = sigcheck_gpg_status[i].result;
1071-
sigc->key = xmemdupz(found, 16);
1072-
found += 17;
1073-
next = strchrnul(found, '\n');
1074-
sigc->signer = xmemdupz(found, next - found);
1075-
break;
1073+
/* The trust messages are not followed by key/signer information */
1074+
if (sigc->result != 'U') {
1075+
sigc->key = xmemdupz(found, 16);
1076+
found += 17;
1077+
next = strchrnul(found, '\n');
1078+
sigc->signer = xmemdupz(found, next - found);
1079+
}
10761080
}
10771081
}
10781082

commit.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,11 @@ extern void print_commit_list(struct commit_list *list,
234234
const char *format_last);
235235

236236
/*
237-
* Check the signature of the given commit. The result of the check is stored in
238-
* sig->result, 'G' for a good signature, 'B' for a bad signature and 'N'
239-
* for no signature at all.
240-
* This may allocate memory for sig->gpg_output, sig->gpg_status, sig->signer
241-
* and sig->key.
237+
* Check the signature of the given commit. The result of the check is stored
238+
* in sig->check_result, 'G' for a good signature, 'U' for a good signature
239+
* from an untrusted signer, 'B' for a bad signature and 'N' for no signature
240+
* at all. This may allocate memory for sig->gpg_output, sig->gpg_status,
241+
* sig->signer and sig->key.
242242
*/
243243
extern void check_commit_signature(const struct commit* commit, struct signature_check *sigc);
244244

gpg-interface.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ struct signature_check {
66
char *gpg_status;
77
char result; /* 0 (not checked),
88
* N (checked but no further result),
9+
* U (untrusted good),
910
* G (good)
1011
* B (bad) */
1112
char *signer;

t/lib-gpg/pubring.gpg

1.17 KB
Binary file not shown.

t/lib-gpg/random_seed

0 Bytes
Binary file not shown.

t/lib-gpg/secring.gpg

2.44 KB
Binary file not shown.

t/lib-gpg/trustdb.gpg

80 Bytes
Binary file not shown.

t/t7612-merge-verify-signatures.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ test_expect_success GPG 'create signed commits' '
2727
git hash-object -w -t commit forged >forged.commit &&
2828
git checkout initial &&
2929
30+
git checkout -b side-untrusted &&
31+
echo 3 >baz && git add baz &&
32+
test_tick && git commit -SB7227189 -m "untrusted on side"
33+
3034
git checkout master
3135
'
3236

@@ -40,6 +44,11 @@ test_expect_success GPG 'merge commit with bad signature with verification' '
4044
test_i18ngrep "has a bad GPG signature" mergeerror
4145
'
4246

47+
test_expect_success GPG 'merge commit with untrusted signature with verification' '
48+
test_must_fail git merge --ff-only --verify-signatures side-untrusted 2>mergeerror &&
49+
test_i18ngrep "has an untrusted GPG signature" mergeerror
50+
'
51+
4352
test_expect_success GPG 'merge signed commit with verification' '
4453
git merge --verbose --ff-only --verify-signatures side-signed >mergeoutput &&
4554
test_i18ngrep "has a good GPG signature" mergeoutput

0 commit comments

Comments
 (0)