/* * Copyright (c) 2019 - 2024 Stefan Strobel * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /** * @file test_integration_auth.cpp * @brief integration test implementation for the authentication functions * @author Stefan Strobel */ #include "test/framework/catch.hpp" extern "C" { #include "shellmatta.h" } #include static uint32_t write_callCnt = 0u; static char write_data[1024]; static uint32_t write_length; #define TEST_SHELLMATTA_SETUP shellmatta_retCode_t ret; \ shellmatta_instance_t inst; \ shellmatta_handle_t handle; \ char buffer[1024] = {0}; \ char historyBuffer[1024] = {0}; \ \ shellmatta_doInit( &inst, \ &handle, \ buffer, \ sizeof(buffer), \ historyBuffer, \ sizeof(historyBuffer), \ "shellmatta->", \ NULL, \ writeFct); \ \ write_callCnt = 0u; \ memset(write_data, 0, sizeof(write_data)); \ write_length = 0u; \ \ shellmatta_addCmd(handle, &publicCmd); \ shellmatta_addCmd(handle, &privateCmd); #define TEST_SHELLMATTA_AUTH_SETUP shellmatta_auth_user_t userList[] = { \ {1, "shimatta", "12345678"}, \ {2, "not_shimatta", "87654321"} \ }; \ \ uint32_t privateCmdPerms[] = {1}; \ shellmatta_auth_perm_t permList[] = { \ {"private", privateCmdPerms, sizeof(privateCmdPerms)/sizeof(privateCmdPerms[0])} \ }; \ \ shellmatta_auth_init(handle, userList, 1, permList, 1, false, NULL, NULL); static shellmatta_retCode_t writeFct(const char* data, uint32_t length) { write_callCnt ++; while((length > 0) && (write_length < sizeof(write_data))) { write_data[write_length] = *data; data ++; length --; write_length ++; } return SHELLMATTA_OK; } static shellmatta_retCode_t publicCmdFct(shellmatta_handle_t handle, const char *arguments, uint32_t length) { (void) handle; (void) arguments; (void) length; shellmatta_retCode_t ret = SHELLMATTA_OK; return ret; } shellmatta_cmd_t publicCmd = {(char*)"public", (char*)"p", NULL, NULL, publicCmdFct, NULL, NULL}; static shellmatta_retCode_t privateCmdFct(shellmatta_handle_t handle, const char *arguments, uint32_t length) { (void) handle; (void) arguments; (void) length; return SHELLMATTA_OK; } shellmatta_cmd_t privateCmd = {(char*)"private", (char*)"r", NULL, NULL, privateCmdFct, NULL, NULL}; SCENARIO("Check help auth uninitialized") { GIVEN("An initialized shellmatta instance without initialized auth") { TEST_SHELLMATTA_SETUP; WHEN("The help command is called") { ret = shellmatta_processData(handle, (char*)"help\r", 5); CHECK(ret == SHELLMATTA_OK); THEN("The help command prints all commands.") { char *dummyData = (char*) "help\r\n" "help ? help [command] - print help or usage information\r\n" "login li Login command\r\n" "logout lo Logout command\r\n" "private r\r\n" "public p\r\n" "\r\n" "shellmatta->"; CHECK(ret == SHELLMATTA_OK); CHECK(write_length == strlen(dummyData)); REQUIRE_THAT(write_data, Catch::Matchers::Equals(dummyData)); } } } } SCENARIO("Check help auth unauthorized") { GIVEN("An initialized shellmatta instance with initialized auth") { TEST_SHELLMATTA_SETUP; TEST_SHELLMATTA_AUTH_SETUP; WHEN("The help command is called") { ret = shellmatta_processData(handle, (char*)"help\r", 5); CHECK(ret == SHELLMATTA_OK); THEN("The help command prints only public commands.") { char *dummyData = (char*) "help\r\n" "help ? help [command] - print help or usage information\r\n" "login li Login command\r\n" "logout lo Logout command\r\n" "public p\r\n" "\r\n" "shellmatta->"; CHECK(ret == SHELLMATTA_OK); CHECK(write_length == strlen(dummyData)); REQUIRE_THAT(write_data, Catch::Matchers::Equals(dummyData)); } } } } SCENARIO("Check help authorized") { GIVEN("An initialized shellmatta instance with initialized auth") { TEST_SHELLMATTA_SETUP; TEST_SHELLMATTA_AUTH_SETUP; WHEN("The user shellmatta is logged in") { ret = shellmatta_auth_login(handle, 1); CHECK(ret == SHELLMATTA_OK); AND_WHEN("The help command is called") { ret = shellmatta_processData(handle, (char*)"help\r", 5); CHECK(ret == SHELLMATTA_OK); THEN("The help command prints all commands.") { char *dummyData = (char*) "help\r\n" "help ? help [command] - print help or usage information\r\n" "login li Login command\r\n" "logout lo Logout command\r\n" "private r\r\n" "public p\r\n" "\r\n" "shimatta@shellmatta->"; CHECK(ret == SHELLMATTA_OK); CHECK(write_length == strlen(dummyData)); REQUIRE_THAT(write_data, Catch::Matchers::Equals(dummyData)); } AND_WHEN("The user is logged out using the logout command") { write_length = 0; memset(write_data, 0, sizeof(write_data)); ret = shellmatta_processData(handle, (char*)"logout\r", 7); CHECK(ret == SHELLMATTA_OK); THEN("The Shellmatta prints the logout message") { char *dummyData = (char*) "logout\r\n" \ "good bye\r\n\r\n" \ "shellmatta->"; CHECK(write_length == strlen(dummyData)); REQUIRE_THAT(write_data, Catch::Matchers::Equals(dummyData)); } AND_WHEN("The help command is called") { write_length = 0; memset(write_data, 0, sizeof(write_data)); ret = shellmatta_processData(handle, (char*)"help\r", 5); CHECK(ret == SHELLMATTA_OK); THEN("The help command prints only public commands.") { char *dummyData = (char*) "help\r\n" "help ? help [command] - print help or usage information\r\n" "login li Login command\r\n" "logout lo Logout command\r\n" "public p\r\n" "\r\n" "shellmatta->"; CHECK(ret == SHELLMATTA_OK); CHECK(write_length == strlen(dummyData)); REQUIRE_THAT(write_data, Catch::Matchers::Equals(dummyData)); } } } } } } } SCENARIO("Check login command") { GIVEN("An initialized shellmatta instance with initialized auth") { TEST_SHELLMATTA_SETUP; TEST_SHELLMATTA_AUTH_SETUP; WHEN("The user shellmatta logges in interactively using the correct credentials") { ret = shellmatta_processData(handle, (char*)"login\r" \ "shimatta\r"\ "12345678\r", 24); CHECK(ret == SHELLMATTA_OK); THEN("The login message is printed - password is hidden") { char *dummyData = (char*) "login\r\n" \ "enter username:\r\n" \ "shimatta\r\n" \ "enter password:\r\n" \ "\r\n" \ "login successful\r\n" \ "\r\n" \ "shimatta@shellmatta->"; CHECK(write_length == strlen(dummyData)); REQUIRE_THAT(write_data, Catch::Matchers::Equals(dummyData)); AND_THEN("The shimatta user is logged in") { REQUIRE(1 == shellmatta_auth_getLoggedInUserId(handle)); } } } WHEN("The user shellmatta logges in interactively manipulating the input") { ret = shellmatta_processData(handle, (char*)"login\r" \ "shimg\batta\r" \ "12346\033[D5\033[C78\r", 32); CHECK(ret == SHELLMATTA_OK); THEN("The login message is printed - password is hidden") { char *dummyData = (char*) "login\r\n" \ "enter username:\r\n" \ "shimg\033[1D\033[K\033[s\033[uatta\r\n" \ "enter password:\r\n" \ "\r\n" \ "login successful\r\n" \ "\r\n" \ "shimatta@shellmatta->"; CHECK(write_length == strlen(dummyData)); REQUIRE_THAT(write_data, Catch::Matchers::Equals(dummyData)); AND_THEN("The shimatta user is logged in") { REQUIRE(1 == shellmatta_auth_getLoggedInUserId(handle)); } } } WHEN("The user shellmatta logges in passing the credentials none interactive") { ret = shellmatta_processData(handle, (char*)"login -u shimatta -p 12345678\r", 30); CHECK(ret == SHELLMATTA_OK); THEN("The login message is printed - password is hidden") { char *dummyData = (char*) "login -u shimatta -p 12345678\r\n" \ "login successful\r\n" \ "\r\n" \ "shimatta@shellmatta->"; CHECK(write_length == strlen(dummyData)); REQUIRE_THAT(write_data, Catch::Matchers::Equals(dummyData)); AND_THEN("The shimatta user is logged in") { REQUIRE(1 == shellmatta_auth_getLoggedInUserId(handle)); } } } } }