~APP~ System::Run rwxat
~APP~ System::Log rwxa
~APP~ _ l
-User ~APP~ rwxa
+User ~APP~ rwx
User ~PKG~ rwxat
+User ~PKG~::RO rwxat
~APP~ User wx
~APP~ User::Home rxl
~APP~ User::App::Shared rwxat
~APP~ ~PKG~ rwxat
+~APP~ ~PKG~::RO rxl
static bool getUserAppDir(const uid_t &uid, std::string &userAppDir);
- static bool installRequestAuthCheck(const app_inst_req &req, uid_t uid, bool &isCorrectPath, std::string &appPath);
+ static bool installRequestAuthCheck(const app_inst_req &req, uid_t uid, std::string &appPath);
static bool getZoneId(std::string &zoneId);
/**
* Sets Smack labels on a directory and its contents, recursively.
*
- * @param appId[in] application's identifier
- * @param path[in] path to a file or directory to setup
- * @param pathType[in] type of path to setup. See description of
- * app_install_path_type in security-manager.h for details
- *
- */
-void setupPath(const std::string &appId, const std::string &path,
- app_install_path_type pathType);
-
-/**
- * Sets Smack labels on a directory and its contents, recursively.
- *
- * @param appId[in] application's identifier
+ * @param pkgId[in] application's package identifier
* @param path[in] path to a file or directory to setup
* @param pathType[in] type of path to setup. See description of
* app_install_path_type in security-manager.h for details
* @param zoneId[in] ID of zone for which label should be set
*/
-void setupPath(const std::string &appId, const std::string &path,
+void setupPath(const std::string &pkgId, const std::string &path,
app_install_path_type pathType, const std::string &zoneId);
/**
- * Sets Smack labels on a <ROOT_APP>/<pkg_id> and <ROOT_APP>/<pkg_id>/<app_id>
- * non-recursively
+ * Sets Smack labels on a <ROOT_APP>/<pkg_id> non-recursively
*
* @param pkgId[in] package identifier
- * @param appId[in] application's identifier
* @param basePath[in] <ROOT_APP> path
*/
-void setupCorrectPath(const std::string &pkgId, const std::string &appId,
- const std::string &basePath);
-
-/**
- * Sets Smack labels on a <ROOT_APP>/<pkg_id> and <ROOT_APP>/<pkg_id>/<app_id>
- * non-recursively
- *
- * @param pkgId[in] package identifier
- * @param appId[in] application's identifier
- * @param basePath[in] <ROOT_APP> path
- * @param zoneId[in] ID of zone for which label should be set
- */
-void setupCorrectPath(const std::string &pkgId, const std::string &appId,
- const std::string &basePath, const std::string &zoneId);
+void setupAppBasePath(const std::string &pkgId, const std::string &basePath);
/**
* Generates application name for a label fetched from Cynara
*/
std::string generatePkgLabel(const std::string &pkgId);
+/**
+ * Generates label for private application RO files with package ID @ref pkgId
+ *
+ * @param[in] pkgId
+ * @return resulting Smack label
+ */
+std::string generatePkgROLabel(const std::string &pkgId);
+
+
} // namespace SmackLabels
} // namespace SecurityManager
*/
static void uninstallRules (const std::string &path);
+ /**
+ * Helper method: replace all occurrences of \ref needle in \ref haystack
+ * with \ref replace.
+ *
+ * @param[in,out] haystack string to modify
+ * @param needle string to find in \ref haystack
+ * @param replace string to replace \ref needle with
+ */
+ static void strReplace(std::string &haystack, const std::string &needle,
+ const std::string &replace);
+
smack_accesses *m_handle;
};
if (*parent++ != *subdir++)
return false;
- return (*subdir == '/');
+ return (*subdir == '/' || *parent == *subdir);
}
bool ServiceImpl::getUserAppDir(const uid_t &uid, std::string &userAppDir)
return true;
}
-bool ServiceImpl::installRequestAuthCheck(const app_inst_req &req, uid_t uid, bool &isCorrectPath, std::string &appPath)
+bool ServiceImpl::installRequestAuthCheck(const app_inst_req &req, uid_t uid, std::string &appPath)
{
std::string userHome;
std::string userAppDir;
appPath = userAppDir;
correctPath.clear();
- correctPath << userAppDir << "/" << req.pkgId << "/" << req.appId;
+ correctPath << userAppDir << "/" << req.pkgId;
LogDebug("correctPath: " << correctPath.str());
for (const auto &appPath : req.appPaths) {
}
LogDebug("Requested path is '" << appPath.first.c_str()
<< "'. User's APPS_DIR is '" << userAppDir << "'");
- if (!isSubDir(userAppDir.c_str(), real_path.get())) {
- LogWarning("User's apps may have registered folders only in user's APPS_DIR");
- return false;
- }
-
if (!isSubDir(correctPath.str().c_str(), real_path.get())) {
- LogWarning("Installation is outside correct path: " << correctPath.str());
- //return false;
- } else
- isCorrectPath = true;
-
- app_install_path_type pathType = static_cast<app_install_path_type>(appPath.second);
- if (pathType == SECURITY_MANAGER_PATH_PUBLIC) {
- LogWarning("Only root can register SECURITY_MANAGER_PATH_PUBLIC path");
+ LogWarning("Installation is outside correct path: " << correctPath.str() << "," << real_path.get());
return false;
}
}
std::vector<std::string> removedPermissions;
std::vector<std::string> pkgContents;
std::string uidstr;
- bool isCorrectPath = false;
std::string appPath;
std::string appLabel;
std::string pkgLabel;
}
checkGlobalUser(uid, uidstr);
- if (!installRequestAuthCheck(req, uid, isCorrectPath, appPath)) {
+ if (!installRequestAuthCheck(req, uid, appPath)) {
LogError("Request from uid " << uid << " for app installation denied");
return SECURITY_MANAGER_API_ERROR_AUTHENTICATION_FAILED;
}
}
try {
- if (isCorrectPath)
- SmackLabels::setupCorrectPath(req.pkgId, req.appId, appPath, zoneId);
+ if (!req.appPaths.empty())
+ SmackLabels::setupAppBasePath(req.pkgId, appPath);
// register paths
for (const auto &appPath : req.appPaths) {
const std::string &path = appPath.first;
app_install_path_type pathType = static_cast<app_install_path_type>(appPath.second);
- SmackLabels::setupPath(req.appId, path, pathType, zoneId);
+ SmackLabels::setupPath(req.pkgId, path, pathType, zoneId);
}
if (isSlave) {
namespace SecurityManager {
namespace SmackLabels {
-/* Const defined below is used to label files accessible to apps only for reading */
-const char *const LABEL_FOR_APP_RO_PATH = "User::Home";
+//! Smack label used for SECURITY_MANAGER_PATH_PUBLIC_RO paths (RO for all apps)
+const char *const LABEL_FOR_APP_PUBLIC_RO_PATH = "User::Home";
typedef std::function<bool(const FTSENT*)> LabelDecisionFn;
dirSetSmack(path, label, XATTR_NAME_SMACKEXEC, &labelExecs);
}
-void setupPath(const std::string &appId, const std::string &path, app_install_path_type pathType)
-{
- setupPath(appId, path, pathType, std::string());
-}
-
-void setupPath(const std::string &appId, const std::string &path, app_install_path_type pathType,
+void setupPath(const std::string &pkgId, const std::string &path, app_install_path_type pathType,
const std::string &zoneId)
{
std::string label;
bool label_executables, label_transmute;
switch (pathType) {
- case SECURITY_MANAGER_PATH_PRIVATE:
case SECURITY_MANAGER_PATH_RW:
- label = zoneSmackLabelGenerate(generateAppLabel(appId), zoneId);
+ label = zoneSmackLabelGenerate(generatePkgLabel(pkgId), zoneId);
label_executables = true;
label_transmute = false;
break;
- case SECURITY_MANAGER_PATH_PUBLIC:
case SECURITY_MANAGER_PATH_RO:
- label.assign(LABEL_FOR_APP_RO_PATH);
+ label = zoneSmackLabelGenerate(generatePkgROLabel(pkgId), zoneId);
label_executables = false;
- label_transmute = true;
+ label_transmute = false;
break;
case SECURITY_MANAGER_PATH_PUBLIC_RO:
- label.assign("_");
+ label.assign(LABEL_FOR_APP_PUBLIC_RO_PATH);
label_executables = false;
- label_transmute = false;
+ label_transmute = true;
break;
default:
LogError("Path type not known.");
return labelDir(path, label, label_transmute, label_executables);
}
-void setupCorrectPath(const std::string &pkgId, const std::string &appId, const std::string &basePath)
-{
- setupCorrectPath(pkgId, appId, basePath, std::string());
-}
-
-void setupCorrectPath(const std::string &pkgId, const std::string &appId, const std::string &basePath,
- const std::string& zoneId)
+void setupAppBasePath(const std::string &pkgId, const std::string &basePath)
{
std::string pkgPath = basePath + "/" + pkgId;
- std::string appPath = pkgPath + "/" + appId;
-
- pathSetSmack(pkgPath.c_str(), zoneSmackLabelGenerate(generatePkgLabel(pkgId), zoneId), XATTR_NAME_SMACK);
- pathSetSmack(appPath.c_str(), zoneSmackLabelGenerate(generateAppLabel(appId), zoneId), XATTR_NAME_SMACK);
- pathSetSmack(appPath.c_str(), "TRUE", XATTR_NAME_SMACKTRANSMUTE);
+ pathSetSmack(pkgPath.c_str(), LABEL_FOR_APP_PUBLIC_RO_PATH, XATTR_NAME_SMACK);
}
std::string generateAppNameFromLabel(const std::string &label)
return label;
}
+std::string generatePkgROLabel(const std::string &pkgId)
+{
+ std::string label = "User::Pkg::" + pkgId + "::RO";
+
+ if (smack_label_length(label.c_str()) <= 0)
+ ThrowMsg(SmackException::InvalidLabel, "Invalid Smack label generated from pkgId " << pkgId);
+
+ return label;
+}
+
+
} // namespace SmackLabels
} // namespace SecurityManager
ThrowMsg(SmackException::FileError, "Invalid rule template: " << rule);
}
- if (subject == SMACK_APP_LABEL_TEMPLATE)
- subject = SmackLabels::generateAppLabel(appId);
-
- if (subject == SMACK_PKG_LABEL_TEMPLATE)
- subject = SmackLabels::generatePkgLabel(pkgId);
-
- if (object == SMACK_APP_LABEL_TEMPLATE)
- object = SmackLabels::generateAppLabel(appId);
-
- if (object == SMACK_PKG_LABEL_TEMPLATE)
- object = SmackLabels::generatePkgLabel(pkgId);
+ strReplace(subject, SMACK_APP_LABEL_TEMPLATE, SmackLabels::generateAppLabel(appId));
+ strReplace(subject, SMACK_PKG_LABEL_TEMPLATE, SmackLabels::generatePkgLabel(pkgId));
+ strReplace(object, SMACK_APP_LABEL_TEMPLATE, SmackLabels::generateAppLabel(appId));
+ strReplace(object, SMACK_PKG_LABEL_TEMPLATE, SmackLabels::generatePkgLabel(pkgId));
if (!zoneId.empty()) {
// FIXME replace with vasum calls. See zone-utils.h
}
}
+void SmackRules::strReplace(std::string &haystack, const std::string &needle,
+ const std::string &replace)
+{
+ size_t pos;
+ while ((pos = haystack.find(needle)) != std::string::npos)
+ haystack.replace(pos, needle.size(), replace);
+}
+
} // namespace SecurityManager
/*! \brief accesses types for application installation paths*/
enum app_install_path_type {
- //accessible read-write only for applications with same package id
- SECURITY_MANAGER_PATH_PRIVATE,
- //read-write access for all applications
- SECURITY_MANAGER_PATH_PUBLIC,
- //read only access for all applications
+ //! RO access for all applications
SECURITY_MANAGER_PATH_PUBLIC_RO,
- //accessible for writing to all apps within its package
+ //! RW access for given application package
SECURITY_MANAGER_PATH_RW,
- //accessible to apps for reading
+ //! RO access for given application package
SECURITY_MANAGER_PATH_RO,
- //this is only for range limit
+ //! this is only for range limit
SECURITY_MANAGER_ENUM_END
};