diff --git a/.gitignore b/.gitignore index 18b234e5..cc340c17 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ cli_srv_conn cli_srv_comm gssproxy.spec interposetest +userproxytest gssproxy.service gssuserproxy.service gssuserproxy.socket diff --git a/Makefile.am b/Makefile.am index e7210e9d..42d37227 100644 --- a/Makefile.am +++ b/Makefile.am @@ -370,6 +370,10 @@ CLEANFILES = *.X */*.X */*/*.X \ check: all $(check_PROGRAMS) $(srcdir)/tests/runtests.py $(CHECKARGS) +if HAVE_SYSTEMD_DAEMON + mkdir -p testdir + tests/userproxytest +endif tests: check diff --git a/external/systemd.m4 b/external/systemd.m4 index 8b7e8c1f..4d5d737b 100644 --- a/external/systemd.m4 +++ b/external/systemd.m4 @@ -23,4 +23,6 @@ AC_DEFUN([AM_CHECK_SYSTEMD], [AC_MSG_NOTICE([Build without $daemon_lib_name support])])], [AC_MSG_NOTICE([Build without $daemon_lib_name support])]) + AM_CONDITIONAL([HAVE_SYSTEMD_DAEMON], [test x"$daemon_lib_name" != x]) + AC_MSG_NOTICE([Will enable systemd socket activation]) ]) diff --git a/tests/Makefile.am b/tests/Makefile.am index d6924d90..3ea5b12b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -57,6 +57,13 @@ check_PROGRAMS = \ t_setcredopt \ $(NULL) +if HAVE_SYSTEMD_DAEMON +userproxytest_SOURCES = \ + userproxytest.c + + check_PROGRAMS += userproxytest +endif + noinst_PROGRAMS = $(check_PROGRAMS) noinst_HEADERS = \ diff --git a/tests/userproxytest.c b/tests/userproxytest.c new file mode 100644 index 00000000..ad6b2a46 --- /dev/null +++ b/tests/userproxytest.c @@ -0,0 +1,90 @@ +/* Copyright (C) 2022 the GSS-PROXY contributors, see COPYING for license */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include + +char *srv_args[] = { + "./gssproxy", + "-u", "-i", + "-s", "./testdir/userproxytest.sock", + "--idle-timeout=3" +}; + +int mock_activation_sockets(void) +{ + struct sockaddr_un addr = { + .sun_family = AF_UNIX, + .sun_path = "./testdir/userproxytest.sock", + }; + int fd; + int ret; + + unlink(addr.sun_path); + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) return -1; + + ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); + if (ret == -1) return -1; + + ret = listen(fd, 1); + if (ret == -1) return -1; + + return 0; +} + +int mock_activation_environment(void) +{ + char *onestr = "1"; + char *pidstr; + int ret; + + ret = asprintf(&pidstr, "%u", (unsigned)getpid()); + if (ret == -1) return -1; + + setenv("LISTEN_PID", pidstr, 1); + setenv("LISTEN_FDS", onestr, 1); + + free(pidstr); + return 0; +} + +int main(int argc, const char *main_argv[]) +{ + pid_t proxy, w; + int ret; + + fprintf(stderr, "Test userproxy mode: "); + + ret = mock_activation_sockets(); + if (ret) return -1; + + proxy = fork(); + if (proxy == -1) return -1; + + if (proxy == 0) { + ret = mock_activation_environment(); + if (ret) return -1; + + execv("./gssproxy", srv_args); + return -1; + } + + sleep(6); + + w = waitpid(-1, &ret, WNOHANG); + if (w != proxy || ret != 0) { + fprintf(stderr, "FAIL\n"); + fflush(stderr); + return -1; + } + + fprintf(stderr, "SUCCESS\n"); + fflush(stderr); + return 0; +}