From: Lukasz Kostyra Date: Tue, 13 Aug 2013 06:06:07 +0000 (+0200) Subject: Add security-server tests for NOSMACK environment. X-Git-Tag: security-manager_5.5_testing~360 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5d4fb9d96c03bdfa4be2da1ee29e5d5abce0b5d7;p=platform%2Fcore%2Ftest%2Fsecurity-tests.git Add security-server tests for NOSMACK environment. [Issue#] SSDWSSP-417 [Feature] Add new security-server tests that test security-server behaviour on NOSMACK environment. [Cause] When previous tests were launched on NOSMACK environment they returned false errors because the system behaved differently with SMACK turned off. [Solution] Creating new tests that would expect different behaviour from security-server. [Verification] After successful compilation launch security-server tests on NOSMACK environment. Tests that previously failed and were turned off in one of my previous commits should appear with "_nosmack" ending in name. Change-Id: I8c03ed8d97ff970f684466f6927a6e01f0c43d46 --- diff --git a/tests/security-server-tests/security_server_tests_client_smack.cpp b/tests/security-server-tests/security_server_tests_client_smack.cpp index 940d1f7..b383ec0 100644 --- a/tests/security-server-tests/security_server_tests_client_smack.cpp +++ b/tests/security-server-tests/security_server_tests_client_smack.cpp @@ -14,6 +14,12 @@ #include #include #include +#include +#include +#include + +#include +#include #include #include @@ -37,6 +43,32 @@ "Cannot prepare environment for test"); \ } while (0) + +/** + * Environment preparation should only differ in setting label. On NOSMACK system + * smack_set_label_for_self returns error because of no access to /proc/self/attr/current. + */ +#define ENVIRONMENT_NOSMACK \ + do { \ + int fd = open("/opt/home/root/pid_cycle", O_CREAT|O_APPEND, 0444);\ + RUNNER_ASSERT_MSG(fd >= 0, \ + "Couldn't create pid_cycle file. errno: " << strerror(errno));\ + close(fd); \ + RUNNER_ASSERT_MSG(-1 != setgid(1), \ + "Cannot prepare environment for test."); \ + RUNNER_ASSERT_MSG(-1 != setuid(1), \ + "Cannot prepare environment for test"); \ + } while (0) + +/** + * Unique_ptr typedef for NOSMACK version of tc06 test + */ +void closesockfdptr(int* sockfd_ptr) +{ + close(*sockfd_ptr); +} +typedef std::unique_ptr > SockFDUniquePtr; + /** * Dropping root privileges * returns 0 on success, 1 on error @@ -386,6 +418,266 @@ RUNNER_TEST_SMACK(tc07_check_privilege_by_sockfd) RUNNER_ASSERT_MSG(SECURITY_SERVER_API_ERROR_ACCESS_DENIED == result2, " result2 = " << result2); } +/////////////////////////// +/////NOSMACK ENV TESTS///// +/////////////////////////// + +/** + * First four test cases are the same as their SMACK versions. The only difference is environment + * preparation (described near ENVIRONMENT_NOSMACK macro). + */ +RUNNER_CHILD_TEST_NOSMACK(tc01_security_server_get_cookie_size_nosmack) +{ + ENVIRONMENT_NOSMACK; + + int ret = security_server_get_cookie_size(); + RUNNER_ASSERT_MSG(ret == 20, "ret = " << ret); +} + +RUNNER_CHILD_TEST_NOSMACK(tc02_security_server_request_cookie_normal_case_nosmack) +{ + ENVIRONMENT_NOSMACK; + + char cookie[20]; + int ret = security_server_request_cookie(cookie, 20); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, "ret = " << ret); +} + +RUNNER_CHILD_TEST_NOSMACK(tc03_security_server_request_cookie_too_small_buffer_size_nosmack) +{ + ENVIRONMENT_NOSMACK; + + char cookie[20]; + int ret = security_server_request_cookie(cookie, 10); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_ERROR_BUFFER_TOO_SMALL, "ret = " << ret); +} + +RUNNER_CHILD_TEST_NOSMACK(tc04_security_server_get_gid_nosmack) +{ + ENVIRONMENT_NOSMACK; + + int ret = security_server_get_gid("definitely_not_existing_object"); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_ERROR_NO_SUCH_OBJECT, "ret = " << ret); + ret = security_server_get_gid("root"); + RUNNER_ASSERT_MSG(ret == 0, "ret = " << ret); +} + +/* + * NOSMACK version of tc05 test. + * + * Correct behaviour of smack_accesses_apply and smack_set_label_for_self was checked by libsmack + * tests. We assume, that those tests pass. Additionally security_server_check_privilege_by_cookie + * should return SUCCESS no matter what access_rights we give to this function. + */ +RUNNER_CHILD_TEST_NOSMACK(tc05_check_privilege_by_cookie_nosmack) +{ + char cookie[20]; + const char* object_label = "tc05objectlabel"; + + RUNNER_ASSERT(security_server_request_cookie(cookie,20) == SECURITY_SERVER_API_SUCCESS); + + RUNNER_ASSERT_MSG(drop_root_privileges() == 0, "uid = " << getuid()); + + RUNNER_ASSERT(SECURITY_SERVER_API_SUCCESS == + security_server_check_privilege_by_cookie(cookie, object_label, "r")); + + //On NOSMACK env security server should return success on any accesses, even those that are + //incorrect. + RUNNER_ASSERT(SECURITY_SERVER_API_SUCCESS == + security_server_check_privilege_by_cookie(cookie, object_label, "rw")); +} + +/** + * NOSMACK version of tc06 test. + * + * Differences between this and SMACK version (server): + * - Skipped setting access_rights + * - Skipped setting label for server + * - get_smacklabel_sockfd is called only once for server, almost right after fork and creation + * of socket (because it should do nothing when SMACK is off) + * - After get_smacklabel_sockfd privileges are dropped and server is prepared to accept connections + * from client + * + * For client the only difference are expected results from check_privilege_by_sockfd - both should + * return SUCCESS. + */ +RUNNER_TEST_NOSMACK(tc06_check_privilege_by_sockfd_nosmack) +{ + const char* object_label = "tc06objectlabel"; + + int result1 = -1; + int result2 = -1; + + int pid = fork(); + char* label; + RUNNER_ASSERT(pid >= 0); + + if (pid == 0) { //child process - server + int ret; + //create new socket + int sockfd = create_new_socket(); + if(sockfd < 0) + exit(1); //failed to create server; return 1 + + SockFDUniquePtr sockfd_ptr(&sockfd, closesockfdptr); + + //check if get_smacklabel_sockfd works correctly + label = security_server_get_smacklabel_sockfd(sockfd); + if(label == NULL) + exit(2); //label is NULL, get_smacklabel_sockfd failed; return 2 + + ret = strcmp(label, ""); + free(label); + if(ret != 0) + exit(3); //label is not an empty string; return 3 + + ret = drop_root_privileges(); + if(ret != 0) + exit(4); //failed to drop root privileges; return 4 + + if (listen(sockfd, 5) < 0) + exit(5); //listen failed; return 5 + + struct sockaddr_un client_addr; + socklen_t client_len = sizeof(client_addr); + + int csockfd; + if((csockfd = accept(sockfd,(struct sockaddr*)&client_addr, &client_len)) <= 0) + exit(6); //accept failed; return 6 + + //wait a little bit for parent to do it's job + usleep(200); + + //if everything works, cleanup and return 0 + close(csockfd); + exit(0); + } else { + //parent + int ret; + sleep(1); + int sockfd = connect_to_testserver(); + RUNNER_ASSERT_MSG(sockfd >= 0, "Failed to connect to server."); + + SockFDUniquePtr sockfd_ptr(&sockfd, closesockfdptr); + + label = security_server_get_smacklabel_sockfd(sockfd); + RUNNER_ASSERT_MSG(label != NULL, "get_smacklabel_sockfd failed."); + + ret = strcmp(label, ""); + free(label); + RUNNER_ASSERT_MSG(ret == 0, "label is \"" << label << "\", should be empty"); + + result1 = security_server_check_privilege_by_sockfd(sockfd, object_label, "r"); + result2 = security_server_check_privilege_by_sockfd(sockfd, object_label, "rw"); + + kill(pid, SIGKILL); + } + + int status; + waitpid(pid, &status, 0); + + //check how our child process returned + switch(WEXITSTATUS(status)) + { + case 1: RUNNER_ASSERT_MSG(false, "Child failed to create server."); + case 2: RUNNER_ASSERT_MSG(false, "Child error - get_smacklabel_sockfd failed."); + case 3: RUNNER_ASSERT_MSG(false, "Child error - label is not an empty string."); + case 4: RUNNER_ASSERT_MSG(false, "Child failed to drop root privileges."); + case 5: RUNNER_ASSERT_MSG(false, "Child error - listen failed."); + case 6: RUNNER_ASSERT_MSG(false, "Child error - accept failed."); + default: ; + } + + RUNNER_ASSERT_MSG(result1 == SECURITY_SERVER_API_SUCCESS, "result = " << result1); + RUNNER_ASSERT_MSG(result2 == SECURITY_SERVER_API_SUCCESS, "result = " << result2); +} + +/** + * NOSMACK version of tc07 test. + */ +RUNNER_TEST_NOSMACK(tc07_check_privilege_by_sockfd_nosmack) +{ + const char* object_label = "tc07objectlabel"; + + int result1 = -1; + int result2 = -1; + + int pid = fork(); + RUNNER_ASSERT(-1 != pid); + + if (pid == 0) { //child process + int ret; + //Create socket + int sockfd = create_new_socket(); + if(sockfd < 0) + exit(1); //failed to create server, return 1 + + SockFDUniquePtr sockfd_ptr(&sockfd, closesockfdptr); + + //Drop privileges + ret = drop_root_privileges(); + if(ret != 0) + exit(2); //failed to drop root privileges; return 2 + + //Prepare for accepting + if (listen(sockfd, 5) < 0) + exit(3); //listen failed; return 3 + + struct sockaddr_un client_addr; + socklen_t client_len = sizeof(client_addr); + + //Accept connections + int csockfd; + if((csockfd = accept(sockfd,(struct sockaddr*)&client_addr, &client_len)) <= 0) + exit(4); //accept failed; return 4 + + //wait a little bit for parent to do it's job + usleep(200); + + //cleanup and kill child + close(csockfd); + exit(0); + } else { //parent process + //Drop root privileges + int ret = drop_root_privileges(); + RUNNER_ASSERT_MSG(ret == 0, + "Failed to drop root privileges. Result: " << ret << ", uid = " << getuid()); + + //Wait for server to set up + sleep(1); + + //Connect and check privileges + int sockfd = connect_to_testserver(); + RUNNER_ASSERT_MSG(sockfd >= 0, "Failed to create socket fd."); + + result1 = security_server_check_privilege_by_sockfd(sockfd, object_label, "r"); + result2 = security_server_check_privilege_by_sockfd(sockfd, object_label, "rw"); + + close(sockfd); + kill(pid, SIGKILL); + } + + int status; + waitpid(pid, &status, 0); + + switch(WEXITSTATUS(status)) + { + case 1: RUNNER_ASSERT_MSG(false, "Child failed to create server."); + case 2: RUNNER_ASSERT_MSG(false, "Child failed to drop root privileges."); + case 3: RUNNER_ASSERT_MSG(false, "Child failed to listen to sockfd."); + case 4: RUNNER_ASSERT_MSG(false, "Child failed to accept connection from server."); + default: ; + } + + //Both results (just like in the previous test case) should return success. + RUNNER_ASSERT_MSG(SECURITY_SERVER_API_SUCCESS == result1, "result1 = " << result1); + RUNNER_ASSERT_MSG(SECURITY_SERVER_API_SUCCESS == result2, "result2 = " << result2); +} + +//////////////////// +/////MAIN/////////// +//////////////////// + int main(int argc, char *argv[]) { return diff --git a/tests/security-server-tests/security_server_tests_dbus.cpp b/tests/security-server-tests/security_server_tests_dbus.cpp index 7c13abb..9ff3b75 100644 --- a/tests/security-server-tests/security_server_tests_dbus.cpp +++ b/tests/security-server-tests/security_server_tests_dbus.cpp @@ -209,6 +209,169 @@ RUNNER_TEST_SMACK(tc01_smack_context_from_DBus) } } +/////////////////////////////////////// +//////NOSMACK ENV TESTS//////////////// +/////////////////////////////////////// + +/** + * NOSMACK version of tc01 test. + * + * This is almost an exact copy of the original SMACK DBus test. As in previous security-server + * tests, parts where SMACK is used are skipped, because most important functions will return error. + */ +RUNNER_TEST_NOSMACK(tc01_smack_context_from_DBus_nosmack) +{ + int ret = -1; + const char* subject_parent = "subject_parent"; + + DBusMessage* msg = NULL; + DBusMessageIter args, iter, var, var_iter, var_value; + DBusConnection* conn = NULL; + DBusError err; + DBusPendingCall *pending = NULL; + const char *dbus_server_name = DBUS_SERVER_NAME; + char *smack_context = NULL; + int status; + + pid_t pid = fork(); + RUNNER_ASSERT_MSG(-1 != pid, "fork() failed"); + + if (pid == 0) { + // child + + // initialize the errors + dbus_error_init(&err); + + // connect to the system bus and check for errors; failure = exit with result 1 + conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + ret = dbus_error_is_set(&err); + if (1 == ret) { + dbus_error_free(&err); + exit(1); + } + + // request our name on the bus; failure = exit with result 2 + ret = dbus_bus_request_name(conn, DBUS_CALLER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err); + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { + dbus_error_free(&err); + exit(2); + } + + // crate a new method call for checking SMACK context from DBus interface + msg = dbus_message_new_method_call(DBUS_SMACK_NAME, + DBUS_SMACK_OBJECT, + DBUS_SMACK_INTERFACE, + DBUS_SMACK_METHOD); + + if(msg == NULL) + exit(3); //dbus_message_new_method_call failed; return 3 + + // append arguments, we need SMACK context for our parent process "test.method.server" + dbus_message_iter_init_append(msg, &args); + ret = dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &dbus_server_name); + if(ret != 1) + exit(4); //out of memory; return 4 + + // wait for parent to connect to DBus + sleep(3); + + // send message and get a handle for a reply + // -1 is default timeout + ret = dbus_connection_send_with_reply (conn, msg, &pending, -1); + if(ret != 1) + exit(4); //out of memory; return 4 + if(pending == NULL) + exit(5); //pending call is null; return 5 + + dbus_connection_flush(conn); + + // free message + dbus_message_unref(msg); + + // block until reply + dbus_pending_call_block(pending); + + // get the reply + msg = dbus_pending_call_steal_reply(pending); + if(msg == NULL) + exit(6); //reply is null; return 6 + + // free message handle + dbus_pending_call_unref(pending); + + ret = dbus_message_iter_init(msg, &iter); + if (ret == 0) + exit(7); //DBus message has no arguments; return 7 + + dbus_message_iter_recurse(&iter, &var); + while (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_INVALID) { + dbus_message_iter_recurse(&var, &var_iter); + while(dbus_message_iter_get_arg_type(&var_iter) != DBUS_TYPE_INVALID) { + dbus_message_iter_recurse(&var_iter, &var_value); + switch(dbus_message_iter_get_arg_type(&var_value)) { + case DBUS_TYPE_STRING: + dbus_message_iter_get_basic(&var_value, &smack_context); + break; + default: + ; + } + dbus_message_iter_next(&var_iter); + } + dbus_message_iter_next(&var); + } + + // free reply and close connection + dbus_message_unref(msg); + dbus_connection_unref(conn); + + ret = strcmp(smack_context, subject_parent); + if(ret != 0) + exit(8); //context mismatch; return 8 + + exit(0); + + } else { + // parent + + // initialise the error + dbus_error_init(&err); + + // connect to the bus and check for errors + conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); + ret = dbus_error_is_set(&err); + if (1 == ret) { + dbus_error_free(&err); + RUNNER_ASSERT_MSG(0 == ret, "dbus_bus_get() failed, ret: " << ret); + } + + // request our name on the bus and check for errors + ret = dbus_bus_request_name(conn, DBUS_SERVER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err); + if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) { + dbus_error_free(&err); + RUNNER_ASSERT_MSG(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret, + "dbus_bus_request_name() failed, ret: " << ret); + } + + // close the connection + dbus_connection_unref(conn); + } + + waitpid(pid, &status, 0); + + switch(WEXITSTATUS(status)) + { + case 1: RUNNER_ASSERT_MSG(false, "Child failed to connect to system bus."); + case 2: RUNNER_ASSERT_MSG(false, "Child failed to request name on the bus."); + case 3: RUNNER_ASSERT_MSG(false, "Child error - dbus_message_new_method_call() failed."); + case 4: RUNNER_ASSERT_MSG(false, "Child error - out of memory."); + case 5: RUNNER_ASSERT_MSG(false, "Child error - Pending call is NULL."); + case 6: RUNNER_ASSERT_MSG(false, "Child failed to get the reply from bus."); + case 7: RUNNER_ASSERT_MSG(false, "Child error - DBus message has no arguments."); + case 8: RUNNER_ASSERT_MSG(false, "Child error - context mismatch."); + default: ; + } +} + int main(int argc, char *argv[]) { int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv); diff --git a/tests/security-server-tests/security_server_tests_label.cpp b/tests/security-server-tests/security_server_tests_label.cpp index 64a810e..df983f6 100644 --- a/tests/security-server-tests/security_server_tests_label.cpp +++ b/tests/security-server-tests/security_server_tests_label.cpp @@ -14,6 +14,10 @@ #include #include #include + +#include +#include + #include #include #include @@ -105,6 +109,55 @@ RUNNER_TEST_SMACK(tc_security_server_get_smacklabel_cookie) { //is changed using security-server API function based on the same cookie } +/** + * NOSMACK version of tc_security_server_get_smacklabel_cookie test. + * + * Most of this test goes exactly as the original one. The only difference are the labels: + * - We assume that libsmack tests passed and smack_new_label_from_self will return -1 and NULL + * label - there is no need to re-check it. + * - Label acquired from security_server_get_smacklabel_cookie should be an empty string. + */ +RUNNER_TEST_NOSMACK(tc_security_server_get_smacklabel_cookie_nosmack) { + int res; + + pid_t mypid; + + 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. Size: " << COOKIESIZE); + + cookie = (char*) calloc(COOKIESIZE, sizeof(char)); + RUNNER_ASSERT_MSG(NULL != cookie, "Memory allocation error"); + + //wrap cookie in smart ptr for garbage collection + std::unique_ptr > cookie_ptr(cookie, free); + + mypid = getpid(); + + //Request cookie from SS + res = security_server_request_cookie(cookie, COOKIESIZE); + RUNNER_ASSERT_MSG(res == SECURITY_SERVER_API_SUCCESS, + "Error in requesting cookie from security-server. Result: " << res); + + printhex((unsigned char*) cookie, COOKIESIZE); + + //Get label; since we only use label_ss to check if it indeed is an empty string there is no + //need to wrap it into unique_ptr (we have only one assert before the end of the test) + label_ss = security_server_get_smacklabel_cookie(cookie); + RUNNER_ASSERT_MSG(label_ss != NULL, "Error in getting label by cookie"); + + //Check if label_ss is correct, that is only one NULL character. + if (label_ss[0] != '\0') { + free(label_ss); + RUNNER_ASSERT_MSG(false, "label_ss was not an empty string."); + } + + free(label_ss); +} + int main(int argc, char *argv[]) { int status = diff --git a/tests/security-server-tests/security_server_tests_server.cpp b/tests/security-server-tests/security_server_tests_server.cpp index 030fae6..4ef5f87 100644 --- a/tests/security-server-tests/security_server_tests_server.cpp +++ b/tests/security-server-tests/security_server_tests_server.cpp @@ -841,6 +841,231 @@ RUNNER_CHILD_TEST(tc10_check_API_app_disable_permissions) RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, "ret: " << ret); } +////////////////////////////////////////// +/////////NOSMACK ENV TESTS//////////////// +////////////////////////////////////////// + +/** + * NOSMACK version of tc01a and tc01c tests. + * + * SMACK is turned off - that means for us, that we don't need any accesses added to our process + * in SMACK before dropping root privileges. This test drops root privileges, calls + * security_server_app_give_access and then checks if smack_have_access returns error (because + * SMACK is off). + * + * security_server_app_give_access shouldn't return anything else than success when SMACK is off, + * hence there is only one test that replaces tests tc01a and tc01c. + */ +RUNNER_CHILD_TEST_NOSMACK(tc01_security_server_app_give_access_nosmack) +{ + const char* subject = "abc345v34sfa"; + const char* object = "efg678x2lkjz"; + int result = 0; + + result = drop_root_privileges(); + RUNNER_ASSERT_MSG(result == 0, + "Failed to drop root privileges. Result: " << result << "uid = " << getuid()); + + result = security_server_app_give_access(subject, getpid()); + RUNNER_ASSERT_MSG(result == SECURITY_SERVER_API_SUCCESS, + "Error in security_server_app_give_access. Result: " << result); + + result = smack_have_access(subject, object, "rwxat"); + RUNNER_ASSERT_MSG(result == -1, + "smack_have_access should return error when SMACK is off. Result: " << result); +} + +/** + * NOSMACK version of tc02 test. + * + * check_privilege_by_pid should always return success when SMACK is off, no matter if label is + * real or not. + */ +RUNNER_TEST_NOSMACK(tc02_check_privilege_by_pid_nosmack) +{ + int ret; + int pid; + + pid = getpid(); + + //we checking existing rule, it should return positive + ret = security_server_check_privilege_by_pid(pid, "_", "rx"); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, + "check_privilege_by_pid for existing label failed. Result: " << ret); + + //we checking rule with label that not exist + ret = security_server_check_privilege_by_pid(pid, "thislabelisnotreal", "rwxat"); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, + "check_privilege_by_pid for nonexisting label failed. Result: " << ret); +} + +/** + * NOSMACK version of clear_password function. + * + * Compared to SMACK version of this function, this one skips adding rules and setting label. + */ +int clear_password_nosmack() +{ + int ret = -1; + unsigned int attempt, max_attempt, expire_sec; + const char* path = "/opt/data/security-server/"; + + attempt = max_attempt = expire_sec = 0; + + if (getuid() == 0) { + if (access(path, F_OK) == 0) { + if (nftw(path, &nftw_rmdir_contents, 20, FTW_DEPTH) == -1) { + return 1; + } + sync(); + } + + ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec); + + RUNNER_ASSERT_MSG(expire_sec == 0, "expire_sec = " << expire_sec << ", should be 0."); + RUNNER_ASSERT_MSG(max_attempt == 0, "max_attempt = " << max_attempt << ", should be 0."); + RUNNER_ASSERT_MSG(attempt == 0, "attempt = " << attempt << ", should be 0."); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD, + "is_pwd_faild should return no password error. Result: " << ret); + + sleep(1); + + return 0; + } + return -1; +} + +/** + * NOSMACK version of tc03 test. + * + * Just as tc01a/tc01c NOSMACK replacement, we don't need to do anything with SMACK because most + * important functions will return errors (that is smack_accesses_apply/smack_have_access etc.). + * First clear password, then drop privileges and proceed to regular testing. + */ + +RUNNER_CHILD_TEST_NOSMACK(tc03_check_API_passwd_allow_nosmack) +{ + int ret = -1; + unsigned int attempt, max_attempt, expire_sec; + + attempt = max_attempt = expire_sec = 0; + + clear_password_nosmack(); + + // drop root privileges + ret = drop_root_privileges(); + RUNNER_ASSERT_MSG(ret == 0, + "Failed to drop root privileges. Result: " << ret << "uid = " << getuid()); + + ret = security_server_set_pwd_validity(10); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD, + "set_pwd_validity should return no password error. Result: " << ret); + + ret = security_server_set_pwd_max_challenge(5); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD, + "set_pwd_max_challenge should return no password error. Result: " << ret); + + ret = security_server_is_pwd_valid(&attempt, &max_attempt, &expire_sec); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_ERROR_NO_PASSWORD, + "is_pwd_valid should return no password error. Result: " << ret); + + sleep(1); + ret = security_server_set_pwd(NULL, "12345", 0, 0); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, + "set_pwd failed. Result: " << ret); + + sleep(1); + ret = security_server_reset_pwd("12345",0, 0); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, + "reset_pwd failed. Result: " << ret); + + sleep(1); + ret = security_server_chk_pwd("12345", &attempt, &max_attempt, &expire_sec); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, + "chk_pwd failed. Result: " << ret); + + sleep(1); + ret = security_server_set_pwd_history(10); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, + "set_pwd_history failed. Result: " << ret); +} + +/** + * NOSMACK version of tc05 test. + * + * This test assumes similar information as previous NOSMACK tests. SMACK off = no need to + * set accesses and apply them in SMACK before dropping privileges. + */ + +RUNNER_CHILD_TEST_NOSMACK(tc05_check_API_middleware_allow_nosmack) +{ + int ret = -1; + size_t cookie_size = security_server_get_cookie_size(); + gid_t gid = 5000; + char cookie[20]; + char* ss_label = NULL; + char object[SECURITY_SERVER_MAX_OBJ_NAME]; + + // drop root privileges + ret = drop_root_privileges(); + RUNNER_ASSERT_MSG(ret == 0, + "Failed to drop root privileges. Result: " << ret << "uid = " << getuid()); + + ret = security_server_request_cookie(cookie, cookie_size); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, + "request_cookie failed. Result: " << ret); + + ret = security_server_get_gid("audio"); + RUNNER_ASSERT_MSG(ret > -1, "Failed to get \"audio\" gid. Result: " << ret); + + ret = security_server_check_privilege(cookie, ret); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, + "check_privilege failed. Result: " << ret); + + ret = security_server_get_object_name(gid, object, sizeof(object)); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, + "get_object_name failed. Result: " << ret); + + ret = security_server_get_gid("root"); + RUNNER_ASSERT_MSG(ret > -1, + "Failed to get \"root\" gid. Result: " << ret); + + ret = security_server_get_cookie_pid(cookie); + RUNNER_ASSERT_MSG(ret == getpid(), + "get_cookie_pid returned different pid than it should. Result: " << ret); + + ss_label = security_server_get_smacklabel_cookie(cookie); + RUNNER_ASSERT_MSG(ss_label != NULL, "get_smacklabel_cookie failed."); + + ret = security_server_check_privilege_by_pid(getpid(), "_", "rx"); + if(ret != SECURITY_SERVER_API_SUCCESS) { + free(ss_label); + RUNNER_ASSERT_MSG(false, "check_privilege_by_pid failed. Result: " << ret); + } +} + +/** + * NOSMACK version of tc07 test. + * + * Similarily to previous tests - no need to set self label because SMACK is off. Just as + * tc01a/tc01c replacement, security_server_app_give_access should return only success. Hence the + * NOSMACK version of tc08 test is skipped. + */ +RUNNER_CHILD_TEST_NOSMACK(tc07_check_API_data_share_allow_nosmack) +{ + int ret = -1; + const char* subject_allow = TEST07_SUBJECT; + + // drop root privileges + ret = drop_root_privileges(); + RUNNER_ASSERT_MSG(ret == 0, + "Failed to drop root privileges. Result: " << ret << "uid = " << getuid()); + + ret = security_server_app_give_access(subject_allow, getpid()); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, + "app_give_access failed. Result: " << ret); +} + int main(int argc, char *argv[]) { server_sockfd = -1; diff --git a/tests/security-server-tests/security_server_tests_weird_arguments.cpp b/tests/security-server-tests/security_server_tests_weird_arguments.cpp index 92e0842..888a25a 100644 --- a/tests/security-server-tests/security_server_tests_weird_arguments.cpp +++ b/tests/security-server-tests/security_server_tests_weird_arguments.cpp @@ -194,3 +194,41 @@ RUNNER_TEST(tc07_security_server_get_cookie_pid_weird_input_case) ret = security_server_get_cookie_pid(cookie); RUNNER_ASSERT(ret == SECURITY_SERVER_API_ERROR_INPUT_PARAM); } + +/////////////////////////// +/////NOSMACK ENV TESTS///// +/////////////////////////// + +/** + * NOSMACK version of tc06 test. + * + * security_server_check_privilege_by_sockfd at first checks if SMACK exists and then checks if + * params are correct. Even with incorrect params we should expect SUCCESS instead of + * ERROR_INPUT_PARAM. + */ + +RUNNER_TEST_NOSMACK(tc06_security_server_check_privilege_by_sockfd_weird_input_case_nosmack) +{ + int ret = 0; + int sockfd = -1; + const char* object = "telephony_makecall"; + const char* access_rights = "r"; + + //invalid sockfd case + ret = security_server_check_privilege_by_sockfd(sockfd, object, access_rights); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, + "check_privilege_by_sockfd failed. Result: " << ret); + sockfd = 0; + + //null object case + char *object2 = NULL; + ret = security_server_check_privilege_by_sockfd(sockfd, object2, access_rights); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, + "check_privilege_by_sockfd failed. Result: " << ret); + + //null access rights case + access_rights = NULL; + ret = security_server_check_privilege_by_sockfd(sockfd, object, access_rights); + RUNNER_ASSERT_MSG(ret == SECURITY_SERVER_API_SUCCESS, + "check_privilege_by_sockfd failed. Result: " << ret); +}