Blame SOURCES/0013-TESTS-Add-a-helper-binary-that-can-trigger-the-SIGPI.patch

ca1eb8
From ef28a3bdc50d0da6fab86b0d27e4c548ac61a749 Mon Sep 17 00:00:00 2001
96eb28
From: Jakub Hrozek <jhrozek@redhat.com>
96eb28
Date: Mon, 28 May 2018 21:49:41 +0200
96eb28
Subject: [PATCH] TESTS: Add a helper binary that can trigger the SIGPIPE to
96eb28
 authorizedkeys
96eb28
MIME-Version: 1.0
96eb28
Content-Type: text/plain; charset=UTF-8
96eb28
Content-Transfer-Encoding: 8bit
96eb28
96eb28
Adds a test tool that simulates the behaviour of OpenSSH in the sense
96eb28
that it starts to read the output from the sss_ssh_authorizedkeys tool,
96eb28
but then closes the pipe before reading the whole output.
96eb28
96eb28
Related:
96eb28
https://pagure.io/SSSD/sssd/issue/3747
96eb28
96eb28
Reviewed-by: Fabiano FidĂȘncio <fidencio@redhat.com>
96eb28
(cherry picked from commit 909c16edb26a3c48b10a49e7919a35d13d31c52e)
96eb28
---
ca1eb8
 Makefile.am                 |  15 +++-
ca1eb8
 src/tests/test_ssh_client.c | 133 ++++++++++++++++++++++++++++++++++++
96eb28
 2 files changed, 147 insertions(+), 1 deletion(-)
96eb28
 create mode 100644 src/tests/test_ssh_client.c
96eb28
96eb28
diff --git a/Makefile.am b/Makefile.am
ca1eb8
index 9055130ed74057987795285c243ff47584cf8316..99974cf0e94e1ec6086a53585042653ec5966c2c 100644
96eb28
--- a/Makefile.am
96eb28
+++ b/Makefile.am
96eb28
@@ -331,6 +331,7 @@ endif   # HAVE_CMOCKA
96eb28
 check_PROGRAMS = \
96eb28
     stress-tests \
96eb28
     krb5-child-test \
96eb28
+    test_ssh_client \
96eb28
     $(non_interactive_cmocka_based_tests) \
96eb28
     $(non_interactive_check_based_tests)
96eb28
 
ca1eb8
@@ -2291,6 +2292,18 @@ krb5_child_test_LDADD = \
96eb28
     $(SSSD_INTERNAL_LTLIBS) \
96eb28
     libsss_test_common.la
96eb28
 
96eb28
+test_ssh_client_SOURCES = \
96eb28
+    src/tests/test_ssh_client.c \
96eb28
+    $(NULL)
96eb28
+test_ssh_client_CFLAGS = \
96eb28
+    $(AM_CFLAGS) \
96eb28
+    -DSSH_CLIENT_DIR=\"$(abs_top_builddir)\" \
96eb28
+    $(NULL)
96eb28
+test_ssh_client_LDADD = \
96eb28
+    $(SSSD_INTERNAL_LTLIBS) \
96eb28
+    $(SSSD_LIBS) \
96eb28
+    $(NULL)
96eb28
+
96eb28
 if BUILD_DBUS_TESTS
96eb28
 
96eb28
 sbus_tests_SOURCES = \
ca1eb8
@@ -3446,7 +3459,6 @@ test_iobuf_LDADD = \
96eb28
     $(SSSD_LIBS) \
96eb28
     $(NULL)
96eb28
 
96eb28
-
96eb28
 EXTRA_simple_access_tests_DEPENDENCIES = \
96eb28
     $(ldblib_LTLIBRARIES)
96eb28
 simple_access_tests_SOURCES = \
ca1eb8
@@ -3655,6 +3667,7 @@ intgcheck-prepare:
96eb28
 	    $(INTGCHECK_CONFIGURE_FLAGS) \
ca1eb8
 	    CFLAGS="-O2 -g $$CFLAGS -DKCM_PEER_UID=$$(id -u)"; \
96eb28
 	$(MAKE) $(AM_MAKEFLAGS) ; \
96eb28
+	$(MAKE) $(AM_MAKEFLAGS) test_ssh_client; \
96eb28
 	: Force single-thread install to workaround concurrency issues; \
96eb28
 	$(MAKE) $(AM_MAKEFLAGS) -j1 install; \
96eb28
 	: Remove .la files from LDB module directory to avoid loader warnings; \
96eb28
diff --git a/src/tests/test_ssh_client.c b/src/tests/test_ssh_client.c
96eb28
new file mode 100644
96eb28
index 0000000000000000000000000000000000000000..8f963941f3249561178436d6f6dfc376780a4cda
96eb28
--- /dev/null
96eb28
+++ b/src/tests/test_ssh_client.c
96eb28
@@ -0,0 +1,133 @@
96eb28
+/*
96eb28
+    Copyright (C) 2018 Red Hat
96eb28
+
96eb28
+    This program is free software; you can redistribute it and/or modify
96eb28
+    it under the terms of the GNU General Public License as published by
96eb28
+    the Free Software Foundation; either version 3 of the License, or
96eb28
+    (at your option) any later version.
96eb28
+
96eb28
+    This program is distributed in the hope that it will be useful,
96eb28
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
96eb28
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
96eb28
+    GNU General Public License for more details.
96eb28
+
96eb28
+    You should have received a copy of the GNU General Public License
96eb28
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
96eb28
+*/
96eb28
+
96eb28
+#include <popt.h>
96eb28
+#include <sys/wait.h>
96eb28
+#include "util/util.h"
96eb28
+
96eb28
+#ifdef SSH_CLIENT_DIR
96eb28
+#define SSH_AK_CLIENT_PATH SSH_CLIENT_DIR"/sss_ssh_authorizedkeys"
96eb28
+#else
96eb28
+#error "The path to the ssh authorizedkeys helper is not defined"
96eb28
+#endif /* SSH_CLIENT_DIR */
96eb28
+
96eb28
+int main(int argc, const char *argv[])
96eb28
+{
96eb28
+    poptContext pc;
96eb28
+    int opt;
96eb28
+    struct poptOption long_options[] = {
96eb28
+        POPT_AUTOHELP
96eb28
+        SSSD_DEBUG_OPTS
96eb28
+        POPT_TABLEEND
96eb28
+    };
96eb28
+    struct stat sb;
96eb28
+    int ret;
96eb28
+    int status;
96eb28
+    int p[2];
96eb28
+    pid_t pid;
96eb28
+    const char *pc_user = NULL;
96eb28
+    char *av[3];
96eb28
+    char buf[5]; /* Ridiculously small buffer by design */
96eb28
+
96eb28
+    /* Set debug level to invalid value so we can decide if -d 0 was used. */
96eb28
+    debug_level = SSSDBG_INVALID;
96eb28
+
96eb28
+    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
96eb28
+    poptSetOtherOptionHelp(pc, "USER");
96eb28
+    while((opt = poptGetNextOpt(pc)) != -1) {
96eb28
+        switch(opt) {
96eb28
+        default:
96eb28
+            fprintf(stderr, "\nInvalid option %s: %s\n\n",
96eb28
+                    poptBadOption(pc, 0), poptStrerror(opt));
96eb28
+            poptPrintUsage(pc, stderr, 0);
96eb28
+            return 3;
96eb28
+        }
96eb28
+    }
96eb28
+
96eb28
+    pc_user = poptGetArg(pc);
96eb28
+    if (pc_user == NULL) {
96eb28
+        fprintf(stderr, "No user specified\n");
96eb28
+        return 3;
96eb28
+    }
96eb28
+
96eb28
+    poptFreeContext(pc);
96eb28
+
96eb28
+    DEBUG_CLI_INIT(debug_level);
96eb28
+
96eb28
+    ret = stat(SSH_AK_CLIENT_PATH, &sb);
96eb28
+    if (ret != 0) {
96eb28
+        ret = errno;
96eb28
+        DEBUG(SSSDBG_CRIT_FAILURE,
96eb28
+              "Could not stat %s [%d]: %s\n",
96eb28
+              SSH_AK_CLIENT_PATH, ret, strerror(ret));
96eb28
+        return 3;
96eb28
+    }
96eb28
+
96eb28
+    ret = pipe(p);
96eb28
+    if (ret != 0) {
96eb28
+        perror("pipe");
96eb28
+        return 3;
96eb28
+    }
96eb28
+
96eb28
+    switch (pid = fork()) {
96eb28
+    case -1:
96eb28
+        ret = errno;
96eb28
+        close(p[0]);
96eb28
+        close(p[1]);
96eb28
+        DEBUG(SSSDBG_CRIT_FAILURE, "fork failed: %d\n", ret);
96eb28
+        return 3;
96eb28
+    case 0:
96eb28
+        /* child */
96eb28
+        av[0] = discard_const(SSH_AK_CLIENT_PATH);
96eb28
+        av[1] = discard_const(pc_user);
96eb28
+        av[2] = NULL;
96eb28
+
96eb28
+        close(p[0]);
96eb28
+        ret = dup2(p[1], STDOUT_FILENO);
96eb28
+        if (ret == -1) {
96eb28
+            perror("dup2");
96eb28
+            return 3;
96eb28
+        }
96eb28
+
96eb28
+        execv(av[0], av);
96eb28
+        return 3;
96eb28
+    default:
96eb28
+        /* parent */
96eb28
+        break;
96eb28
+    }
96eb28
+
96eb28
+    close(p[1]);
96eb28
+    read(p[0], buf, sizeof(buf));
96eb28
+    close(p[0]);
96eb28
+
96eb28
+    pid = waitpid(pid, &status, 0);
96eb28
+    if (pid == -1) {
96eb28
+        perror("waitpid");
96eb28
+        return 3;
96eb28
+    }
96eb28
+
96eb28
+    if (WIFEXITED(status)) {
96eb28
+        printf("sss_ssh_authorizedkeys exited with return code %d\n", WEXITSTATUS(status));
96eb28
+        return 0;
96eb28
+    } else if (WIFSIGNALED(status)) {
96eb28
+        printf("sss_ssh_authorizedkeys exited with signal %d\n", WTERMSIG(status));
96eb28
+        return 1;
96eb28
+    }
96eb28
+
96eb28
+    printf("sss_ssh_authorizedkeys exited for another reason\n");
96eb28
+    return 2;
96eb28
+}
96eb28
-- 
ca1eb8
2.17.1
96eb28