#include <dpl/singleton_safe_impl.h>
#include <message-buffer.h>
-#include <smack-common.h>
#include <protocols.h>
#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>
SECURITY_MANAGER_API
int security_manager_set_process_label_from_appid(const char *app_id)
{
- char *pkg_id;
int ret;
std::string appLabel;
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
${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
"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,
* 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);
enum class QueryType {
EGetPkgPrivileges,
+ EGetAppPrivileges,
EAddApplication,
ERemoveApplication,
EAddAppPrivileges,
EGetPkgId,
EGetPrivilegeGroups,
EGetUserApps,
+ EGetAppsInPkg
};
class PrivilegeDb {
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 (?, ?, ?)" },
{ 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 = ?" },
};
/**
std::vector<std::string> ¤tPrivilege);
/**
+ * 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> ¤tPrivileges);
+
+ /**
* 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
* @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
+++ /dev/null
-/*
- * 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_ */
-
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_ */
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;
};
}
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());
});
}
+void PrivilegeDb::GetAppPrivileges(const std::string &appId, uid_t uid,
+ std::vector<std::string> ¤tPrivileges)
+{
+ 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>([&] {
});
}
+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
#include "protocols.h"
#include "privilege_db.h"
#include "cynara.h"
-#include "smack-common.h"
#include "smack-rules.h"
#include "smack-labels.h"
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) {
}
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;
}
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) {
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) {
}
}
- 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;
{
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)) {
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");
}
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;
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);
+++ /dev/null
-/*
- * 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
-
#include <string>
#include <dpl/log/log.h>
-#include <smack-common.h>
#include "security-manager.h"
#include "smack-labels.h"
switch (pathType) {
case SECURITY_MANAGER_PATH_PRIVATE:
- if (!generateAppLabel(pkgId, label))
+ if (!generatePkgLabel(pkgId, label))
return false;
label_executables = true;
label_transmute = false;
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
#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()
{
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);
}
-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;
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())
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;
}
}
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
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;
}
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 {
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