Skip to content

Commit ef16391

Browse files
committed
Merge branch 'fs/ssh-signing-fix'
Fix-up for the other topic already in 'next'. * fs/ssh-signing-fix: gpg-interface: fix leak of strbufs in get_ssh_key_fingerprint() gpg-interface: fix leak of "line" in parse_ssh_output() ssh signing: clarify trustlevel usage in docs ssh signing: fmt-merge-msg tests & config parse
2 parents 18c6653 + f3af71c commit ef16391

File tree

4 files changed

+46
-6
lines changed

4 files changed

+46
-6
lines changed

Documentation/config/gpg.txt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ gpg.ssh.allowedSignersFile::
5252
SSH has no concept of trust levels like gpg does. To be able to differentiate
5353
between valid signatures and trusted signatures the trust level of a signature
5454
verification is set to `fully` when the public key is present in the allowedSignersFile.
55-
Therefore to only mark fully trusted keys as verified set gpg.minTrustLevel to `fully`.
56-
Otherwise valid but untrusted signatures will still verify but show no principal
57-
name of the signer.
55+
Otherwise the trust level is `undefined` and git verify-commit/tag will fail.
5856
+
5957
This file can be set to a location outside of the repository and every developer
6058
maintains their own trust store. A central repository server could generate this

fmt-merge-msg.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@
99
#include "branch.h"
1010
#include "fmt-merge-msg.h"
1111
#include "commit-reach.h"
12+
#include "gpg-interface.h"
1213

1314
static int use_branch_desc;
1415
static int suppress_dest_pattern_seen;
1516
static struct string_list suppress_dest_patterns = STRING_LIST_INIT_DUP;
1617

1718
int fmt_merge_msg_config(const char *key, const char *value, void *cb)
1819
{
20+
int status = 0;
21+
1922
if (!strcmp(key, "merge.log") || !strcmp(key, "merge.summary")) {
2023
int is_bool;
2124
merge_log_config = git_config_bool_or_int(key, value, &is_bool);
@@ -34,6 +37,9 @@ int fmt_merge_msg_config(const char *key, const char *value, void *cb)
3437
string_list_append(&suppress_dest_patterns, value);
3538
suppress_dest_pattern_seen = 1;
3639
} else {
40+
status = git_gpg_config(key, value, NULL);
41+
if (status)
42+
return status;
3743
return git_default_config(key, value, cb);
3844
}
3945
return 0;

gpg-interface.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ static int verify_gpg_signed_buffer(struct signature_check *sigc,
365365
static void parse_ssh_output(struct signature_check *sigc)
366366
{
367367
const char *line, *principal, *search;
368+
char *to_free;
368369
char *key = NULL;
369370

370371
/*
@@ -383,7 +384,7 @@ static void parse_ssh_output(struct signature_check *sigc)
383384
sigc->result = 'B';
384385
sigc->trust_level = TRUST_NEVER;
385386

386-
line = xmemdupz(sigc->output, strcspn(sigc->output, "\n"));
387+
line = to_free = xmemdupz(sigc->output, strcspn(sigc->output, "\n"));
387388

388389
if (skip_prefix(line, "Good \"git\" signature for ", &line)) {
389390
/* Valid signature and known principal */
@@ -403,7 +404,7 @@ static void parse_ssh_output(struct signature_check *sigc)
403404
sigc->result = 'G';
404405
sigc->trust_level = TRUST_UNDEFINED;
405406
} else {
406-
return;
407+
goto cleanup;
407408
}
408409

409410
key = strstr(line, "key");
@@ -417,6 +418,9 @@ static void parse_ssh_output(struct signature_check *sigc)
417418
*/
418419
sigc->result = 'B';
419420
}
421+
422+
cleanup:
423+
free(to_free);
420424
}
421425

422426
static int verify_ssh_signed_buffer(struct signature_check *sigc,
@@ -707,6 +711,7 @@ static char *get_ssh_key_fingerprint(const char *signing_key)
707711
int ret = -1;
708712
struct strbuf fingerprint_stdout = STRBUF_INIT;
709713
struct strbuf **fingerprint;
714+
char *fingerprint_ret;
710715

711716
/*
712717
* With SSH Signing this can contain a filename or a public key
@@ -733,7 +738,10 @@ static char *get_ssh_key_fingerprint(const char *signing_key)
733738
die_errno(_("failed to get the ssh fingerprint for key '%s'"),
734739
signing_key);
735740

736-
return strbuf_detach(fingerprint[1], NULL);
741+
fingerprint_ret = strbuf_detach(fingerprint[1], NULL);
742+
strbuf_list_free(fingerprint);
743+
strbuf_release(&fingerprint_stdout);
744+
return fingerprint_ret;
737745
}
738746

739747
/* Returns the first public key from an ssh-agent to use for signing */

t/t6200-fmt-merge-msg.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,16 @@ test_expect_success GPG 'set up a signed tag' '
8181
git tag -s -m signed-tag-msg signed-good-tag left
8282
'
8383

84+
test_expect_success GPGSSH 'created ssh signed commit and tag' '
85+
test_config gpg.format ssh &&
86+
git checkout -b signed-ssh &&
87+
touch file &&
88+
git add file &&
89+
git commit -m "ssh signed" -S"${GPGSSH_KEY_PRIMARY}" &&
90+
git tag -s -u"${GPGSSH_KEY_PRIMARY}" -m signed-ssh-tag-msg signed-good-ssh-tag left &&
91+
git tag -s -u"${GPGSSH_KEY_UNTRUSTED}" -m signed-ssh-tag-msg-untrusted signed-untrusted-ssh-tag left
92+
'
93+
8494
test_expect_success 'message for merging local branch' '
8595
echo "Merge branch ${apos}left${apos}" >expected &&
8696
@@ -109,6 +119,24 @@ test_expect_success GPG 'message for merging local tag signed by unknown key' '
109119
grep -E "^# gpg: Can${apos}t check signature: (public key not found|No public key)" actual
110120
'
111121

122+
test_expect_success GPGSSH 'message for merging local tag signed by good ssh key' '
123+
test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
124+
git checkout main &&
125+
git fetch . signed-good-ssh-tag &&
126+
git fmt-merge-msg <.git/FETCH_HEAD >actual 2>&1 &&
127+
grep "${GPGSSH_GOOD_SIGNATURE_TRUSTED}" actual &&
128+
! grep "${GPGSSH_BAD_SIGNATURE}" actual
129+
'
130+
131+
test_expect_success GPGSSH 'message for merging local tag signed by unknown ssh key' '
132+
test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" &&
133+
git checkout main &&
134+
git fetch . signed-untrusted-ssh-tag &&
135+
git fmt-merge-msg <.git/FETCH_HEAD >actual 2>&1 &&
136+
grep "${GPGSSH_GOOD_SIGNATURE_UNTRUSTED}" actual &&
137+
! grep "${GPGSSH_BAD_SIGNATURE}" actual &&
138+
grep "${GPGSSH_KEY_NOT_TRUSTED}" actual
139+
'
112140
test_expect_success 'message for merging external branch' '
113141
echo "Merge branch ${apos}left${apos} of $(pwd)" >expected &&
114142

0 commit comments

Comments
 (0)