Add tests for cynara-creds-dbus 38/30438/17
authorAleksander Zdyb <a.zdyb@samsung.com>
Wed, 11 Mar 2015 11:02:01 +0000 (12:02 +0100)
committerZofia Abramowska <z.abramowska@samsung.com>
Wed, 29 Jun 2016 10:10:27 +0000 (12:10 +0200)
Change-Id: Iea7f5e9290899302cd4b2c992110895591ae8903
Signed-off-by: Radoslaw Bartosiak <r.bartosiak@samsung.com>
Signed-off-by: Lukasz Kostyra <l.kostyra@samsung.com>
packaging/security-tests.spec
src/common/security-tests.conf
src/cynara-tests/CMakeLists.txt
src/cynara-tests/common/cynara_test_helpers.cpp
src/cynara-tests/common/cynara_test_helpers.h
src/cynara-tests/common/cynara_test_helpers_dbus.h [new file with mode: 0644]
src/cynara-tests/test_cases_helpers.cpp

index 18011c5..d48021a 100644 (file)
@@ -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
index 0ae6722..f3cc851 100644 (file)
@@ -3,8 +3,11 @@
 <busconfig>
   <!-- Only root can own this service -->
   <policy user="root">
-       <allow own="tests.dbus.client"/>
-       <allow own="test.method.caller"/>
-       <allow own="test.method.server"/>
+    <allow own="tests.dbus.client"/>
+    <allow own="test.method.caller"/>
+    <allow own="test.method.server"/>
+  </policy>
+  <policy user="security_test_user">
+    <allow own="tests.dbus.cynara"/>
   </policy>
 </busconfig>
index 98dcde1..83f4d40 100644 (file)
@@ -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
index 033fbec..a86bead 100644 (file)
@@ -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 <dpl/test/test_runner.h>
 
+#include <cynara-creds-dbus.h>
 #include <cynara-creds-socket.h>
 
 #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
index 1acd6f8..8bfc646 100644 (file)
@@ -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.
 #ifndef CYNARA_TEST_HELPERS_H_
 #define CYNARA_TEST_HELPERS_H_
 
+#include <string>
 #include <sys/types.h>
 
 #include <cynara-creds-commons.h>
 #include <cynara-error.h>
 
+#include <cynara_test_helpers_dbus.h>
+
 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 (file)
index 0000000..c348b08
--- /dev/null
@@ -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 <a.zdyb@samsung.com>
+ * @version     1.0
+ */
+#ifndef CYNARA_TEST_HELPERS_DBUS_H_
+#define CYNARA_TEST_HELPERS_DBUS_H_
+
+#include <dbus/dbus.h>
+#include <functional>
+#include <memory>
+
+typedef std::function<void(DBusConnection *)> DBusConnectionCloseAndUnref;
+typedef std::unique_ptr<DBusConnection, DBusConnectionCloseAndUnref> DBusConnectionPtr;
+
+
+#endif // CYNARA_TEST_HELPERS_DBUS_H_
index 43a73f4..a8ff29f 100644 (file)
@@ -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 <a.zdyb@samsung.com>
  * @version     1.0
- * @brief       Tests for cynara-helper-credentials-socket
+ * @brief       Tests for cynara-helper-credentials-socket and cynara-helper-credentials-dbus
  */
 
 #include <cstdlib>
 #include <sys/types.h>
 #include <sys/un.h>
 #include <unistd.h>
+#include <utility>
 
+#include <dbus/dbus.h>
+
+#include <tests_common.h>
 #include <access_provider.h>
 #include <dpl/test/test_runner.h>
 #include <memory.h>
@@ -36,6 +40,7 @@
 #include <passwd_access.h>
 
 #include <cynara_test_helpers.h>
+#include <cynara_test_helpers_dbus.h>
 
 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<void(DBusConnectionPtr conn, pid_t pid,
+                           const std::string &requestedName,
+                           const ProcessCredentials &peerCredentials)> 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");
+}