security-manager: fix tests related to privacy privileges 51/168851/5
authorRafal Krypa <r.krypa@samsung.com>
Wed, 17 Jan 2018 17:23:30 +0000 (18:23 +0100)
committerZofia Grzelewska <z.abramowska@samsung.com>
Tue, 6 Feb 2018 10:00:21 +0000 (11:00 +0100)
When application is registered in security-manager with privileges
that should be set as privacy, it is required to first register the
app in security-privilege-manager. Otherwise, when security-manager
checks if a privilege is privacy, it will always see privileges as
non-privacy.

This patch fixes the following tests:
- security_manager_ap1_app_policy_fetch_for_self
- security_manager_18_privacy_manager_privacy_related_privileges_policy_install_remove
- security_manager_19a_privacy_manager_privacy_related_privileges_policy_hybrid
- security_manager_19b_privacy_manager_privacy_related_privileges_policy_no_hybrid
- security_manager_20_privacy_manager_privacy_related_privileges_policy_admin_check

Change-Id: I34ec671f02a42e175ecbd53c428d17fcee65e909
Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
src/common/CMakeLists.txt
src/common/app_def_privilege.h
src/common/pkg_privacy_privileges.h [new file with mode: 0644]
src/common/privilege_manager.cpp [new file with mode: 0644]
src/common/privilege_manager.h [new file with mode: 0644]
src/security-manager-tests/test_cases_app_policy.cpp
src/security-manager-tests/test_cases_privacy_manager.cpp

index caccd72..dc9aeeb 100644 (file)
@@ -13,6 +13,7 @@ PKG_CHECK_MODULES(COMMON_TARGET_DEP
     cynara-creds-dbus
     cynara-creds-gdbus
     security-manager
+    security-privilege-manager
     REQUIRED
     )
 
@@ -44,6 +45,7 @@ SET(COMMON_TARGET_TEST_SOURCES
     ${PROJECT_SOURCE_DIR}/src/common/sm_user_request.cpp
     ${PROJECT_SOURCE_DIR}/src/common/sm_policy_request.cpp
     ${PROJECT_SOURCE_DIR}/src/common/tzplatform.cpp
+    ${PROJECT_SOURCE_DIR}/src/common/privilege_manager.cpp
     )
 
 #system and local includes
index 6d00972..d399dac 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2017 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2018 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.
@@ -29,6 +29,7 @@ public:
         UNSET,
         UNTRUSTED,
         LICENSED,
+        PRIVACY,
     };
 
     Privilege(std::string systemPrivilege, Type type = UNSET, std::string license = std::string())
@@ -46,6 +47,7 @@ public:
     bool isUnset() const { return m_type == UNSET; }
     bool isUntrusted() const { return m_type == UNTRUSTED; }
     bool isLicensed() const { return m_type == LICENSED; }
+    bool isPrivacy() const { return m_type == PRIVACY; }
 
     int getType() const { return m_type; }
     app_defined_privilege_type getSMType () const {
diff --git a/src/common/pkg_privacy_privileges.h b/src/common/pkg_privacy_privileges.h
new file mode 100644 (file)
index 0000000..dfa6db5
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#pragma once
+
+#include <string>
+#include <sys/types.h>
+#include <vector>
+
+#include <app_def_privilege.h>
+#include <app_install_helper.h>
+#include <privilege_manager.h>
+#include <memory.h>
+#include <dpl/test/safe_cleanup.h>
+
+class PkgPrivacyPrivileges {
+public:
+    PkgPrivacyPrivileges(const AppInstallHelper &app)
+        : m_pkgId(app.getPkgId()),
+          m_uid(app.getUID()),
+          m_creatorPid(getpid()),
+          m_shouldUnsetPrivacy(false)
+    {
+        std::vector<std::string> privacyPrivileges;
+        for (const Privilege &privilege : app.getPrivileges())
+            if (privilege.isPrivacy())
+                privacyPrivileges.push_back(privilege.getName());
+
+        if (!privacyPrivileges.empty()) {
+            PrivilegeManager::setPrivacyPrivileges(
+                app.getUID(), app.getPkgId(), app.getVersion(), privacyPrivileges);
+            m_shouldUnsetPrivacy = true;
+        }
+    }
+
+    PkgPrivacyPrivileges(const PkgPrivacyPrivileges &) = delete;
+    PkgPrivacyPrivileges(PkgPrivacyPrivileges &&other)
+        : m_pkgId(std::move(other.m_pkgId)),
+          m_uid(other.m_uid),
+          m_shouldUnsetPrivacy(other.m_shouldUnsetPrivacy)
+    {
+        other.m_uid = 0;
+        other.m_shouldUnsetPrivacy = false;
+        other.m_creatorPid = -1;
+    }
+
+    PkgPrivacyPrivileges& operator=(const PkgPrivacyPrivileges &) = delete;
+
+    virtual ~PkgPrivacyPrivileges() {
+        if (m_creatorPid == getpid())
+        {
+            SafeCleanup::run([this]{ unsetPrivacy(); });
+        }
+    }
+
+    void unsetPrivacy() {
+        if (!m_shouldUnsetPrivacy)
+            return;
+        PrivilegeManager::unsetPrivacyPrivileges(m_uid, m_pkgId);
+        m_shouldUnsetPrivacy = false;
+    }
+
+protected:
+    std::string m_pkgId;
+    uid_t m_uid;
+    pid_t m_creatorPid;
+    bool m_shouldUnsetPrivacy;
+};
diff --git a/src/common/privilege_manager.cpp b/src/common/privilege_manager.cpp
new file mode 100644 (file)
index 0000000..01d1f47
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2018 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 <new>
+#include <glib.h>
+#include <gmodule.h>
+
+#include "dpl/test/test_runner.h"
+#include "privilege_manager.h"
+
+namespace PrivilegeManager {
+
+void setPrivacyPrivileges(const uid_t uid, const std::string &pkgId,
+    const std::string &tizenVersion, const std::vector<std::string> &privileges,
+    const privilege_manager_package_type_e &type)
+{
+    GList *list = nullptr;
+
+    for (const std::string &privilege : privileges) {
+        gchar *str = g_strdup(privilege.c_str());
+        if (str == nullptr) {
+            g_list_free_full(list, g_free);
+            throw std::bad_alloc();
+        }
+
+        GList *listNew = g_list_append(list, str);
+        if (listNew == nullptr) {
+            g_list_free_full(list, g_free);
+            throw std::bad_alloc();
+        }
+
+        list = listNew;
+    }
+
+    int ret = privilege_package_info_set_privacy_privilege(uid, pkgId.c_str(),
+        type, tizenVersion.empty() ? "4.0" : tizenVersion.c_str(), list);
+    g_list_free_full(list, g_free);
+
+    RUNNER_ASSERT_MSG(ret == PRVMGR_ERR_NONE,
+        "privilege_package_info_set_privacy_privilege failed: " << ret);
+}
+
+void unsetPrivacyPrivileges(const uid_t uid, const std::string &pkgId)
+{
+    int ret = privilege_package_info_unset_package_privilege_info(
+        uid, pkgId.c_str());
+
+    RUNNER_ASSERT_MSG(ret == PRVMGR_ERR_NONE,
+        "privilege_package_info_unset_privacy_privilege failed: " << ret);
+}
+
+} // namespace PrivilegeManager
diff --git a/src/common/privilege_manager.h b/src/common/privilege_manager.h
new file mode 100644 (file)
index 0000000..b46414a
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2018 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.
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+#include <privilege_package_info.h>
+
+namespace PrivilegeManager {
+
+void setPrivacyPrivileges(const uid_t uid, const std::string &pkgId,
+    const std::string &tizenVersion, const std::vector<std::string> &privileges,
+    const privilege_manager_package_type_e &type = PRVMGR_PACKAGE_TYPE_CORE);
+
+void unsetPrivacyPrivileges(const uid_t uid, const std::string &pkgId);
+
+} // namespace PrivilegeManager
index afd9a09..bb3ab94 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016-2018 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.
@@ -18,6 +18,7 @@
 #include <vector>
 
 #include <app_install_helper.h>
+#include <pkg_privacy_privileges.h>
 #include <scoped_installer.h>
 #include <sm_api.h>
 #include <sm_commons.h>
 #include <dpl/test/test_runner.h>
 #include <dpl/test/test_runner_child.h>
 
-const std::vector<std::string> TEST_PRIVACY_PRIVILEGES = {
-        "http://tizen.org/privilege/callhistory.read",
-        "http://tizen.org/privilege/account.read",
-        "http://tizen.org/privilege/healthinfo" };
+const PrivilegeVector TEST_PRIVACY_PRIVILEGES = {
+    Privilege("http://tizen.org/privilege/callhistory.read", Privilege::PRIVACY),
+    Privilege("http://tizen.org/privilege/account.read", Privilege::PRIVACY),
+    Privilege("http://tizen.org/privilege/healthinfo", Privilege::PRIVACY) };
 
 using namespace SecurityManagerTest;
 
@@ -49,6 +50,7 @@ RUNNER_CHILD_TEST(security_manager_ap1_app_policy_fetch_for_self) {
     RUNNER_ASSERT_MSG(isAskuserDisabled() || expectedPolicyCount > 0,
             "Application won't be installed with any privacy privileges, fix test");
 
+    PkgPrivacyPrivileges setupPrivacyPrivs(app);
     ScopedInstaller appInstall(app);
 
     pid_t pid = fork();
@@ -103,6 +105,7 @@ RUNNER_CHILD_TEST(security_manager_ap2_app_policy_fetch_for_self_different_user)
     AppInstallHelper app("sm_test_ap2", tmpUser.getUid());
     app.addPrivileges(TEST_PRIVACY_PRIVILEGES);
 
+    PkgPrivacyPrivileges setupPrivacyPrivs(app);
     ScopedInstaller appInstall(app);
 
     pid_t pid = fork();
@@ -137,6 +140,7 @@ RUNNER_CHILD_TEST(security_manager_ap3_app_policy_fetch_for_self_different_user_
     app.setInstallType(SM_APP_INSTALL_GLOBAL);
     app.addPrivileges(TEST_PRIVACY_PRIVILEGES);
 
+    PkgPrivacyPrivileges setupPrivacyPrivs(app);
     ScopedInstaller appInstall(app);
 
     pid_t pid = fork();
@@ -171,7 +175,10 @@ RUNNER_CHILD_TEST(security_manager_ap3_app_policy_fetch_for_self_different_app)
     AppInstallHelper app2("sm_test_ap3_2", tmpUser.getUid());
     app2.addPrivileges(TEST_PRIVACY_PRIVILEGES);
 
+    PkgPrivacyPrivileges setupPrivacyPrivs1(app1);
     ScopedInstaller appInstall1(app1);
+
+    PkgPrivacyPrivileges setupPrivacyPrivs2(app2);
     ScopedInstaller appInstall2(app2);
 
     pid_t pid = fork();
index d40e864..eeec39a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016-2018 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.
@@ -28,6 +28,7 @@
 #include <cynara_test_admin.h>
 #include <dpl/test/test_runner.h>
 #include <dpl/test/test_runner_child.h>
+#include <pkg_privacy_privileges.h>
 #include <policy_configuration.h>
 #include <scoped_installer.h>
 #include <sm_api.h>
@@ -78,18 +79,18 @@ const std::vector<Privileges> TEST_PRIVILEGES = {
     }
 };
 
-const std::vector<Privileges> TEST_PRIVACY_PRIVILEGES = {
+const PrivilegeVector TEST_PRIVACY_PRIVILEGES[] = {
     {
-        "http://tizen.org/privilege/telephony",
-        "http://tizen.org/privilege/led",
-        "http://tizen.org/privilege/callhistory.read", // privacy-related privileges start here
-        "http://tizen.org/privilege/account.read",
-        "http://tizen.org/privilege/healthinfo"
+        Privilege("http://tizen.org/privilege/telephony"),
+        Privilege("http://tizen.org/privilege/led"),
+        Privilege("http://tizen.org/privilege/callhistory.read", Privilege::PRIVACY),
+        Privilege("http://tizen.org/privilege/account.read", Privilege::PRIVACY),
+        Privilege("http://tizen.org/privilege/healthinfo", Privilege::PRIVACY),
     },
     {
-        "http://tizen.org/privilege/telephony",
-        "http://tizen.org/privilege/led",
-        "http://tizen.org/privilege/callhistory.read" // privacy-related privileges start here
+        Privilege("http://tizen.org/privilege/telephony"),
+        Privilege("http://tizen.org/privilege/led"),
+        Privilege("http://tizen.org/privilege/callhistory.read", Privilege::PRIVACY),
     }
 };
 
@@ -836,6 +837,7 @@ RUNNER_CHILD_TEST(security_manager_18_privacy_manager_privacy_related_privileges
     PolicyEntry filter (app.getAppId(), user.getUidString(), SECURITY_MANAGER_ANY);
     std::vector<PolicyEntry> policyEntries;
     {
+        PkgPrivacyPrivileges setupPrivacyPrivs(app);
         ScopedInstaller installer(app);
         unsigned int privacyNum = countPrivacyPrivileges(app.getPrivileges());
 
@@ -878,12 +880,14 @@ void test_privacy_related_privileges(bool isHybrid) {
     if (isHybrid)
         app1.setHybrid();
     app1.addPrivileges(TEST_PRIVACY_PRIVILEGES[0]);
+    PkgPrivacyPrivileges setupPrivacyPrivs1(app1);
     ScopedInstaller installer1(app1);
 
     AppInstallHelper app2("sm_test_19_app_id_2", pkgId, user.getUid());
     if (isHybrid)
         app2.setHybrid();
     app2.addPrivileges(TEST_PRIVACY_PRIVILEGES[1]);
+    PkgPrivacyPrivileges setupPrivacyPrivs2(app2);
     ScopedInstaller installer2(app2);
 
     int privacyCount1, privacyCount2;
@@ -941,6 +945,7 @@ RUNNER_CHILD_TEST(security_manager_20_privacy_manager_privacy_related_privileges
     AppInstallHelper app("sm_test_20", user.getUid());
     app.addPrivileges(TEST_PRIVACY_PRIVILEGES[0]);
 
+    PkgPrivacyPrivileges setupPrivacyPrivs(app);
     ScopedInstaller installer(app);
 
     CynaraTestAdmin::Admin admin;