diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /security/nss/gtests/sysinit_gtest/getUserDB_unittest.cc | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'security/nss/gtests/sysinit_gtest/getUserDB_unittest.cc')
-rw-r--r-- | security/nss/gtests/sysinit_gtest/getUserDB_unittest.cc | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/security/nss/gtests/sysinit_gtest/getUserDB_unittest.cc b/security/nss/gtests/sysinit_gtest/getUserDB_unittest.cc new file mode 100644 index 0000000000..845b6e36e5 --- /dev/null +++ b/security/nss/gtests/sysinit_gtest/getUserDB_unittest.cc @@ -0,0 +1,164 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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 http://mozilla.org/MPL/2.0/. */ +#include "gtest/gtest.h" +#include "prenv.h" +#include "seccomon.h" + +#include <stdlib.h> +#include <string> +#include <unistd.h> +#include <sys/stat.h> + +namespace nss_test { + +// Return the path to user's NSS database. +extern "C" char *getUserDB(void); + +class Sysinit : public ::testing::Test { + protected: + void SetUp() { + home_var_ = PR_GetEnvSecure("HOME"); + if (home_var_) { + old_home_dir_ = home_var_; + } + xdg_data_home_var_ = PR_GetEnvSecure("XDG_DATA_HOME"); + if (xdg_data_home_var_) { + old_xdg_data_home_ = xdg_data_home_var_; + ASSERT_EQ(0, unsetenv("XDG_DATA_HOME")); + } + char tmp[] = "/tmp/nss-tmp.XXXXXX"; + tmp_home_ = mkdtemp(tmp); + ASSERT_EQ(0, setenv("HOME", tmp_home_.c_str(), 1)); + } + + void TearDown() { + // Set HOME back to original + if (home_var_) { + ASSERT_EQ(0, setenv("HOME", old_home_dir_.c_str(), 1)); + } else { + ASSERT_EQ(0, unsetenv("HOME")); + } + // Set XDG_DATA_HOME back to original + if (xdg_data_home_var_) { + ASSERT_EQ(0, setenv("XDG_DATA_HOME", old_xdg_data_home_.c_str(), 1)); + } + // Remove test dirs. + if (!nssdir_.empty()) { + ASSERT_EQ(0, RemoveEmptyDirsFromStart(nssdir_, tmp_home_)); + } + } + + // Remove all dirs within @start from @path containing only empty dirs. + // Assumes @start already exists. + // Upon successful completion, return 0. Otherwise, -1. + static int RemoveEmptyDirsFromStart(std::string path, std::string start) { + if (path.find(start) == std::string::npos) { + return -1; + } + std::string temp = path; + if (rmdir(temp.c_str())) { + return -1; + } + for (size_t i = temp.length() - 1; i > start.length(); --i) { + if (temp[i] == '/') { + temp[i] = '\0'; + if (rmdir(temp.c_str())) { + return -1; + } + } + } + if (rmdir(start.c_str())) { + return -1; + } + return 0; + } + + // Create empty dirs appending @path to @start with mode @mode. + // Assumes @start already exists. + // Upon successful completion, return the string @start + @path. + static std::string CreateEmptyDirsFromStart(std::string start, + std::string path, mode_t mode) { + std::string temp = start + "/"; + for (size_t i = 1; i < path.length(); ++i) { + if (path[i] == '/') { + EXPECT_EQ(0, mkdir(temp.c_str(), mode)); + } + temp += path[i]; + } + // We reach the end of string before the last dir is created + EXPECT_EQ(0, mkdir(temp.c_str(), mode)); + return temp; + } + + char *home_var_; + char *xdg_data_home_var_; + std::string old_home_dir_; + std::string old_xdg_data_home_; + std::string nssdir_; + std::string tmp_home_; +}; + +class SysinitSetXdgUserDataHome : public Sysinit { + protected: + void SetUp() { + Sysinit::SetUp(); + ASSERT_EQ(0, setenv("XDG_DATA_HOME", tmp_home_.c_str(), 1)); + } +}; + +class SysinitSetTrashXdgUserDataHome : public Sysinit { + protected: + void SetUp() { + Sysinit::SetUp(); + std::string trashPath = tmp_home_ + "/this/path/does/not/exist"; + ASSERT_EQ(0, setenv("XDG_DATA_HOME", trashPath.c_str(), 1)); + } + + void TearDown() { + ASSERT_EQ(0, rmdir(tmp_home_.c_str())); + Sysinit::TearDown(); + } +}; + +// Check if $HOME/.pki/nssdb is used if it exists +TEST_F(Sysinit, LegacyPath) { + nssdir_ = CreateEmptyDirsFromStart(tmp_home_, "/.pki/nssdb", 0760); + char *nssdb = getUserDB(); + ASSERT_EQ(nssdir_, nssdb); + PORT_Free(nssdb); +} + +// Check if $HOME/.local/share/pki/nssdb is used if: +// - $HOME/.pki/nssdb does not exist; +// - XDG_DATA_HOME is not set. +TEST_F(Sysinit, XdgDefaultPath) { + nssdir_ = CreateEmptyDirsFromStart(tmp_home_, "/.local/share", 0755); + nssdir_ = CreateEmptyDirsFromStart(nssdir_, "/pki/nssdb", 0760); + char *nssdb = getUserDB(); + ASSERT_EQ(nssdir_, nssdb); + PORT_Free(nssdb); +} + +// Check if ${XDG_DATA_HOME}/pki/nssdb is used if: +// - $HOME/.pki/nssdb does not exist; +// - XDG_DATA_HOME is set and the path exists. +TEST_F(SysinitSetXdgUserDataHome, XdgSetPath) { + // XDG_DATA_HOME is set to HOME + nssdir_ = CreateEmptyDirsFromStart(tmp_home_, "/pki/nssdb", 0760); + char *nssdb = getUserDB(); + ASSERT_EQ(nssdir_, nssdb); + PORT_Free(nssdb); +} + +// Check if it fails when: +// - XDG_DATA_HOME is set to a path that does not exist; +// - $HOME/.pki/nssdb also does not exist. */ +TEST_F(SysinitSetTrashXdgUserDataHome, XdgSetToTrashPath) { + char *nssdb = getUserDB(); + ASSERT_EQ(nullptr, nssdb); +} + +} // namespace nss_test |