From 8f932a5ae7b9b5589f03c2e5a1c60c2cafb7912b Mon Sep 17 00:00:00 2001 From: Mariusz Domanski Date: Wed, 23 Jan 2013 10:41:37 +0100 Subject: [PATCH] security-server tests on DPL framework 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 | 8 + tests/CMakeLists.txt | 1 + tests/security-server-tests/CMakeLists.txt | 107 ++++ .../security_server_tests_client.cpp | 169 ++++++ .../security_server_tests_client.h | 308 ++++++++++ .../security_server_tests_client_smack.cpp | 178 ++++++ .../security_server_tests_label.cpp | 113 ++++ .../security_server_tests_password.cpp | 376 ++++++++++++ .../security_server_tests_pid_reuser.cpp | 160 +++++ .../security_server_tests_server.cpp | 644 +++++++++++++++++++++ tests/security-server-tests/test.h | 43 ++ 11 files changed, 2107 insertions(+) create mode 100644 tests/security-server-tests/CMakeLists.txt create mode 100644 tests/security-server-tests/security_server_tests_client.cpp create mode 100644 tests/security-server-tests/security_server_tests_client.h create mode 100644 tests/security-server-tests/security_server_tests_client_smack.cpp create mode 100644 tests/security-server-tests/security_server_tests_label.cpp create mode 100644 tests/security-server-tests/security_server_tests_password.cpp create mode 100644 tests/security-server-tests/security_server_tests_pid_reuser.cpp create mode 100644 tests/security-server-tests/security_server_tests_server.cpp create mode 100644 tests/security-server-tests/test.h diff --git a/packaging/security-tests.spec b/packaging/security-tests.spec index fb99191..ee4f687 100644 --- a/packaging/security-tests.spec +++ b/packaging/security-tests.spec @@ -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 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 01f9a38..9ab6aaf 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -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 index 0000000..0641d09 --- /dev/null +++ b/tests/security-server-tests/CMakeLists.txt @@ -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 index 0000000..5a89ea0 --- /dev/null +++ b/tests/security-server-tests/security_server_tests_client.cpp @@ -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 +#include +#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 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 index 0000000..344a6a7 --- /dev/null +++ b/tests/security-server-tests/security_server_tests_client.h @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include "security-server.h" +#include +#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 +#include +#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 index 0000000..a1025de --- /dev/null +++ b/tests/security-server-tests/security_server_tests_label.cpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#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 index 0000000..668b2a6 --- /dev/null +++ b/tests/security-server-tests/security_server_tests_password.cpp @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "security-server.h" +#include +#include +#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 index 0000000..e22a87a --- /dev/null +++ b/tests/security-server-tests/security_server_tests_pid_reuser.cpp @@ -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 +#include +#include +#include +#include +#include +#include +#include "security-server.h" +#include +#include +#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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "security-server.h" +#include +#include +#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 index 0000000..0b0f625 --- /dev/null +++ b/tests/security-server-tests/test.h @@ -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 +#include +#include + +#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(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 -- 2.7.4