From d672a29bd604d58f63bc0be98cd927b45834c41f Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Wed, 4 Feb 2015 17:58:14 +0100 Subject: [PATCH] Before running client in off-line mode, attempt to socket-activate the server Security-manager is started by systemd on socket-activation basis. This means that it won't start unless a client connects to its socket. But client library attempts to detect off-line mode by checking whether the service is already running. This leads to erroneous off-line runs when in fact a message should be sent over socket to activate the service. This change adds one more step to off-line mode detection. When the service isn't running, client will send a special NOOP message over socket. If systemd manages to activate security-manager service, normal on-line operation is then performed. Change-Id: I94b1b10af24e3b90d048fe1b96b8d870da785d8b Signed-off-by: Rafal Krypa --- src/client/client-offline.cpp | 20 +++++++++++++++++++- src/common/file-lock.cpp | 1 + src/common/include/file-lock.h | 2 -- src/common/include/protocols.h | 1 + src/server/service/service.cpp | 4 ++++ 5 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/client/client-offline.cpp b/src/client/client-offline.cpp index 115051a..f926d77 100644 --- a/src/client/client-offline.cpp +++ b/src/client/client-offline.cpp @@ -22,6 +22,10 @@ * @brief Helper class for client "off-line" mode detection */ +#include +#include +#include +#include #include #include "client-offline.h" @@ -33,7 +37,21 @@ ClientOffline::ClientOffline() serviceLock = nullptr; try { serviceLock = new SecurityManager::FileLocker(SecurityManager::SERVICE_LOCK_FILE, false); - offlineMode = serviceLock->Locked(); + if (serviceLock->Locked()) { + int retval; + MessageBuffer send, recv; + + LogInfo("Service isn't running, try to trigger it via socket activation."); + serviceLock->Unlock(); + Serialization::Serialize(send, static_cast(SecurityModuleCall::NOOP)); + retval = sendToServer(SERVICE_SOCKET, send.Pop(), recv); + if (retval != SECURITY_MANAGER_API_SUCCESS) { + LogInfo("Socket activation attempt failed."); + serviceLock->Lock(); + offlineMode = serviceLock->Locked(); + } else + LogInfo("Service seems to be running now."); + } } catch (...) { /* Ignore exceptions, assume on-line */ } diff --git a/src/common/file-lock.cpp b/src/common/file-lock.cpp index 1b9b0b8..36b2ccb 100644 --- a/src/common/file-lock.cpp +++ b/src/common/file-lock.cpp @@ -98,6 +98,7 @@ void FileLocker::Unlock() { if (m_locked) { m_flock.unlock(); + m_locked = false; LogDebug("Lock released."); } } diff --git a/src/common/include/file-lock.h b/src/common/include/file-lock.h index 620d757..604b019 100644 --- a/src/common/include/file-lock.h +++ b/src/common/include/file-lock.h @@ -50,8 +50,6 @@ public: ~FileLocker(); bool Locked(); - -protected: void Lock(); void Unlock(); diff --git a/src/common/include/protocols.h b/src/common/include/protocols.h index 907a41a..20902ba 100644 --- a/src/common/include/protocols.h +++ b/src/common/include/protocols.h @@ -131,6 +131,7 @@ enum class SecurityModuleCall GET_POLICY, GET_CONF_POLICY_ADMIN, GET_CONF_POLICY_SELF, + NOOP = 0x90, }; } // namespace SecurityManager diff --git a/src/server/service/service.cpp b/src/server/service/service.cpp index 7f75bed..ca0bf52 100644 --- a/src/server/service/service.cpp +++ b/src/server/service/service.cpp @@ -94,6 +94,10 @@ bool Service::processOne(const ConnectionID &conn, MessageBuffer &buffer, SecurityModuleCall call_type = static_cast(call_type_int); switch (call_type) { + case SecurityModuleCall::NOOP: + LogDebug("call_type: SecurityModuleCall::NOOP"); + Serialization::Serialize(send, SECURITY_MANAGER_API_SUCCESS); + break; case SecurityModuleCall::APP_INSTALL: LogDebug("call_type: SecurityModuleCall::APP_INSTALL"); processAppInstall(buffer, send, uid); -- 2.7.4