Blame SOURCES/0115-SSH-Do-not-exit-abruptly-if-SSHD-closes-its-end-of-t.patch

75e304
From d1b01f0a04e54c55183fd5cee4b713e28e4e2cd7 Mon Sep 17 00:00:00 2001
75e304
From: Jakub Hrozek <jhrozek@redhat.com>
75e304
Date: Mon, 28 May 2018 21:41:49 +0200
75e304
Subject: [PATCH] SSH: Do not exit abruptly if SSHD closes its end of the pipe
75e304
 before reading all the SSH keys
75e304
MIME-Version: 1.0
75e304
Content-Type: text/plain; charset=UTF-8
75e304
Content-Transfer-Encoding: 8bit
75e304
75e304
Resolves:
75e304
https://pagure.io/SSSD/sssd/issue/3747
75e304
75e304
Before writing the keys to sshd, ignore SIGPIPE so that if the pipe
75e304
towards the authorizedkeys helper is closed, the sss_ssh_authorizedkeys
75e304
helper is not terminated with SIGPIPE, but instead proceeds and then the
75e304
write(2) calls would non-terminally fail with EPIPE.
75e304
75e304
Reviewed-by: Fabiano FidĂȘncio <fidencio@redhat.com>
75e304
(cherry picked from commit cb138d7d060611e891d341db08477e41f9a3d17d)
75e304
---
75e304
 src/sss_client/ssh/sss_ssh_authorizedkeys.c | 35 ++++++++++++++++++++++++++++-
75e304
 1 file changed, 34 insertions(+), 1 deletion(-)
75e304
75e304
diff --git a/src/sss_client/ssh/sss_ssh_authorizedkeys.c b/src/sss_client/ssh/sss_ssh_authorizedkeys.c
75e304
index 782a9f44379bff5346c896b3e03570720632c0be..b0280fbf8b0ed0501d792973241b826fc4a7a04d 100644
75e304
--- a/src/sss_client/ssh/sss_ssh_authorizedkeys.c
75e304
+++ b/src/sss_client/ssh/sss_ssh_authorizedkeys.c
75e304
@@ -21,6 +21,7 @@
75e304
 #include <stdio.h>
75e304
 #include <talloc.h>
75e304
 #include <popt.h>
75e304
+#include <signal.h>
75e304
 
75e304
 #include "util/util.h"
75e304
 #include "util/crypto/sss_crypto.h"
75e304
@@ -99,8 +100,16 @@ int main(int argc, const char **argv)
75e304
         goto fini;
75e304
     }
75e304
 
75e304
+    /* if sshd closes its end of the pipe, we don't want sss_ssh_authorizedkeys
75e304
+     * to exit abruptly, but to finish gracefully instead because the valid
75e304
+     * key can be present in the data already written
75e304
+     */
75e304
+    signal(SIGPIPE, SIG_IGN);
75e304
+
75e304
     /* print results */
75e304
     for (i = 0; i < ent->num_pubkeys; i++) {
75e304
+        char *repr_break = NULL;
75e304
+
75e304
         ret = sss_ssh_format_pubkey(mem_ctx, &ent->pubkeys[i], &repr);
75e304
         if (ret != EOK) {
75e304
             DEBUG(SSSDBG_OP_FAILURE,
75e304
@@ -109,7 +118,31 @@ int main(int argc, const char **argv)
75e304
             continue;
75e304
         }
75e304
 
75e304
-        printf("%s\n", repr);
75e304
+        /* OpenSSH expects a linebreak after each key */
75e304
+        repr_break = talloc_asprintf(mem_ctx, "%s\n", repr);
75e304
+        talloc_zfree(repr);
75e304
+        if (repr_break == NULL) {
75e304
+            ret = ENOMEM;
75e304
+            goto fini;
75e304
+        }
75e304
+
75e304
+        ret = sss_atomic_write_s(STDOUT_FILENO, repr_break, strlen(repr_break));
75e304
+        /* Avoid spiking memory with too many large keys */
75e304
+        talloc_zfree(repr_break);
75e304
+        if (ret < 0) {
75e304
+            ret = errno;
75e304
+            if (ret == EPIPE) {
75e304
+                DEBUG(SSSDBG_MINOR_FAILURE,
75e304
+                      "SSHD closed the pipe before all keys could be written\n");
75e304
+                /* Return 0 so that openssh doesn't abort pubkey auth */
75e304
+                ret = 0;
75e304
+                goto fini;
75e304
+            }
75e304
+            DEBUG(SSSDBG_CRIT_FAILURE,
75e304
+                  "sss_atomic_write_s() failed (%d): %s\n",
75e304
+                  ret, strerror(ret));
75e304
+            goto fini;
75e304
+        }
75e304
     }
75e304
 
75e304
     ret = EXIT_SUCCESS;
75e304
-- 
75e304
2.14.4
75e304