From 06c008e9f0b250a1a50744d3efa33f1e4fffdddf Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Thu, 5 Mar 2015 12:46:04 +0100 Subject: [PATCH 01/16] Grant all privileges to programs with "User" and "System" Smack labels Now with application labels no longer hardcoded to "User", it's time to work on actual policy enforcment in services. Platform components that are not downloadabla applications will run with "User" and "System" labels (for User and System domains). They should not be restricted by Cynara. Change-Id: I62ea8295804f3ad04b1a538642d2098aab45cb48 Signed-off-by: Rafal Krypa --- policy/security-manager-policy-reload | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/policy/security-manager-policy-reload b/policy/security-manager-policy-reload index 807daf3..d15cec5 100755 --- a/policy/security-manager-policy-reload +++ b/policy/security-manager-policy-reload @@ -5,7 +5,7 @@ USERTYPE_POLICY_PATH=/usr/share/security-manager/policy # Create default buckets while read bucket default_policy do - # Reuse the main bucket for PRIVACY_MANAGER bucket + # Reuse the primary bucket for PRIVACY_MANAGER bucket [ "$bucket" = "PRIVACY_MANAGER" ] && bucket="" cyad --set-bucket="$bucket" --type="$default_policy" done < Date: Thu, 5 Mar 2015 12:36:02 +0100 Subject: [PATCH 02/16] Move template for application Smack rules to security-manager-policy Change-Id: If323c8d8e8a930291d2db348e5a375711345707a Signed-off-by: Rafal Krypa --- packaging/security-manager.spec | 3 --- policy/CMakeLists.txt | 1 + app-rules-template.smack => policy/app-rules-template.smack | 0 src/common/smack-rules.cpp | 2 +- 4 files changed, 2 insertions(+), 4 deletions(-) rename app-rules-template.smack => policy/app-rules-template.smack (100%) diff --git a/packaging/security-manager.spec b/packaging/security-manager.spec index 3daa3be..1783fc4 100644 --- a/packaging/security-manager.spec +++ b/packaging/security-manager.spec @@ -81,8 +81,6 @@ rm -rf %{buildroot} mkdir -p %{buildroot}%{_datadir}/license cp LICENSE %{buildroot}%{_datadir}/license/%{name} cp LICENSE %{buildroot}%{_datadir}/license/libsecurity-manager-client -mkdir -p %{buildroot}/%{TZ_SYS_SMACK} -cp app-rules-template.smack %{buildroot}/%{TZ_SYS_SMACK} %make_install mkdir -p %{buildroot}/%{_unitdir}/sockets.target.wants @@ -137,7 +135,6 @@ fi %{_libdir}/libsecurity-manager-commons.so.* %attr(-,root,root) %{_unitdir}/security-manager.* %attr(-,root,root) %{_unitdir}/sockets.target.wants/security-manager.* -%attr(-,root,root) %{TZ_SYS_SMACK}/app-rules-template.smack %config(noreplace) %attr(0600,root,root) %{TZ_SYS_DB}/.security-manager.db %config(noreplace) %attr(0600,root,root) %{TZ_SYS_DB}/.security-manager.db-journal %{_datadir}/license/%{name} diff --git a/policy/CMakeLists.txt b/policy/CMakeLists.txt index 1d35a3f..32d6ee6 100644 --- a/policy/CMakeLists.txt +++ b/policy/CMakeLists.txt @@ -1,3 +1,4 @@ FILE(GLOB USERTYPE_POLICY_FILES usertype-*.profile) INSTALL(FILES ${USERTYPE_POLICY_FILES} DESTINATION ${SHARE_INSTALL_PREFIX}/security-manager/policy) +INSTALL(FILES "app-rules-template.smack" DESTINATION ${SHARE_INSTALL_PREFIX}/security-manager/policy) INSTALL(PROGRAMS security-manager-policy-reload DESTINATION ${BIN_INSTALL_DIR}) diff --git a/app-rules-template.smack b/policy/app-rules-template.smack similarity index 100% rename from app-rules-template.smack rename to policy/app-rules-template.smack diff --git a/src/common/smack-rules.cpp b/src/common/smack-rules.cpp index ace23ba..221cf4d 100644 --- a/src/common/smack-rules.cpp +++ b/src/common/smack-rules.cpp @@ -44,7 +44,7 @@ namespace SecurityManager { const char *const SMACK_APP_LABEL_TEMPLATE = "~APP~"; const char *const SMACK_PKG_LABEL_TEMPLATE = "~PKG~"; -const char *const APP_RULES_TEMPLATE_FILE_PATH = tzplatform_mkpath(TZ_SYS_SMACK, "app-rules-template.smack"); +const char *const APP_RULES_TEMPLATE_FILE_PATH = tzplatform_mkpath4(TZ_SYS_SHARE, "security-manager", "policy", "app-rules-template.smack"); const char *const SMACK_APP_IN_PACKAGE_PERMS = "rwxat"; SmackRules::SmackRules() -- 2.7.4 From 294bf3a4a6f5379f590b8d63f0a00485b7a46f78 Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Fri, 6 Mar 2015 18:22:14 +0100 Subject: [PATCH 03/16] Provide support for loading privilege-group mapping A mapping file in policy/privilege-group.list will be contained in security-manager-policy package. All mappings from that file will be loaded during package installation by security-manager-policy-reload tool. For development purposes it is also possible to modify the mapping file on the image and re-run security-manager-policy-reload. Change-Id: I9a7d5b16888de98013da281978e299c5b19750ce Signed-off-by: Rafal Krypa --- db/db.sql | 14 +++++++++++--- policy/CMakeLists.txt | 1 + policy/privilege-group.list | 6 ++++++ policy/security-manager-policy-reload | 18 ++++++++++++++++-- src/common/include/privilege_db.h | 2 +- 5 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 policy/privilege-group.list diff --git a/db/db.sql b/db/db.sql index e9ca886..fd3e084 100644 --- a/db/db.sql +++ b/db/db.sql @@ -37,8 +37,8 @@ FOREIGN KEY (privilege_id) REFERENCES privilege (privilege_id) CREATE TABLE IF NOT EXISTS privilege_group ( privilege_id INTEGER NOT NULL, -name VARCHAR NOT NULL, -PRIMARY KEY (privilege_id, name), +group_name VARCHAR NOT NULL, +PRIMARY KEY (privilege_id, group_name), FOREIGN KEY (privilege_id) REFERENCES privilege (privilege_id) ); @@ -106,8 +106,16 @@ CREATE VIEW privilege_group_view AS SELECT privilege_id, privilege.name as privilege_name, - privilege_group.name + privilege_group.group_name FROM privilege_group LEFT JOIN privilege USING (privilege_id); +DROP TRIGGER IF EXISTS privilege_group_view_insert_trigger; +CREATE TRIGGER privilege_group_view_insert_trigger +INSTEAD OF INSERT ON privilege_group_view +BEGIN + INSERT OR IGNORE INTO privilege(name) VALUES (NEW.privilege_name); + INSERT OR IGNORE INTO privilege_group(privilege_id, group_name) VALUES ((SELECT privilege_id FROM privilege WHERE name=NEW.privilege_name), NEW.group_name); +END; + COMMIT TRANSACTION; diff --git a/policy/CMakeLists.txt b/policy/CMakeLists.txt index 32d6ee6..bd08edc 100644 --- a/policy/CMakeLists.txt +++ b/policy/CMakeLists.txt @@ -1,4 +1,5 @@ FILE(GLOB USERTYPE_POLICY_FILES usertype-*.profile) INSTALL(FILES ${USERTYPE_POLICY_FILES} DESTINATION ${SHARE_INSTALL_PREFIX}/security-manager/policy) INSTALL(FILES "app-rules-template.smack" DESTINATION ${SHARE_INSTALL_PREFIX}/security-manager/policy) +INSTALL(FILES "privilege-group.list" DESTINATION ${SHARE_INSTALL_PREFIX}/security-manager/policy) INSTALL(PROGRAMS security-manager-policy-reload DESTINATION ${BIN_INSTALL_DIR}) diff --git a/policy/privilege-group.list b/policy/privilege-group.list new file mode 100644 index 0000000..d679d0c --- /dev/null +++ b/policy/privilege-group.list @@ -0,0 +1,6 @@ +# Configuration of groups assignment to privileges. +# Run security-manager-policy-reload to apply. +# Format: +# - each line of " " describes single mapping +# - privilege and group separated by white spaces +# - lines starting with '#' are ignored diff --git a/policy/security-manager-policy-reload b/policy/security-manager-policy-reload index d15cec5..5a78f2d 100755 --- a/policy/security-manager-policy-reload +++ b/policy/security-manager-policy-reload @@ -1,6 +1,8 @@ #!/bin/sh -e -USERTYPE_POLICY_PATH=/usr/share/security-manager/policy +POLICY_PATH=/usr/share/security-manager/policy +PRIVILEGE_GROUP_MAPPING=$POLICY_PATH/privilege-group.list +DB_FILE=`tzplatform-get TZ_SYS_DB | cut -d= -f2`/.security-manager.db # Create default buckets while read bucket default_policy @@ -28,7 +30,7 @@ PRIVACY_MANAGER MAIN END # Import user-type policies -find "$USERTYPE_POLICY_PATH" -name "usertype-*.profile" | +find "$POLICY_PATH" -name "usertype-*.profile" | while read file do bucket="`echo $file | sed -r 's|.*/usertype-(.*).profile$|USER_TYPE_\U\1|'`" @@ -56,3 +58,15 @@ for client in User System do cyad --set-policy --bucket=MAIN --client="$client" --user="*" --privilege="*" --type=ALLOW done + +# Load privilege-group mappings +( +echo "BEGIN;" +echo "DELETE FROM privilege_group;" +grep -v '^#' "$PRIVILEGE_GROUP_MAPPING" | +while read privilege group +do + echo "INSERT INTO privilege_group_view (privilege_name, group_name) VALUES ('$privilege', '$group');" +done +echo "COMMIT;" +) | sqlite3 "$DB_FILE" diff --git a/src/common/include/privilege_db.h b/src/common/include/privilege_db.h index cf8bdcf..4d73d90 100644 --- a/src/common/include/privilege_db.h +++ b/src/common/include/privilege_db.h @@ -80,7 +80,7 @@ private: { QueryType::ERemoveAppPrivileges, "DELETE FROM app_privilege_view WHERE app_name=? AND uid=?" }, { QueryType::EPkgIdExists, "SELECT * FROM pkg WHERE name=?" }, { QueryType::EGetPkgId, " SELECT pkg_name FROM app_pkg_view WHERE app_name = ?" }, - { QueryType::EGetPrivilegeGroups, " SELECT name FROM privilege_group_view WHERE privilege_name = ?" }, + { QueryType::EGetPrivilegeGroups, " SELECT group_name FROM privilege_group_view WHERE privilege_name = ?" }, { QueryType::EGetUserApps, "SELECT name FROM app WHERE uid=?" }, { QueryType::EGetAppsInPkg, " SELECT app_name FROM app_pkg_view WHERE pkg_name = ?" }, }; -- 2.7.4 From 6d8a974977af77c467d94797c2838948028c868a Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Fri, 6 Mar 2015 18:52:20 +0100 Subject: [PATCH 04/16] Drop workaround for all applications labeled with "User" label Because every app used to have the same label, special fixes were needed for app uninstallation not to break Smack policy for "User" label. Now with final application labels this is no longer needed. Dropping the workaround. Change-Id: I83d3df1499f8c0eb21d2c954c2fcba3283938a5e Signed-off-by: Rafal Krypa --- src/common/smack-rules.cpp | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/src/common/smack-rules.cpp b/src/common/smack-rules.cpp index 221cf4d..3629e0f 100644 --- a/src/common/smack-rules.cpp +++ b/src/common/smack-rules.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -253,27 +252,6 @@ void SmackRules::updatePackageRules(const std::string &pkgId, const std::vector< smackRules.saveToFile(pkgPath); } -/* FIXME: Remove this function if real pkgId instead of "User" label will be used - * in generateAppLabel(). */ -void SmackRules::addMissingRulesFix() -{ - struct dirent *ent; - - std::string path(tzplatform_mkpath(TZ_SYS_SMACK, "accesses.d")); - std::unique_ptr> dir(opendir(path.c_str()), closedir); - if (!dir) - ThrowMsg(SmackException::FileError, "opendir"); - - while ((ent = readdir(dir.get()))) { - SmackRules rules; - if (ent->d_type == DT_REG) { - rules.loadFromFile(tzplatform_mkpath3(TZ_SYS_SMACK, "accesses.d/", ent->d_name)); - // Do not check error here. If this fails we can't do anything anyway. - } - rules.apply(); - } -} - void SmackRules::uninstallPackageRules(const std::string &pkgId) { uninstallRules(getPackageRulesFilePath(pkgId)); @@ -284,9 +262,6 @@ void SmackRules::uninstallApplicationRules(const std::string &appId, { uninstallRules(getApplicationRulesFilePath(appId)); updatePackageRules(pkgId, pkgContents); - - // FIXME: Reloading all rules: - SmackRules::addMissingRulesFix(); } void SmackRules::uninstallRules(const std::string &path) -- 2.7.4 From 4b0445821d3a9da3c0c6ae7aec308e80f2ac4b7c Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Tue, 10 Mar 2015 10:48:08 +0100 Subject: [PATCH 05/16] Fix grant all privileges to programs with "User" and "System" Smack labels Cynara rules for granting said policy was added to the wrong bucket. Another bucket, with default "Deny" policy was shadowing them. Adding the rules to the proper bucket now. Change-Id: Iec6b3bd093e89c8b3629994681871c94f797187b Signed-off-by: Rafal Krypa --- policy/security-manager-policy-reload | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/policy/security-manager-policy-reload b/policy/security-manager-policy-reload index 5a78f2d..274c49c 100755 --- a/policy/security-manager-policy-reload +++ b/policy/security-manager-policy-reload @@ -56,7 +56,7 @@ done # Non-application programs get access to all privileges for client in User System do - cyad --set-policy --bucket=MAIN --client="$client" --user="*" --privilege="*" --type=ALLOW + cyad --set-policy --bucket=MANIFESTS --client="$client" --user="*" --privilege="*" --type=ALLOW done # Load privilege-group mappings -- 2.7.4 From b913489d695e9aff2f7e930a7961b3b0c95af82c Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Fri, 6 Mar 2015 18:46:38 +0100 Subject: [PATCH 06/16] Release version 1.0.0 Change-Id: I11bb09f16e150b4a95f7385084f3f8c08ce94790 Signed-off-by: Rafal Krypa --- packaging/security-manager.changes | 33 +++++++++++++++++++++++++++++++++ packaging/security-manager.spec | 2 +- pc/security-manager.pc.in | 2 +- src/client/CMakeLists.txt | 4 ++-- src/common/CMakeLists.txt | 4 ++-- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/packaging/security-manager.changes b/packaging/security-manager.changes index 53a89dc..ff5d6d3 100644 --- a/packaging/security-manager.changes +++ b/packaging/security-manager.changes @@ -1,3 +1,36 @@ +* Fri Mar 06 2015 Rafal Krypa +- Version 1.0.0 +- User management + - Support for managing policy per user + - Interface for registering user creation and removal + - Hook-based Integration with gumd for user creation/removal events + - Initial user policy based on user type (guest, normal, admin) + - Initial configuration of user type policy granting all privileges to every + user type +- API for managing per-user policy + - Support for user-admin-like interface for tuning per-user policy by + administrator + - Support for privacy-manager-like interface for users limiting their own + applications +- Off-line mode supporting limited functionality when service is not running + - Application installation + - User creation +- Command line tool wrapping some of security-manager's APIs + - Registration of application installation and deinstallation with privileges + and application paths + - Registration of user creation/removal (for gumd integration mentioned above) +- Enhanced configuration of Cynara policy + - Structured policy based on several buckets + - Initial policy created on security-manager installation + - Programs with "User" and "System" labels get access to all privileges (with + regard to per-user policy) +- Easier setup of privilege-group mapping + - A config file with the mapping and command line tool for importing it to + security-manager +- Smack labeling for applications in final form + - No longer hard-code labels of all applications to "User" + - Each application gets unique Smack label based on appId + * Tue Sep 18 2014 Rafal Krypa - Version 0.2.0 - No longer use libprivilege-control diff --git a/packaging/security-manager.spec b/packaging/security-manager.spec index 1783fc4..7d88875 100644 --- a/packaging/security-manager.spec +++ b/packaging/security-manager.spec @@ -1,6 +1,6 @@ Name: security-manager Summary: Security manager and utilities -Version: 0.2.0 +Version: 1.0.0 Release: 1 Group: Security/Service License: Apache-2.0 diff --git a/pc/security-manager.pc.in b/pc/security-manager.pc.in index ec43046..b008725 100644 --- a/pc/security-manager.pc.in +++ b/pc/security-manager.pc.in @@ -5,7 +5,7 @@ includedir=${prefix}/include Name: security-manager Description: Security Manager Package -Version: 1.0.1 +Version: 1.0.0 Requires: Libs: -L${libdir} -lsecurity-manager-client Cflags: -I${includedir}/security-manager diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 4868c54..6f7b033 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -4,8 +4,8 @@ PKG_CHECK_MODULES(CLIENT_DEP libcap ) -SET(CLIENT_VERSION_MAJOR 0) -SET(CLIENT_VERSION ${CLIENT_VERSION_MAJOR}.2.0) +SET(CLIENT_VERSION_MAJOR 1) +SET(CLIENT_VERSION ${CLIENT_VERSION_MAJOR}.0.0) INCLUDE_DIRECTORIES(SYSTEM ${CLIENT_DEP_INCLUDE_DIRS} diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index aebe1bc..e1575e4 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,5 +1,5 @@ -SET(COMMON_VERSION_MAJOR 0) -SET(COMMON_VERSION ${COMMON_VERSION_MAJOR}.2.0) +SET(COMMON_VERSION_MAJOR 1) +SET(COMMON_VERSION ${COMMON_VERSION_MAJOR}.0.0) PKG_CHECK_MODULES(COMMON_DEP REQUIRED -- 2.7.4 From 11908993ce82db95bded5ddc69ec4fbf3f50bcd9 Mon Sep 17 00:00:00 2001 From: Jacek Bukarewicz Date: Wed, 11 Mar 2015 16:07:14 +0100 Subject: [PATCH 07/16] Remove references to non-existing security-manager.target Change-Id: I57a6d196be2d87b51d63c3226a40480e21e91e9f --- systemd/security-manager.socket | 4 ---- 1 file changed, 4 deletions(-) diff --git a/systemd/security-manager.socket b/systemd/security-manager.socket index c0590ad..af1c1da 100644 --- a/systemd/security-manager.socket +++ b/systemd/security-manager.socket @@ -7,9 +7,5 @@ SmackLabelIPOut=@ # TODO: move to separate systemd service Service=security-manager.service -[Unit] -Wants=security-manager.target -Before=security-manager.target - [Install] WantedBy=sockets.target -- 2.7.4 From b2a4f7b95986786b786660290fb82d02f6e828e6 Mon Sep 17 00:00:00 2001 From: Sebastian Grabowski Date: Tue, 16 Dec 2014 14:37:46 +0100 Subject: [PATCH 08/16] Removed timeout for poll. Security-server in many cases may need much more time than just 2s to accomplish given client request. It seems to be reasonable to just remove the timeout by changing it to be infinite. Change-Id: Iae8074b3bb5bfa134fd6dc324907ad3bba6f3b9b Signed-off-by: Sebastian Grabowski --- src/client/client-common.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/client-common.cpp b/src/client/client-common.cpp index dd5796a..883ab8d 100644 --- a/src/client/client-common.cpp +++ b/src/client/client-common.cpp @@ -45,7 +45,7 @@ IMPLEMENT_SAFE_SINGLETON(SecurityManager::Log::LogSystem); namespace { -const int POLL_TIMEOUT = 2000; +const int POLL_TIMEOUT = -1; void securityClientEnableLogSystem(void) { SecurityManager::Singleton::Instance().SetTag("SECURITY_MANAGER_CLIENT"); -- 2.7.4 From 728cc2d695bd61b80aeaba08b0f8e51818064774 Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Wed, 18 Mar 2015 11:27:47 +0100 Subject: [PATCH 09/16] security-manager-policy: add missing dependencies on required tools The policy loading script uses sqlite3 and tzplatform-get programs. The package should depend on them. Change-Id: I16d5b3b9d4914ba791a493305fbdf4a57c2f37a7 Signed-off-by: Rafal Krypa --- packaging/security-manager.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packaging/security-manager.spec b/packaging/security-manager.spec index 7d88875..92496b2 100644 --- a/packaging/security-manager.spec +++ b/packaging/security-manager.spec @@ -50,6 +50,8 @@ Summary: Security manager policy Group: Security/Access Control Requires(post): security-manager = %{version}-%{release} Requires(post): cyad +Requires(post): sqlite +Requires(post): tizen-platform-config-tools %description policy Set of security rules that constitute security policy in the system -- 2.7.4 From 275b5c0b5c495abd84da7779bef9354755446449 Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Thu, 19 Mar 2015 17:53:03 +0100 Subject: [PATCH 10/16] Fix advisory locking in client library Enhance off-line mode detection based on lock: - don't use exceptions for non-exceptional code paths - only attempt off-line mode if caller is root Also fix misleading logs informing about lock failures (that doesn't lead to actual security-mnanager failures) caused by lock attempt on a lock file without proper permissions. Change-Id: Ie7fca37154a1993cd46c59a0204837904593e5db Signed-off-by: Rafal Krypa --- src/client/client-offline.cpp | 9 ++++++++- src/common/file-lock.cpp | 41 ++++++++++++++++------------------------- 2 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/client/client-offline.cpp b/src/client/client-offline.cpp index f926d77..e442c2f 100644 --- a/src/client/client-offline.cpp +++ b/src/client/client-offline.cpp @@ -35,6 +35,12 @@ ClientOffline::ClientOffline() { offlineMode = false; serviceLock = nullptr; + + if (geteuid()) { + LogInfo("UID != 0, attempting only on-line mode."); + return; + } + try { serviceLock = new SecurityManager::FileLocker(SecurityManager::SERVICE_LOCK_FILE, false); if (serviceLock->Locked()) { @@ -53,7 +59,8 @@ ClientOffline::ClientOffline() LogInfo("Service seems to be running now."); } } catch (...) { - /* Ignore exceptions, assume on-line */ + LogError("Cannot detect off-line mode by lock."); + offlineMode = false; } if (offlineMode) diff --git a/src/common/file-lock.cpp b/src/common/file-lock.cpp index 36b2ccb..6f3996c 100644 --- a/src/common/file-lock.cpp +++ b/src/common/file-lock.cpp @@ -41,18 +41,11 @@ FileLocker::FileLocker(const std::string &lockFile, bool blocking) ThrowMsg(FileLocker::Exception::LockFailed, "File name can not be empty."); } - try { - m_locked = false; - m_blocking = blocking; - m_lockFile = lockFile; - Lock(); - } catch (FileLocker::Exception::Base &e) { - LogError("Failed to lock " << lockFile << " file: " - << e.DumpToString()); - ThrowMsg(FileLocker::Exception::LockFailed, - "Failed to lock " << lockFile << " file: " - << e.DumpToString()); - } + + m_locked = false; + m_blocking = blocking; + m_lockFile = lockFile; + Lock(); } FileLocker::~FileLocker() @@ -69,9 +62,11 @@ void FileLocker::Lock() { if (m_locked) return; + try { - if (!std::ifstream(m_lockFile).good()) - std::ofstream(m_lockFile.c_str()); + std::ofstream tmpf(m_lockFile); + tmpf.close(); + m_flock = boost::interprocess::file_lock(m_lockFile.c_str()); if (m_blocking) { m_flock.lock(); @@ -79,19 +74,15 @@ void FileLocker::Lock() } else m_locked = m_flock.try_lock(); } catch (const std::exception &e) { - ThrowMsg(FileLocker::Exception::LockFailed, - "Error while locking a file."); + LogError("Error while locking a file: " << e.what()); + ThrowMsg(FileLocker::Exception::LockFailed, + "Error while locking a file: " << e.what()); } - if (m_locked) { + + if (m_locked) LogDebug("We have a lock on " << m_lockFile << " file."); - } else { - if (m_blocking) { - ThrowMsg(FileLocker::Exception::LockFailed, - "Unable to lock file."); - } else { - LogDebug("Impossible to lock a file now."); - } - } + else + LogDebug("Impossible to lock a file now."); } void FileLocker::Unlock() -- 2.7.4 From 6eb825a3876061b2e152d42974e117dcbedf7c70 Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Fri, 20 Mar 2015 16:19:44 +0100 Subject: [PATCH 11/16] Release version 1.0.1 Change-Id: Ied8852ec3ed3e8dc3ea3457a99ee4a9822349f55 --- packaging/security-manager.changes | 4 ++++ packaging/security-manager.spec | 2 +- pc/security-manager.pc.in | 2 +- src/client/CMakeLists.txt | 2 +- src/common/CMakeLists.txt | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packaging/security-manager.changes b/packaging/security-manager.changes index ff5d6d3..1c02c3a 100644 --- a/packaging/security-manager.changes +++ b/packaging/security-manager.changes @@ -1,3 +1,7 @@ +* Fri Mar 20 2015 Rafal Krypa +- Version 1.0.1 +- Bug-fix release, no new features. + * Fri Mar 06 2015 Rafal Krypa - Version 1.0.0 - User management diff --git a/packaging/security-manager.spec b/packaging/security-manager.spec index 92496b2..1ebced1 100644 --- a/packaging/security-manager.spec +++ b/packaging/security-manager.spec @@ -1,6 +1,6 @@ Name: security-manager Summary: Security manager and utilities -Version: 1.0.0 +Version: 1.0.1 Release: 1 Group: Security/Service License: Apache-2.0 diff --git a/pc/security-manager.pc.in b/pc/security-manager.pc.in index b008725..ec43046 100644 --- a/pc/security-manager.pc.in +++ b/pc/security-manager.pc.in @@ -5,7 +5,7 @@ includedir=${prefix}/include Name: security-manager Description: Security Manager Package -Version: 1.0.0 +Version: 1.0.1 Requires: Libs: -L${libdir} -lsecurity-manager-client Cflags: -I${includedir}/security-manager diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 6f7b033..66a33ab 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -5,7 +5,7 @@ PKG_CHECK_MODULES(CLIENT_DEP ) SET(CLIENT_VERSION_MAJOR 1) -SET(CLIENT_VERSION ${CLIENT_VERSION_MAJOR}.0.0) +SET(CLIENT_VERSION ${CLIENT_VERSION_MAJOR}.0.1) INCLUDE_DIRECTORIES(SYSTEM ${CLIENT_DEP_INCLUDE_DIRS} diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index e1575e4..cbcea64 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,5 +1,5 @@ SET(COMMON_VERSION_MAJOR 1) -SET(COMMON_VERSION ${COMMON_VERSION_MAJOR}.0.0) +SET(COMMON_VERSION ${COMMON_VERSION_MAJOR}.0.1) PKG_CHECK_MODULES(COMMON_DEP REQUIRED -- 2.7.4 From 5462f5e2da37bef5519d63511f0dd08f155c1f0b Mon Sep 17 00:00:00 2001 From: Stephane Desneux Date: Wed, 25 Mar 2015 11:27:38 +0100 Subject: [PATCH 12/16] Raise socket inactivity timeout to 300s This is a quick workaround to installation problems on slow targets. Bug-Tizen: TC-2483 Change-Id: I6515438e7fdc02ba6c6de6efba32cfcaaa030f7f Signed-off-by: Stephane Desneux --- src/server/main/socket-manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server/main/socket-manager.cpp b/src/server/main/socket-manager.cpp index d917a68..94c54c6 100644 --- a/src/server/main/socket-manager.cpp +++ b/src/server/main/socket-manager.cpp @@ -48,7 +48,7 @@ namespace { -const time_t SOCKET_TIMEOUT = 20; +const time_t SOCKET_TIMEOUT = 300; } // namespace anonymous -- 2.7.4 From beb6b6fcae57dc62f0c01831dd1510e8ad9dfecd Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Wed, 25 Mar 2015 11:50:36 +0100 Subject: [PATCH 13/16] Don't call Cynara if there are no policies to set Change-Id: I3a25cbc0cdbf5ee4cb82890fbd40ea4e51b8a08d --- src/common/cynara.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/common/cynara.cpp b/src/common/cynara.cpp index 6d19977..29b06bc 100644 --- a/src/common/cynara.cpp +++ b/src/common/cynara.cpp @@ -249,6 +249,11 @@ CynaraAdmin &CynaraAdmin::getInstance() void CynaraAdmin::SetPolicies(const std::vector &policies) { + if (policies.empty()) { + LogDebug("no policies to set in Cynara."); + return; + } + std::vector pp_policies(policies.size() + 1); LogDebug("Sending " << policies.size() << " policies to Cynara"); -- 2.7.4 From 860305a595d681d650024ad07b3b0977e1fcb0a6 Mon Sep 17 00:00:00 2001 From: Jacek Bukarewicz Date: Wed, 25 Mar 2015 11:44:33 +0100 Subject: [PATCH 14/16] Release version 1.0.2 Change-Id: Ia46e9cf268fe0a7302066ee014e5d44c393fb587 --- packaging/security-manager.changes | 4 ++++ packaging/security-manager.spec | 2 +- pc/security-manager.pc.in | 2 +- src/client/CMakeLists.txt | 2 +- src/common/CMakeLists.txt | 2 +- 5 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packaging/security-manager.changes b/packaging/security-manager.changes index 1c02c3a..2bc5c15 100644 --- a/packaging/security-manager.changes +++ b/packaging/security-manager.changes @@ -1,3 +1,7 @@ +* Wed Mar 25 2015 Jacek Bukarewicz +- Version 1.0.2 +- Work around application installation problems on slow targets + * Fri Mar 20 2015 Rafal Krypa - Version 1.0.1 - Bug-fix release, no new features. diff --git a/packaging/security-manager.spec b/packaging/security-manager.spec index 1ebced1..5269334 100644 --- a/packaging/security-manager.spec +++ b/packaging/security-manager.spec @@ -1,6 +1,6 @@ Name: security-manager Summary: Security manager and utilities -Version: 1.0.1 +Version: 1.0.2 Release: 1 Group: Security/Service License: Apache-2.0 diff --git a/pc/security-manager.pc.in b/pc/security-manager.pc.in index ec43046..c2916c5 100644 --- a/pc/security-manager.pc.in +++ b/pc/security-manager.pc.in @@ -5,7 +5,7 @@ includedir=${prefix}/include Name: security-manager Description: Security Manager Package -Version: 1.0.1 +Version: 1.0.2 Requires: Libs: -L${libdir} -lsecurity-manager-client Cflags: -I${includedir}/security-manager diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 66a33ab..5399a55 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -5,7 +5,7 @@ PKG_CHECK_MODULES(CLIENT_DEP ) SET(CLIENT_VERSION_MAJOR 1) -SET(CLIENT_VERSION ${CLIENT_VERSION_MAJOR}.0.1) +SET(CLIENT_VERSION ${CLIENT_VERSION_MAJOR}.0.2) INCLUDE_DIRECTORIES(SYSTEM ${CLIENT_DEP_INCLUDE_DIRS} diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index cbcea64..2da9c3e 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,5 +1,5 @@ SET(COMMON_VERSION_MAJOR 1) -SET(COMMON_VERSION ${COMMON_VERSION_MAJOR}.0.1) +SET(COMMON_VERSION ${COMMON_VERSION_MAJOR}.0.2) PKG_CHECK_MODULES(COMMON_DEP REQUIRED -- 2.7.4 From d5559a8207f79896129d734911f385d2d08ac024 Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Fri, 6 Feb 2015 18:25:11 +0100 Subject: [PATCH 15/16] Prepare security-manager for master-slave mode This commit prepares security-manager for work in master/slave mode. In order to properly install/uninstall applications inside containers, security-manager inside container (slave) must delegate calls related to SMACK to security-manager outside a container (master). Since entire master/slave mode is a huge change, it is divided into two commits - this is the first one. Logic for master service and changes in service to work as slave are left for second commit. With this change security-manager launched without additional arguments should work as it did. Change-Id: If05cdeb2d2c35c046bf4cb46d884a3689dab57ad --- packaging/security-manager.spec | 6 ++ src/common/include/protocols.h | 2 + src/common/include/service_impl.h | 11 +++ src/common/protocols.cpp | 4 + src/common/service_impl.cpp | 15 ++++ src/server/CMakeLists.txt | 4 +- src/server/main/server-main.cpp | 86 ++++++++++++++++++--- src/server/service/include/master-service.h | 61 +++++++++++++++ src/server/service/include/service.h | 4 +- src/server/service/master-service.cpp | 111 ++++++++++++++++++++++++++++ src/server/service/service.cpp | 26 +++++-- systemd/CMakeLists.txt | 6 ++ systemd/security-manager-master.service.in | 10 +++ systemd/security-manager-master.socket | 13 ++++ systemd/security-manager-slave.service.in | 9 +++ systemd/security-manager-slave.socket | 10 +++ systemd/security-manager.service.in | 2 + systemd/security-manager.socket | 4 + 18 files changed, 363 insertions(+), 21 deletions(-) create mode 100644 src/server/service/include/master-service.h create mode 100644 src/server/service/master-service.cpp create mode 100644 systemd/security-manager-master.service.in create mode 100644 systemd/security-manager-master.socket create mode 100644 systemd/security-manager-slave.service.in create mode 100644 systemd/security-manager-slave.socket diff --git a/packaging/security-manager.spec b/packaging/security-manager.spec index 5269334..d6d259b 100644 --- a/packaging/security-manager.spec +++ b/packaging/security-manager.spec @@ -87,6 +87,8 @@ cp LICENSE %{buildroot}%{_datadir}/license/libsecurity-manager-client mkdir -p %{buildroot}/%{_unitdir}/sockets.target.wants ln -s ../security-manager.socket %{buildroot}/%{_unitdir}/sockets.target.wants/security-manager.socket +ln -s ../security-manager-master.socket %{buildroot}/%{_unitdir}/sockets.target.wants/security-manager-master.socket +ln -s ../security-manager-slave.socket %{buildroot}/%{_unitdir}/sockets.target.wants/security-manager-slave.socket %clean rm -rf %{buildroot} @@ -136,7 +138,11 @@ fi %{_libdir}/libsecurity-manager-commons.so.* %attr(-,root,root) %{_unitdir}/security-manager.* +%attr(-,root,root) %{_unitdir}/security-manager-master.* +%attr(-,root,root) %{_unitdir}/security-manager-slave.* %attr(-,root,root) %{_unitdir}/sockets.target.wants/security-manager.* +%attr(-,root,root) %{_unitdir}/sockets.target.wants/security-manager-master.* +%attr(-,root,root) %{_unitdir}/sockets.target.wants/security-manager-slave.* %config(noreplace) %attr(0600,root,root) %{TZ_SYS_DB}/.security-manager.db %config(noreplace) %attr(0600,root,root) %{TZ_SYS_DB}/.security-manager.db-journal %{_datadir}/license/%{name} diff --git a/src/common/include/protocols.h b/src/common/include/protocols.h index 9f3b11b..8360a26 100644 --- a/src/common/include/protocols.h +++ b/src/common/include/protocols.h @@ -120,6 +120,8 @@ struct user_req { namespace SecurityManager { extern char const * const SERVICE_SOCKET; +extern char const * const MASTER_SERVICE_SOCKET; +extern char const * const SLAVE_SERVICE_SOCKET; enum class SecurityModuleCall { diff --git a/src/common/include/service_impl.h b/src/common/include/service_impl.h index 827496a..fa999b6 100644 --- a/src/common/include/service_impl.h +++ b/src/common/include/service_impl.h @@ -35,6 +35,17 @@ namespace SecurityManager { namespace ServiceImpl { /** + * Retrieves ID (UID and PID) of peer connected to socket + * + * @param[in] Socket file descriptor + * @param[out] UID of connected peer. Function does not modify the variable if ID retrieval fails. + * @param[out] PID of connected peer. Function does not modify the variable if ID retrieval fails. + * + * @return True if peer ID was successfully retrieved, false otherwise. + */ +bool getPeerID(int sock, uid_t &uid, pid_t &pid); + +/** * Process application installation request. * * @param[in] req installation request diff --git a/src/common/protocols.cpp b/src/common/protocols.cpp index 798b9d6..eac619a 100644 --- a/src/common/protocols.cpp +++ b/src/common/protocols.cpp @@ -32,6 +32,10 @@ namespace SecurityManager { char const * const SERVICE_SOCKET = SOCKET_PATH_PREFIX "security-manager.socket"; +char const * const MASTER_SERVICE_SOCKET = + SOCKET_PATH_PREFIX "security-manager-master.socket"; +char const * const SLAVE_SERVICE_SOCKET = + SOCKET_PATH_PREFIX "security-manager-slave.socket"; } // namespace SecurityManager diff --git a/src/common/service_impl.cpp b/src/common/service_impl.cpp index 7fd621c..20ee7a9 100644 --- a/src/common/service_impl.cpp +++ b/src/common/service_impl.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -159,6 +160,20 @@ static inline bool isSubDir(const char *parent, const char *subdir) return (*subdir == '/'); } +bool getPeerID(int sock, uid_t &uid, pid_t &pid) +{ + struct ucred cr; + socklen_t len = sizeof(cr); + + if (!getsockopt(sock, SOL_SOCKET, SO_PEERCRED, &cr, &len)) { + uid = cr.uid; + pid = cr.pid; + return true; + } + + return false; +} + static bool getUserAppDir(const uid_t &uid, std::string &userAppDir) { struct tzplatform_context *tz_ctx = nullptr; diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 753eb96..8890aa3 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -3,7 +3,7 @@ PKG_CHECK_MODULES(SERVER_DEP libsystemd-daemon ) -FIND_PACKAGE(Boost REQUIRED) +FIND_PACKAGE(Boost REQUIRED COMPONENTS program_options) FIND_PACKAGE(Threads REQUIRED) INCLUDE_DIRECTORIES(SYSTEM @@ -27,6 +27,7 @@ SET(SERVER_SOURCES ${SERVER_PATH}/main/server-main.cpp ${SERVER_PATH}/service/base-service.cpp ${SERVER_PATH}/service/service.cpp + ${SERVER_PATH}/service/master-service.cpp ) ADD_EXECUTABLE(${TARGET_SERVER} ${SERVER_SOURCES}) @@ -39,6 +40,7 @@ TARGET_LINK_LIBRARIES(${TARGET_SERVER} ${TARGET_COMMON} ${CMAKE_THREAD_LIBS_INIT} ${SERVER_DEP_LIBRARIES} + ${Boost_LIBRARIES} ) INSTALL(TARGETS ${TARGET_SERVER} DESTINATION ${BIN_INSTALL_DIR}) diff --git a/src/server/main/server-main.cpp b/src/server/main/server-main.cpp index c9609e2..f8e1f71 100644 --- a/src/server/main/server-main.cpp +++ b/src/server/main/server-main.cpp @@ -28,22 +28,30 @@ #include #include +#include +#include + #include #include #include +#include + +namespace po = boost::program_options; IMPLEMENT_SAFE_SINGLETON(SecurityManager::Log::LogSystem); -#define REGISTER_SOCKET_SERVICE(manager, service) \ - registerSocketService(manager, #service) +#define REGISTER_SOCKET_SERVICE(manager, service, allocator) \ + registerSocketService(manager, #service, allocator) template -bool registerSocketService(SecurityManager::SocketManager &manager, const std::string& serviceName) +bool registerSocketService(SecurityManager::SocketManager &manager, + const std::string& serviceName, + const std::function& serviceAllocator) { T *service = NULL; try { - service = new T(); + service = serviceAllocator(); service->Create(); manager.RegisterSocketService(service); return true; @@ -62,12 +70,59 @@ bool registerSocketService(SecurityManager::SocketManager &manager, const std::s return false; } -int main(void) { - +int main(int argc, char* argv[]) +{ UNHANDLED_EXCEPTION_HANDLER_BEGIN { + // initialize logging SecurityManager::Singleton::Instance().SetTag("SECURITY_MANAGER"); + // parse arguments + bool masterMode = false, slaveMode = false; + po::options_description optDesc("Allowed options"); + + optDesc.add_options() + ("help,h", "Print this help message") + ("master,m", "Enable master mode") + ("slave,s", "Enable slave mode") + ; + + po::variables_map vm; + po::basic_parsed_options parsed = + po::command_line_parser(argc, argv).options(optDesc).allow_unregistered().run(); + + std::vector unrecognizedOptions = + po::collect_unrecognized(parsed.options, po::include_positional); + + if (!unrecognizedOptions.empty()) { + std::cerr << "Unrecognized options: "; + + for (auto& uo : unrecognizedOptions) { + std::cerr << ' ' << uo; + } + + std::cerr << std::endl << std::endl; + std::cerr << optDesc << std::endl; + + return EXIT_FAILURE; + } + + po::store(parsed, vm); + po::notify(vm); + + if (vm.count("help")) { + std::cout << optDesc << std::endl; + return EXIT_SUCCESS; + } + + masterMode = vm.count("master") > 0; + slaveMode = vm.count("slave") > 0; + + if (masterMode && slaveMode) { + LogError("Cannot be both master and slave!"); + return EXIT_FAILURE; + } + SecurityManager::FileLocker serviceLock(SecurityManager::SERVICE_LOCK_FILE, true); @@ -77,15 +132,24 @@ int main(void) { sigaddset(&mask, SIGPIPE); if (-1 == pthread_sigmask(SIG_BLOCK, &mask, NULL)) { LogError("Error in pthread_sigmask"); - return 1; + return EXIT_FAILURE; } LogInfo("Start!"); SecurityManager::SocketManager manager; - if (!REGISTER_SOCKET_SERVICE(manager, SecurityManager::Service)) { - LogError("Unable to create socket service. Exiting."); - return EXIT_FAILURE; + if (masterMode) { + if (!REGISTER_SOCKET_SERVICE(manager, SecurityManager::MasterService, + []() { return new SecurityManager::MasterService(); } )) { + LogError("Unable to create master socket service. Exiting."); + return EXIT_FAILURE; + } + } else { + if (!REGISTER_SOCKET_SERVICE(manager, SecurityManager::Service, + [&slaveMode]() { return new SecurityManager::Service(slaveMode); } )) { + LogError("Unable to create socket service. Exiting."); + return EXIT_FAILURE; + } } manager.MainLoop(); @@ -94,5 +158,5 @@ int main(void) { return EXIT_FAILURE; } UNHANDLED_EXCEPTION_HANDLER_END - return 0; + return EXIT_SUCCESS; } diff --git a/src/server/service/include/master-service.h b/src/server/service/include/master-service.h new file mode 100644 index 0000000..170bfd9 --- /dev/null +++ b/src/server/service/include/master-service.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Rafal Krypa + * + * 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 master-service.h + * @author Lukasz Kostyra + * @author Rafal Krypa + * @brief Implementation of security-manager master service + */ + +#ifndef _SECURITY_MANAGER_MASTER_SERVICE_ +#define _SECURITY_MANAGER_MASTER_SERVICE_ + +#include "base-service.h" + +namespace SecurityManager { + +class MasterServiceException +{ +public: + DECLARE_EXCEPTION_TYPE(SecurityManager::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, InvalidAction) +}; + +class MasterService : + public SecurityManager::BaseService +{ +public: + MasterService(); + ServiceDescriptionVector GetServiceDescription(); + +private: + + /** + * Handle request from a client + * + * @param conn Socket connection information + * @param buffer Raw received data buffer + * @param interfaceID identifier used to distinguish source socket + * @return true on success + */ + bool processOne(const ConnectionID &conn, MessageBuffer &buffer, InterfaceID interfaceID); +}; + +} // namespace SecurityManager + +#endif // _SECURITY_MANAGER_MASTER_SERVICE_ diff --git a/src/server/service/include/service.h b/src/server/service/include/service.h index 883c989..765d0d0 100644 --- a/src/server/service/include/service.h +++ b/src/server/service/include/service.h @@ -40,10 +40,12 @@ class Service : public SecurityManager::BaseService { public: - Service(); + Service(const bool isSlave); ServiceDescriptionVector GetServiceDescription(); private: + const bool m_isSlave; + /** * Handle request from a client * diff --git a/src/server/service/master-service.cpp b/src/server/service/master-service.cpp new file mode 100644 index 0000000..2afae00 --- /dev/null +++ b/src/server/service/master-service.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Rafal Krypa + * + * 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 master-service.cpp + * @author Lukasz Kostyra + * @author Rafal Krypa + * @brief Implementation of security-manager master service. + */ + +#include + +#include +#include + +#include "protocols.h" +#include "master-service.h" +#include "service_impl.h" + +namespace SecurityManager { + +const InterfaceID IFACE = 1; + +MasterService::MasterService() +{ +} + +GenericSocketService::ServiceDescriptionVector MasterService::GetServiceDescription() +{ + return ServiceDescriptionVector { + {MASTER_SERVICE_SOCKET, "security-manager-master", IFACE}, + }; +} + +bool MasterService::processOne(const ConnectionID &conn, MessageBuffer &buffer, + InterfaceID interfaceID) +{ + LogDebug("Iteration begin. Interface = " << interfaceID); + + //waiting for all data + if (!buffer.Ready()) { + return false; + } + + MessageBuffer send; + bool retval = false; + + uid_t uid; + pid_t pid; + + if (!ServiceImpl::getPeerID(conn.sock, uid, pid)) { + LogError("Closing socket because of error: unable to get peer's uid and pid"); + m_serviceManager->Close(conn); + return false; + } + + if (IFACE == interfaceID) { + Try { + // deserialize API call type + int call_type_int; + Deserialization::Deserialize(buffer, call_type_int); + SecurityModuleCall call_type = static_cast(call_type_int); + + switch (call_type) { + default: + LogError("Invalid call: " << call_type_int); + Throw(MasterServiceException::InvalidAction); + } + // if we reach this point, the protocol is OK + retval = true; + } Catch (MessageBuffer::Exception::Base) { + LogError("Broken protocol."); + } Catch (MasterServiceException::Base) { + LogError("Broken protocol."); + } catch (const std::exception &e) { + LogError("STD exception " << e.what()); + } catch (...) { + LogError("Unknown exception"); + } + } + else { + LogError("Wrong interface"); + } + + if (retval) { + //send response + m_serviceManager->Write(conn, send.Pop()); + } else { + LogError("Closing socket because of error"); + m_serviceManager->Close(conn); + } + + return retval; +} + + +} // namespace SecurityManager diff --git a/src/server/service/service.cpp b/src/server/service/service.cpp index e0925b1..522356f 100644 --- a/src/server/service/service.cpp +++ b/src/server/service/service.cpp @@ -37,19 +37,29 @@ namespace SecurityManager { const InterfaceID IFACE = 1; -Service::Service() +Service::Service(const bool isSlave): + m_isSlave(isSlave) { } GenericSocketService::ServiceDescriptionVector Service::GetServiceDescription() { - return ServiceDescriptionVector { - {SERVICE_SOCKET, /* path */ - "*", /* smackLabel label (not used, we rely on systemd) */ - IFACE, /* InterfaceID */ - false, /* useSendMsg */ - true}, /* systemdOnly */ - }; + if (m_isSlave) + return ServiceDescriptionVector { + {SLAVE_SERVICE_SOCKET, /* path */ + "*", /* smackLabel label (not used, we rely on systemd) */ + IFACE, /* InterfaceID */ + false, /* useSendMsg */ + true}, /* systemdOnly */ + }; + else + return ServiceDescriptionVector { + {SERVICE_SOCKET, /* path */ + "*", /* smackLabel label (not used, we rely on systemd) */ + IFACE, /* InterfaceID */ + false, /* useSendMsg */ + true}, /* systemdOnly */ + }; } static bool getPeerID(int sock, uid_t &uid, pid_t &pid, std::string &smackLabel) diff --git a/systemd/CMakeLists.txt b/systemd/CMakeLists.txt index 90c0ec1..02814a5 100644 --- a/systemd/CMakeLists.txt +++ b/systemd/CMakeLists.txt @@ -1,8 +1,14 @@ CONFIGURE_FILE(security-manager.service.in security-manager.service @ONLY) +CONFIGURE_FILE(security-manager-master.service.in security-manager-master.service @ONLY) +CONFIGURE_FILE(security-manager-slave.service.in security-manager-slave.service @ONLY) INSTALL(FILES security-manager.service security-manager.socket + security-manager-master.service + security-manager-master.socket + security-manager-slave.service + security-manager-slave.socket DESTINATION ${SYSTEMD_INSTALL_DIR} ) diff --git a/systemd/security-manager-master.service.in b/systemd/security-manager-master.service.in new file mode 100644 index 0000000..ef14a57 --- /dev/null +++ b/systemd/security-manager-master.service.in @@ -0,0 +1,10 @@ +[Unit] +Description=Start the security manager master +ConditionVirtualization=!lxc +ConditionPathExists=/usr/share/.zones/enabled + +[Service] +Type=notify +ExecStart=@BIN_INSTALL_DIR@/security-manager --master + +Sockets=security-manager-master.socket diff --git a/systemd/security-manager-master.socket b/systemd/security-manager-master.socket new file mode 100644 index 0000000..d41eae0 --- /dev/null +++ b/systemd/security-manager-master.socket @@ -0,0 +1,13 @@ +[Socket] +ListenStream=/run/security-manager-master.socket +SocketMode=0700 +SmackLabelIPIn=System +SmackLabelIPOut=System +Service=security-manager-master.service + +[Unit] +ConditionVirtualization=!lxc +ConditionPathExists=/usr/share/.zones/enabled + +[Install] +WantedBy=sockets.target diff --git a/systemd/security-manager-slave.service.in b/systemd/security-manager-slave.service.in new file mode 100644 index 0000000..6eb7505 --- /dev/null +++ b/systemd/security-manager-slave.service.in @@ -0,0 +1,9 @@ +[Unit] +Description=Start the security manager slave +ConditionVirtualization=lxc + +[Service] +Type=notify +ExecStart=@BIN_INSTALL_DIR@/security-manager --slave + +Sockets=security-manager-slave.socket diff --git a/systemd/security-manager-slave.socket b/systemd/security-manager-slave.socket new file mode 100644 index 0000000..8d0a2c6 --- /dev/null +++ b/systemd/security-manager-slave.socket @@ -0,0 +1,10 @@ +[Socket] +ListenStream=/run/security-manager-slave.socket +Symlinks=/run/security-manager.socket +SocketMode=0777 +SmackLabelIPIn=* +SmackLabelIPOut=@ +Service=security-manager-slave.service + +[Unit] +ConditionVirtualization=lxc diff --git a/systemd/security-manager.service.in b/systemd/security-manager.service.in index 23fd1b2..f15ab90 100644 --- a/systemd/security-manager.service.in +++ b/systemd/security-manager.service.in @@ -1,5 +1,7 @@ [Unit] Description=Start the security manager +ConditionVirtualization=!lxc +ConditionPathExists=!/usr/share/.zones/enabled [Service] Type=notify diff --git a/systemd/security-manager.socket b/systemd/security-manager.socket index af1c1da..95411e8 100644 --- a/systemd/security-manager.socket +++ b/systemd/security-manager.socket @@ -7,5 +7,9 @@ SmackLabelIPOut=@ # TODO: move to separate systemd service Service=security-manager.service +[Unit] +ConditionVirtualization=!lxc +ConditionPathExists=!/usr/share/.zones/enabled + [Install] WantedBy=sockets.target -- 2.7.4 From 9703e341cc614b519a3a57d9356c6e8d3ca2cc1a Mon Sep 17 00:00:00 2001 From: Lukasz Kostyra Date: Mon, 17 Nov 2014 12:48:55 +0100 Subject: [PATCH 16/16] Extract communication functions to common library Since slave service will use the same functions as client library to send data, these are extracted in this commit and will be used in the next change. [Verification] Build, install, run tests. Change-Id: I4b9e11015c657066657f493e87d68958283bb947 --- src/client/client-common.cpp | 211 -------------------------- src/client/client-offline.cpp | 3 +- src/client/client-security-manager.cpp | 2 + src/client/include/client-common.h | 21 --- src/common/CMakeLists.txt | 1 + src/common/connection.cpp | 261 +++++++++++++++++++++++++++++++++ src/common/include/connection.h | 57 +++++++ src/server/service/service.cpp | 1 + 8 files changed, 324 insertions(+), 233 deletions(-) create mode 100644 src/common/connection.cpp create mode 100644 src/common/include/connection.h diff --git a/src/client/client-common.cpp b/src/client/client-common.cpp index 883ab8d..3051cbc 100644 --- a/src/client/client-common.cpp +++ b/src/client/client-common.cpp @@ -45,225 +45,14 @@ IMPLEMENT_SAFE_SINGLETON(SecurityManager::Log::LogSystem); namespace { -const int POLL_TIMEOUT = -1; - void securityClientEnableLogSystem(void) { SecurityManager::Singleton::Instance().SetTag("SECURITY_MANAGER_CLIENT"); } -int waitForSocket(int sock, int event, int timeout) { - int retval; - pollfd desc[1]; - desc[0].fd = sock; - desc[0].events = event; - - while((-1 == (retval = poll(desc, 1, timeout))) && (errno == EINTR)) { - timeout >>= 1; - errno = 0; - } - - if (0 == retval) { - LogDebug("Poll timeout"); - } else if (-1 == retval) { - int err = errno; - LogError("Error in poll: " << strerror(err)); - } - return retval; -} - -class SockRAII { -public: - SockRAII() - : m_sock(-1) - {} - - virtual ~SockRAII() { - if (m_sock > -1) - close(m_sock); - } - - int Connect(char const * const interface) { - sockaddr_un clientAddr; - int flags; - - if (m_sock != -1) // guard - close(m_sock); - - m_sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (m_sock < 0) { - int err = errno; - LogError("Error creating socket: " << strerror(err)); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - - if ((flags = fcntl(m_sock, F_GETFL, 0)) < 0 || - fcntl(m_sock, F_SETFL, flags | O_NONBLOCK) < 0) - { - int err = errno; - LogError("Error in fcntl: " << strerror(err)); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - - memset(&clientAddr, 0, sizeof(clientAddr)); - - clientAddr.sun_family = AF_UNIX; - - if (strlen(interface) >= sizeof(clientAddr.sun_path)) { - LogError("Error: interface name " << interface << "is too long. Max len is:" << sizeof(clientAddr.sun_path)); - return SECURITY_MANAGER_API_ERROR_NO_SUCH_SERVICE; - } - - strcpy(clientAddr.sun_path, interface); - - LogDebug("ClientAddr.sun_path = " << interface); - - int retval = TEMP_FAILURE_RETRY(connect(m_sock, (struct sockaddr*)&clientAddr, SUN_LEN(&clientAddr))); - if ((retval == -1) && (errno == EINPROGRESS)) { - if (0 >= waitForSocket(m_sock, POLLOUT, POLL_TIMEOUT)) { - LogError("Error in waitForSocket."); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - int error = 0; - socklen_t len = sizeof(error); - retval = getsockopt(m_sock, SOL_SOCKET, SO_ERROR, &error, &len); - - if (-1 == retval) { - int err = errno; - LogError("Error in getsockopt: " << strerror(err)); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - - if (error == EACCES) { - LogError("Access denied"); - return SECURITY_MANAGER_API_ERROR_ACCESS_DENIED; - } - - if (error != 0) { - LogError("Error in connect: " << strerror(error)); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - - return SECURITY_MANAGER_API_SUCCESS; - } - - if (-1 == retval) { - int err = errno; - LogError("Error connecting socket: " << strerror(err)); - if (err == EACCES) - return SECURITY_MANAGER_API_ERROR_ACCESS_DENIED; - if (err == ENOTSOCK) - return SECURITY_MANAGER_API_ERROR_NO_SUCH_SERVICE; - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - - return SECURITY_MANAGER_API_SUCCESS; - } - - int Get() { - return m_sock; - } - -private: - int m_sock; -}; - } // namespace anonymous namespace SecurityManager { -int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv) { - int ret; - SockRAII sock; - ssize_t done = 0; - char buffer[2048]; - - if (SECURITY_MANAGER_API_SUCCESS != (ret = sock.Connect(interface))) { - LogError("Error in SockRAII"); - return ret; - } - - while ((send.size() - done) > 0) { - if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) { - LogError("Error in poll(POLLOUT)"); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done)); - if (-1 == temp) { - int err = errno; - LogError("Error in write: " << strerror(err)); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - done += temp; - } - - do { - if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) { - LogError("Error in poll(POLLIN)"); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - ssize_t temp = TEMP_FAILURE_RETRY(read(sock.Get(), buffer, 2048)); - if (-1 == temp) { - int err = errno; - LogError("Error in read: " << strerror(err)); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - - if (0 == temp) { - LogError("Read return 0/Connection closed by server(?)"); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - - RawBuffer raw(buffer, buffer+temp); - recv.Push(raw); - } while(!recv.Ready()); - return SECURITY_MANAGER_API_SUCCESS; -} - -int sendToServerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr) { - int ret; - SockRAII sock; - ssize_t done = 0; - - if (SECURITY_MANAGER_API_SUCCESS != (ret = sock.Connect(interface))) { - LogError("Error in SockRAII"); - return ret; - } - - while ((send.size() - done) > 0) { - if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) { - LogError("Error in poll(POLLOUT)"); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done)); - if (-1 == temp) { - int err = errno; - LogError("Error in write: " << strerror(err)); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - done += temp; - } - - if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) { - LogError("Error in poll(POLLIN)"); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - - ssize_t temp = TEMP_FAILURE_RETRY(recvmsg(sock.Get(), &hdr, MSG_CMSG_CLOEXEC)); - - if (temp < 0) { - int err = errno; - LogError("Error in recvmsg(): " << strerror(err) << " errno: " << err); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - - if (0 == temp) { - LogError("Read return 0/Connection closed by server(?)"); - return SECURITY_MANAGER_API_ERROR_SOCKET; - } - - return SECURITY_MANAGER_API_SUCCESS; -} - int try_catch(const std::function& func) { try { diff --git a/src/client/client-offline.cpp b/src/client/client-offline.cpp index e442c2f..d60911d 100644 --- a/src/client/client-offline.cpp +++ b/src/client/client-offline.cpp @@ -22,12 +22,13 @@ * @brief Helper class for client "off-line" mode detection */ +#include #include #include #include +#include #include #include -#include "client-offline.h" namespace SecurityManager { diff --git a/src/client/client-security-manager.cpp b/src/client/client-security-manager.cpp index 74a6b30..4d6fecb 100644 --- a/src/client/client-security-manager.cpp +++ b/src/client/client-security-manager.cpp @@ -44,6 +44,8 @@ #include #include #include +#include + #include #include diff --git a/src/client/include/client-common.h b/src/client/include/client-common.h index c7d18a4..b82f6a5 100644 --- a/src/client/include/client-common.h +++ b/src/client/include/client-common.h @@ -26,34 +26,13 @@ #ifndef _SECURITY_MANAGER_CLIENT_ #define _SECURITY_MANAGER_CLIENT_ -#include #include -#include - #define SECURITY_MANAGER_API __attribute__((visibility("default"))) #define SECURITY_MANAGER_UNUSED __attribute__((unused)) -extern "C" { - struct msghdr; -} - namespace SecurityManager { -typedef std::vector RawBuffer; - -int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv); - -/* - * sendToServerAncData is special case when we want to receive file descriptor - * passed by Security Manager on behalf of calling process. We can't get it with - * MessageBuffer. - * - * This function should be called _ONLY_ in this particular case. - * - */ -int sendToManagerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr); - /* * Decorator function that performs frequently repeated exception handling in * SS client API functions. Accepts lambda expression as an argument. diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 2da9c3e..6571e64 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -41,6 +41,7 @@ SET(COMMON_SOURCES ${DPL_PATH}/core/src/string.cpp ${DPL_PATH}/db/src/naive_synchronization_object.cpp ${DPL_PATH}/db/src/sql_connection.cpp + ${COMMON_PATH}/connection.cpp ${COMMON_PATH}/cynara.cpp ${COMMON_PATH}/file-lock.cpp ${COMMON_PATH}/protocols.cpp diff --git a/src/common/connection.cpp b/src/common/connection.cpp new file mode 100644 index 0000000..e4dc9ee --- /dev/null +++ b/src/common/connection.cpp @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Rafal Krypa + * + * 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 connection.cpp + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @author Lukasz Kostyra (l.kostyra@samsung.com) + * @version 1.0 + * @brief This file is implementation of common connection functions. + */ + +#include "connection.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +namespace { + +const int POLL_TIMEOUT = -1; + +int waitForSocket(int sock, int event, int timeout) { + int retval; + pollfd desc[1]; + desc[0].fd = sock; + desc[0].events = event; + + while((-1 == (retval = poll(desc, 1, timeout))) && (errno == EINTR)) { + timeout >>= 1; + errno = 0; + } + + if (0 == retval) { + LogDebug("Poll timeout"); + } else if (-1 == retval) { + int err = errno; + LogError("Error in poll: " << strerror(err)); + } + return retval; +} + +class SockRAII { +public: + SockRAII() + : m_sock(-1) + {} + + virtual ~SockRAII() { + if (m_sock > -1) + close(m_sock); + } + + int Connect(char const * const interface) { + sockaddr_un clientAddr; + int flags; + + if (m_sock != -1) // guard + close(m_sock); + + m_sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (m_sock < 0) { + int err = errno; + LogError("Error creating socket: " << strerror(err)); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + + if ((flags = fcntl(m_sock, F_GETFL, 0)) < 0 || + fcntl(m_sock, F_SETFL, flags | O_NONBLOCK) < 0) + { + int err = errno; + LogError("Error in fcntl: " << strerror(err)); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + + memset(&clientAddr, 0, sizeof(clientAddr)); + + clientAddr.sun_family = AF_UNIX; + + if (strlen(interface) >= sizeof(clientAddr.sun_path)) { + LogError("Error: interface name " << interface << "is too long. Max len is:" << sizeof(clientAddr.sun_path)); + return SECURITY_MANAGER_API_ERROR_NO_SUCH_SERVICE; + } + + strcpy(clientAddr.sun_path, interface); + + LogDebug("ClientAddr.sun_path = " << interface); + + int retval = TEMP_FAILURE_RETRY(connect(m_sock, (struct sockaddr*)&clientAddr, SUN_LEN(&clientAddr))); + if ((retval == -1) && (errno == EINPROGRESS)) { + if (0 >= waitForSocket(m_sock, POLLIN, POLL_TIMEOUT)) { + LogError("Error in waitForSocket."); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + int error = 0; + socklen_t len = sizeof(error); + retval = getsockopt(m_sock, SOL_SOCKET, SO_ERROR, &error, &len); + + if (-1 == retval) { + int err = errno; + LogError("Error in getsockopt: " << strerror(err)); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + + if (error == EACCES) { + LogError("Access denied"); + return SECURITY_MANAGER_API_ERROR_ACCESS_DENIED; + } + + if (error != 0) { + LogError("Error in connect: " << strerror(error)); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + + return SECURITY_MANAGER_API_SUCCESS; + } + + if (-1 == retval) { + int err = errno; + LogError("Error connecting socket: " << strerror(err)); + if (err == EACCES) + return SECURITY_MANAGER_API_ERROR_ACCESS_DENIED; + if (err == ENOTSOCK) + return SECURITY_MANAGER_API_ERROR_NO_SUCH_SERVICE; + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + + return SECURITY_MANAGER_API_SUCCESS; + } + + int Get() { + return m_sock; + } + +private: + int m_sock; +}; + +} // namespace anonymous + +namespace SecurityManager { + +int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv) { + int ret; + SockRAII sock; + ssize_t done = 0; + char buffer[2048]; + + if (SECURITY_MANAGER_API_SUCCESS != (ret = sock.Connect(interface))) { + LogError("Error in SockRAII"); + return ret; + } + + while ((send.size() - done) > 0) { + if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) { + LogError("Error in poll(POLLOUT)"); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done)); + if (-1 == temp) { + int err = errno; + LogError("Error in write: " << strerror(err)); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + done += temp; + } + + do { + if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) { + LogError("Error in poll(POLLIN)"); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + ssize_t temp = TEMP_FAILURE_RETRY(read(sock.Get(), buffer, 2048)); + if (-1 == temp) { + int err = errno; + LogError("Error in read: " << strerror(err)); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + + if (0 == temp) { + LogError("Read return 0/Connection closed by server(?)"); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + + RawBuffer raw(buffer, buffer+temp); + recv.Push(raw); + } while(!recv.Ready()); + return SECURITY_MANAGER_API_SUCCESS; +} + +int sendToServerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr) { + int ret; + SockRAII sock; + ssize_t done = 0; + + if (SECURITY_MANAGER_API_SUCCESS != (ret = sock.Connect(interface))) { + LogError("Error in SockRAII"); + return ret; + } + + while ((send.size() - done) > 0) { + if (0 >= waitForSocket(sock.Get(), POLLOUT, POLL_TIMEOUT)) { + LogError("Error in poll(POLLOUT)"); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + ssize_t temp = TEMP_FAILURE_RETRY(write(sock.Get(), &send[done], send.size() - done)); + if (-1 == temp) { + int err = errno; + LogError("Error in write: " << strerror(err)); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + done += temp; + } + + if (0 >= waitForSocket(sock.Get(), POLLIN, POLL_TIMEOUT)) { + LogError("Error in poll(POLLIN)"); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + + ssize_t temp = TEMP_FAILURE_RETRY(recvmsg(sock.Get(), &hdr, MSG_CMSG_CLOEXEC)); + + if (temp < 0) { + int err = errno; + LogError("Error in recvmsg(): " << strerror(err) << " errno: " << err); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + + if (0 == temp) { + LogError("Read return 0/Connection closed by server(?)"); + return SECURITY_MANAGER_API_ERROR_SOCKET; + } + + return SECURITY_MANAGER_API_SUCCESS; +} + +} // namespace SecurityManager diff --git a/src/common/include/connection.h b/src/common/include/connection.h new file mode 100644 index 0000000..77967c4 --- /dev/null +++ b/src/common/include/connection.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved + * + * Contact: Rafal Krypa + * + * 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 sock-raii.h + * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) + * @author Lukasz Kostyra (l.kostyra@samsung.com) + * @version 1.0 + * @brief This file constains declarations of connection-related functions + * used in security manager. + */ + +#ifndef _SECURITY_MANAGER_CONNECTION_ +#define _SECURITY_MANAGER_CONNECTION_ + +#include +#include + +#include + +extern "C" { + struct msghdr; +} + +namespace SecurityManager { + +typedef std::vector RawBuffer; + +int sendToServer(char const * const interface, const RawBuffer &send, MessageBuffer &recv); + +/* + * sendToServerAncData is special case when we want to receive file descriptor + * passed by Security Manager on behalf of calling process. We can't get it with + * MessageBuffer. + * + * This function should be called _ONLY_ in this particular case. + * + */ +int sendToManagerAncData(char const * const interface, const RawBuffer &send, struct msghdr &hdr); + +} // namespace SecurityManager + +#endif // _SECURITY_MANAGER_CONNECTION_ diff --git a/src/server/service/service.cpp b/src/server/service/service.cpp index 522356f..334ce19 100644 --- a/src/server/service/service.cpp +++ b/src/server/service/service.cpp @@ -29,6 +29,7 @@ #include #include +#include "connection.h" #include "protocols.h" #include "service.h" #include "service_impl.h" -- 2.7.4