1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-05-09 20:46:09 +02:00

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 <jaseg@physik-pool.tu-berlin.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Sebastian Götte 2013-03-31 18:02:46 +02:00 committed by Junio C Hamano
parent efed002249
commit eb307ae7bb
10 changed files with 29 additions and 12 deletions

View File

@ -85,8 +85,8 @@ option can be used to override --squash.
--verify-signatures:: --verify-signatures::
--no-verify-signatures:: --no-verify-signatures::
Verify that the commits being merged have good GPG signatures and abort the Verify that the commits being merged have good and trusted GPG signatures
merge in case they do not. and abort the merge in case they do not.
--summary:: --summary::
--no-summary:: --no-summary::

View File

@ -1248,6 +1248,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
switch (signature_check.result) { switch (signature_check.result) {
case 'G': case 'G':
break; break;
case 'U':
die(_("Commit %s has an untrusted GPG signature, "
"allegedly by %s."), hex, signature_check.signer);
case 'B': case 'B':
die(_("Commit %s has a bad GPG signature " die(_("Commit %s has a bad GPG signature "
"allegedly by %s."), hex, signature_check.signer); "allegedly by %s."), hex, signature_check.signer);

View File

@ -1047,6 +1047,8 @@ static struct {
} sigcheck_gpg_status[] = { } sigcheck_gpg_status[] = {
{ 'G', "\n[GNUPG:] GOODSIG " }, { 'G', "\n[GNUPG:] GOODSIG " },
{ 'B', "\n[GNUPG:] BADSIG " }, { 'B', "\n[GNUPG:] BADSIG " },
{ 'U', "\n[GNUPG:] TRUST_NEVER" },
{ 'U', "\n[GNUPG:] TRUST_UNDEFINED" },
}; };
static void parse_gpg_output(struct signature_check *sigc) static void parse_gpg_output(struct signature_check *sigc)
@ -1068,11 +1070,13 @@ static void parse_gpg_output(struct signature_check *sigc)
found += strlen(sigcheck_gpg_status[i].check); found += strlen(sigcheck_gpg_status[i].check);
} }
sigc->result = sigcheck_gpg_status[i].result; sigc->result = sigcheck_gpg_status[i].result;
sigc->key = xmemdupz(found, 16); /* The trust messages are not followed by key/signer information */
found += 17; if (sigc->result != 'U') {
next = strchrnul(found, '\n'); sigc->key = xmemdupz(found, 16);
sigc->signer = xmemdupz(found, next - found); found += 17;
break; next = strchrnul(found, '\n');
sigc->signer = xmemdupz(found, next - found);
}
} }
} }

View File

@ -234,11 +234,11 @@ extern void print_commit_list(struct commit_list *list,
const char *format_last); const char *format_last);
/* /*
* Check the signature of the given commit. The result of the check is stored in * Check the signature of the given commit. The result of the check is stored
* sig->result, 'G' for a good signature, 'B' for a bad signature and 'N' * in sig->check_result, 'G' for a good signature, 'U' for a good signature
* for no signature at all. * from an untrusted signer, 'B' for a bad signature and 'N' for no signature
* This may allocate memory for sig->gpg_output, sig->gpg_status, sig->signer * at all. This may allocate memory for sig->gpg_output, sig->gpg_status,
* and sig->key. * sig->signer and sig->key.
*/ */
extern void check_commit_signature(const struct commit* commit, struct signature_check *sigc); extern void check_commit_signature(const struct commit* commit, struct signature_check *sigc);

View File

@ -6,6 +6,7 @@ struct signature_check {
char *gpg_status; char *gpg_status;
char result; /* 0 (not checked), char result; /* 0 (not checked),
* N (checked but no further result), * N (checked but no further result),
* U (untrusted good),
* G (good) * G (good)
* B (bad) */ * B (bad) */
char *signer; char *signer;

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -27,6 +27,10 @@ test_expect_success GPG 'create signed commits' '
git hash-object -w -t commit forged >forged.commit && git hash-object -w -t commit forged >forged.commit &&
git checkout initial && 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 git checkout master
' '
@ -40,6 +44,11 @@ test_expect_success GPG 'merge commit with bad signature with verification' '
test_i18ngrep "has a bad GPG signature" mergeerror test_i18ngrep "has a bad GPG signature" mergeerror
' '
test_expect_success GPG 'merge commit with untrusted signature with verification' '
test_must_fail git merge --ff-only --verify-signatures side-untrusted 2>mergeerror &&
test_i18ngrep "has an untrusted GPG signature" mergeerror
'
test_expect_success GPG 'merge signed commit with verification' ' test_expect_success GPG 'merge signed commit with verification' '
git merge --verbose --ff-only --verify-signatures side-signed >mergeoutput && git merge --verbose --ff-only --verify-signatures side-signed >mergeoutput &&
test_i18ngrep "has a good GPG signature" mergeoutput test_i18ngrep "has a good GPG signature" mergeoutput