Blob Blame History Raw
From 187b9f28f1ea2e3fa4b5e3385050701fdc1d0f69 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek@redhat.com>
Date: Mon, 28 May 2018 21:49:41 +0200
Subject: [PATCH] TESTS: Add a helper binary that can trigger the SIGPIPE to
 authorizedkeys
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Adds a test tool that simulates the behaviour of OpenSSH in the sense
that it starts to read the output from the sss_ssh_authorizedkeys tool,
but then closes the pipe before reading the whole output.

Related:
https://pagure.io/SSSD/sssd/issue/3747

Reviewed-by: Fabiano FidĂȘncio <fidencio@redhat.com>
(cherry picked from commit 909c16edb26a3c48b10a49e7919a35d13d31c52e)
---
 Makefile.am                 |  15 ++++-
 src/tests/test_ssh_client.c | 133 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 147 insertions(+), 1 deletion(-)
 create mode 100644 src/tests/test_ssh_client.c

diff --git a/Makefile.am b/Makefile.am
index 5917bd904054055a259eb69217282e4fb914c700..01fa4e43e48dcb722056d614e19f02687d32014b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -331,6 +331,7 @@ endif   # HAVE_CMOCKA
 check_PROGRAMS = \
     stress-tests \
     krb5-child-test \
+    test_ssh_client \
     $(non_interactive_cmocka_based_tests) \
     $(non_interactive_check_based_tests)
 
@@ -2294,6 +2295,18 @@ krb5_child_test_LDADD = \
     $(SSSD_INTERNAL_LTLIBS) \
     libsss_test_common.la
 
+test_ssh_client_SOURCES = \
+    src/tests/test_ssh_client.c \
+    $(NULL)
+test_ssh_client_CFLAGS = \
+    $(AM_CFLAGS) \
+    -DSSH_CLIENT_DIR=\"$(abs_top_builddir)\" \
+    $(NULL)
+test_ssh_client_LDADD = \
+    $(SSSD_INTERNAL_LTLIBS) \
+    $(SSSD_LIBS) \
+    $(NULL)
+
 if BUILD_DBUS_TESTS
 
 sbus_tests_SOURCES = \
@@ -3418,7 +3431,6 @@ test_iobuf_LDADD = \
     $(SSSD_LIBS) \
     $(NULL)
 
-
 EXTRA_simple_access_tests_DEPENDENCIES = \
     $(ldblib_LTLIBRARIES)
 simple_access_tests_SOURCES = \
@@ -3607,6 +3619,7 @@ intgcheck-prepare:
 	    $(INTGCHECK_CONFIGURE_FLAGS) \
 	    CFLAGS="$$CFLAGS -DKCM_PEER_UID=$$(id -u)"; \
 	$(MAKE) $(AM_MAKEFLAGS) ; \
+	$(MAKE) $(AM_MAKEFLAGS) test_ssh_client; \
 	: Force single-thread install to workaround concurrency issues; \
 	$(MAKE) $(AM_MAKEFLAGS) -j1 install; \
 	: Remove .la files from LDB module directory to avoid loader warnings; \
diff --git a/src/tests/test_ssh_client.c b/src/tests/test_ssh_client.c
new file mode 100644
index 0000000000000000000000000000000000000000..8f963941f3249561178436d6f6dfc376780a4cda
--- /dev/null
+++ b/src/tests/test_ssh_client.c
@@ -0,0 +1,133 @@
+/*
+    Copyright (C) 2018 Red Hat
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <popt.h>
+#include <sys/wait.h>
+#include "util/util.h"
+
+#ifdef SSH_CLIENT_DIR
+#define SSH_AK_CLIENT_PATH SSH_CLIENT_DIR"/sss_ssh_authorizedkeys"
+#else
+#error "The path to the ssh authorizedkeys helper is not defined"
+#endif /* SSH_CLIENT_DIR */
+
+int main(int argc, const char *argv[])
+{
+    poptContext pc;
+    int opt;
+    struct poptOption long_options[] = {
+        POPT_AUTOHELP
+        SSSD_DEBUG_OPTS
+        POPT_TABLEEND
+    };
+    struct stat sb;
+    int ret;
+    int status;
+    int p[2];
+    pid_t pid;
+    const char *pc_user = NULL;
+    char *av[3];
+    char buf[5]; /* Ridiculously small buffer by design */
+
+    /* Set debug level to invalid value so we can decide if -d 0 was used. */
+    debug_level = SSSDBG_INVALID;
+
+    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
+    poptSetOtherOptionHelp(pc, "USER");
+    while((opt = poptGetNextOpt(pc)) != -1) {
+        switch(opt) {
+        default:
+            fprintf(stderr, "\nInvalid option %s: %s\n\n",
+                    poptBadOption(pc, 0), poptStrerror(opt));
+            poptPrintUsage(pc, stderr, 0);
+            return 3;
+        }
+    }
+
+    pc_user = poptGetArg(pc);
+    if (pc_user == NULL) {
+        fprintf(stderr, "No user specified\n");
+        return 3;
+    }
+
+    poptFreeContext(pc);
+
+    DEBUG_CLI_INIT(debug_level);
+
+    ret = stat(SSH_AK_CLIENT_PATH, &sb);
+    if (ret != 0) {
+        ret = errno;
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              "Could not stat %s [%d]: %s\n",
+              SSH_AK_CLIENT_PATH, ret, strerror(ret));
+        return 3;
+    }
+
+    ret = pipe(p);
+    if (ret != 0) {
+        perror("pipe");
+        return 3;
+    }
+
+    switch (pid = fork()) {
+    case -1:
+        ret = errno;
+        close(p[0]);
+        close(p[1]);
+        DEBUG(SSSDBG_CRIT_FAILURE, "fork failed: %d\n", ret);
+        return 3;
+    case 0:
+        /* child */
+        av[0] = discard_const(SSH_AK_CLIENT_PATH);
+        av[1] = discard_const(pc_user);
+        av[2] = NULL;
+
+        close(p[0]);
+        ret = dup2(p[1], STDOUT_FILENO);
+        if (ret == -1) {
+            perror("dup2");
+            return 3;
+        }
+
+        execv(av[0], av);
+        return 3;
+    default:
+        /* parent */
+        break;
+    }
+
+    close(p[1]);
+    read(p[0], buf, sizeof(buf));
+    close(p[0]);
+
+    pid = waitpid(pid, &status, 0);
+    if (pid == -1) {
+        perror("waitpid");
+        return 3;
+    }
+
+    if (WIFEXITED(status)) {
+        printf("sss_ssh_authorizedkeys exited with return code %d\n", WEXITSTATUS(status));
+        return 0;
+    } else if (WIFSIGNALED(status)) {
+        printf("sss_ssh_authorizedkeys exited with signal %d\n", WTERMSIG(status));
+        return 1;
+    }
+
+    printf("sss_ssh_authorizedkeys exited for another reason\n");
+    return 2;
+}
-- 
2.14.4