From fb484907f18361091b011edf6b27b6735a9a384b Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Tue, 29 Sep 2015 08:16:11 +0200 Subject: [PATCH] Add 'socket/pid to appId and pkgId' functionality This patch introduces client functions for obtaining package Id and application Id of an application with given socket descriptor or process identifiers. To test this functionality run tests added in patch: https://review.tizen.org/gerrit/#/c/48887/ Change-Id: Ib9bd924563ea932ecf64d421f90bc3dde3bb38ec --- src/client/client-security-manager.cpp | 66 ++++++++++++++++++++++++++++++++++ src/common/include/smack-labels.h | 17 ++++++++- src/common/smack-labels.cpp | 43 ++++++++++++++++++++-- src/include/security-manager.h | 38 ++++++++++++++++++++ 4 files changed, 161 insertions(+), 3 deletions(-) diff --git a/src/client/client-security-manager.cpp b/src/client/client-security-manager.cpp index 3949867..24aa565 100644 --- a/src/client/client-security-manager.cpp +++ b/src/client/client-security-manager.cpp @@ -1149,3 +1149,69 @@ void security_manager_groups_free(char **groups, size_t groups_count) free(groups); } + +static lib_retcode get_app_and_pkg_id_from_smack_label( + const std::string &label, + char **pkg_id, + char **app_id) +{ + std::string appIdString; + + try { + appIdString = SmackLabels::generateAppNameFromLabel(label); + } catch (const SmackException::InvalidLabel &) { + return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT; + } + + if (app_id && !(*app_id = strdup(appIdString.c_str()))) { + LogError("Memory allocation in strdup failed."); + return SECURITY_MANAGER_ERROR_MEMORY; + } + + return pkg_id ? static_cast(security_manager_get_app_pkgid(pkg_id, appIdString.c_str())) + : SECURITY_MANAGER_SUCCESS; +} + +static int security_manager_identify_app( + const std::function &getLabel, + char **pkg_id, + char **app_id) +{ + using namespace SecurityManager; + + LogDebug(__PRETTY_FUNCTION__ << " called"); + + if (pkg_id == NULL && app_id == NULL) { + LogError("Both pkg_id and app_id are NULL"); + return SECURITY_MANAGER_ERROR_INPUT_PARAM; + } + + std::string label; + try { + label = getLabel(); + } catch (...) { + return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT; + } + + return get_app_and_pkg_id_from_smack_label(label, pkg_id, app_id); +} + +SECURITY_MANAGER_API +int security_manager_identify_app_from_socket(int sockfd, char **pkg_id, char **app_id) +{ + return try_catch([&] { + return security_manager_identify_app([&] { + return SmackLabels::getSmackLabelFromSocket(sockfd); + }, pkg_id, app_id); + }); +} + +SECURITY_MANAGER_API +int security_manager_identify_app_from_pid(pid_t pid, char **pkg_id, char **app_id) +{ + return try_catch([&] { + return security_manager_identify_app([&] { + return SmackLabels::getSmackLabelFromPid(pid); + }, pkg_id, app_id); + }); +} diff --git a/src/common/include/smack-labels.h b/src/common/include/smack-labels.h index 1a68f1e..e9d4549 100644 --- a/src/common/include/smack-labels.h +++ b/src/common/include/smack-labels.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Rafal Krypa * @@ -86,6 +86,21 @@ std::string generatePkgLabel(const std::string &pkgId); */ std::string generatePkgROLabel(const std::string &pkgId); +/** + * Returns smack label for given socket + * + * @param[in] socket descriptor + * @return resulting Smack label + */ +std::string getSmackLabelFromSocket(int socketFd); + +/** + * Returns smack label for given process + * + * @param[in] process identifier + * @return resulting Smack label + */ +std::string getSmackLabelFromPid(pid_t pid); } // namespace SmackLabels } // namespace SecurityManager diff --git a/src/common/smack-labels.cpp b/src/common/smack-labels.cpp index d90abbb..ba5802d 100644 --- a/src/common/smack-labels.cpp +++ b/src/common/smack-labels.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd All Rights Reserved * * Contact: Rafal Krypa * @@ -31,7 +31,9 @@ #include #include #include +#include #include +#include #include @@ -168,7 +170,13 @@ std::string generateAppNameFromLabel(const std::string &label) if (label.compare(0, sizeof(prefix) - 1, prefix)) ThrowMsg(SmackException::InvalidLabel, "Cannot extract appId from Smack label " << label); - return label.substr(sizeof(prefix) - 1); + std::string ret = label.substr(sizeof(prefix) - 1); + + if (ret.size() == 0) { + ThrowMsg(SmackException::InvalidLabel, "No appId in Smack label " << label); + } + + return ret; } std::string generateAppLabel(const std::string &appId) @@ -201,6 +209,37 @@ std::string generatePkgROLabel(const std::string &pkgId) return label; } +std::string getSmackLabelFromSocket(int socketFd) +{ + char *label = nullptr; + + ssize_t labelSize = smack_new_label_from_socket(socketFd, &label); + if (labelSize < 0) { + ThrowMsg(SmackException::Base, + "smack_new_label_from_socket error for socket: " << socketFd); + } + + return label; +} + +std::string getSmackLabelFromPid(pid_t pid) +{ + std::ifstream smackFileStream("/proc/" + std::to_string(pid) + "/attr/current"); + if (!smackFileStream.is_open()) + ThrowMsg(SmackException::FileError, + "/attr/current file open error for pid: " << pid); + + std::string result; + if (!std::getline(smackFileStream, result)) + ThrowMsg(SmackException::FileError, + "/attr/current file read error for pid: " << pid); + + if (smack_label_length(result.c_str()) <= 0) + ThrowMsg(SmackException::InvalidLabel, "Invalid Smack label for process " << pid); + + return result; +} + } // namespace SmackLabels } // namespace SecurityManager diff --git a/src/include/security-manager.h b/src/include/security-manager.h index d9a735e..652ffc6 100644 --- a/src/include/security-manager.h +++ b/src/include/security-manager.h @@ -42,6 +42,7 @@ enum lib_retcode { SECURITY_MANAGER_ERROR_REQ_NOT_COMPLETE, SECURITY_MANAGER_ERROR_AUTHENTICATION_FAILED, SECURITY_MANAGER_ERROR_ACCESS_DENIED, + SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT, }; /*! \brief accesses types for application installation paths*/ @@ -778,6 +779,43 @@ int security_manager_groups_get(char ***groups, size_t *groups_count); */ void security_manager_groups_free(char **groups, size_t groups_count); +/** + * Get package and application id of an application with given socket descriptor + * + * On successful call pkg_id and app_id should be freed when caller is done with them. + * Both pkg_id and app_id are allocated with malloc() so they should be freed with free() function. + * Either app_id or pkg_id may be NULL. NULL-ed argument will be ignored. + * If both app_id and pkg_id are NULL then SECURITY_MANAGER_ERROR_INPUT_PARAM will be returned. + * When socket descriptor is incorrect or not related to any package, this function will + * return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT. + * + * \param[in] Socket descriptor of wanted application + * \param[out] package id of the application + * \param[out] application id of the application + * \return API return code or error code + */ +int security_manager_identify_app_from_socket(int sockfd, char **pkg_id, char **app_id); + +/** + * Get package and application id of an application with given process identifier + * + * On successful call pkg_id and app_id should be freed when caller is done with them. + * Both pkg_id and app_id are allocated with malloc() so they should be freed with free() function. + * Either app_id or pkg_id may be NULL. NULL-ed argument will be ignored. + * If both app_id and pkg_id are NULL then SECURITY_MANAGER_ERROR_INPUT_PARAM will be returned. + * When process identifier is incorrect or not related to any package, this function will + * return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT. + * + * \note Caller must be able to access and read file /proc/PID/atrr/current where PID is the given + * process identifier. + * + * \param[in] process identifier of wanted application + * \param[out] package id of the application + * \param[out] application id of the application + * \return API return code or error code + */ +int security_manager_identify_app_from_pid(pid_t pid, char **pkg_id, char **app_id); + #ifdef __cplusplus } #endif -- 2.7.4