From 90548ee67bf03b82ded394d9fada2a45acfd616d Mon Sep 17 00:00:00 2001 From: Aleksander Zdyb Date: Wed, 11 Mar 2015 12:02:01 +0100 Subject: [PATCH] Add tests for cynara-creds-dbus Change-Id: Iea7f5e9290899302cd4b2c992110895591ae8903 Signed-off-by: Radoslaw Bartosiak Signed-off-by: Lukasz Kostyra --- packaging/security-tests.spec | 4 + src/common/security-tests.conf | 9 +- src/cynara-tests/CMakeLists.txt | 1 + src/cynara-tests/common/cynara_test_helpers.cpp | 31 +++++- src/cynara-tests/common/cynara_test_helpers.h | 18 +++- src/cynara-tests/common/cynara_test_helpers_dbus.h | 32 ++++++ src/cynara-tests/test_cases_helpers.cpp | 117 ++++++++++++++++++++- 7 files changed, 204 insertions(+), 8 deletions(-) create mode 100644 src/cynara-tests/common/cynara_test_helpers_dbus.h diff --git a/packaging/security-tests.spec b/packaging/security-tests.spec index 18011c5..d48021a 100644 --- a/packaging/security-tests.spec +++ b/packaging/security-tests.spec @@ -21,6 +21,7 @@ BuildRequires: pkgconfig(libxml-2.0) BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgconfig(libwebappenc) BuildRequires: cynara-devel +BuildRequires: libcynara-creds-dbus-devel BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: boost-devel BuildRequires: pkgconfig(vconf) @@ -64,6 +65,9 @@ ln -sf /etc/smack/test_smack_rules %{buildroot}/etc/smack/test_smack_rules_lnk id -u security_test_user 1>/dev/null 2>&1 || \ useradd -r -g users -s /sbin/nologin -c "for tests only" security_test_user +# Reload dbus daemon to apply newly installed configuration +systemctl reload dbus + echo "security-tests postinst done ..." %files diff --git a/src/common/security-tests.conf b/src/common/security-tests.conf index 0ae6722..f3cc851 100644 --- a/src/common/security-tests.conf +++ b/src/common/security-tests.conf @@ -3,8 +3,11 @@ - - - + + + + + + diff --git a/src/cynara-tests/CMakeLists.txt b/src/cynara-tests/CMakeLists.txt index 98dcde1..83f4d40 100644 --- a/src/cynara-tests/CMakeLists.txt +++ b/src/cynara-tests/CMakeLists.txt @@ -24,6 +24,7 @@ PKG_CHECK_MODULES(CYNARA_TARGET_DEP cynara-agent cynara-client cynara-client-async + cynara-creds-dbus cynara-creds-socket cynara-plugin dbus-1 diff --git a/src/cynara-tests/common/cynara_test_helpers.cpp b/src/cynara-tests/common/cynara_test_helpers.cpp index 033fbec..a86bead 100644 --- a/src/cynara-tests/common/cynara_test_helpers.cpp +++ b/src/cynara-tests/common/cynara_test_helpers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,7 @@ #include +#include #include #include "cynara_test_helpers.h" @@ -55,4 +56,32 @@ pid_t socketGetPid(int sock, int expectedResult) { return pid; } +char *dbusGetClient(DBusConnectionPtr connection, const char *uniqueName, + cynara_client_creds method, int expectedResult) { + char *buff; + auto ret = cynara_creds_dbus_get_client(connection.get(), uniqueName, method, &buff); + RUNNER_ASSERT_MSG(ret == expectedResult, + "cynara_creds_dbus_get_client failed, ret = " << ret + << "; expected = " << expectedResult); + return buff; +} + +char *dbusGetUser(DBusConnectionPtr connection, const char *uniqueName, cynara_user_creds method, + int expectedResult) { + char *buff; + auto ret = cynara_creds_dbus_get_user(connection.get(), uniqueName, method, &buff); + RUNNER_ASSERT_MSG(ret == expectedResult, + "cynara_creds_dbus_get_user failed, ret = " << ret + << "; expected = " << expectedResult); + return buff; +} + +pid_t dbusGetPid(DBusConnectionPtr connection, const char *uniqueName, int expectedResult) { + pid_t pid; + auto ret = cynara_creds_dbus_get_pid(connection.get(), uniqueName, &pid); + RUNNER_ASSERT_MSG(ret == expectedResult, "cynara_creds_dbus_get_pid failed, ret = " << ret + << "; expected = " << expectedResult); + return pid; +} + } //namespace CynaraHelperCredentials diff --git a/src/cynara-tests/common/cynara_test_helpers.h b/src/cynara-tests/common/cynara_test_helpers.h index 1acd6f8..8bfc646 100644 --- a/src/cynara-tests/common/cynara_test_helpers.h +++ b/src/cynara-tests/common/cynara_test_helpers.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,11 +23,14 @@ #ifndef CYNARA_TEST_HELPERS_H_ #define CYNARA_TEST_HELPERS_H_ +#include #include #include #include +#include + namespace CynaraHelperCredentials { char *socketGetClient(int sock, cynara_client_creds method, @@ -38,7 +41,18 @@ char *socketGetUser(int sock, cynara_user_creds method, pid_t socketGetPid(int sock, int expectedResult = CYNARA_API_SUCCESS); -} // namespace CynaraHelperCredentials +DBusConnectionPtr createDBusConnection(const std::string &name); + +char *dbusGetClient(DBusConnectionPtr connection, const char *uniqueName, + cynara_client_creds method, int expectedResult = CYNARA_API_SUCCESS); + +char *dbusGetUser(DBusConnectionPtr connection, const char *uniqueName, cynara_user_creds method, + int expectedResult = CYNARA_API_SUCCESS); + +pid_t dbusGetPid(DBusConnectionPtr connection, const char *uniqueName, + int expectedResult = CYNARA_API_SUCCESS); + +} // namespace CynaraHelperCredentials #endif // CYNARA_TEST_HELPERS_H_ diff --git a/src/cynara-tests/common/cynara_test_helpers_dbus.h b/src/cynara-tests/common/cynara_test_helpers_dbus.h new file mode 100644 index 0000000..c348b08 --- /dev/null +++ b/src/cynara-tests/common/cynara_test_helpers_dbus.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ +/** + * @file cynara_test_helpers_dbus.h + * @author Aleksander Zdyb + * @version 1.0 + */ +#ifndef CYNARA_TEST_HELPERS_DBUS_H_ +#define CYNARA_TEST_HELPERS_DBUS_H_ + +#include +#include +#include + +typedef std::function DBusConnectionCloseAndUnref; +typedef std::unique_ptr DBusConnectionPtr; + + +#endif // CYNARA_TEST_HELPERS_DBUS_H_ diff --git a/src/cynara-tests/test_cases_helpers.cpp b/src/cynara-tests/test_cases_helpers.cpp index 43a73f4..a8ff29f 100644 --- a/src/cynara-tests/test_cases_helpers.cpp +++ b/src/cynara-tests/test_cases_helpers.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2015-2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ * @file test_cases_helpers.cpp * @author Aleksander Zdyb * @version 1.0 - * @brief Tests for cynara-helper-credentials-socket + * @brief Tests for cynara-helper-credentials-socket and cynara-helper-credentials-dbus */ #include @@ -26,7 +26,11 @@ #include #include #include +#include +#include + +#include #include #include #include @@ -36,6 +40,7 @@ #include #include +#include class ProcessCredentials { public: @@ -163,3 +168,111 @@ RUNNER_CHILD_TEST_SMACK(tccs05_cynara_creds_socket_pid) RUNNER_ASSERT_MSG(helperPid == expectedPid, "PIDs don't match ret = " << helperPid << "; expected = " << expectedPid); } + +// TODO: Create utility namespace for DBus, maybe? +DBusConnectionPtr createDBusConnection(const std::string &name) { + DBusError err; + + dbus_error_init(&err); + DBusConnection *conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err); + RUNNER_ASSERT_MSG(dbus_error_is_set(&err) != 1, "Error in dbus_bus_get: " << err.message); + dbus_connection_set_exit_on_disconnect(conn, FALSE); + + DBusConnectionPtr ret(conn, [] (DBusConnection *conn) { + dbus_connection_close(conn); + dbus_connection_unref(conn); + }); + + if (name.empty() == false) { + dbus_bus_request_name(conn, name.c_str(), DBUS_NAME_FLAG_REPLACE_EXISTING , &err); + RUNNER_ASSERT_MSG(dbus_error_is_set(&err) != TRUE, + "Error in dbus_bus_request_name: " << err.message); + } + + return ret; +} + +void dbusServer(SynchronizationPipe &pipe, const std::string &requestedName, + const ProcessCredentials &peerCredentials) { + // for DBus connection, System must have access to our peer creds as well. + SecurityServer::AccessProvider systemAp("System"); + systemAp.addObjectRule(peerCredentials.label(), "rwx"); + systemAp.apply(); + + SecurityServer::AccessProvider ap(peerCredentials.label()); + ap.addObjectRule("System", "w"); + ap.addObjectRule("System::Run", "x"); + ap.addObjectRule("System::Shared", "x"); // for GDB + ap.addObjectRule("User", "r"); // for /usr/lib/debug access + ap.applyAndSwithToUser(peerCredentials.uid(), peerCredentials.gid()); + pipe.claimChildEp(); + + auto conn = createDBusConnection(requestedName); + pipe.post(); + pipe.wait(); +} + +typedef std::function DBusAssertionFn; + +void dbusTestTemplate(DBusAssertionFn assertion, const std::string &/*scope*/) { + std::string requestedName = "tests.dbus.cynara"; + const ProcessCredentials peerCredentials; + + SynchronizationPipe pipe; + pid_t pid = runInChild(std::bind(dbusServer, std::ref(pipe), std::cref(requestedName), + std::cref(peerCredentials))); + + pipe.claimParentEp(); + pipe.wait(); + + auto conn = createDBusConnection(""); + assertion(std::move(conn), pid, requestedName, peerCredentials); + pipe.post(); +} + +RUNNER_TEST_GROUP_INIT(cynara_creds_dbus) + +RUNNER_TEST_SMACK(tccd01_dbus_credentials_client_pid) { + dbusTestTemplate([] (DBusConnectionPtr conn, pid_t pid, const std::string &requestedName, + const ProcessCredentials &) { + CStringPtr clientPidStr(CynaraHelperCredentials::dbusGetClient(std::move(conn), + requestedName.c_str(), CLIENT_METHOD_PID, CYNARA_API_SUCCESS)); + pid_t clientPid = std::stoi(clientPidStr.get()); + RUNNER_ASSERT_MSG(pid == clientPid, "PIDs don't match ret = " << clientPid + << "; expected = " << pid); + }, "tccd01"); +} + +RUNNER_TEST_SMACK(tccd02_dbus_credentials_client_smack) { + dbusTestTemplate([] (DBusConnectionPtr conn, pid_t, const std::string &requestedName, + const ProcessCredentials &peerCredentials) { + CStringPtr label(CynaraHelperCredentials::dbusGetClient(std::move(conn), + requestedName.c_str(), CLIENT_METHOD_SMACK, CYNARA_API_SUCCESS)); + RUNNER_ASSERT_MSG(peerCredentials.label() == label.get(), + "Labels don't match ret = " << label.get() + << "; expected = " << peerCredentials.label()); + }, "tccd02"); +} + +RUNNER_TEST_SMACK(tccd03_dbus_credentials_user_uid) { + dbusTestTemplate([] (DBusConnectionPtr conn, pid_t, const std::string &requestedName, + const ProcessCredentials &peerCredentials) { + CStringPtr uidStr(CynaraHelperCredentials::dbusGetUser(std::move(conn), + requestedName.c_str(), USER_METHOD_UID, CYNARA_API_SUCCESS)); + uid_t uid = std::stoul(uidStr.get()); + RUNNER_ASSERT_MSG(peerCredentials.uid() == uid, "UIDs don't match ret = " << uid + << "; expected = "<< peerCredentials.uid()); + }, "tccd03"); +} + +RUNNER_TEST_SMACK(tccd04_dbus_credentials_pid) { + dbusTestTemplate([] (DBusConnectionPtr conn, pid_t expectedPid, + const std::string &requestedName, const ProcessCredentials &) { + auto helperPid = CynaraHelperCredentials::dbusGetPid(std::move(conn), + requestedName.c_str(), CYNARA_API_SUCCESS); + RUNNER_ASSERT_MSG(helperPid == expectedPid, "PIDs don't match ret = " << helperPid + << "; expected = " << expectedPid); + }, "tccd04"); +} -- 2.7.4