Change smack labeling to be appId based. 89/30889/26
authorRoman, Kubiak <r.kubiak@samsung.com>
Wed, 26 Nov 2014 12:43:15 +0000 (04:43 -0800)
committerGerrit Code Review <gerrit@review.vlan103.tizen.org>
Fri, 9 Jan 2015 16:27:06 +0000 (08:27 -0800)
* Generation of rules for all applications in a package so
  that they can share resources

* Smack labels are now appId based (appId refers to app_name
  in the database)

Change-Id: I464ca4b1a4558a0579b9da69b5b599d07340a60d

14 files changed:
src/client/client-common.cpp
src/client/client-security-manager.cpp
src/common/CMakeLists.txt
src/common/cynara.cpp
src/common/include/cynara.h
src/common/include/privilege_db.h
src/common/include/smack-common.h [deleted file]
src/common/include/smack-labels.h
src/common/include/smack-rules.h
src/common/privilege_db.cpp
src/common/service_impl.cpp
src/common/smack-common.cpp [deleted file]
src/common/smack-labels.cpp
src/common/smack-rules.cpp

index 783da66..dd5796a 100644 (file)
@@ -38,7 +38,6 @@
 #include <dpl/singleton_safe_impl.h>
 
 #include <message-buffer.h>
-#include <smack-common.h>
 
 #include <protocols.h>
 
index f9e3484..51b0ad0 100644 (file)
 
 #include <dpl/log/log.h>
 #include <dpl/exception.h>
-
+#include <smack-labels.h>
 #include <message-buffer.h>
 #include <client-common.h>
 #include <protocols.h>
-#include <smack-common.h>
 #include <service_impl.h>
 #include <file-lock.h>
 
@@ -360,7 +359,6 @@ static bool setup_smack(const char *label)
 SECURITY_MANAGER_API
 int security_manager_set_process_label_from_appid(const char *app_id)
 {
-    char *pkg_id;
     int ret;
     std::string appLabel;
 
@@ -369,23 +367,17 @@ int security_manager_set_process_label_from_appid(const char *app_id)
     if (smack_smackfs_path() == NULL)
         return SECURITY_MANAGER_SUCCESS;
 
-    ret = security_manager_get_app_pkgid(&pkg_id, app_id);
-    if (ret != SECURITY_MANAGER_SUCCESS) {
-        return ret;
+    if (SecurityManager::generateAppLabel(std::string(app_id), appLabel) == false) {
+        LogError("Failed to generate smack label for appId: " << app_id);
+        return SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT;
     }
 
-    if (SecurityManager::generateAppLabel(std::string(pkg_id), appLabel)) {
-        ret = setup_smack(appLabel.c_str());
-        if (ret != SECURITY_MANAGER_SUCCESS) {
-            LogError("Failed to set smack label " << appLabel << " for current process");
-        }
-    }
-    else {
-        ret = SECURITY_MANAGER_ERROR_UNKNOWN;
+    if ((ret = setup_smack(appLabel.c_str())) != SECURITY_MANAGER_SUCCESS) {
+        LogError("Failed to set smack label " << appLabel << " for current process");
+        return ret;
     }
 
-    free(pkg_id);
-    return ret;
+    return SECURITY_MANAGER_SUCCESS;
 }
 
 SECURITY_MANAGER_API
index 13bac8e..aebe1bc 100644 (file)
@@ -46,7 +46,6 @@ SET(COMMON_SOURCES
     ${COMMON_PATH}/protocols.cpp
     ${COMMON_PATH}/message-buffer.cpp
     ${COMMON_PATH}/privilege_db.cpp
-    ${COMMON_PATH}/smack-common.cpp
     ${COMMON_PATH}/smack-labels.cpp
     ${COMMON_PATH}/smack-rules.cpp
     ${COMMON_PATH}/smack-check.cpp
index 174f8a1..2073da3 100644 (file)
@@ -161,7 +161,7 @@ void CynaraAdmin::SetPolicies(const std::vector<CynaraAdminPolicy> &policies)
         "Error while updating Cynara policy.");
 }
 
-void CynaraAdmin::UpdatePackagePolicy(
+void CynaraAdmin::UpdateAppPolicy(
     const std::string &label,
     const std::string &user,
     const std::vector<std::string> &oldPrivileges,
index 254ab6c..646deff 100644 (file)
@@ -101,7 +101,7 @@ public:
      * TODO: drop oldPrivileges argument and get them directly from Cynara.
      * Appropriate Cynara interface is needed first.
      */
-    static void UpdatePackagePolicy(const std::string &label, const std::string &user,
+    static void UpdateAppPolicy(const std::string &label, const std::string &user,
         const std::vector<std::string> &oldPrivileges,
         const std::vector<std::string> &newPrivileges);
 
index 5135d93..cf8bdcf 100644 (file)
@@ -45,6 +45,7 @@ const char *const PRIVILEGE_DB_PATH = tzplatform_mkpath(TZ_SYS_DB, ".security-ma
 
 enum class QueryType {
     EGetPkgPrivileges,
+    EGetAppPrivileges,
     EAddApplication,
     ERemoveApplication,
     EAddAppPrivileges,
@@ -53,6 +54,7 @@ enum class QueryType {
     EGetPkgId,
     EGetPrivilegeGroups,
     EGetUserApps,
+    EGetAppsInPkg
 };
 
 class PrivilegeDb {
@@ -71,6 +73,7 @@ private:
     SecurityManager::DB::SqlConnection *mSqlConnection;
     const std::map<QueryType, const char * const > Queries = {
         { QueryType::EGetPkgPrivileges, "SELECT DISTINCT privilege_name FROM app_privilege_view WHERE pkg_name=? AND uid=? ORDER BY privilege_name"},
+        { QueryType::EGetAppPrivileges, "SELECT DISTINCT privilege_name FROM app_privilege_view WHERE app_name=? AND uid=? ORDER BY privilege_name"},
         { QueryType::EAddApplication, "INSERT INTO app_pkg_view (app_name, pkg_name, uid) VALUES (?, ?, ?)" },
         { QueryType::ERemoveApplication, "DELETE FROM app_pkg_view WHERE app_name=? AND uid=?" },
         { QueryType::EAddAppPrivileges, "INSERT INTO app_privilege_view (app_name, uid, privilege_name) VALUES (?, ?, ?)" },
@@ -79,6 +82,7 @@ private:
         { QueryType::EGetPkgId, " SELECT pkg_name FROM app_pkg_view WHERE app_name = ?" },
         { QueryType::EGetPrivilegeGroups, " SELECT name FROM privilege_group_view WHERE privilege_name = ?" },
         { QueryType::EGetUserApps, "SELECT name FROM app WHERE uid=?" },
+        { QueryType::EGetAppsInPkg, " SELECT app_name FROM app_pkg_view WHERE pkg_name = ?" },
     };
 
     /**
@@ -170,16 +174,26 @@ public:
             std::vector<std::string> &currentPrivilege);
 
     /**
+     * Retrieve list of privileges assigned to an appId
+     *
+     * @param appId - application identifier
+     * @param uid - user identifier for whom privileges will be retrieved
+     * @param[out] currentPrivileges - list of current privileges assigned to appId
+     * @exception DB::SqlConnection::Exception::InternalError on internal error
+     */
+    void GetAppPrivileges(const std::string &appId, uid_t uid,
+        std::vector<std::string> &currentPrivileges);
+
+    /**
      * Add an application into the database
      *
      * @param appId - application identifier
      * @param pkgId - package identifier
      * @param uid - user identifier for whom application is going to be installed
-     * @param[out] pkgIdIsNew - return info if pkgId is new to the database
      * @exception DB::SqlConnection::Exception::InternalError on internal error
      */
     void AddApplication(const std::string &appId, const std::string &pkgId,
-            uid_t uid, bool &pkgIdIsNew);
+            uid_t uid);
 
     /**
      * Remove an application from the database
@@ -232,6 +246,15 @@ public:
      * @exception DB::SqlConnection::Exception::InternalError on internal error
      */
     void GetUserApps(uid_t uid, std::vector<std::string> &apps);
+    /**
+     * Retrieve a list of all application ids for a package id
+     *
+     * @param pkgId - package id
+     * @param[out] appIds - list of application ids for the package id
+     * @exception DB::SqlConnection::Exception::InternalError on internal error
+     */
+    void GetAppIdsForPkgId (const std::string &pkgId,
+        std::vector<std::string> &appIds);
 };
 
 } //namespace SecurityManager
diff --git a/src/common/include/smack-common.h b/src/common/include/smack-common.h
deleted file mode 100644 (file)
index 6810764..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- *  Contact: Rafal Krypa <r.krypa@samsung.com>
- *
- *  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
- */
-/*
- * @file        smack-common.h
- * @author      Jacek Bukarewicz <j.bukarewicz@samsung.com>
- * @author      Jan Cybulski <j.cybulski@samsung.com>
- * @version     1.0
- * @brief       Header file for smack-related functions and constants
- */
-#ifndef _SMACK_COMMON_H_
-#define _SMACK_COMMON_H_
-
-#include <string>
-#include <linux/xattr.h>
-
-namespace SecurityManager {
-    /**
-     * Generates label for application with package identifier
-     * read from @ref pkgId and assigns it to @ref label.
-     *
-     * @param[in] pkgId application's package identifier
-     * @param[out] label string in which application's label will be stored
-     * @return true on success, false on error.
-    */
-    bool generateAppLabel(const std::string &pkgId, std::string &label);
-}
-
-#endif /* _SMACK_COMMON_H_ */
-
index 955f54f..e45b085 100644 (file)
@@ -46,6 +46,24 @@ namespace SecurityManager {
 bool setupPath(const std::string &pkgId, const std::string &path,
     app_install_path_type pathType);
 
+/**
+ * Generates label for an application with a specific application ID
+ * read from @ref appId and assigns it to @ref label.
+ *
+ * @param[in] appId application's identifier
+ * @param[out] label string in which application's label will be stored
+ * @return true on success, false on error.
+*/
+bool generateAppLabel(const std::string &appId, std::string &label);
+/**
+ * Generates label for an application with a package ID
+ * read from @ref appPkgId and assigns it to @ref label.
+ *
+ * @param[in] pkgId
+ * @param[out] label
+ * @return true on success, false on error.
+ */
+bool generatePkgLabel(const std::string &pkgId, std::string &label);
 } // namespace SecurityManager
 
 #endif /* _SMACK_LABELS_H_ */
index 3adbea0..5f5dae8 100644 (file)
@@ -40,42 +40,99 @@ public:
 
     bool add(const std::string &subject, const std::string &object,
             const std::string &permissions);
+    bool addModify(const std::string &subject, const std::string &object,
+            const std::string &allowPermissions, const std::string &denyPermissions);
     bool loadFromFile(const std::string &path);
-    bool addFromTemplate(const std::vector<std::string> &templateRules, const std::string &pkgId);
-    bool addFromTemplateFile(const std::string &pkgId);
+    bool addFromTemplate(const std::vector<std::string> &templateRules,
+        const std::string &appId, const std::string &pkgId);
+    bool addFromTemplateFile(const std::string &appId, const std::string &pkgId);
 
     bool apply() const;
     bool clear() const;
     bool saveToFile(const std::string &path) const;
 
     /**
+     * Create cross dependencies for all applications in a package
+     *
+     * This is needed for all applications within a package to have
+     * correct permissions to shared data.
+     *
+     * @param[in] pkgContents - a list of all applications inside this package
+     * @return true on success, false on error
+     */
+    bool generatePackageCrossDeps(const std::vector<std::string> &pkgContents);
+    /**
      * Install package-specific smack rules.
      *
      * Function creates smack rules using predefined template. Rules are applied
      * to the kernel and saved on persistent storage so they are loaded on system boot.
      *
-     * @param[in] pkgId - package identifier
+     * @param[in] appId - application id that is beeing installed
+     * @param[in] pkgId - package id that the application is in
+     * @param[in] pkgContents - a list of all applications in the package
      * @return true on success, false on error
      */
-    static bool installPackageRules(const std::string &pkgId);
+    static bool installApplicationRules(const std::string &appId, const std::string &pkgId,
+        const std::vector<std::string> &pkgContents);
     /**
      * Uninstall package-specific smack rules.
      *
      * Function loads package-specific smack rules, revokes them from the kernel
-     * and removes from persistent storage.
+     * and removes them from the persistent storage.
      *
      * @param[in] pkgId - package identifier
      * @return true if smack rule file has been uninstalled or didn't exist
      *         false otherwise
      */
     static bool uninstallPackageRules(const std::string &pkgId);
-
     /* FIXME: Remove this function if real pkgId instead of "User" label will be used
      * in generateAppLabel(). */
     static bool addMissingRulesFix();
-
+    /**
+    * Uninstall application-specific smack rules.
+    *
+    * Function removes application specific rules from the kernel, and
+    * removes them for persistent storage.
+    *
+    * @param[in] appId - application id
+    * @param[in] pkgId - package id that the application belongs to
+    * @param[in] appsInPkg - a list of other applications in the same package id that the application belongs to
+    * @return true if smack rules have been removed false otherwise
+    */
+    static bool uninstallApplicationRules(const std::string &appId, const std::string &pkgId,
+            std::vector<std::string> appsInPkg);
+    /**
+     * Update package specific rules
+     *
+     * This function regenerates all package rules that
+     * need to exist currently for all application in that
+     * package
+     *
+     * @param[in] pkgId - id of the package to update
+     * @param[in] pkgContents - a list of all applications in the package
+     * @return true in case of success false otherwise
+     */
+    static bool updatePackageRules(const std::string &pkgId, const std::vector<std::string> &pkgContents);
 private:
+    /**
+     * Create a path for package rules
+     *
+     */
     static std::string getPackageRulesFilePath(const std::string &pkgId);
+    /**
+     * Create a path for application rules
+     */
+    static std::string getApplicationRulesFilePath(const std::string &appId);
+    /**
+     * Uninstall rules inside a specified file path
+     *
+     * This is a utility function that will clear all
+     * rules in the file specified by path
+     *
+     * @param[in] path - path to the file that contains the rules
+     * @return true in case of success false otherwise
+     */
+    static bool uninstallRules (const std::string &path);
 
     smack_accesses *m_handle;
 };
index 4d87cdd..53190fa 100644 (file)
@@ -143,10 +143,8 @@ bool PrivilegeDb::GetAppPkgId(const std::string &appId, std::string &pkgId)
 }
 
 void PrivilegeDb::AddApplication(const std::string &appId,
-        const std::string &pkgId, uid_t uid, bool &pkgIdIsNew)
+        const std::string &pkgId, uid_t uid)
 {
-    pkgIdIsNew = !(this->PkgIdExists(pkgId));
-
     try_catch<void>([&] {
         auto &command = getQuery(QueryType::EAddApplication);
         command->BindString(1, appId.c_str());
@@ -203,6 +201,26 @@ void PrivilegeDb::GetPkgPrivileges(const std::string &pkgId, uid_t uid,
     });
 }
 
+void PrivilegeDb::GetAppPrivileges(const std::string &appId, uid_t uid,
+        std::vector<std::string> &currentPrivileges)
+{
+    try_catch<void>([&] {
+        DB::SqlConnection::DataCommandAutoPtr &command =
+                m_commands.at(static_cast<size_t>(QueryType::EGetAppPrivileges));
+
+        command->Reset();
+        command->BindString(1, appId.c_str());
+        command->BindInteger(2, static_cast<unsigned int>(uid));
+        currentPrivileges.clear();
+
+        while (command->Step()) {
+            std::string privilege = command->GetColumnString(0);
+            LogDebug("Got privilege: " << privilege);
+            currentPrivileges.push_back(privilege);
+        };
+    });
+}
+
 void PrivilegeDb::RemoveAppPrivileges(const std::string &appId, uid_t uid)
 {
     try_catch<void>([&] {
@@ -266,5 +284,23 @@ void PrivilegeDb::GetUserApps(uid_t uid, std::vector<std::string> &apps)
     });
 }
 
+void PrivilegeDb::GetAppIdsForPkgId(const std::string &pkgId,
+        std::vector<std::string> &appIds)
+{
+    try_catch<void>([&] {
+        DB::SqlConnection::DataCommandAutoPtr &command =
+                m_commands.at(static_cast<size_t>(QueryType::EGetAppsInPkg));
+
+        command->Reset();
+        command->BindString(1, pkgId.c_str());
+        appIds.clear();
+
+        while (command->Step()) {
+            std::string appId = command->GetColumnString (0);
+            LogDebug ("Got appid: " << appId << " for pkgId " << pkgId);
+            appIds.push_back(appId);
+        };
+    });
+}
 
 } //namespace SecurityManager
index 6660561..f4ec16f 100644 (file)
@@ -36,7 +36,6 @@
 #include "protocols.h"
 #include "privilege_db.h"
 #include "cynara.h"
-#include "smack-common.h"
 #include "smack-rules.h"
 #include "smack-labels.h"
 
@@ -122,10 +121,9 @@ static inline bool installRequestAuthCheck(const app_inst_req &req, uid_t uid)
 
 int appInstall(const app_inst_req &req, uid_t uid)
 {
-    bool pkgIdIsNew = false;
     std::vector<std::string> addedPermissions;
     std::vector<std::string> removedPermissions;
-
+    std::vector<std::string> pkgContents;
     std::string uidstr;
     if (uid) {
         if (uid != req.uid) {
@@ -145,8 +143,8 @@ int appInstall(const app_inst_req &req, uid_t uid)
     }
 
     std::string smackLabel;
-    if (!generateAppLabel(req.pkgId, smackLabel)) {
-        LogError("Cannot generate Smack label for package: " << req.pkgId);
+    if (!generateAppLabel(req.appId, smackLabel)) {
+        LogError("Cannot generate Smack label for application: " << req.appId);
         return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
     }
 
@@ -162,13 +160,11 @@ int appInstall(const app_inst_req &req, uid_t uid)
     pp_permissions[req.privileges.size()] = nullptr;
 
     try {
-        std::vector<std::string> oldPkgPrivileges, newPkgPrivileges;
-
+        std::vector<std::string> oldAppPrivileges;
         LogDebug("Install parameters: appId: " << req.appId << ", pkgId: " << req.pkgId
                  << ", uidstr " << uidstr << ", generated smack label: " << smackLabel);
 
         PrivilegeDb::getInstance().BeginTransaction();
-
         std::string pkg;
         bool ret = PrivilegeDb::getInstance().GetAppPkgId(req.appId, pkg);
         if (ret == true && pkg != req.pkgId) {
@@ -176,12 +172,13 @@ int appInstall(const app_inst_req &req, uid_t uid)
             PrivilegeDb::getInstance().RollbackTransaction();
             return SECURITY_MANAGER_API_ERROR_INPUT_PARAM;
         }
-        PrivilegeDb::getInstance().GetPkgPrivileges(req.pkgId, uid, oldPkgPrivileges);
-        PrivilegeDb::getInstance().AddApplication(req.appId, req.pkgId, uid, pkgIdIsNew);
+        PrivilegeDb::getInstance().GetAppPrivileges(req.appId, uid, oldAppPrivileges);
+        PrivilegeDb::getInstance().AddApplication(req.appId, req.pkgId, uid);
         PrivilegeDb::getInstance().UpdateAppPrivileges(req.appId, uid, req.privileges);
-        PrivilegeDb::getInstance().GetPkgPrivileges(req.pkgId, uid, newPkgPrivileges);
-        CynaraAdmin::UpdatePackagePolicy(smackLabel, uidstr, oldPkgPrivileges,
-                                         newPkgPrivileges);
+        /* Get all application ids in the package to generate rules withing the package */
+        PrivilegeDb::getInstance().GetAppIdsForPkgId(req.pkgId, pkgContents);
+        CynaraAdmin::UpdateAppPolicy(smackLabel, uidstr, oldAppPrivileges,
+                                         req.privileges);
         PrivilegeDb::getInstance().CommitTransaction();
         LogDebug("Application installation commited to database");
     } catch (const PrivilegeDb::Exception::IOError &e) {
@@ -213,12 +210,11 @@ int appInstall(const app_inst_req &req, uid_t uid)
         }
     }
 
-    if (pkgIdIsNew) {
-        LogDebug("Adding Smack rules for new pkgId " << req.pkgId);
-        if (!SmackRules::installPackageRules(req.pkgId)) {
-            LogError("Failed to apply package-specific smack rules");
-            return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
-        }
+    LogDebug("Adding Smack rules for new appId: " << req.appId << " with pkgId: "
+            << req.pkgId << ". Applications in package: " << pkgContents.size());
+    if (!SmackRules::installApplicationRules(req.appId, req.pkgId, pkgContents)) {
+        LogError("Failed to apply package-specific smack rules");
+        return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
     }
 
     return SECURITY_MANAGER_API_SUCCESS;
@@ -228,13 +224,14 @@ int appUninstall(const std::string &appId, uid_t uid)
 {
     std::string pkgId;
     std::string smackLabel;
+    std::vector<std::string> pkgContents;
     bool appExists = true;
     bool removePkg = false;
     std::string uidstr;
     checkGlobalUser(uid, uidstr);
 
     try {
-        std::vector<std::string> oldPkgPrivileges, newPkgPrivileges;
+        std::vector<std::string> oldAppPrivileges;
 
         PrivilegeDb::getInstance().BeginTransaction();
         if (!PrivilegeDb::getInstance().GetAppPkgId(appId, pkgId)) {
@@ -247,17 +244,20 @@ int appUninstall(const std::string &appId, uid_t uid)
             LogDebug("Uninstall parameters: appId: " << appId << ", pkgId: " << pkgId
                      << ", uidstr " << uidstr << ", generated smack label: " << smackLabel);
 
-            if (!generateAppLabel(pkgId, smackLabel)) {
+            if (!generateAppLabel(appId, smackLabel)) {
                 LogError("Cannot generate Smack label for package: " << pkgId);
                 return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
             }
 
-            PrivilegeDb::getInstance().GetPkgPrivileges(pkgId, uid, oldPkgPrivileges);
+            /* Before we remove the app from the database, let's fetch all apps in the package
+                that this app belongs to, this will allow us to remove all rules withing the
+                package that the app appears in */
+            PrivilegeDb::getInstance().GetAppIdsForPkgId(pkgId, pkgContents);
+            PrivilegeDb::getInstance().GetAppPrivileges(appId, uid, oldAppPrivileges);
             PrivilegeDb::getInstance().UpdateAppPrivileges(appId, uid, std::vector<std::string>());
             PrivilegeDb::getInstance().RemoveApplication(appId, uid, removePkg);
-            PrivilegeDb::getInstance().GetPkgPrivileges(pkgId, uid, newPkgPrivileges);
-            CynaraAdmin::UpdatePackagePolicy(smackLabel, uidstr, oldPkgPrivileges,
-                                             newPkgPrivileges);
+            CynaraAdmin::UpdateAppPolicy(smackLabel, uidstr, oldAppPrivileges,
+                                             std::vector<std::string>());
             PrivilegeDb::getInstance().CommitTransaction();
             LogDebug("Application uninstallation commited to database");
         }
@@ -287,6 +287,11 @@ int appUninstall(const std::string &appId, uid_t uid)
                 return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
             }
         }
+        LogDebug ("Removing smack rules for deleted appId " << appId);
+        if (!SmackRules::uninstallApplicationRules(appId, pkgId, pkgContents)) {
+            LogError("Error during uninstallation of application-specific smack rules");
+            return SECURITY_MANAGER_API_ERROR_SERVER_ERROR;
+        }
     }
 
     return SECURITY_MANAGER_API_SUCCESS;
@@ -326,9 +331,8 @@ int getAppGroups(const std::string &appId, uid_t uid, pid_t pid, std::unordered_
             return SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT;
         }
         LogDebug("pkgId: " << pkgId);
-
-        if (!generateAppLabel(pkgId, smackLabel)) {
-             LogError("Cannot generate Smack label for package: " << pkgId);
+        if (!generatePkgLabel(pkgId, smackLabel)) {
+            LogError("Cannot generate Smack label for pkgId: " << pkgId);
             return SECURITY_MANAGER_API_ERROR_NO_SUCH_OBJECT;
         }
         LogDebug("smack label: " << smackLabel);
diff --git a/src/common/smack-common.cpp b/src/common/smack-common.cpp
deleted file mode 100644 (file)
index 173a368..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
- *
- *  Contact: Rafal Krypa <r.krypa@samsung.com>
- *
- *  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
- */
-/*
- * @file        smack-common.cpp
- * @author      Jacek Bukarewicz <j.bukarewicz@samsung.com>
- * @author      Jan Cybulski <j.cybulski@samsung.com>
- * @version     1.0
- * @brief       Implementation of smack-related functions
- */
-
-#include <smack-common.h>
-
-namespace SecurityManager {
-
-bool generateAppLabel(const std::string &appPkgId, std::string &label)
-{
-    (void) appPkgId; // TODO use pkgId to generate label
-    label = "User";
-    return true;
-}
-
-} // namespace SecurityManager
-
index 45bab51..7b68a45 100644 (file)
@@ -34,7 +34,6 @@
 #include <string>
 
 #include <dpl/log/log.h>
-#include <smack-common.h>
 
 #include "security-manager.h"
 #include "smack-labels.h"
@@ -166,7 +165,7 @@ bool setupPath(const std::string &pkgId, const std::string &path,
 
     switch (pathType) {
     case SECURITY_MANAGER_PATH_PRIVATE:
-        if (!generateAppLabel(pkgId, label))
+        if (!generatePkgLabel(pkgId, label))
             return false;
         label_executables = true;
         label_transmute = false;
@@ -188,4 +187,18 @@ bool setupPath(const std::string &pkgId, const std::string &path,
     return labelDir(path, label, label_transmute, label_executables);
 }
 
+bool generateAppLabel(const std::string &appId, std::string &label)
+{
+    (void) appId;
+    label = "User";
+    return true;
+}
+
+bool generatePkgLabel(const std::string &pkgId, std::string &label)
+{
+    (void) pkgId;
+    label = "User";
+    return (true);
+}
+
 } // namespace SecurityManager
index 1b637bd..b2dceb9 100644 (file)
 #include <dpl/log/log.h>
 #include <tzplatform_config.h>
 
-#include <smack-common.h>
 #include "smack-labels.h"
 #include "smack-rules.h"
 
 namespace SecurityManager {
 
 const char *const SMACK_APP_LABEL_TEMPLATE     = "~APP~";
+const char *const SMACK_PKG_LABEL_TEMPLATE     = "~PKG~";
 const char *const APP_RULES_TEMPLATE_FILE_PATH = tzplatform_mkpath(TZ_SYS_SMACK, "app-rules-template.smack");
+const char *const SMACK_APP_IN_PACKAGE_PERMS   = "rwxat";
 
 SmackRules::SmackRules()
 {
@@ -63,6 +64,12 @@ bool SmackRules::add(const std::string &subject, const std::string &object,
     return 0 == smack_accesses_add(m_handle, subject.c_str(), object.c_str(), permissions.c_str());
 }
 
+bool SmackRules::addModify(const std::string &subject, const std::string &object,
+        const std::string &allowPermissions, const std::string &denyPermissions)
+{
+    return 0 == smack_accesses_add_modify(m_handle, subject.c_str(), object.c_str(), allowPermissions.c_str(), denyPermissions.c_str());
+}
+
 bool SmackRules::clear() const
 {
     return 0 == smack_accesses_clear(m_handle);
@@ -130,7 +137,8 @@ bool SmackRules::saveToFile(const std::string &path) const
 }
 
 
-bool SmackRules::addFromTemplateFile(const std::string &pkgId)
+bool SmackRules::addFromTemplateFile(const std::string &appId,
+        const std::string &pkgId)
 {
     std::vector<std::string> templateRules;
     std::string line;
@@ -150,11 +158,11 @@ bool SmackRules::addFromTemplateFile(const std::string &pkgId)
         return false;
     }
 
-    return addFromTemplate(templateRules, pkgId);
+    return addFromTemplate(templateRules, appId, pkgId);
 }
 
 bool SmackRules::addFromTemplate(const std::vector<std::string> &templateRules,
-        const std::string &pkgId)
+        const std::string &appId, const std::string &pkgId)
 {
     for (auto rule : templateRules) {
         if (rule.empty())
@@ -169,24 +177,30 @@ bool SmackRules::addFromTemplate(const std::vector<std::string> &templateRules,
             return false;
         }
 
-        bool subjectIsTemplate = (subject == SMACK_APP_LABEL_TEMPLATE);
-        bool objectIsTemplate = (object == SMACK_APP_LABEL_TEMPLATE);
+        if (subject == SMACK_APP_LABEL_TEMPLATE) {
+            if (!generateAppLabel(appId, subject)) {
+                LogError("Failed to generate app label from appId: " << appId);
+                return false;
+            }
+        }
 
-        if (objectIsTemplate == subjectIsTemplate) {
-            LogError("Invalid rule template. Exactly one app label template expected: " << rule);
-            return false;
+        if (subject == SMACK_PKG_LABEL_TEMPLATE) {
+            if (!generatePkgLabel(pkgId, object)) {
+                LogError("Failed to generate pkg label from pkgid: " << pkgId);
+                return false;
+            }
         }
 
-        if (subjectIsTemplate) {
-            if (!generateAppLabel(pkgId, subject)) {
-                LogError("Failed to generate app label from pkgid: " << pkgId);
+        if (object == SMACK_APP_LABEL_TEMPLATE) {
+            if (!generateAppLabel(appId, object)) {
+                LogError("Failed to generate app label from appId: " << appId);
                 return false;
             }
         }
 
-        if (objectIsTemplate) {
-            if (!generateAppLabel(pkgId, object)) {
-                LogError("Failed to generate app label from pkgid: " << pkgId);
+        if (object == SMACK_PKG_LABEL_TEMPLATE) {
+            if (!generatePkgLabel(pkgId, object)) {
+                LogError("Failed to generate pkg label from pkgId: " << pkgId);
                 return false;
             }
         }
@@ -200,38 +214,111 @@ bool SmackRules::addFromTemplate(const std::vector<std::string> &templateRules,
     return true;
 }
 
+bool SmackRules::generatePackageCrossDeps(const std::vector<std::string> &pkgContents)
+{
+    LogDebug ("Generating cross-package rules");
+
+    std::string subjectLabel, objectLabel;
+    std::string appsInPackagePerms = SMACK_APP_IN_PACKAGE_PERMS;
+
+    for (const auto &subject : pkgContents) {
+        for (const auto &object : pkgContents) {
+            if (object == subject)
+                continue;
+
+            if (generateAppLabel(subject, subjectLabel) && generateAppLabel(object, objectLabel)) {
+                LogDebug ("Trying to add rule subject: " << subjectLabel << " object: " << objectLabel
+                            << " perms: " << appsInPackagePerms);
+                if (!add (subjectLabel, objectLabel, appsInPackagePerms)) {
+                    LogError ("Can't add in-package rule for subject: "
+                                << subject << " and object: " << object);
+                    return false;
+                }
+            }
+            else {
+                LogError ("Failed to created smack labels for subject: "
+                            << subject << " and object: " << object);
+                return false;
+            }
+        }
+    }
+
+    return true;
+}
+
 std::string SmackRules::getPackageRulesFilePath(const std::string &pkgId)
 {
-    std::string path(tzplatform_mkpath3(TZ_SYS_SMACK, "accesses.d", pkgId.c_str()));
+    std::string path(tzplatform_mkpath3(TZ_SYS_SMACK, "accesses.d", ("pkg_" + pkgId).c_str()));
     return path;
 }
 
-bool SmackRules::installPackageRules(const std::string &pkgId)
+std::string SmackRules::getApplicationRulesFilePath(const std::string &appId)
 {
+    std::string path(tzplatform_mkpath3(TZ_SYS_SMACK, "accesses.d", ("app_" +  appId).c_str()));
+    return path;
+}
+
+bool SmackRules::installApplicationRules(const std::string &appId, const std::string &pkgId,
+        const std::vector<std::string> &pkgContents) {
     try {
-         SmackRules smackRules;
-         std::string path = getPackageRulesFilePath(pkgId);
+        SmackRules smackRules;
+        std::string appPath = getApplicationRulesFilePath(appId);
 
-         if (!smackRules.addFromTemplateFile(pkgId)) {
-             LogError("Failed to load smack rules for pkgId " << pkgId);
-             return false;
-         }
+        if (!smackRules.addFromTemplateFile(appId, pkgId)) {
+            LogError("Failed to load smack rules for appId: " << appId << " with pkgId: " << pkgId);
+            return false;
+        }
+
+        if (smack_smackfs_path() != NULL && !smackRules.apply()) {
+            LogError("Failed to apply application rules to kernel [app]");
+            return false;
+        }
+
+        if (!smackRules.saveToFile(appPath)) {
+            smackRules.clear();
+            return false;
+        }
+
+        if (!updatePackageRules(pkgId, pkgContents))
+        {
+            return false;
+        }
 
-         if (smack_smackfs_path() != NULL && !smackRules.apply()) {
-             LogError("Failed to apply application rules to kernel");
+        return true;
+    } catch (const std::bad_alloc &e) {
+        LogError("Out of memory while trying to install smack rules for appId: "
+                << appId << "in pkgId: " << pkgId);
+        return false;
+    }
+}
+
+bool SmackRules::updatePackageRules(const std::string &pkgId, const std::vector<std::string> &pkgContents)
+{
+    try {
+        SmackRules smackRules;
+        std::string pkgPath = getPackageRulesFilePath(pkgId);
+
+        if (!smackRules.generatePackageCrossDeps(pkgContents))
+        {
+            LogError("Failed to create application in-package cross dependencies");
+            return false;
+        }
+
+        if (smack_smackfs_path() != NULL && !smackRules.apply()) {
+             LogError("Failed to apply application rules to kernel [pkg]");
              return false;
          }
 
-         if (!smackRules.saveToFile(path)) {
+         if (!smackRules.saveToFile(pkgPath)) {
              smackRules.clear();
              return false;
          }
 
          return true;
-     } catch (const std::bad_alloc &e) {
-         LogError("Out of memory while trying to install smack rules for pkgId " << pkgId);
-         return false;
-     }
+    } catch (const std::bad_alloc &e) {
+        LogError("Out of memory while trying to install smack rules for pkgId: " << pkgId);
+        return false;
+    }
 }
 
 /* FIXME: Remove this function if real pkgId instead of "User" label will be used
@@ -263,10 +350,42 @@ bool SmackRules::addMissingRulesFix()
 
 bool SmackRules::uninstallPackageRules(const std::string &pkgId)
 {
-    std::string path = getPackageRulesFilePath(pkgId);
+    if (!uninstallRules(getPackageRulesFilePath(pkgId)))
+    {
+        LogError("Failed to uninstall application rules for pkgId: " << pkgId);
+        return false;
+    }
+
+    return true;
+}
+
+bool SmackRules::uninstallApplicationRules(const std::string &appId,
+        const std::string &pkgId, std::vector<std::string> pkgContents)
+{
+    if (!uninstallRules (getApplicationRulesFilePath(appId)))
+    {
+        LogError("Failed to uninstall application rules for appId: " << appId);
+        return false;
+    }
+
+    if (!updatePackageRules(pkgId, pkgContents))
+    {
+        LogError("failed to update package rules for appId: " << appId
+                << " pkgId: " << pkgId);
+        return false;
+    }
+
+    // FIXME: Reloading all rules:
+    SmackRules::addMissingRulesFix();
+
+    return true;
+}
+
+bool SmackRules::uninstallRules(const std::string &path)
+{
     if (access(path.c_str(), F_OK) == -1) {
         if (errno == ENOENT) {
-            LogWarning("Smack rules were not installed for pkgId: " << pkgId);
+            LogWarning("Smack rules not found in file: " << path);
             return true;
         }
 
@@ -278,7 +397,7 @@ bool SmackRules::uninstallPackageRules(const std::string &pkgId)
         SmackRules rules;
         if (rules.loadFromFile(path)) {
             if (smack_smackfs_path() != NULL && !rules.clear()) {
-                LogWarning("Failed to clear smack kernel rules for pkgId: " << pkgId);
+                LogWarning("Failed to clear smack kernel rules from file: " << path);
                 // don't stop uninstallation
             }
         } else {
@@ -290,15 +409,11 @@ bool SmackRules::uninstallPackageRules(const std::string &pkgId)
             LogError("Failed to remove smack rules file: " << path);
             return false;
         }
-
-        // FIXME: Reloading all rules:
-        SmackRules::addMissingRulesFix();
-
-        return true;
     } catch (const std::bad_alloc &e) {
-        LogError("Out of memory while trying to uninstall smack rules for pkgId: " << pkgId);
+        LogError("Out of memory while trying to uninstall smack rules from path: " << path);
         return false;
     }
+    return true;
 }
 
 } // namespace SecurityManager