SM: Add tests for NSS plugin 28/86328/9
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 2 Sep 2016 13:17:44 +0000 (15:17 +0200)
committerZofia Abramowska <z.abramowska@samsung.com>
Tue, 20 Sep 2016 11:40:59 +0000 (04:40 -0700)
Change-Id: I7e3e387869efdb2cad1c868aa3ab4c12dc09c815

src/security-manager-tests/CMakeLists.txt
src/security-manager-tests/common/policy_configuration.cpp [new file with mode: 0644]
src/security-manager-tests/common/policy_configuration.h [new file with mode: 0644]
src/security-manager-tests/test_cases_nss.cpp [new file with mode: 0644]

index 273f444..a9b1455 100644 (file)
@@ -42,12 +42,14 @@ SET(SEC_MGR_SOURCES
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_credentials.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_dyntransition.cpp
+    ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_nss.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_privacy_manager.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_private_sharing.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_public_sharing.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_register_paths.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/test_cases_trusted_sharing.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/security_manager_tests.cpp
+    ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/policy_configuration.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_api.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_commons.cpp
     ${PROJECT_SOURCE_DIR}/src/security-manager-tests/common/sm_db.cpp
diff --git a/src/security-manager-tests/common/policy_configuration.cpp b/src/security-manager-tests/common/policy_configuration.cpp
new file mode 100644 (file)
index 0000000..111d6bc
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#include <fstream>
+#include <regex>
+#include <string>
+#include <vector>
+
+#include <grp.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <policy_configuration.h>
+
+#define CONF_DIR "/usr/share/security-manager/policy/"
+#define CONF_GROUP_FILE "privilege-group.list"
+#define CONF_USER_TEMPLATE_FILE "usertype-%s.profile"
+
+namespace SecurityManagerTest {
+
+gid_t nameToGid(const char *name) {
+    struct group entry, *gresult;
+    char buffer[1024];
+    RUNNER_ASSERT_MSG(
+        0 == getgrnam_r(name, &entry, buffer, 1024, &gresult) && (gresult != NULL),
+        "Error in getgrnam. Group name: " << name);
+    return entry.gr_gid;
+}
+
+
+std::string PolicyConfiguration::getConfigFilePath(UserType userType) {
+    const char *user = NULL;
+    switch(userType) {
+    case GUEST:  user = "guest"; break;
+    case NORMAL: user = "normal"; break;
+    case ADMIN:  user = "admin"; break;
+    case SYSTEM: user = "system"; break;
+    }
+    char buffer[1024];
+    snprintf(buffer, 1024, CONF_DIR CONF_USER_TEMPLATE_FILE, user);
+    return std::string(buffer);
+}
+
+PolicyConfiguration::PrivVector PolicyConfiguration::getUserPriv(PolicyConfiguration::UserType userType) {
+    return getUserDescription(userType).privVector;
+}
+
+PolicyConfiguration::GroupVector PolicyConfiguration::getUserGroup(PolicyConfiguration::UserType userType) {
+    return getUserDescription(userType).groupVector;
+}
+
+PolicyConfiguration::GidVector PolicyConfiguration::getUserGid(PolicyConfiguration::UserType userType) {
+    return getUserDescription(userType).gidVector;
+}
+
+PolicyConfiguration::GidVector PolicyConfiguration::getGid() {
+    GroupVector result;
+    if (m_privGroupMap.empty())
+        loadPrivGroupMap();
+    for (auto &e : m_privGroupMap)
+        result.push_back(e.second);
+    return groupToGid(result);
+}
+
+PolicyConfiguration::UserDescription& PolicyConfiguration::getUserDescription(PolicyConfiguration::UserType userType) {
+    auto it = m_userDescriptionMap.find(userType);
+    if (it == m_userDescriptionMap.end())
+        m_userDescriptionMap[userType] = loadUserDescription(userType);
+    return m_userDescriptionMap[userType];
+}
+
+gid_t PolicyConfiguration::groupToGid(const std::string &gname) {
+    auto it = m_groupGidMap.find(gname);
+    if (it == m_groupGidMap.end())
+        m_groupGidMap[gname] = nameToGid(gname.c_str());
+    return m_groupGidMap[gname];
+}
+
+PolicyConfiguration::GidVector PolicyConfiguration::groupToGid(const PolicyConfiguration::GroupVector &groupVector) {
+    GidVector result;
+    for (auto &e : groupVector)
+        result.push_back(groupToGid(e));
+    return result;
+}
+
+PolicyConfiguration::UserDescription PolicyConfiguration::loadUserDescription(PolicyConfiguration::UserType userType) {
+    UserDescription result;
+    std::string path = getConfigFilePath(userType);
+    result.privVector = loadPrivFile(path);
+    result.groupVector = privToGroup(result.privVector);
+    result.gidVector = groupToGid(result.groupVector);
+    return result;
+}
+
+PolicyConfiguration::PrivVector PolicyConfiguration::loadPrivFile(const std::string &path) {
+    PrivVector result;
+    std::ifstream file(path);
+    std::string line;
+    std::regex r("^\\*[ \t]+(.*)");
+    while (std::getline(file, line)) {
+        std::smatch m;
+        if (std::regex_search(line, m, r))
+            result.push_back(m[1]);
+    }
+    return result;
+}
+
+PolicyConfiguration::GroupVector PolicyConfiguration::privToGroup(const PolicyConfiguration::PrivVector &privVector) {
+    GroupVector result;
+    if (m_privGroupMap.empty())
+        loadPrivGroupMap();
+    for (auto &e : privVector) {
+        auto it = m_privGroupMap.find(e);
+        if (it == m_privGroupMap.end())
+            continue;
+        result.push_back(it->second);
+    }
+    return result;
+}
+
+void PolicyConfiguration::loadPrivGroupMap(void) {
+    std::string pgPath(CONF_DIR CONF_GROUP_FILE);
+    std::ifstream file(pgPath);
+
+    RUNNER_ASSERT_MSG(file.is_open(),
+      "Unable to read group mapping file " << pgPath);
+
+    std::string line;
+    std::regex r("^(http(.*)) +(.*)");
+    while (std::getline(file, line)) {
+        std::smatch m;
+        if (std::regex_search(line, m, r))
+            m_privGroupMap[m[1]] = m[3];
+    }
+}
+
+} // namespace SecurityManagerTest
+
diff --git a/src/security-manager-tests/common/policy_configuration.h b/src/security-manager-tests/common/policy_configuration.h
new file mode 100644 (file)
index 0000000..f937e8e
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+#ifndef _SECURITY_MANAGER_TEST_POLICY_CONFIGURATION_
+#define _SECURITY_MANAGER_TEST_POLICY_CONFIGURATION_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include <sys/types.h>
+
+namespace SecurityManagerTest {
+
+gid_t nameToGid(const char *name);
+
+class PolicyConfiguration {
+public:
+    typedef std::vector<gid_t> GidVector;
+    typedef std::vector<std::string> GroupVector;
+    typedef std::vector<std::string> PrivVector;
+
+    struct UserDescription {
+        PrivVector privVector;
+        GroupVector groupVector;
+        GidVector gidVector;
+    };
+
+    enum UserType { GUEST, NORMAL, ADMIN, SYSTEM };
+
+    std::string getConfigFilePath(UserType userType);
+    PrivVector getUserPriv(UserType userType);
+    GroupVector getUserGroup(UserType userType);
+    GidVector getUserGid(UserType userType);
+    GidVector getGid();
+    UserDescription& getUserDescription(UserType userType);
+    gid_t groupToGid(const std::string &gname);
+
+private:
+    GidVector groupToGid(const GroupVector &groupVector);
+    UserDescription loadUserDescription(UserType userType);
+    PrivVector loadPrivFile(const std::string &path);
+    GroupVector privToGroup(const PrivVector &privVector);
+    void loadPrivGroupMap(void);
+
+    std::map<std::string, std::string> m_privGroupMap;
+    std::map<std::string, gid_t> m_groupGidMap;
+    std::map<UserType, UserDescription> m_userDescriptionMap;
+};
+
+} // namespace SecurityManagerTest
+
+#endif
diff --git a/src/security-manager-tests/test_cases_nss.cpp b/src/security-manager-tests/test_cases_nss.cpp
new file mode 100644 (file)
index 0000000..90099e2
--- /dev/null
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+#include <algorithm>
+#include <string>
+#include <vector>
+
+#include <grp.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <dpl/test/test_runner.h>
+#include <dpl/test/test_runner_child.h>
+#include <policy_configuration.h>
+#include <sm_api.h>
+#include <sm_policy_request.h>
+#include <sm_user_request.h>
+#include <temp_test_user.h>
+
+#include <security-manager.h>
+
+using namespace SecurityManagerTest;
+
+RUNNER_TEST_GROUP_INIT(SECURITY_MANAGER_NSS_PLUGIN)
+
+RUNNER_CHILD_TEST(nss_01_unknown_user) {
+    const std::string newUserName = "nss_01_user";
+    PolicyConfiguration pc;
+    TemporaryTestUser testUser(newUserName, GUM_USERTYPE_NORMAL, false);
+    testUser.create();
+
+    auto gidVector = pc.getGid();
+
+    RUNNER_ASSERT_MSG(0 == initgroups(newUserName.c_str(), 0), "Init groups failed");
+
+    gid_t list[64];
+    int grsize = getgroups(64, list);
+    size_t counter = 0;
+
+    for (size_t i=0; i<gidVector.size(); ++i) {
+        for (int j=0; j<grsize; ++j)
+            if(list[j] == gidVector[i]) {
+                counter++;
+                break;
+            }
+    }
+
+    RUNNER_ASSERT_MSG(gidVector.size() == counter,
+        "Process should have all groups related with privileges but it have only " <<
+        counter << " of " << gidVector.size() << " required groups");
+}
+
+RUNNER_CHILD_TEST(nss_02_normal_user_all_priv) {
+    const std::string newUserName = "nss_02_user";
+    PolicyConfiguration pc;
+    TemporaryTestUser testUser(newUserName, GUM_USERTYPE_NORMAL, false);
+    testUser.create();
+
+    auto gidVector = pc.getUserGid(PolicyConfiguration::NORMAL);
+
+    UserRequest addUserRequest;
+    addUserRequest.setUid(testUser.getUid());
+    addUserRequest.setUserType(SM_USER_TYPE_NORMAL);
+    Api::addUser(addUserRequest);
+
+    RUNNER_ASSERT_MSG(0 == initgroups(newUserName.c_str(), 0), "Init groups failed");
+
+    gid_t list[64];
+    int grsize = getgroups(64, list);
+    size_t counter = 0;
+
+    for (size_t i=0; i<gidVector.size(); ++i) {
+        for (int j=0; j<grsize; ++j)
+            if(list[j] == gidVector[i]) {
+                counter++;
+                break;
+            }
+    }
+
+    RUNNER_ASSERT_MSG(gidVector.size() == counter,
+        "Process should have all groups related with privileges but it have only " <<
+        counter << " of " << gidVector.size() << " required groups");
+}
+
+RUNNER_CHILD_TEST(nss_03_normal_user_without_camera) {
+    const std::string newUserName = "nss_03_user";
+    TemporaryTestUser testUser(newUserName, GUM_USERTYPE_NORMAL, false);
+    testUser.create();
+    gid_t cameraPrivId = nameToGid("priv_camera");
+
+    UserRequest addUserRequest;
+    addUserRequest.setUid(testUser.getUid());
+    addUserRequest.setUserType(SM_USER_TYPE_NORMAL);
+    Api::addUser(addUserRequest);
+
+    PolicyRequest policyRequest;
+    PolicyEntry entry(
+        SECURITY_MANAGER_ANY,
+        std::to_string(static_cast<int>(testUser.getUid())),
+        "http://tizen.org/privilege/camera");
+    entry.setMaxLevel("Deny");
+    policyRequest.addEntry(entry);
+    Api::sendPolicy(policyRequest);
+
+    RUNNER_ASSERT_MSG(0 == initgroups(newUserName.c_str(), 0), "Init groups failed");
+
+    gid_t list[64];
+    int grsize = getgroups(64, list);
+    size_t counter = 0;
+
+    for (int i=0; i<grsize; ++i) {
+        if (list[i] == cameraPrivId) {
+            counter++;
+            break;
+        }
+    }
+
+    RUNNER_ASSERT_MSG(0 == counter, "Process should not have priv_camera group");
+
+    PolicyConfiguration pc;
+    auto gidVector = pc.getUserGid(PolicyConfiguration::NORMAL);
+    gidVector.erase(
+        std::remove_if(gidVector.begin(), gidVector.end(), [=](gid_t g) { return g == cameraPrivId; }),
+        gidVector.end());
+
+    for (size_t i=0; i<gidVector.size(); ++i) {
+        for (int j=0; j<grsize; ++j)
+            if(list[j] == gidVector[i]) {
+                counter++;
+                break;
+            }
+    }
+
+    RUNNER_ASSERT_MSG(gidVector.size() == counter,
+        "Process should have all groups related with privileges but it have only " <<
+        counter << " of " << gidVector.size() << " required groups");
+}
+
+RUNNER_CHILD_TEST(nss_04_guest_user) {
+    const std::string newUserName = "nss_04_user";
+    TemporaryTestUser testUser(newUserName, GUM_USERTYPE_GUEST, false);
+    testUser.create();
+
+    UserRequest addUserRequest;
+    addUserRequest.setUid(testUser.getUid());
+    addUserRequest.setUserType(SM_USER_TYPE_GUEST);
+    Api::addUser(addUserRequest);
+
+    RUNNER_ASSERT_MSG(0 == initgroups(newUserName.c_str(), 0), "Init groups failed");
+
+    gid_t list[64];
+    int grsize = getgroups(64, list);
+    size_t counter = 0;
+
+    PolicyConfiguration pc;
+    auto gidVector = pc.getUserGid(PolicyConfiguration::GUEST);
+
+    for (size_t i=0; i<gidVector.size(); ++i) {
+        for (int j=0; j<grsize; ++j)
+            if(list[j] == gidVector[i]) {
+                counter++;
+                break;
+            }
+    }
+
+    RUNNER_ASSERT_MSG(gidVector.size() == counter,
+        "Process should have all groups related with privileges but it have only " <<
+        counter << " of " << gidVector.size() << " required groups");
+}
+
+