summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKrzysztof Jackiewicz <k.jackiewicz@samsung.com>2016-05-02 11:16:16 +0200
committerRafal Krypa <r.krypa@samsung.com>2016-05-13 09:04:44 -0700
commita16fdd2243716f5a71a35c06fa3096920dce642e (patch)
treecd143fbd020cfdfcba43d45186b90841db85e6c3
parentb9f3fbed5e620329cf123b41ce2bce6551b7edda (diff)
downloadsecurity-manager-a16fdd2243716f5a71a35c06fa3096920dce642e.tar.gz
security-manager-a16fdd2243716f5a71a35c06fa3096920dce642e.tar.bz2
security-manager-a16fdd2243716f5a71a35c06fa3096920dce642e.zip
Path registration requests - server side implementation
[Feature] Provide API for package path registration [Solution] Update server side logic. [Verification] Run tests Change-Id: Ie20db0c0764d48b97ef195ea422aa120f38c7125
-rw-r--r--src/common/include/service_impl.h21
-rw-r--r--src/common/include/smack-labels.h5
-rwxr-xr-xsrc/common/service_impl.cpp195
-rwxr-xr-xsrc/common/smack-labels.cpp5
-rw-r--r--src/server/service/service.cpp2
5 files changed, 154 insertions, 74 deletions
diff --git a/src/common/include/service_impl.h b/src/common/include/service_impl.h
index de7c9e31..53917bda 100644
--- a/src/common/include/service_impl.h
+++ b/src/common/include/service_impl.h
@@ -43,13 +43,26 @@ private:
static bool isSubDir(const char *parent, const char *subdir);
- static bool getUserPkgDir(const uid_t &uid, const app_install_type &installType, std::string &userAppDir);
+ static bool getUserPkgDir(const uid_t &uid,
+ const std::string &pkgName,
+ app_install_type installType,
+ std::string &userPkgDir);
+
+ static void setRequestDefaultValues(uid_t& uid, int& installationType);
static void installRequestMangle(app_inst_req &req, std::string &cynaraUserStr);
- static bool installRequestAuthCheck(const Credentials &creds, const app_inst_req &req);
+ static bool authCheck(const Credentials &creds,
+ const uid_t &uid,
+ int installationType);
+
+ static bool pathsCheck(const pkg_paths &requestedPaths,
+ const std::string pkgPath);
- static bool installRequestPathsCheck(const app_inst_req &req, std::string &appPath);
+ static int labelPaths(const pkg_paths &paths,
+ const std::string &pkgName,
+ app_install_type installationType,
+ const uid_t &uid);
static bool getZoneId(std::string &zoneId);
@@ -233,7 +246,7 @@ public:
*
* @return API return code, as defined in protocols.h
*/
- int pathsRegister(const Credentials &creds, const path_req &p_req);
+ int pathsRegister(const Credentials &creds, path_req p_req);
};
} /* namespace SecurityManager */
diff --git a/src/common/include/smack-labels.h b/src/common/include/smack-labels.h
index 9a93e25d..07b10795 100644
--- a/src/common/include/smack-labels.h
+++ b/src/common/include/smack-labels.h
@@ -51,10 +51,9 @@ void setupPath(
/**
* Sets Smack labels on a <ROOT_APP>/<pkg_id> non-recursively
*
- * @param pkgName[in] package identifier
- * @param basePath[in] <ROOT_APP> path
+ * @param basePath[in] <ROOT_APP>/<pkg_id> path
*/
-void setupPkgBasePath(const std::string &pkgName, const std::string &basePath);
+void setupPkgBasePath(const std::string &basePath);
/**
* Changes Smack label on path to enable private sharing
diff --git a/src/common/service_impl.cpp b/src/common/service_impl.cpp
index 49a99af0..ce4e32da 100755
--- a/src/common/service_impl.cpp
+++ b/src/common/service_impl.cpp
@@ -197,7 +197,10 @@ bool ServiceImpl::isSubDir(const char *parent, const char *subdir)
return (*subdir == '/' || *parent == *subdir);
}
-bool ServiceImpl::getUserPkgDir(const uid_t &uid, const app_install_type &installType, std::string &userAppDir)
+bool ServiceImpl::getUserPkgDir(const uid_t &uid,
+ const std::string &pkgName,
+ app_install_type installType,
+ std::string &userPkgDir)
{
struct tzplatform_context *tz_ctx = nullptr;
@@ -227,37 +230,43 @@ bool ServiceImpl::getUserPkgDir(const uid_t &uid, const app_install_type &instal
id = TZ_SYS_RO_APP;
break;
default:
+ LogError("Unsupported installation type: " << installType);
return false;
}
- const char *appDir = tzplatform_context_getenv(tz_ctxPtr.get(), id);
- if (!appDir) {
+ const char *pkgDir = tzplatform_context_getenv(tz_ctxPtr.get(), id);
+ if (!pkgDir) {
LogError("Error in tzplatform_context_getenv()");
return false;
}
- std::unique_ptr<char, decltype(free)*> real_pathPtr(realpath(appDir, NULL), free);
+ std::unique_ptr<char, decltype(free)*> real_pathPtr(realpath(pkgDir, NULL), free);
if (!real_pathPtr.get()) {
- LogError("Error in realpath(): " << GetErrnoString(errno) << " for: " << appDir);
+ LogError("Error in realpath(): " << GetErrnoString(errno) << " for: " << pkgDir);
return false;
}
- userAppDir.assign(real_pathPtr.get());
+ userPkgDir.assign(real_pathPtr.get());
+ userPkgDir.append("/").append(pkgName);
return true;
}
-void ServiceImpl::installRequestMangle(app_inst_req &req, std::string &cynaraUserStr)
+void ServiceImpl::setRequestDefaultValues(uid_t& uid, int& installationType)
{
uid_t globalUid = getGlobalUserId();
- if (req.uid == 0)
- req.uid = globalUid;
+ if (uid == 0)
+ uid = globalUid;
- if (req.installationType == SM_APP_INSTALL_NONE)
- req.installationType = (req.uid == globalUid) ?
- SM_APP_INSTALL_GLOBAL : SM_APP_INSTALL_LOCAL;
+ if (installationType == SM_APP_INSTALL_NONE)
+ installationType = (uid == globalUid) ? SM_APP_INSTALL_GLOBAL :
+ SM_APP_INSTALL_LOCAL;
+}
+void ServiceImpl::installRequestMangle(app_inst_req &req, std::string &cynaraUserStr)
+{
+ setRequestDefaultValues(req.uid, req.installationType);
if (req.installationType == SM_APP_INSTALL_GLOBAL
|| req.installationType == SM_APP_INSTALL_PRELOADED) {
@@ -270,16 +279,18 @@ void ServiceImpl::installRequestMangle(app_inst_req &req, std::string &cynaraUse
LogError("Installation type: unknown");
}
-bool ServiceImpl::installRequestAuthCheck(const Credentials &creds, const app_inst_req &req)
+bool ServiceImpl::authCheck(const Credentials &creds,
+ const uid_t& uid,
+ int installationType)
{
- if (req.installationType == SM_APP_INSTALL_LOCAL && req.uid == creds.uid) {
+ if (installationType == SM_APP_INSTALL_LOCAL && uid == creds.uid) {
if (!authenticate(creds, Config::PRIVILEGE_APPINST_USER)) {
- LogError("Caller is not permitted to install applications locally");
+ LogError("Caller is not permitted to manage local applications");
return false;
}
} else {
if (!authenticate(creds, Config::PRIVILEGE_APPINST_ADMIN)) {
- LogError("Caller is not permitted to install applications globally");
+ LogError("Caller is not permitted to manage global applications");
return false;
}
}
@@ -287,18 +298,11 @@ bool ServiceImpl::installRequestAuthCheck(const Credentials &creds, const app_in
return true;
}
-bool ServiceImpl::installRequestPathsCheck(const app_inst_req &req, std::string &pkgPath)
-{
- if (!getUserPkgDir(req.uid, static_cast<app_install_type>(req.installationType), pkgPath)) {
- LogError("Failed getting pkg dir for user uid: " << req.uid);
- return false;
- }
+bool ServiceImpl::pathsCheck(const pkg_paths &requestedPaths,
+ const std::string pkgPath)
- std::string correctPath{pkgPath};
- correctPath.append("/").append(req.pkgName);
- LogDebug("correctPath: " << correctPath);
-
- for (const auto &path : req.pkgPaths) {
+{
+ for (const auto &path : requestedPaths) {
std::unique_ptr<char, std::function<void(void*)>> real_path(
realpath(path.first.c_str(), NULL), free);
if (!real_path.get()) {
@@ -308,14 +312,65 @@ bool ServiceImpl::installRequestPathsCheck(const app_inst_req &req, std::string
}
LogDebug("Requested path is '" << path.first.c_str()
<< "'. User's pkg dir is '" << pkgPath << "'");
- if (!isSubDir(correctPath.c_str(), real_path.get())) {
- LogWarning("Installation is outside correct path: " << correctPath << "," << real_path.get());
+ if (!isSubDir(pkgPath.c_str(), real_path.get())) {
+ LogWarning("Installation is outside correct path: " << pkgPath << "," << real_path.get());
return false;
}
}
return true;
}
+int ServiceImpl::labelPaths(const pkg_paths &paths,
+ const std::string &pkgName,
+ app_install_type installationType,
+ const uid_t &uid)
+{
+ try {
+ std::string pkgBasePath;
+ int authorId;
+
+ if (!PrivilegeDb::getInstance().PkgNameExists(pkgName)) {
+ LogError("No such package: " << pkgName);
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ }
+
+ PrivilegeDb::getInstance().GetPkgAuthorId(pkgName, authorId);
+
+ if (!getUserPkgDir(uid, pkgName, installationType, pkgBasePath))
+ return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+
+ // check if paths are inside
+ if (!pathsCheck(paths, pkgBasePath))
+ return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
+
+ if (!paths.empty())
+ SmackLabels::setupPkgBasePath(pkgBasePath);
+
+ // register paths
+ for (const auto &pkgPath : paths) {
+ const std::string &path = pkgPath.first;
+ app_install_path_type pathType = static_cast<app_install_path_type>(pkgPath.second);
+ SmackLabels::setupPath(pkgName, path, pathType, authorId);
+ }
+ return SECURITY_MANAGER_SUCCESS;
+ } catch (const PrivilegeDb::Exception::Base &e) {
+ LogError("Database error: " << e.DumpToString());
+ return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+ } catch (const SmackException::InvalidParam &e) {
+ LogError("Invalid parameter during labeling: " << e.DumpToString());
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ } catch (const SmackException::InvalidPathType &e) {
+ LogError("Invalid path type: " << e.DumpToString());
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ } catch (const SmackException::Base &e) {
+ LogError("Error while generating Smack labels: " << e.DumpToString());
+ return SECURITY_MANAGER_ERROR_SETTING_FILE_LABEL_FAILED;
+ } catch (const std::bad_alloc &e) {
+ LogError("Memory allocation failed: " << e.what());
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ }
+}
+
int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
{
std::vector<std::string> addedPermissions;
@@ -328,30 +383,23 @@ int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
std::vector<std::string> allTizen2XApps, allTizen2XPackages;
int authorId;
- installRequestMangle(req, cynaraUserStr);
-
- LogDebug("Install parameters: appName: " << req.appName << ", pkgName: " << req.pkgName
- << ", uid: " << req.uid << ", target Tizen API ver: "
- << (req.tizenVersion.empty() ? "unknown" : req.tizenVersion));
+ try {
+ installRequestMangle(req, cynaraUserStr);
- if (!installRequestAuthCheck(creds, req)) {
- LogError("Request from uid=" << creds.uid << ", Smack=" << creds.label <<
- " for app installation denied");
- return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
- }
+ LogDebug("Install parameters: appName: " << req.appName << ", pkgName: " << req.pkgName
+ << ", uid: " << req.uid << ", target Tizen API ver: "
+ << (req.tizenVersion.empty() ? "unknown" : req.tizenVersion));
- if (!installRequestPathsCheck(req, pkgBasePath)) {
- LogError("Installation request with paths outside expected application path");
- return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
- }
+ if (!authCheck(creds, req.uid, req.installationType)) {
+ LogError("Request from uid=" << creds.uid << ", Smack=" << creds.label <<
+ " for app installation denied");
+ return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
+ }
- try {
appLabel = SmackLabels::generateAppLabel(req.appName);
-
- /* NOTE: we don't use pkgLabel here, but generate it for pkgName validation */
pkgLabel = SmackLabels::generatePkgLabel(req.pkgName);
- LogDebug("Generated install parameters: "
- << "app label: " << appLabel << ", pkg label: " << pkgLabel);
+ LogDebug("Generated install parameters: app label: " << appLabel <<
+ ", pkg label: " << pkgLabel);
PrivilegeDb::getInstance().BeginTransaction();
std::string pkg;
@@ -366,7 +414,7 @@ int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
PrivilegeDb::getInstance().UpdateAppPrivileges(req.appName, req.uid, req.privileges);
/* Get all application ids in the package to generate rules withing the package */
PrivilegeDb::getInstance().GetPkgApps(req.pkgName, pkgContents);
- PrivilegeDb::getInstance().GetAuthorIdByName(req.authorName, authorId);
+ PrivilegeDb::getInstance().GetPkgAuthorId(req.pkgName, authorId);
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
@@ -401,17 +449,14 @@ int ServiceImpl::appInstall(const Credentials &creds, app_inst_req &&req)
return SECURITY_MANAGER_ERROR_MEMORY;
}
- try {
- if (!req.pkgPaths.empty())
- SmackLabels::setupPkgBasePath(req.pkgName, pkgBasePath);
-
- // register paths
- for (const auto &pkgPath : req.pkgPaths) {
- const std::string &path = pkgPath.first;
- app_install_path_type pathType = static_cast<app_install_path_type>(pkgPath.second);
- SmackLabels::setupPath(req.pkgName, path, pathType, authorId);
- }
+ int ret = labelPaths(req.pkgPaths,
+ req.pkgName,
+ static_cast<app_install_type>(req.installationType),
+ req.uid);
+ if (ret != SECURITY_MANAGER_SUCCESS)
+ return ret;
+ 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);
@@ -449,7 +494,7 @@ int ServiceImpl::appUninstall(const Credentials &creds, app_inst_req &&req)
LogDebug("Uninstall parameters: appName=" << req.appName << ", uid=" << req.uid);
- if (!installRequestAuthCheck(creds, req)) {
+ if (!authCheck(creds, req.uid, req.installationType)) {
LogError("Request from uid=" << creds.uid << ", Smack=" << creds.label <<
" for app uninstallation denied");
return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
@@ -1243,10 +1288,34 @@ int ServiceImpl::dropPrivatePathSharing(
return errorRet;
}
-int ServiceImpl::pathsRegister(const Credentials &/*creds*/, const path_req &/*req*/)
+int ServiceImpl::pathsRegister(const Credentials &creds, path_req req)
{
- // TODO
- return SECURITY_MANAGER_ERROR_UNKNOWN;
+ LogDebug("Paths registration parameters: pkgName: " << req.pkgName <<
+ ", uid: " << req.uid);
+
+ if (req.pkgPaths.empty())
+ return SECURITY_MANAGER_SUCCESS;
+
+ setRequestDefaultValues(req.uid, req.installationType);
+
+ try {
+ if (!authCheck(creds, req.uid, req.installationType)) {
+ LogError("Request from uid=" << creds.uid << ", Smack=" << creds.label <<
+ " for path registration denied");
+ return SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED;
+ }
+ } catch (const CynaraException::Base &e) {
+ LogError("Error while querying Cynara for permissions: " << e.DumpToString());
+ return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+ } catch (const std::bad_alloc &e) {
+ LogError("Memory allocation failed: " << e.what());
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ }
+
+ return labelPaths(req.pkgPaths,
+ req.pkgName,
+ static_cast<app_install_type>(req.installationType),
+ req.uid);
}
} /* namespace SecurityManager */
diff --git a/src/common/smack-labels.cpp b/src/common/smack-labels.cpp
index 863d6631..07394b89 100755
--- a/src/common/smack-labels.cpp
+++ b/src/common/smack-labels.cpp
@@ -176,10 +176,9 @@ void setupPath(
return labelDir(path, label, label_transmute, label_executables);
}
-void setupPkgBasePath(const std::string &pkgName, const std::string &basePath)
+void setupPkgBasePath(const std::string &basePath)
{
- std::string pkgPath = basePath + "/" + pkgName;
- pathSetSmack(pkgPath.c_str(), LABEL_FOR_APP_PUBLIC_RO_PATH, XATTR_NAME_SMACK);
+ pathSetSmack(basePath.c_str(), LABEL_FOR_APP_PUBLIC_RO_PATH, XATTR_NAME_SMACK);
}
void setupSharedPrivatePath(const std::string &pkgName, const std::string &path) {
diff --git a/src/server/service/service.cpp b/src/server/service/service.cpp
index 97af66ed..510f0b04 100644
--- a/src/server/service/service.cpp
+++ b/src/server/service/service.cpp
@@ -351,7 +351,7 @@ void Service::processPathsRegister(MessageBuffer &recv, MessageBuffer &send, con
Deserialization::Deserialize(recv, req.uid);
Deserialization::Deserialize(recv, req.pkgPaths);
Deserialization::Deserialize(recv, req.installationType);
- int ret = serviceImpl.pathsRegister(creds, req);
+ int ret = serviceImpl.pathsRegister(creds, std::move(req));
Serialization::Serialize(send, ret);
}
} // namespace SecurityManager