summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafał Krypa <rafal@krypa.net>2014-07-11 21:28:21 +0200
committerRafał Krypa <rafal@krypa.net>2014-07-13 23:11:10 +0200
commitff65c427acfcb6d445ee6ae8cbeb570dc744edae (patch)
tree7964c3b620834aa07066d8333ba58a1624ab5343
parent2b9788436113767c3c31b5d0b6d5b8c7303babc5 (diff)
downloadsecurity-manager-ff65c427acfcb6d445ee6ae8cbeb570dc744edae.tar.gz
security-manager-ff65c427acfcb6d445ee6ae8cbeb570dc744edae.tar.bz2
security-manager-ff65c427acfcb6d445ee6ae8cbeb570dc744edae.zip
Refactoring: put code operating on Smack labels in a separate file
Create smack-labels.cpp, containing code for label assignment and file labeling. Avoid clutter in installer.cpp. Change-Id: I97f5251e1bfcd53e242cd0117d48539a378fefde Signed-off-by: Rafal Krypa <r.krypa@samsung.com>
-rw-r--r--src/server/CMakeLists.txt1
-rw-r--r--src/server/service/include/installer.h2
-rw-r--r--src/server/service/include/smack-labels.h61
-rw-r--r--src/server/service/include/smack-rules.h9
-rw-r--r--src/server/service/installer.cpp233
-rw-r--r--src/server/service/smack-labels.cpp249
-rw-r--r--src/server/service/smack-rules.cpp8
7 files changed, 320 insertions, 243 deletions
diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt
index 5fc4c399..38948881 100644
--- a/src/server/CMakeLists.txt
+++ b/src/server/CMakeLists.txt
@@ -38,6 +38,7 @@ SET(SERVER_SOURCES
${SERVER_PATH}/main/socket-manager.cpp
${SERVER_PATH}/main/server-main.cpp
${SERVER_PATH}/service/smack-rules.cpp
+ ${SERVER_PATH}/service/smack-labels.cpp
${SERVER_PATH}/service/installer.cpp
${SERVER_PATH}/db/privilege_db.cpp
${DPL_PATH}/core/src/errno_string.cpp
diff --git a/src/server/service/include/installer.h b/src/server/service/include/installer.h
index 8e240aef..c73f93ac 100644
--- a/src/server/service/include/installer.h
+++ b/src/server/service/include/installer.h
@@ -58,8 +58,6 @@ public:
void process(const ReadEvent &event);
void close(const CloseEvent &event);
- static const char *const LABEL_FOR_PUBLIC_APP_PATH;
-
private:
ConnectionInfoMap m_connectionInfoMap;
PrivilegeDb m_privilegeDb;
diff --git a/src/server/service/include/smack-labels.h b/src/server/service/include/smack-labels.h
new file mode 100644
index 00000000..a017991d
--- /dev/null
+++ b/src/server/service/include/smack-labels.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2014 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 smack-labels.h
+ * @author Jan Cybulski <j.cybulski@samsung.com>
+ * @author Rafal Krypa <r.krypa@samsung.com>
+ * @version 1.0
+ * @brief Header file of functions managing smack labels
+ *
+ */
+#ifndef _SMACK_LABELS_H_
+#define _SMACK_LABELS_H_
+
+#include <string>
+#include <utility>
+
+#include "security-manager.h"
+
+namespace SecurityManager {
+
+/**
+ * Generates label for application with package identifier
+ * read from @ref pkgId and assigns it to @ref label.
+ * @param[in] pkgId application's package identifier.
+ * @param[out] label string into which application's label will be stored into.
+ *
+ * @return true on success, false on error.
+*/
+bool generateAppLabel(const std::string &pkgId, std::string &label);
+
+/**
+ * Sets Smack labels on a directory and its contents, recursively.
+ *
+ * @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
+ *
+ * @return true on success, false on error.
+ */
+bool setupPath(const std::string &pkgId, const std::string &path,
+ app_install_path_type pathType);
+
+} // namespace SecurityManager
+
+#endif /* _SMACK_LABELS_H_ */
diff --git a/src/server/service/include/smack-rules.h b/src/server/service/include/smack-rules.h
index 6aa6775d..db816311 100644
--- a/src/server/service/include/smack-rules.h
+++ b/src/server/service/include/smack-rules.h
@@ -70,15 +70,6 @@ public:
*/
static bool uninstallPackageRules(const std::string &pkgId);
- /**
- * Generates label for application with package identifier
- * read from @ref appPkgId and assigns it to @ref label.
- * @param[in] appPkgId application's package identifier.
- * @param[out] label string into which application's label will be stored into.
- * @return true on success, false on error.
- */
- static bool generateAppLabel(const std::string &appPkgId, std::string &label);
-
private:
static std::string getPackageRulesFilePath(const std::string &pkgId);
diff --git a/src/server/service/installer.cpp b/src/server/service/installer.cpp
index fc993e0d..d7810a9b 100644
--- a/src/server/service/installer.cpp
+++ b/src/server/service/installer.cpp
@@ -28,237 +28,17 @@
#include <privilege-control.h>
-#include <sys/stat.h>
-#include <sys/smack.h>
-#include <sys/xattr.h>
-#include <linux/xattr.h>
-#include <memory>
-#include <fts.h>
-#include <cstring>
-
#include "installer.h"
#include "protocols.h"
#include "security-manager.h"
#include "smack-rules.h"
+#include "smack-labels.h"
#include "privilege_db.h"
namespace SecurityManager {
-namespace {
-
const InterfaceID INSTALLER_IFACE = 0;
-/* Const defined below is used to label links to executables */
-const char *const XATTR_NAME_TIZENEXEC = XATTR_SECURITY_PREFIX "TIZEN_EXEC_LABEL";
-
-/**
- * Return values
- * -1 - error
- * 0 - skip
- * 1 - label
- */
-enum class FileDecision {
- SKIP = 0,
- LABEL = 1,
- ERROR = -1
-};
-
-typedef std::function<FileDecision(const FTSENT*)> LabelDecisionFn;
-
-
-FileDecision labelAll(const FTSENT *ftsent __attribute__((unused)))
-{
- LogDebug("Entering function: " << __func__);
-
- return FileDecision::LABEL;
-}
-
-FileDecision labelDirs(const FTSENT *ftsent)
-{
- LogDebug("Entering function: " << __func__);
-
- // label only directories
- if (S_ISDIR(ftsent->fts_statp->st_mode))
- return FileDecision::LABEL;
- return FileDecision::SKIP;
-}
-
-FileDecision labelExecs(const FTSENT *ftsent)
-{
- LogDebug("Entering function: " << __func__);
-
- LogDebug("Mode = " << ftsent->fts_statp->st_mode);
- // label only regular executable files
- if (S_ISREG(ftsent->fts_statp->st_mode) && (ftsent->fts_statp->st_mode & S_IXUSR))
- return FileDecision::LABEL;
- return FileDecision::SKIP;
-}
-
-
-FileDecision labelLinksToExecs(const FTSENT *ftsent)
-{
- LogDebug("Entering function: " << __func__);
-
- struct stat buf;
-
- // check if it's a link
- if ( !S_ISLNK(ftsent->fts_statp->st_mode))
- return FileDecision::SKIP;
-
- std::unique_ptr<char, std::function<void(void*)>> target(realpath(ftsent->fts_path, NULL), free);
-
- if (!target.get()) {
- LogError("Getting link target for " << ftsent->fts_path << " failed (Error = " << strerror(errno) << ")");
- return FileDecision::ERROR;
- }
-
- if (-1 == stat(target.get(), &buf)) {
- LogError("stat failed for " << target.get() << " (Error = " << strerror(errno) << ")");
- return FileDecision::ERROR;
- }
- // skip if link target is not a regular executable file
- if (buf.st_mode != (buf.st_mode | S_IXUSR | S_IFREG)) {
- LogDebug(target.get() << "is not a regular executable file. Skipping.");
- return FileDecision::SKIP;
- }
-
- return FileDecision::LABEL;
-}
-
-bool dirSetSmack(const std::string &path, const std::string &label,
- const char *xattr_name, LabelDecisionFn fn)
-{
- LogDebug("Entering function: "<< __func__ <<". Params:"
- " path=" << path << ", label=" << label << ", xattr=" << xattr_name);
-
-
- char *const path_argv[] = {const_cast<char *>(path.c_str()), NULL};
- FTSENT *ftsent;
- FileDecision ret;
-
- std::unique_ptr<FTS, std::function<void(FTS*)> > fts(
- fts_open(path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL),
- fts_close);
-
- if (fts.get() == NULL) {
- LogError("fts_open failed.");
- return false;
- }
-
- while ((ftsent = fts_read(fts.get())) != NULL) {
- /* Check for error (FTS_ERR) or failed stat(2) (FTS_NS) */
- if (ftsent->fts_info == FTS_ERR || ftsent->fts_info == FTS_NS) {
- LogError("FTS_ERR error or failed stat(2) (FTS_NS)");
- return false;
- }
-
- ret = fn(ftsent);
- if (ret == FileDecision::ERROR) {
- LogError("fn(ftsent) failed.");
- return false;
- }
-
- if (ret == FileDecision::LABEL) {
- if (lsetxattr(ftsent->fts_path, xattr_name, label.c_str(), label.length(), 0) != 0) {
- LogError("lsetxattr failed.");
- return false;
- }
- }
-
- }
-
- /* If last call to fts_read() set errno, we need to return error. */
- if ((errno != 0) && (ftsent == NULL)) {
- LogError("Last errno from fts_read: " << strerror(errno));
- return false;
- }
- return true;
-}
-
-
-bool labelDir(const std::string &path, const std::string &label,
- bool set_transmutable, bool set_executables)
-{
- LogDebug("Entering function: "<< __func__ <<". Params:"
- " path=" << path << " label= " << label
- << " set_transmutable= " << set_transmutable
- << " set_executables= " << set_executables);
- bool ret = true;
-
- // setting access label on everything in given directory and below
- ret = dirSetSmack(path, label, XATTR_NAME_SMACK, labelAll);
- if (!ret) {
- LogError("dirSetSmack failed (access label)");
- return ret;
- }
-
- if (set_transmutable) {
- // setting transmute on dirs
- ret = dirSetSmack(path, "TRUE", XATTR_NAME_SMACKTRANSMUTE, labelDirs);
- if (!ret) {
- LogError("dirSetSmack failed (transmute)");
- return ret;
- }
- }
-
- if (set_executables) {
- ret = dirSetSmack(path, label, XATTR_NAME_SMACKEXEC, &labelExecs);
- if (!ret)
- {
- LogError("dirSetSmack failed (execs).");
- return ret;
- }
-
- //setting execute label for everything with permission to execute
- ret = dirSetSmack(path, label, XATTR_NAME_TIZENEXEC, &labelLinksToExecs);
- if (!ret)
- {
- LogError("dirSetSmack failed (link to execs).");
- return ret;
- }
- }
-
- return ret;
-}
-
-
-bool setupPath(const std::string &pkgId, const std::pair<std::string, int> &appPath)
-{
- using namespace SecurityManager;
-
- app_install_path_type pathType = static_cast<app_install_path_type>(appPath.second);
- std::string label;
- bool label_executables, label_transmute;
-
-
- switch (pathType) {
- case SECURITY_MANAGER_PATH_PRIVATE:
- if (!SmackRules::generateAppLabel(pkgId, label))
- return false;
- label_executables = true;
- label_transmute = false;
- break;
- case SECURITY_MANAGER_PATH_PUBLIC:
- label.assign(InstallerService::LABEL_FOR_PUBLIC_APP_PATH);
- label_executables = false;
- label_transmute = true;
- break;
- case SECURITY_MANAGER_PATH_PUBLIC_RO:
- label.assign("_");
- label_executables = false;
- label_transmute = false;
- break;
- default:
- LogError("Path type not known.");
- return false;
- }
- return labelDir(appPath.first, label, label_transmute, label_executables);
-}
-
-} // namespace anonymous
-
-/* Const defined below is used to label links to executables */
-const char *const InstallerService::LABEL_FOR_PUBLIC_APP_PATH = "User";
InstallerService::InstallerService()
{
@@ -383,7 +163,7 @@ bool InstallerService::processAppInstall(MessageBuffer &buffer, MessageBuffer &s
LogDebug("pkgId: " << req.pkgId);
std::string smackLabel;
- if (!SmackRules::generateAppLabel(req.pkgId, smackLabel)) {
+ if (!generateAppLabel(req.pkgId, smackLabel)) {
LogError("Cannot generate Smack label for package");
Serialization::Serialize(send, SECURITY_MANAGER_API_ERROR_SERVER_ERROR);
return false;
@@ -440,8 +220,11 @@ bool InstallerService::processAppInstall(MessageBuffer &buffer, MessageBuffer &s
}
// register paths
- for (const auto& appPath : req.appPaths) {
- result = setupPath(req.pkgId, appPath);
+ 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);
+ result = setupPath(req.pkgId, path, pathType);
+
if (!result) {
LogDebug("setupPath() failed ");
goto error_label;
@@ -512,7 +295,7 @@ bool InstallerService::processAppUninstall(MessageBuffer &buffer, MessageBuffer
} else {
LogDebug("pkgId: " << pkgId);
- if (!SmackRules::generateAppLabel(pkgId, smackLabel)) {
+ if (!generateAppLabel(pkgId, smackLabel)) {
LogError("Cannot generate Smack label for package");
goto error_label;
}
diff --git a/src/server/service/smack-labels.cpp b/src/server/service/smack-labels.cpp
new file mode 100644
index 00000000..3b88c738
--- /dev/null
+++ b/src/server/service/smack-labels.cpp
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2014 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 smack-labels.cpp
+ * @author Jan Cybulski <j.cybulski@samsung.com>
+ * @author Rafal Krypa <r.krypa@samsung.com>
+ * @version 1.0
+ * @brief Implementation of functions managing smack labels
+ *
+ */
+
+#include <sys/stat.h>
+#include <sys/smack.h>
+#include <sys/xattr.h>
+#include <linux/xattr.h>
+#include <memory>
+#include <fts.h>
+#include <cstring>
+#include <string>
+
+#include <dpl/log/log.h>
+
+#include "security-manager.h"
+#include "smack-labels.h"
+
+namespace SecurityManager {
+
+/* Const defined below is used to label links to executables */
+const char *const XATTR_NAME_TIZENEXEC = XATTR_SECURITY_PREFIX "TIZEN_EXEC_LABEL";
+
+/* Const defined below is used to label links to executables */
+const char *const LABEL_FOR_PUBLIC_APP_PATH = "User";
+
+enum class FileDecision {
+ SKIP = 0,
+ LABEL = 1,
+ ERROR = -1
+};
+
+typedef std::function<FileDecision(const FTSENT*)> LabelDecisionFn;
+
+
+bool generateAppLabel(const std::string &appPkgId, std::string &label)
+{
+ (void) appPkgId; // TODO use pkgId to generate label
+ label = "User";
+ return true;
+}
+
+static FileDecision labelAll(const FTSENT *ftsent __attribute__((unused)))
+{
+ LogDebug("Entering function: " << __func__);
+
+ return FileDecision::LABEL;
+}
+
+static FileDecision labelDirs(const FTSENT *ftsent)
+{
+ LogDebug("Entering function: " << __func__);
+
+ // label only directories
+ if (S_ISDIR(ftsent->fts_statp->st_mode))
+ return FileDecision::LABEL;
+ return FileDecision::SKIP;
+}
+
+static FileDecision labelExecs(const FTSENT *ftsent)
+{
+ LogDebug("Entering function: " << __func__);
+
+ LogDebug("Mode = " << ftsent->fts_statp->st_mode);
+ // label only regular executable files
+ if (S_ISREG(ftsent->fts_statp->st_mode) && (ftsent->fts_statp->st_mode & S_IXUSR))
+ return FileDecision::LABEL;
+ return FileDecision::SKIP;
+}
+
+static FileDecision labelLinksToExecs(const FTSENT *ftsent)
+{
+ LogDebug("Entering function: " << __func__);
+
+ struct stat buf;
+
+ // check if it's a link
+ if ( !S_ISLNK(ftsent->fts_statp->st_mode))
+ return FileDecision::SKIP;
+
+ std::unique_ptr<char, std::function<void(void*)>> target(realpath(ftsent->fts_path, NULL), free);
+
+ if (!target.get()) {
+ LogError("Getting link target for " << ftsent->fts_path << " failed (Error = " << strerror(errno) << ")");
+ return FileDecision::ERROR;
+ }
+
+ if (-1 == stat(target.get(), &buf)) {
+ LogError("stat failed for " << target.get() << " (Error = " << strerror(errno) << ")");
+ return FileDecision::ERROR;
+ }
+ // skip if link target is not a regular executable file
+ if (buf.st_mode != (buf.st_mode | S_IXUSR | S_IFREG)) {
+ LogDebug(target.get() << "is not a regular executable file. Skipping.");
+ return FileDecision::SKIP;
+ }
+
+ return FileDecision::LABEL;
+}
+
+static bool dirSetSmack(const std::string &path, const std::string &label,
+ const char *xattr_name, LabelDecisionFn fn)
+{
+ LogDebug("Entering function: "<< __func__ <<". Params:"
+ " path=" << path << ", label=" << label << ", xattr=" << xattr_name);
+
+
+ char *const path_argv[] = {const_cast<char *>(path.c_str()), NULL};
+ FTSENT *ftsent;
+ FileDecision ret;
+
+ std::unique_ptr<FTS, std::function<void(FTS*)> > fts(
+ fts_open(path_argv, FTS_PHYSICAL | FTS_NOCHDIR, NULL),
+ fts_close);
+
+ if (fts.get() == NULL) {
+ LogError("fts_open failed.");
+ return false;
+ }
+
+ while ((ftsent = fts_read(fts.get())) != NULL) {
+ /* Check for error (FTS_ERR) or failed stat(2) (FTS_NS) */
+ if (ftsent->fts_info == FTS_ERR || ftsent->fts_info == FTS_NS) {
+ LogError("FTS_ERR error or failed stat(2) (FTS_NS)");
+ return false;
+ }
+
+ ret = fn(ftsent);
+ if (ret == FileDecision::ERROR) {
+ LogError("fn(ftsent) failed.");
+ return false;
+ }
+
+ if (ret == FileDecision::LABEL) {
+ if (lsetxattr(ftsent->fts_path, xattr_name, label.c_str(), label.length(), 0) != 0) {
+ LogError("lsetxattr failed.");
+ return false;
+ }
+ }
+
+ }
+
+ /* If last call to fts_read() set errno, we need to return error. */
+ if ((errno != 0) && (ftsent == NULL)) {
+ LogError("Last errno from fts_read: " << strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+
+static bool labelDir(const std::string &path, const std::string &label,
+ bool set_transmutable, bool set_executables)
+{
+ LogDebug("Entering function: "<< __func__ <<". Params:"
+ " path=" << path << " label= " << label
+ << " set_transmutable= " << set_transmutable
+ << " set_executables= " << set_executables);
+ bool ret = true;
+
+ // setting access label on everything in given directory and below
+ ret = dirSetSmack(path, label, XATTR_NAME_SMACK, labelAll);
+ if (!ret) {
+ LogError("dirSetSmack failed (access label)");
+ return ret;
+ }
+
+ if (set_transmutable) {
+ // setting transmute on dirs
+ ret = dirSetSmack(path, "TRUE", XATTR_NAME_SMACKTRANSMUTE, labelDirs);
+ if (!ret) {
+ LogError("dirSetSmack failed (transmute)");
+ return ret;
+ }
+ }
+
+ if (set_executables) {
+ ret = dirSetSmack(path, label, XATTR_NAME_SMACKEXEC, &labelExecs);
+ if (!ret)
+ {
+ LogError("dirSetSmack failed (execs).");
+ return ret;
+ }
+
+ //setting execute label for everything with permission to execute
+ ret = dirSetSmack(path, label, XATTR_NAME_TIZENEXEC, &labelLinksToExecs);
+ if (!ret)
+ {
+ LogError("dirSetSmack failed (link to execs).");
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+bool setupPath(const std::string &pkgId, const std::string &path,
+ app_install_path_type pathType)
+{
+ std::string label;
+ bool label_executables, label_transmute;
+
+ switch (pathType) {
+ case SECURITY_MANAGER_PATH_PRIVATE:
+ if (!generateAppLabel(pkgId, label))
+ return false;
+ label_executables = true;
+ label_transmute = false;
+ break;
+ case SECURITY_MANAGER_PATH_PUBLIC:
+ label.assign(LABEL_FOR_PUBLIC_APP_PATH);
+ label_executables = false;
+ label_transmute = true;
+ break;
+ case SECURITY_MANAGER_PATH_PUBLIC_RO:
+ label.assign("_");
+ label_executables = false;
+ label_transmute = false;
+ break;
+ default:
+ LogError("Path type not known.");
+ return false;
+ }
+ return labelDir(path, label, label_transmute, label_executables);
+}
+
+} // namespace SecurityManager
diff --git a/src/server/service/smack-rules.cpp b/src/server/service/smack-rules.cpp
index 32b83c93..f8d4f09d 100644
--- a/src/server/service/smack-rules.cpp
+++ b/src/server/service/smack-rules.cpp
@@ -35,6 +35,7 @@
#include <dpl/log/log.h>
#include <tzplatform_config.h>
+#include "smack-labels.h"
#include "smack-rules.h"
namespace SecurityManager {
@@ -42,13 +43,6 @@ namespace SecurityManager {
const char *const SMACK_APP_LABEL_TEMPLATE = "~APP~";
const char *const APP_RULES_TEMPLATE_FILE_PATH = tzplatform_mkpath(TZ_SYS_SMACK, "app-rules-template.smack");
-bool SmackRules::generateAppLabel(const std::string &appPkgId, std::string &label)
-{
- (void) appPkgId; //todo use pkgId to generate label
- label = "User";
- return true;
-}
-
SmackRules::SmackRules()
{
if (smack_accesses_new(&m_handle) < 0) {