security-server tests on DPL framework
authorMariusz Domanski <m.domanski@samsung.com>
Wed, 23 Jan 2013 09:41:37 +0000 (10:41 +0100)
committerMariusz Domanski <m.domanski@samsung.com>
Mon, 4 Feb 2013 09:06:00 +0000 (10:06 +0100)
based on security_server_tests form security-server repository

[Issue] N/A
[Bug] N/A
[Cause] N/A
[Solution] N/A
[Verification] Build and run tests. The new tests are named security-server-tests*

Change-Id: I2dd47aad5363e7c595f7df03a46899638ec7f5bb

packaging/security-tests.spec
tests/CMakeLists.txt
tests/security-server-tests/CMakeLists.txt [new file with mode: 0644]
tests/security-server-tests/security_server_tests_client.cpp [new file with mode: 0644]
tests/security-server-tests/security_server_tests_client.h [new file with mode: 0644]
tests/security-server-tests/security_server_tests_client_smack.cpp [new file with mode: 0644]
tests/security-server-tests/security_server_tests_label.cpp [new file with mode: 0644]
tests/security-server-tests/security_server_tests_password.cpp [new file with mode: 0644]
tests/security-server-tests/security_server_tests_pid_reuser.cpp [new file with mode: 0644]
tests/security-server-tests/security_server_tests_server.cpp [new file with mode: 0644]
tests/security-server-tests/test.h [new file with mode: 0644]

index fb99191..ee4f687 100644 (file)
@@ -10,7 +10,9 @@ Source0:    %{name}-%{version}.tar.gz
 BuildRequires: cmake
 BuildRequires: pkgconfig(libsmack)
 BuildRequires: pkgconfig(libprivilege-control)
+BuildRequires: pkgconfig(security-server)
 BuildRequires: pkgconfig(dpl-test-efl)
+BuildRequires: pkgconfig(dlog)
 Requires:   smack
 Requires:   libprivilege-control
 
@@ -47,6 +49,12 @@ echo "security-tests postinst done ..."
 /usr/bin/security-tests-all.sh
 /usr/bin/libsmack-test
 /usr/bin/libprivilege-control-test
+/usr/bin/security-server-tests-client
+/usr/bin/security-server-tests-client-smack
+/usr/bin/security-server-tests-label
+/usr/bin/security-server-tests-pid-reuser
+/usr/bin/security-server-tests-server
+/usr/bin/security-server-tests-password
 /etc/smack/test_smack_rules
 /etc/smack/test_smack_rules_lnk
 /usr/share/privilege-control/test_privilege_control_rules.smack
index 01f9a38..9ab6aaf 100644 (file)
@@ -37,3 +37,4 @@ INSTALL(FILES ${PROJECT_SOURCE_DIR}/tests/security-tests-all.sh
 
 ADD_SUBDIRECTORY(libprivilege-control-tests)
 ADD_SUBDIRECTORY(libsmack-tests)
+ADD_SUBDIRECTORY(security-server-tests)
diff --git a/tests/security-server-tests/CMakeLists.txt b/tests/security-server-tests/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0641d09
--- /dev/null
@@ -0,0 +1,107 @@
+#
+#Copyright (c) 2013 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        CMakeLists.txt
+# @author      Tomasz Swierczek (t.swierczek@samsung.com)
+# @author      Mariusz Domanski (m.domanski@samsung.com)
+# @brief
+#
+
+INCLUDE(FindPkgConfig)
+
+# Dependencies
+PKG_CHECK_MODULES(SEC_SRV_TESTS_DEP
+    libsmack
+    security-server
+    dpl-test-efl
+    dlog
+    REQUIRED)
+
+# Targets definition
+
+SET(TARGET_SEC_SRV_CLIENT_TESTS "security-server-tests-client")
+SET(TARGET_SEC_SRV_CLIENT_SMACK_TESTS "security-server-tests-client-smack")
+SET(TARGET_SEC_SRV_LABEL_TESTS "security-server-tests-label")
+SET(TARGET_SEC_SRV_PID_TESTS "security-server-tests-pid-reuser")
+SET(TARGET_SEC_SRV_TC_SERVER_TESTS "security-server-tests-server")
+SET(TARGET_SEC_SRV_PWD_TESTS "security-server-tests-password")
+
+# Sources definition
+
+SET(SEC_SRV_CLIENT_SOURCES
+    ${PROJECT_SOURCE_DIR}/tests/security-server-tests/security_server_tests_client.cpp
+   )
+
+SET(SEC_SRV_CLIENT_SMACK_SOURCES
+    ${PROJECT_SOURCE_DIR}/tests/security-server-tests/security_server_tests_client_smack.cpp
+   )
+
+SET(SEC_SRV_LABEL_SOURCES
+    ${PROJECT_SOURCE_DIR}/tests/security-server-tests/security_server_tests_label.cpp
+   )
+
+SET(SEC_SRV_PID_SOURCES
+    ${PROJECT_SOURCE_DIR}/tests/security-server-tests/security_server_tests_pid_reuser.cpp
+   )
+
+SET(SEC_SRV_TC_SERVER_SOURCES
+    ${PROJECT_SOURCE_DIR}/tests/security-server-tests/security_server_tests_server.cpp
+   )
+
+SET(SEC_SRV_PWD_SOURCES
+    ${PROJECT_SOURCE_DIR}/tests/security-server-tests/security_server_tests_password.cpp
+   )
+
+
+INCLUDE_DIRECTORIES(
+    ${SEC_SRV_TESTS_DEP_INCLUDE_DIRS}
+   )
+
+#LINK_DIRECTORIES(${SEC_SRV_PKGS_LIBRARY_DIRS})
+
+ADD_EXECUTABLE(${TARGET_SEC_SRV_CLIENT_TESTS} ${SEC_SRV_CLIENT_SOURCES})
+ADD_EXECUTABLE(${TARGET_SEC_SRV_CLIENT_SMACK_TESTS} ${SEC_SRV_CLIENT_SMACK_SOURCES})
+ADD_EXECUTABLE(${TARGET_SEC_SRV_LABEL_TESTS} ${SEC_SRV_LABEL_SOURCES})
+ADD_EXECUTABLE(${TARGET_SEC_SRV_PID_TESTS} ${SEC_SRV_PID_SOURCES})
+ADD_EXECUTABLE(${TARGET_SEC_SRV_TC_SERVER_TESTS} ${SEC_SRV_TC_SERVER_SOURCES})
+ADD_EXECUTABLE(${TARGET_SEC_SRV_PWD_TESTS} ${SEC_SRV_PWD_SOURCES})
+
+
+TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_CLIENT_TESTS}
+    ${SEC_SRV_TESTS_DEP_LIBRARIES})
+
+TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_CLIENT_SMACK_TESTS}
+    ${SEC_SRV_TESTS_DEP_LIBRARIES})
+
+TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_LABEL_TESTS}
+    ${SEC_SRV_TESTS_DEP_LIBRARIES})
+
+TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_PID_TESTS}
+    ${SEC_SRV_TESTS_DEP_LIBRARIES})
+
+TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_TC_SERVER_TESTS}
+    ${SEC_SRV_TESTS_DEP_LIBRARIES})
+
+TARGET_LINK_LIBRARIES(${TARGET_SEC_SRV_PWD_TESTS}
+    ${SEC_SRV_TESTS_DEP_LIBRARIES})
+
+# Installation
+
+INSTALL(TARGETS ${TARGET_SEC_SRV_CLIENT_TESTS} DESTINATION /usr/bin)
+INSTALL(TARGETS ${TARGET_SEC_SRV_CLIENT_SMACK_TESTS} DESTINATION /usr/bin)
+INSTALL(TARGETS ${TARGET_SEC_SRV_LABEL_TESTS} DESTINATION /usr/bin)
+INSTALL(TARGETS ${TARGET_SEC_SRV_PID_TESTS} DESTINATION /usr/bin)
+INSTALL(TARGETS ${TARGET_SEC_SRV_TC_SERVER_TESTS} DESTINATION /usr/bin)
+INSTALL(TARGETS ${TARGET_SEC_SRV_PWD_TESTS} DESTINATION /usr/bin)
diff --git a/tests/security-server-tests/security_server_tests_client.cpp b/tests/security-server-tests/security_server_tests_client.cpp
new file mode 100644 (file)
index 0000000..5a89ea0
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ */
+/*
+ * @file    security_server_tests_client.cpp
+ * @author  Bumjin Im (bj.im@samsung.com)
+ * @author  Mariusz Domanski (m.domanski@samsung.com)
+ * @version 1.0
+ * @brief   Test cases for security server client
+ */
+
+#include <dpl/test/test_runner.h>
+#include <dlog.h>
+#include "security_server_tests_client.h"
+
+RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_CLIENT)
+
+RUNNER_TEST(tc_security_server_get_cookie_size)
+{
+    int ret = security_server_get_cookie_size();
+    LOGD("ret = %d", ret);
+    RUNNER_ASSERT(ret == 20);
+}
+
+RUNNER_TEST(tc_security_server_request_cookie_normal_case)
+{
+    int ret = security_server_request_cookie(cookie, 20);
+    LOGD("ret = %d", ret);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+}
+
+RUNNER_TEST(tc_security_server_request_cookie_too_small_buffer_size)
+{
+    int ret = security_server_request_cookie(cookie, 10);
+    LOGD("ret = %d", ret);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_BUFFER_TOO_SMALL);
+}
+
+RUNNER_TEST(tc_security_server_check_privilege_client_is_not_allowed)
+{
+    int ret = security_server_check_privilege(cookie, g_permissions[0]);
+    LOGD("ret = %d", ret);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_AUTHENTICATION_FAILED);
+}
+
+RUNNER_TEST(tc_security_server_get_gid_client_is_not_allowed)
+{
+    int ret = security_server_get_gid("telephony");
+    LOGD("ret = %d", ret);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_AUTHENTICATION_FAILED);
+}
+
+RUNNER_TEST(tc_security_server_get_object_name_client_is_not_allowed)
+{
+    int ret = security_server_get_object_name(g_groups[0], tmpchar,
+            sizeof(tmpchar));
+    LOGD("ret = %d", ret);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_AUTHENTICATION_FAILED);
+}
+
+RUNNER_TEST(tc_requesting_access_to_test_server_via_security_server)
+{
+    for(i=0;i<g_perm_num;i++)
+    {
+        sock_fd = connect_to_testserver();
+        if(sock_fd < 1)
+        {
+            LOGD("sock_fd = %d", sock_fd);
+            RUNNER_ASSERT_MSG(false, "Socket connection error");
+        }
+        LOGD("%d: requesting %d permission...sockfd=%d\n", i, g_permissions[i],
+                sock_fd);
+        int ret = send_request(sock_fd, (unsigned char *) cookie,
+                g_permissions[i]);
+
+        if(ret != 0)
+        {
+            close(sock_fd);
+            LOGD("ret = %d", ret);
+            RUNNER_ASSERT_MSG(false, "send failed");
+        }
+
+        ret = recv_result(sock_fd);
+        close(sock_fd);
+        sock_fd = 0;
+        if(ret == SECURITY_SERVER_API_SUCCESS)
+        {
+            LOGD("Permission granted\n");
+        }
+        else if(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED)
+        {
+            LOGD("Permission denied\n\n");
+            RUNNER_ASSERT_MSG(false, "Permission denied");
+        }
+        else
+        {
+            LOGD("ret = %d", ret);
+            RUNNER_ASSERT_MSG(false, "Recv error");
+        }
+    }
+}
+
+RUNNER_TEST(tc_requesting_cookie_for_same_pid_with_different_path)
+{
+    LOGI("       Exiting this process to cycle different process as same PID.\n");
+    LOGI("       Please look at the test server's terminal for the result\n");
+    cur_pid = getpid();
+    sock_fd = connect_to_testserver();
+    if(sock_fd < 1)
+    {
+        RUNNER_ASSERT_MSG(false, "Socket connection error");
+    }
+
+    unsigned char buf[32] = {255, 255, 255, 255, };
+    int size;
+
+    memcpy(buf + 4, cookie, 20);
+    memcpy(buf + 24, &cur_pid, sizeof(int));
+    int ret = getuid();
+    memcpy(buf + 28, &ret, sizeof(int));
+
+    size = write(sock_fd, buf, 32);
+    if(size < 32)
+    {
+        close(sock_fd);
+        LOGD("size = %d", size);
+        RUNNER_ASSERT_MSG(false, "Cannot send");
+    }
+    if(sock_fd > 0)
+        close(sock_fd);
+}
+
+
+int main(int argc, char *argv[])
+{
+    /* needed for dlog to work properly
+     * during tests guid changes and dlog looses permission to write logs
+     * printing log now opens file descriptor with proper privileges */
+    LOGD("%s starts", argv[0]);
+
+    g_group_num = 0;
+    g_perm_num = 0;
+
+    int ret = getuid();
+    if(ret != 0)
+    {
+        printf("You must be root to test. Current UID: %d\nExiting...\n", ret);
+        exit(1);
+    }
+
+    int argcc = 15;
+    char *argvv[] = {argv[0], "-u", "5000",
+            "-g", "6001", "6002", "6003", "6004", "6005", "6006", "6007",
+            "-p", "6001", "6002", "6010"};
+
+    system("touch /opt/home/root/pid_cycle");
+    privilege_control(argcc, argvv);
+
+    LOGI("Strting test. My PID is %d", getpid());
+
+    int status =
+        DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+
+    if(g_groups != NULL)
+        free(g_groups);
+    if(g_permissions != NULL)
+        free(g_permissions);
+    return status;
+}
diff --git a/tests/security-server-tests/security_server_tests_client.h b/tests/security-server-tests/security_server_tests_client.h
new file mode 100644 (file)
index 0000000..344a6a7
--- /dev/null
@@ -0,0 +1,308 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ */
+/*
+ * @file    security_server_tests_client.h
+ * @author  Bumjin Im (bj.im@samsung.com)
+ * @author  Mariusz Domanski (m.domanski@samsung.com)
+ * @version 1.0
+ * @brief   Test cases for security server client
+ */
+
+#ifndef SECURITY_SERVER_TESTS_CLIENT_H
+#define    SECURITY_SERVER_TESTS_CLIENT_H
+
+#include <unistd.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <sys/un.h>
+#include <sys/socket.h>
+#include <sys/smack.h>
+#include "security-server.h"
+#include <grp.h>
+#include "test.h"
+
+int *g_permissions = NULL;
+gid_t *g_groups = NULL;
+int g_perm_num, g_group_num;
+
+char *object_label = NULL;
+char *subject_label = NULL;
+char *access_rights = NULL;
+
+int sock_fd, i, cur_pid, cnt;
+char cookie[20];
+char tmpchar[100];
+
+/* deprecated info for old c-style binary
+ * still useful for understanding the test itself
+ *
+ * Usage:
+ * cmd -u uid -g gid1 gid2 gid3... -p gid_a gid_b gid_c ...
+ * or:
+ * cmd -s subject -o object -a access-rights
+ * [Options]
+ * -u: UID that the process are running as
+ *     Only one UID is allowed.
+ * -g: GIDs that the process belongs to
+ * -p: GIDs that the process wants to get privilege
+ * -s: subject label (label of the process)
+ * -o: object label to be accessed
+ * -a: accessed rights requested (one or more of the letterrs rwx)
+ * Examples:
+ * cmd -u 5000 -g 6001 6002 6003 6004 6005 6006 6007 -p 6001 6002 6010
+ * cmd -s mylabel -o objlabel -a rx
+ */
+
+int privilege_control_old(int argc, char *argv[])
+{
+    int option = 0; /* 0: no, 1: uID, 2: gid, 3: permission */
+    int uid_flag = 0, gid_flag= 0, perm_flag = 0, i = 1, number, uid = 0, j;
+
+    while(i < argc)
+    {
+        if(strcmp(argv[i], "-u") == 0)
+        {
+            if(uid_flag != 0)
+            {
+                printf("%s\n", "-u option already used");
+                exit(1);
+            }
+            option = 1;
+            uid_flag = 1;
+        }
+        else if (strcmp(argv[i], "-g") == 0)
+        {
+            if(gid_flag != 0)
+            {
+                printf("%s\n", "-g option already used");
+                exit(1);
+            }
+            option = 2;
+            gid_flag = 1;
+        }
+        else if (strcmp(argv[i], "-p") == 0)
+        {
+            if(perm_flag != 0)
+            {
+                printf("%s\n", "-p option already used");
+                exit(1);
+            }
+            option = 3;
+            perm_flag = 1;
+        }
+        else
+        {
+            errno = 0;
+            number = strtoul(argv[i], 0, 10);
+            if(errno != 0)
+            {
+                printf("%s\n", "Invalid option");
+                exit(1);
+            }
+            switch(option)
+            {
+                case 1:
+                    if(uid != 0)
+                    {
+                        printf("%s\n", "You cannot assign more than 1 uID");
+                        exit(1);
+                    }
+                    uid = number;
+                    break;
+                case 2:
+                    for(j=0;i<g_group_num;j++)
+                    {
+                        if(number == g_groups[j])
+                            break;
+                    }
+                    g_groups = (gid_t *)realloc(g_groups, sizeof(gid_t) * (++g_group_num));
+                    g_groups[g_group_num -1] = number;
+                    break;
+                case 3:
+                    for(j=0;i<g_perm_num;j++)
+                    {
+                        if(number == g_permissions[j])
+                            break;
+                    }
+                    g_permissions = (int *)realloc(g_permissions, sizeof(int) * (++g_perm_num));
+                    g_permissions[g_perm_num -1] = number;
+                    break;
+                default:
+                    printf("%s\n", "Invalid option");
+                    exit(1);
+                    break;
+            }
+        }
+        i++;
+    }
+    if(g_group_num == 0 || g_perm_num == 0)
+    {
+        printf("%s\n", "You must assign groups and permissions");
+        exit(1);
+    }
+    if(setgroups(g_group_num, g_groups) != 0)
+    {
+        printf("%s\n", "Error on setgroups{}");
+        exit(1);
+    }
+
+    setgid(uid);
+    setuid(uid);
+    return 0;
+}
+
+int privilege_control_new(int argc, char *argv[])
+{
+    if (argc == 7 && !strcmp(argv[1], "-s") &&
+                     !strcmp(argv[3], "-o") &&
+                     !strcmp(argv[5], "-a"))
+    {
+        int ret;
+        subject_label = argv[2];
+        object_label = argv[4];
+        access_rights = argv[6];
+
+        ret = smack_set_label_for_self(subject_label);
+        if (ret != 0)
+        {
+            printf("(2)Cannot set my own smack label... maybe I'm not root?");
+            exit(1);
+        }
+        setgid(1);
+        setuid(1);
+    }
+    else
+    {
+        exit(1);
+    }
+
+    return 0;
+}
+
+int privilege_control(int argc, char *argv[])
+{
+
+    if (argc == 7 && !strcmp(argv[1], "-s"))
+    {
+        return privilege_control_new(argc, argv);
+    }
+    else
+    {
+        return privilege_control_old(argc, argv);
+    }
+}
+
+int connect_to_testserver()
+{
+    struct sockaddr_un clientaddr;
+    int client_len = 0, localsockfd, ret;
+
+    /* Create a socket */
+    if((localsockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
+    {
+        LOGE("%s", "Error on socket()");
+        return 0;
+    }
+
+    bzero(&clientaddr, sizeof(clientaddr));
+    clientaddr.sun_family = AF_UNIX;
+    strncpy(clientaddr.sun_path, SECURITY_SERVER_TEST_SOCK_PATH, strlen(SECURITY_SERVER_TEST_SOCK_PATH));
+    clientaddr.sun_path[strlen(SECURITY_SERVER_TEST_SOCK_PATH)] = 0;
+    client_len = sizeof(clientaddr);
+    if(connect(localsockfd, (struct sockaddr*)&clientaddr, client_len) < 0)
+    {
+        LOGE("%s", "Error on connect");
+        close(localsockfd);
+        return 0;
+    }
+    return localsockfd;
+}
+
+
+int send_request(int sock_fd, unsigned char *cookie, int perm)
+{
+    unsigned char buf[28] = {0, 0, 0, 0, };
+    int size;
+    memcpy(buf + 4, cookie, 20);
+    memcpy(buf + 24, &perm, sizeof(int));
+    size = write(sock_fd, buf, 28);
+    if(size < 28)
+    {
+        printf("Cannot send\n");
+        close(sock_fd);
+        exit(1);
+    }
+    return 0;
+}
+
+/*
+ * @param direct 0=via security server 1=directly from IPC socket
+ */
+int send_request_new_cookie(int sock_fd,
+                            const char *cookie,
+                            const char *subject_label,
+                            const char *access_rights)
+{
+    unsigned char buf[1024] = {17, 0, 0, 0, };
+    int olen, alen;
+    int size, ret;
+    olen = strlen(subject_label);
+    alen = strlen(access_rights);
+    size = 24+2*sizeof(int)+olen+alen;
+    memcpy(buf + 4, cookie, 20);
+    memcpy(buf + 24, &olen, sizeof(int));
+    memcpy(buf + 28, &alen, sizeof(int));
+    memcpy(buf + 32, subject_label, olen);
+    memcpy(buf + 32 + olen, access_rights, alen);
+    ret = write(sock_fd, buf, size);
+    if(ret < size)
+    {
+        printf("Cannot send\n");
+        close(sock_fd);
+        exit(1);
+    }
+    return 0;
+}
+
+int send_request_new_direct(int sock_fd,
+                            const char *object_label,
+                            const char *access_rights)
+{
+    unsigned char buf[1024] = {17, 0, 0, 1, };
+    int olen, alen;
+    int size, ret;
+    olen = strlen(object_label);
+    alen = strlen(access_rights);
+    size = 24+2*sizeof(int)+olen+alen;
+    memcpy(buf + 4, &olen, sizeof(int));
+    memcpy(buf + 8, &alen, sizeof(int));
+    memcpy(buf + 12, object_label, olen);
+    memcpy(buf + 12 + olen, access_rights, alen);
+    ret = write(sock_fd, buf, size);
+    if(ret < size)
+    {
+        printf("Cannot send\n");
+        close(sock_fd);
+        exit(1);
+    }
+    return 0;
+}
+
+int recv_result(int sock_fd)
+{
+    int buf, size;
+    size = read(sock_fd, &buf, sizeof(int));
+    if(size < sizeof(int))
+    {
+        printf("Cannot recv\n");
+        close(sock_fd);
+        exit(1);
+    }
+    return buf;
+}
+
+#endif    /* SECURITY_SERVER_TESTS_CLIENT_H */
diff --git a/tests/security-server-tests/security_server_tests_client_smack.cpp b/tests/security-server-tests/security_server_tests_client_smack.cpp
new file mode 100644 (file)
index 0000000..a786912
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ */
+/*
+ * @file    security_server_tests_client_smack.cpp
+ * @author  Bumjin Im (bj.im@samsung.com)
+ * @author  Mariusz Domanski (m.domanski@samsung.com)
+ * @version 1.0
+ * @brief   Test cases for security server client
+ */
+
+#include <dpl/test/test_runner.h>
+#include <dlog.h>
+#include "security_server_tests_client.h"
+
+RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_CLIENT_SMACK)
+
+RUNNER_TEST(tc_security_server_get_cookie_size)
+{
+    int ret = security_server_get_cookie_size();
+    LOGD("ret = %d", ret);
+    RUNNER_ASSERT(ret == 20);
+}
+
+RUNNER_TEST(tc_security_server_request_cookie_normal_case)
+{
+    int ret = security_server_request_cookie(cookie, 20);
+    LOGD("ret = %d", ret);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+}
+
+RUNNER_TEST(tc_security_server_request_cookie_too_small_buffer_size)
+{
+    int ret = security_server_request_cookie(cookie, 10);
+    LOGD("ret = %d", ret);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_BUFFER_TOO_SMALL);
+}
+
+RUNNER_TEST(tc_security_server_get_gid_client_is_not_allowed)
+{
+    int ret = security_server_get_gid("telephony");
+    LOGD("ret = %d", ret);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_AUTHENTICATION_FAILED);
+}
+
+RUNNER_TEST(tc_requesting_access_to_test_server_via_security_server)
+{
+    sock_fd = connect_to_testserver();
+    if(sock_fd < 1)
+    {
+        LOGD("sock_fd = %d", sock_fd);
+        RUNNER_ASSERT_MSG(false, "Socket connection error");
+    }
+    int ret = send_request_new_cookie(sock_fd, cookie, object_label, access_rights);
+    if(ret != 0)
+    {
+        close(sock_fd);
+        LOGD("ret = %d", ret);
+        RUNNER_ASSERT_MSG(false, "send failed");
+    }
+    ret = recv_result(sock_fd);
+    close(sock_fd);
+    sock_fd = 0;
+    if(ret == SECURITY_SERVER_API_SUCCESS)
+    {
+        LOGD("Permission granted\n");
+    }
+    else if(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED)
+    {
+        RUNNER_ASSERT_MSG(false, "Permission denied");
+    }
+    else
+    {
+        LOGD("ret = %d", ret);
+        RUNNER_ASSERT_MSG(false, "Recv error");
+    }
+}
+
+RUNNER_TEST(tc_requesting_access_to_test_server_with_direct_ipc)
+{
+    LOGD("subject: >%s<\n", subject_label);
+    LOGD("object:  >%s<\n", object_label);
+    LOGD("access:  >%s<\n", access_rights);
+
+    sock_fd = connect_to_testserver();
+    if(sock_fd < 1)
+    {
+        LOGD("sock_fd = %d", sock_fd);
+        RUNNER_ASSERT_MSG(false, "Socket connection error");
+    }
+    int ret = send_request_new_direct(sock_fd, object_label, access_rights);
+    if(ret != 0)
+    {
+        close(sock_fd);
+        LOGD("ret = %d", ret);
+        RUNNER_ASSERT_MSG(false, "send failed");
+    }
+    ret = recv_result(sock_fd);
+    close(sock_fd);
+    if(ret == SECURITY_SERVER_API_SUCCESS)
+    {
+        LOGD("Permission granted\n");
+    }
+    else if(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED)
+    {
+        RUNNER_ASSERT_MSG(false, "Permission denied");
+    }
+    else
+    {
+        LOGD("ret = %d", ret);
+        RUNNER_ASSERT_MSG(false, "Recv error");
+    }
+}
+
+RUNNER_TEST(tc_requesting_cookie_for_same_pid_with_different_path)
+{
+    LOGI("       Exiting this process to cycle different process as same PID.\n");
+    LOGI("       Please look at the test server's terminal for the result\n");
+    cur_pid = getpid();
+    sock_fd = connect_to_testserver();
+    if(sock_fd < 1)
+    {
+        RUNNER_ASSERT_MSG(false, "Socket connection error");
+    }
+
+    unsigned char buf[32] = {255, 255, 255, 255, };
+    int size;
+
+    memcpy(buf + 4, cookie, 20);
+    memcpy(buf + 24, &cur_pid, sizeof(int));
+    int ret = getuid();
+    memcpy(buf + 28, &ret, sizeof(int));
+
+    size = write(sock_fd, buf, 32);
+    if(size < 32)
+    {
+        close(sock_fd);
+        RUNNER_ASSERT_MSG(false, "Cannot send");
+    }
+    if(sock_fd > 0)
+        close(sock_fd);
+}
+
+
+int main(int argc, char *argv[])
+{
+    /* needed for dlog to work properly
+     * during tests guid changes and dlog looses permission to write logs
+     * printing log now opens file descriptor with proper privileges */
+    LOGD("%s starts", argv[0]);
+
+    g_group_num = 0;
+    g_perm_num = 0;
+
+    int ret = getuid();
+    if(ret != 0)
+    {
+        printf("You must be root to test. Current UID: %d\nExiting...\n", ret);
+        exit(1);
+    }
+
+    int argcc = 7;
+    char *argvv[] = {argv[0], "-s", "mylabel", "-o", "objlabel", "-a", "rx"};
+
+    system("touch /opt/home/root/pid_cycle");
+    privilege_control(argcc, argvv);
+
+    LOGD("Strting test. My PID is %d", getpid());
+
+    int status =
+        DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+
+    if(g_groups != NULL)
+        free(g_groups);
+    if(g_permissions != NULL)
+        free(g_permissions);
+    return status;
+}
diff --git a/tests/security-server-tests/security_server_tests_label.cpp b/tests/security-server-tests/security_server_tests_label.cpp
new file mode 100644 (file)
index 0000000..a1025de
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+* Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+*/
+/*
+* @file    security_server_tests_label.cpp
+* @author  Pawel Polawski (p.polawski@samsung.com)
+* @author  Mariusz Domanski (m.domanski@samsung.com)
+* @version 1.0
+* @brief   Test cases for security server
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/smack.h>
+#include <security-server.h>
+#include <dpl/test/test_runner.h>
+#include <dlog.h>
+#include "test.h"
+
+RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_LABEL);
+
+RUNNER_TEST(tc_security_server_get_smacklabel_cookie) {
+    int res;
+
+    pid_t mypid;
+
+    char * label_smack = NULL;
+    char * label_ss = NULL;
+    char * cookie = NULL;
+
+    int COOKIESIZE = security_server_get_cookie_size();
+    RUNNER_ASSERT_MSG(20 == COOKIESIZE, "Wrong cookie size from security-server");
+    LOGD("%s %d", "Cookie size:", COOKIESIZE);
+
+    cookie = (char *) calloc(COOKIESIZE, 1);
+    RUNNER_ASSERT_MSG(NULL != cookie, "Memory allocation error");
+
+    mypid = getpid();
+    LOGD("%s %d", "This binary PID is:", mypid);
+
+    res = smack_new_label_from_self(&label_smack);
+    if (0 != res) {
+        if (NULL != label_smack)
+            free(label_smack);
+        if (NULL != label_ss)
+            free(label_ss);
+        if (NULL != cookie)
+            free(cookie);
+        RUNNER_ASSERT_MSG(false, "Error in getting self SMACK label");
+    }
+
+    res = security_server_request_cookie(cookie, COOKIESIZE);
+    if (SECURITY_SERVER_API_SUCCESS != res) {
+        if (NULL != label_smack)
+            free(label_smack);
+        if (NULL != label_ss)
+            free(label_ss);
+        if (NULL != cookie)
+            free(cookie);
+        RUNNER_ASSERT_MSG(false, "Error in requesting cookie from security-server");
+    }
+
+    LOGD("%s", "Received cookie:");
+    printhex((unsigned char *) cookie, COOKIESIZE);
+
+    label_ss = security_server_get_smacklabel_cookie(cookie);
+    if (NULL == label_ss) {
+        if (NULL != label_smack)
+            free(label_smack);
+        if (NULL != label_ss)
+            free(label_ss);
+        if (NULL != cookie)
+            free(cookie);
+        RUNNER_ASSERT_MSG(false, "Error in getting label by cookie");
+    }
+
+    LOGD("%s %s", "Label from SMACK:", label_smack);
+    LOGD("%s %s", "Label from SS:", label_ss);
+
+    if (sizeof(label_smack) != sizeof(label_ss)) {
+        if (NULL != label_smack)
+            free(label_smack);
+        if (NULL != label_ss)
+            free(label_ss);
+        if (NULL != cookie)
+            free(cookie);
+        RUNNER_ASSERT_MSG(false, "No match in SMACK labels sizes");
+    }
+
+    res = memcmp(label_smack, label_ss, sizeof(label_smack));
+    if (0 != res) {
+        if (NULL != label_smack)
+            free(label_smack);
+        if (NULL != label_ss)
+            free(label_ss);
+        if (NULL != cookie)
+            free(cookie);
+        RUNNER_ASSERT_MSG(false, "No match in SMACK labels");
+    }
+
+    //TODO: here could be label change using SMACK API and checking if it
+    //is changed using security-server API function based on the same cookie
+}
+
+int main(int argc, char * argv[])
+{
+    int status =
+        DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+
+    return status;
+}
diff --git a/tests/security-server-tests/security_server_tests_password.cpp b/tests/security-server-tests/security_server_tests_password.cpp
new file mode 100644 (file)
index 0000000..668b2a6
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ */
+/*
+ * @file    security_server_tests_password.cpp
+ * @author  Bumjin Im (bj.im@samsung.com)
+ * @author  Mariusz Domanski (m.domanski@samsung.com)
+ * @version 1.0
+ * @brief   Test cases for security server
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <dirent.h>
+#include "security-server.h"
+#include <dpl/test/test_runner.h>
+#include <dlog.h>
+#include "test.h"
+
+unsigned long i=1;
+unsigned int attempt, max_attempt, expire_sec, temp_sec;
+struct timeval cur_time;
+char buf1[33], buf2[33];
+struct dirent **mydirent;
+
+char ** argvv;
+
+/* deprecated info for old c-style binary
+ * still useful for understanding the test itself
+ *
+ * Usage:
+ * cmd password1 password2
+ * Example:
+ * cmd 123456 abcdef
+ */
+
+int dir_filter(const struct dirent *entry)
+{
+    if ((strcmp(entry->d_name, ".") == 0) ||
+        (strcmp(entry->d_name, "..") == 0) ||
+        (strcmp(entry->d_name, "attempts") ==0) ||
+        (strcmp(entry->d_name, "history") ==0) )
+        return (0);
+    else
+        return (1);
+}
+
+RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_PASSWORD);
+
+RUNNER_TEST(tc_security_server_is_pwd_empty_no_pwd_case)
+{
+    if(getuid() == 0)
+    {
+        system("rm /opt/data/security-server/*");
+        sync();
+
+        int ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
+        RUNNER_ASSERT(!(ret != SECURITY_SERVER_API_ERROR_NO_PASSWORD || attempt != 0 || max_attempt != 0 || expire_sec != 0));
+    }
+    else
+    {
+        LOGD("To run the test as non root user, please remove password files (/opt/data/security-server/*) in root shell\n");
+        LOGD("If not, you will see some failures\n");
+        RUNNER_IGNORED_MSG("I'm not root");
+    }
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_validity_there_is_no_password_yet)
+{
+    RUNNER_ASSERT(security_server_set_pwd_validity(10) == SECURITY_SERVER_API_ERROR_NO_PASSWORD);
+    RUNNER_ASSERT(security_server_set_pwd_validity(11) == SECURITY_SERVER_API_ERROR_NO_PASSWORD);
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_max_challenge_there_is_no_password_yet)
+{
+    RUNNER_ASSERT(security_server_set_pwd_max_challenge(5) == SECURITY_SERVER_API_ERROR_NO_PASSWORD);
+    RUNNER_ASSERT(security_server_set_pwd_max_challenge(6) == SECURITY_SERVER_API_ERROR_NO_PASSWORD);
+}
+
+RUNNER_TEST(tc_security_server_chk_pwd_too_long_password_case)
+{
+    int ret = security_server_chk_pwd("abcdefghijklmnopqrstuvwxyz0123456", &attempt, &max_attempt, &expire_sec); /* 33 chars */
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
+}
+
+RUNNER_TEST(tc_security_server_chk_pwd_null_input_case)
+{
+    int ret = security_server_chk_pwd(NULL, &attempt, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
+    ret = security_server_chk_pwd("password", NULL, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
+    ret = security_server_chk_pwd("password", &attempt, NULL, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
+    ret = security_server_chk_pwd("password", &attempt, &max_attempt, NULL);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
+}
+
+RUNNER_TEST(tc_security_server_chk_pwd_no_password_case)
+{
+    int ret = security_server_chk_pwd("isthisempty", &attempt, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(!(ret != SECURITY_SERVER_API_ERROR_NO_PASSWORD || max_attempt != 0 || expire_sec != 0));
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_null_input_case)
+{
+    RUNNER_ASSERT(security_server_set_pwd(NULL, NULL, 0, 0) == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_too_long_input_param)
+{
+    int ret = security_server_set_pwd("abcdefghijklmnopqrstuvwxyz0123456", "abcdefghijklmnopqrstuvwxyz0123456", 0, 0);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_normal_case_when_current_pwd_is_empty)
+{
+    RUNNER_ASSERT(security_server_set_pwd(NULL, argvv[1], 0, 0) == SECURITY_SERVER_API_SUCCESS);
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_validity_normal_case_when_there_is_a_password)
+{
+    RUNNER_ASSERT(security_server_set_pwd_validity(1) == SECURITY_SERVER_API_SUCCESS);
+    RUNNER_ASSERT(security_server_set_pwd_validity(2) == SECURITY_SERVER_API_SUCCESS);
+    RUNNER_ASSERT(security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec) == SECURITY_SERVER_API_ERROR_PASSWORD_EXIST);
+    RUNNER_ASSERT(expire_sec >= 172798 && expire_sec <= 172800); // About 2 days in seconds +-1 second
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_max_challenge_normal_case_when_there_is_a_password)
+{
+    RUNNER_ASSERT(security_server_set_pwd_max_challenge(5) == SECURITY_SERVER_API_SUCCESS);
+    RUNNER_ASSERT(security_server_set_pwd_max_challenge(6) == SECURITY_SERVER_API_SUCCESS);
+    RUNNER_ASSERT(security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec) == SECURITY_SERVER_API_ERROR_PASSWORD_EXIST);
+    RUNNER_ASSERT (6 == max_attempt);
+}
+
+RUNNER_TEST(tc_security_server_chk_pwd_normal_correct_pwd_case)
+{
+    int ret = security_server_chk_pwd(argvv[1], &attempt, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+}
+
+RUNNER_TEST(tc_security_server_is_pwd_empty_password_exists)
+{
+    int ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_EXIST);
+}
+
+RUNNER_TEST(tc_security_server_chk_pwd_incorrect_pwd_case)
+{
+    (argvv[1])[0]++;
+    int ret = security_server_chk_pwd(argvv[1], &attempt, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH);
+    (argvv[1])[0]--;
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_incorrect_current_password)
+{
+    (argvv[1])[0]++;
+    int ret = security_server_set_pwd(argvv[1], argvv[2], 0, 0);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH);
+    (argvv[1])[0]--;
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_correct_password)
+{
+    int ret = security_server_set_pwd(argvv[1], argvv[2], 0, 0);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+}
+
+RUNNER_TEST(tc_security_server_chk_pwd_check_increasing_attempts_with_reset_when_correct_password_has_been_checked)
+{
+    int ret = security_server_set_pwd(argvv[2], argvv[1], 10, 0);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+    for(i=0;i<5;i++)
+    {
+        LOGD("%d\n", i+1);
+        ret = security_server_chk_pwd(argvv[2],  &attempt, &max_attempt, &expire_sec);
+        RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH);
+        RUNNER_ASSERT(attempt == (i+1));
+        sleep(1);
+    }
+    LOGD("%d\n", i+1);
+    ret = security_server_chk_pwd(argvv[1],  &attempt, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+    LOGD("%d\n", i+2);
+    ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_EXIST);
+    RUNNER_ASSERT(!(attempt != 0 || max_attempt != 10));
+}
+
+RUNNER_TEST(tc_security_server_chk_pwd_attempt_exceeding_case)
+{
+    for(i=0;i<10;i++)
+    {
+        LOGD("%d\n", i+1);
+        int ret = security_server_chk_pwd(argvv[2],  &attempt, &max_attempt, &expire_sec);
+        RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH);
+        RUNNER_ASSERT(attempt == (i+1));
+        sleep(1);
+    }
+    LOGD("%d\n", i+1);
+    int ret = security_server_chk_pwd(argvv[1],  &attempt, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_MAX_ATTEMPTS_EXCEEDED);
+}
+
+RUNNER_TEST(tc_security_server_reset_pwd_reset_current_password)
+{
+    RUNNER_ASSERT(security_server_reset_pwd(argvv[1],0, 0) == SECURITY_SERVER_API_SUCCESS);
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_check_expiration)
+{
+    int ret = security_server_set_pwd(argvv[1], argvv[2], 10, 1);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+    sleep(1);
+    ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_EXIST);
+    RUNNER_ASSERT(expire_sec <= 86400 && expire_sec >= 86398);
+}
+
+RUNNER_TEST(tc_security_server_chk_pwd_check_expiration_sec_decreasing)
+{
+    int ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_EXIST);
+    sleep(1);
+    temp_sec = 0;
+    for(i=0;i<5;i++)
+    {
+        expire_sec = 0;
+        ret = security_server_chk_pwd(argvv[2],  &attempt, &max_attempt, &expire_sec);
+        RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+        RUNNER_ASSERT(!(temp_sec != 0 && ((temp_sec -expire_sec) > 2) && ((temp_sec -expire_sec) < 1)));
+        temp_sec = expire_sec;
+        LOGD("%d\n", expire_sec);
+        sleep(1);
+    }
+}
+
+RUNNER_TEST(tc_security_server_chk_pwd_check_expiration_with_system_time_change)
+{
+    int ret = gettimeofday(&cur_time, NULL);
+    RUNNER_ASSERT(ret >= 0);
+    cur_time.tv_sec += (expire_sec -4);
+    ret = settimeofday(&cur_time, NULL);
+    RUNNER_ASSERT(ret >= 0);
+    temp_sec = 0;
+    for(i=0;i<5;i++)
+    {
+        expire_sec = 0;
+        ret = security_server_chk_pwd(argvv[2],  &attempt, &max_attempt, &expire_sec);
+        RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS || ret == SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED);
+        if(ret == SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED)
+            break;
+        RUNNER_ASSERT(!(temp_sec != 0 && ((temp_sec -expire_sec) > 2) && ((temp_sec -expire_sec) < 1)));
+        temp_sec = expire_sec;
+        LOGD("%d\n", expire_sec);
+        sleep(1);
+    }
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED);
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_history_too_big_and_small_number)
+{
+    RUNNER_ASSERT(security_server_set_pwd_history(100) == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
+    RUNNER_ASSERT(security_server_set_pwd_history(-5) == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_history_normal_case)
+{
+    RUNNER_ASSERT(security_server_set_pwd_history(10) == SECURITY_SERVER_API_SUCCESS);
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_history_check_history_is_working)
+{
+    int ret = security_server_reset_pwd("history1",0, 0);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+    LOGD("1\n");
+    sleep(1);
+    for(i=1;i<11;i++)
+    {
+        sprintf(buf1, "history%d", i);
+        sprintf(buf2, "history%d", i+1);
+        ret = security_server_set_pwd(buf1, buf2, 0, 0);
+        RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+        LOGD("%d\n", i+1);
+        sleep(1);
+    }
+    ret = security_server_set_pwd("history11", "history1", 0, 0);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+    sleep(1);
+    ret = security_server_set_pwd("history1", "history8", 0, 0);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_REUSED);
+}
+
+RUNNER_TEST(tc_security_server_set_pwd_check_garbage_collection)
+{
+    int ret = security_server_set_pwd("history1", "history12", 0, 0);
+    sprintf(buf1, "history12");
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+    LOGD("12\n");
+    sleep(1);
+    for(i=12;i<60;i++)
+    {
+        sprintf(buf1, "history%d", i);
+        sprintf(buf2, "history%d", i+1);
+        ret = security_server_set_pwd(buf1, buf2, 0, 0);
+        RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+        LOGD("%d\n", i+1);
+        sleep(1);
+    }
+    ret = scandir("/opt/data/security-server", &mydirent, &dir_filter, alphasort);
+    i = ret;
+    while((i--))
+    {
+        free(mydirent[i]);
+    }
+    free(mydirent);
+    RUNNER_ASSERT( ret == 50 || ret == 51);
+}
+
+RUNNER_TEST(tc_security_server_chk_pwd_incorrect_with_replay_attack)
+{
+    int ret = security_server_chk_pwd("quickquickquick", &attempt, &max_attempt, &expire_sec);
+    do
+    {
+        i =  i + 100000;
+        ret = security_server_chk_pwd("quickquickquick", &attempt, &max_attempt, &expire_sec);
+        usleep(i);
+    }
+    while(ret == SECURITY_SERVER_API_ERROR_PASSWORD_RETRY_TIMER);
+
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH);
+    i = i - 100000;
+    LOGD("Last interval was %d.%06d sec.\n", (i /1000000), (i % 1000000) );
+}
+
+RUNNER_TEST(tc_security_server_chk_pwd_wrong_challenge_on_expired_password)
+{
+    sleep(2);
+    int ret = security_server_set_pwd("history60", "newpwd23", 4, 1);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+    sleep(2);
+    ret = security_server_chk_pwd("newpwd23", &attempt, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+    ret = gettimeofday(&cur_time, NULL);
+    RUNNER_ASSERT(ret >= 0);
+    cur_time.tv_sec += (expire_sec + 1);
+    ret = settimeofday(&cur_time, NULL);
+    RUNNER_ASSERT(ret >= 0);
+    sleep(2);
+    ret = security_server_chk_pwd("newpwd23", &attempt, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_EXPIRED);
+    sleep(2);
+    ret = security_server_chk_pwd("newpwd23_invalid", &attempt, &max_attempt, &expire_sec);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_PASSWORD_MISMATCH);
+}
+
+int main(int argc, char *argv[])
+{
+    int argcc = 3;
+    char a[7] = {'1','2','3','4','5','6',0};
+    char * argvtmp[] = {argv[0], a, "abcdef"};
+    argvv = argvtmp;
+
+    int status =
+        DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+
+    return status;
+}
diff --git a/tests/security-server-tests/security_server_tests_pid_reuser.cpp b/tests/security-server-tests/security_server_tests_pid_reuser.cpp
new file mode 100644 (file)
index 0000000..e22a87a
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ */
+/*
+ * @file    security_server_tests_pid_reuser.cpp
+ * @author  Bumjin Im (bj.im@samsung.com)
+ * @author  Mariusz Domanski (m.domanski@samsung.com)
+ * @version 1.0
+ * @brief   Test cases for security server
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include "security-server.h"
+#include <dpl/test/test_runner.h>
+#include <dlog.h>
+#include "test.h"
+
+unsigned int target_pid, target_uid;
+unsigned char *prev_cookie, *new_cookie;
+int cookie_size;
+
+/* deprecated info for old c-style binary
+ * still useful for understanding the test itself
+ *
+ * Usage:
+ * cmd uid pid hexa_decimal_cookie
+ * pid: PID want to be reused
+ * hexa_decimal_cookie: Cookie value which is issued to the previous process
+ *                      with the [pid] for comparison\nThe cookie must be hexa
+ *                      decimal, with lower case and without whitespace and
+ *                      new line characters
+ * This test program must be executed as root process
+ */
+
+void convert_prev_cookie(const char *cmdline, const char *prev, unsigned char *now)
+{
+    int i, cnt;
+    char tmphexnum[3] = {0};
+    cnt = security_server_get_cookie_size();
+    cnt = cnt * 2;
+    if(strlen(prev) != cnt)
+    {
+        printf("%s\n", "Cookie length is wrong");
+        exit(1);
+    }
+
+    for(i=0, cnt=0 ; i<strlen(prev) ; i=i+2)
+    {
+        strncpy(tmphexnum, prev+i, 2);
+        tmphexnum[2] = 0;
+        errno = 0;
+        now[cnt] = strtoul(tmphexnum, 0, 16);
+        if(errno != 0)
+        {
+            printf("%s\n", "cannot convert hex cookie to binary");
+            exit(1);
+        }
+        cnt++;
+    }
+}
+
+void check_status()
+{
+    struct stat statbuf;
+    int ret;
+    ret = stat("/opt/home/root/pid_cycle", &statbuf);
+    if(ret != 0)
+    {
+        printf("Interrupt encountered. exiting...\n");
+        exit(0);
+    }
+
+}
+
+void cycle_pid(int pid)
+{
+    int cur_pid = getpid();
+    int dotval;
+
+    while(cur_pid != pid)
+    {
+        if(fork() != 0)
+        {
+            dotval = cur_pid % 1000;
+            if(dotval == 0)
+                LOGD(".");
+            exit(0);
+        }
+        cur_pid = getpid();
+        check_status();
+    }
+}
+
+RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_PID);
+
+RUNNER_TEST(tc_security_server_request_cookie)
+{
+    RUNNER_IGNORED_MSG("needs FIX, check FIXME comment");
+    LOGD("Cycling PID to %d\n", target_pid);
+    cycle_pid(target_pid);
+    unlink("/opt/home/root/pid_cycle");
+    RUNNER_ASSERT(security_server_request_cookie((char *)new_cookie, 20) == SECURITY_SERVER_API_SUCCESS);
+    LOGD("\nTarget PID: %d, Target UID: %d\n", target_pid, target_uid);
+    LOGD("Previous cookie:\n");
+    printhex(prev_cookie, 20);
+    LOGD("Newly issued cookie:\n");
+    printhex(new_cookie, 20);
+    RUNNER_ASSERT_MSG(memcmp(prev_cookie, new_cookie, cookie_size) != 0, "cookies are the same");
+}
+
+int main(int argc, char *argv[])
+{
+    /* FIXME: proper parameters needed (these below are fake)
+     *        or better idea for this test case...*/
+    char *argvv[] = {argv[0], "12345", "5000" , "abcdefabcdefabcdefabcdefabcdefabcdefabcd"};
+    int argcc = 4;
+
+    target_uid = getuid();
+    if(target_uid != 0)
+    {
+        printf("Error: %s must be executed by root\n", argv[0]);
+        exit(1);
+    }
+
+    cookie_size = security_server_get_cookie_size();
+    unsigned char prev_cookie_tmp[cookie_size], new_cookie_tmp[cookie_size];
+    prev_cookie = prev_cookie_tmp;
+    new_cookie = new_cookie_tmp;
+
+    errno = 0;
+    target_uid = strtoul(argvv[1], 0, 10);
+    if(errno != 0)
+    {
+        printf("%s\n", "cannot convert string uid to integer");
+        exit(1);
+    }
+    LOGD("Target UID is %d. change user...\n", target_uid);
+    setuid(target_uid);
+
+    errno = 0;
+    target_pid = strtoul(argvv[2], 0, 10);
+    if(errno != 0)
+    {
+        printf("%s\n", "cannot convert string pid to integer");
+        exit(1);
+    }
+    convert_prev_cookie(argvv[0], argvv[3], prev_cookie);
+    check_status();
+
+    int status =
+        DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+
+    return status;
+}
diff --git a/tests/security-server-tests/security_server_tests_server.cpp b/tests/security-server-tests/security_server_tests_server.cpp
new file mode 100644 (file)
index 0000000..b82fd49
--- /dev/null
@@ -0,0 +1,644 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ */
+/*
+ * @file    security_server_tests_server.cpp
+ * @author  Bumjin Im (bj.im@samsung.com)
+ * @author  Mariusz Domanski (m.domanski@samsung.com)
+ * @version 1.0
+ * @brief   Test cases for security server
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <fcntl.h>
+#include <sys/un.h>
+#include <unistd.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include "security-server.h"
+#include <dpl/test/test_runner.h>
+#include <dlog.h>
+#include "test.h"
+
+#define SECURITY_SERVER_SOCK_PATH    "/tmp/.security_server.sock"
+
+/* Message */
+typedef struct
+{
+    unsigned char version;
+    unsigned char msg_id;
+    unsigned short msg_len;
+} basic_header;
+
+typedef struct
+{
+    basic_header basic_hdr;
+    unsigned char return_code;
+} response_header;
+
+int server_sockfd, client_sockfd, ret, recved_gid, client_len, i;
+unsigned char cookie[20], recved_cookie[20], recvbuf[33], wrong_cookie[20];
+char obj_name[30];
+struct pollfd accept_poll[1], client_poll[1];
+struct sockaddr_un clientaddr;
+int olen, alen;
+char olabel[1024];
+char arights[32];
+
+/* Create a Unix domain socket and bind */
+int create_new_socket()
+{
+    int localsockfd = 0, flags;
+    int tmp;
+    struct sockaddr_un serveraddr;
+    mode_t sock_mode;
+
+    tmp = remove(SECURITY_SERVER_TEST_SOCK_PATH);
+
+    if (tmp == -1) {
+        localsockfd = -1;
+        LOGE("%s\n", "Unable to remove /tmp/.security_server.sock");
+        goto error;
+    }
+
+    /* Create Unix domain socket */
+    if((localsockfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0 )
+    {
+        localsockfd = -1;
+        LOGE("%s\n", "Socket creation failed");
+        goto error;
+    }
+
+    /* Make socket as non blocking */
+    if((flags = fcntl(localsockfd, F_GETFL, 0)) < 0 ||
+            fcntl(localsockfd, F_SETFL, flags | O_NONBLOCK) < 0)
+    {
+        close(localsockfd);
+        localsockfd = -1;
+        LOGE("%s\n", "Cannot go to nonblocking mode");
+        goto error;
+    }
+
+    bzero (&serveraddr, sizeof(serveraddr));
+    serveraddr.sun_family = AF_UNIX;
+    strncpy(serveraddr.sun_path, SECURITY_SERVER_TEST_SOCK_PATH,
+            strlen(SECURITY_SERVER_TEST_SOCK_PATH) + 1);
+
+    /* Bind the socket */
+    if((bind(localsockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr))) < 0)
+    {
+        LOGE("%s\n", "Cannot bind");
+        close(localsockfd);
+        localsockfd = -1;
+        goto error;
+    }
+
+    /* Change permission to accept all processes that has different uID/gID */
+    sock_mode = (S_IRWXU | S_IRWXG | S_IRWXO);
+    /* Flawfinder hits this chmod function as level 5 CRITICAL as race condition flaw *
+    * Flawfinder recommends to user fchmod insted of chmod
+    * But, fchmod doesn't work on socket file so there is no other choice at this point */
+    if(chmod(SECURITY_SERVER_TEST_SOCK_PATH, sock_mode) < 0)        /* Flawfinder: ignore */
+    {
+        LOGE("%s\n", "chmod() error");
+        close(localsockfd);
+        localsockfd = -1;
+        goto error;
+    }
+error:
+    return localsockfd;
+}
+
+int check_socket_poll(int sockfd, int event, int timeout)
+{
+    struct pollfd poll_fd[1];
+    int retval;
+
+    poll_fd[0].fd = sockfd;
+    poll_fd[0].events = event;
+    retval = poll(poll_fd, 1, timeout);
+    if(retval < 0)
+    {
+        LOGE("%s\n", "poll() error");
+        return -1;
+    }
+
+    /* Timed out */
+    if(retval == 0)
+    {
+        LOGE("%s", "poll() timeout");
+        return 0;
+    }
+    return 1;
+}
+
+int send_gid_request(int sock_fd, const char* object)
+{
+    basic_header hdr;
+    int retval, send_len = 0;
+    unsigned char *buf = NULL;
+
+    hdr.version = 0x01; /* SECURITY_SERVER_MSG_VERSION; */
+    hdr.msg_id = 0x07; /* SECURITY_SERVER_MSG_TYPE_GID_REQUEST; */
+    hdr.msg_len = strlen(object);
+
+    send_len = sizeof(hdr) + strlen(object);
+
+    buf = (unsigned char *) malloc(send_len);
+    if(buf == NULL)
+    {
+        LOGE("%s\n", "out of memory");
+        return -1;
+    }
+
+    memcpy(buf, &hdr, sizeof(hdr));
+    memcpy(buf + sizeof(hdr), object, strlen(object));
+
+    /* Check poll */
+    retval = check_socket_poll(sock_fd, POLLOUT, 1000);
+    if(retval == -1)
+    {
+        LOGE("%s\n", "poll() error");
+        if(buf != NULL)
+            free(buf);
+        return -1;
+    }
+    if(retval == 0)
+    {
+        LOGE("%s\n", "poll() timeout");
+        if(buf != NULL)
+            free(buf);
+        return -1;
+    }
+
+    retval = write(sock_fd, buf, send_len);
+    if(retval < send_len)
+    {
+        /* Write error */
+        LOGE("Error on write(): %d. errno=%d, sockfd=%d\n", retval, errno, sock_fd);
+        if(buf != NULL)
+            free(buf);
+        return -1;
+    }
+    if(buf != NULL)
+        free(buf);
+
+    return 0;
+}
+
+int connect_to_server(int *fd)
+{
+    struct sockaddr_un clientaddr;
+    int client_len = 0, localsockfd, ret, flags;
+    *fd = -1;
+
+    /* Create a socket */
+    localsockfd = socket(AF_UNIX, SOCK_STREAM, 0);
+    if(localsockfd < 0)
+    {
+        LOGE("%s\n", "Error on socket()");
+        return -1;
+    }
+
+    /* Make socket as non blocking */
+    if((flags = fcntl(localsockfd, F_GETFL, 0)) < 0 ||
+            fcntl(localsockfd, F_SETFL, flags | O_NONBLOCK) < 0)
+    {
+        close(localsockfd);
+        LOGE("%s\n", "Cannot go to nonblocking mode");
+        return -1;
+    }
+
+    bzero(&clientaddr, sizeof(clientaddr));
+    clientaddr.sun_family = AF_UNIX;
+    strncpy(clientaddr.sun_path, SECURITY_SERVER_SOCK_PATH, strlen(SECURITY_SERVER_SOCK_PATH));
+    clientaddr.sun_path[strlen(SECURITY_SERVER_SOCK_PATH)] = 0;
+    client_len = sizeof(clientaddr);
+
+    ret = connect(localsockfd, (struct sockaddr*)&clientaddr, client_len);
+    if( ret < 0)
+    {
+        if(errno == EINPROGRESS)
+        {
+            LOGD("%s\n", "Connection is in progress");
+            check_socket_poll(localsockfd, POLLOUT, 1000);
+            if(ret == -1)
+            {
+                LOGE("%s\n", "poll() error");
+                close(localsockfd);
+                return -1;
+            }
+            ret = connect(localsockfd, (struct sockaddr*)&clientaddr, client_len);
+            if(ret < 0)
+            {
+                LOGE("%s\n", "connection failed");
+                close(localsockfd);
+                return -1;
+            }
+        }
+        else
+        {
+            LOGE("%s\n", "Connection failed");
+            close(localsockfd);
+            return -1;
+        }
+    }
+
+    *fd = localsockfd;
+    return 0;
+}
+
+
+int fake_get_gid(const char *object)
+{
+    int sockfd = -1, retval, gid;
+    response_header hdr;
+
+    retval = connect_to_server(&sockfd);
+    if(retval != 0)
+    {
+        /* Error on socket */
+        LOGE("Connection failed: %d\n", retval);
+        goto error;
+    }
+
+    /* make request packet and send to server*/
+    retval = send_gid_request(sockfd, object);
+    if(retval != 0)
+    {
+        /* Error on socket */
+        LOGE("Send request failed: %d\n", retval);
+        goto error;
+    }
+    LOGD("%s", "Just closing the socket and exit\n");
+
+error:
+    if(sockfd > 0)
+        close(sockfd);
+
+    return 0;
+}
+
+RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_SERVER);
+
+RUNNER_TEST(tc_getting_default_cookie)
+{
+    printhex(cookie, 20);
+    RUNNER_ASSERT(security_server_request_cookie((char *)cookie, 20) == SECURITY_SERVER_API_SUCCESS);
+}
+
+RUNNER_TEST(tc_security_server_get_gid_normal_case_trying_to_get_gid_of_tel_gprs)
+{
+    RUNNER_ASSERT(security_server_get_gid("tel_gprs") >= 0);
+}
+
+RUNNER_TEST(tc_security_server_get_gid_empty_object_name)
+{
+    RUNNER_ASSERT(security_server_get_gid("") == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
+}
+
+RUNNER_TEST(tc_security_server_get_gid_wrong_object_name_teltel)
+{
+    RUNNER_ASSERT(security_server_get_gid("teltel") == SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT);
+}
+
+RUNNER_TEST(tc_security_server_get_object_name_normal_case_trying_6001)
+{
+    ret = security_server_get_object_name(6001, obj_name, sizeof(obj_name));
+    LOGD("Result: %s\n", obj_name);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+}
+
+RUNNER_TEST(tc_security_server_get_object_name_too_small_buffer_size)
+{
+    ret = security_server_get_object_name(6001, obj_name, 5);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_BUFFER_TOO_SMALL);
+}
+
+RUNNER_TEST(tc_security_server_get_object_name_invalid_gid)
+{
+    ret = security_server_get_object_name(9876, obj_name, sizeof(obj_name));
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT);
+}
+
+RUNNER_TEST(tc_ask_for_priviege_with_default_cookie_normal_case_to_check_audio_privilege)
+{
+    ret = security_server_get_gid("audio");
+    ret = security_server_check_privilege((char *) cookie, ret);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS);
+}
+
+RUNNER_TEST(tc_ask_for_priviege_with_default_cookie_case_with_wrong_cookie)
+{
+    ret = security_server_get_gid("audio");
+    srand(time(NULL));
+    for(i=0;i<20;i++)
+        wrong_cookie[i] = rand() % 255;
+    ret = security_server_check_privilege((const char *) wrong_cookie, ret);
+    RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED);
+}
+
+RUNNER_TEST(tc_fake_security_server_get_gid)
+{
+    /* Close socket just after sending request msg.
+     * This is done with fake security_server_get_gid()*/
+    ret = fake_get_gid("audio");
+    RUNNER_IGNORED_MSG("Watch whether security server has crashed or not.");
+}
+
+RUNNER_TEST(tc_get_pid_of_a_given_cookie_default_cookie_case)
+{
+    RUNNER_ASSERT(security_server_get_cookie_pid((const char *) cookie) == 0);
+}
+
+RUNNER_TEST(tc_get_pid_of_non_existing_cookie)
+{
+    RUNNER_ASSERT(security_server_get_cookie_pid((const char *) wrong_cookie)== SECURITY_SERVER_API_ERROR_NO_SUCH_COOKIE);
+}
+
+RUNNER_TEST(tc_get_pid_of_null_cookie)
+{
+    RUNNER_ASSERT(security_server_get_cookie_pid(NULL) == SECURITY_SERVER_API_ERROR_INPUT_PARAM);
+}
+
+RUNNER_TEST(tc_communicating_with_client_and_test_cookie_and_privilege_control)
+{
+    server_sockfd = create_new_socket();
+    RUNNER_ASSERT_MSG(server_sockfd >= 1,"Error on creating a new socket");
+    RUNNER_ASSERT_MSG(listen(server_sockfd, 5) >= 0, "listen() failed");
+
+    while(1)
+    {
+        accept_poll[0].fd = server_sockfd;
+        accept_poll[0].events = POLLIN;
+        ret = poll(accept_poll, 1, 5000);
+
+        /* Call poll() to wait for socket connection */
+        ret = poll(accept_poll, 1, 5000);
+        RUNNER_ASSERT(ret > 0);
+        if(ret == 0)
+        {
+            continue;
+        }
+
+        errno = 0;
+        client_len = sizeof(clientaddr);
+        client_sockfd = accept(server_sockfd, (struct sockaddr *)&clientaddr,
+                (socklen_t *) &client_len);
+        RUNNER_ASSERT_MSG(client_sockfd >= 0, "Cannot accept client");
+
+        LOGD("New session accepted\n");
+
+        /* Wait until packet received */
+        client_poll[0].fd = client_sockfd;
+        client_poll[0].events = POLLIN;
+
+        /* Poll here */
+        ret = poll(client_poll, 1, 500);
+        RUNNER_ASSERT(ret > 0); /* poll() error */
+        if(ret == 0)
+        {
+            close(client_sockfd);
+            client_sockfd = 0;
+            LOGD("%s\n", "No request from client. closing socket");
+            continue;
+        }
+
+        ret = read(client_sockfd, recvbuf, 4);
+        if(recvbuf[0] == 0 && recvbuf[1] == 0 && recvbuf[2] == 0 && recvbuf[3] == 0)
+        {
+            ret = read(client_sockfd, recvbuf, 24);
+            if(ret < 24)
+            {
+                close(client_sockfd);
+                LOGD("cannot read request:%d\n", ret);
+                close(client_sockfd);
+                continue;
+            }
+
+            memcpy(recved_cookie, recvbuf, 20);
+            memcpy(&recved_gid, recvbuf+20, sizeof(int));
+
+            LOGD("requested cookie: \n");
+            printhex(recved_cookie, 20);
+            LOGD("requested gid: %d\n", recved_gid);
+
+            ret = security_server_check_privilege((const char *) recved_cookie, recved_gid);
+            RUNNER_ASSERT(ret == SECURITY_SERVER_API_SUCCESS ||
+                    ret == SECURITY_SERVER_API_ERROR_ACCESS_DENIED); /* Unexpected error occurred */
+
+            LOGD("Privilege for the request: %d\n", ret);
+
+            RUNNER_ASSERT(write(client_sockfd, &ret, sizeof(int)) >= sizeof(int)); /* Send error */
+
+            ret = security_server_get_cookie_pid((const char *) recved_cookie);
+            RUNNER_ASSERT(ret > 0); /* Unexpected error occurred */
+            if(ret == 0)
+            {
+                LOGD("client is root process\n");
+            }
+            else
+            {
+                LOGD("Peer PID is %d\n", ret);
+            }
+        }
+        else if(recvbuf[0] == 255 && recvbuf[1] == 255 && recvbuf[2] == 255 && recvbuf[3] == 255)
+        {
+            char *myargv[5] = {NULL};
+            int i, cnt;
+            ret = read(client_sockfd, recvbuf, 28);
+            if(ret < 28)
+            {
+                close(client_sockfd);
+                LOGD("cannot read request:%d\n", ret);
+                close(client_sockfd);
+                continue;
+            }
+
+            memcpy(recved_cookie, recvbuf, 20);
+            memcpy(&recved_gid, recvbuf + 20, sizeof(int));
+            memcpy(&cnt, recvbuf + 24, sizeof(int));
+
+            if(fork() == 0)
+            {
+                myargv[0] = (char *) malloc(strlen("/opt/home/root/security_server_tc_pid_reuser") + 1);
+                sprintf(myargv[0], "/opt/home/root/security_server_tc_pid_reuser");
+                myargv[1] = (char *) malloc(6);
+                sprintf(myargv[1], "%d", cnt);
+                myargv[2] = (char *) malloc(6);
+                sprintf(myargv[2], "%d", recved_gid);
+                myargv[3] = (char *) malloc(40);
+                myargv[4] = NULL;
+                for(i=0, cnt=0;i<20;i++)
+                {
+                    if(recved_cookie[i] < 0x10)
+                        sprintf(myargv[3] + cnt, "0%x", recved_cookie[i]);
+                    else
+                        sprintf(myargv[3] + cnt, "%x", recved_cookie[i]);
+                    cnt += 2;
+                }
+                LOGD("argv[0]=%s, argv[1]=%s, argv[2]=%s, argv[3]=%s\n", myargv[0], myargv[1], myargv[2], myargv[3]);
+                ret = execve("/opt/home/root/security_server_tc_pid_reuser", myargv, NULL);
+                LOGD("execve failed. errno=%d\n", errno);
+
+                if(myargv[0] != NULL)
+                    free(myargv[0]);
+                if(myargv[1] != NULL)
+                    free(myargv[1]);
+                if(myargv[2] != NULL)
+                    free(myargv[2]);
+                if(myargv[3] != NULL)
+                    free(myargv[3]);
+            }
+        }
+        else if(recvbuf[0] == 17 )
+        {
+            if (recvbuf[3] == 0)
+            {
+                ret = read(client_sockfd, recvbuf, 20);
+                if(ret < 20)
+                {
+                    close(client_sockfd);
+                    LOGD("cannot read request:%d\n", ret);
+                    close(client_sockfd);
+                    continue;
+                }
+                memcpy(recved_cookie, recvbuf, 20);
+                ret = read(client_sockfd, &olen, 4);
+                if(ret < 4)
+                {
+                    close(client_sockfd);
+                    LOGD("cannot read request:%d\n", ret);
+                    close(client_sockfd);
+                    continue;
+                }
+                ret = read(client_sockfd, &alen, 4);
+                if(ret < 4)
+                {
+                    close(client_sockfd);
+                    LOGD("cannot read request:%d\n", ret);
+                    close(client_sockfd);
+                    continue;
+                }
+                ret = read(client_sockfd, olabel, olen);
+                if(ret < olen)
+                {
+                    close(client_sockfd);
+                    LOGD("cannot read request:%d\n", ret);
+                    close(client_sockfd);
+                    continue;
+                }
+                olabel[olen] = '\0';
+                ret = read(client_sockfd, arights, alen);
+                if(ret < alen)
+                {
+                    close(client_sockfd);
+                    LOGD("cannot read request:%d\n", ret);
+                    close(client_sockfd);
+                    continue;
+                }
+                arights[alen] = '\0';
+                LOGD("Check by cookie requested.\n");
+                LOGD("requested cookie: \n");
+                printhex(recved_cookie, 20);
+                LOGD("olen: %d\n", olen);
+                LOGD("object label: >%s<\n", olabel);
+                LOGD("alen: %d\n", alen);
+                LOGD("access rights: >%s<\n", arights);
+
+                ret = security_server_check_privilege_by_cookie(
+                        (const char *) recved_cookie, olabel, arights);
+
+                LOGD("return: %d\n", ret);
+
+                RUNNER_ASSERT(write(client_sockfd, &ret, sizeof(int)) >= sizeof(int));
+            }
+            else if (recvbuf[3] == 1)
+            {
+                ret = read(client_sockfd, &olen, 4);
+                if(ret < 4)
+                {
+                    close(client_sockfd);
+                    LOGD("cannot read request:%d\n", ret);
+                    close(client_sockfd);
+                    continue;
+                }
+                ret = read(client_sockfd, &alen, 4);
+                if(ret < 4)
+                {
+                    close(client_sockfd);
+                    LOGD("cannot read request:%d\n", ret);
+                    close(client_sockfd);
+                    continue;
+                }
+                ret = read(client_sockfd, olabel, olen);
+                if(ret < olen)
+                {
+                    close(client_sockfd);
+                    LOGD("cannot read request:%d\n", ret);
+                    close(client_sockfd);
+                    continue;
+                }
+                olabel[olen] = '\0';
+                ret = read(client_sockfd, arights, alen);
+                if(ret < alen)
+                {
+                    close(client_sockfd);
+                    LOGD("cannot read request:%d\n", ret);
+                    close(client_sockfd);
+                    continue;
+                }
+                arights[alen] = '\0';
+                LOGD("Check by sockfd requested.\n");
+                LOGD("olen: %d\n", olen);
+                LOGD("object label: >%s<\n", olabel);
+                LOGD("alen: %d\n", alen);
+                LOGD("access rights: >%s<\n", arights);
+
+                ret = security_server_check_privilege_by_sockfd(
+                        client_sockfd, olabel, arights);
+
+                RUNNER_ASSERT(write(client_sockfd, &ret, sizeof(int)) >= sizeof(int));
+            } else {
+                LOGE("malformed request. %d, %d, %d, %d\n", recvbuf[0], recvbuf[1],  recvbuf[2], recvbuf[3]);
+                RUNNER_ASSERT_MSG(false, "malformed request");
+            }
+        }
+        else
+        {
+            LOGE("malformed request. %d, %d, %d, %d\n", recvbuf[0], recvbuf[1], recvbuf[2], recvbuf[3]);
+            RUNNER_ASSERT_MSG(false, "malfiormed request");
+        }
+        if(client_sockfd > 0)
+        {
+            close(client_sockfd);
+        }
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    server_sockfd = -1;
+
+    ret = getuid();
+    if(ret != 0)
+    {
+        printf("Error: %s must be executed by root\n", argv[0]);
+        exit(1);
+    }
+
+    int status =
+        DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
+
+    if(server_sockfd > 0)
+        close(server_sockfd);
+    if(client_sockfd > 0)
+        close(client_sockfd);
+
+    return status;
+}
diff --git a/tests/security-server-tests/test.h b/tests/security-server-tests/test.h
new file mode 100644 (file)
index 0000000..0b0f625
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd All Rights Reserved
+ */
+/*
+ * @file    test.h
+ * @author  Bumjin Im (bj.im@samsung.com)
+ * @author  Mariusz Domanski (m.domanski@samsung.com)
+ * @version 1.0
+ * @brief   Test cases for security server
+ */
+
+#ifndef SECURITY_SERVER_TESTS_TEST_H
+#define    SECURITY_SERVER_TESTS_TEST_H
+
+#include <dlog.h>
+#include <sstream>
+#include <iomanip>
+
+#define SECURITY_SERVER_TEST_SOCK_PATH "/tmp/.security-server-test"
+
+#ifdef LOG_TAG
+    #undef LOG_TAG
+#endif // LOG_TAG
+#ifndef LOG_TAG
+    #define LOG_TAG "SEC_SRV_TESTS"
+#endif // LOG_TAG
+
+void printhex(unsigned char *data, int size)
+{
+    int i;
+    std::ostringstream msg;
+    msg << std::hex << std::setfill('0') << std::uppercase;
+    for(i=0;i<size;i++)
+    {
+        msg << std::setw(2) << static_cast<int>(data[i]) << " ";
+        if(((i+1) % 16) == 0 && i != 0)
+            msg << std::endl;
+    }
+    msg << std::endl;
+    LOGD("%s", msg.str().c_str());
+}
+
+#endif // SECURITY_SERVER_TESTS_TEST_H