214 lines
6.0 KiB
Diff
214 lines
6.0 KiB
Diff
|
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
|
||
|
|