SRC_PATH=/etc/smack/accesses.d
DSC_PATH=@LOCAL_STATE_DIR@/security-manager/rules
MRG_PATH=@LOCAL_STATE_DIR@/security-manager/rules-merged/rules.merged
+SHARED_RO_PATH=$DSC_PATH/2x_shared_ro
-if [ -e $MRG_PATH ]; then
- echo "No migration needed. File ${MRG_PATH} already exists."
- exit 0
+echo "Running migration process"
+
+if [ ! -e $MRG_PATH ]
+then
+ echo "Moving files from ${SRC_PATH} to ${DSC_PATH}"
+ mv ${SRC_PATH}/app_* ${SRC_PATH}/pkg_* ${SRC_PATH}/author_* ${DSC_PATH}
+ echo "Merging files from ${DSC_PATH} to ${MRG_PATH}"
+ cat ${DSC_PATH}/* > ${MRG_PATH}
fi
-echo "Running migration process"
-echo "Moving files from ${SRC_PATH} to ${DSC_PATH}"
-mv ${SRC_PATH}/app_* ${SRC_PATH}/pkg_* ${SRC_PATH}/author_* ${DSC_PATH}
-echo "Merging files from ${DSC_PATH} to ${MRG_PATH}"
-cat ${DSC_PATH}/* > ${MRG_PATH}
-echo "Migration process was finished"
+if [ ! -e $SHARED_RO_PATH ]
+then
+ echo "Moving SharedRO rules to ${SHARED_RO_PATH}"
+ cat ${DSC_PATH}/pkg_* | grep 'User::App.*SharedRO' >${SHARED_RO_PATH}
+ sed '/User::App.*SharedRO/d' -i ${DSC_PATH}/pkg_*
+fi
+echo "Migration process was finished"
EClearPrivatePaths,
EGetPrivilegeGroups,
EGetUserApps,
- EGetAllTizen2XApps,
- EGetAllTizen2XPackages,
+ EGetTizen2XPackages,
EGetAppsInPkg,
EGetGroups,
EGetPkgAuthorId,
{ StmtType::EClearPrivatePaths, "DELETE FROM shared_path;"},
{ StmtType::EGetPrivilegeGroups, " SELECT group_name FROM privilege_group_view WHERE privilege_name = ?" },
{ StmtType::EGetUserApps, "SELECT name FROM app WHERE uid=?" },
- { StmtType::EGetAllTizen2XApps, "SELECT name FROM app WHERE version LIKE '2.%%' AND name <> ?" },
- { StmtType::EGetAllTizen2XPackages, "SELECT DISTINCT pkg_name FROM app_pkg_view WHERE version LIKE '2.%%'" },
+ { StmtType::EGetTizen2XPackages, "SELECT DISTINCT pkg_name FROM app_pkg_view WHERE version LIKE '2.%%'" },
{ StmtType::EGetAppsInPkg, " SELECT app_name FROM app_pkg_view WHERE pkg_name = ?" },
{ StmtType::EGetGroups, "SELECT DISTINCT group_name FROM privilege_group_view" },
{ StmtType::EGetPkgAuthorId, "SELECT author_id FROM pkg WHERE name = ? AND author_id IS NOT NULL"},
void GetPkgApps(const std::string &pkgName, std::vector<std::string> &appNames);
/**
- * Retrieve list of all apps excluding one specified (typically action originator)
- *
- * @param origApp - do not include specific application name in the list
- * @param[out] apps - vector of application identifiers describing installed 2.x apps,
- * this parameter do not need to be empty, but
- * it is being overwritten during function call.
- * @exception DB::SqlConnection::Exception::InternalError on internal error
- * @exception DB::SqlConnection::Exception::ConstraintError on constraint violation
- */
- void GetTizen2XApps(const std::string &origApp, std::vector<std::string> &apps);
-
- /**
* Retrieve list of all Tizen 2.X packages
*
* @param[out] packages - vector of package identifiers describing installed 2.x packages,
#include "credentials.h"
#include "security-manager.h"
+#include "smack-rules.h"
#include "protocols.h"
namespace SecurityManager {
app_install_type installationType,
const uid_t &uid);
+ static void getTizen2XApps(SmackRules::PkgsApps &pkgsApps);
+
static bool getZoneId(std::string &zoneId);
int dropOnePrivateSharing(const std::string &ownerAppName,
public:
typedef std::string Rule;
typedef std::vector<Rule> RuleVector;
+ typedef std::vector<std::pair<std::string, std::vector<std::string>>> PkgsApps;
SmackRules();
virtual ~SmackRules();
void generatePackageCrossDeps(const std::vector<std::string> &pkgContents);
/**
- * Create cross dependencies for all other 2.X applications
+ * Generate SharedRO rules for Tizen 2.x applications
+ * Each 2.X application gets read-only access to files shared by all other 2.X packages.
*
- * @param[in] pkgName - installed package identifier to access it's shared dir
- * @param[in] other2XApps - list of 2.x apps to grant access
+ * @param[in] pkgsApps vector of Tizen 2.X applications - each element contains
+ * a pair with package name and contents
*/
- void generateAllowOther2XApplicationDeps(
- const std::string pkgName,
- const std::vector<std::string> &other2XApps);
+ static void generateSharedRORules(PkgsApps &pkgsApps);
+
+ /**
+ * Revoke SharedRO rules for Tizen 2.x applications when a package is being removed
+ * Rules from all applications in \ref pkgsApps to SharedRO label of the package
+ * under removal will be revoked from kernel.
+ *
+ * @param[in] pkgsApps vector of Tizen 2.X applications - each element contains
+ * a pair with package name and contents
+ * @param[in] revokePkg package name being removed
+ */
+ static void revokeSharedRORules(PkgsApps &pkgsApps, const std::string &revokePkg);
/**
* Install package-specific smack rules plus add rules for specified external apps.
* @param[in] pkgName - package identifier
* @param[in] authorId - author id of application
* @param[in] pkgContents - list of all applications in the package
- * @param[in] appsGranted - list of 2.x apps granted access
- * @param[in] accessPackages - list of 2.x packages to be accessed
*/
static void installApplicationRules(
const std::string &appName,
const std::string &pkgName,
const int authorId,
- const std::vector<std::string> &pkgContents,
- const std::vector<std::string> &appsGranted,
- const std::vector<std::string> &accessPackages);
+ const std::vector<std::string> &pkgContents);
/**
* Uninstall package-specific smack rules.
*
* @param[in] pkgName - package identifier that the application is in
* @param[in] pkgContents - list of all applications in the package
- * @param[in] appsGranted - list of 2.x apps granted access
*/
static void updatePackageRules(
const std::string &pkgName,
- const std::vector<std::string> &pkgContents,
- const std::vector<std::string> &appsGranted);
+ const std::vector<std::string> &pkgContents);
/**
* Uninstall author-specific smack rules.
bool isPathSharedNoMore,
bool isTargetSharingNoMore);
- static void updatePackageRules(const std::string &pkgName, const std::vector<std::string> &pkgContents);
-
/**
* This function will read all rules created by security-manager and
* save them in one file. This file will be used during next system
static void uninstallRules(const std::string &path);
/**
- * Allow application to access other packages shared directory.
- *
- * @param[in] appName - application identifier
- * @param[in] other2XPackages - list of 2.x packages to be accessed
- */
- static void generateAppToOtherPackagesDeps(
- const std::string appName,
- const std::vector<std::string> &other2XPackages);
-
- /**
* Helper method: replace all occurrences of \ref needle in \ref haystack
* with \ref replace.
*
});
}
-void PrivilegeDb::GetTizen2XApps(const std::string& origApp, std::vector<std::string> &apps)
-{
- try_catch<void>([&] {
- auto command = getStatement(StmtType::EGetAllTizen2XApps);
- command->BindString(1, origApp);
- apps.clear();
- while (command->Step()) {
- const std::string & tizen2XApp = command->GetColumnString(0);
- LogDebug("Found " << tizen2XApp << " Tizen 2.X apps installed");
- apps.push_back(tizen2XApp);
- };
- });
-}
-
void PrivilegeDb::GetTizen2XPackages(std::vector<std::string> &packages)
{
try_catch<void>([&] {
- auto command = getStatement(StmtType::EGetAllTizen2XPackages);
+ auto command = getStatement(StmtType::EGetTizen2XPackages);
packages.clear();
while (command->Step()) {
const std::string & tizen2XPkg = command->GetColumnString(0);
}
}
+void ServiceImpl::getTizen2XApps(SmackRules::PkgsApps &pkgsApps)
+{
+ std::vector<std::string> pkgs;
+ PrivilegeDb::getInstance().GetTizen2XPackages(pkgs);
+
+ pkgsApps.resize(pkgs.size());
+ for (size_t i = 0; i < pkgs.size(); ++i) {
+ pkgsApps[i].first = std::move(pkgs[i]);
+ PrivilegeDb::getInstance().GetPkgApps(pkgsApps[i].first, pkgsApps[i].second);
+ }
+}
+
int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
{
std::vector<std::string> addedPermissions;
std::string pkgBasePath;
std::string appLabel;
std::string pkgLabel;
- std::vector<std::string> allTizen2XApps, allTizen2XPackages;
+ SmackRules::PkgsApps tizen2XpkgsApps;
int authorId;
try {
CynaraAdmin::getInstance().UpdateAppPolicy(appLabel, cynaraUserStr, req.privileges);
// if app is targetted to Tizen 2.X, give other 2.X apps RO rules to it's shared dir
- if(isTizen2XVersion(req.tizenVersion)) {
- PrivilegeDb::getInstance().GetTizen2XApps(req.appName, allTizen2XApps);
- PrivilegeDb::getInstance().GetTizen2XPackages(allTizen2XPackages);
- }
+ if (isTizen2XVersion(req.tizenVersion))
+ getTizen2XApps(tizen2XpkgsApps);
// WTF? Why this commit is here? Shouldn't it be at the end of this function?
PrivilegeDb::getInstance().CommitTransaction();
try {
LogDebug("Adding Smack rules for new appName: " << req.appName << " with pkgName: "
<< req.pkgName << ". Applications in package: " << pkgContents.size());
- SmackRules::installApplicationRules(req.appName, req.pkgName, authorId, pkgContents, allTizen2XApps, allTizen2XPackages);
+ SmackRules::installApplicationRules(req.appName, req.pkgName, authorId, pkgContents);
+
+ if (isTizen2XVersion(req.tizenVersion))
+ SmackRules::generateSharedRORules(tizen2XpkgsApps);
+
SmackRules::mergeRules();
} catch (const SmackException::InvalidParam &e) {
LogError("Invalid paramater during labeling: " << e.GetMessage());
int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &&req)
{
- std::string tizenVersion;
std::string smackLabel;
std::vector<std::string> pkgContents;
bool removeApp = false;
bool removePkg = false;
bool removeAuthor = false;
std::string cynaraUserStr;
- std::vector<std::string> allTizen2XApps;
+ SmackRules::PkgsApps tizen2XpkgsApps;
int authorId;
installRequestMangle(req, cynaraUserStr);
package that the app appears in */
PrivilegeDb::getInstance().GetPkgAuthorId(req.pkgName, authorId);
PrivilegeDb::getInstance().GetPkgApps(req.pkgName, pkgContents);
+ PrivilegeDb::getInstance().GetAppVersion(req.appName, req.tizenVersion);
PrivilegeDb::getInstance().UpdateAppPrivileges(req.appName, req.uid, std::vector<std::string>());
PrivilegeDb::getInstance().RemoveApplication(req.appName, req.uid, removeApp, removePkg, removeAuthor);
// if uninstalled app is targetted to Tizen 2.X, remove other 2.X apps RO rules it's shared dir
- PrivilegeDb::getInstance().GetAppVersion(req.appName, tizenVersion);
- if (isTizen2XVersion(tizenVersion))
- PrivilegeDb::getInstance().GetTizen2XApps(req.appName, allTizen2XApps);
+ if (isTizen2XVersion(req.tizenVersion))
+ getTizen2XApps(tizen2XpkgsApps);
CynaraAdmin::getInstance().UpdateAppPolicy(smackLabel, cynaraUserStr, std::vector<std::string>());
-
PrivilegeDb::getInstance().CommitTransaction();
LogDebug("Application uninstallation commited to database");
} catch (const PrivilegeDb::Exception::IOError &e) {
if (!removePkg) {
LogDebug("Recreating Smack rules for pkgName " << req.pkgName);
pkgContents.erase(std::remove(pkgContents.begin(), pkgContents.end(),req.appName), pkgContents.end());
- SmackRules::updatePackageRules(req.pkgName, pkgContents, allTizen2XApps);
+ SmackRules::updatePackageRules(req.pkgName, pkgContents);
+ }
+
+ if (isTizen2XVersion(req.tizenVersion)) {
+ SmackRules::generateSharedRORules(tizen2XpkgsApps);
+ if (removePkg)
+ SmackRules::revokeSharedRORules(tizen2XpkgsApps, req.pkgName);
}
}
const char *const SMACK_RULES_PATH_MERGED = LOCAL_STATE_DIR "/security-manager/rules-merged/rules.merged";
const char *const SMACK_RULES_PATH_MERGED_T = LOCAL_STATE_DIR "/security-manager/rules-merged/rules.merged.temp";
const char *const SMACK_RULES_PATH = LOCAL_STATE_DIR "/security-manager/rules";
+const char *const SMACK_RULES_SHARED_RO_PATH = LOCAL_STATE_DIR "/security-manager/rules/2x_shared_ro";
const char *const SMACK_APP_IN_PACKAGE_PERMS = "rwxat";
const char *const SMACK_APP_CROSS_PKG_PERMS = "rx";
const char *const SMACK_APP_PATH_OWNER_PERMS = "rwxat";
}
}
-void SmackRules::generateAppToOtherPackagesDeps(
- const std::string appName,
- const std::vector<std::string> &other2XPackages)
+void SmackRules::generateSharedRORules(PkgsApps &pkgsApps)
{
- // reverse: allow installed app to access others' contents
- // for every 2.X package
- for (const auto &object : other2XPackages) {
- std::string otherObjectLabel = SmackLabels::generatePkgLabelOwnerRWothersRO(object);
-
- SmackRules packageRules;
- std::string accessPackageRulesPath = getPackageRulesFilePath(object);
- packageRules.loadFromFile(accessPackageRulesPath);
-
- std::string subjectLabel = SmackLabels::generateAppLabel(appName);
- LogDebug("Addding cross app rule for newly installed subject " << subjectLabel << " to already installed 2.x package object: " << otherObjectLabel << " perms: " << SMACK_APP_CROSS_PKG_PERMS);
- packageRules.add(subjectLabel, otherObjectLabel, SMACK_APP_CROSS_PKG_PERMS);
- packageRules.saveToFile(accessPackageRulesPath);
- if (smack_smackfs_path() != NULL)
- packageRules.apply();
+ LogDebug("Generating SharedRO rules");
+
+ SmackRules rules;
+ for (size_t i = 0; i < pkgsApps.size(); ++i) {
+ for (const std::string &appName : pkgsApps[i].second) {
+ std::string appLabel = SmackLabels::generateAppLabel(appName);
+ for (size_t j = 0; j < pkgsApps.size(); ++j) {
+ if (j != i) { // Rules for SharedRO files from own pkg are generated elsewhere
+ std::string &pkgName = pkgsApps[j].first;
+ rules.add(appLabel,
+ SmackLabels::generatePkgLabelOwnerRWothersRO(pkgName),
+ SMACK_APP_CROSS_PKG_PERMS);
+ }
+ }
+ }
}
+
+ if (smack_smackfs_path() != NULL)
+ rules.apply();
+
+ rules.saveToFile(SMACK_RULES_SHARED_RO_PATH);
}
-/**
- * this below works in N^2 and should be replaced by an alternative mechanism
- */
-void SmackRules::generateAllowOther2XApplicationDeps(
- const std::string pkgName,
- const std::vector<std::string> &other2XApps)
+void SmackRules::revokeSharedRORules(PkgsApps &pkgsApps, const std::string &revokePkg)
{
- LogDebug("Generating cross-package rules");
-
- std::string objectLabel = SmackLabels::generatePkgLabelOwnerRWothersRO(pkgName);
- std::string appsInPackagePerms = SMACK_APP_IN_PACKAGE_PERMS;
+ LogDebug("Revoking SharedRO rules for target pkg " << revokePkg);
- // allow other app to access installed package contents
- for (const auto &subject : other2XApps) {
- std::string subjectLabel = SmackLabels::generateAppLabel(subject);
+ if (smack_smackfs_path() == NULL)
+ return;
- LogDebug("Addding cross 2.x app rule subject: " << subjectLabel << " to newly installed object: "
- << objectLabel << " perms: " << SMACK_APP_CROSS_PKG_PERMS);
- add(subjectLabel, objectLabel, SMACK_APP_CROSS_PKG_PERMS);
+ SmackRules rules;
+ for (size_t i = 0; i < pkgsApps.size(); ++i) {
+ for (const std::string &appName : pkgsApps[i].second) {
+ std::string appLabel = SmackLabels::generateAppLabel(appName);
+ rules.add(appLabel,
+ SmackLabels::generatePkgLabelOwnerRWothersRO(revokePkg),
+ SMACK_APP_CROSS_PKG_PERMS);
+ }
}
+
+ rules.clear();
}
std::string SmackRules::getPackageRulesFilePath(const std::string &pkgName)
const std::string &appName,
const std::string &pkgName,
const int authorId,
- const std::vector<std::string> &pkgContents,
- const std::vector<std::string> &appsGranted,
- const std::vector<std::string> &accessPackages)
+ const std::vector<std::string> &pkgContents)
{
useTemplate(APP_RULES_TEMPLATE_FILE_PATH, getApplicationRulesFilePath(appName), appName, pkgName, authorId);
if (authorId >= 0)
useTemplate(AUTHOR_RULES_TEMPLATE_FILE_PATH, getAuthorRulesFilePath(authorId), appName, pkgName, authorId);
- updatePackageRules(pkgName, pkgContents, appsGranted);
- generateAppToOtherPackagesDeps(appName, accessPackages);
+ updatePackageRules(pkgName, pkgContents);
}
void SmackRules::updatePackageRules(
const std::string &pkgName,
- const std::vector<std::string> &pkgContents,
- const std::vector<std::string> &appsGranted)
+ const std::vector<std::string> &pkgContents)
{
SmackRules smackRules;
smackRules.addFromTemplateFile(
-1);
smackRules.generatePackageCrossDeps(pkgContents);
- smackRules.generateAllowOther2XApplicationDeps(pkgName, appsGranted);
if (smack_smackfs_path() != NULL)
smackRules.apply();