#include <sys/smack.h>
#include <sys/wait.h>
#include <sys/un.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <memory>
+#include <functional>
#include <dpl/log/log.h>
#include <dpl/test/test_runner.h>
"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<int, std::function<void(int*)> > SockFDUniquePtr;
+
/**
* Dropping root privileges
* returns 0 on success, 1 on error
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
}
}
+///////////////////////////////////////
+//////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);
#include <sys/types.h>
#include <unistd.h>
#include <sys/smack.h>
+
+#include <memory>
+#include <functional>
+
#include <security-server.h>
#include <dpl/test/test_runner.h>
#include <dlog.h>
//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<char, std::function<void(char*)> > 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 =
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;
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);
+}