Tests for new Security Server security_server_open_for function.
authorZbigniew Jasinski <z.jasinski@samsung.com>
Wed, 30 Oct 2013 15:57:41 +0000 (16:57 +0100)
committerMarcin Niesluchowski <m.niesluchow@samsung.com>
Thu, 23 Jan 2014 14:19:10 +0000 (15:19 +0100)
This function allows to create, if doesn't exist, or open existing file by
Security Server on behalf of calling process in secured directory.

[Issue#]        SSDWSSP-398
[Bug/Feature]   New SS API function.
[Cause]         DataControl issues.
[Solution]      Proposal for DataControl issues.
[Verification]  Build and run new tests.

Change-Id: I86303926a53092fdcc1c14599bfbfc81cb91e8bc

tests/common/tests_common.h
tests/security-server-tests/CMakeLists.txt
tests/security-server-tests/security_server_tests_open_for.cpp [new file with mode: 0644]

index 18ad08c62c91b37bb14f812af6d3057aa0bc0065..8b25108b899134d5cceadebb5f7d8faac7d1b1dd 100644 (file)
@@ -32,6 +32,7 @@
 
 int smack_runtime_check(void);
 int smack_check(void);
+int drop_root_privileges(void);
 
 const uid_t APP_UID = 5000;
 const gid_t APP_GID = 5000;
index 44d395dbb0b0d4ecd536869579c41833b3862ed6..35d56d23488f76c7a898caa1519bcd8a4f79b181 100644 (file)
@@ -51,6 +51,7 @@ SET(SEC_SRV_CLIENT_SMACK_SOURCES
 
 SET(SEC_SRV_TC_SERVER_SOURCES
     ${PROJECT_SOURCE_DIR}/tests/security-server-tests/security_server_tests_server.cpp
+    ${PROJECT_SOURCE_DIR}/tests/security-server-tests/security_server_tests_open_for.cpp
     ${PROJECT_SOURCE_DIR}/tests/security-server-tests/security_server_tests_weird_arguments.cpp
     ${PROJECT_SOURCE_DIR}/tests/security-server-tests/common/security_server_tests_common.cpp
    )
diff --git a/tests/security-server-tests/security_server_tests_open_for.cpp b/tests/security-server-tests/security_server_tests_open_for.cpp
new file mode 100644 (file)
index 0000000..14aa0a4
--- /dev/null
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ */
+/*
+ * @file    security_server_tests_open-for.cpp
+ * @author  Zbigniew Jasinski (z.jasinski@samsung.com)
+ * @version 1.0
+ * @brief   Test cases for security server open-for API
+ */
+
+#include "tests_common.h"
+#include "security-server.h"
+#include "privilege-control.h"
+#include <dpl/test/test_runner.h>
+#include <dpl/log/log.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string>
+#include <vector>
+
+#define TEST01_SUBJECT      "open-for-client"
+
+#define API_OPEN_FOR        "security-server::api-open-for"
+#define API_RULE_REQUIRED   "w"
+
+typedef std::unique_ptr<smack_accesses, std::function<void(smack_accesses*)> > AccessesUniquePtr;
+
+const char *file = "file";
+const char *write_buf1 = "ala ma kota";
+const char *write_buf2 = "kot ma ale";
+char *read_buf1 = new char[strlen(write_buf1)];
+char *read_buf2 = new char[strlen(write_buf2)];
+
+void closefdptr(int* fd_ptr)
+{
+    close(*fd_ptr);
+}
+typedef std::unique_ptr<int, std::function<void(int*)> > FDUniquePtr;
+
+RUNNER_CHILD_TEST_SMACK(tc11_open_for_new_file)
+{
+    std::string subject_allow = TEST01_SUBJECT;
+    struct smack_accesses *handle = NULL;
+    int ret = -1;
+    int fd = -1;
+
+    FDUniquePtr fd_ptr(&fd, closefdptr);
+
+    ret = smack_accesses_new(&handle);
+    RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
+    AccessesUniquePtr rules(handle, smack_accesses_free);
+
+    ret = smack_accesses_add(rules.get(), subject_allow.c_str(), API_OPEN_FOR, API_RULE_REQUIRED);
+    RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
+
+    ret = smack_accesses_apply(rules.get());
+    RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS, "ret: " << ret);
+
+    ret = smack_set_label_for_self(subject_allow.c_str());
+    RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS, "ret: " << ret);
+
+    RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
+
+    ret = security_server_open_for(file, fd_ptr.get());
+    RUNNER_ASSERT_MSG(ret == 0, "ret: " << ret);
+
+    ret = write(*fd_ptr, write_buf1, strlen(write_buf1));
+    RUNNER_ASSERT_MSG(ret == (int)strlen(write_buf1), "error in write: " << ret);
+}
+
+RUNNER_CHILD_TEST_SMACK(tc12_open_for_read_from_existing_file)
+{
+    std::string subject_allow = TEST01_SUBJECT;
+    struct smack_accesses *handle = NULL;
+    int ret = -1;
+    int fd = -1;
+
+    FDUniquePtr fd_ptr(&fd, closefdptr);
+
+    ret = smack_accesses_new(&handle);
+    RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
+    AccessesUniquePtr rules(handle, smack_accesses_free);
+
+    ret = smack_accesses_add(rules.get(), subject_allow.c_str(), API_OPEN_FOR, API_RULE_REQUIRED);
+    RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
+
+    ret = smack_accesses_apply(rules.get());
+    RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS, "ret: " << ret);
+
+    ret = smack_set_label_for_self(subject_allow.c_str());
+    RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS, "ret: " << ret);
+
+    RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
+
+    ret = security_server_open_for(file, fd_ptr.get());
+    RUNNER_ASSERT_MSG(ret == 0, "ret: " << ret);
+
+    ret = read(*fd_ptr, read_buf1, strlen(write_buf1));
+    int err = errno;
+    RUNNER_ASSERT_MSG(ret == (int)strlen(write_buf1), "error in read: " << ret << " err: " << strerror(err));
+
+    RUNNER_ASSERT_MSG(strncmp(read_buf1, write_buf1, strlen(read_buf1)) == 0, "string mismatch");
+}
+
+RUNNER_CHILD_TEST_SMACK(tc13_open_for_write_to_existing_file)
+{
+    std::string subject_allow = TEST01_SUBJECT;
+    struct smack_accesses *handle = NULL;
+    int ret = -1;
+    int fd = -1;
+
+    FDUniquePtr fd_ptr(&fd, closefdptr);
+
+    fd = open("/var/run/security-server/file", O_RDWR);
+    ret = ftruncate(fd, 0);
+    ret = write(*fd_ptr, write_buf2, strlen(write_buf2));
+    int err = errno;
+    RUNNER_ASSERT_MSG(ret == (int)strlen(write_buf2), "error in read: " << ret << " err: " << strerror(err));
+
+    ret = smack_accesses_new(&handle);
+    RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
+    AccessesUniquePtr rules(handle, smack_accesses_free);
+
+    ret = smack_accesses_add(rules.get(), subject_allow.c_str(), API_OPEN_FOR, API_RULE_REQUIRED);
+    RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
+
+    ret = smack_accesses_apply(rules.get());
+    RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS, "ret: " << ret);
+
+    ret = smack_set_label_for_self(subject_allow.c_str());
+    RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS, "ret: " << ret);
+
+    RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
+
+    ret = security_server_open_for(file, fd_ptr.get());
+    RUNNER_ASSERT_MSG(ret == 0, "ret: " << ret);
+
+    ret = read(*fd_ptr, read_buf2, strlen(write_buf2));
+    err = errno;
+    RUNNER_ASSERT_MSG(ret == (int)strlen(write_buf2), "error in read: " << ret << " err: " << strerror(err));
+
+    RUNNER_ASSERT_MSG(strncmp(read_buf2, write_buf2, strlen(read_buf2)) == 0, "string mismatch");
+}
+
+RUNNER_CHILD_TEST_SMACK(tc14_open_for_bad_file_name)
+{
+    std::string subject_allow = TEST01_SUBJECT;
+    struct smack_accesses *handle = NULL;
+    int ret = -1;
+    int fd = -1;
+
+    FDUniquePtr fd_ptr(&fd, closefdptr);
+
+    ret = smack_accesses_new(&handle);
+    RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
+    AccessesUniquePtr rules(handle, smack_accesses_free);
+
+    ret = smack_accesses_add(rules.get(), subject_allow.c_str(), API_OPEN_FOR, API_RULE_REQUIRED);
+    RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret);
+
+    ret = smack_accesses_apply(rules.get());
+    RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS, "ret: " << ret);
+
+    ret = smack_set_label_for_self(subject_allow.c_str());
+    RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS, "ret: " << ret);
+
+    RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid());
+
+    std::vector<std::string> badFile = { "/plik","-plik",".plik","pl..k","..plik",
+                                        "..","." };
+    for (auto iter = badFile.begin(); iter != badFile.end(); ++iter) {
+        ret = security_server_open_for((*iter).c_str(), fd_ptr.get());
+        RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_ERROR_INPUT_PARAM, "ret: " << ret);
+    }
+}