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:
parent
efed002249
commit
eb307ae7bb
|
@ -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::
|
||||||
|
|
|
@ -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);
|
||||||
|
|
14
commit.c
14
commit.c
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
commit.h
10
commit.h
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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.
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue