From 376f38dafa0b7ee5eae3d8f0ba0333c84a79742d Mon Sep 17 00:00:00 2001 From: sanghyeok oh Date: Thu, 1 Dec 2016 21:05:33 -0800 Subject: [PATCH 01/16] Revert "tests: Add test package for libdbuspolicy" This reverts commit bb7d32bb63f1d0fc463255000fbc773a119314a9. Change-Id: I6bc92edf4cd438c07f6ed99acf4e8bfe531d1d1a --- Makefile.am | 19 - configure.ac | 1 - packaging/libdbuspolicy_tests.spec | 59 ---- src/cynara_prepare.sh | 8 - src/dbus_daemon.c | 236 ------------- src/libdbuspolicy1.c | 7 - src/stest_common.c | 31 -- src/stest_common.h | 21 -- src/stest_cynara.c | 30 -- src/stest_method_call.c | 77 ---- src/stest_ownership.c | 56 --- src/stest_signal.c | 23 -- src/test_runner.c | 699 ------------------------------------- src/test_runner.h | 69 ---- 14 files changed, 1336 deletions(-) delete mode 100644 packaging/libdbuspolicy_tests.spec delete mode 100644 src/cynara_prepare.sh delete mode 100644 src/dbus_daemon.c delete mode 100644 src/stest_common.c delete mode 100644 src/stest_common.h delete mode 100644 src/stest_cynara.c delete mode 100644 src/stest_method_call.c delete mode 100644 src/stest_ownership.c delete mode 100644 src/stest_signal.c delete mode 100644 src/test_runner.c delete mode 100644 src/test_runner.h diff --git a/Makefile.am b/Makefile.am index 941f6e6..30eec82 100644 --- a/Makefile.am +++ b/Makefile.am @@ -100,25 +100,6 @@ src_test_libdbuspolicy1_signal_LDADD = $(CYNARA_LIBS) \ src_test_libdbuspolicy1_method_LDADD = $(CYNARA_LIBS) \ src/libinternal.a -if ENABLE_STANDALONE_TESTS -bin_PROGRAMS = test_runner -test_runner_SOURCES = src/test_runner.c - -alonetestdir = ${bindir}/tests/ -alonetest_PROGRAMS = dbus_daemon stest_ownership stest_method_call stest_signal stest_cynara - -dbus_daemon_SOURCES = src/dbus_daemon.c -stest_ownership_SOURCES = src/stest_ownership.c src/stest_common.c -stest_method_call_SOURCES = src/stest_method_call.c src/stest_common.c -stest_signal_SOURCES = src/stest_signal.c src/stest_common.c -stest_cynara_SOURCES = src/stest_cynara.c src/stest_common.c - -stest_ownership_LDADD = src/libdbuspolicy1.la -stest_method_call_LDADD = src/libdbuspolicy1.la -stest_signal_LDADD = src/libdbuspolicy1.la -stest_cynara_LDADD = src/libdbuspolicy1.la -endif - if ENABLE_DOXYGEN CLEANFILES += documentation diff --git a/configure.ac b/configure.ac index 6d6dbf4..9c5aa73 100644 --- a/configure.ac +++ b/configure.ac @@ -50,7 +50,6 @@ AS_IF([test "x$enable_debug" = "xyes"], [ AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests], [Add API function that allows to change credentials during execution]), [with_tests=yes], with_tests=no) -AM_CONDITIONAL([ENABLE_STANDALONE_TESTS], [test x$with_tests = xyes]) if test "x$with_tests" = "xyes"; then AC_DEFINE(LIBDBUSPOLICY_TESTS_API, 1, [Define if tests are enabled]) fi diff --git a/packaging/libdbuspolicy_tests.spec b/packaging/libdbuspolicy_tests.spec deleted file mode 100644 index d8c7feb..0000000 --- a/packaging/libdbuspolicy_tests.spec +++ /dev/null @@ -1,59 +0,0 @@ -Name: libdbuspolicy-tests -Summary: Helper library -License: Apache-2.0 -Group: Base/IPC -Version: 1.0.0 -Release: 0 -Source: %{name}-%{version}.tar.gz -BuildRequires: boost-devel -BuildRequires: pkgconfig(cynara-client) - - -%description -This package contains contains integration tests for libdbuspolicy. - -%prep -%setup -q - -%build - -%reconfigure --libdir=%{_libdir} --prefix=/usr --enable-tests - -make -make check - -%install -make DESTDIR=%{buildroot} install -rm %{buildroot}%{_libdir}/libdbuspolicy1.la -rm %{buildroot}%{_includedir}/dbuspolicy/libdbuspolicy1.h -rm %{buildroot}%{_libdir}/pkgconfig/libdbuspolicy1.pc -rm %{buildroot}%{_libdir}/libdbuspolicy1.so - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/lib/%{name} -mv %{buildroot}%{_libdir}/libdbuspolicy1.so.* %{buildroot}%{_libdir}/dbus-tests/lib/%{name} - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/runner -mv %{buildroot}%{_bindir}/test_runner %{buildroot}%{_libdir}/dbus-tests/runner/%{name} - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/test-suites/%{name} -mv %{buildroot}%{_bindir}/tests/* %{buildroot}%{_libdir}/dbus-tests/test-suites/%{name}/ - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/configs/%{name} -install -m 0644 tests/system.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/ - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0644 tests/system.d/ownerships.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0644 tests/system.d/signals.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0644 tests/system.d/methods.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0644 tests/system.d/cynara.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0654 src/cynara_prepare.sh %{buildroot}%{_libdir}/dbus-tests/test-suites/%{name}/ - -%post -p /sbin/ldconfig -%postun -p /sbin/ldconfig - -%files -%defattr(-,root,root) -%{_libdir}/dbus-tests/lib/%{name}/libdbuspolicy1.so.* -%{_libdir}/dbus-tests/runner/%{name} -%{_libdir}/dbus-tests/test-suites/%{name}/* -%{_libdir}/dbus-tests/configs/%{name}/* diff --git a/src/cynara_prepare.sh b/src/cynara_prepare.sh deleted file mode 100644 index acc2401..0000000 --- a/src/cynara_prepare.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -if [ -z "${1}" ]; then - cyad -e "MANIFESTS" -u 200 -c L -p t -r y - cyad -e "USER_TYPE_ADMIN" -u 200 -c L -p t -r y -else - cyad -s -k "MANIFESTS" -u 200 -c L -p t -t $1 - cyad -s -k "USER_TYPE_ADMIN" -u 200 -c L -p t -t $1 -fi diff --git a/src/dbus_daemon.c b/src/dbus_daemon.c deleted file mode 100644 index 058106e..0000000 --- a/src/dbus_daemon.c +++ /dev/null @@ -1,236 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kdbus.h" - -#define KDBUS_SYSTEM_BUS_PATH "/sys/fs/kdbus/0-system/bus" - -#define KDBUS_ALIGN8(l) (((l) + 7) & ~7) -#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) -#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE) -#define KDBUS_ITEM_NEXT(item) \ - (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size)) -#define KDBUS_FOREACH(iter, first, _size) \ - for (iter = (first); \ - ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \ - ((uint8_t *)(iter) >= (uint8_t *)(first)); \ - iter = (void*)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size))) - -#define POOL_SIZE (16 * 1024 * 1024) - -#define err_r(_r, _msg) fprintf(stderr, "log: %d, %s, %s, %d, %s\n",(_r), (_msg), __func__, __LINE__, __FILE__) -#define err(_msg) err_r(errno, (_msg)) - -static uint8_t* pool; -static char* server_names[16]; -int ready_fd = 0; - -static inline int kdbus_cmd_hello(int bus_fd, struct kdbus_cmd_hello *cmd) -{ - int ret = ioctl(bus_fd, KDBUS_CMD_HELLO, cmd); - return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; -} - -static inline int kdbus_cmd_free(int conn_fd, struct kdbus_cmd_free *cmd) -{ - int ret = ioctl(conn_fd, KDBUS_CMD_FREE, cmd); - return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; -} - -static inline int kdbus_cmd_name_acquire(int conn_fd, struct kdbus_cmd *cmd) -{ - int ret = ioctl(conn_fd, KDBUS_CMD_NAME_ACQUIRE, cmd); - return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; -} - -static void bus_poool_free_slice(int fd, uint64_t offset) -{ - struct kdbus_cmd_free cmd = { - .size = sizeof(cmd), - .offset = offset, - }; - int r; - r = kdbus_cmd_free(fd, &cmd); - if (r < 0) - err_r(r, "cannot free pool slice"); -} - -static int bus_open_connection(const char *name, - uint64_t recv_flags) -{ - struct kdbus_cmd_hello hello; - int r; - int fd; - - fd = open(name, O_RDWR | O_CLOEXEC); - if (fd < 0) { - r = err("cannot open bus"); - goto error; - } - - memset(&hello, 0, sizeof(hello)); - hello.size = sizeof(hello); - hello.attach_flags_send = _KDBUS_ATTACH_ALL; - hello.attach_flags_recv = recv_flags; - hello.pool_size = POOL_SIZE; - r = kdbus_cmd_hello(fd, &hello); - if (r < 0) { - err_r(r, "HELLO failed"); - goto error; - } - - bus_poool_free_slice(fd, hello.offset); - - /* - * Map the pool of the connection. Its size has been set in the - * command struct above. See kdbus.pool(7). - */ - pool = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0); - if (pool == MAP_FAILED) { - r = err("cannot mmap pool"); - goto error; - } - - return fd; - -error: - return -1; -} - - - -static int bus_acquire_name(int fd, const char *name) -{ - struct kdbus_item *item; - struct kdbus_cmd *cmd; - size_t size; - int r; - - /* - * This function acquires a well-known name on the bus through the - * KDBUS_CMD_NAME_ACQUIRE ioctl. This ioctl takes an argument of type - * 'struct kdbus_cmd', which is assembled below. See kdbus.name(7). - */ - size = sizeof(*cmd); - size += KDBUS_ITEM_SIZE(strlen(name) + 1); - - cmd = alloca(size); - memset(cmd, 0, size); - cmd->size = size; - - /* - * The command requires an item of type KDBUS_ITEM_NAME, and its - * content must be a valid bus name. - */ - item = cmd->items; - item->type = KDBUS_ITEM_NAME; - item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; - strcpy(item->str, name); - - /* - * Employ the command on the connection owner file descriptor. - */ - r = kdbus_cmd_name_acquire(fd, cmd); - if (r < 0) - return err_r(r, "cannot acquire name"); - - return 0; -} - - -int parse_args(int argc, char** argv) -{ - char state = 0; - unsigned long int uid = 0; - unsigned long int gid = 0; - int i = 1; - int r = 0; - int fdl = -1; - int count = 0; - - while (i < argc) - { - if (argv[i][0] == '-') - state = argv[i][1]; - else { - switch (state) { - - case 'n': - server_names[count++] = argv[i]; - break; - - case 'u': - uid = strtoul(argv[i],NULL,10); - r = setuid((uid_t)uid); - if (r< 0) { - fprintf(stderr, "Cannot set uid"); - exit(-3245); - } - break; - - case 'g': - gid = strtoul(argv[i],NULL,10); - r = setgid((gid_t)gid); - if (r< 0) { - fprintf(stderr, "Cannot set gid"); - exit(-3245); - } - break; - - case 'l': - fdl = open("/proc/self/attr/current", 0, S_IWUSR); - if (fdl < 0) - { - fprintf(stderr,"Cannot open /proc/self/attr/current\n"); - exit(-345); - } - - r = write(fdl, argv[i], strlen(argv[i])); - if (r < 0) - { - fprintf(stderr, "Cannot write to /proc/self/attr/current\n"); - close(fdl); - exit(-345); - } - close(fdl); - break; - case 'q': - ready_fd = strtol(argv[i], NULL, 10); - break; - } - } - i++; - } - return 0; -} - -int main(int argc, char* argv[]) { - int j = 0; - int fd; - parse_args(argc, argv); - fd = bus_open_connection(KDBUS_SYSTEM_BUS_PATH, KDBUS_ATTACH_PIDS); - if (fd < 0) { - return -1; - } - - while(server_names[j] != '\0') - { - if (bus_acquire_name(fd, server_names[j])) - return -1; - j++; - } - - close(ready_fd); - - for(;;); - return 0; -} diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 11817ad..1721185 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -51,13 +51,6 @@ #define UID_INVALID ((uid_t) -1) #define GID_INVALID ((gid_t) -1) -#ifdef LIBDBUSPOLICY_TESTS_API -#undef SYSTEM_BUS_CONF_FILE_PRIMARY -#undef SESSION_BUS_CONF_FILE_PRIMARY -#define SYSTEM_BUS_CONF_FILE_PRIMARY "/usr/lib/dbus-tests/configs/libdbuspolicy-tests/system.conf" -#define SESSION_BUS_CONF_FILE_PRIMARY "/usr/lib/dbus-tests/configs/libdbuspolicy-tests/session.conf" -#endif - /** A process ID */ typedef unsigned long dbus_pid_t; /** A user ID */ diff --git a/src/stest_common.c b/src/stest_common.c deleted file mode 100644 index 8cb9f35..0000000 --- a/src/stest_common.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include - -uint64_t test_cases_mask = ~(0ULL); -int test_count = 0; - -void assert_printf(int res, int tc, const char* value, int line, const char* file) -{ - if (res) { - printf("[r][%d]1\n", tc); - } else { - printf("[r][%d]0\n", tc); - fprintf(stderr, "[r][%d]0<-w=%s, line=%d, file=%s\n", tc, value, line, file); - } -} - -void prepare_mask(int argc, char* argv[]) -{ - if (argc > 1) - { - int i = 1; - test_cases_mask = 0; - for (;i < argc; i++) { - int val = strtol(argv[i], NULL, 10); - if (val >= 0) - test_cases_mask |= (1< - -#define assert(v) \ - do { \ - if (test_cases_mask & (1 << test_count)) \ - { \ - int ___r = (v); \ - assert_printf(___r, test_count, #v, __LINE__, __FILE__); \ - } \ - test_count++; \ - } while (0) - -enum { - false, - true -}; - -extern uint64_t test_cases_mask; -extern int test_count; -void prepare_mask(int argc, char* argv[]); -void assert_printf(int res, int tc, const char* value, int line, const char* file); diff --git a/src/stest_cynara.c b/src/stest_cynara.c deleted file mode 100644 index db885f8..0000000 --- a/src/stest_cynara.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include -#include -#include -#include "stest_common.h" - -#define NEGATIVE_MATCH "negative" - -void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); - -int main(int argc, char* argv[]) -{ - void* c = NULL; - int result = true; - - prepare_mask(argc,argv); - - if (!strncmp(argv[0], NEGATIVE_MATCH, sizeof(NEGATIVE_MATCH)-1)) - result = false; - - printf("---result: %d %s\n\n", result, argv[0]); - assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); - - __dbuspolicy1_change_creds(c,200,0,"L"); - assert(dbuspolicy1_check_in(c, "cynara.destination", "cynara.sender", "L", 200, 0, NULL, "cynara.interface", "cynara.method", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == result); - - assert(dbuspolicy1_check_in(c, "cynara.destination", "cynara.sender", "L", 200, 0, NULL, "cynara.interface", "cynara.method", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == result); - return 0; -} diff --git a/src/stest_method_call.c b/src/stest_method_call.c deleted file mode 100644 index 7507659..0000000 --- a/src/stest_method_call.c +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include -#include "stest_common.h" - -void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); - -int main(int argc, char* argv[]) -{ - void* c = NULL; - - prepare_mask(argc,argv); - - assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", NULL, "org.test.Itest1", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", NULL, 0, 0, "", "org.test.Itest1", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest1", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest1", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest1", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest1", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest2", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest2", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "", "org.test.Itest3", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "", "org.test.Itest3", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "" ,"org.test.Itest3", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test9", "org.test.test10", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test9", "org.test.test10", "", 5001, 100, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test10", "org.test.test9", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test10", "org.test.test9", "", 0, 0, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - return 0; -} diff --git a/src/stest_ownership.c b/src/stest_ownership.c deleted file mode 100644 index a6c191b..0000000 --- a/src/stest_ownership.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include "stest_common.h" - -void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); - -int main(int argc, char* argv[]) -{ - void* c = NULL; - - prepare_mask(argc,argv); - - assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test1")); - - __dbuspolicy1_change_creds(c, 5009, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test1")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test2")); - - __dbuspolicy1_change_creds(c, 5009, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test2")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test3")); - - __dbuspolicy1_change_creds(c, 5009, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test3")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test4")); - - __dbuspolicy1_change_creds(c, 5009, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test4")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test5")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test6")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test7")); - - assert(dbuspolicy1_can_own(c, "a.b.c")); - assert(dbuspolicy1_can_own(c, "a.b")); - assert(!dbuspolicy1_can_own(c, "c")); - assert(!dbuspolicy1_can_own(c, "a.c")); - assert(!dbuspolicy1_can_own(c, "b.c")); - - return 0; -} diff --git a/src/stest_signal.c b/src/stest_signal.c deleted file mode 100644 index 165c90e..0000000 --- a/src/stest_signal.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include -#include "stest_common.h" - -void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); - -int main(int argc, char* argv[]) -{ - void* c = NULL; - - prepare_mask(argc,argv); - - assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "", "bli.bla.blubb test.test1 test.tes3", "", "/an/object/path", "", DBUSPOLICY_MESSAGE_TYPE_SIGNAL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5010,0,NULL); - assert(dbuspolicy1_check_out(c, "", "bli.bla.blubb", "", "/an/object/path", "", DBUSPOLICY_MESSAGE_TYPE_SIGNAL, "", 0, 0) == false); - - return 0; -} diff --git a/src/test_runner.c b/src/test_runner.c deleted file mode 100644 index 81c4e0e..0000000 --- a/src/test_runner.c +++ /dev/null @@ -1,699 +0,0 @@ -/* This file contains test-runner for libdbuspolicy - * - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * Author: Kazimierz Krosman - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "test_runner.h" - -enum { - PIPE_READ, - PIPE_WRITE, -}; - -/*****************CUSTOM SECTION***********************************/ -/*custom function that parse stdout of binary and result of binary*/ -void parse_test_state(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); -void parse_one_test_one_binary(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); -char** prepare_args_for_binary(const struct binary* b, const char* test_name); -int daemon_init(void); -int daemon_clear(void); -int cynara_init(void); -int cynara_clear(void); -int cynara_n_init(void); -int cynara_n_clear(void); - -static struct test_case ownership_test_cases[] = { - {"0", "Libdbuspolicy1 init function call"}, - {"1", "Simple check for ownership in default context"}, - {"2", "Simple check for ownership in default context"}, - {"3", "Ownership check in user context"}, - {"4", "Ownership check in user context (negative test)"}, - {"5", "Ownership check in mandatory context with user context (context priority check)"}, - {"6", "Ownership check in mandatory context with user context (for another user)"}, - {"7", "Ownership check for not root user context (negative test)"}, - {"8", "Ownership check for not root user context"}, - {"9", "Ownership check for group context"}, - {"10", "Ownership check for all context (priority check)"}, - {"11", "Ownership check for all context (priority check)"}, - {"12", "Ownership check for own_prefix case (1)"}, - {"13", "Ownership check for own_prefix case (2)"}, - {"14", "Ownership check for own_prefix case (negative test)"}, - {"15", "Ownership check for own_prefix case (negative test)"}, - {"16", "Ownership check for own_prefix case (negative test)"}, - {NULL, NULL} -}; - -static struct test_case method_call_test_cases[] = { - {"0", "Libdbuspolicy1 init function call"}, - {"1", "check_out test"}, - {"2", "check_in test"}, - {"3", "check_out test"}, - {"4", "check_in test"}, - {"5", "check_out test"}, - {"6", "check_in test"}, - {"7", "check_out test"}, - {"8", "check_in test"}, - {"9", "check_out test"}, - {"10", "check_in test"}, - {"11", "check_out test"}, - {"12", "check_in test"}, - {"13", "check_out test"}, - {"14", "check_in test"}, - {"15", "check_out test"}, - {"16", "check_in test"}, - {"17", "check_out test"}, - {"18", "check_in test"}, - {"19", "check_out test"}, - {"20", "check_in test"}, - {NULL, NULL} -}; - -static struct test_case signal_test_cases[] = { - {"1", "Libdbuspolicy1 init"}, - {"2", "Check out for signal"}, - {"3", "Check out for signal (negative)"}, - {NULL, NULL} -}; - -static struct test_case cynara_test_cases[] = { - {"0", "Libdbuspolicy1 init function call"}, - {"1", "Check cynara for result"}, - {"2", "Check cynara for result (second attempt to use cache)"}, - {NULL, NULL} -}; - -static struct test_case negative_cynara_test_cases[] = { - {"0", "Libdbuspolicy1 init function call"}, - {"1", "Check cynara for result (negative test)"}, - {"2", "Check cynara for result (second attempt to use cache) (negative test)"}, - {NULL, NULL} -}; - -/* This table is used to start binaries */ -struct binary tests[] = { -/*path, name, TC_table, timeout in us, prepare_args_handler, parse_function_handler, init_handler, clean_handler*/ - {TEST_PATH "stest_ownership", "ownership", ownership_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, - {TEST_PATH "stest_method_call", "method_call", method_call_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, - {TEST_PATH "stest_signal", "signal", signal_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, - {TEST_PATH "stest_cynara", "cynara", cynara_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, cynara_init, cynara_clear}, - {TEST_PATH "stest_cynara", "negative_cynara", negative_cynara_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, cynara_n_init, cynara_n_clear}, -}; - - -static const char result_pattern[] = "[r][%0]%1"; -static struct state { - unsigned int i; // index of input buffer - unsigned int j; // index in results[n] - unsigned int n; //index in results buffer (0 or 1) - char results[2][MAX_COMMENT]; -} g_state; - -static void sm_reset(void) -{ - memset(&g_state, 0, sizeof (g_state)); -} - -static int sm_update(char* buffer, int i) -{ - int l = strlen(buffer) + 1; - while (i < l && g_state.i < sizeof(result_pattern) - 1) { - if (result_pattern[g_state.i] == '%') { - g_state.n = result_pattern[g_state.i+1] - '0'; - if (g_state.n > 1) { - sm_reset(); - i--; - } else if (isalnum(buffer[i])) { - g_state.results[g_state.n][g_state.j++] = buffer[i]; - } else if (buffer[i] == result_pattern[g_state.i+2] || buffer[i] == '\n') { - g_state.results[g_state.n][g_state.j] = 0; - g_state.i += 3; - g_state.j = 0; - if (g_state.n == 1) - return i; - } else { - g_state.i = 0; - g_state.j = 0; - } - } else if (result_pattern[g_state.i] == buffer[i]) { - g_state.i++; - } else { - sm_reset(); - } - i++; - } - - if (g_state.i >= sizeof(result_pattern) - 1) { - g_state.results[g_state.n][g_state.j] = 0; - g_state.i += 3; - g_state.j = 0; - if (g_state.n == 1) - return i; - } - - return 0; -} - -static const char* sm_get_result(int i) -{ - return g_state.results[i]; -} - -static pid_t daemon_pids[4] ={0}; -static int daemons_pipe[4][2]; -static char* daemon_argv1[] = {TEST_PATH "dbus_daemon", "-q", NULL, "-n","org.test.test3", NULL}; -static char* daemon_argv2[] = {TEST_PATH "dbus_daemon", "-q", NULL,"-n", "org.test.test2", "-g", "100", "-u", "5001", NULL}; -static char* daemon_argv3[] = {TEST_PATH "dbus_daemon", "-q", NULL,"-n", "org.test.test12", "org.test.test9", NULL}; -static char* daemon_argv4[] = {TEST_PATH "dbus_daemon", "-q", NULL, "-n", "org.test.test13", "org.test.test10", "org.test.test11", "-g", "100", "-u", "5001", NULL}; -static char** daemons[] = { daemon_argv1, daemon_argv2, daemon_argv3, daemon_argv4}; - -int daemon_init(void) -{ - int i = 0; - int ready_proc = 0; - struct timeval tv; - fd_set rfds; - int nfds = -1; - int proc_num = sizeof(daemons)/sizeof(daemons[0]); - - for (;i < proc_num;i++) { - if (pipe(daemons_pipe[i]) < 0) { - perror("cannot create pipe"); - goto error1; - } - - daemon_pids[i] = fork(); - if (!daemon_pids[i]) { - char fdd[15]; - sprintf(fdd,"%d",daemons_pipe[i][PIPE_WRITE]); - daemons[i][2] = fdd; - close (daemons_pipe[i][PIPE_READ]); - (void)execv(daemons[i][0],daemons[i]); - exit(0); - } else if (daemon_pids[i] > 0){ - close (daemons_pipe[i][PIPE_WRITE]); - } else - goto error1; - } - - tv.tv_sec = 1; - tv.tv_usec = 0; - while(1) { - FD_ZERO(&rfds); - for (i = 0; i < proc_num;i++) { - if (daemons_pipe[i][PIPE_READ] > -1) - FD_SET(daemons_pipe[i][PIPE_READ], &rfds); - } - - if (ready_proc >= proc_num) - break; - - nfds = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); - if (nfds > 0) { - for (i = 0; i < proc_num;i++) { - if (daemons_pipe[i][PIPE_READ] > -1 && FD_ISSET(daemons_pipe[i][PIPE_READ], &rfds)) { - ++ready_proc; - close (daemons_pipe[i][PIPE_READ]); - daemons_pipe[i][PIPE_READ] = -1; - } - } - } else - goto error1; - } - - return 1; -error1: - daemon_clear(); - return 0; -} - -int daemon_clear(void) -{ - unsigned int i = 0; - for (;i < sizeof(daemons)/sizeof(daemons[0]);i++) { - if (daemon_pids[i]) - kill(daemon_pids[i], SIGKILL); - } - return 0; -} - -static int call_script(char* path, char* argv[]) -{ - int status; - int r; - pid_t pid = fork(); - - if (pid < 0) - return 0; - else if (!pid) { - (void)execv(path, argv); - exit(-1); - } - - r = waitpid(pid, &status, 0); - if (r > 0) { - if (WIFEXITED(status)) - return !(WEXITSTATUS(status)); - else if (WIFCONTINUED(status)) - kill(pid, SIGKILL); - } - - /* fail */ - return 0; -} - -int cynara_n_init(void) -{ - char* argv[] = {CYNARA_PATH, "DENY", NULL}; - return call_script(argv[0],argv); -} - -int cynara_n_clear(void) -{ - return cynara_clear(); -} - -int cynara_init(void) -{ - char* argv[] = {CYNARA_PATH, "ALLOW", NULL}; - return call_script(argv[0],argv); -} - -int cynara_clear(void) -{ - char* argv[] = {CYNARA_PATH, NULL}; - return call_script(argv[0],argv); -} - -static char* args[3]; -char** prepare_args_for_binary(const struct binary* b, const char* test_name) -{ - args[0] = (char*)b->name; - if (!test_name[0]) - args[1] = NULL; - else { - args[1] = (char*)test_name; - args[2] = NULL; - } - return args; -} - - -/* - * Example of test_result detector function implementation - */ -void parse_test_state(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option) -{ - char test_id[MAX_COMMENT]; - - switch(state_change) { - case INIT_TEST: - sm_reset(); - break; - case NEW_STDOUT: - { - int k = 0; - buffer[state_option] = 0; - get_test_id(test_id, b, test_name); - fprintf(stderr, "[stdout][%s]%s\n",test_id, buffer); - while ( (k = sm_update(buffer, k))) { - const char* t_name = sm_get_result(0); - const char* result_code = sm_get_result(1); - bool is_successful = result_code[0] == '1' && result_code[1] == 0; - const char* result_text = is_successful ? "PASS" : "FAIL"; - - get_test_id(test_id, b, t_name); - add_test_result(test_id, result_text, "", is_successful); - sm_reset(); - } - } - break; - case NEW_STDERR: - buffer[state_option] = 0; - get_test_id(test_id, b, test_name); - fprintf(stderr, "[stderr][%s]%s\n",test_id, buffer); - break; - case RESULT_CODE: - if (state_option != 0) - add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Test exited with error code", 0); - break; - case RESULT_SIGNAL: - add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Finished by SIGNAL", 0); - break; - case RESULT_TIMEOUT: - add_test_result(get_test_id(test_id, b, test_name), "FAIL", "Test TIMEOUT", 0); - break; - } -} - -/****************************END of CUSTOM FUNCTIONS************************/ - - -static struct option long_options[] = { - {"list", no_argument, 0, 'l'}, - {"run", required_argument, 0, 'r'}, - {"description", required_argument, 0, 'd'}, - {0, 0, 0, 0 } -}; - -static int stdin_pipe[2]; -static int stdout_pipe[2]; -static int stderr_pipe[2]; -static struct test_result test_results[MAX_TC_NUM]; -static int test_results_i; -static char buffer[MAX_BUFFER]; -static const char* requested_tc[MAX_TC_NUM]; - -char* get_test_id(char* dest, const struct binary* b, const char* test_name) -{ - int len = strlen(b->name); - memcpy(dest, b->name, len); - memcpy(dest + len, test_name, strlen(test_name)+1); - return dest; -} - -static void print_description(const char* name, const char* description) -{ - printf("%s;%s\n",name, description); -} - -static void print_list(const char* test_name) -{ - unsigned int i; - char full_name[MAX_COMMENT]; - for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) { - int j = 0; - int l = strlen(tests[i].name); - memcpy(full_name, tests[i].name, l+1); - if (test_name && strncmp(test_name, full_name, l) != 0) - continue; - - while (tests[i].test_cases[j].name) { - memcpy(full_name + l, tests[i].test_cases[j].name, strlen(tests[i].test_cases[j].name) + 1); - if (!test_name || strcmp(full_name, test_name) == 0) - print_description(full_name,tests[i].test_cases[j].description); - j++; - } - } -} - - -static void stop_binary(const struct binary* b, pid_t pid, const char* test_name) -{ - int status = 0; - int res = 0; - res = waitpid(pid, &status, 0); - if (res == 0) { - //timeouted - kill(pid, SIGKILL); - res = waitpid(pid, &status, WNOHANG); - b->parse(b, test_name, buffer, RESULT_TIMEOUT, res); - } else if (res < 0) { - //errno check - kill(pid, SIGKILL); - res = waitpid(pid, &status, WNOHANG); - b->parse(b, test_name, buffer, RESULT_ERROR, res); - } else if (res > 0) { - if (WIFEXITED(status)) { - b->parse(b, test_name, buffer, RESULT_CODE, WEXITSTATUS(status)); - } else if (WIFSIGNALED(status)) { - b->parse(b, test_name, buffer, RESULT_SIGNAL, WTERMSIG(status)); - } else if (WIFSTOPPED(status)) { - b->parse(b, test_name, buffer, RESULT_SIGNAL, WSTOPSIG(status)); - } else if (WIFCONTINUED(status)) { - kill(pid, SIGKILL); - b->parse(b, test_name, buffer, RESULT_SIGNAL, -1); - } - } -} - -static void parse_output_with_timeout(const struct binary* b, pid_t pid, const char* test_name) -{ - struct timeval tv; - fd_set rfds; - int nfds; - int res; - tv.tv_sec = b->timeout/(1000*1000); - tv.tv_usec = (b->timeout-tv.tv_sec*1000*1000); - while (1) { - FD_ZERO(&rfds); - FD_SET(stdout_pipe[PIPE_READ], &rfds); - FD_SET(stderr_pipe[PIPE_READ], &rfds); - nfds = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); - if (nfds == -1) { - if (errno != EINTR) - break; - } else if (nfds > 0) { - if (FD_ISSET(stdout_pipe[PIPE_READ], &rfds)) { - res = read(stdout_pipe[PIPE_READ], buffer, MAX_BUFFER-1); - if (res == 0 || (res < 0 && errno != EINTR)) - break; - else if (res >=0) - b->parse(b, test_name, buffer, NEW_STDOUT, res); - } - - if (FD_ISSET(stderr_pipe[PIPE_READ], &rfds)) { - res = read(stderr_pipe[PIPE_READ], buffer, MAX_BUFFER-1); - if (res == 0 || (res < 0 && errno != EINTR)) - break; - b->parse(b, test_name, buffer, NEW_STDERR, res); - } - } else { - //timeout - break; - } - } - stop_binary(b, pid, test_name); -} - -static int create_child(const char* path, char* const arguments[]) -{ - int child; - int nResult; - if (pipe(stdin_pipe) < 0) { - perror("allocating pipe for child input redirect failed"); - goto error1; - } - - if (pipe(stdout_pipe) < 0) { - perror("allocating pipe for child output redirect failed"); - goto error2; - } - - if (pipe(stderr_pipe) < 0) { - perror("allocating pipe for child output redirect failed"); - goto error3; - } - - child = fork(); - if (!child) { - char ld_path[512]; - sprintf(ld_path, "/usr/lib/dbus-tests/lib/libdbuspolicy-tests/:"); - // redirect stdin - if (dup2(stdin_pipe[PIPE_READ], STDIN_FILENO) == -1) { - perror("redirecting stdin failed"); - return -1; - } - - // redirect stdout - if (dup2(stdout_pipe[PIPE_WRITE], STDOUT_FILENO) == -1) { - perror("redirecting stdout failed"); - return -1; - } - - // redirect stderr - if (dup2(stderr_pipe[PIPE_WRITE], STDERR_FILENO) == -1) { - perror("redirecting stderr failed"); - return -1; - } - - // all these are for use by parent only - close(stdin_pipe[PIPE_READ]); - close(stdin_pipe[PIPE_WRITE]); - close(stdout_pipe[PIPE_READ]); - close(stdout_pipe[PIPE_WRITE]); - close(stderr_pipe[PIPE_READ]); - close(stderr_pipe[PIPE_WRITE]); - - char* ld_path_b = getenv("LD_LIBRARY_PATH"); - if (ld_path_b != NULL) - memcpy(ld_path + strlen(ld_path), ld_path_b, strlen(ld_path_b)+1); - setenv("LD_LIBRARY_PATH", ld_path, 1); - // run child process image - nResult = execv(path, arguments); - - // if we get here at all, an error occurred, but we are in the child - // process, so just exit - perror("exec of the child process failed"); - exit(nResult); - } else if (child > 0) { - // parent continues here - - // close unused file descriptors, these are for child only - close(stdin_pipe[PIPE_READ]); - close(stdout_pipe[PIPE_WRITE]); - close(stderr_pipe[PIPE_WRITE]); - } else { - // failed to create child - goto error4; - } - - return child; - -error4: - close(stderr_pipe[PIPE_READ]); - close(stderr_pipe[PIPE_WRITE]); -error3: - close(stdout_pipe[PIPE_READ]); - close(stdout_pipe[PIPE_WRITE]); -error2: - close(stdin_pipe[PIPE_READ]); - close(stdin_pipe[PIPE_WRITE]); -error1: - return -1; -} - -static void run_test(const struct binary* b, const char* test_name) -{ - int res = -1; - char** arg; - char test_id[MAX_COMMENT]; - - assert(b); - assert(b->name); - assert(b->path); - assert(test_name); - - arg = b->prepare_args(b, test_name); - - if (b->init) - if (!b->init()) { - add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Internal error: Cannot init test", 0); - return; - } - - res = create_child(b->path, arg); - if (res > 0) - parse_output_with_timeout(b, res, test_name); - else - add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Internal error: Cannot start test", 0); - - if (b->clean) - b->clean(); -} - -static void parse_run_test(const char* tc) { - unsigned int i = 0; - for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) { - int len = strlen(tests[i].name); - if (strncmp(tc, tests[i].name, len) == 0) { - if (tc[len] == '*' || tc[len] == '\0') - run_test(&tests[i], ""); - else - run_test(&tests[i], tc + len); - } - } -} - -static int parse_option(int argc, char* argv[]) -{ - int ch = 0; - int c = 0; - while ((ch = getopt_long(argc, argv, "lr:d:", long_options, NULL)) != -1) { - switch (ch) { - case 'l': - print_list(NULL); - return 1; - case 'r': - if (c >= MAX_TC_NUM - 1) //NULL at the end - return 0; - - if (optarg) - requested_tc[c++] = optarg; - - break; - case 'd': - print_list(optarg); - return 1; - } - } - return 0; -} - -//output_new/fail/success -void add_test_result(const char* test_id, const char* result, const char* comment, int res) -{ - test_results[test_results_i].is_positive = res; - strcpy(test_results[test_results_i].result, result); - strcpy(test_results[test_results_i].comment, comment); - strcpy(test_results[test_results_i++].name, test_id); -} - -static void prepare_results(void) -{ - //todo -} - -static void print_results() -{ - int i = 0; - for (i = 0; i < test_results_i; i++) - { - printf("%s;%s;%s\n", test_results[i].name, test_results[i].result, test_results[i].comment); - } -} - -int main(int argc, char* argv[]) -{ - unsigned int i; - signal(SIGPIPE, SIG_IGN); - if (parse_option(argc, argv)) - return 0; - - prepare_results(); - - if (!requested_tc[0]) { - for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) - run_test(&tests[i], ""); - } else { - i = 0; - while(requested_tc[i]) { - parse_run_test(requested_tc[i]); - i++; - } - } - - print_results(); - return 0; -} diff --git a/src/test_runner.h b/src/test_runner.h deleted file mode 100644 index 3c79a99..0000000 --- a/src/test_runner.h +++ /dev/null @@ -1,69 +0,0 @@ -/* This file is part of test-runner (see template.c) - * - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * Author: Kazimierz Krosman - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#ifndef TEST_RUNNER_H -#define TEST_RUNNER_H -#include - -#define TC_NAME "libdbuspolicy-tests" -#define TEST_PATH "/usr/lib/dbus-tests/test-suites/libdbuspolicy-tests/" -#define CYNARA_PATH TEST_PATH "cynara_prepare.sh" -#define MAX_TC_NUM 1024 -#define MAX_BUFFER (64*1024) -#define MAX_COMMENT 1024 - -enum { - INIT_TEST, - NEW_STDOUT, - NEW_STDERR, - RESULT_CODE, - RESULT_SIGNAL, - RESULT_ERROR, - RESULT_TIMEOUT -}; - -struct test_result { - bool is_positive; - char comment[MAX_COMMENT]; - char result[MAX_COMMENT]; - char name[MAX_COMMENT]; -}; - -struct test_case { - const char* name; - const char* description; -}; - -struct binary { - const char* path; - const char* name; - /* can be filled by asking binary */ - struct test_case* test_cases; - int timeout; - - char** (*prepare_args) (const struct binary* b, const char* test_name); - void (*parse) (const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); - int (*init)(void); - int (*clean)(void); -}; - -char* get_test_id(char* dest, const struct binary* b, const char* test_name); -void add_test_result(const char* test_id, const char* result, const char* comment, int res); - - -#endif /* TEST_RUNNER_H */ -- 2.7.4 From 259df82e824f82949e024f8852a310d6a08e9271 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Tue, 6 Dec 2016 21:22:59 +0900 Subject: [PATCH 02/16] svace:handling wrong policy syntax Change-Id: I6230b4487625240a0ee9f422c0203f0ec33a5d19 Signed-off-by: sanghyeok.oh --- src/internal/policy.cpp | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) mode change 100644 => 100755 src/internal/policy.cpp diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp old mode 100644 new mode 100755 index d4ab166..3bc5fce --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -19,6 +19,9 @@ static const char* message_dir[] = { "ANY", "SEND", "RECEIVE"}; static const char* message_decision[] = {"NO_DECISION", "ALLOW", "DENY", "CHECK"}; static MessageType __str_to_message_type(const char* str) { + if (!str) + return MessageType::ANY; + if (!std::strcmp(str, "method_call")) return MessageType::METHOD_CALL; else if (!std::strcmp(str, "method_return")) @@ -113,23 +116,22 @@ void DbAdapter::updateDecision(const boost::property_tree::ptree::value_type& v, if (v.second.data() != "*") value = v.second.data().c_str(); - if (v.first == "context") { - if (std::strcmp(value, "mandatory") == 0 ) { - policy_type = PolicyType::CONTEXT; - policy_type_value.context = ContextType::MANDATORY; - } else if (std::strcmp(value, "default") == 0) { - policy_type = PolicyType::CONTEXT; - policy_type_value.context = ContextType::DEFAULT; + if (value) { + if (v.first == "context") { + if (std::strcmp(value, "mandatory") == 0 ) { + policy_type = PolicyType::CONTEXT; + policy_type_value.context = ContextType::MANDATORY; + } else if (std::strcmp(value, "default") == 0) { + policy_type = PolicyType::CONTEXT; + policy_type_value.context = ContextType::DEFAULT; + } + } else if (v.first == "user") { + policy_type = PolicyType::USER; + policy_type_value.user = convertToUid(value); + } else if (v.first == "group") { + policy_type = PolicyType::GROUP; + policy_type_value.group = convertToGid(value); } - } else if (v.first == "user") { - policy_type = PolicyType::USER; - policy_type_value.user = convertToUid(value); - } else if (v.first == "group") { - policy_type = PolicyType::GROUP; - policy_type_value.group = convertToGid(value); - } else { - attr = false; - t = NONE; } } else if (attr && t == ALLOW_DENY_CHECK) { if (v.second.data() != "*") -- 2.7.4 From ac5104410561ac7407c7ea853c902c5210c799d3 Mon Sep 17 00:00:00 2001 From: sanghyeok oh Date: Thu, 1 Dec 2016 21:05:33 -0800 Subject: [PATCH 03/16] Revert "tests: Add test package for libdbuspolicy" This reverts commit bb7d32bb63f1d0fc463255000fbc773a119314a9. Change-Id: I6bc92edf4cd438c07f6ed99acf4e8bfe531d1d1a (cherry picked from commit 376f38dafa0b7ee5eae3d8f0ba0333c84a79742d) --- Makefile.am | 19 - configure.ac | 1 - packaging/libdbuspolicy_tests.spec | 59 ---- src/cynara_prepare.sh | 8 - src/dbus_daemon.c | 236 ------------- src/libdbuspolicy1.c | 7 - src/stest_common.c | 31 -- src/stest_common.h | 21 -- src/stest_cynara.c | 30 -- src/stest_method_call.c | 77 ---- src/stest_ownership.c | 56 --- src/stest_signal.c | 23 -- src/test_runner.c | 699 ------------------------------------- src/test_runner.h | 69 ---- 14 files changed, 1336 deletions(-) delete mode 100644 packaging/libdbuspolicy_tests.spec delete mode 100644 src/cynara_prepare.sh delete mode 100644 src/dbus_daemon.c delete mode 100644 src/stest_common.c delete mode 100644 src/stest_common.h delete mode 100644 src/stest_cynara.c delete mode 100644 src/stest_method_call.c delete mode 100644 src/stest_ownership.c delete mode 100644 src/stest_signal.c delete mode 100644 src/test_runner.c delete mode 100644 src/test_runner.h diff --git a/Makefile.am b/Makefile.am index 941f6e6..30eec82 100644 --- a/Makefile.am +++ b/Makefile.am @@ -100,25 +100,6 @@ src_test_libdbuspolicy1_signal_LDADD = $(CYNARA_LIBS) \ src_test_libdbuspolicy1_method_LDADD = $(CYNARA_LIBS) \ src/libinternal.a -if ENABLE_STANDALONE_TESTS -bin_PROGRAMS = test_runner -test_runner_SOURCES = src/test_runner.c - -alonetestdir = ${bindir}/tests/ -alonetest_PROGRAMS = dbus_daemon stest_ownership stest_method_call stest_signal stest_cynara - -dbus_daemon_SOURCES = src/dbus_daemon.c -stest_ownership_SOURCES = src/stest_ownership.c src/stest_common.c -stest_method_call_SOURCES = src/stest_method_call.c src/stest_common.c -stest_signal_SOURCES = src/stest_signal.c src/stest_common.c -stest_cynara_SOURCES = src/stest_cynara.c src/stest_common.c - -stest_ownership_LDADD = src/libdbuspolicy1.la -stest_method_call_LDADD = src/libdbuspolicy1.la -stest_signal_LDADD = src/libdbuspolicy1.la -stest_cynara_LDADD = src/libdbuspolicy1.la -endif - if ENABLE_DOXYGEN CLEANFILES += documentation diff --git a/configure.ac b/configure.ac index 6d6dbf4..9c5aa73 100644 --- a/configure.ac +++ b/configure.ac @@ -50,7 +50,6 @@ AS_IF([test "x$enable_debug" = "xyes"], [ AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests], [Add API function that allows to change credentials during execution]), [with_tests=yes], with_tests=no) -AM_CONDITIONAL([ENABLE_STANDALONE_TESTS], [test x$with_tests = xyes]) if test "x$with_tests" = "xyes"; then AC_DEFINE(LIBDBUSPOLICY_TESTS_API, 1, [Define if tests are enabled]) fi diff --git a/packaging/libdbuspolicy_tests.spec b/packaging/libdbuspolicy_tests.spec deleted file mode 100644 index d8c7feb..0000000 --- a/packaging/libdbuspolicy_tests.spec +++ /dev/null @@ -1,59 +0,0 @@ -Name: libdbuspolicy-tests -Summary: Helper library -License: Apache-2.0 -Group: Base/IPC -Version: 1.0.0 -Release: 0 -Source: %{name}-%{version}.tar.gz -BuildRequires: boost-devel -BuildRequires: pkgconfig(cynara-client) - - -%description -This package contains contains integration tests for libdbuspolicy. - -%prep -%setup -q - -%build - -%reconfigure --libdir=%{_libdir} --prefix=/usr --enable-tests - -make -make check - -%install -make DESTDIR=%{buildroot} install -rm %{buildroot}%{_libdir}/libdbuspolicy1.la -rm %{buildroot}%{_includedir}/dbuspolicy/libdbuspolicy1.h -rm %{buildroot}%{_libdir}/pkgconfig/libdbuspolicy1.pc -rm %{buildroot}%{_libdir}/libdbuspolicy1.so - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/lib/%{name} -mv %{buildroot}%{_libdir}/libdbuspolicy1.so.* %{buildroot}%{_libdir}/dbus-tests/lib/%{name} - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/runner -mv %{buildroot}%{_bindir}/test_runner %{buildroot}%{_libdir}/dbus-tests/runner/%{name} - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/test-suites/%{name} -mv %{buildroot}%{_bindir}/tests/* %{buildroot}%{_libdir}/dbus-tests/test-suites/%{name}/ - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/configs/%{name} -install -m 0644 tests/system.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/ - -mkdir -p %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0644 tests/system.d/ownerships.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0644 tests/system.d/signals.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0644 tests/system.d/methods.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0644 tests/system.d/cynara.test.conf %{buildroot}%{_libdir}/dbus-tests/configs/%{name}/system.d/ -install -m 0654 src/cynara_prepare.sh %{buildroot}%{_libdir}/dbus-tests/test-suites/%{name}/ - -%post -p /sbin/ldconfig -%postun -p /sbin/ldconfig - -%files -%defattr(-,root,root) -%{_libdir}/dbus-tests/lib/%{name}/libdbuspolicy1.so.* -%{_libdir}/dbus-tests/runner/%{name} -%{_libdir}/dbus-tests/test-suites/%{name}/* -%{_libdir}/dbus-tests/configs/%{name}/* diff --git a/src/cynara_prepare.sh b/src/cynara_prepare.sh deleted file mode 100644 index acc2401..0000000 --- a/src/cynara_prepare.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -if [ -z "${1}" ]; then - cyad -e "MANIFESTS" -u 200 -c L -p t -r y - cyad -e "USER_TYPE_ADMIN" -u 200 -c L -p t -r y -else - cyad -s -k "MANIFESTS" -u 200 -c L -p t -t $1 - cyad -s -k "USER_TYPE_ADMIN" -u 200 -c L -p t -t $1 -fi diff --git a/src/dbus_daemon.c b/src/dbus_daemon.c deleted file mode 100644 index 058106e..0000000 --- a/src/dbus_daemon.c +++ /dev/null @@ -1,236 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "kdbus.h" - -#define KDBUS_SYSTEM_BUS_PATH "/sys/fs/kdbus/0-system/bus" - -#define KDBUS_ALIGN8(l) (((l) + 7) & ~7) -#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) -#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE) -#define KDBUS_ITEM_NEXT(item) \ - (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size)) -#define KDBUS_FOREACH(iter, first, _size) \ - for (iter = (first); \ - ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \ - ((uint8_t *)(iter) >= (uint8_t *)(first)); \ - iter = (void*)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size))) - -#define POOL_SIZE (16 * 1024 * 1024) - -#define err_r(_r, _msg) fprintf(stderr, "log: %d, %s, %s, %d, %s\n",(_r), (_msg), __func__, __LINE__, __FILE__) -#define err(_msg) err_r(errno, (_msg)) - -static uint8_t* pool; -static char* server_names[16]; -int ready_fd = 0; - -static inline int kdbus_cmd_hello(int bus_fd, struct kdbus_cmd_hello *cmd) -{ - int ret = ioctl(bus_fd, KDBUS_CMD_HELLO, cmd); - return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; -} - -static inline int kdbus_cmd_free(int conn_fd, struct kdbus_cmd_free *cmd) -{ - int ret = ioctl(conn_fd, KDBUS_CMD_FREE, cmd); - return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; -} - -static inline int kdbus_cmd_name_acquire(int conn_fd, struct kdbus_cmd *cmd) -{ - int ret = ioctl(conn_fd, KDBUS_CMD_NAME_ACQUIRE, cmd); - return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; -} - -static void bus_poool_free_slice(int fd, uint64_t offset) -{ - struct kdbus_cmd_free cmd = { - .size = sizeof(cmd), - .offset = offset, - }; - int r; - r = kdbus_cmd_free(fd, &cmd); - if (r < 0) - err_r(r, "cannot free pool slice"); -} - -static int bus_open_connection(const char *name, - uint64_t recv_flags) -{ - struct kdbus_cmd_hello hello; - int r; - int fd; - - fd = open(name, O_RDWR | O_CLOEXEC); - if (fd < 0) { - r = err("cannot open bus"); - goto error; - } - - memset(&hello, 0, sizeof(hello)); - hello.size = sizeof(hello); - hello.attach_flags_send = _KDBUS_ATTACH_ALL; - hello.attach_flags_recv = recv_flags; - hello.pool_size = POOL_SIZE; - r = kdbus_cmd_hello(fd, &hello); - if (r < 0) { - err_r(r, "HELLO failed"); - goto error; - } - - bus_poool_free_slice(fd, hello.offset); - - /* - * Map the pool of the connection. Its size has been set in the - * command struct above. See kdbus.pool(7). - */ - pool = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0); - if (pool == MAP_FAILED) { - r = err("cannot mmap pool"); - goto error; - } - - return fd; - -error: - return -1; -} - - - -static int bus_acquire_name(int fd, const char *name) -{ - struct kdbus_item *item; - struct kdbus_cmd *cmd; - size_t size; - int r; - - /* - * This function acquires a well-known name on the bus through the - * KDBUS_CMD_NAME_ACQUIRE ioctl. This ioctl takes an argument of type - * 'struct kdbus_cmd', which is assembled below. See kdbus.name(7). - */ - size = sizeof(*cmd); - size += KDBUS_ITEM_SIZE(strlen(name) + 1); - - cmd = alloca(size); - memset(cmd, 0, size); - cmd->size = size; - - /* - * The command requires an item of type KDBUS_ITEM_NAME, and its - * content must be a valid bus name. - */ - item = cmd->items; - item->type = KDBUS_ITEM_NAME; - item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; - strcpy(item->str, name); - - /* - * Employ the command on the connection owner file descriptor. - */ - r = kdbus_cmd_name_acquire(fd, cmd); - if (r < 0) - return err_r(r, "cannot acquire name"); - - return 0; -} - - -int parse_args(int argc, char** argv) -{ - char state = 0; - unsigned long int uid = 0; - unsigned long int gid = 0; - int i = 1; - int r = 0; - int fdl = -1; - int count = 0; - - while (i < argc) - { - if (argv[i][0] == '-') - state = argv[i][1]; - else { - switch (state) { - - case 'n': - server_names[count++] = argv[i]; - break; - - case 'u': - uid = strtoul(argv[i],NULL,10); - r = setuid((uid_t)uid); - if (r< 0) { - fprintf(stderr, "Cannot set uid"); - exit(-3245); - } - break; - - case 'g': - gid = strtoul(argv[i],NULL,10); - r = setgid((gid_t)gid); - if (r< 0) { - fprintf(stderr, "Cannot set gid"); - exit(-3245); - } - break; - - case 'l': - fdl = open("/proc/self/attr/current", 0, S_IWUSR); - if (fdl < 0) - { - fprintf(stderr,"Cannot open /proc/self/attr/current\n"); - exit(-345); - } - - r = write(fdl, argv[i], strlen(argv[i])); - if (r < 0) - { - fprintf(stderr, "Cannot write to /proc/self/attr/current\n"); - close(fdl); - exit(-345); - } - close(fdl); - break; - case 'q': - ready_fd = strtol(argv[i], NULL, 10); - break; - } - } - i++; - } - return 0; -} - -int main(int argc, char* argv[]) { - int j = 0; - int fd; - parse_args(argc, argv); - fd = bus_open_connection(KDBUS_SYSTEM_BUS_PATH, KDBUS_ATTACH_PIDS); - if (fd < 0) { - return -1; - } - - while(server_names[j] != '\0') - { - if (bus_acquire_name(fd, server_names[j])) - return -1; - j++; - } - - close(ready_fd); - - for(;;); - return 0; -} diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index b37b1ac..f507f25 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -51,13 +51,6 @@ #define UID_INVALID ((uid_t) -1) #define GID_INVALID ((gid_t) -1) -#ifdef LIBDBUSPOLICY_TESTS_API -#undef SYSTEM_BUS_CONF_FILE_PRIMARY -#undef SESSION_BUS_CONF_FILE_PRIMARY -#define SYSTEM_BUS_CONF_FILE_PRIMARY "/usr/lib/dbus-tests/configs/libdbuspolicy-tests/system.conf" -#define SESSION_BUS_CONF_FILE_PRIMARY "/usr/lib/dbus-tests/configs/libdbuspolicy-tests/session.conf" -#endif - /** A process ID */ typedef unsigned long dbus_pid_t; /** A user ID */ diff --git a/src/stest_common.c b/src/stest_common.c deleted file mode 100644 index 8cb9f35..0000000 --- a/src/stest_common.c +++ /dev/null @@ -1,31 +0,0 @@ -#include -#include -#include - -uint64_t test_cases_mask = ~(0ULL); -int test_count = 0; - -void assert_printf(int res, int tc, const char* value, int line, const char* file) -{ - if (res) { - printf("[r][%d]1\n", tc); - } else { - printf("[r][%d]0\n", tc); - fprintf(stderr, "[r][%d]0<-w=%s, line=%d, file=%s\n", tc, value, line, file); - } -} - -void prepare_mask(int argc, char* argv[]) -{ - if (argc > 1) - { - int i = 1; - test_cases_mask = 0; - for (;i < argc; i++) { - int val = strtol(argv[i], NULL, 10); - if (val >= 0) - test_cases_mask |= (1< - -#define assert(v) \ - do { \ - if (test_cases_mask & (1 << test_count)) \ - { \ - int ___r = (v); \ - assert_printf(___r, test_count, #v, __LINE__, __FILE__); \ - } \ - test_count++; \ - } while (0) - -enum { - false, - true -}; - -extern uint64_t test_cases_mask; -extern int test_count; -void prepare_mask(int argc, char* argv[]); -void assert_printf(int res, int tc, const char* value, int line, const char* file); diff --git a/src/stest_cynara.c b/src/stest_cynara.c deleted file mode 100644 index db885f8..0000000 --- a/src/stest_cynara.c +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include -#include -#include -#include "stest_common.h" - -#define NEGATIVE_MATCH "negative" - -void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); - -int main(int argc, char* argv[]) -{ - void* c = NULL; - int result = true; - - prepare_mask(argc,argv); - - if (!strncmp(argv[0], NEGATIVE_MATCH, sizeof(NEGATIVE_MATCH)-1)) - result = false; - - printf("---result: %d %s\n\n", result, argv[0]); - assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); - - __dbuspolicy1_change_creds(c,200,0,"L"); - assert(dbuspolicy1_check_in(c, "cynara.destination", "cynara.sender", "L", 200, 0, NULL, "cynara.interface", "cynara.method", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == result); - - assert(dbuspolicy1_check_in(c, "cynara.destination", "cynara.sender", "L", 200, 0, NULL, "cynara.interface", "cynara.method", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == result); - return 0; -} diff --git a/src/stest_method_call.c b/src/stest_method_call.c deleted file mode 100644 index 7507659..0000000 --- a/src/stest_method_call.c +++ /dev/null @@ -1,77 +0,0 @@ -#include -#include -#include -#include "stest_common.h" - -void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); - -int main(int argc, char* argv[]) -{ - void* c = NULL; - - prepare_mask(argc,argv); - - assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", NULL, "org.test.Itest1", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", NULL, 0, 0, "", "org.test.Itest1", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest1", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest1", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest1", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest1", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest2", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest2", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "", "org.test.Itest3", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "", "org.test.Itest3", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "" ,"org.test.Itest3", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test9", "org.test.test10", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test9", "org.test.test10", "", 5001, 100, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "org.test.test10", "org.test.test9", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5001,100,NULL); - assert(dbuspolicy1_check_in(c, "org.test.test10", "org.test.test9", "", 0, 0, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); - - return 0; -} diff --git a/src/stest_ownership.c b/src/stest_ownership.c deleted file mode 100644 index a6c191b..0000000 --- a/src/stest_ownership.c +++ /dev/null @@ -1,56 +0,0 @@ -#include -#include -#include -#include "stest_common.h" - -void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); - -int main(int argc, char* argv[]) -{ - void* c = NULL; - - prepare_mask(argc,argv); - - assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test1")); - - __dbuspolicy1_change_creds(c, 5009, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test1")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test2")); - - __dbuspolicy1_change_creds(c, 5009, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test2")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test3")); - - __dbuspolicy1_change_creds(c, 5009, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test3")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test4")); - - __dbuspolicy1_change_creds(c, 5009, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test4")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(!dbuspolicy1_can_own(c, "org.test.test5")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test6")); - - __dbuspolicy1_change_creds(c, 0, 0, NULL); - assert(dbuspolicy1_can_own(c, "org.test.test7")); - - assert(dbuspolicy1_can_own(c, "a.b.c")); - assert(dbuspolicy1_can_own(c, "a.b")); - assert(!dbuspolicy1_can_own(c, "c")); - assert(!dbuspolicy1_can_own(c, "a.c")); - assert(!dbuspolicy1_can_own(c, "b.c")); - - return 0; -} diff --git a/src/stest_signal.c b/src/stest_signal.c deleted file mode 100644 index 165c90e..0000000 --- a/src/stest_signal.c +++ /dev/null @@ -1,23 +0,0 @@ -#include -#include -#include -#include "stest_common.h" - -void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); - -int main(int argc, char* argv[]) -{ - void* c = NULL; - - prepare_mask(argc,argv); - - assert(((c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus")) != NULL)); - - __dbuspolicy1_change_creds(c,0,0,NULL); - assert(dbuspolicy1_check_out(c, "", "bli.bla.blubb test.test1 test.tes3", "", "/an/object/path", "", DBUSPOLICY_MESSAGE_TYPE_SIGNAL, "", 0, 0) == true); - - __dbuspolicy1_change_creds(c,5010,0,NULL); - assert(dbuspolicy1_check_out(c, "", "bli.bla.blubb", "", "/an/object/path", "", DBUSPOLICY_MESSAGE_TYPE_SIGNAL, "", 0, 0) == false); - - return 0; -} diff --git a/src/test_runner.c b/src/test_runner.c deleted file mode 100644 index 81c4e0e..0000000 --- a/src/test_runner.c +++ /dev/null @@ -1,699 +0,0 @@ -/* This file contains test-runner for libdbuspolicy - * - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * Author: Kazimierz Krosman - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "test_runner.h" - -enum { - PIPE_READ, - PIPE_WRITE, -}; - -/*****************CUSTOM SECTION***********************************/ -/*custom function that parse stdout of binary and result of binary*/ -void parse_test_state(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); -void parse_one_test_one_binary(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); -char** prepare_args_for_binary(const struct binary* b, const char* test_name); -int daemon_init(void); -int daemon_clear(void); -int cynara_init(void); -int cynara_clear(void); -int cynara_n_init(void); -int cynara_n_clear(void); - -static struct test_case ownership_test_cases[] = { - {"0", "Libdbuspolicy1 init function call"}, - {"1", "Simple check for ownership in default context"}, - {"2", "Simple check for ownership in default context"}, - {"3", "Ownership check in user context"}, - {"4", "Ownership check in user context (negative test)"}, - {"5", "Ownership check in mandatory context with user context (context priority check)"}, - {"6", "Ownership check in mandatory context with user context (for another user)"}, - {"7", "Ownership check for not root user context (negative test)"}, - {"8", "Ownership check for not root user context"}, - {"9", "Ownership check for group context"}, - {"10", "Ownership check for all context (priority check)"}, - {"11", "Ownership check for all context (priority check)"}, - {"12", "Ownership check for own_prefix case (1)"}, - {"13", "Ownership check for own_prefix case (2)"}, - {"14", "Ownership check for own_prefix case (negative test)"}, - {"15", "Ownership check for own_prefix case (negative test)"}, - {"16", "Ownership check for own_prefix case (negative test)"}, - {NULL, NULL} -}; - -static struct test_case method_call_test_cases[] = { - {"0", "Libdbuspolicy1 init function call"}, - {"1", "check_out test"}, - {"2", "check_in test"}, - {"3", "check_out test"}, - {"4", "check_in test"}, - {"5", "check_out test"}, - {"6", "check_in test"}, - {"7", "check_out test"}, - {"8", "check_in test"}, - {"9", "check_out test"}, - {"10", "check_in test"}, - {"11", "check_out test"}, - {"12", "check_in test"}, - {"13", "check_out test"}, - {"14", "check_in test"}, - {"15", "check_out test"}, - {"16", "check_in test"}, - {"17", "check_out test"}, - {"18", "check_in test"}, - {"19", "check_out test"}, - {"20", "check_in test"}, - {NULL, NULL} -}; - -static struct test_case signal_test_cases[] = { - {"1", "Libdbuspolicy1 init"}, - {"2", "Check out for signal"}, - {"3", "Check out for signal (negative)"}, - {NULL, NULL} -}; - -static struct test_case cynara_test_cases[] = { - {"0", "Libdbuspolicy1 init function call"}, - {"1", "Check cynara for result"}, - {"2", "Check cynara for result (second attempt to use cache)"}, - {NULL, NULL} -}; - -static struct test_case negative_cynara_test_cases[] = { - {"0", "Libdbuspolicy1 init function call"}, - {"1", "Check cynara for result (negative test)"}, - {"2", "Check cynara for result (second attempt to use cache) (negative test)"}, - {NULL, NULL} -}; - -/* This table is used to start binaries */ -struct binary tests[] = { -/*path, name, TC_table, timeout in us, prepare_args_handler, parse_function_handler, init_handler, clean_handler*/ - {TEST_PATH "stest_ownership", "ownership", ownership_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, - {TEST_PATH "stest_method_call", "method_call", method_call_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, - {TEST_PATH "stest_signal", "signal", signal_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, - {TEST_PATH "stest_cynara", "cynara", cynara_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, cynara_init, cynara_clear}, - {TEST_PATH "stest_cynara", "negative_cynara", negative_cynara_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, cynara_n_init, cynara_n_clear}, -}; - - -static const char result_pattern[] = "[r][%0]%1"; -static struct state { - unsigned int i; // index of input buffer - unsigned int j; // index in results[n] - unsigned int n; //index in results buffer (0 or 1) - char results[2][MAX_COMMENT]; -} g_state; - -static void sm_reset(void) -{ - memset(&g_state, 0, sizeof (g_state)); -} - -static int sm_update(char* buffer, int i) -{ - int l = strlen(buffer) + 1; - while (i < l && g_state.i < sizeof(result_pattern) - 1) { - if (result_pattern[g_state.i] == '%') { - g_state.n = result_pattern[g_state.i+1] - '0'; - if (g_state.n > 1) { - sm_reset(); - i--; - } else if (isalnum(buffer[i])) { - g_state.results[g_state.n][g_state.j++] = buffer[i]; - } else if (buffer[i] == result_pattern[g_state.i+2] || buffer[i] == '\n') { - g_state.results[g_state.n][g_state.j] = 0; - g_state.i += 3; - g_state.j = 0; - if (g_state.n == 1) - return i; - } else { - g_state.i = 0; - g_state.j = 0; - } - } else if (result_pattern[g_state.i] == buffer[i]) { - g_state.i++; - } else { - sm_reset(); - } - i++; - } - - if (g_state.i >= sizeof(result_pattern) - 1) { - g_state.results[g_state.n][g_state.j] = 0; - g_state.i += 3; - g_state.j = 0; - if (g_state.n == 1) - return i; - } - - return 0; -} - -static const char* sm_get_result(int i) -{ - return g_state.results[i]; -} - -static pid_t daemon_pids[4] ={0}; -static int daemons_pipe[4][2]; -static char* daemon_argv1[] = {TEST_PATH "dbus_daemon", "-q", NULL, "-n","org.test.test3", NULL}; -static char* daemon_argv2[] = {TEST_PATH "dbus_daemon", "-q", NULL,"-n", "org.test.test2", "-g", "100", "-u", "5001", NULL}; -static char* daemon_argv3[] = {TEST_PATH "dbus_daemon", "-q", NULL,"-n", "org.test.test12", "org.test.test9", NULL}; -static char* daemon_argv4[] = {TEST_PATH "dbus_daemon", "-q", NULL, "-n", "org.test.test13", "org.test.test10", "org.test.test11", "-g", "100", "-u", "5001", NULL}; -static char** daemons[] = { daemon_argv1, daemon_argv2, daemon_argv3, daemon_argv4}; - -int daemon_init(void) -{ - int i = 0; - int ready_proc = 0; - struct timeval tv; - fd_set rfds; - int nfds = -1; - int proc_num = sizeof(daemons)/sizeof(daemons[0]); - - for (;i < proc_num;i++) { - if (pipe(daemons_pipe[i]) < 0) { - perror("cannot create pipe"); - goto error1; - } - - daemon_pids[i] = fork(); - if (!daemon_pids[i]) { - char fdd[15]; - sprintf(fdd,"%d",daemons_pipe[i][PIPE_WRITE]); - daemons[i][2] = fdd; - close (daemons_pipe[i][PIPE_READ]); - (void)execv(daemons[i][0],daemons[i]); - exit(0); - } else if (daemon_pids[i] > 0){ - close (daemons_pipe[i][PIPE_WRITE]); - } else - goto error1; - } - - tv.tv_sec = 1; - tv.tv_usec = 0; - while(1) { - FD_ZERO(&rfds); - for (i = 0; i < proc_num;i++) { - if (daemons_pipe[i][PIPE_READ] > -1) - FD_SET(daemons_pipe[i][PIPE_READ], &rfds); - } - - if (ready_proc >= proc_num) - break; - - nfds = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); - if (nfds > 0) { - for (i = 0; i < proc_num;i++) { - if (daemons_pipe[i][PIPE_READ] > -1 && FD_ISSET(daemons_pipe[i][PIPE_READ], &rfds)) { - ++ready_proc; - close (daemons_pipe[i][PIPE_READ]); - daemons_pipe[i][PIPE_READ] = -1; - } - } - } else - goto error1; - } - - return 1; -error1: - daemon_clear(); - return 0; -} - -int daemon_clear(void) -{ - unsigned int i = 0; - for (;i < sizeof(daemons)/sizeof(daemons[0]);i++) { - if (daemon_pids[i]) - kill(daemon_pids[i], SIGKILL); - } - return 0; -} - -static int call_script(char* path, char* argv[]) -{ - int status; - int r; - pid_t pid = fork(); - - if (pid < 0) - return 0; - else if (!pid) { - (void)execv(path, argv); - exit(-1); - } - - r = waitpid(pid, &status, 0); - if (r > 0) { - if (WIFEXITED(status)) - return !(WEXITSTATUS(status)); - else if (WIFCONTINUED(status)) - kill(pid, SIGKILL); - } - - /* fail */ - return 0; -} - -int cynara_n_init(void) -{ - char* argv[] = {CYNARA_PATH, "DENY", NULL}; - return call_script(argv[0],argv); -} - -int cynara_n_clear(void) -{ - return cynara_clear(); -} - -int cynara_init(void) -{ - char* argv[] = {CYNARA_PATH, "ALLOW", NULL}; - return call_script(argv[0],argv); -} - -int cynara_clear(void) -{ - char* argv[] = {CYNARA_PATH, NULL}; - return call_script(argv[0],argv); -} - -static char* args[3]; -char** prepare_args_for_binary(const struct binary* b, const char* test_name) -{ - args[0] = (char*)b->name; - if (!test_name[0]) - args[1] = NULL; - else { - args[1] = (char*)test_name; - args[2] = NULL; - } - return args; -} - - -/* - * Example of test_result detector function implementation - */ -void parse_test_state(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option) -{ - char test_id[MAX_COMMENT]; - - switch(state_change) { - case INIT_TEST: - sm_reset(); - break; - case NEW_STDOUT: - { - int k = 0; - buffer[state_option] = 0; - get_test_id(test_id, b, test_name); - fprintf(stderr, "[stdout][%s]%s\n",test_id, buffer); - while ( (k = sm_update(buffer, k))) { - const char* t_name = sm_get_result(0); - const char* result_code = sm_get_result(1); - bool is_successful = result_code[0] == '1' && result_code[1] == 0; - const char* result_text = is_successful ? "PASS" : "FAIL"; - - get_test_id(test_id, b, t_name); - add_test_result(test_id, result_text, "", is_successful); - sm_reset(); - } - } - break; - case NEW_STDERR: - buffer[state_option] = 0; - get_test_id(test_id, b, test_name); - fprintf(stderr, "[stderr][%s]%s\n",test_id, buffer); - break; - case RESULT_CODE: - if (state_option != 0) - add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Test exited with error code", 0); - break; - case RESULT_SIGNAL: - add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Finished by SIGNAL", 0); - break; - case RESULT_TIMEOUT: - add_test_result(get_test_id(test_id, b, test_name), "FAIL", "Test TIMEOUT", 0); - break; - } -} - -/****************************END of CUSTOM FUNCTIONS************************/ - - -static struct option long_options[] = { - {"list", no_argument, 0, 'l'}, - {"run", required_argument, 0, 'r'}, - {"description", required_argument, 0, 'd'}, - {0, 0, 0, 0 } -}; - -static int stdin_pipe[2]; -static int stdout_pipe[2]; -static int stderr_pipe[2]; -static struct test_result test_results[MAX_TC_NUM]; -static int test_results_i; -static char buffer[MAX_BUFFER]; -static const char* requested_tc[MAX_TC_NUM]; - -char* get_test_id(char* dest, const struct binary* b, const char* test_name) -{ - int len = strlen(b->name); - memcpy(dest, b->name, len); - memcpy(dest + len, test_name, strlen(test_name)+1); - return dest; -} - -static void print_description(const char* name, const char* description) -{ - printf("%s;%s\n",name, description); -} - -static void print_list(const char* test_name) -{ - unsigned int i; - char full_name[MAX_COMMENT]; - for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) { - int j = 0; - int l = strlen(tests[i].name); - memcpy(full_name, tests[i].name, l+1); - if (test_name && strncmp(test_name, full_name, l) != 0) - continue; - - while (tests[i].test_cases[j].name) { - memcpy(full_name + l, tests[i].test_cases[j].name, strlen(tests[i].test_cases[j].name) + 1); - if (!test_name || strcmp(full_name, test_name) == 0) - print_description(full_name,tests[i].test_cases[j].description); - j++; - } - } -} - - -static void stop_binary(const struct binary* b, pid_t pid, const char* test_name) -{ - int status = 0; - int res = 0; - res = waitpid(pid, &status, 0); - if (res == 0) { - //timeouted - kill(pid, SIGKILL); - res = waitpid(pid, &status, WNOHANG); - b->parse(b, test_name, buffer, RESULT_TIMEOUT, res); - } else if (res < 0) { - //errno check - kill(pid, SIGKILL); - res = waitpid(pid, &status, WNOHANG); - b->parse(b, test_name, buffer, RESULT_ERROR, res); - } else if (res > 0) { - if (WIFEXITED(status)) { - b->parse(b, test_name, buffer, RESULT_CODE, WEXITSTATUS(status)); - } else if (WIFSIGNALED(status)) { - b->parse(b, test_name, buffer, RESULT_SIGNAL, WTERMSIG(status)); - } else if (WIFSTOPPED(status)) { - b->parse(b, test_name, buffer, RESULT_SIGNAL, WSTOPSIG(status)); - } else if (WIFCONTINUED(status)) { - kill(pid, SIGKILL); - b->parse(b, test_name, buffer, RESULT_SIGNAL, -1); - } - } -} - -static void parse_output_with_timeout(const struct binary* b, pid_t pid, const char* test_name) -{ - struct timeval tv; - fd_set rfds; - int nfds; - int res; - tv.tv_sec = b->timeout/(1000*1000); - tv.tv_usec = (b->timeout-tv.tv_sec*1000*1000); - while (1) { - FD_ZERO(&rfds); - FD_SET(stdout_pipe[PIPE_READ], &rfds); - FD_SET(stderr_pipe[PIPE_READ], &rfds); - nfds = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); - if (nfds == -1) { - if (errno != EINTR) - break; - } else if (nfds > 0) { - if (FD_ISSET(stdout_pipe[PIPE_READ], &rfds)) { - res = read(stdout_pipe[PIPE_READ], buffer, MAX_BUFFER-1); - if (res == 0 || (res < 0 && errno != EINTR)) - break; - else if (res >=0) - b->parse(b, test_name, buffer, NEW_STDOUT, res); - } - - if (FD_ISSET(stderr_pipe[PIPE_READ], &rfds)) { - res = read(stderr_pipe[PIPE_READ], buffer, MAX_BUFFER-1); - if (res == 0 || (res < 0 && errno != EINTR)) - break; - b->parse(b, test_name, buffer, NEW_STDERR, res); - } - } else { - //timeout - break; - } - } - stop_binary(b, pid, test_name); -} - -static int create_child(const char* path, char* const arguments[]) -{ - int child; - int nResult; - if (pipe(stdin_pipe) < 0) { - perror("allocating pipe for child input redirect failed"); - goto error1; - } - - if (pipe(stdout_pipe) < 0) { - perror("allocating pipe for child output redirect failed"); - goto error2; - } - - if (pipe(stderr_pipe) < 0) { - perror("allocating pipe for child output redirect failed"); - goto error3; - } - - child = fork(); - if (!child) { - char ld_path[512]; - sprintf(ld_path, "/usr/lib/dbus-tests/lib/libdbuspolicy-tests/:"); - // redirect stdin - if (dup2(stdin_pipe[PIPE_READ], STDIN_FILENO) == -1) { - perror("redirecting stdin failed"); - return -1; - } - - // redirect stdout - if (dup2(stdout_pipe[PIPE_WRITE], STDOUT_FILENO) == -1) { - perror("redirecting stdout failed"); - return -1; - } - - // redirect stderr - if (dup2(stderr_pipe[PIPE_WRITE], STDERR_FILENO) == -1) { - perror("redirecting stderr failed"); - return -1; - } - - // all these are for use by parent only - close(stdin_pipe[PIPE_READ]); - close(stdin_pipe[PIPE_WRITE]); - close(stdout_pipe[PIPE_READ]); - close(stdout_pipe[PIPE_WRITE]); - close(stderr_pipe[PIPE_READ]); - close(stderr_pipe[PIPE_WRITE]); - - char* ld_path_b = getenv("LD_LIBRARY_PATH"); - if (ld_path_b != NULL) - memcpy(ld_path + strlen(ld_path), ld_path_b, strlen(ld_path_b)+1); - setenv("LD_LIBRARY_PATH", ld_path, 1); - // run child process image - nResult = execv(path, arguments); - - // if we get here at all, an error occurred, but we are in the child - // process, so just exit - perror("exec of the child process failed"); - exit(nResult); - } else if (child > 0) { - // parent continues here - - // close unused file descriptors, these are for child only - close(stdin_pipe[PIPE_READ]); - close(stdout_pipe[PIPE_WRITE]); - close(stderr_pipe[PIPE_WRITE]); - } else { - // failed to create child - goto error4; - } - - return child; - -error4: - close(stderr_pipe[PIPE_READ]); - close(stderr_pipe[PIPE_WRITE]); -error3: - close(stdout_pipe[PIPE_READ]); - close(stdout_pipe[PIPE_WRITE]); -error2: - close(stdin_pipe[PIPE_READ]); - close(stdin_pipe[PIPE_WRITE]); -error1: - return -1; -} - -static void run_test(const struct binary* b, const char* test_name) -{ - int res = -1; - char** arg; - char test_id[MAX_COMMENT]; - - assert(b); - assert(b->name); - assert(b->path); - assert(test_name); - - arg = b->prepare_args(b, test_name); - - if (b->init) - if (!b->init()) { - add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Internal error: Cannot init test", 0); - return; - } - - res = create_child(b->path, arg); - if (res > 0) - parse_output_with_timeout(b, res, test_name); - else - add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Internal error: Cannot start test", 0); - - if (b->clean) - b->clean(); -} - -static void parse_run_test(const char* tc) { - unsigned int i = 0; - for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) { - int len = strlen(tests[i].name); - if (strncmp(tc, tests[i].name, len) == 0) { - if (tc[len] == '*' || tc[len] == '\0') - run_test(&tests[i], ""); - else - run_test(&tests[i], tc + len); - } - } -} - -static int parse_option(int argc, char* argv[]) -{ - int ch = 0; - int c = 0; - while ((ch = getopt_long(argc, argv, "lr:d:", long_options, NULL)) != -1) { - switch (ch) { - case 'l': - print_list(NULL); - return 1; - case 'r': - if (c >= MAX_TC_NUM - 1) //NULL at the end - return 0; - - if (optarg) - requested_tc[c++] = optarg; - - break; - case 'd': - print_list(optarg); - return 1; - } - } - return 0; -} - -//output_new/fail/success -void add_test_result(const char* test_id, const char* result, const char* comment, int res) -{ - test_results[test_results_i].is_positive = res; - strcpy(test_results[test_results_i].result, result); - strcpy(test_results[test_results_i].comment, comment); - strcpy(test_results[test_results_i++].name, test_id); -} - -static void prepare_results(void) -{ - //todo -} - -static void print_results() -{ - int i = 0; - for (i = 0; i < test_results_i; i++) - { - printf("%s;%s;%s\n", test_results[i].name, test_results[i].result, test_results[i].comment); - } -} - -int main(int argc, char* argv[]) -{ - unsigned int i; - signal(SIGPIPE, SIG_IGN); - if (parse_option(argc, argv)) - return 0; - - prepare_results(); - - if (!requested_tc[0]) { - for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) - run_test(&tests[i], ""); - } else { - i = 0; - while(requested_tc[i]) { - parse_run_test(requested_tc[i]); - i++; - } - } - - print_results(); - return 0; -} diff --git a/src/test_runner.h b/src/test_runner.h deleted file mode 100644 index 3c79a99..0000000 --- a/src/test_runner.h +++ /dev/null @@ -1,69 +0,0 @@ -/* This file is part of test-runner (see template.c) - * - * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved - * Author: Kazimierz Krosman - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. -*/ - -#ifndef TEST_RUNNER_H -#define TEST_RUNNER_H -#include - -#define TC_NAME "libdbuspolicy-tests" -#define TEST_PATH "/usr/lib/dbus-tests/test-suites/libdbuspolicy-tests/" -#define CYNARA_PATH TEST_PATH "cynara_prepare.sh" -#define MAX_TC_NUM 1024 -#define MAX_BUFFER (64*1024) -#define MAX_COMMENT 1024 - -enum { - INIT_TEST, - NEW_STDOUT, - NEW_STDERR, - RESULT_CODE, - RESULT_SIGNAL, - RESULT_ERROR, - RESULT_TIMEOUT -}; - -struct test_result { - bool is_positive; - char comment[MAX_COMMENT]; - char result[MAX_COMMENT]; - char name[MAX_COMMENT]; -}; - -struct test_case { - const char* name; - const char* description; -}; - -struct binary { - const char* path; - const char* name; - /* can be filled by asking binary */ - struct test_case* test_cases; - int timeout; - - char** (*prepare_args) (const struct binary* b, const char* test_name); - void (*parse) (const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); - int (*init)(void); - int (*clean)(void); -}; - -char* get_test_id(char* dest, const struct binary* b, const char* test_name); -void add_test_result(const char* test_id, const char* result, const char* comment, int res); - - -#endif /* TEST_RUNNER_H */ -- 2.7.4 From 575b04077b18ca810aa1974314785e32340d4bb6 Mon Sep 17 00:00:00 2001 From: Kazimierz Krosman Date: Mon, 19 Dec 2016 14:02:50 +0100 Subject: [PATCH 04/16] tests: Add test package for libdbuspolicy - again This reverts commit 376f38dafa0b7ee5eae3d8f0ba0333c84a79742d, which reverted commit bb7d32bb63f1d0fc463255000fbc773a119314a9. This is different from commit bb7d32bb63f1d0fc463255000fbc773a119314a9 in handling builds - it provides single spec file. Additionally, corrections for tests, mostly excluding initialization of the library from "test cases". Author: Kazimierz Krosman with some corrections by Adrian Szyndela Change-Id: I64a58818c5c7f692db38f8225bec1e7a11954de6 --- Makefile.am | 43 ++- configure.ac | 1 + packaging/libdbuspolicy.spec | 43 ++- src/cynara_prepare.sh | 8 + src/dbus_daemon.c | 236 +++++++++++++++ src/libdbuspolicy1.c | 7 + src/stest_common.c | 32 ++ src/stest_common.h | 22 ++ src/stest_cynara.c | 40 +++ src/stest_method_call.c | 80 +++++ src/stest_ownership.c | 59 ++++ src/stest_signal.c | 26 ++ src/test_runner.c | 692 +++++++++++++++++++++++++++++++++++++++++++ src/test_runner.h | 69 +++++ 14 files changed, 1347 insertions(+), 11 deletions(-) create mode 100644 src/cynara_prepare.sh create mode 100644 src/dbus_daemon.c create mode 100644 src/stest_common.c create mode 100644 src/stest_common.h create mode 100644 src/stest_cynara.c create mode 100644 src/stest_method_call.c create mode 100644 src/stest_ownership.c create mode 100644 src/stest_signal.c create mode 100644 src/test_runner.c create mode 100644 src/test_runner.h diff --git a/Makefile.am b/Makefile.am index 30eec82..c2e9409 100644 --- a/Makefile.am +++ b/Makefile.am @@ -43,7 +43,7 @@ LIBDBUSPOLICY1_AGE=0 pkginclude_HEADERS = src/dbuspolicy1/libdbuspolicy1.h lib_LTLIBRARIES = src/libdbuspolicy1.la -src_libdbuspolicy1_la_SOURCES =\ +COMMON_SRC =\ src/libdbuspolicy1-private.h \ src/libdbuspolicy1.c \ src/internal/internal.cpp \ @@ -51,7 +51,10 @@ src_libdbuspolicy1_la_SOURCES =\ src/internal/naive_policy_db.cpp \ src/internal/policy.cpp \ src/internal/xml_parser.cpp \ - src/internal/tslog.cpp \ + src/internal/tslog.cpp + +src_libdbuspolicy1_la_SOURCES =\ + $(COMMON_SRC) \ src/internal/cynara.cpp EXTRA_DIST += src/libdbuspolicy1.sym @@ -81,14 +84,7 @@ src_test_libdbuspolicy1_method_SOURCES = src/test-libdbuspolicy1-method.cpp noinst_LTLIBRARIES = src/libinternal.a src_libinternal_a_SOURCES =\ - src/libdbuspolicy1-private.h \ - src/internal/internal.cpp \ - src/libdbuspolicy1.c \ - src/internal/naive_policy_checker.cpp \ - src/internal/naive_policy_db.cpp \ - src/internal/policy.cpp \ - src/internal/xml_parser.cpp \ - src/internal/tslog.cpp \ + $(COMMON_SRC) \ src/internal/cynara_mockup.cpp src_test_libdbuspolicy1_ownership_LDADD = $(CYNARA_LIBS) \ @@ -100,6 +96,33 @@ src_test_libdbuspolicy1_signal_LDADD = $(CYNARA_LIBS) \ src_test_libdbuspolicy1_method_LDADD = $(CYNARA_LIBS) \ src/libinternal.a +if ENABLE_STANDALONE_TESTS +noinst_LTLIBRARIES += src/libinternalfortests.a +src_libinternalfortests_a_SOURCES =\ + $(COMMON_SRC) \ + src/internal/cynara.cpp + +runner_PROGRAMS = libdbuspolicy-tests +libdbuspolicy_tests_SOURCES = src/test_runner.c +runnerdir = ${libdir}/dbus-tests/runner/ + +alonetestdir = ${libdir}/dbus-tests/test-suites/libdbuspolicy-tests/ +alonetest_PROGRAMS = dbus_daemon stest_ownership stest_method_call stest_signal stest_cynara + +dbus_daemon_SOURCES = src/dbus_daemon.c +stest_ownership_SOURCES = src/stest_ownership.c src/stest_common.c +stest_method_call_SOURCES = src/stest_method_call.c src/stest_common.c +stest_signal_SOURCES = src/stest_signal.c src/stest_common.c +stest_cynara_SOURCES = src/stest_cynara.c src/stest_common.c + +stest_ownership_LDADD = src/libinternalfortests.a -lstdc++ $(CYNARA_LIBS) +stest_method_call_LDADD = src/libinternalfortests.a -lstdc++ $(CYNARA_LIBS) +stest_signal_LDADD = src/libinternalfortests.a -lstdc++ $(CYNARA_LIBS) +stest_cynara_LDADD = src/libinternalfortests.a -lstdc++ $(CYNARA_LIBS) + +all-tests:: $(alonetest_PROGRAMS) $(runner_PROGRAMS) +endif + if ENABLE_DOXYGEN CLEANFILES += documentation diff --git a/configure.ac b/configure.ac index 9c5aa73..6d6dbf4 100644 --- a/configure.ac +++ b/configure.ac @@ -50,6 +50,7 @@ AS_IF([test "x$enable_debug" = "xyes"], [ AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests], [Add API function that allows to change credentials during execution]), [with_tests=yes], with_tests=no) +AM_CONDITIONAL([ENABLE_STANDALONE_TESTS], [test x$with_tests = xyes]) if test "x$with_tests" = "xyes"; then AC_DEFINE(LIBDBUSPOLICY_TESTS_API, 1, [Define if tests are enabled]) fi diff --git a/packaging/libdbuspolicy.spec b/packaging/libdbuspolicy.spec index f9e6e7e..0ec26d2 100644 --- a/packaging/libdbuspolicy.spec +++ b/packaging/libdbuspolicy.spec @@ -11,6 +11,9 @@ BuildRequires: pkgconfig(cynara-client) %package devel Summary: Helper library for fine-grained userspace policy handling-development package + +%package tests +Summary: Helper library for fine-grained userspace policy handling-development package Requires: %{name} = %{version} %description @@ -22,6 +25,8 @@ libdbuspolicy is a helper library for fine-grained userspace policy handling (with SMACK support). This package contains development files. +%description tests +This package contains contains integration tests for libdbuspolicy. %if 0%{?enable_doxygen:1} %package doc @@ -32,11 +37,18 @@ BuildRequires: doxygen Doxygen documentation for libdbuspolicy. %endif +%define testsdirname %{name}-tests +%define runnername %{testsdirname} +%define dbustestsdir %{_libdir}/dbus-tests + %prep %setup -q cp %{SOURCE1001} . %build +%reconfigure --libdir=%{_libdir} --prefix=/usr --enable-tests +make all-tests + %reconfigure --libdir=%{_libdir} --prefix=/usr \ %if 0%{?enable_doxygen:1} --enable-doxygen @@ -49,6 +61,30 @@ make check make DESTDIR=%{buildroot} install rm %{buildroot}%{_libdir}/libdbuspolicy1.la +%define testconfigsdir %{dbustestsdir}/configs/%{testsdirname} +%define btestconfigsdir %{buildroot}%{testconfigsdir} +mkdir -p %{btestconfigsdir} +libtool --mode=install install -m 0644 tests/system.conf %{btestconfigsdir} + +%define testconfigsystemddir %{testconfigsdir}/system.d +%define btestconfigsystemddir %{buildroot}%{testconfigsystemddir} +mkdir -p %{btestconfigsystemddir} +libtool --mode=install install -m 0644 tests/system.d/ownerships.test.conf %{btestconfigsystemddir} +libtool --mode=install install -m 0644 tests/system.d/signals.test.conf %{btestconfigsystemddir} +libtool --mode=install install -m 0644 tests/system.d/methods.test.conf %{btestconfigsystemddir} +libtool --mode=install install -m 0644 tests/system.d/cynara.test.conf %{btestconfigsystemddir} + +%define testsuitedir %{dbustestsdir}/test-suites/%{testsdirname} +%define btestsuitedir %{buildroot}%{testsuitedir} +mkdir -p %{btestsuitedir} +libtool --mode=install install -m 0755 src/cynara_prepare.sh %{btestsuitedir} +libtool --mode=install install -m 0755 stest_* dbus_daemon %{btestsuitedir} + +%define testrunnerdir %{dbustestsdir}/runner +%define btestrunnerdir %{buildroot}%{testrunnerdir} +mkdir -p %{btestrunnerdir} +libtool --mode=install install -m 0755 %{runnername} %{btestrunnerdir} + %post -p /sbin/ldconfig %postun -p /sbin/ldconfig @@ -60,7 +96,6 @@ rm %{buildroot}%{_libdir}/libdbuspolicy1.la %files devel %defattr(-,root,root) %{_includedir}/* - %{_libdir}/pkgconfig/* %{_libdir}/libdbuspolicy1.so %manifest %{name}.manifest @@ -71,3 +106,9 @@ rm %{buildroot}%{_libdir}/libdbuspolicy1.la %{_datadir}/doc/dbuspolicy/* %endif %changelog + +%files tests +%defattr(-,root,root) +%{testrunnerdir}/%{runnername} +%{testsuitedir}/* +%{testconfigsdir}/* diff --git a/src/cynara_prepare.sh b/src/cynara_prepare.sh new file mode 100644 index 0000000..acc2401 --- /dev/null +++ b/src/cynara_prepare.sh @@ -0,0 +1,8 @@ +#!/bin/sh +if [ -z "${1}" ]; then + cyad -e "MANIFESTS" -u 200 -c L -p t -r y + cyad -e "USER_TYPE_ADMIN" -u 200 -c L -p t -r y +else + cyad -s -k "MANIFESTS" -u 200 -c L -p t -t $1 + cyad -s -k "USER_TYPE_ADMIN" -u 200 -c L -p t -t $1 +fi diff --git a/src/dbus_daemon.c b/src/dbus_daemon.c new file mode 100644 index 0000000..058106e --- /dev/null +++ b/src/dbus_daemon.c @@ -0,0 +1,236 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kdbus.h" + +#define KDBUS_SYSTEM_BUS_PATH "/sys/fs/kdbus/0-system/bus" + +#define KDBUS_ALIGN8(l) (((l) + 7) & ~7) +#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) +#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE) +#define KDBUS_ITEM_NEXT(item) \ + (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size)) +#define KDBUS_FOREACH(iter, first, _size) \ + for (iter = (first); \ + ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \ + ((uint8_t *)(iter) >= (uint8_t *)(first)); \ + iter = (void*)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size))) + +#define POOL_SIZE (16 * 1024 * 1024) + +#define err_r(_r, _msg) fprintf(stderr, "log: %d, %s, %s, %d, %s\n",(_r), (_msg), __func__, __LINE__, __FILE__) +#define err(_msg) err_r(errno, (_msg)) + +static uint8_t* pool; +static char* server_names[16]; +int ready_fd = 0; + +static inline int kdbus_cmd_hello(int bus_fd, struct kdbus_cmd_hello *cmd) +{ + int ret = ioctl(bus_fd, KDBUS_CMD_HELLO, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline int kdbus_cmd_free(int conn_fd, struct kdbus_cmd_free *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_FREE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline int kdbus_cmd_name_acquire(int conn_fd, struct kdbus_cmd *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_NAME_ACQUIRE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static void bus_poool_free_slice(int fd, uint64_t offset) +{ + struct kdbus_cmd_free cmd = { + .size = sizeof(cmd), + .offset = offset, + }; + int r; + r = kdbus_cmd_free(fd, &cmd); + if (r < 0) + err_r(r, "cannot free pool slice"); +} + +static int bus_open_connection(const char *name, + uint64_t recv_flags) +{ + struct kdbus_cmd_hello hello; + int r; + int fd; + + fd = open(name, O_RDWR | O_CLOEXEC); + if (fd < 0) { + r = err("cannot open bus"); + goto error; + } + + memset(&hello, 0, sizeof(hello)); + hello.size = sizeof(hello); + hello.attach_flags_send = _KDBUS_ATTACH_ALL; + hello.attach_flags_recv = recv_flags; + hello.pool_size = POOL_SIZE; + r = kdbus_cmd_hello(fd, &hello); + if (r < 0) { + err_r(r, "HELLO failed"); + goto error; + } + + bus_poool_free_slice(fd, hello.offset); + + /* + * Map the pool of the connection. Its size has been set in the + * command struct above. See kdbus.pool(7). + */ + pool = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0); + if (pool == MAP_FAILED) { + r = err("cannot mmap pool"); + goto error; + } + + return fd; + +error: + return -1; +} + + + +static int bus_acquire_name(int fd, const char *name) +{ + struct kdbus_item *item; + struct kdbus_cmd *cmd; + size_t size; + int r; + + /* + * This function acquires a well-known name on the bus through the + * KDBUS_CMD_NAME_ACQUIRE ioctl. This ioctl takes an argument of type + * 'struct kdbus_cmd', which is assembled below. See kdbus.name(7). + */ + size = sizeof(*cmd); + size += KDBUS_ITEM_SIZE(strlen(name) + 1); + + cmd = alloca(size); + memset(cmd, 0, size); + cmd->size = size; + + /* + * The command requires an item of type KDBUS_ITEM_NAME, and its + * content must be a valid bus name. + */ + item = cmd->items; + item->type = KDBUS_ITEM_NAME; + item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; + strcpy(item->str, name); + + /* + * Employ the command on the connection owner file descriptor. + */ + r = kdbus_cmd_name_acquire(fd, cmd); + if (r < 0) + return err_r(r, "cannot acquire name"); + + return 0; +} + + +int parse_args(int argc, char** argv) +{ + char state = 0; + unsigned long int uid = 0; + unsigned long int gid = 0; + int i = 1; + int r = 0; + int fdl = -1; + int count = 0; + + while (i < argc) + { + if (argv[i][0] == '-') + state = argv[i][1]; + else { + switch (state) { + + case 'n': + server_names[count++] = argv[i]; + break; + + case 'u': + uid = strtoul(argv[i],NULL,10); + r = setuid((uid_t)uid); + if (r< 0) { + fprintf(stderr, "Cannot set uid"); + exit(-3245); + } + break; + + case 'g': + gid = strtoul(argv[i],NULL,10); + r = setgid((gid_t)gid); + if (r< 0) { + fprintf(stderr, "Cannot set gid"); + exit(-3245); + } + break; + + case 'l': + fdl = open("/proc/self/attr/current", 0, S_IWUSR); + if (fdl < 0) + { + fprintf(stderr,"Cannot open /proc/self/attr/current\n"); + exit(-345); + } + + r = write(fdl, argv[i], strlen(argv[i])); + if (r < 0) + { + fprintf(stderr, "Cannot write to /proc/self/attr/current\n"); + close(fdl); + exit(-345); + } + close(fdl); + break; + case 'q': + ready_fd = strtol(argv[i], NULL, 10); + break; + } + } + i++; + } + return 0; +} + +int main(int argc, char* argv[]) { + int j = 0; + int fd; + parse_args(argc, argv); + fd = bus_open_connection(KDBUS_SYSTEM_BUS_PATH, KDBUS_ATTACH_PIDS); + if (fd < 0) { + return -1; + } + + while(server_names[j] != '\0') + { + if (bus_acquire_name(fd, server_names[j])) + return -1; + j++; + } + + close(ready_fd); + + for(;;); + return 0; +} diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index f507f25..b37b1ac 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -51,6 +51,13 @@ #define UID_INVALID ((uid_t) -1) #define GID_INVALID ((gid_t) -1) +#ifdef LIBDBUSPOLICY_TESTS_API +#undef SYSTEM_BUS_CONF_FILE_PRIMARY +#undef SESSION_BUS_CONF_FILE_PRIMARY +#define SYSTEM_BUS_CONF_FILE_PRIMARY "/usr/lib/dbus-tests/configs/libdbuspolicy-tests/system.conf" +#define SESSION_BUS_CONF_FILE_PRIMARY "/usr/lib/dbus-tests/configs/libdbuspolicy-tests/session.conf" +#endif + /** A process ID */ typedef unsigned long dbus_pid_t; /** A user ID */ diff --git a/src/stest_common.c b/src/stest_common.c new file mode 100644 index 0000000..6938047 --- /dev/null +++ b/src/stest_common.c @@ -0,0 +1,32 @@ +/* Author: Kazimierz Krosman */ +#include +#include +#include + +uint64_t test_cases_mask = ~(0ULL); +int test_count = 0; + +void assert_printf(int res, int tc, const char* value, int line, const char* file) +{ + if (res) { + printf("[r][%d]1\n", tc); + } else { + printf("[r][%d]0\n", tc); + fprintf(stderr, "[r][%d]0<-w=%s, line=%d, file=%s\n", tc, value, line, file); + } +} + +void prepare_mask(int argc, char* argv[]) +{ + if (argc > 1) + { + int i = 1; + test_cases_mask = 0; + for (;i < argc; i++) { + int val = strtol(argv[i], NULL, 10); + if (val >= 0) + test_cases_mask |= (1< + +#define tassert(v) \ + do { \ + if (test_cases_mask & (1 << test_count)) \ + { \ + int ___r = (v); \ + assert_printf(___r, test_count, #v, __LINE__, __FILE__); \ + } \ + test_count++; \ + } while (0) + +enum { + false, + true +}; + +extern uint64_t test_cases_mask; +extern int test_count; +void prepare_mask(int argc, char* argv[]); +void assert_printf(int res, int tc, const char* value, int line, const char* file); diff --git a/src/stest_cynara.c b/src/stest_cynara.c new file mode 100644 index 0000000..7e1df99 --- /dev/null +++ b/src/stest_cynara.c @@ -0,0 +1,40 @@ +/* Author: Kazimierz Krosman */ +#include +#include +#include +#include +#include +#include +#include "stest_common.h" + +#define NEGATIVE_MATCH "negative" +#define COUNT 1000 + +void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); + +int main(int argc, char* argv[]) +{ + void* c = NULL; + int desired_result = 1; + int i; + + assert(argc>0); + + if (!strncmp(argv[0], NEGATIVE_MATCH, sizeof(NEGATIVE_MATCH)-1)) + desired_result = 0; + + printf("---desired result: %d %s\n\n", desired_result, argv[0]); + c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus"); + assert(c != NULL); + + __dbuspolicy1_change_creds(c,200,0,"L"); + + for (i = 0; i < COUNT; i++) { + int result = dbuspolicy1_check_in(c, "cynara.destination", "cynara.sender", + "L", 200, 0, NULL, "cynara.interface", "cynara.method", + DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0); + assert(result == desired_result); + } + printf("[r][0]1\n"); + return 0; +} diff --git a/src/stest_method_call.c b/src/stest_method_call.c new file mode 100644 index 0000000..d1bf8e1 --- /dev/null +++ b/src/stest_method_call.c @@ -0,0 +1,80 @@ +/* Author: Kazimierz Krosman */ +#include +#include +#include +#include +#include "stest_common.h" + +void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); + +int main(int argc, char* argv[]) +{ + void* c = NULL; + + prepare_mask(argc,argv); + + c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus"); + assert(c != NULL); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", NULL, "org.test.Itest1", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", NULL, 0, 0, "", "org.test.Itest1", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest1", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest1", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest1", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest1", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest2", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest2", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "", "org.test.Itest3", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "", "org.test.Itest3", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "" ,"org.test.Itest3", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test9", "org.test.test10", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test9", "org.test.test10", "", 5001, 100, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test10", "org.test.test9", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test10", "org.test.test9", "", 0, 0, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + return 0; +} diff --git a/src/stest_ownership.c b/src/stest_ownership.c new file mode 100644 index 0000000..9172500 --- /dev/null +++ b/src/stest_ownership.c @@ -0,0 +1,59 @@ +/* Author: Kazimierz Krosman */ +#include +#include +#include +#include +#include "stest_common.h" + +void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); + +int main(int argc, char* argv[]) +{ + void* c = NULL; + + prepare_mask(argc,argv); + + c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus"); + assert(c != NULL); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(dbuspolicy1_can_own(c, "org.test.test1")); + + __dbuspolicy1_change_creds(c, 5009, 0, NULL); + tassert(dbuspolicy1_can_own(c, "org.test.test1")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(!dbuspolicy1_can_own(c, "org.test.test2")); + + __dbuspolicy1_change_creds(c, 5009, 0, NULL); + tassert(!dbuspolicy1_can_own(c, "org.test.test2")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(!dbuspolicy1_can_own(c, "org.test.test3")); + + __dbuspolicy1_change_creds(c, 5009, 0, NULL); + tassert(!dbuspolicy1_can_own(c, "org.test.test3")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(!dbuspolicy1_can_own(c, "org.test.test4")); + + __dbuspolicy1_change_creds(c, 5009, 0, NULL); + tassert(dbuspolicy1_can_own(c, "org.test.test4")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(!dbuspolicy1_can_own(c, "org.test.test5")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(dbuspolicy1_can_own(c, "org.test.test6")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(dbuspolicy1_can_own(c, "org.test.test7")); + + tassert(dbuspolicy1_can_own(c, "a.b.c")); + tassert(dbuspolicy1_can_own(c, "a.b")); + tassert(!dbuspolicy1_can_own(c, "c")); + tassert(!dbuspolicy1_can_own(c, "a.c")); + tassert(!dbuspolicy1_can_own(c, "b.c")); + + return 0; +} diff --git a/src/stest_signal.c b/src/stest_signal.c new file mode 100644 index 0000000..5fbef7c --- /dev/null +++ b/src/stest_signal.c @@ -0,0 +1,26 @@ +/* Author: Kazimierz Krosman */ +#include +#include +#include +#include +#include "stest_common.h" + +void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); + +int main(int argc, char* argv[]) +{ + void* c = NULL; + + prepare_mask(argc,argv); + + c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus"); + assert(c != NULL); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_out(c, "", "bli.bla.blubb test.test1 test.tes3", "", "/an/object/path", "", DBUSPOLICY_MESSAGE_TYPE_SIGNAL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5010,0,NULL); + tassert(dbuspolicy1_check_out(c, "", "bli.bla.blubb", "", "/an/object/path", "", DBUSPOLICY_MESSAGE_TYPE_SIGNAL, "", 0, 0) == false); + + return 0; +} diff --git a/src/test_runner.c b/src/test_runner.c new file mode 100644 index 0000000..33517a0 --- /dev/null +++ b/src/test_runner.c @@ -0,0 +1,692 @@ +/* This file contains test-runner for libdbuspolicy + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Author: Kazimierz Krosman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "test_runner.h" + +enum { + PIPE_READ, + PIPE_WRITE, +}; + +/*****************CUSTOM SECTION***********************************/ +/*custom function that parse stdout of binary and result of binary*/ +void parse_test_state(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); +void parse_one_test_one_binary(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); +char** prepare_args_for_binary(const struct binary* b, const char* test_name); +int daemon_init(void); +int daemon_clear(void); +int cynara_init(void); +int cynara_clear(void); +int cynara_n_init(void); +int cynara_n_clear(void); + +static struct test_case ownership_test_cases[] = { + {"0", "Simple check for ownership in default context"}, + {"1", "Simple check for ownership in default context"}, + {"2", "Ownership check in user context"}, + {"3", "Ownership check in user context (negative test)"}, + {"4", "Ownership check in mandatory context with user context (context priority check)"}, + {"5", "Ownership check in mandatory context with user context (for another user)"}, + {"6", "Ownership check for not root user context (negative test)"}, + {"7", "Ownership check for not root user context"}, + {"8", "Ownership check for group context"}, + {"9", "Ownership check for all context (priority check)"}, + {"10", "Ownership check for all context (priority check)"}, + {"11", "Ownership check for own_prefix case (1)"}, + {"12", "Ownership check for own_prefix case (2)"}, + {"13", "Ownership check for own_prefix case (negative test)"}, + {"14", "Ownership check for own_prefix case (negative test)"}, + {"15", "Ownership check for own_prefix case (negative test)"}, + {NULL, NULL} +}; + +static struct test_case method_call_test_cases[] = { + {"0", "check_out test"}, + {"1", "check_in test"}, + {"2", "check_out test"}, + {"3", "check_in test"}, + {"4", "check_out test"}, + {"5", "check_in test"}, + {"6", "check_out test"}, + {"7", "check_in test"}, + {"8", "check_out test"}, + {"9", "check_in test"}, + {"10", "check_out test"}, + {"11", "check_in test"}, + {"12", "check_out test"}, + {"13", "check_in test"}, + {"14", "check_out test"}, + {"15", "check_in test"}, + {"16", "check_out test"}, + {"17", "check_in test"}, + {"18", "check_out test"}, + {"19", "check_in test"}, + {NULL, NULL} +}; + +static struct test_case signal_test_cases[] = { + {"0", "Check out for signal"}, + {"1", "Check out for signal (negative)"}, + {NULL, NULL} +}; + +static struct test_case cynara_test_cases[] = { + {"0", "Check cynara for result"}, + {NULL, NULL} +}; + +static struct test_case negative_cynara_test_cases[] = { + {"0", "Check cynara for result (negative test)"}, + {NULL, NULL} +}; + +/* This table is used to start binaries */ +struct binary tests[] = { +/*path, name, TC_table, timeout in us, prepare_args_handler, parse_function_handler, init_handler, clean_handler*/ + {TEST_PATH "stest_ownership", "ownership", ownership_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, + {TEST_PATH "stest_method_call", "method_call", method_call_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, + {TEST_PATH "stest_signal", "signal", signal_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, + {TEST_PATH "stest_cynara", "cynara", cynara_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, cynara_init, cynara_clear}, + {TEST_PATH "stest_cynara", "negative_cynara", negative_cynara_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, cynara_n_init, cynara_n_clear}, +}; + + +static const char result_pattern[] = "[r][%0]%1"; +static struct state { + unsigned int i; // index of input buffer + unsigned int j; // index in results[n] + unsigned int n; //index in results buffer (0 or 1) + char results[2][MAX_COMMENT]; +} g_state; + +static void sm_reset(void) +{ + memset(&g_state, 0, sizeof (g_state)); +} + +static int sm_update(char* buffer, int i) +{ + int l = strlen(buffer) + 1; + while (i < l && g_state.i < sizeof(result_pattern) - 1) { + if (result_pattern[g_state.i] == '%') { + g_state.n = result_pattern[g_state.i+1] - '0'; + if (g_state.n > 1) { + sm_reset(); + i--; + } else if (isalnum(buffer[i])) { + g_state.results[g_state.n][g_state.j++] = buffer[i]; + } else if (buffer[i] == result_pattern[g_state.i+2] || buffer[i] == '\n') { + g_state.results[g_state.n][g_state.j] = 0; + g_state.i += 3; + g_state.j = 0; + if (g_state.n == 1) + return i; + } else { + g_state.i = 0; + g_state.j = 0; + } + } else if (result_pattern[g_state.i] == buffer[i]) { + g_state.i++; + } else { + sm_reset(); + } + i++; + } + + if (g_state.i >= sizeof(result_pattern) - 1) { + g_state.results[g_state.n][g_state.j] = 0; + g_state.i += 3; + g_state.j = 0; + if (g_state.n == 1) + return i; + } + + return 0; +} + +static const char* sm_get_result(int i) +{ + return g_state.results[i]; +} + +static pid_t daemon_pids[4] ={0}; +static int daemons_pipe[4][2]; +static char* daemon_argv1[] = {TEST_PATH "dbus_daemon", "-q", NULL, "-n","org.test.test3", NULL}; +static char* daemon_argv2[] = {TEST_PATH "dbus_daemon", "-q", NULL,"-n", "org.test.test2", "-g", "100", "-u", "5001", NULL}; +static char* daemon_argv3[] = {TEST_PATH "dbus_daemon", "-q", NULL,"-n", "org.test.test12", "org.test.test9", NULL}; +static char* daemon_argv4[] = {TEST_PATH "dbus_daemon", "-q", NULL, "-n", "org.test.test13", "org.test.test10", "org.test.test11", "-g", "100", "-u", "5001", NULL}; +static char** daemons[] = { daemon_argv1, daemon_argv2, daemon_argv3, daemon_argv4}; + +int daemon_init(void) +{ + int i = 0; + int ready_proc = 0; + struct timeval tv; + fd_set rfds; + int nfds = -1; + int proc_num = sizeof(daemons)/sizeof(daemons[0]); + + for (;i < proc_num;i++) { + if (pipe(daemons_pipe[i]) < 0) { + perror("cannot create pipe"); + goto error1; + } + + daemon_pids[i] = fork(); + if (!daemon_pids[i]) { + char fdd[15]; + sprintf(fdd,"%d",daemons_pipe[i][PIPE_WRITE]); + daemons[i][2] = fdd; + close (daemons_pipe[i][PIPE_READ]); + (void)execv(daemons[i][0],daemons[i]); + exit(0); + } else if (daemon_pids[i] > 0){ + close (daemons_pipe[i][PIPE_WRITE]); + } else + goto error1; + } + + tv.tv_sec = 1; + tv.tv_usec = 0; + while(1) { + FD_ZERO(&rfds); + for (i = 0; i < proc_num;i++) { + if (daemons_pipe[i][PIPE_READ] > -1) + FD_SET(daemons_pipe[i][PIPE_READ], &rfds); + } + + if (ready_proc >= proc_num) + break; + + nfds = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); + if (nfds > 0) { + for (i = 0; i < proc_num;i++) { + if (daemons_pipe[i][PIPE_READ] > -1 && FD_ISSET(daemons_pipe[i][PIPE_READ], &rfds)) { + ++ready_proc; + close (daemons_pipe[i][PIPE_READ]); + daemons_pipe[i][PIPE_READ] = -1; + } + } + } else + goto error1; + } + + return 1; +error1: + daemon_clear(); + return 0; +} + +int daemon_clear(void) +{ + unsigned int i = 0; + for (;i < sizeof(daemons)/sizeof(daemons[0]);i++) { + if (daemon_pids[i]) + kill(daemon_pids[i], SIGKILL); + } + return 0; +} + +static int call_script(char* path, char* argv[]) +{ + int status; + int r; + pid_t pid = fork(); + + if (pid < 0) + return 0; + else if (!pid) { + (void)execv(path, argv); + exit(-1); + } + + r = waitpid(pid, &status, 0); + if (r > 0) { + if (WIFEXITED(status)) + return !(WEXITSTATUS(status)); + else if (WIFCONTINUED(status)) + kill(pid, SIGKILL); + } + + /* fail */ + return 0; +} + +int cynara_n_init(void) +{ + char* argv[] = {CYNARA_PATH, "DENY", NULL}; + return call_script(argv[0],argv); +} + +int cynara_n_clear(void) +{ + return cynara_clear(); +} + +int cynara_init(void) +{ + char* argv[] = {CYNARA_PATH, "ALLOW", NULL}; + return call_script(argv[0],argv); +} + +int cynara_clear(void) +{ + char* argv[] = {CYNARA_PATH, NULL}; + return call_script(argv[0],argv); +} + +static char* args[3]; +char** prepare_args_for_binary(const struct binary* b, const char* test_name) +{ + args[0] = (char*)b->name; + if (!test_name[0]) + args[1] = NULL; + else { + args[1] = (char*)test_name; + args[2] = NULL; + } + return args; +} + + +/* + * Example of test_result detector function implementation + */ +void parse_test_state(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option) +{ + char test_id[MAX_COMMENT]; + + switch(state_change) { + case INIT_TEST: + sm_reset(); + break; + case NEW_STDOUT: + { + int k = 0; + buffer[state_option] = 0; + get_test_id(test_id, b, test_name); + fprintf(stderr, "[stdout][%s]%s\n",test_id, buffer); + while ( (k = sm_update(buffer, k))) { + const char* t_name = sm_get_result(0); + const char* result_code = sm_get_result(1); + bool is_successful = result_code[0] == '1' && result_code[1] == 0; + const char* result_text = is_successful ? "PASS" : "FAIL"; + + get_test_id(test_id, b, t_name); + add_test_result(test_id, result_text, "", is_successful); + sm_reset(); + } + } + break; + case NEW_STDERR: + buffer[state_option] = 0; + get_test_id(test_id, b, test_name); + fprintf(stderr, "[stderr][%s]%s\n",test_id, buffer); + break; + case RESULT_CODE: + if (state_option != 0) + add_test_result(get_test_id(test_id, b, test_name), "FAIL", "Test exited with error code", 0); + break; + case RESULT_SIGNAL: + add_test_result(get_test_id(test_id, b, test_name), "FAIL", "Finished by SIGNAL", 0); + break; + case RESULT_TIMEOUT: + add_test_result(get_test_id(test_id, b, test_name), "FAIL", "Test TIMEOUT", 0); + break; + } +} + +/****************************END of CUSTOM FUNCTIONS************************/ + + +static struct option long_options[] = { + {"list", no_argument, 0, 'l'}, + {"run", required_argument, 0, 'r'}, + {"description", required_argument, 0, 'd'}, + {0, 0, 0, 0 } +}; + +static int stdin_pipe[2]; +static int stdout_pipe[2]; +static int stderr_pipe[2]; +static struct test_result test_results[MAX_TC_NUM]; +static int test_results_i; +static char buffer[MAX_BUFFER]; +static const char* requested_tc[MAX_TC_NUM]; + +char* get_test_id(char* dest, const struct binary* b, const char* test_name) +{ + int len = strlen(b->name); + memcpy(dest, b->name, len); + memcpy(dest + len, test_name, strlen(test_name)+1); + return dest; +} + +static void print_description(const char* name, const char* description) +{ + printf("%s;%s\n",name, description); +} + +static void print_list(const char* test_name) +{ + unsigned int i; + char full_name[MAX_COMMENT]; + for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) { + int j = 0; + int l = strlen(tests[i].name); + memcpy(full_name, tests[i].name, l+1); + if (test_name && strncmp(test_name, full_name, l) != 0) + continue; + + while (tests[i].test_cases[j].name) { + memcpy(full_name + l, tests[i].test_cases[j].name, strlen(tests[i].test_cases[j].name) + 1); + if (!test_name || strcmp(full_name, test_name) == 0) + print_description(full_name,tests[i].test_cases[j].description); + j++; + } + } +} + + +static void stop_binary(const struct binary* b, pid_t pid, const char* test_name) +{ + int status = 0; + int res = 0; + res = waitpid(pid, &status, 0); + if (res == 0) { + //timeouted + kill(pid, SIGKILL); + res = waitpid(pid, &status, WNOHANG); + b->parse(b, test_name, buffer, RESULT_TIMEOUT, res); + } else if (res < 0) { + //errno check + kill(pid, SIGKILL); + res = waitpid(pid, &status, WNOHANG); + b->parse(b, test_name, buffer, RESULT_ERROR, res); + } else if (res > 0) { + if (WIFEXITED(status)) { + b->parse(b, test_name, buffer, RESULT_CODE, WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + b->parse(b, test_name, buffer, RESULT_SIGNAL, WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { + b->parse(b, test_name, buffer, RESULT_SIGNAL, WSTOPSIG(status)); + } else if (WIFCONTINUED(status)) { + kill(pid, SIGKILL); + b->parse(b, test_name, buffer, RESULT_SIGNAL, -1); + } + } +} + +static void parse_output_with_timeout(const struct binary* b, pid_t pid, const char* test_name) +{ + struct timeval tv; + fd_set rfds; + int nfds; + int res; + tv.tv_sec = b->timeout/(1000*1000); + tv.tv_usec = (b->timeout-tv.tv_sec*1000*1000); + while (1) { + FD_ZERO(&rfds); + FD_SET(stdout_pipe[PIPE_READ], &rfds); + FD_SET(stderr_pipe[PIPE_READ], &rfds); + nfds = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); + if (nfds == -1) { + if (errno != EINTR) + break; + } else if (nfds > 0) { + if (FD_ISSET(stdout_pipe[PIPE_READ], &rfds)) { + res = read(stdout_pipe[PIPE_READ], buffer, MAX_BUFFER-1); + if (res == 0 || (res < 0 && errno != EINTR)) + break; + else if (res >=0) + b->parse(b, test_name, buffer, NEW_STDOUT, res); + } + + if (FD_ISSET(stderr_pipe[PIPE_READ], &rfds)) { + res = read(stderr_pipe[PIPE_READ], buffer, MAX_BUFFER-1); + if (res == 0 || (res < 0 && errno != EINTR)) + break; + b->parse(b, test_name, buffer, NEW_STDERR, res); + } + } else { + //timeout + break; + } + } + stop_binary(b, pid, test_name); +} + +static int create_child(const char* path, char* const arguments[]) +{ + int child; + int nResult; + if (pipe(stdin_pipe) < 0) { + perror("allocating pipe for child input redirect failed"); + goto error1; + } + + if (pipe(stdout_pipe) < 0) { + perror("allocating pipe for child output redirect failed"); + goto error2; + } + + if (pipe(stderr_pipe) < 0) { + perror("allocating pipe for child output redirect failed"); + goto error3; + } + + child = fork(); + if (!child) { + char ld_path[512]; + sprintf(ld_path, "/usr/lib/dbus-tests/lib/libdbuspolicy-tests/:"); + // redirect stdin + if (dup2(stdin_pipe[PIPE_READ], STDIN_FILENO) == -1) { + perror("redirecting stdin failed"); + return -1; + } + + // redirect stdout + if (dup2(stdout_pipe[PIPE_WRITE], STDOUT_FILENO) == -1) { + perror("redirecting stdout failed"); + return -1; + } + + // redirect stderr + if (dup2(stderr_pipe[PIPE_WRITE], STDERR_FILENO) == -1) { + perror("redirecting stderr failed"); + return -1; + } + + // all these are for use by parent only + close(stdin_pipe[PIPE_READ]); + close(stdin_pipe[PIPE_WRITE]); + close(stdout_pipe[PIPE_READ]); + close(stdout_pipe[PIPE_WRITE]); + close(stderr_pipe[PIPE_READ]); + close(stderr_pipe[PIPE_WRITE]); + + char* ld_path_b = getenv("LD_LIBRARY_PATH"); + if (ld_path_b != NULL) + memcpy(ld_path + strlen(ld_path), ld_path_b, strlen(ld_path_b)+1); + setenv("LD_LIBRARY_PATH", ld_path, 1); + // run child process image + nResult = execv(path, arguments); + + // if we get here at all, an error occurred, but we are in the child + // process, so just exit + perror("exec of the child process failed"); + exit(nResult); + } else if (child > 0) { + // parent continues here + + // close unused file descriptors, these are for child only + close(stdin_pipe[PIPE_READ]); + close(stdout_pipe[PIPE_WRITE]); + close(stderr_pipe[PIPE_WRITE]); + } else { + // failed to create child + goto error4; + } + + return child; + +error4: + close(stderr_pipe[PIPE_READ]); + close(stderr_pipe[PIPE_WRITE]); +error3: + close(stdout_pipe[PIPE_READ]); + close(stdout_pipe[PIPE_WRITE]); +error2: + close(stdin_pipe[PIPE_READ]); + close(stdin_pipe[PIPE_WRITE]); +error1: + return -1; +} + +static void run_test(const struct binary* b, const char* test_name) +{ + int res = -1; + char** arg; + char test_id[MAX_COMMENT]; + + assert(b); + assert(b->name); + assert(b->path); + assert(test_name); + + arg = b->prepare_args(b, test_name); + + if (b->init) + if (!b->init()) { + add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Internal error: Cannot init test", 0); + return; + } + + res = create_child(b->path, arg); + if (res > 0) + parse_output_with_timeout(b, res, test_name); + else + add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Internal error: Cannot start test", 0); + + if (b->clean) + b->clean(); +} + +static void parse_run_test(const char* tc) { + unsigned int i = 0; + for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) { + int len = strlen(tests[i].name); + if (strncmp(tc, tests[i].name, len) == 0) { + if (tc[len] == '*' || tc[len] == '\0') + run_test(&tests[i], ""); + else + run_test(&tests[i], tc + len); + } + } +} + +static int parse_option(int argc, char* argv[]) +{ + int ch = 0; + int c = 0; + while ((ch = getopt_long(argc, argv, "lr:d:", long_options, NULL)) != -1) { + switch (ch) { + case 'l': + print_list(NULL); + return 1; + case 'r': + if (c >= MAX_TC_NUM - 1) //NULL at the end + return 0; + + if (optarg) + requested_tc[c++] = optarg; + + break; + case 'd': + print_list(optarg); + return 1; + } + } + return 0; +} + +//output_new/fail/success +void add_test_result(const char* test_id, const char* result, const char* comment, int res) +{ + test_results[test_results_i].is_positive = res; + strcpy(test_results[test_results_i].result, result); + strcpy(test_results[test_results_i].comment, comment); + strcpy(test_results[test_results_i++].name, test_id); +} + +static void prepare_results(void) +{ + //todo +} + +static void print_results() +{ + int i = 0; + for (i = 0; i < test_results_i; i++) + { + printf("%s;%s;%s\n", test_results[i].name, test_results[i].result, test_results[i].comment); + } +} + +int main(int argc, char* argv[]) +{ + unsigned int i; + signal(SIGPIPE, SIG_IGN); + if (parse_option(argc, argv)) + return 0; + + prepare_results(); + + if (!requested_tc[0]) { + for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) + run_test(&tests[i], ""); + } else { + i = 0; + while(requested_tc[i]) { + parse_run_test(requested_tc[i]); + i++; + } + } + + print_results(); + return 0; +} diff --git a/src/test_runner.h b/src/test_runner.h new file mode 100644 index 0000000..3c79a99 --- /dev/null +++ b/src/test_runner.h @@ -0,0 +1,69 @@ +/* This file is part of test-runner (see template.c) + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Author: Kazimierz Krosman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef TEST_RUNNER_H +#define TEST_RUNNER_H +#include + +#define TC_NAME "libdbuspolicy-tests" +#define TEST_PATH "/usr/lib/dbus-tests/test-suites/libdbuspolicy-tests/" +#define CYNARA_PATH TEST_PATH "cynara_prepare.sh" +#define MAX_TC_NUM 1024 +#define MAX_BUFFER (64*1024) +#define MAX_COMMENT 1024 + +enum { + INIT_TEST, + NEW_STDOUT, + NEW_STDERR, + RESULT_CODE, + RESULT_SIGNAL, + RESULT_ERROR, + RESULT_TIMEOUT +}; + +struct test_result { + bool is_positive; + char comment[MAX_COMMENT]; + char result[MAX_COMMENT]; + char name[MAX_COMMENT]; +}; + +struct test_case { + const char* name; + const char* description; +}; + +struct binary { + const char* path; + const char* name; + /* can be filled by asking binary */ + struct test_case* test_cases; + int timeout; + + char** (*prepare_args) (const struct binary* b, const char* test_name); + void (*parse) (const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); + int (*init)(void); + int (*clean)(void); +}; + +char* get_test_id(char* dest, const struct binary* b, const char* test_name); +void add_test_result(const char* test_id, const char* result, const char* comment, int res); + + +#endif /* TEST_RUNNER_H */ -- 2.7.4 From 6bb5ffa99134707b610d5b2b55b33239b73b2140 Mon Sep 17 00:00:00 2001 From: Kazimierz Krosman Date: Mon, 19 Dec 2016 14:02:50 +0100 Subject: [PATCH 05/16] tests: Add test package for libdbuspolicy - again This reverts commit 376f38dafa0b7ee5eae3d8f0ba0333c84a79742d, which reverted commit bb7d32bb63f1d0fc463255000fbc773a119314a9. This is different from commit bb7d32bb63f1d0fc463255000fbc773a119314a9 in handling builds - it provides single spec file. Additionally, corrections for tests, mostly excluding initialization of the library from "test cases". Author: Kazimierz Krosman with some corrections by Adrian Szyndela Change-Id: I64a58818c5c7f692db38f8225bec1e7a11954de6 (cherry picked from commit 575b04077b18ca810aa1974314785e32340d4bb6) --- Makefile.am | 43 ++- configure.ac | 1 + packaging/libdbuspolicy.spec | 43 ++- src/cynara_prepare.sh | 8 + src/dbus_daemon.c | 236 +++++++++++++++ src/libdbuspolicy1.c | 7 + src/stest_common.c | 32 ++ src/stest_common.h | 22 ++ src/stest_cynara.c | 40 +++ src/stest_method_call.c | 80 +++++ src/stest_ownership.c | 59 ++++ src/stest_signal.c | 26 ++ src/test_runner.c | 692 +++++++++++++++++++++++++++++++++++++++++++ src/test_runner.h | 69 +++++ 14 files changed, 1347 insertions(+), 11 deletions(-) create mode 100644 src/cynara_prepare.sh create mode 100644 src/dbus_daemon.c create mode 100644 src/stest_common.c create mode 100644 src/stest_common.h create mode 100644 src/stest_cynara.c create mode 100644 src/stest_method_call.c create mode 100644 src/stest_ownership.c create mode 100644 src/stest_signal.c create mode 100644 src/test_runner.c create mode 100644 src/test_runner.h diff --git a/Makefile.am b/Makefile.am index 30eec82..c2e9409 100644 --- a/Makefile.am +++ b/Makefile.am @@ -43,7 +43,7 @@ LIBDBUSPOLICY1_AGE=0 pkginclude_HEADERS = src/dbuspolicy1/libdbuspolicy1.h lib_LTLIBRARIES = src/libdbuspolicy1.la -src_libdbuspolicy1_la_SOURCES =\ +COMMON_SRC =\ src/libdbuspolicy1-private.h \ src/libdbuspolicy1.c \ src/internal/internal.cpp \ @@ -51,7 +51,10 @@ src_libdbuspolicy1_la_SOURCES =\ src/internal/naive_policy_db.cpp \ src/internal/policy.cpp \ src/internal/xml_parser.cpp \ - src/internal/tslog.cpp \ + src/internal/tslog.cpp + +src_libdbuspolicy1_la_SOURCES =\ + $(COMMON_SRC) \ src/internal/cynara.cpp EXTRA_DIST += src/libdbuspolicy1.sym @@ -81,14 +84,7 @@ src_test_libdbuspolicy1_method_SOURCES = src/test-libdbuspolicy1-method.cpp noinst_LTLIBRARIES = src/libinternal.a src_libinternal_a_SOURCES =\ - src/libdbuspolicy1-private.h \ - src/internal/internal.cpp \ - src/libdbuspolicy1.c \ - src/internal/naive_policy_checker.cpp \ - src/internal/naive_policy_db.cpp \ - src/internal/policy.cpp \ - src/internal/xml_parser.cpp \ - src/internal/tslog.cpp \ + $(COMMON_SRC) \ src/internal/cynara_mockup.cpp src_test_libdbuspolicy1_ownership_LDADD = $(CYNARA_LIBS) \ @@ -100,6 +96,33 @@ src_test_libdbuspolicy1_signal_LDADD = $(CYNARA_LIBS) \ src_test_libdbuspolicy1_method_LDADD = $(CYNARA_LIBS) \ src/libinternal.a +if ENABLE_STANDALONE_TESTS +noinst_LTLIBRARIES += src/libinternalfortests.a +src_libinternalfortests_a_SOURCES =\ + $(COMMON_SRC) \ + src/internal/cynara.cpp + +runner_PROGRAMS = libdbuspolicy-tests +libdbuspolicy_tests_SOURCES = src/test_runner.c +runnerdir = ${libdir}/dbus-tests/runner/ + +alonetestdir = ${libdir}/dbus-tests/test-suites/libdbuspolicy-tests/ +alonetest_PROGRAMS = dbus_daemon stest_ownership stest_method_call stest_signal stest_cynara + +dbus_daemon_SOURCES = src/dbus_daemon.c +stest_ownership_SOURCES = src/stest_ownership.c src/stest_common.c +stest_method_call_SOURCES = src/stest_method_call.c src/stest_common.c +stest_signal_SOURCES = src/stest_signal.c src/stest_common.c +stest_cynara_SOURCES = src/stest_cynara.c src/stest_common.c + +stest_ownership_LDADD = src/libinternalfortests.a -lstdc++ $(CYNARA_LIBS) +stest_method_call_LDADD = src/libinternalfortests.a -lstdc++ $(CYNARA_LIBS) +stest_signal_LDADD = src/libinternalfortests.a -lstdc++ $(CYNARA_LIBS) +stest_cynara_LDADD = src/libinternalfortests.a -lstdc++ $(CYNARA_LIBS) + +all-tests:: $(alonetest_PROGRAMS) $(runner_PROGRAMS) +endif + if ENABLE_DOXYGEN CLEANFILES += documentation diff --git a/configure.ac b/configure.ac index 9c5aa73..6d6dbf4 100644 --- a/configure.ac +++ b/configure.ac @@ -50,6 +50,7 @@ AS_IF([test "x$enable_debug" = "xyes"], [ AC_ARG_ENABLE(tests, AS_HELP_STRING([--enable-tests], [Add API function that allows to change credentials during execution]), [with_tests=yes], with_tests=no) +AM_CONDITIONAL([ENABLE_STANDALONE_TESTS], [test x$with_tests = xyes]) if test "x$with_tests" = "xyes"; then AC_DEFINE(LIBDBUSPOLICY_TESTS_API, 1, [Define if tests are enabled]) fi diff --git a/packaging/libdbuspolicy.spec b/packaging/libdbuspolicy.spec index f9e6e7e..0ec26d2 100644 --- a/packaging/libdbuspolicy.spec +++ b/packaging/libdbuspolicy.spec @@ -11,6 +11,9 @@ BuildRequires: pkgconfig(cynara-client) %package devel Summary: Helper library for fine-grained userspace policy handling-development package + +%package tests +Summary: Helper library for fine-grained userspace policy handling-development package Requires: %{name} = %{version} %description @@ -22,6 +25,8 @@ libdbuspolicy is a helper library for fine-grained userspace policy handling (with SMACK support). This package contains development files. +%description tests +This package contains contains integration tests for libdbuspolicy. %if 0%{?enable_doxygen:1} %package doc @@ -32,11 +37,18 @@ BuildRequires: doxygen Doxygen documentation for libdbuspolicy. %endif +%define testsdirname %{name}-tests +%define runnername %{testsdirname} +%define dbustestsdir %{_libdir}/dbus-tests + %prep %setup -q cp %{SOURCE1001} . %build +%reconfigure --libdir=%{_libdir} --prefix=/usr --enable-tests +make all-tests + %reconfigure --libdir=%{_libdir} --prefix=/usr \ %if 0%{?enable_doxygen:1} --enable-doxygen @@ -49,6 +61,30 @@ make check make DESTDIR=%{buildroot} install rm %{buildroot}%{_libdir}/libdbuspolicy1.la +%define testconfigsdir %{dbustestsdir}/configs/%{testsdirname} +%define btestconfigsdir %{buildroot}%{testconfigsdir} +mkdir -p %{btestconfigsdir} +libtool --mode=install install -m 0644 tests/system.conf %{btestconfigsdir} + +%define testconfigsystemddir %{testconfigsdir}/system.d +%define btestconfigsystemddir %{buildroot}%{testconfigsystemddir} +mkdir -p %{btestconfigsystemddir} +libtool --mode=install install -m 0644 tests/system.d/ownerships.test.conf %{btestconfigsystemddir} +libtool --mode=install install -m 0644 tests/system.d/signals.test.conf %{btestconfigsystemddir} +libtool --mode=install install -m 0644 tests/system.d/methods.test.conf %{btestconfigsystemddir} +libtool --mode=install install -m 0644 tests/system.d/cynara.test.conf %{btestconfigsystemddir} + +%define testsuitedir %{dbustestsdir}/test-suites/%{testsdirname} +%define btestsuitedir %{buildroot}%{testsuitedir} +mkdir -p %{btestsuitedir} +libtool --mode=install install -m 0755 src/cynara_prepare.sh %{btestsuitedir} +libtool --mode=install install -m 0755 stest_* dbus_daemon %{btestsuitedir} + +%define testrunnerdir %{dbustestsdir}/runner +%define btestrunnerdir %{buildroot}%{testrunnerdir} +mkdir -p %{btestrunnerdir} +libtool --mode=install install -m 0755 %{runnername} %{btestrunnerdir} + %post -p /sbin/ldconfig %postun -p /sbin/ldconfig @@ -60,7 +96,6 @@ rm %{buildroot}%{_libdir}/libdbuspolicy1.la %files devel %defattr(-,root,root) %{_includedir}/* - %{_libdir}/pkgconfig/* %{_libdir}/libdbuspolicy1.so %manifest %{name}.manifest @@ -71,3 +106,9 @@ rm %{buildroot}%{_libdir}/libdbuspolicy1.la %{_datadir}/doc/dbuspolicy/* %endif %changelog + +%files tests +%defattr(-,root,root) +%{testrunnerdir}/%{runnername} +%{testsuitedir}/* +%{testconfigsdir}/* diff --git a/src/cynara_prepare.sh b/src/cynara_prepare.sh new file mode 100644 index 0000000..acc2401 --- /dev/null +++ b/src/cynara_prepare.sh @@ -0,0 +1,8 @@ +#!/bin/sh +if [ -z "${1}" ]; then + cyad -e "MANIFESTS" -u 200 -c L -p t -r y + cyad -e "USER_TYPE_ADMIN" -u 200 -c L -p t -r y +else + cyad -s -k "MANIFESTS" -u 200 -c L -p t -t $1 + cyad -s -k "USER_TYPE_ADMIN" -u 200 -c L -p t -t $1 +fi diff --git a/src/dbus_daemon.c b/src/dbus_daemon.c new file mode 100644 index 0000000..058106e --- /dev/null +++ b/src/dbus_daemon.c @@ -0,0 +1,236 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "kdbus.h" + +#define KDBUS_SYSTEM_BUS_PATH "/sys/fs/kdbus/0-system/bus" + +#define KDBUS_ALIGN8(l) (((l) + 7) & ~7) +#define KDBUS_ITEM_HEADER_SIZE offsetof(struct kdbus_item, data) +#define KDBUS_ITEM_SIZE(s) KDBUS_ALIGN8((s) + KDBUS_ITEM_HEADER_SIZE) +#define KDBUS_ITEM_NEXT(item) \ + (typeof(item))(((uint8_t *)item) + KDBUS_ALIGN8((item)->size)) +#define KDBUS_FOREACH(iter, first, _size) \ + for (iter = (first); \ + ((uint8_t *)(iter) < (uint8_t *)(first) + (_size)) && \ + ((uint8_t *)(iter) >= (uint8_t *)(first)); \ + iter = (void*)(((uint8_t *)iter) + KDBUS_ALIGN8((iter)->size))) + +#define POOL_SIZE (16 * 1024 * 1024) + +#define err_r(_r, _msg) fprintf(stderr, "log: %d, %s, %s, %d, %s\n",(_r), (_msg), __func__, __LINE__, __FILE__) +#define err(_msg) err_r(errno, (_msg)) + +static uint8_t* pool; +static char* server_names[16]; +int ready_fd = 0; + +static inline int kdbus_cmd_hello(int bus_fd, struct kdbus_cmd_hello *cmd) +{ + int ret = ioctl(bus_fd, KDBUS_CMD_HELLO, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline int kdbus_cmd_free(int conn_fd, struct kdbus_cmd_free *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_FREE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static inline int kdbus_cmd_name_acquire(int conn_fd, struct kdbus_cmd *cmd) +{ + int ret = ioctl(conn_fd, KDBUS_CMD_NAME_ACQUIRE, cmd); + return (ret < 0) ? (errno > 0 ? -errno : -EINVAL) : 0; +} + +static void bus_poool_free_slice(int fd, uint64_t offset) +{ + struct kdbus_cmd_free cmd = { + .size = sizeof(cmd), + .offset = offset, + }; + int r; + r = kdbus_cmd_free(fd, &cmd); + if (r < 0) + err_r(r, "cannot free pool slice"); +} + +static int bus_open_connection(const char *name, + uint64_t recv_flags) +{ + struct kdbus_cmd_hello hello; + int r; + int fd; + + fd = open(name, O_RDWR | O_CLOEXEC); + if (fd < 0) { + r = err("cannot open bus"); + goto error; + } + + memset(&hello, 0, sizeof(hello)); + hello.size = sizeof(hello); + hello.attach_flags_send = _KDBUS_ATTACH_ALL; + hello.attach_flags_recv = recv_flags; + hello.pool_size = POOL_SIZE; + r = kdbus_cmd_hello(fd, &hello); + if (r < 0) { + err_r(r, "HELLO failed"); + goto error; + } + + bus_poool_free_slice(fd, hello.offset); + + /* + * Map the pool of the connection. Its size has been set in the + * command struct above. See kdbus.pool(7). + */ + pool = mmap(NULL, POOL_SIZE, PROT_READ, MAP_SHARED, fd, 0); + if (pool == MAP_FAILED) { + r = err("cannot mmap pool"); + goto error; + } + + return fd; + +error: + return -1; +} + + + +static int bus_acquire_name(int fd, const char *name) +{ + struct kdbus_item *item; + struct kdbus_cmd *cmd; + size_t size; + int r; + + /* + * This function acquires a well-known name on the bus through the + * KDBUS_CMD_NAME_ACQUIRE ioctl. This ioctl takes an argument of type + * 'struct kdbus_cmd', which is assembled below. See kdbus.name(7). + */ + size = sizeof(*cmd); + size += KDBUS_ITEM_SIZE(strlen(name) + 1); + + cmd = alloca(size); + memset(cmd, 0, size); + cmd->size = size; + + /* + * The command requires an item of type KDBUS_ITEM_NAME, and its + * content must be a valid bus name. + */ + item = cmd->items; + item->type = KDBUS_ITEM_NAME; + item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; + strcpy(item->str, name); + + /* + * Employ the command on the connection owner file descriptor. + */ + r = kdbus_cmd_name_acquire(fd, cmd); + if (r < 0) + return err_r(r, "cannot acquire name"); + + return 0; +} + + +int parse_args(int argc, char** argv) +{ + char state = 0; + unsigned long int uid = 0; + unsigned long int gid = 0; + int i = 1; + int r = 0; + int fdl = -1; + int count = 0; + + while (i < argc) + { + if (argv[i][0] == '-') + state = argv[i][1]; + else { + switch (state) { + + case 'n': + server_names[count++] = argv[i]; + break; + + case 'u': + uid = strtoul(argv[i],NULL,10); + r = setuid((uid_t)uid); + if (r< 0) { + fprintf(stderr, "Cannot set uid"); + exit(-3245); + } + break; + + case 'g': + gid = strtoul(argv[i],NULL,10); + r = setgid((gid_t)gid); + if (r< 0) { + fprintf(stderr, "Cannot set gid"); + exit(-3245); + } + break; + + case 'l': + fdl = open("/proc/self/attr/current", 0, S_IWUSR); + if (fdl < 0) + { + fprintf(stderr,"Cannot open /proc/self/attr/current\n"); + exit(-345); + } + + r = write(fdl, argv[i], strlen(argv[i])); + if (r < 0) + { + fprintf(stderr, "Cannot write to /proc/self/attr/current\n"); + close(fdl); + exit(-345); + } + close(fdl); + break; + case 'q': + ready_fd = strtol(argv[i], NULL, 10); + break; + } + } + i++; + } + return 0; +} + +int main(int argc, char* argv[]) { + int j = 0; + int fd; + parse_args(argc, argv); + fd = bus_open_connection(KDBUS_SYSTEM_BUS_PATH, KDBUS_ATTACH_PIDS); + if (fd < 0) { + return -1; + } + + while(server_names[j] != '\0') + { + if (bus_acquire_name(fd, server_names[j])) + return -1; + j++; + } + + close(ready_fd); + + for(;;); + return 0; +} diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index f507f25..b37b1ac 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -51,6 +51,13 @@ #define UID_INVALID ((uid_t) -1) #define GID_INVALID ((gid_t) -1) +#ifdef LIBDBUSPOLICY_TESTS_API +#undef SYSTEM_BUS_CONF_FILE_PRIMARY +#undef SESSION_BUS_CONF_FILE_PRIMARY +#define SYSTEM_BUS_CONF_FILE_PRIMARY "/usr/lib/dbus-tests/configs/libdbuspolicy-tests/system.conf" +#define SESSION_BUS_CONF_FILE_PRIMARY "/usr/lib/dbus-tests/configs/libdbuspolicy-tests/session.conf" +#endif + /** A process ID */ typedef unsigned long dbus_pid_t; /** A user ID */ diff --git a/src/stest_common.c b/src/stest_common.c new file mode 100644 index 0000000..6938047 --- /dev/null +++ b/src/stest_common.c @@ -0,0 +1,32 @@ +/* Author: Kazimierz Krosman */ +#include +#include +#include + +uint64_t test_cases_mask = ~(0ULL); +int test_count = 0; + +void assert_printf(int res, int tc, const char* value, int line, const char* file) +{ + if (res) { + printf("[r][%d]1\n", tc); + } else { + printf("[r][%d]0\n", tc); + fprintf(stderr, "[r][%d]0<-w=%s, line=%d, file=%s\n", tc, value, line, file); + } +} + +void prepare_mask(int argc, char* argv[]) +{ + if (argc > 1) + { + int i = 1; + test_cases_mask = 0; + for (;i < argc; i++) { + int val = strtol(argv[i], NULL, 10); + if (val >= 0) + test_cases_mask |= (1< + +#define tassert(v) \ + do { \ + if (test_cases_mask & (1 << test_count)) \ + { \ + int ___r = (v); \ + assert_printf(___r, test_count, #v, __LINE__, __FILE__); \ + } \ + test_count++; \ + } while (0) + +enum { + false, + true +}; + +extern uint64_t test_cases_mask; +extern int test_count; +void prepare_mask(int argc, char* argv[]); +void assert_printf(int res, int tc, const char* value, int line, const char* file); diff --git a/src/stest_cynara.c b/src/stest_cynara.c new file mode 100644 index 0000000..7e1df99 --- /dev/null +++ b/src/stest_cynara.c @@ -0,0 +1,40 @@ +/* Author: Kazimierz Krosman */ +#include +#include +#include +#include +#include +#include +#include "stest_common.h" + +#define NEGATIVE_MATCH "negative" +#define COUNT 1000 + +void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); + +int main(int argc, char* argv[]) +{ + void* c = NULL; + int desired_result = 1; + int i; + + assert(argc>0); + + if (!strncmp(argv[0], NEGATIVE_MATCH, sizeof(NEGATIVE_MATCH)-1)) + desired_result = 0; + + printf("---desired result: %d %s\n\n", desired_result, argv[0]); + c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus"); + assert(c != NULL); + + __dbuspolicy1_change_creds(c,200,0,"L"); + + for (i = 0; i < COUNT; i++) { + int result = dbuspolicy1_check_in(c, "cynara.destination", "cynara.sender", + "L", 200, 0, NULL, "cynara.interface", "cynara.method", + DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0); + assert(result == desired_result); + } + printf("[r][0]1\n"); + return 0; +} diff --git a/src/stest_method_call.c b/src/stest_method_call.c new file mode 100644 index 0000000..d1bf8e1 --- /dev/null +++ b/src/stest_method_call.c @@ -0,0 +1,80 @@ +/* Author: Kazimierz Krosman */ +#include +#include +#include +#include +#include "stest_common.h" + +void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); + +int main(int argc, char* argv[]) +{ + void* c = NULL; + + prepare_mask(argc,argv); + + c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus"); + assert(c != NULL); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", NULL, "org.test.Itest1", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", NULL, 0, 0, "", "org.test.Itest1", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest1", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest1", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest1", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest1", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test2", "org.test.test3", "", "org.test.Itest2", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test2", "org.test.test3", "", 0, 0, "", "org.test.Itest2", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "", "org.test.Itest3", "NotKnown", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "", "org.test.Itest3", "DontDoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == false); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest3", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, "" ,"org.test.Itest3", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test3", "org.test.test2", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test3", "org.test.test2", "", 5001, 100, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test9", "org.test.test10", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test9", "org.test.test10", "", 5001, 100, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_out(c, "org.test.test10", "org.test.test9", "", "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5001,100,NULL); + tassert(dbuspolicy1_check_in(c, "org.test.test10", "org.test.test9", "", 0, 0, NULL, "org.test.Itest4", "DoIt", DBUSPOLICY_MESSAGE_TYPE_METHOD_CALL, "", 0, 0) == true); + + return 0; +} diff --git a/src/stest_ownership.c b/src/stest_ownership.c new file mode 100644 index 0000000..9172500 --- /dev/null +++ b/src/stest_ownership.c @@ -0,0 +1,59 @@ +/* Author: Kazimierz Krosman */ +#include +#include +#include +#include +#include "stest_common.h" + +void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); + +int main(int argc, char* argv[]) +{ + void* c = NULL; + + prepare_mask(argc,argv); + + c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus"); + assert(c != NULL); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(dbuspolicy1_can_own(c, "org.test.test1")); + + __dbuspolicy1_change_creds(c, 5009, 0, NULL); + tassert(dbuspolicy1_can_own(c, "org.test.test1")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(!dbuspolicy1_can_own(c, "org.test.test2")); + + __dbuspolicy1_change_creds(c, 5009, 0, NULL); + tassert(!dbuspolicy1_can_own(c, "org.test.test2")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(!dbuspolicy1_can_own(c, "org.test.test3")); + + __dbuspolicy1_change_creds(c, 5009, 0, NULL); + tassert(!dbuspolicy1_can_own(c, "org.test.test3")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(!dbuspolicy1_can_own(c, "org.test.test4")); + + __dbuspolicy1_change_creds(c, 5009, 0, NULL); + tassert(dbuspolicy1_can_own(c, "org.test.test4")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(!dbuspolicy1_can_own(c, "org.test.test5")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(dbuspolicy1_can_own(c, "org.test.test6")); + + __dbuspolicy1_change_creds(c, 0, 0, NULL); + tassert(dbuspolicy1_can_own(c, "org.test.test7")); + + tassert(dbuspolicy1_can_own(c, "a.b.c")); + tassert(dbuspolicy1_can_own(c, "a.b")); + tassert(!dbuspolicy1_can_own(c, "c")); + tassert(!dbuspolicy1_can_own(c, "a.c")); + tassert(!dbuspolicy1_can_own(c, "b.c")); + + return 0; +} diff --git a/src/stest_signal.c b/src/stest_signal.c new file mode 100644 index 0000000..5fbef7c --- /dev/null +++ b/src/stest_signal.c @@ -0,0 +1,26 @@ +/* Author: Kazimierz Krosman */ +#include +#include +#include +#include +#include "stest_common.h" + +void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label); + +int main(int argc, char* argv[]) +{ + void* c = NULL; + + prepare_mask(argc,argv); + + c = dbuspolicy1_init("/sys/fs/kdbus/0-system/bus"); + assert(c != NULL); + + __dbuspolicy1_change_creds(c,0,0,NULL); + tassert(dbuspolicy1_check_out(c, "", "bli.bla.blubb test.test1 test.tes3", "", "/an/object/path", "", DBUSPOLICY_MESSAGE_TYPE_SIGNAL, "", 0, 0) == true); + + __dbuspolicy1_change_creds(c,5010,0,NULL); + tassert(dbuspolicy1_check_out(c, "", "bli.bla.blubb", "", "/an/object/path", "", DBUSPOLICY_MESSAGE_TYPE_SIGNAL, "", 0, 0) == false); + + return 0; +} diff --git a/src/test_runner.c b/src/test_runner.c new file mode 100644 index 0000000..33517a0 --- /dev/null +++ b/src/test_runner.c @@ -0,0 +1,692 @@ +/* This file contains test-runner for libdbuspolicy + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Author: Kazimierz Krosman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "test_runner.h" + +enum { + PIPE_READ, + PIPE_WRITE, +}; + +/*****************CUSTOM SECTION***********************************/ +/*custom function that parse stdout of binary and result of binary*/ +void parse_test_state(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); +void parse_one_test_one_binary(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); +char** prepare_args_for_binary(const struct binary* b, const char* test_name); +int daemon_init(void); +int daemon_clear(void); +int cynara_init(void); +int cynara_clear(void); +int cynara_n_init(void); +int cynara_n_clear(void); + +static struct test_case ownership_test_cases[] = { + {"0", "Simple check for ownership in default context"}, + {"1", "Simple check for ownership in default context"}, + {"2", "Ownership check in user context"}, + {"3", "Ownership check in user context (negative test)"}, + {"4", "Ownership check in mandatory context with user context (context priority check)"}, + {"5", "Ownership check in mandatory context with user context (for another user)"}, + {"6", "Ownership check for not root user context (negative test)"}, + {"7", "Ownership check for not root user context"}, + {"8", "Ownership check for group context"}, + {"9", "Ownership check for all context (priority check)"}, + {"10", "Ownership check for all context (priority check)"}, + {"11", "Ownership check for own_prefix case (1)"}, + {"12", "Ownership check for own_prefix case (2)"}, + {"13", "Ownership check for own_prefix case (negative test)"}, + {"14", "Ownership check for own_prefix case (negative test)"}, + {"15", "Ownership check for own_prefix case (negative test)"}, + {NULL, NULL} +}; + +static struct test_case method_call_test_cases[] = { + {"0", "check_out test"}, + {"1", "check_in test"}, + {"2", "check_out test"}, + {"3", "check_in test"}, + {"4", "check_out test"}, + {"5", "check_in test"}, + {"6", "check_out test"}, + {"7", "check_in test"}, + {"8", "check_out test"}, + {"9", "check_in test"}, + {"10", "check_out test"}, + {"11", "check_in test"}, + {"12", "check_out test"}, + {"13", "check_in test"}, + {"14", "check_out test"}, + {"15", "check_in test"}, + {"16", "check_out test"}, + {"17", "check_in test"}, + {"18", "check_out test"}, + {"19", "check_in test"}, + {NULL, NULL} +}; + +static struct test_case signal_test_cases[] = { + {"0", "Check out for signal"}, + {"1", "Check out for signal (negative)"}, + {NULL, NULL} +}; + +static struct test_case cynara_test_cases[] = { + {"0", "Check cynara for result"}, + {NULL, NULL} +}; + +static struct test_case negative_cynara_test_cases[] = { + {"0", "Check cynara for result (negative test)"}, + {NULL, NULL} +}; + +/* This table is used to start binaries */ +struct binary tests[] = { +/*path, name, TC_table, timeout in us, prepare_args_handler, parse_function_handler, init_handler, clean_handler*/ + {TEST_PATH "stest_ownership", "ownership", ownership_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, + {TEST_PATH "stest_method_call", "method_call", method_call_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, + {TEST_PATH "stest_signal", "signal", signal_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, daemon_init, daemon_clear}, + {TEST_PATH "stest_cynara", "cynara", cynara_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, cynara_init, cynara_clear}, + {TEST_PATH "stest_cynara", "negative_cynara", negative_cynara_test_cases, 1000*1000, prepare_args_for_binary, parse_test_state, cynara_n_init, cynara_n_clear}, +}; + + +static const char result_pattern[] = "[r][%0]%1"; +static struct state { + unsigned int i; // index of input buffer + unsigned int j; // index in results[n] + unsigned int n; //index in results buffer (0 or 1) + char results[2][MAX_COMMENT]; +} g_state; + +static void sm_reset(void) +{ + memset(&g_state, 0, sizeof (g_state)); +} + +static int sm_update(char* buffer, int i) +{ + int l = strlen(buffer) + 1; + while (i < l && g_state.i < sizeof(result_pattern) - 1) { + if (result_pattern[g_state.i] == '%') { + g_state.n = result_pattern[g_state.i+1] - '0'; + if (g_state.n > 1) { + sm_reset(); + i--; + } else if (isalnum(buffer[i])) { + g_state.results[g_state.n][g_state.j++] = buffer[i]; + } else if (buffer[i] == result_pattern[g_state.i+2] || buffer[i] == '\n') { + g_state.results[g_state.n][g_state.j] = 0; + g_state.i += 3; + g_state.j = 0; + if (g_state.n == 1) + return i; + } else { + g_state.i = 0; + g_state.j = 0; + } + } else if (result_pattern[g_state.i] == buffer[i]) { + g_state.i++; + } else { + sm_reset(); + } + i++; + } + + if (g_state.i >= sizeof(result_pattern) - 1) { + g_state.results[g_state.n][g_state.j] = 0; + g_state.i += 3; + g_state.j = 0; + if (g_state.n == 1) + return i; + } + + return 0; +} + +static const char* sm_get_result(int i) +{ + return g_state.results[i]; +} + +static pid_t daemon_pids[4] ={0}; +static int daemons_pipe[4][2]; +static char* daemon_argv1[] = {TEST_PATH "dbus_daemon", "-q", NULL, "-n","org.test.test3", NULL}; +static char* daemon_argv2[] = {TEST_PATH "dbus_daemon", "-q", NULL,"-n", "org.test.test2", "-g", "100", "-u", "5001", NULL}; +static char* daemon_argv3[] = {TEST_PATH "dbus_daemon", "-q", NULL,"-n", "org.test.test12", "org.test.test9", NULL}; +static char* daemon_argv4[] = {TEST_PATH "dbus_daemon", "-q", NULL, "-n", "org.test.test13", "org.test.test10", "org.test.test11", "-g", "100", "-u", "5001", NULL}; +static char** daemons[] = { daemon_argv1, daemon_argv2, daemon_argv3, daemon_argv4}; + +int daemon_init(void) +{ + int i = 0; + int ready_proc = 0; + struct timeval tv; + fd_set rfds; + int nfds = -1; + int proc_num = sizeof(daemons)/sizeof(daemons[0]); + + for (;i < proc_num;i++) { + if (pipe(daemons_pipe[i]) < 0) { + perror("cannot create pipe"); + goto error1; + } + + daemon_pids[i] = fork(); + if (!daemon_pids[i]) { + char fdd[15]; + sprintf(fdd,"%d",daemons_pipe[i][PIPE_WRITE]); + daemons[i][2] = fdd; + close (daemons_pipe[i][PIPE_READ]); + (void)execv(daemons[i][0],daemons[i]); + exit(0); + } else if (daemon_pids[i] > 0){ + close (daemons_pipe[i][PIPE_WRITE]); + } else + goto error1; + } + + tv.tv_sec = 1; + tv.tv_usec = 0; + while(1) { + FD_ZERO(&rfds); + for (i = 0; i < proc_num;i++) { + if (daemons_pipe[i][PIPE_READ] > -1) + FD_SET(daemons_pipe[i][PIPE_READ], &rfds); + } + + if (ready_proc >= proc_num) + break; + + nfds = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); + if (nfds > 0) { + for (i = 0; i < proc_num;i++) { + if (daemons_pipe[i][PIPE_READ] > -1 && FD_ISSET(daemons_pipe[i][PIPE_READ], &rfds)) { + ++ready_proc; + close (daemons_pipe[i][PIPE_READ]); + daemons_pipe[i][PIPE_READ] = -1; + } + } + } else + goto error1; + } + + return 1; +error1: + daemon_clear(); + return 0; +} + +int daemon_clear(void) +{ + unsigned int i = 0; + for (;i < sizeof(daemons)/sizeof(daemons[0]);i++) { + if (daemon_pids[i]) + kill(daemon_pids[i], SIGKILL); + } + return 0; +} + +static int call_script(char* path, char* argv[]) +{ + int status; + int r; + pid_t pid = fork(); + + if (pid < 0) + return 0; + else if (!pid) { + (void)execv(path, argv); + exit(-1); + } + + r = waitpid(pid, &status, 0); + if (r > 0) { + if (WIFEXITED(status)) + return !(WEXITSTATUS(status)); + else if (WIFCONTINUED(status)) + kill(pid, SIGKILL); + } + + /* fail */ + return 0; +} + +int cynara_n_init(void) +{ + char* argv[] = {CYNARA_PATH, "DENY", NULL}; + return call_script(argv[0],argv); +} + +int cynara_n_clear(void) +{ + return cynara_clear(); +} + +int cynara_init(void) +{ + char* argv[] = {CYNARA_PATH, "ALLOW", NULL}; + return call_script(argv[0],argv); +} + +int cynara_clear(void) +{ + char* argv[] = {CYNARA_PATH, NULL}; + return call_script(argv[0],argv); +} + +static char* args[3]; +char** prepare_args_for_binary(const struct binary* b, const char* test_name) +{ + args[0] = (char*)b->name; + if (!test_name[0]) + args[1] = NULL; + else { + args[1] = (char*)test_name; + args[2] = NULL; + } + return args; +} + + +/* + * Example of test_result detector function implementation + */ +void parse_test_state(const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option) +{ + char test_id[MAX_COMMENT]; + + switch(state_change) { + case INIT_TEST: + sm_reset(); + break; + case NEW_STDOUT: + { + int k = 0; + buffer[state_option] = 0; + get_test_id(test_id, b, test_name); + fprintf(stderr, "[stdout][%s]%s\n",test_id, buffer); + while ( (k = sm_update(buffer, k))) { + const char* t_name = sm_get_result(0); + const char* result_code = sm_get_result(1); + bool is_successful = result_code[0] == '1' && result_code[1] == 0; + const char* result_text = is_successful ? "PASS" : "FAIL"; + + get_test_id(test_id, b, t_name); + add_test_result(test_id, result_text, "", is_successful); + sm_reset(); + } + } + break; + case NEW_STDERR: + buffer[state_option] = 0; + get_test_id(test_id, b, test_name); + fprintf(stderr, "[stderr][%s]%s\n",test_id, buffer); + break; + case RESULT_CODE: + if (state_option != 0) + add_test_result(get_test_id(test_id, b, test_name), "FAIL", "Test exited with error code", 0); + break; + case RESULT_SIGNAL: + add_test_result(get_test_id(test_id, b, test_name), "FAIL", "Finished by SIGNAL", 0); + break; + case RESULT_TIMEOUT: + add_test_result(get_test_id(test_id, b, test_name), "FAIL", "Test TIMEOUT", 0); + break; + } +} + +/****************************END of CUSTOM FUNCTIONS************************/ + + +static struct option long_options[] = { + {"list", no_argument, 0, 'l'}, + {"run", required_argument, 0, 'r'}, + {"description", required_argument, 0, 'd'}, + {0, 0, 0, 0 } +}; + +static int stdin_pipe[2]; +static int stdout_pipe[2]; +static int stderr_pipe[2]; +static struct test_result test_results[MAX_TC_NUM]; +static int test_results_i; +static char buffer[MAX_BUFFER]; +static const char* requested_tc[MAX_TC_NUM]; + +char* get_test_id(char* dest, const struct binary* b, const char* test_name) +{ + int len = strlen(b->name); + memcpy(dest, b->name, len); + memcpy(dest + len, test_name, strlen(test_name)+1); + return dest; +} + +static void print_description(const char* name, const char* description) +{ + printf("%s;%s\n",name, description); +} + +static void print_list(const char* test_name) +{ + unsigned int i; + char full_name[MAX_COMMENT]; + for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) { + int j = 0; + int l = strlen(tests[i].name); + memcpy(full_name, tests[i].name, l+1); + if (test_name && strncmp(test_name, full_name, l) != 0) + continue; + + while (tests[i].test_cases[j].name) { + memcpy(full_name + l, tests[i].test_cases[j].name, strlen(tests[i].test_cases[j].name) + 1); + if (!test_name || strcmp(full_name, test_name) == 0) + print_description(full_name,tests[i].test_cases[j].description); + j++; + } + } +} + + +static void stop_binary(const struct binary* b, pid_t pid, const char* test_name) +{ + int status = 0; + int res = 0; + res = waitpid(pid, &status, 0); + if (res == 0) { + //timeouted + kill(pid, SIGKILL); + res = waitpid(pid, &status, WNOHANG); + b->parse(b, test_name, buffer, RESULT_TIMEOUT, res); + } else if (res < 0) { + //errno check + kill(pid, SIGKILL); + res = waitpid(pid, &status, WNOHANG); + b->parse(b, test_name, buffer, RESULT_ERROR, res); + } else if (res > 0) { + if (WIFEXITED(status)) { + b->parse(b, test_name, buffer, RESULT_CODE, WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + b->parse(b, test_name, buffer, RESULT_SIGNAL, WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { + b->parse(b, test_name, buffer, RESULT_SIGNAL, WSTOPSIG(status)); + } else if (WIFCONTINUED(status)) { + kill(pid, SIGKILL); + b->parse(b, test_name, buffer, RESULT_SIGNAL, -1); + } + } +} + +static void parse_output_with_timeout(const struct binary* b, pid_t pid, const char* test_name) +{ + struct timeval tv; + fd_set rfds; + int nfds; + int res; + tv.tv_sec = b->timeout/(1000*1000); + tv.tv_usec = (b->timeout-tv.tv_sec*1000*1000); + while (1) { + FD_ZERO(&rfds); + FD_SET(stdout_pipe[PIPE_READ], &rfds); + FD_SET(stderr_pipe[PIPE_READ], &rfds); + nfds = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); + if (nfds == -1) { + if (errno != EINTR) + break; + } else if (nfds > 0) { + if (FD_ISSET(stdout_pipe[PIPE_READ], &rfds)) { + res = read(stdout_pipe[PIPE_READ], buffer, MAX_BUFFER-1); + if (res == 0 || (res < 0 && errno != EINTR)) + break; + else if (res >=0) + b->parse(b, test_name, buffer, NEW_STDOUT, res); + } + + if (FD_ISSET(stderr_pipe[PIPE_READ], &rfds)) { + res = read(stderr_pipe[PIPE_READ], buffer, MAX_BUFFER-1); + if (res == 0 || (res < 0 && errno != EINTR)) + break; + b->parse(b, test_name, buffer, NEW_STDERR, res); + } + } else { + //timeout + break; + } + } + stop_binary(b, pid, test_name); +} + +static int create_child(const char* path, char* const arguments[]) +{ + int child; + int nResult; + if (pipe(stdin_pipe) < 0) { + perror("allocating pipe for child input redirect failed"); + goto error1; + } + + if (pipe(stdout_pipe) < 0) { + perror("allocating pipe for child output redirect failed"); + goto error2; + } + + if (pipe(stderr_pipe) < 0) { + perror("allocating pipe for child output redirect failed"); + goto error3; + } + + child = fork(); + if (!child) { + char ld_path[512]; + sprintf(ld_path, "/usr/lib/dbus-tests/lib/libdbuspolicy-tests/:"); + // redirect stdin + if (dup2(stdin_pipe[PIPE_READ], STDIN_FILENO) == -1) { + perror("redirecting stdin failed"); + return -1; + } + + // redirect stdout + if (dup2(stdout_pipe[PIPE_WRITE], STDOUT_FILENO) == -1) { + perror("redirecting stdout failed"); + return -1; + } + + // redirect stderr + if (dup2(stderr_pipe[PIPE_WRITE], STDERR_FILENO) == -1) { + perror("redirecting stderr failed"); + return -1; + } + + // all these are for use by parent only + close(stdin_pipe[PIPE_READ]); + close(stdin_pipe[PIPE_WRITE]); + close(stdout_pipe[PIPE_READ]); + close(stdout_pipe[PIPE_WRITE]); + close(stderr_pipe[PIPE_READ]); + close(stderr_pipe[PIPE_WRITE]); + + char* ld_path_b = getenv("LD_LIBRARY_PATH"); + if (ld_path_b != NULL) + memcpy(ld_path + strlen(ld_path), ld_path_b, strlen(ld_path_b)+1); + setenv("LD_LIBRARY_PATH", ld_path, 1); + // run child process image + nResult = execv(path, arguments); + + // if we get here at all, an error occurred, but we are in the child + // process, so just exit + perror("exec of the child process failed"); + exit(nResult); + } else if (child > 0) { + // parent continues here + + // close unused file descriptors, these are for child only + close(stdin_pipe[PIPE_READ]); + close(stdout_pipe[PIPE_WRITE]); + close(stderr_pipe[PIPE_WRITE]); + } else { + // failed to create child + goto error4; + } + + return child; + +error4: + close(stderr_pipe[PIPE_READ]); + close(stderr_pipe[PIPE_WRITE]); +error3: + close(stdout_pipe[PIPE_READ]); + close(stdout_pipe[PIPE_WRITE]); +error2: + close(stdin_pipe[PIPE_READ]); + close(stdin_pipe[PIPE_WRITE]); +error1: + return -1; +} + +static void run_test(const struct binary* b, const char* test_name) +{ + int res = -1; + char** arg; + char test_id[MAX_COMMENT]; + + assert(b); + assert(b->name); + assert(b->path); + assert(test_name); + + arg = b->prepare_args(b, test_name); + + if (b->init) + if (!b->init()) { + add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Internal error: Cannot init test", 0); + return; + } + + res = create_child(b->path, arg); + if (res > 0) + parse_output_with_timeout(b, res, test_name); + else + add_test_result(get_test_id(test_id, b, test_name), "ERROR", "Internal error: Cannot start test", 0); + + if (b->clean) + b->clean(); +} + +static void parse_run_test(const char* tc) { + unsigned int i = 0; + for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) { + int len = strlen(tests[i].name); + if (strncmp(tc, tests[i].name, len) == 0) { + if (tc[len] == '*' || tc[len] == '\0') + run_test(&tests[i], ""); + else + run_test(&tests[i], tc + len); + } + } +} + +static int parse_option(int argc, char* argv[]) +{ + int ch = 0; + int c = 0; + while ((ch = getopt_long(argc, argv, "lr:d:", long_options, NULL)) != -1) { + switch (ch) { + case 'l': + print_list(NULL); + return 1; + case 'r': + if (c >= MAX_TC_NUM - 1) //NULL at the end + return 0; + + if (optarg) + requested_tc[c++] = optarg; + + break; + case 'd': + print_list(optarg); + return 1; + } + } + return 0; +} + +//output_new/fail/success +void add_test_result(const char* test_id, const char* result, const char* comment, int res) +{ + test_results[test_results_i].is_positive = res; + strcpy(test_results[test_results_i].result, result); + strcpy(test_results[test_results_i].comment, comment); + strcpy(test_results[test_results_i++].name, test_id); +} + +static void prepare_results(void) +{ + //todo +} + +static void print_results() +{ + int i = 0; + for (i = 0; i < test_results_i; i++) + { + printf("%s;%s;%s\n", test_results[i].name, test_results[i].result, test_results[i].comment); + } +} + +int main(int argc, char* argv[]) +{ + unsigned int i; + signal(SIGPIPE, SIG_IGN); + if (parse_option(argc, argv)) + return 0; + + prepare_results(); + + if (!requested_tc[0]) { + for (i = 0;i < sizeof(tests)/sizeof(struct binary); i++) + run_test(&tests[i], ""); + } else { + i = 0; + while(requested_tc[i]) { + parse_run_test(requested_tc[i]); + i++; + } + } + + print_results(); + return 0; +} diff --git a/src/test_runner.h b/src/test_runner.h new file mode 100644 index 0000000..3c79a99 --- /dev/null +++ b/src/test_runner.h @@ -0,0 +1,69 @@ +/* This file is part of test-runner (see template.c) + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * Author: Kazimierz Krosman + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +#ifndef TEST_RUNNER_H +#define TEST_RUNNER_H +#include + +#define TC_NAME "libdbuspolicy-tests" +#define TEST_PATH "/usr/lib/dbus-tests/test-suites/libdbuspolicy-tests/" +#define CYNARA_PATH TEST_PATH "cynara_prepare.sh" +#define MAX_TC_NUM 1024 +#define MAX_BUFFER (64*1024) +#define MAX_COMMENT 1024 + +enum { + INIT_TEST, + NEW_STDOUT, + NEW_STDERR, + RESULT_CODE, + RESULT_SIGNAL, + RESULT_ERROR, + RESULT_TIMEOUT +}; + +struct test_result { + bool is_positive; + char comment[MAX_COMMENT]; + char result[MAX_COMMENT]; + char name[MAX_COMMENT]; +}; + +struct test_case { + const char* name; + const char* description; +}; + +struct binary { + const char* path; + const char* name; + /* can be filled by asking binary */ + struct test_case* test_cases; + int timeout; + + char** (*prepare_args) (const struct binary* b, const char* test_name); + void (*parse) (const struct binary* b, const char* test_name, char* buffer, int state_change, int state_option); + int (*init)(void); + int (*clean)(void); +}; + +char* get_test_id(char* dest, const struct binary* b, const char* test_name); +void add_test_result(const char* test_id, const char* result, const char* comment, int res); + + +#endif /* TEST_RUNNER_H */ -- 2.7.4 From 9fd3add7b2a931bfd74db0e995adbbf21633df8c Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Thu, 5 Jan 2017 12:22:57 +0900 Subject: [PATCH 06/16] svace:handling wrong policy syntax Change-Id: I8871c77bf5f58ad89885c128f96442ce009197a8 Signed-off-by: sanghyeok.oh --- src/internal/policy.cpp | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index d4ab166..3bc5fce 100644 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -19,6 +19,9 @@ static const char* message_dir[] = { "ANY", "SEND", "RECEIVE"}; static const char* message_decision[] = {"NO_DECISION", "ALLOW", "DENY", "CHECK"}; static MessageType __str_to_message_type(const char* str) { + if (!str) + return MessageType::ANY; + if (!std::strcmp(str, "method_call")) return MessageType::METHOD_CALL; else if (!std::strcmp(str, "method_return")) @@ -113,23 +116,22 @@ void DbAdapter::updateDecision(const boost::property_tree::ptree::value_type& v, if (v.second.data() != "*") value = v.second.data().c_str(); - if (v.first == "context") { - if (std::strcmp(value, "mandatory") == 0 ) { - policy_type = PolicyType::CONTEXT; - policy_type_value.context = ContextType::MANDATORY; - } else if (std::strcmp(value, "default") == 0) { - policy_type = PolicyType::CONTEXT; - policy_type_value.context = ContextType::DEFAULT; + if (value) { + if (v.first == "context") { + if (std::strcmp(value, "mandatory") == 0 ) { + policy_type = PolicyType::CONTEXT; + policy_type_value.context = ContextType::MANDATORY; + } else if (std::strcmp(value, "default") == 0) { + policy_type = PolicyType::CONTEXT; + policy_type_value.context = ContextType::DEFAULT; + } + } else if (v.first == "user") { + policy_type = PolicyType::USER; + policy_type_value.user = convertToUid(value); + } else if (v.first == "group") { + policy_type = PolicyType::GROUP; + policy_type_value.group = convertToGid(value); } - } else if (v.first == "user") { - policy_type = PolicyType::USER; - policy_type_value.user = convertToUid(value); - } else if (v.first == "group") { - policy_type = PolicyType::GROUP; - policy_type_value.group = convertToGid(value); - } else { - attr = false; - t = NONE; } } else if (attr && t == ALLOW_DENY_CHECK) { if (v.second.data() != "*") -- 2.7.4 From 74494cf8da978299c73034518e0900ac0488bd23 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Fri, 6 Jan 2017 16:49:59 +0900 Subject: [PATCH 07/16] fix build error for gcc 6.2 Change-Id: Idec2ea8f8d55140eb1864d0f981f0071b5898bba Signed-off-by: sanghyeok.oh --- src/test-libdbuspolicy1-method.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test-libdbuspolicy1-method.cpp b/src/test-libdbuspolicy1-method.cpp index 7ed039b..9240590 100644 --- a/src/test-libdbuspolicy1-method.cpp +++ b/src/test-libdbuspolicy1-method.cpp @@ -54,7 +54,7 @@ struct MethodTest method_tests[]={ void methodTest_print(struct MethodTest* t, bool result) { printf("uid = %lu, gid = %lu, label = %s, name = %s, path = %s, interface = %s, member = %s, expected = %d, result = %d (type=%d)", - (unsigned long)t->user, (unsigned long)t->group, t->label, t->name, t->path, t->interface, t->member, ((int)t->expected_result), (int)result, t->recv_send); + (unsigned long)t->user, (unsigned long)t->group, t->label, t->name, t->path, t->interface, t->member, ((int)t->expected_result), (int)result, (int)t->recv_send); } bool method_test() { -- 2.7.4 From 27d2b1c86480d99b9eca2eb66e514e2974e5aa26 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Fri, 6 Jan 2017 16:49:59 +0900 Subject: [PATCH 08/16] fix build error for gcc 6.2 Change-Id: Idec2ea8f8d55140eb1864d0f981f0071b5898bba Signed-off-by: sanghyeok.oh (cherry picked from commit 74494cf8da978299c73034518e0900ac0488bd23) --- src/test-libdbuspolicy1-method.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test-libdbuspolicy1-method.cpp b/src/test-libdbuspolicy1-method.cpp index 7ed039b..9240590 100644 --- a/src/test-libdbuspolicy1-method.cpp +++ b/src/test-libdbuspolicy1-method.cpp @@ -54,7 +54,7 @@ struct MethodTest method_tests[]={ void methodTest_print(struct MethodTest* t, bool result) { printf("uid = %lu, gid = %lu, label = %s, name = %s, path = %s, interface = %s, member = %s, expected = %d, result = %d (type=%d)", - (unsigned long)t->user, (unsigned long)t->group, t->label, t->name, t->path, t->interface, t->member, ((int)t->expected_result), (int)result, t->recv_send); + (unsigned long)t->user, (unsigned long)t->group, t->label, t->name, t->path, t->interface, t->member, ((int)t->expected_result), (int)result, (int)t->recv_send); } bool method_test() { -- 2.7.4 From 9b5824e9cda569d92803fc23322828ddd9dab61a Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Wed, 18 Jan 2017 15:03:44 +0900 Subject: [PATCH 09/16] modified to init global instance once Change-Id: Ib5092c6bee952b7a51f7da90d9d65414a0f10697 Signed-off-by: sanghyeok.oh --- src/libdbuspolicy1.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) mode change 100644 => 100755 src/libdbuspolicy1.c diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c old mode 100644 new mode 100755 index b37b1ac..b2a3248 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -69,8 +69,10 @@ struct kconn { int fd; uint64_t id; char *pool; - int counter; -} g_conn[2]; +} g_conn[2] = { + {.pool = MAP_FAILED}, + {.pool = MAP_FAILED} +}; struct udesc { dbus_uid_t uid; @@ -180,13 +182,13 @@ static int bus_path_resolve(const char *bus_path, char *resolved_path, unsigned } static bool init_once_done = false; +static bool init_once[2] = {false, false}; DBUSPOLICY1_EXPORT void* dbuspolicy1_init(const char *bus_path) { unsigned int bus_type = -1; char resolved_path[PATH_MAX] = { 0 }; int rp, rs; - bool rb; _Static_assert(SYSTEM_BUS == 0, "SYSTEM_BUS not 0"); _Static_assert(SESSION_BUS == 1, "SESSION_BUS not 0"); @@ -197,15 +199,12 @@ DBUSPOLICY1_EXPORT void* dbuspolicy1_init(const char *bus_path) if (bus_type) bus_type = SESSION_BUS; - rb = false; pthread_mutex_lock(&g_mutex); if (!init_once_done) { init_once_done = true; - rb = dbuspolicy_init_once(); + dbuspolicy_init_once(); } - if (rb) - goto err_close; - if (g_conn[bus_type].counter == 0) { + if (!init_once[bus_type]) { if ((g_conn[bus_type].fd = kdbus_open_bus(resolved_path)) < 0) goto err; @@ -220,15 +219,18 @@ DBUSPOLICY1_EXPORT void* dbuspolicy1_init(const char *bus_path) if (rp < 0 && rs < 0) /* when both negative */ goto err_close; + + init_once[bus_type] = true; } - g_conn[bus_type].counter++; pthread_mutex_unlock(&g_mutex); __internal_init_flush_logs(); return &g_conn[bus_type]; err_close: + if (g_conn[bus_type].pool != MAP_FAILED) + munmap(g_conn[bus_type].pool, KDBUS_POOL_SIZE); close(g_conn[bus_type].fd); err: pthread_mutex_unlock(&g_mutex); @@ -237,18 +239,7 @@ err: DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) { - if (configuration) { - struct kconn* k = (struct kconn*)configuration; - pthread_mutex_lock(&g_mutex); - - --k->counter; - if (k->counter <= 0) { - munmap(k->pool, KDBUS_POOL_SIZE); - close(k->fd); - } - - pthread_mutex_unlock(&g_mutex); - } + configuration = configuration; } #ifdef LIBDBUSPOLICY_TESTS_API -- 2.7.4 From 2cbb173538da9ba7d4c753ec5aaca80bec5b2525 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Sat, 11 Feb 2017 12:04:08 +0900 Subject: [PATCH 10/16] svace fix Change-Id: I72700b1e9a1929388c181eb536214eaa98a696f2 Signed-off-by: sanghyeok.oh --- src/internal/policy.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index 3bc5fce..4a994b3 100755 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -235,7 +235,7 @@ const char* DecisionItem::toString(char* str) const { ItemOwn::ItemOwn(const char* name, Decision decision, const char* privilege) - : __decision(DecisionItem(decision, privilege)), __name(name) { + : __decision(DecisionItem(decision, privilege)), __name(name), __is_prefix(false) { } ItemType ItemOwn::getType() const { @@ -392,7 +392,7 @@ ItemSendReceive* ItemBuilder::getSendReceiveItem() { return __current_sr; } -ItemBuilder::ItemBuilder() : __current_own(NULL), __current_sr(NULL) { +ItemBuilder::ItemBuilder() : __current_own(NULL), __current_item_type(ItemType::GENERIC), __current_sr(NULL) { } ItemBuilder::~ItemBuilder(){ -- 2.7.4 From 71a65f3f2c167a9fbaf4efb86c377c0035cb9d2f Mon Sep 17 00:00:00 2001 From: Hyotaek Shim Date: Mon, 20 Mar 2017 01:00:52 -0700 Subject: [PATCH 11/16] Revert "retrieve label on every cynara check" This reverts commit fe403b9aa7ad1ff7e56327af2d88477b26094746. Change-Id: I8dc57d2e6d821650e5d0d5198c6e1a0cd79fed84 --- src/internal/cynara.cpp | 29 +++-------------------------- src/internal/internal.h | 1 - src/libdbuspolicy1.c | 32 +++++++++++++++++++++----------- 3 files changed, 24 insertions(+), 38 deletions(-) diff --git a/src/internal/cynara.cpp b/src/internal/cynara.cpp index 02cb574..8be1c11 100644 --- a/src/internal/cynara.cpp +++ b/src/internal/cynara.cpp @@ -1,11 +1,9 @@ -#include +#include "cynara.hpp" +#include "libdbuspolicy1-private.hpp" #include #include #include #include -#include "cynara.hpp" -#include "internal.h" -#include "libdbuspolicy1-private.hpp" using namespace ldp_cynara; @@ -24,33 +22,12 @@ bool Cynara::init() { static pthread_mutex_t __mutex = PTHREAD_MUTEX_INITIALIZER; static Cynara c; -#ifdef LIBDBUSPOLICY_TESTS_API -extern char label_override[4096]; -extern bool have_label_override; -#endif - CynaraResult Cynara::check(const char* label, const char* privilege, const char* uid) { const char* _label = ""; const char* _uid = ""; const char* _privilege = ""; CynaraResult ret; - char buf[4096]; -#ifdef LIBDBUSPOLICY_TESTS_API - if (have_label_override) _label = label_override; else -#endif - if (SELF_LABEL == label) { - int attr_fd = open("/proc/self/attr/current", O_RDONLY); - if (attr_fd < 0) - return CynaraResult::ERROR_CHECK; - int r = read(attr_fd, buf, sizeof(buf)-1); - close(attr_fd); - if (r < 0) - return CynaraResult::ERROR_CHECK; - if (r) { - buf[r] = 0; - _label = buf; - } - } else if (label) + if (label) _label = label; if (privilege) _privilege = privilege; diff --git a/src/internal/internal.h b/src/internal/internal.h index be72bfa..787b380 100644 --- a/src/internal/internal.h +++ b/src/internal/internal.h @@ -31,7 +31,6 @@ extern "C" { #endif #define KDBUS_CONN_MAX_NAMES 256 -#define SELF_LABEL ((void*)-1) /** Initializes policies from given policy configuration file name * \param[in] bus_type Bus type (system/session) diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index b37b1ac..d1de0ca 100644 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -75,6 +75,7 @@ struct kconn { struct udesc { dbus_uid_t uid; dbus_gid_t gid; + char label[256]; } g_udesc; static int kdbus_open_bus(const char *path) @@ -140,8 +141,22 @@ static uint64_t kdbus_unique_id(char const *name) static bool dbuspolicy_init_once(void) { + char buf[1024]; + int attr_fd; + int r; + + attr_fd = open("/proc/self/attr/current", O_RDONLY); + if (attr_fd < 0) + return -1; + r = read(attr_fd, buf, sizeof(buf)); + close(attr_fd); + + if (r < 0 || r >= (long int)sizeof(g_udesc.label)) /* read */ + return true; + g_udesc.uid = getuid(); g_udesc.gid = getgid(); + snprintf(g_udesc.label, r + 1 /* additional byte for \0 */, "%s", buf); __internal_init_once(); @@ -252,17 +267,12 @@ DBUSPOLICY1_EXPORT void dbuspolicy1_free(void* configuration) } #ifdef LIBDBUSPOLICY_TESTS_API -char label_override[4096]; -bool have_label_override; DBUSPOLICY1_EXPORT void __dbuspolicy1_change_creds(void* configuration, uid_t uid, gid_t gid,const char* label) { (void)configuration; g_udesc.uid = uid; g_udesc.gid = gid; - if (label) { - strncpy(label_override, label, sizeof(label_override)); - label_override[sizeof(label_override)-1] = 0; - have_label_override = 1; - } + if (label) + strcpy (g_udesc.label, label); } #endif @@ -362,10 +372,10 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, } if (empty_names) - r = __internal_can_send(bus_type, g_udesc.uid, g_udesc.gid, SELF_LABEL, destination, path, interface, member, message_type); + r = __internal_can_send(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, destination, path, interface, member, message_type); else { k_names[k_i++] = NULL; - r = __internal_can_send_multi_dest(bus_type, g_udesc.uid, g_udesc.gid, SELF_LABEL, k_names, path, interface, member, message_type); + r = __internal_can_send_multi_dest(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, k_names, path, interface, member, message_type); } if (r <= 0) goto end; @@ -409,7 +419,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, goto end; if (message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) { - r = __internal_can_recv(bus_type, g_udesc.uid, g_udesc.gid, SELF_LABEL, sender, path, interface, member, message_type); + r = __internal_can_recv(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, sender, path, interface, member, message_type); if (r <= 0) goto end; } @@ -423,7 +433,7 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_can_own(void* configuration, const char* cons int r; bool bus_type = configuration_bus_type(configuration); __internal_enter(); - r = __internal_can_own(bus_type, g_udesc.uid, g_udesc.gid, SELF_LABEL, service); + r = __internal_can_own(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, service); __internal_exit(); return r; } -- 2.7.4 From 65e077b739b38c1d162d3bae7448bfb2d7cff501 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Mon, 12 Jun 2017 14:11:56 +0900 Subject: [PATCH 12/16] dbuspolicy1_check_out: change sender to NULL if sender is unique id, can_recv will return wrong value Change-Id: Idf8b3ce964cc4d5d064d8bf125071772b4987a2b Signed-off-by: sanghyeok.oh --- src/libdbuspolicy1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index d1477a5..61b2a37 100755 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -371,8 +371,10 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, if (r <= 0) goto end; - if (message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) + if (message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) { + sender = NULL; r = __internal_can_recv(bus_type, uid_n, gid_n, label, sender, path, interface, member, message_type); + } end: if (free_offset) -- 2.7.4 From ff862ce88cc1c6589525e6f5a7d4c9b3436cab5e Mon Sep 17 00:00:00 2001 From: INSUN PYO Date: Mon, 12 Jun 2017 17:16:54 +0900 Subject: [PATCH 13/16] cynara : modify cyad option. requested by security team Signed-off-by: INSUN PYO Change-Id: I5d58b692a30c9c3570d93c04effbada32e61dc1e --- src/cynara_prepare.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cynara_prepare.sh b/src/cynara_prepare.sh index acc2401..79c9054 100644 --- a/src/cynara_prepare.sh +++ b/src/cynara_prepare.sh @@ -1,8 +1,8 @@ #!/bin/sh if [ -z "${1}" ]; then - cyad -e "MANIFESTS" -u 200 -c L -p t -r y + cyad -e "MANIFESTS_GLOBAL" -u 200 -c L -p t -r y cyad -e "USER_TYPE_ADMIN" -u 200 -c L -p t -r y else - cyad -s -k "MANIFESTS" -u 200 -c L -p t -t $1 + cyad -s -k "MANIFESTS_GLOBAL" -u 200 -c L -p t -t $1 cyad -s -k "USER_TYPE_ADMIN" -u 200 -c L -p t -t $1 fi -- 2.7.4 From d3eb8361efb5f070505d641eab8572653c34eaa7 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Fri, 14 Jul 2017 00:34:37 +0900 Subject: [PATCH 14/16] policy checking scheme: modified to get connection information from kdbus To check dbus policy it is needed to get every information, especially multiple names and label. For example, if Service A have multiple name such as name_A1, name_A2, and name_A3, and if Service A specify the rule as below, then according to dbus policy, last specified rule '' is applied, *** In dbus policy world dbus treat multiple names of Service A as same name, this also affect every other names of Service A, meaning, or or After all, Service B can send message to name_A1, name_A2, and name_A3. send message to unique name of Service A also allowed by this rule. *** unique name also treat as same as well-known name of Service A. Change-Id: I2253296267d8c844c53813455c829bf625f4360c Signed-off-by: sanghyeok.oh --- src/internal/internal.cpp | 20 ++++ src/internal/internal.h | 22 ++++ src/libdbuspolicy1.c | 268 +++++++++++++++++++++++++++++++--------------- 3 files changed, 223 insertions(+), 87 deletions(-) mode change 100644 => 100755 src/internal/internal.cpp mode change 100644 => 100755 src/internal/internal.h diff --git a/src/internal/internal.cpp b/src/internal/internal.cpp old mode 100644 new mode 100755 index fb2676f..aa0e947 --- a/src/internal/internal.cpp +++ b/src/internal/internal.cpp @@ -123,6 +123,26 @@ int __internal_can_recv(bool bus_type, return static_cast(policy_checker().check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::RECEIVE)); } +int __internal_can_recv_multi(bool bus_type, + const uid_t user, + const gid_t group, + const char* const label, + const char** const sender, + const char* const path, + const char* const interface, + const char* const member, + int type) +{ + int i = 0; + ldp_xml_parser::MatchItemSR matcher(interface, member, path, static_cast(type), ldp_xml_parser::MessageDirection::RECEIVE); + if (sender) + while (sender[i]) { + matcher.addName(sender[i++]); + } + return static_cast(policy_checker().check(bus_type, user, group, label, matcher, ldp_xml_parser::ItemType::RECEIVE)); +} + + int __internal_can_own(bool bus_type, const uid_t user, const gid_t group, diff --git a/src/internal/internal.h b/src/internal/internal.h old mode 100644 new mode 100755 index 787b380..94db50b --- a/src/internal/internal.h +++ b/src/internal/internal.h @@ -118,6 +118,28 @@ int __internal_can_recv(bool bus_type, const char* const member, int type); +/** Check if user can receive messages. + * \param[in] bus_type Bus type (system/session) + * \param[in] user User id + * \param[in] group User group id + * \param[in] label User label + * \param[in] sender Sender of received message + * \param[in] path Path + * \param[in] interface Interface name + * \param[in] member Member name + * \param[in] type Message type + * \return 1 on allow, 0 on deny, negative error code otherwise + */ +int __internal_can_recv_multi(bool bus_type, + uid_t user, + gid_t group, + const char* const label, + const char** const sender, + const char* const path, + const char* const interface, + const char* const member, + int type); + /** Checks if given user can own interface with given label * \param[in] bus_type Bus type (system/session) * \param[in] user User id diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 61b2a37..1c9723b 100755 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -94,6 +94,8 @@ static int kdbus_hello(bool bus_type, uint64_t hello_flags, uint64_t attach_flag int size = ALIGN8(sizeof(struct kdbus_cmd_hello)) + ALIGN8(offsetof(struct kdbus_item, data) + sizeof(CONNECTION_LABEL)); cmd = calloc(1, size); + if (!cmd) + goto err; cmd->size = size; cmd->flags = hello_flags; cmd->attach_flags_send = attach_flags_send; @@ -263,12 +265,111 @@ DBUSPOLICY1_EXPORT void __dbuspolicy1_change_creds(void* configuration, uid_t ui g_udesc.uid = uid; g_udesc.gid = gid; if (label) - strcpy (g_udesc.label, label); + strncpy (g_udesc.label, label, strlen(label) + 1); } #endif static bool configuration_bus_type(struct kconn const *configuration) { return configuration != g_conn; } +union kdbus_cmd_union { + struct kdbus_cmd_info cmd_info; + struct kdbus_cmd_free cmd_free; + uint8_t _buffer_[sizeof(struct kdbus_cmd_info) + offsetof(struct kdbus_item, data) + ALIGN8(MAX_DBUS_NAME_LEN+1)]; +}; + +struct kdbus_cmd_param { + char const *label; + const char* k_names[KDBUS_CONN_MAX_NAMES+1]; + uid_t uid_n; + gid_t gid_n; + bool free_offset; + bool empty_names; + union kdbus_cmd_union cmd; +}; + +int kdbus_get_conn_info(bool bus_type, const char *destination, int message_type, struct kdbus_cmd_param *info) +{ + char const *label = NULL; + const char** k_names = info->k_names; + int k_i = 0; + int r; + uid_t uid_n = UID_INVALID; + gid_t gid_n = GID_INVALID; + bool free_offset = false; + bool empty_names = true; + union kdbus_cmd_union *cmd = &info->cmd; + + struct kdbus_info *conn_info; + struct kdbus_item *item; + uintptr_t items_end; + + cmd->cmd_info.flags = 0; + cmd->cmd_info.attach_flags = (__u64)(KDBUS_ATTACH_CREDS | KDBUS_ATTACH_NAMES | (DBUSPOLICY_MESSAGE_TYPE_SIGNAL != message_type ? KDBUS_ATTACH_SECLABEL : 0)); + + if (kdbus_is_unique_id(destination)) { + cmd->cmd_info.size = sizeof(cmd->cmd_info); + cmd->cmd_info.id = kdbus_unique_id(destination); + } else { + unsigned int l = strlen(destination); + cmd->cmd_info.size = sizeof(struct kdbus_cmd_info) + offsetof(struct kdbus_item, data) + ALIGN8(l+1); + cmd->cmd_info.id = 0; + cmd->cmd_info.items->size = (__u64)offsetof(struct kdbus_item, data) + (__u64)l + (__u64)1; + cmd->cmd_info.items->type = KDBUS_ITEM_NAME; + *(uint64_t*)ALIGNDN8((uintptr_t)cmd->cmd_info.items->str + l) = 0; /* trailing zero + padding */ + memcpy(cmd->cmd_info.items->str, destination, l); + } + r = ioctl(g_conn[bus_type].fd, KDBUS_CMD_CONN_INFO, &cmd->cmd_info); + if (r < 0) { + if (errno == ENXIO || errno == ESRCH) + r = DBUSPOLICY_RESULT_DEST_NOT_AVAILABLE; + else + r = DBUSPOLICY_RESULT_KDBUS_ERROR; + goto end; + } + + cmd->cmd_free.size = sizeof(cmd->cmd_free); + /* flags already 0 */ + _Static_assert(sizeof(cmd->cmd_info.flags) == sizeof(cmd->cmd_free.flags), "cmd_info/cmd_free: flag sizeof differs"); + _Static_assert(offsetof(typeof(cmd->cmd_info), flags) == offsetof(typeof(cmd->cmd_free), flags), "cmd_info/cmd_free: flag offsetof differs"); + cmd->cmd_free.offset = cmd->cmd_info.offset; + + free_offset = true; + + conn_info = (struct kdbus_info *) ((uint8_t *) g_conn[bus_type].pool + cmd->cmd_info.offset); + items_end = (uintptr_t)conn_info + (unsigned)conn_info->size; + + _Static_assert((unsigned)KDBUS_ITEM_CREDS == KDBUS_ITEM_CREDS, "KDBUS_ITEM_CREDS not preserved when cast to unsigned"); + _Static_assert((unsigned)KDBUS_ITEM_SECLABEL == KDBUS_ITEM_SECLABEL, "KDBUS_ITEM_SECLABEL not preserved when cast to unsigned"); + _Static_assert((unsigned)KDBUS_ITEM_OWNED_NAME == KDBUS_ITEM_OWNED_NAME, "KDBUS_ITEM_OWNED_NAME not preserved when cast to unsigned"); + + for (item = conn_info->items; (uintptr_t)item < items_end; item = (typeof(item))ALIGN8((uintptr_t)item + (unsigned)item->size)) + switch ((unsigned)item->type) + { + case KDBUS_ITEM_CREDS: + uid_n = item->creds.euid; + gid_n = item->creds.egid; + break; + case KDBUS_ITEM_SECLABEL: + label = item->str; + break; + case KDBUS_ITEM_OWNED_NAME: + empty_names = false; + k_names[k_i++] = item->name.name; + break; + } + if (!empty_names) + k_names[k_i++] = NULL; + +end: + info->label = label; + info->uid_n = uid_n; + info->gid_n = gid_n; + info->free_offset = free_offset; + info->empty_names = empty_names; + + return r; +} + DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, const char *destination, const char *sender, @@ -284,103 +385,78 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, (void)reply_serial; (void)requested_reply; - char const *label = NULL; - const char* k_names[KDBUS_CONN_MAX_NAMES+1]; - int k_i = 0; int r; - uid_t uid_n = UID_INVALID; - gid_t gid_n = GID_INVALID; - bool free_offset = false; - bool empty_names = true; bool bus_type = configuration_bus_type(configuration); - union { - struct kdbus_cmd_info cmd_info; - struct kdbus_cmd_free cmd_free; - uint8_t _buffer_[sizeof(struct kdbus_cmd_info) + offsetof(struct kdbus_item, data) + ALIGN8(MAX_DBUS_NAME_LEN+1)]; - } cmd; + struct kdbus_cmd_param info = { + .free_offset = false, + .empty_names = true + }; + union kdbus_cmd_union *cmd = &info.cmd; + char *dest_label = NULL; + + /* Broadcast signal has NULL destination */ + /* Due to this sender can not check rule correctly */ + if (message_type == DBUSPOLICY_MESSAGE_TYPE_SIGNAL && !destination) + return 1; __internal_enter(); - if (DBUSPOLICY_MESSAGE_TYPE_SIGNAL != message_type || (destination && *destination)) { - struct kdbus_info *conn_info; - struct kdbus_item *item; - uintptr_t items_end; - - cmd.cmd_info.flags = 0; - cmd.cmd_info.attach_flags = KDBUS_ATTACH_CREDS | KDBUS_ATTACH_NAMES | (DBUSPOLICY_MESSAGE_TYPE_SIGNAL != message_type ? KDBUS_ATTACH_SECLABEL : 0); - - if (kdbus_is_unique_id(destination)) { - cmd.cmd_info.size = sizeof(cmd.cmd_info); - cmd.cmd_info.id = kdbus_unique_id(destination); - } else { - int l = strlen(destination); - cmd.cmd_info.size = sizeof(struct kdbus_cmd_info) + offsetof(struct kdbus_item, data) + ALIGN8(l+1); - cmd.cmd_info.id = 0; - cmd.cmd_info.items->size = offsetof(struct kdbus_item, data) + l+1; - cmd.cmd_info.items->type = KDBUS_ITEM_NAME; - *(uint64_t*)ALIGNDN8((uintptr_t)cmd.cmd_info.items->str + l) = 0; /* trailing zero + padding */ - memcpy(cmd.cmd_info.items->str, destination, l); - } - r = ioctl(g_conn[bus_type].fd, KDBUS_CMD_CONN_INFO, &cmd.cmd_info); - if (r < 0) { - if (errno == ENXIO || errno == ESRCH) - r = DBUSPOLICY_RESULT_DEST_NOT_AVAILABLE; - else - r = DBUSPOLICY_RESULT_KDBUS_ERROR; + /* check can send */ + /* if broadcasting, then pass - null destination */ + if (destination && *destination) { + r = kdbus_get_conn_info(bus_type, destination, message_type, &info); + if (r < 0) goto end; - } - - cmd.cmd_free.size = sizeof(cmd.cmd_free); - /* flags already 0 */ - _Static_assert(sizeof(cmd.cmd_info.flags) == sizeof(cmd.cmd_free.flags), "cmd_info/cmd_free: flag sizeof differs"); - _Static_assert(offsetof(typeof(cmd.cmd_info), flags) == offsetof(typeof(cmd.cmd_free), flags), "cmd_info/cmd_free: flag offsetof differs"); - cmd.cmd_free.offset = cmd.cmd_info.offset; - - free_offset = true; - - conn_info = (struct kdbus_info *) ((uint8_t *) g_conn[bus_type].pool + cmd.cmd_info.offset); - items_end = (uintptr_t)conn_info + (unsigned)conn_info->size; - - _Static_assert((unsigned)KDBUS_ITEM_CREDS == KDBUS_ITEM_CREDS, "KDBUS_ITEM_CREDS not preserved when cast to unsigned"); - _Static_assert((unsigned)KDBUS_ITEM_SECLABEL == KDBUS_ITEM_SECLABEL, "KDBUS_ITEM_SECLABEL not preserved when cast to unsigned"); - _Static_assert((unsigned)KDBUS_ITEM_OWNED_NAME == KDBUS_ITEM_OWNED_NAME, "KDBUS_ITEM_OWNED_NAME not preserved when cast to unsigned"); - - for (item = conn_info->items; (uintptr_t)item < items_end; item = (typeof(item))ALIGN8((uintptr_t)item + (unsigned)item->size)) - switch ((unsigned)item->type) - { - case KDBUS_ITEM_CREDS: - uid_n = item->creds.euid; - gid_n = item->creds.egid; - break; - case KDBUS_ITEM_SECLABEL: - label = item->str; - break; - case KDBUS_ITEM_OWNED_NAME: - empty_names = false; - k_names[k_i++] = item->name.name; - break; - } } - if (empty_names) + if (info.empty_names) r = __internal_can_send(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, destination, path, interface, member, message_type); - else { - k_names[k_i++] = NULL; - r = __internal_can_send_multi_dest(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, k_names, path, interface, member, message_type); - } + else + r = __internal_can_send_multi_dest(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, info.k_names, path, interface, member, message_type); + if (r <= 0) goto end; - if (message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) { - sender = NULL; - r = __internal_can_recv(bus_type, uid_n, gid_n, label, sender, path, interface, member, message_type); + uid_t dest_uid_n = 0; + gid_t dest_gid_n = 0; + + /* copy & free */ + if (destination && *destination) { + dest_uid_n = info.uid_n; + dest_gid_n = info.gid_n; + + if (info.label) { + dest_label = (char*)malloc(sizeof(char) * strlen(info.label) + 1); + strncpy(dest_label, info.label, strlen(info.label) + 1); + } + if (info.free_offset) + ioctl(g_conn[bus_type].fd, KDBUS_CMD_FREE, &cmd->cmd_free); + + info.free_offset = false; + info.empty_names = true; + } + + /* check can recv */ + /* get sender information from kdbus */ + r = kdbus_get_conn_info(bus_type, sender, message_type, &info); + if (r < 0) { + fprintf(stderr, "failed to kdbus conn info:%d\n", r); + goto end; } + if (info.empty_names) + r = __internal_can_recv(bus_type, dest_uid_n, dest_gid_n, dest_label, sender, path, interface, member, message_type); + else + r = __internal_can_recv_multi(bus_type, dest_uid_n, dest_gid_n, dest_label, info.k_names, path, interface, member, message_type); + end: - if (free_offset) - ioctl(g_conn[bus_type].fd, KDBUS_CMD_FREE, &cmd.cmd_free); + if (info.free_offset) + ioctl(g_conn[bus_type].fd, KDBUS_CMD_FREE, &cmd->cmd_free); + if (dest_label) + free(dest_label); __internal_exit(); + return r; } @@ -404,19 +480,37 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, int r; bool bus_type = configuration_bus_type(configuration); + struct kdbus_cmd_param info = { + .free_offset = false, + .empty_names = true + }; __internal_enter(); - r = __internal_can_send(bus_type, sender_uid, sender_gid, sender_label, destination, path, interface, member, message_type); + if (destination && *destination) { + r = kdbus_get_conn_info(bus_type, destination, message_type, &info); + if (r < 0) + goto end; + } + + if (info.empty_names) + r = __internal_can_send(bus_type, sender_uid, sender_gid, sender_label, destination, path, interface, member, message_type); + else + r = __internal_can_send_multi_dest(bus_type, sender_uid, sender_gid, sender_label, info.k_names, path, interface, member, message_type); + if (r <= 0) goto end; - if (message_type != DBUSPOLICY_MESSAGE_TYPE_SIGNAL) { - r = __internal_can_recv(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, sender, path, interface, member, message_type); - if (r <= 0) - goto end; - } + /* libdbus, gdbus pass multiple sender as parameter : eg. "name_A name_B name_C". */ + /* Because of '__internal_can_recv' can check rule against multiple names, */ + /* it is not needed to use __internal_can_recv_multi here. */ + r = __internal_can_recv(bus_type, g_udesc.uid, g_udesc.gid, g_udesc.label, sender, path, interface, member, message_type); + if (r <= 0) + goto end; end: + if (info.free_offset) + ioctl(g_conn[bus_type].fd, KDBUS_CMD_FREE, &info.cmd.cmd_free); + __internal_exit(); return r; } -- 2.7.4 From 1eba92cf058358c5967e54f8ebfb153685188d82 Mon Sep 17 00:00:00 2001 From: "sanghyeok.oh" Date: Thu, 10 Aug 2017 21:29:40 +0900 Subject: [PATCH 15/16] dbuspolicy1_check_out/in: ignore signal Change-Id: Ifb95079fe93a04ab1f871c49e13fa0cec54c6935 Signed-off-by: sanghyeok.oh --- src/dbus_daemon.c | 2 +- src/internal/naive_policy_db.cpp | 2 ++ src/libdbuspolicy1.c | 8 +++++++- src/test_runner.c | 11 ++++++----- 4 files changed, 16 insertions(+), 7 deletions(-) mode change 100644 => 100755 src/dbus_daemon.c mode change 100644 => 100755 src/internal/naive_policy_db.cpp mode change 100644 => 100755 src/test_runner.c diff --git a/src/dbus_daemon.c b/src/dbus_daemon.c old mode 100644 new mode 100755 index 058106e..79e749e --- a/src/dbus_daemon.c +++ b/src/dbus_daemon.c @@ -134,7 +134,7 @@ static int bus_acquire_name(int fd, const char *name) item = cmd->items; item->type = KDBUS_ITEM_NAME; item->size = KDBUS_ITEM_HEADER_SIZE + strlen(name) + 1; - strcpy(item->str, name); + strncpy(item->str, name, strlen(name)); /* * Employ the command on the connection owner file descriptor. diff --git a/src/internal/naive_policy_db.cpp b/src/internal/naive_policy_db.cpp old mode 100644 new mode 100755 index e213c70..809d62e --- a/src/internal/naive_policy_db.cpp +++ b/src/internal/naive_policy_db.cpp @@ -13,6 +13,7 @@ using namespace ldp_xml_parser; NaivePolicyDb::PolicyOwn::PolicyOwn(){ treeRootPtr = new struct TreeNode; + assert(treeRootPtr); treeRootPtr->__decisionItem = {Decision::ANY, NULL}; treeRootPtr->__nameChar = '\0'; treeRootPtr->__is_prefix = false; @@ -164,6 +165,7 @@ void NaivePolicyDb::PolicyOwn::addItem(ItemOwn* item) { childIndex = char_map[static_cast(*name)]; if (node->children[childIndex] == NULL) { node->children[childIndex] = new struct TreeNode; + assert(node->children[childIndex]); node->children[childIndex]->__decisionItem = {Decision::ANY, NULL}; node->children[childIndex]->__nameChar = *name; node->children[childIndex]->__is_prefix = false; diff --git a/src/libdbuspolicy1.c b/src/libdbuspolicy1.c index 1c9723b..9c8c840 100755 --- a/src/libdbuspolicy1.c +++ b/src/libdbuspolicy1.c @@ -396,8 +396,9 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, /* Broadcast signal has NULL destination */ /* Due to this sender can not check rule correctly */ - if (message_type == DBUSPOLICY_MESSAGE_TYPE_SIGNAL && !destination) + if (message_type == DBUSPOLICY_MESSAGE_TYPE_SIGNAL) return 1; + sender = NULL; __internal_enter(); @@ -438,11 +439,13 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_out(void* configuration, /* check can recv */ /* get sender information from kdbus */ + if (sender) { r = kdbus_get_conn_info(bus_type, sender, message_type, &info); if (r < 0) { fprintf(stderr, "failed to kdbus conn info:%d\n", r); goto end; } + } if (info.empty_names) r = __internal_can_recv(bus_type, dest_uid_n, dest_gid_n, dest_label, sender, path, interface, member, message_type); @@ -485,6 +488,9 @@ DBUSPOLICY1_EXPORT int dbuspolicy1_check_in(void* configuration, .empty_names = true }; + if (message_type == DBUSPOLICY_MESSAGE_TYPE_SIGNAL) + return 1; + __internal_enter(); if (destination && *destination) { diff --git a/src/test_runner.c b/src/test_runner.c old mode 100644 new mode 100755 index 33517a0..cfcfac7 --- a/src/test_runner.c +++ b/src/test_runner.c @@ -209,7 +209,7 @@ int daemon_init(void) daemon_pids[i] = fork(); if (!daemon_pids[i]) { char fdd[15]; - sprintf(fdd,"%d",daemons_pipe[i][PIPE_WRITE]); + snprintf(fdd,sizeof(fdd)-1, "%d",daemons_pipe[i][PIPE_WRITE]); daemons[i][2] = fdd; close (daemons_pipe[i][PIPE_READ]); (void)execv(daemons[i][0],daemons[i]); @@ -512,7 +512,7 @@ static int create_child(const char* path, char* const arguments[]) child = fork(); if (!child) { char ld_path[512]; - sprintf(ld_path, "/usr/lib/dbus-tests/lib/libdbuspolicy-tests/:"); + snprintf(ld_path, sizeof(ld_path)-1, "/usr/lib/dbus-tests/lib/libdbuspolicy-tests/:"); // redirect stdin if (dup2(stdin_pipe[PIPE_READ], STDIN_FILENO) == -1) { perror("redirecting stdin failed"); @@ -648,9 +648,10 @@ static int parse_option(int argc, char* argv[]) void add_test_result(const char* test_id, const char* result, const char* comment, int res) { test_results[test_results_i].is_positive = res; - strcpy(test_results[test_results_i].result, result); - strcpy(test_results[test_results_i].comment, comment); - strcpy(test_results[test_results_i++].name, test_id); + strncpy(test_results[test_results_i].result, result, sizeof(test_results[test_results_i].result) - 1); + strncpy(test_results[test_results_i].comment, comment, sizeof(test_results[test_results_i].comment) - 1); + strncpy(test_results[test_results_i].name, test_id, sizeof(test_results[test_results_i].name) - 1); + test_results_i++; } static void prepare_results(void) -- 2.7.4 From 23f6efe62348daecade9ec321039a2fa344254dc Mon Sep 17 00:00:00 2001 From: INSUN PYO Date: Tue, 12 Sep 2017 10:08:34 +0900 Subject: [PATCH 16/16] Modification of coding rule violation Signed-off-by: INSUN PYO Change-Id: Id6cafd73c09a8d4c444a04d145da6686ef3ec8ac (cherry picked from commit b7b3a3a5986174a460adc96d6d5f4208c3bde4e2) --- src/internal/naive_policy_checker.cpp | 2 +- src/internal/naive_policy_db.cpp | 2 +- src/internal/policy.cpp | 2 +- src/test_runner.h | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/internal/naive_policy_checker.cpp b/src/internal/naive_policy_checker.cpp index 0c7cb71..f684ac6 100644 --- a/src/internal/naive_policy_checker.cpp +++ b/src/internal/naive_policy_checker.cpp @@ -137,7 +137,7 @@ Decision NaivePolicyChecker::checkPolicyOwn(const NaivePolicyDb::PolicyOwn& poli if (node->children[childIndex] == NULL) { if(ret != Decision::ANY) return ret; - else if(policy.getTreeRoot()->__is_prefix) + else if (policy.getTreeRoot()->__is_prefix) return policy.getTreeRoot()->__decisionItem.getDecision(); else return Decision::ANY; diff --git a/src/internal/naive_policy_db.cpp b/src/internal/naive_policy_db.cpp index 809d62e..b01f8da 100755 --- a/src/internal/naive_policy_db.cpp +++ b/src/internal/naive_policy_db.cpp @@ -181,7 +181,7 @@ void NaivePolicyDb::PolicyOwn::addItem(ItemOwn* item) { } /*If item is prefix, delete children*/ if(item->isPrefix()){ - for(int i=0; ichildren[i])); } node->__decisionItem = item->getDecision(); diff --git a/src/internal/policy.cpp b/src/internal/policy.cpp index 4a994b3..07caa3a 100755 --- a/src/internal/policy.cpp +++ b/src/internal/policy.cpp @@ -281,7 +281,7 @@ bool MatchItemSR::addNames(const char* name) { int len; j = i; if (tslog::verbose() && !((name[i] >= 'a'&& name[i] <= 'z') || (name[i] >= 'A'&& name[i] <= 'Z') || (name[i] >= '0'&& name[i] <= '9') || name[i] == ' ')) { - std::cout<<"Wrong name("<