]> git.ipfire.org Git - thirdparty/git.git/commitdiff
gpg-interface: trim CR from ssh-keygen
authorFabian Stelzer <fs@gigacodes.de>
Fri, 7 Jan 2022 09:07:35 +0000 (10:07 +0100)
committerJunio C Hamano <gitster@pobox.com>
Fri, 7 Jan 2022 21:42:49 +0000 (13:42 -0800)
We need to trim \r from the output of 'ssh-keygen -Y find-principals' on
Windows, or we end up calling 'ssh-keygen -Y verify' with a bogus signer
identity. ssh-keygen.c:2841 contains a call to puts(3), which confirms
this hypothesis. Signature verification passes with the fix.

Helped-by: Pedro Martelletto <pedro@yubico.com>
Signed-off-by: Fabian Stelzer <fs@gigacodes.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
gpg-interface.c

index b52eb0e2e04b37c6868f7573d750b688a4ec0e68..17b1e44baa6a97a73fa5566d201de46c856c13ff 100644 (file)
@@ -433,7 +433,6 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
        struct tempfile *buffer_file;
        int ret = -1;
        const char *line;
-       size_t trust_size;
        char *principal;
        struct strbuf ssh_principals_out = STRBUF_INIT;
        struct strbuf ssh_principals_err = STRBUF_INIT;
@@ -502,15 +501,30 @@ static int verify_ssh_signed_buffer(struct signature_check *sigc,
                ret = -1;
        } else {
                /* Check every principal we found (one per line) */
-               for (line = ssh_principals_out.buf; *line;
-                    line = strchrnul(line + 1, '\n')) {
-                       while (*line == '\n')
-                               line++;
-                       if (!*line)
-                               break;
-
-                       trust_size = strcspn(line, "\n");
-                       principal = xmemdupz(line, trust_size);
+               const char *next;
+               for (line = ssh_principals_out.buf;
+                    *line;
+                    line = next) {
+                       const char *end_of_text;
+
+                       next = end_of_text = strchrnul(line, '\n');
+
+                        /* Did we find a LF, and did we have CR before it? */
+                       if (*end_of_text &&
+                           line < end_of_text &&
+                           end_of_text[-1] == '\r')
+                               end_of_text--;
+
+                       /* Unless we hit NUL, skip over the LF we found */
+                       if (*next)
+                               next++;
+
+                       /* Not all lines are data.  Skip empty ones */
+                       if (line == end_of_text)
+                               continue;
+
+                       /* We now know we have an non-empty line. Process it */
+                       principal = xmemdupz(line, end_of_text - line);
 
                        child_process_init(&ssh_keygen);
                        strbuf_release(&ssh_keygen_out);