mkdir -p %{buildroot}/%{TZ_SYS_DB}
touch %{buildroot}/%{TZ_SYS_DB}/.security-manager.db
touch %{buildroot}/%{TZ_SYS_DB}/.security-manager.db-journal
+mkdir -p %{buildroot}%{_sysconfdir}/skel/apps_rw
+touch %{buildroot}%{_sysconfdir}/skel/apps_rw/apps-names
+chsmack -a _ %{buildroot}%{_sysconfdir}/skel/apps_rw/apps-names
+mkdir -p %{buildroot}%{TZ_SYS_RW_APP}
+touch %{buildroot}%{TZ_SYS_RW_APP}/apps-names
+chsmack -a _ %{buildroot}%{TZ_SYS_RW_APP}/apps-names
%clean
rm -rf %{buildroot}
%attr(755,root,root) %{_bindir}/security-manager-cleanup
%attr(755,root,root) %{_sysconfdir}/gumd/useradd.d/50_security-manager-add.post
%attr(755,root,root) %{_sysconfdir}/gumd/userdel.d/50_security-manager-remove.pre
+%attr(444,root,root) %{_sysconfdir}/skel/apps_rw/apps-names
+%attr(444,root,root) %{TZ_SYS_RW_APP}/apps-names
%dir %attr(700,root,root) %{TZ_SYS_VAR}/security-manager/rules
%dir %attr(700,root,root) %{TZ_SYS_VAR}/security-manager/rules-merged
${CLIENT_PATH}/client-security-manager.cpp
${CLIENT_PATH}/client-common.cpp
${CLIENT_PATH}/client-offline.cpp
+ ${CLIENT_PATH}/client-label-monitor.cpp
)
ADD_LIBRARY(${TARGET_CLIENT} SHARED ${CLIENT_SOURCES})
--- /dev/null
+/*
+ * Copyright (c) 2016 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 client-label-monitor.cpp
+ * @author Rafal Krypa <r.krypa@samsung.com>
+ * @author Radoslaw Bartosiak <r.bartosiak@samsung.com>
+ * @version 1.0
+ * @brief Implementation of API for managing list of permited labels for launcher
+ */
+
+#include <algorithm>
+#include <cstring>
+#include <cstdlib>
+#include <memory>
+#include <string>
+#include <string.h>
+#include <vector>
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <sys/inotify.h>
+#include <sys/ioctl.h>
+#include <sys/smack.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <client-common.h>
+#include <config.h>
+#include <dpl/log/log.h>
+#include <dpl/errno_string.h>
+#include <label-monitor.h>
+#include <permissible-set.h>
+#include <protocols.h>
+#include <smack-labels.h>
+
+struct app_labels_monitor {
+ int inotify;
+ int global_labels_file_watch;
+ int user_labels_file_watch;
+ bool fresh;
+ std::string user_label_file_path;
+ app_labels_monitor() : inotify(-1), global_labels_file_watch(-1), user_labels_file_watch(-1),
+ fresh(true) {}
+};
+
+static lib_retcode apply_relabel_list(const std::string &global_label_file,
+ const std::string &user_label_file)
+{
+ std::vector<std::string> names;
+ try {
+ PermissibleSet::readNamesFromPermissibleFile(global_label_file, names);
+ PermissibleSet::readNamesFromPermissibleFile(user_label_file, names);
+ std::vector<const char*> temp;
+ std::transform(names.begin(), names.end(), std::back_inserter(temp),
+ [] (std::string &label) {label = SmackLabels::generateAppLabel(label);
+ return label.c_str();});
+ if (smack_set_relabel_self(const_cast<const char **>(temp.data()), temp.size()) != 0) {
+ LogError("smack_set_relabel_self failed");
+ return SECURITY_MANAGER_ERROR_SET_RELABEL_SELF_FAILED;
+ }
+ } catch (PermissibleSet::PermissibleSetException::FileOpenError &e) {
+ LogWarning("Invalid state of configuration files - smack_set_relabel_self not called");
+ return SECURITY_MANAGER_SUCCESS;
+ } catch (PermissibleSet::PermissibleSetException::FileReadError &e) {
+ LogError("Failed to read the configuration files");
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+ return SECURITY_MANAGER_SUCCESS;
+}
+
+static lib_retcode inotify_add_watch_full(int fd, const char* pathname, uint32_t mask, int *wd)
+{
+ int inotify_fd = inotify_add_watch(fd, pathname, mask);
+ if (inotify_fd == -1) {
+ LogError("Inotify watch failed on file " << pathname << ": " << GetErrnoString(errno));
+ return SECURITY_MANAGER_ERROR_WATCH_ADD_TO_FILE_FAILED;
+ }
+ *wd = inotify_fd;
+ return SECURITY_MANAGER_SUCCESS;
+}
+
+SECURITY_MANAGER_API
+int security_manager_app_labels_monitor_init(app_labels_monitor **monitor)
+{
+ typedef std::unique_ptr<app_labels_monitor, void (*)(app_labels_monitor *)> monitorPtr;
+ return try_catch([&] {
+ LogDebug("security_manager_app_labels_monitor_init() called");
+ if (monitor == nullptr) {
+ LogWarning("Error input param \"monitor\"");
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ }
+ int ret;
+ lib_retcode ret_lib;
+ const std::string globalFile =
+ PermissibleSet::getPerrmissibleFileLocation(SM_APP_INSTALL_GLOBAL);
+ const std::string userFile =
+ PermissibleSet::getPerrmissibleFileLocation(SM_APP_INSTALL_LOCAL);
+
+ *monitor = nullptr;
+
+ monitorPtr m(new app_labels_monitor, security_manager_app_labels_monitor_finish);
+ if (!m) {
+ LogError("Bad memory allocation for app_labels_monitor");
+ return SECURITY_MANAGER_ERROR_MEMORY;
+ }
+ ret = inotify_init();
+ if (ret == -1) {
+ LogError("Inotify init failed: " << GetErrnoString(errno));
+ return SECURITY_MANAGER_ERROR_WATCH_ADD_TO_FILE_FAILED;
+ }
+ m.get()->inotify = ret;
+ ret_lib = inotify_add_watch_full(m.get()->inotify, globalFile.c_str(),
+ IN_CLOSE_WRITE, &(m.get()->global_labels_file_watch));
+ if (ret_lib != SECURITY_MANAGER_SUCCESS) {
+ return ret_lib;
+ }
+ ret_lib = inotify_add_watch_full(m.get()->inotify,
+ userFile.c_str(), IN_CLOSE_WRITE, &(m.get()->user_labels_file_watch));
+ if (ret_lib != SECURITY_MANAGER_SUCCESS) {
+ return ret_lib;
+ }
+ m->user_label_file_path = userFile;
+ *monitor = m.release();
+ return SECURITY_MANAGER_SUCCESS;
+ });
+}
+
+SECURITY_MANAGER_API
+void security_manager_app_labels_monitor_finish(app_labels_monitor *monitor)
+{
+ try_catch([&] {
+ LogDebug("security_manager_app_labels_monitor_finish() called");
+ if (monitor == nullptr) {
+ LogDebug("input param \"monitor\" is nullptr");
+ return 0;
+ }
+ std::unique_ptr<app_labels_monitor> m(monitor);
+ if (!m)
+ LogError("Bad memory allocation for app_labels_monitor");
+ if (monitor->inotify != -1) {
+ if (monitor->global_labels_file_watch != -1) {
+ int ret = inotify_rm_watch(monitor->inotify, monitor->global_labels_file_watch);
+ if (ret == -1) {
+ LogError("Inotify watch removal failed on file " <<
+ Config::APPS_NAME_FILE << ": " << GetErrnoString(errno));
+ }
+ }
+ if (monitor->user_labels_file_watch != -1) {
+ int ret = inotify_rm_watch(monitor->inotify, monitor->user_labels_file_watch);
+ if (ret == -1) {
+ LogError("Inotify watch removal failed on file "
+ << monitor->user_label_file_path << ": " << GetErrnoString(errno));
+ }
+ }
+ close(monitor->inotify);
+ }
+ return 0;
+ });
+}
+
+SECURITY_MANAGER_API
+int security_manager_app_labels_monitor_get_fd(app_labels_monitor const *monitor, int *fd)
+{
+ return try_catch([&] {
+ LogDebug("security_manager_app_labels_monitor_get_fd() called");
+
+ if (monitor == nullptr) {
+ LogWarning("Error input param \"monitor\"");
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ }
+
+ if (fd == nullptr) {
+ LogWarning("Error input param \"fd\"");
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ }
+
+ if (monitor->inotify == -1 || monitor->global_labels_file_watch == -1 ||
+ monitor->user_labels_file_watch == -1) {
+ LogWarning("Relabel list monitor was not initialized");
+ return SECURITY_MANAGER_ERROR_NOT_INITIALIZED;
+ }
+
+ *fd = monitor->inotify;
+ return SECURITY_MANAGER_SUCCESS;
+ });
+}
+
+SECURITY_MANAGER_API
+int security_manager_app_labels_monitor_process(app_labels_monitor *monitor)
+{
+ typedef std::unique_ptr<char, void (*)(void *)> bufPtr;
+ return try_catch([&] {
+ LogDebug("security_manager_app_labels_process() called");
+ if (monitor == nullptr) {
+ LogWarning("Error input param \"monitor\"");
+ return SECURITY_MANAGER_ERROR_INPUT_PARAM;
+ }
+ const std::string globalFile =
+ PermissibleSet::getPerrmissibleFileLocation(SM_APP_INSTALL_GLOBAL);
+
+ if (monitor->inotify == -1 || monitor->global_labels_file_watch == -1 ||
+ monitor->user_labels_file_watch == -1) {
+ LogWarning("Relabel list monitor was not initialized");
+ return SECURITY_MANAGER_ERROR_NO_SUCH_OBJECT;
+ }
+
+ if (monitor->fresh) {
+ monitor->fresh = false;
+ return apply_relabel_list(globalFile, monitor->user_label_file_path);
+ }
+
+ int avail;
+ int ret = ioctl(monitor->inotify, FIONREAD, &avail);
+ if (ret == -1) {
+ LogError("Ioctl on inotify descriptor failed: " << GetErrnoString(errno));
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+
+ bufPtr buffer(static_cast<char *>(malloc(avail)), free);
+ for (int pos = 0; pos < avail;) {
+ int ret = TEMP_FAILURE_RETRY(read(monitor->inotify, buffer.get() + pos, avail - pos));
+ if (ret == -1) {
+ LogError("Inotify read failed: " << GetErrnoString(errno));
+ return SECURITY_MANAGER_ERROR_UNKNOWN;
+ }
+ pos += ret;
+ }
+
+ for (int pos = 0; pos < avail;) {
+ struct inotify_event event;
+
+ /* Event must be copied to avoid memory alignment issues */
+ memcpy(&event, buffer.get() + pos, sizeof(struct inotify_event));
+ pos += sizeof(struct inotify_event) + event.len;
+ if ((event.mask & IN_CLOSE_WRITE) &&
+ ((event.wd == monitor->global_labels_file_watch) ||
+ (event.wd == monitor->user_labels_file_watch))
+ ){
+ lib_retcode r = apply_relabel_list(globalFile, monitor->user_label_file_path);
+ if (r != SECURITY_MANAGER_SUCCESS)
+ return r;
+ break;
+ }
+ }
+ return SECURITY_MANAGER_SUCCESS;
+ });
+}
+
+
+
${COMMON_PATH}/credentials.cpp
${COMMON_PATH}/cynara.cpp
${COMMON_PATH}/file-lock.cpp
+ ${COMMON_PATH}/permissible-set.cpp
${COMMON_PATH}/protocols.cpp
${COMMON_PATH}/message-buffer.cpp
${COMMON_PATH}/privilege_db.cpp
const std::string PRIVILEGE_POLICY_ADMIN = "http://tizen.org/privilege/internal/usermanagement";
const std::string PRIVILEGE_APPSHARING_ADMIN = "http://tizen.org/privilege/notexist";
+const std::string APPS_NAME_FILE = "apps-names";
};
} /* namespace SecurityManager */
extern const std::string PRIVILEGE_POLICY_ADMIN;
extern const std::string PRIVILEGE_APPSHARING_ADMIN;
+/* Files used in permitted label managment*/
+extern const std::string APPS_NAME_FILE;
+
};
} /* namespace SecurityManager */
--- /dev/null
+/*
+ * Copyright (c) 2016 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 permissible-set.h
+ * @author RafaĆ Krypa <r.krypa@samsung.com>
+ * @author Radoslaw Bartosiak <r.bartosiak@samsung.com>
+ * @version 1.0
+ * @brief Header with API for adding, deleting and reading permissible names
+ * @brief (names of installed applications)
+ */
+#ifndef _PERMISSIBLE_SET_H_
+#define _PERMISSIBLE_SET_H_
+
+#include <cstdlib>
+#include <string>
+#include <vector>
+
+#include <dpl/exception.h>
+#include <security-manager-types.h>
+
+namespace SecurityManager {
+namespace PermissibleSet {
+
+class PermissibleSetException {
+public:
+ DECLARE_EXCEPTION_TYPE(SecurityManager::Exception, Base)
+ DECLARE_EXCEPTION_TYPE(Base, FileLockError)
+ DECLARE_EXCEPTION_TYPE(Base, FileOpenError)
+ DECLARE_EXCEPTION_TYPE(Base, FileReadError)
+ DECLARE_EXCEPTION_TYPE(Base, FileWriteError)
+};
+/**
+ * Return path to file with current list of application names
+ * installed globally or locally for the user.
+ *
+ * @param[in] installationType type of installation (global or local)
+ * @return path to file with names
+ */
+std::string getPerrmissibleFileLocation(int installationType);
+/**
+ * Update permissable file with current content of database
+ * @throws FileLockError
+ * @throws FileOpenError
+ * @throws FileWriteError
+ *
+ * @param[in] uid user id
+ * @param[in] installationType type of installation (global or local)
+ * @return resulting true on success
+ */
+void updatePermissibleFile(const uid_t uid, const int installationType);
+/**
+ * Read names from a file into a vector
+ * @throws FileLockError
+ * @throws FileOpenError
+ * @throws FileReadError
+ *
+ * @param[in] nameFile contains application names
+ * @param[out] names vector to which application names are added
+ * @return SECURITY_MANAGER_SUCCESS or error code
+ */
+void readNamesFromPermissibleFile(const std::string &nameFile, std::vector<std::string> &names);
+} // PermissibleSet
+} // SecurityManager
+#endif /* _PERMISSIBLE_SET_H_ */
static void getTizen2XApps(SmackRules::PkgsApps &pkgsApps);
- static bool getZoneId(std::string &zoneId);
-
int dropOnePrivateSharing(const std::string &ownerAppName,
const std::string &ownerPkgName,
const std::vector<std::string> &ownerPkgContents,
--- /dev/null
+/*
+ * Copyright (c) 2016 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 permissible-set.cpp
+ * @author Rafal Krypa <r.krypa@samsung.com>
+ * @author Radoslaw Bartosiak <r.bartosiak@samsung.com>
+ * @version 1.0
+ * @brief Implementation of API for adding, deleting and reading permissible names
+ * @brief (names of installed applications)
+ */
+#ifndef _GNU_SOURCE //for TEMP_FAILURE_RETRY
+#define _GNU_SOURCE
+#endif
+
+#include <cstdio>
+#include <cstring>
+#include <memory>
+#include <pwd.h>
+#include <string>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <config.h>
+#include <dpl/errno_string.h>
+#include <dpl/exception.h>
+#include <dpl/log/log.h>
+#include <permissible-set.h>
+#include <privilege_db.h>
+#include <security-manager-types.h>
+#include <tzplatform_config.h>
+
+typedef std::unique_ptr<FILE, int (*)(FILE *)> filePtr;
+
+namespace SecurityManager {
+namespace PermissibleSet {
+
+static filePtr openAndLockNameFile(const std::string &nameFile, const char* mode)
+{
+ filePtr file(fopen(nameFile.c_str(), mode), fclose);
+ if (!file) {
+ LogError("Unable to open file" << nameFile << ": " << GetErrnoString(errno));
+ ThrowMsg(PermissibleSetException::FileOpenError, "Unable to open file ");
+ }
+
+ int ret = TEMP_FAILURE_RETRY(flock(fileno(file.get()), LOCK_EX));
+ if (ret == -1) {
+ LogError("Unable to lock file " << nameFile << ": " << GetErrnoString(errno));
+ ThrowMsg(PermissibleSetException::FileLockError, "Unable to lock file");
+ }
+ return file;
+}
+
+std::string getPerrmissibleFileLocation(int installationType)
+{
+ if ((installationType == SM_APP_INSTALL_GLOBAL)
+ || (installationType == SM_APP_INSTALL_PRELOADED))
+ return tzplatform_mkpath(TZ_SYS_RW_APP, Config::APPS_NAME_FILE.c_str());
+ return tzplatform_mkpath(TZ_USER_APP, Config::APPS_NAME_FILE.c_str());
+
+}
+
+static void markPermissibleFileValid(int fd, const std::string &nameFile, bool valid)
+{
+ int ret;
+ if (valid)
+ ret = TEMP_FAILURE_RETRY(fchmod(fd, 00444));
+ else
+ ret = TEMP_FAILURE_RETRY(fchmod(fd, 00000));
+ if (ret == -1) {
+ LogError("Error at fchmod " << nameFile << ": " << GetErrnoString(errno));
+ ThrowMsg(PermissibleSetException::FileWriteError, "Error at fchmod");
+ }
+}
+
+void updatePermissibleFile(uid_t uid, int installationType)
+{
+ std::string nameFile = getPerrmissibleFileLocation(installationType);
+ filePtr file = openAndLockNameFile(nameFile, "w");
+ markPermissibleFileValid(fileno(file.get()), nameFile, false);
+ std::vector<std::string> appNames;
+ PrivilegeDb::getInstance().GetUserApps(uid, appNames);
+ for (auto &name : appNames) {
+ if (fprintf(file.get(), "%s\n", name.c_str()) < 0) {
+ LogError("Unable to fprintf() to file " << nameFile << ": " << GetErrnoString(errno));
+ ThrowMsg(PermissibleSetException::PermissibleSetException::FileWriteError,
+ "Unable to fprintf() to file");
+ }
+ }
+ if (fflush(file.get()) != 0) {
+ LogError("Error at fflush " << nameFile << ": " << GetErrnoString(errno));
+ ThrowMsg(PermissibleSetException::FileWriteError, "Error at fflush");
+ }
+ if (fsync(fileno(file.get())) == -1) {
+ LogError("Error at fsync " << nameFile << ": " << GetErrnoString(errno));
+ ThrowMsg(PermissibleSetException::FileWriteError, "Error at fsync");
+ }
+ markPermissibleFileValid(fileno(file.get()), nameFile, true);
+}
+
+void readNamesFromPermissibleFile(const std::string &nameFile, std::vector<std::string> &names)
+{
+ filePtr file = openAndLockNameFile(nameFile, "r");
+ int ret;
+ do {
+ char *buf = nullptr;
+ std::size_t bufSize = 0;
+ switch (ret = getline(&buf, &bufSize, file.get())) {
+ case 0:
+ continue;
+ case -1:
+ if (feof(file.get()))
+ break;
+ LogError("Failure while reading file " << nameFile << ": " << GetErrnoString(errno));
+ ThrowMsg(PermissibleSetException::FileReadError, "Failure while reading file");
+ default:
+ std::unique_ptr<char, decltype(free)*> buf_up(buf, free);
+ if (buf[ret - 1] == '\n')
+ buf[ret - 1] = '\0';
+ names.push_back(buf);
+ buf_up.release();
+ }
+ } while (ret != -1);
+}
+
+} // PermissibleSet
+} // SecurityManager
#include "protocols.h"
#include "privilege_db.h"
#include "cynara.h"
+#include "permissible-set.h"
#include "smack-rules.h"
#include "smack-labels.h"
#include "security-manager.h"
// WTF? Why this commit is here? Shouldn't it be at the end of this function?
PrivilegeDb::getInstance().CommitTransaction();
LogDebug("Application installation commited to database");
+ PermissibleSet::updatePermissibleFile(req.uid, req.installationType);
} catch (const PrivilegeDb::Exception::IOError &e) {
LogError("Cannot access application database: " << e.DumpToString());
return SECURITY_MANAGER_ERROR_SERVER_ERROR;
PrivilegeDb::getInstance().RollbackTransaction();
LogError("Error while setting Cynara rules for application: " << e.DumpToString());
return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+ } catch (const PermissibleSet::PermissibleSetException::Base &e) {
+ LogError("Error while updating permissible file: " << e.DumpToString());
+ return SECURITY_MANAGER_ERROR_SERVER_ERROR;
} catch (const SmackException::InvalidLabel &e) {
PrivilegeDb::getInstance().RollbackTransaction();
LogError("Error while generating Smack labels: " << e.DumpToString());
CynaraAdmin::getInstance().UpdateAppPolicy(smackLabel, cynaraUserStr, std::vector<std::string>());
PrivilegeDb::getInstance().CommitTransaction();
LogDebug("Application uninstallation commited to database");
+ PermissibleSet::updatePermissibleFile(req.uid, req.installationType);
} catch (const PrivilegeDb::Exception::IOError &e) {
LogError("Cannot access application database: " << e.DumpToString());
return SECURITY_MANAGER_ERROR_SERVER_ERROR;
PrivilegeDb::getInstance().RollbackTransaction();
LogError("Error while setting Cynara rules for application: " << e.DumpToString());
return SECURITY_MANAGER_ERROR_SERVER_ERROR;
+ } catch (const PermissibleSet::PermissibleSetException::Base &e) {
+ LogError("Error while updating permissible file: " << e.DumpToString());
+ return SECURITY_MANAGER_ERROR_SERVER_ERROR;
} catch (const SmackException::InvalidLabel &e) {
PrivilegeDb::getInstance().RollbackTransaction();
LogError("Error while generating Smack labels: " << e.DumpToString());
${INCLUDE_PATH}/app-manager.h
${INCLUDE_PATH}/app-runtime.h
${INCLUDE_PATH}/app-sharing.h
+ ${INCLUDE_PATH}/label-monitor.h
${INCLUDE_PATH}/user-manager.h
${INCLUDE_PATH}/policy-manager.h
DESTINATION ${INCLUDE_INSTALL_DIR}/security-manager
--- /dev/null
+/*
+ * Copyright (c) 2016 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 label-monitor.h
+ * @author Rafal Krypa (r.krypa@samsung.com)
+ * @author Radoslaw Bartosiak (r.bartosiak@samsung.com)
+ * @version 1.0
+ * @brief Header with API targeted for launcher to monitor labels of installed applications
+ */
+#ifndef _LABEL_MONITOR_H_
+#define _LABEL_MONITOR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "security-manager-types.h"
+
+typedef struct app_labels_monitor app_labels_monitor;
+
+/**
+ * Initialize applications' labels monitor
+ * The monitor is intended for watching for changes to the list of labels
+ * assigned to currently installed applications.
+ * It will allocate resources that must be freed later by
+ * \ref security_manager_app_labels_monitor_finish.
+ * Intended user of this function is the application launcher.
+ *
+ * \param[out] monitor pointer to the resulting applications' label monitor
+ *
+ * \return SECURITY_MANAGER_SUCCESS on success or error code on failure
+ *
+ * \par Example
+ * \parblock
+ * (warning: simplified code example, with committed error handling)
+ * \code{.c}
+ * app_labels_monitor *monitor;
+ * int fd;
+ * nfds_t nfds = 1;
+ * struct pollfd fds[1];
+ *
+ * security_manager_app_labels_monitor_init(&monitor);
+ * security_manager_app_labels_monitor_process(monitor);
+ * security_manager_app_labels_monitor_get_fd(monitor, &fd);
+ * fds[0].fd = fd;
+ * fds[0].events = POLLIN;
+ * while (1) {
+ * int poll_num = TEMP_FAILURE_RETRY(poll(fds, nfds, -1));
+ * if (poll_num > 0) {
+ * if (fds[0].revents & POLLIN) {
+ * security_manager_app_labels_monitor_process(monitor);
+ * // Do your stuff - react on new list of applications' labels
+ * }
+ * }
+ * }
+ * // ...
+ * // Before finishing, release the labels monitor
+ * security_manager_app_labels_monitor_finish(monitor);
+ *
+ * \endcode
+ */
+int security_manager_app_labels_monitor_init(app_labels_monitor **monitor);
+
+/**
+ * De-initialize applications' labels monitor
+ * Frees all resources previously allocated by \ref security_manager_app_labels_monitor_init
+ *
+ * \param[in] monitor an initialized applications' label monitor
+ *
+ * \return SECURITY_MANAGER_SUCCESS on success or error code on failure
+ */
+void security_manager_app_labels_monitor_finish(app_labels_monitor *monitor);
+
+/**
+ * Retrieve file descriptor for waiting on applications' labels monitor
+ * The file descriptor should be put to a select-like waiting loop. It will indicate
+ * new list of applications' labels by being ready for reading.
+ *
+ * \param[in] monitor an initialized applications' label monitor
+ * \param[out] fd pointer to the resulting file descriptor
+ *
+ * \return SECURITY_MANAGER_SUCCESS on success or error code on failure
+ */
+int security_manager_app_labels_monitor_get_fd(app_labels_monitor const *monitor, int *fd);
+
+/**
+ * Apply new list of applications' labels to Smack relabel-list of the current process
+ * This will give permission to the current process to change its Smack label to one
+ * of application labels, even after it drops CAP_MAC_ADMIN capability.
+ *
+ * \param[in] monitor an initialized applications' label monitor
+ *
+ * \return SECURITY_MANAGER_SUCCESS on success or error code on failure
+ *
+ * Access to this function requires CAP_MAC_ADMIN capability.
+ */
+int security_manager_app_labels_monitor_process(app_labels_monitor *monitor);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LABEL_MONITOR_H_ */
SECURITY_MANAGER_ERROR_NO_SUCH_SERVICE,
SECURITY_MANAGER_ERROR_SERVER_ERROR,
SECURITY_MANAGER_ERROR_SETTING_FILE_LABEL_FAILED,
+ SECURITY_MANAGER_ERROR_WATCH_ADD_TO_FILE_FAILED,
+ SECURITY_MANAGER_ERROR_FILE_OPEN_FAILED,
+ SECURITY_MANAGER_ERROR_SET_RELABEL_SELF_FAILED,
+ SECURITY_MANAGER_ERROR_NOT_INITIALIZED,
};
/*! \brief accesses types for application installation paths*/
struct path_req;
typedef struct path_req path_req;
+/*! \brief data structure responsible for handling information on
+ * changes in labels required by applications*/
+struct app_labels_monitor;
+typedef struct app_labels_monitor app_labels_monitor;
+
/*! \brief wildcard to be used in requests to match all possible values of given field.
* Use it, for example when it is desired to list or apply policy change for all
* users or all apps for selected user.
#include "app-manager.h"
#include "app-runtime.h"
#include "app-sharing.h"
+#include "label-monitor.h"
#include "user-manager.h"
#include "policy-manager.h"