]> granicus.if.org Git - p11-kit/commitdiff
test: Add test for client-server interaction
authorDaiki Ueno <dueno@redhat.com>
Mon, 26 Feb 2018 10:44:01 +0000 (11:44 +0100)
committerDaiki Ueno <ueno@gnu.org>
Tue, 27 Feb 2018 11:27:45 +0000 (12:27 +0100)
The test spawns a process running the server command and connects to
it through p11-kit-client.so.  It's is a bit tricky that the child
process requires to preload libasan.so when ASan is in in effect, to
properly load a mock module.

.travis.yml
build/lsan.supp [new file with mode: 0644]
p11-kit/Makefile.am
p11-kit/test-server.c [new file with mode: 0644]

index dab8c2caa977ed57adbb449a8498e0f70395729d..51fab880f0557423516b1f1e282754bd35639d43 100644 (file)
@@ -5,8 +5,8 @@ language: c
 env:
   - BUILD_OPTS="--prefix=/usr --libdir=/usr/lib64" SRCDIR=/srcdir BUILDDIR=/builddir
   - BUILD_OPTS="--prefix=/usr --libdir=/usr/lib64 --enable-coverage" COVERAGE=yes SRCDIR=/coverage BUILDDIR=/coverage
-  - BUILD_OPTS="--prefix=/usr --libdir=/usr/lib64 CFLAGS='-fsanitize=address -g -fno-common -U_FORTIFY_SOURCE' CXXFLAGS='-fsanitize=address -g -fno-common -U_FORTIFY_SOURCE' LDFLAGS='-fsanitize=address -g -fno-common -U_FORTIFY_SOURCE' LIBS='-ldl -lpthread'" SRCDIR=/srcdir BUILDDIR=/builddir
-  - BUILD_OPTS="--prefix=/usr --libdir=/usr/lib64 CFLAGS='-fsanitize=undefined -g -fno-common -U_FORTIFY_SOURCE' CXXFLAGS='-fsanitize=undefined -g -fno-common -U_FORTIFY_SOURCE' LDFLAGS='-fsanitize=undefined -g -fno-common -U_FORTIFY_SOURCE' LIBS='-ldl -lpthread'" SRCDIR=/srcdir BUILDDIR=/builddir
+  - BUILD_OPTS="--prefix=/usr --libdir=/usr/lib64 CFLAGS='-fsanitize=address -g -fno-common -U_FORTIFY_SOURCE' CXXFLAGS='-fsanitize=address -g -fno-common -U_FORTIFY_SOURCE' LDFLAGS='-fsanitize=address -g -fno-common -U_FORTIFY_SOURCE' LIBS='-lasan -ldl -lpthread'" SRCDIR=/srcdir BUILDDIR=/builddir PRELOAD_CMD='ls -1 /usr/lib64/libasan.so.* | head -1' LSAN_OPTIONS='suppressions=/srcdir/build/lsan.supp'
+  - BUILD_OPTS="--prefix=/usr --libdir=/usr/lib64 CFLAGS='-fsanitize=undefined -g -fno-common -U_FORTIFY_SOURCE' CXXFLAGS='-fsanitize=undefined -g -fno-common -U_FORTIFY_SOURCE' LDFLAGS='-fsanitize=undefined -g -fno-common -U_FORTIFY_SOURCE' LIBS='-lubsan -ldl -lpthread'" SRCDIR=/srcdir BUILDDIR=/builddir
   - BUILD_OPTS="--prefix=/usr --libdir=/usr/lib64" SCAN_BUILD="scan-build --status-bugs" SRCDIR=/srcdir BUILDDIR=/builddir
   - BUILD_OPTS="-host=x86_64-w64-mingw32 --prefix=/usr/x86_64-w64-mingw32 --without-libffi" TESTS_ENVIRONMENT="wine" SRCDIR=/srcdir BUILDDIR=/builddir
 
@@ -41,7 +41,11 @@ install:
 script:
   - docker exec $CONTAINER sh -c "cd $SRCDIR && NOCONFIGURE=1 ./autogen.sh"
   - docker exec $CONTAINER su - user sh -c "cd $BUILDDIR && $SRCDIR/configure --enable-strict $BUILD_OPTS"
-  - docker exec $CONTAINER su - user sh -c "cd $BUILDDIR && $SCAN_BUILD make -j$(nproc) V=1 && make check -j$(nproc) V=1 TESTS_ENVIRONMENT=\"$TESTS_ENVIRONMENT\""
+  - |
+      if test -n "$PRELOAD_CMD"; then
+        P11_KIT_TEST_LD_PRELOAD=$(docker exec $CONTAINER su - user sh -c "$PRELOAD_CMD")
+      fi
+  - docker exec $CONTAINER su - user sh -c "cd $BUILDDIR && $SCAN_BUILD make -j$(nproc) V=1 && P11_KIT_DEBUG=all LSAN_OPTIONS="$LSAN_OPTIONS" P11_KIT_TEST_LD_PRELOAD=\"$P11_KIT_TEST_LD_PRELOAD\" make check -j$(nproc) V=1 TESTS_ENVIRONMENT=\"$TESTS_ENVIRONMENT\""
 
 after_failure:
   - docker exec $CONTAINER su - user sh -c "cd $BUILDDIR && cat test-suite.log"
diff --git a/build/lsan.supp b/build/lsan.supp
new file mode 100644 (file)
index 0000000..9e22787
--- /dev/null
@@ -0,0 +1,3 @@
+leak:bash
+leak:bfd
+leak:gcc
index 243ee54d5d4bf1c26e2e21c299a18cbbf652b604..f4e9069cbcab6a77022ccc34509c626571b511bd 100644 (file)
@@ -246,6 +246,7 @@ c_tests += \
        $(NULL)
 
 if !OS_WIN32
+c_tests += test-server
 sh_tests += p11-kit/test-server.sh
 endif
 
@@ -276,6 +277,9 @@ test_proxy_LDADD = $(p11_kit_LIBS)
 test_rpc_SOURCES = p11-kit/test-rpc.c
 test_rpc_LDADD = $(p11_kit_LIBS)
 
+test_server_SOURCES = p11-kit/test-server.c
+test_server_LDADD = $(p11_kit_LIBS)
+
 test_uri_SOURCES = p11-kit/test-uri.c
 test_uri_LDADD = $(p11_kit_LIBS)
 
diff --git a/p11-kit/test-server.c b/p11-kit/test-server.c
new file mode 100644 (file)
index 0000000..c6f877b
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2018 Red Hat Inc
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *     * Redistributions of source code must retain the above
+ *       copyright notice, this list of conditions and the
+ *       following disclaimer.
+ *     * Redistributions in binary form must reproduce the
+ *       above copyright notice, this list of conditions and
+ *       the following disclaimer in the documentation and/or
+ *       other materials provided with the distribution.
+ *     * The names of contributors to this software may not be
+ *       used to endorse or promote products derived from this
+ *       software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * Author: Daiki Ueno
+ */
+
+#include "config.h"
+#include "test.h"
+
+#include "dict.h"
+#include "library.h"
+#include "filter.h"
+#include "mock.h"
+#include "modules.h"
+#include "p11-kit.h"
+#include "remote.h"
+#include "virtual.h"
+
+#include <errno.h>
+#include <poll.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+struct {
+       char *directory;
+       char *socket_path;
+       pid_t pid;
+} test;
+
+static void
+setup_server (void *arg)
+{
+       char *argv[] = {
+               "p11-kit-server",
+               "-f",
+               "--provider",
+               BUILDDIR "/.libs/mock-one" SHLEXT,
+               "-n",
+               NULL,
+               NULL,
+               NULL
+       };
+       char *address;
+       int fds[2];
+       struct pollfd pfd;
+       int ret;
+       const char *envvar;
+
+       test.directory = p11_test_directory ("p11-test-server");
+       if (asprintf (&test.socket_path, "%s/pkcs11", test.directory) < 0)
+               assert_not_reached ();
+       unlink (test.socket_path);
+
+       ret = socketpair (AF_UNIX, SOCK_STREAM, 0, fds);
+       assert_num_cmp (-1, !=, ret);
+
+       setenv ("P11_KIT_PRIVATEDIR", BUILDDIR, 1);
+
+       /* Allow the child process to preload libasan.so */
+       envvar = secure_getenv ("P11_KIT_TEST_LD_PRELOAD");
+       if (envvar)
+               setenv ("LD_PRELOAD", envvar, 1);
+
+       argv[5] = test.socket_path;
+       argv[6] = (char *)arg;
+
+       test.pid = fork ();
+
+       /* The child */
+       if (test.pid == 0) {
+               close (STDOUT_FILENO);
+               dup2 (fds[0], STDOUT_FILENO);
+               execv (BUILDDIR "/p11-kit-server", argv);
+               _exit (0);
+       }
+
+       memset (&pfd, 0, sizeof (struct pollfd));
+       pfd.fd = fds[1];
+       pfd.events = POLLIN | POLLHUP | POLLERR;
+       ret = poll (&pfd, 1, 10000);
+       assert_num_cmp (-1, !=, ret);
+
+       close (fds[0]);
+       close (fds[1]);
+
+       if (asprintf (&address, "unix:path=%s", test.socket_path) < 0)
+               assert_not_reached ();
+       setenv ("P11_KIT_SERVER_ADDRESS", address, 1);
+       free (address);
+}
+
+static void
+teardown_server (void *unused)
+{
+       int status;
+       kill (test.pid, SIGKILL);
+       waitpid (test.pid, &status, 0);
+
+       p11_test_directory_delete (test.directory);
+       free (test.directory);
+       free (test.socket_path);
+}
+
+static void
+test_initialize (void *unused)
+{
+       CK_FUNCTION_LIST_PTR module;
+       CK_RV rv;
+
+       module = p11_kit_module_load (BUILDDIR "/.libs/p11-kit-client" SHLEXT, 0);
+       assert (module != NULL);
+
+       rv = p11_kit_module_initialize (module);
+       assert (rv == CKR_OK);
+
+       rv = p11_kit_module_finalize (module);
+       assert (rv == CKR_OK);
+
+       p11_kit_module_release (module);
+}
+
+static void
+test_open_session (void *unused)
+{
+       CK_SESSION_HANDLE session;
+       CK_FUNCTION_LIST_PTR module;
+       CK_SLOT_ID slots[32];
+       CK_ULONG count;
+       CK_RV rv;
+
+       module = p11_kit_module_load (BUILDDIR "/.libs/p11-kit-client" SHLEXT, 0);
+       assert (module != NULL);
+
+       rv = p11_kit_module_initialize (module);
+       assert (rv == CKR_OK);
+
+       count = 32;
+       rv = module->C_GetSlotList (CK_TRUE, slots, &count);
+       assert (rv == CKR_OK);
+       assert_num_eq (1, count);
+
+       rv = module->C_OpenSession (slots[0], CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL, NULL, &session);
+       assert (rv == CKR_OK);
+
+       rv = module->C_CloseSession (session);
+       assert (rv == CKR_OK);
+
+       rv = p11_kit_module_finalize (module);
+       assert (rv == CKR_OK);
+
+       p11_kit_module_release (module);
+}
+
+int
+main (int argc,
+      char *argv[])
+{
+       p11_library_init ();
+       mock_module_init ();
+
+       p11_fixture (setup_server, teardown_server);
+       p11_testx (test_initialize, (void *)"pkcs11:", "/server/initialize");
+       p11_testx (test_open_session, (void *)"pkcs11:", "/server/open-session");
+
+       return p11_test_run (argc, argv);
+}