--- /dev/null
+/*
+ * 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);
+ }
+}