Add unit tests for permissible file update, initialization and removal
authorFilip Skrzeczkowski <f.skrzeczkow@samsung.com>
Wed, 4 Oct 2023 09:12:23 +0000 (11:12 +0200)
committerTomasz Swierczek <t.swierczek@samsung.com>
Wed, 29 Nov 2023 10:07:35 +0000 (11:07 +0100)
Change-Id: Id05b5deaa8d4fd39c53478c555524f4be4ddac2b

test/test_permissible-set.cpp

index 16d86ad..6c30b30 100644 (file)
 #include <fstream>
 #include <sstream>
 #include <string>
+#include <sys/stat.h>
 #include <vector>
 
 #include <dpl/log/log.h>
+#include <filesystem.h>
 #include <permissible-set.h>
+#include <service_impl_utils.h>
 #include <testmacros.h>
+#include <tzplatform-config.h>
 
 using namespace SecurityManager::PermissibleSet;
 
 static constexpr int validHashLength = 40;
 static const std::string hashMarker = "-SHA-1";
+static const uid_t globalUserId = getGlobalUserId();
+static constexpr int testUserId = 5001;
 
 class PermissibleFileFixture
 {
@@ -60,7 +66,7 @@ public:
         removeFile(nonExistentFile);
     }
 
-    virtual ~PermissibleFileFixture()
+    ~PermissibleFileFixture()
     {
         removeFile(existentFile);
         removeFile(nonExistentFile);
@@ -253,4 +259,157 @@ NEGATIVE_FIXTURE_TEST_CASE(T1724_read_non_existent_file, PermissibleFileFixture)
     BOOST_REQUIRE_THROW(readLabelsFromPermissibleFile(PermissibleFileFixture::nonExistentFile, appLabels), PermissibleSetException::FileOpenError);
 }
 
+POSITIVE_TEST_CASE(T1730_get_permissible_file_location_global)
+{
+    uid_t user = globalUserId;
+    std::string path;
+    BOOST_REQUIRE_NO_THROW(path = getPermissibleFileLocation(user, SM_APP_INSTALL_GLOBAL));
+}
+
+POSITIVE_TEST_CASE(T1731_get_permissible_file_location_local)
+{
+    uid_t user = testUserId;
+    std::string path;
+    BOOST_REQUIRE_NO_THROW(path = getPermissibleFileLocation(user, SM_APP_INSTALL_LOCAL));
+}
+
+POSITIVE_TEST_CASE(T1740_update_permissible_file)
+{
+    uid_t user = globalUserId;
+    std::string path;
+    BOOST_REQUIRE_NO_THROW(path = getPermissibleFileLocation(user, SM_APP_INSTALL_GLOBAL));
+
+    std::string content = "label1\nlabel2\nlabel3\n";
+    std::vector<std::string> labelsToAdd = {
+        "label4",
+        "label5"
+    };
+    std::vector<std::string> labelsToRemove = {
+        "label1",
+        "label3"
+    };
+    std::vector<std::string> expectedOutput = {
+        "label2",
+        "label4",
+        "label5"
+    };
+    {
+        std::ofstream os(path);
+        os << hashMarker << " " << calculateHash(content) << "\n" << content;
+    }
+    BOOST_REQUIRE_NO_THROW(updatePermissibleFile(user, SM_APP_INSTALL_GLOBAL, labelsToAdd, labelsToRemove));
+
+    std::vector<std::string> output;
+    BOOST_REQUIRE_NO_THROW(readLabelsFromPermissibleFile(path, output));
+    BOOST_CHECK_EQUAL_COLLECTIONS(output.begin(), output.end(), expectedOutput.begin(), expectedOutput.end());
+}
+
+POSITIVE_TEST_CASE(T1741_update_permissible_file_no_hash)
+{
+    uid_t user = globalUserId;
+    std::string path;
+    BOOST_REQUIRE_NO_THROW(path = getPermissibleFileLocation(user, SM_APP_INSTALL_GLOBAL));
+
+    std::string content = "label1\nlabel2\nlabel3\n";
+    std::vector<std::string> labelsToAdd = {};
+    std::vector<std::string> labelsToRemove = {};
+    {
+        std::ofstream os(path);
+        os << content;
+    }
+    BOOST_REQUIRE_NO_THROW(updatePermissibleFile(user, SM_APP_INSTALL_GLOBAL, labelsToAdd, labelsToRemove));
+
+    std::string hashMarkerRead;
+    std::string hashRead;
+    {
+        std::ifstream is(path);
+        is >> hashMarkerRead >> hashRead;
+    }
+
+    // The newly updated file should now have a hash, even if no changes were made
+    BOOST_REQUIRE(hashMarkerRead == hashMarker);
+    BOOST_REQUIRE(hashRead == calculateHash(content));
+}
+
+POSITIVE_TEST_CASE(T1742_update_permissible_file_local_file_created)
+{
+    uid_t user = testUserId;
+    std::string path;
+    BOOST_REQUIRE_NO_THROW(path = getPermissibleFileLocation(user, SM_APP_INSTALL_LOCAL));
+    std::string dir = FS::getDirectoryName(path);
+
+    BOOST_REQUIRE(mkdir(dir.c_str(), 0755) == 0 || errno == EEXIST);
+    BOOST_REQUIRE(unlink(path.c_str()) == 0 || errno == ENOENT);
+
+    std::vector<std::string> labelsToAdd = {
+        "label1",
+        "label2"
+    };
+    std::vector<std::string> labelsToRemove = {
+        "label3",
+        "label4"
+    };
+
+    BOOST_REQUIRE_NO_THROW(updatePermissibleFile(user, SM_APP_INSTALL_LOCAL, labelsToAdd, labelsToRemove));
+    BOOST_REQUIRE(FS::fileExists(path));
+
+    std::vector<std::string> output;
+    BOOST_REQUIRE_NO_THROW(readLabelsFromPermissibleFile(path, output));
+    BOOST_CHECK_EQUAL_COLLECTIONS(output.begin(), output.end(), labelsToAdd.begin(), labelsToAdd.end());
+
+    BOOST_REQUIRE(unlink(path.c_str()) == 0 || errno == ENOENT);
+}
+
+NEGATIVE_TEST_CASE(T1743_update_permissible_file_not_initialized)
+{
+    uid_t user = testUserId;
+    std::string path;
+    BOOST_REQUIRE_NO_THROW(path = getPermissibleFileLocation(user, SM_APP_INSTALL_LOCAL));
+    std::string dir = FS::getDirectoryName(path);
+
+    BOOST_REQUIRE(unlink(path.c_str()) == 0 || errno == ENOENT);
+    BOOST_REQUIRE(rmdir(dir.c_str()) == 0 || errno == ENOENT);
+
+    BOOST_REQUIRE_THROW(updatePermissibleFile(user, SM_APP_INSTALL_LOCAL, std::vector<std::string>{}, std::vector<std::string>{}),
+        PermissibleSetException::FileOpenError);
+
+    BOOST_REQUIRE(mkdir(dir.c_str(), 0755) == 0 || errno == EEXIST);
+}
+
+NEGATIVE_TEST_CASE(T1744_update_permissible_file_global_id_local_install)
+{
+    uid_t user = globalUserId;
+    std::string path;
+    BOOST_REQUIRE_NO_THROW(path = getPermissibleFileLocation(user, SM_APP_INSTALL_LOCAL));
+    std::string dir = FS::getDirectoryName(path);
+
+    // A permissible file for the reserved global id should not exist under normal circumstances
+    // In other words, no user with id equal to globalUserId should have their permissible file initialized
+    BOOST_REQUIRE(unlink(path.c_str()) == 0 || errno == ENOENT);
+    BOOST_REQUIRE(rmdir(dir.c_str()) == 0 || errno == ENOENT);
+
+    BOOST_REQUIRE_THROW(updatePermissibleFile(user, SM_APP_INSTALL_LOCAL,
+    std::vector<std::string>{}, std::vector<std::string>{}), PermissibleSetException::FileOpenError);
+}
+
+POSITIVE_TEST_CASE(T1750_initialize_and_delete_permissible_file)
+{
+    uid_t user = testUserId;
+    std::string path;
+    BOOST_REQUIRE_NO_THROW(path = getPermissibleFileLocation(user, SM_APP_INSTALL_LOCAL));
+    std::string dir = FS::getDirectoryName(path);
+
+    BOOST_REQUIRE(unlink(path.c_str()) == 0 || errno == ENOENT);
+    BOOST_REQUIRE(rmdir(dir.c_str()) == 0 || errno == ENOENT);
+
+    BOOST_REQUIRE_NO_THROW(initializeUserPermissibleFile(testUserId));
+    BOOST_REQUIRE(FS::fileExists(path));
+
+    BOOST_REQUIRE_NO_THROW(removeUserPermissibleFile(testUserId));
+    BOOST_REQUIRE(!FS::fileExists(path));
+
+    BOOST_REQUIRE(unlink(path.c_str()) == 0 || errno == ENOENT);
+
+}
+
 BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file