From ef28a3bdc50d0da6fab86b0d27e4c548ac61a749 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 9055130ed74057987795285c243ff47584cf8316..99974cf0e94e1ec6086a53585042653ec5966c2c 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)
@@ -2291,6 +2292,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 = \
@@ -3446,7 +3459,6 @@ test_iobuf_LDADD = \
$(SSSD_LIBS) \
$(NULL)
-
EXTRA_simple_access_tests_DEPENDENCIES = \
$(ldblib_LTLIBRARIES)
simple_access_tests_SOURCES = \
@@ -3655,6 +3667,7 @@ intgcheck-prepare:
$(INTGCHECK_CONFIGURE_FLAGS) \
CFLAGS="-O2 -g $$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.17.1