From 035a96983cdf8a11a1c2380106c11c94cb8418b2 Mon Sep 17 00:00:00 2001 From: Vishwanatha Subbanna Date: Fri, 15 Sep 2017 18:50:43 +0530 Subject: Add GTEST cases Fixes openbmc/openbmc#1714 Change-Id: I51964f16fc2ea733ee3b3ae822f72ac7b431189a Signed-off-by: Vishwanatha Subbanna --- test/Makefile.am | 27 +++++++ test/utest.cpp | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 237 insertions(+) create mode 100644 test/Makefile.am create mode 100644 test/utest.cpp (limited to 'test') diff --git a/test/Makefile.am b/test/Makefile.am new file mode 100644 index 0000000..3acdaab --- /dev/null +++ b/test/Makefile.am @@ -0,0 +1,27 @@ +AM_CPPFLAGS = -I$(top_srcdir) + +# Run all 'check' test programs +TESTS = $(check_PROGRAMS) + +# Build/add utest to test suite +check_PROGRAMS = utest +utest_CPPFLAGS = -Igtest \ + $(GTEST_CPPFLAGS) \ + $(AM_CPPFLAGS) \ + $(PHOSPHOR_LOGGING_CFLAGS) \ + $(SDBUSPLUS_CFLAGS) + +utest_CXXFLAGS = $(PTHREAD_CFLAGS) + +utest_LDFLAGS = -lgtest_main \ + -lgtest \ + $(PTHREAD_LIBS) \ + $(OESDK_TESTCASE_FLAGS) \ + $(PHOSPHOR_DBUS_INTERFACES_LIBS) \ + $(PHOSPHOR_LOGGING_LIBS) \ + $(SDBUSPLUS_LIBS) \ + -lcrypt \ + -lstdc++fs + +utest_SOURCES = utest.cpp +utest_LDADD = $(top_builddir)/user.o diff --git a/test/utest.cpp b/test/utest.cpp new file mode 100644 index 0000000..bdca968 --- /dev/null +++ b/test/utest.cpp @@ -0,0 +1,210 @@ +#include +#include +#include +#include +#include +#include +#include "user.hpp" +namespace phosphor +{ +namespace user +{ + +namespace fs = std::experimental::filesystem; + +constexpr auto path = "/dummy/user"; +constexpr auto testShadow = "/tmp/__tshadow__"; +constexpr auto shadowCopy = "/tmp/__tshadowCopy__"; +constexpr auto shadowCompare = "/tmp/__tshadowCompare__"; + +// New password +constexpr auto password = "passw0rd"; + +constexpr auto MD5 = "1"; +constexpr auto SHA512 = "6"; +constexpr auto salt = "1G.cK/YP"; + +// Example entry matching /etc/shadow structure +constexpr auto spPwdp = "$1$1G.cK/YP$JI5t0oliPxZveXOvLcZ/H.:17344:1:90:7:::"; + +class UserTest : public ::testing::Test +{ + public: + const std::string md5Salt = '$' + std::string(MD5) + '$' + + std::string(salt) + '$'; + const std::string shaSalt = '$' + std::string(SHA512) + '$' + + std::string(salt) + '$'; + + const std::string entry = fs::path(path).filename().string() + + ':' + std::string(spPwdp); + sdbusplus::bus::bus bus; + phosphor::user::User user; + + // Gets called as part of each TEST_F construction + UserTest() + : bus(sdbusplus::bus::new_default()), + user(bus, path) + { + // Create a shadow file entry + std::ofstream file(testShadow); + file << entry; + file.close(); + + // File to compare against + std::ofstream compare(shadowCompare); + compare << entry; + compare.close(); + } + + // Gets called as part of each TEST_F destruction + ~UserTest() + { + if (fs::exists(testShadow)) + { + fs::remove(testShadow); + } + + if (fs::exists(shadowCopy)) + { + fs::remove(shadowCopy); + } + + if (fs::exists(shadowCompare)) + { + fs::remove(shadowCompare); + } + } + + /** @brief wrapper for get crypt field */ + auto getCryptField(char* data) + { + return User::getCryptField( + std::forward(data)); + } + + /** @brief wrapper for getSaltString */ + auto getSaltString(const std::string& crypt, + const std::string& salt) + { + return User::getSaltString( + std::forward(crypt), + std::forward(salt)); + } + + /** @brief wrapper for generateHash */ + auto generateHash(const std::string& password, + const std::string& salt) + { + return User::generateHash( + std::forward(password), + std::forward(salt)); + } + + /** @brief Applies the new password */ + auto applyPassword() + { + return user.applyPassword(testShadow, shadowCopy, + password, salt); + } +}; + +/** @brief Makes sure that SHA512 crypt field is extracted + */ +TEST_F(UserTest, sha512GetCryptField) +{ + auto salt = const_cast(shaSalt.c_str()); + EXPECT_EQ(SHA512, this->getCryptField(salt)); +} + +/** @brief Makes sure that MD5 crypt field is extracted as default + */ +TEST_F(UserTest, md55GetCryptFieldDefault) +{ + auto salt = const_cast("hello"); + EXPECT_EQ(MD5, this->getCryptField(salt)); +} + +/** @brief Makes sure that MD5 crypt field is extracted + */ +TEST_F(UserTest, md55GetCryptField) +{ + auto salt = const_cast(md5Salt.c_str()); + EXPECT_EQ(MD5, this->getCryptField(salt)); +} + +/** @brief Makes sure that salt string is put within $$ + */ +TEST_F(UserTest, getSaltString) +{ + EXPECT_EQ(md5Salt, this->getSaltString(MD5, salt)); +} + +/** @brief Makes sure hash is generated correctly + */ +TEST_F(UserTest, generateHash) +{ + std::string sample = crypt(password, md5Salt.c_str()); + std::string actual = generateHash(password, md5Salt); + EXPECT_EQ(sample, actual); +} + +/** @brief Verifies that the correct password is written to file + */ +TEST_F(UserTest, applyPassword) +{ + // Update the password + applyPassword(); + + // Read files and compare + std::ifstream shadow(testShadow); + std::ifstream copy(shadowCompare); + + std::string shadowEntry; + shadow >> shadowEntry; + + std::string shadowCompareEntry; + copy >> shadowCompareEntry; + + EXPECT_EQ(shadowEntry, shadowCompareEntry); +} + +/** @brief Verifies the shadow copy file is removed + */ +TEST_F(UserTest, checkShadowCopyRemove) +{ + // Update the password so that the temp file is in action + applyPassword(); + + // Compare the permission of 2 files + struct stat shadow{}; + struct stat temp{}; + + stat(testShadow, &shadow); + stat(shadowCopy, &temp); + EXPECT_EQ(false, fs::exists(shadowCopy)); +} + +/** @brief Verifies the permissions are correct + */ +TEST_F(UserTest, verifyShadowPermission) +{ + // Change the permission to 400-> -r-------- + chmod(testShadow, S_IRUSR); + chmod(shadowCompare, S_IRUSR); + + // Update the password so that the temp file is in action + applyPassword(); + + // Compare the permission of 2 files. + // file rename would make sure that the permissions + // of old are moved to new + struct stat shadow{}; + struct stat compare{}; + + stat(testShadow, &shadow); + stat(shadowCompare, &compare); + EXPECT_EQ(shadow.st_mode, compare.st_mode); +} + +} // namespace user +} // namespace phosphor -- cgit v1.2.1