diff options
author | Konrad Lipinski <k.lipinski2@samsung.com> | 2022-07-20 13:57:14 +0200 |
---|---|---|
committer | Konrad Lipinski <k.lipinski2@samsung.com> | 2022-07-22 15:35:51 +0200 |
commit | 6971fdaa527bfc3ba86ad77ebb5c7c7c2ab47848 (patch) | |
tree | 1e0eea1ca4d7eb9473c3fafaf0a5ac1363cb36ed | |
parent | 91d0ff9814354ec5ba65db8a36c5af0ff3c796e2 (diff) | |
download | security-manager-6971fdaa527bfc3ba86ad77ebb5c7c7c2ab47848.tar.gz security-manager-6971fdaa527bfc3ba86ad77ebb5c7c7c2ab47848.tar.bz2 security-manager-6971fdaa527bfc3ba86ad77ebb5c7c7c2ab47848.zip |
Simplify service and IO thread's class hierarchies
* get rid of useless Generic* and Base* classes that do nothing
* shift what little functionality they provided to other entities
* make a few leaf classes final
* devirtualize a few methods across the hierarchy, either by making them
local or via CRTP
* replace the virtual Event hierarchy and handlers by a single
statically known Event type
Change-Id: Id3afef98ff99a5b0eb3966f1cfdf0dcaa52cd909
-rw-r--r-- | README | 8 | ||||
-rw-r--r-- | src/common/include/service_impl.h | 5 | ||||
-rw-r--r-- | src/common/service_impl.cpp | 4 | ||||
-rw-r--r-- | src/server/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/server/main/include/generic-event.h | 43 | ||||
-rw-r--r-- | src/server/main/include/generic-socket-manager.h | 97 | ||||
-rw-r--r-- | src/server/main/include/service-thread.h | 108 | ||||
-rw-r--r-- | src/server/main/include/socket-manager.h | 39 | ||||
-rw-r--r-- | src/server/main/server-main.cpp | 10 | ||||
-rw-r--r-- | src/server/main/service-thread.cpp | 101 | ||||
-rw-r--r-- | src/server/main/socket-manager.cpp | 30 | ||||
-rw-r--r-- | src/server/service/base-service.cpp | 65 | ||||
-rw-r--r-- | src/server/service/include/base-service.h | 74 | ||||
-rw-r--r-- | src/server/service/include/service.h | 48 | ||||
-rw-r--r-- | src/server/service/service.cpp | 143 |
15 files changed, 202 insertions, 575 deletions
@@ -8,12 +8,12 @@ it inherits its main design: division for two parts: The implementation of daemon part is divided into: manager part: that is responsible for threads and communication management with no awareness of what information is being transferred. This part is - implemented by SocketManager class that works with GenericSocketService as + implemented by SocketManager class that works with Service as a generalization for services that security-server provides. and - services part: implemented as classes derived from GenericSocketService - grouped in src/server/service directory that defines actions done by - security-manager after receiving certain requests from client side. + services part: implemented as classes grouped in src/server/service + directory that defines actions done by security-manager after receiving + certain requests from client side. The security-manager's manager part is fully inherited from security-server, while services are completely diffrent. diff --git a/src/common/include/service_impl.h b/src/common/include/service_impl.h index 468a54db..808692df 100644 --- a/src/common/include/service_impl.h +++ b/src/common/include/service_impl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2014-2022 Samsung Electronics Co., Ltd. All rights reserved. * * This file is licensed under the terms of MIT License or the Apache License * Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details. @@ -67,11 +67,10 @@ struct UninstallHelper { UninstallHelper(); }; -class ServiceImpl { +class ServiceImpl final { public: using Offline = PrivilegeDb::Offline; explicit ServiceImpl(Offline offline); - virtual ~ServiceImpl(); /** * Process application installation request. diff --git a/src/common/service_impl.cpp b/src/common/service_impl.cpp index 1de360fe..35518847 100644 --- a/src/common/service_impl.cpp +++ b/src/common/service_impl.cpp @@ -188,10 +188,6 @@ ServiceImpl::ServiceImpl(Offline offline) : } } -ServiceImpl::~ServiceImpl() -{ -} - int ServiceImpl::validatePolicy(const Credentials &creds, policy_entry &policyEntry, CynaraAdminPolicy &cyap) { LogDebug("Authenticating and validating policy update request for user with id: " << creds.uid); diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 7b2350da..e19f8eec 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -47,8 +47,6 @@ INCLUDE_DIRECTORIES( SET(SERVER_SOURCES ${SERVER_PATH}/main/socket-manager.cpp ${SERVER_PATH}/main/server-main.cpp - ${SERVER_PATH}/main/service-thread.cpp - ${SERVER_PATH}/service/base-service.cpp ${SERVER_PATH}/service/service.cpp ) diff --git a/src/server/main/include/generic-event.h b/src/server/main/include/generic-event.h deleted file mode 100644 index 462db473..00000000 --- a/src/server/main/include/generic-event.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved. - * - * This file is licensed under the terms of MIT License or the Apache License - * Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details. - * See the LICENSE file or the notice below for Apache License Version 2.0 - * details. - * - * 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 generic-event.h - * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) - * @version 1.0 - * @brief Implementation of GenericEvent. - */ - -#pragma once - -namespace SecurityManager { - -struct GenericEvent { - GenericEvent() = default; - GenericEvent(const GenericEvent &) = delete; - GenericEvent(GenericEvent &&) = default; - - GenericEvent &operator=(const GenericEvent &) = delete; - GenericEvent &operator=(GenericEvent &&) = default; - virtual ~GenericEvent(){} -}; - -} // namespace SecurityManager diff --git a/src/server/main/include/generic-socket-manager.h b/src/server/main/include/generic-socket-manager.h deleted file mode 100644 index e1b4b6c6..00000000 --- a/src/server/main/include/generic-socket-manager.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2014-2022 Samsung Electronics Co., Ltd. All rights reserved. - * - * This file is licensed under the terms of MIT License or the Apache License - * Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details. - * See the LICENSE file or the notice below for Apache License Version 2.0 - * details. - * - * 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 generic-socket-manager.h - * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com) - * @version 1.0 - * @brief Implementation of GenericSocketService and GenericSocketManager. - */ - -#pragma once - -#include <string> - -#include <dpl/exception.h> - -#include <credentials.h> -#include <generic-event.h> -#include <message-buffer.h> - -namespace SecurityManager { - -struct ConnectionID { - int sock; // Socket file descriptor number. - unsigned counter; // Unique counter per that descriptor number. -}; - -struct GenericSocketManager; - -struct GenericSocketService { - typedef std::string SmackLabel; - typedef std::string ServiceHandlerPath; - struct ServiceDescription { - ServiceDescription(const char *path, - const char *smackLabel) - : smackLabel(smackLabel) - , serviceHandlerPath(path) - {} - - SmackLabel smackLabel; // Smack label for socket - ServiceHandlerPath serviceHandlerPath; // Path to file - }; - - struct MessageEvent : public GenericEvent { - MessageEvent(ConnectionID connection, Credentials &&crd, MessageBuffer &&messageBuffer) - : connectionID(connection) - , creds(std::move(crd)) - , messageBuffer(std::move(messageBuffer)) - {} - ConnectionID connectionID; - Credentials creds; - MessageBuffer messageBuffer; - }; - - virtual void SetSocketManager(GenericSocketManager *manager) { - m_serviceManager = manager; - } - - virtual const ServiceDescription &GetServiceDescription() const = 0; - virtual void Event(MessageEvent &&event) = 0; - - virtual void Start() {}; - virtual void Stop() {}; - - GenericSocketService() : m_serviceManager(NULL) {} - virtual ~GenericSocketService(){} -protected: - GenericSocketManager *m_serviceManager; -}; - -struct GenericSocketManager { - virtual void MainLoop() = 0; - virtual void RegisterSocketService(GenericSocketService *ptr) = 0; - virtual void Close(ConnectionID connectionID) = 0; - virtual void Write(ConnectionID connectionID, MessageBuffer &&messageBuffer) = 0; - virtual ~GenericSocketManager(){} -}; - -} // namespace SecurityManager diff --git a/src/server/main/include/service-thread.h b/src/server/main/include/service-thread.h index dccd94d1..82d319bf 100644 --- a/src/server/main/include/service-thread.h +++ b/src/server/main/include/service-thread.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2014-2022 Samsung Electronics Co., Ltd. All rights reserved. * * This file is licensed under the terms of MIT License or the Apache License * Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details. @@ -28,66 +28,76 @@ #pragma once -#include <queue> +#include <cassert> +#include <condition_variable> +#include <dpl/exception.h> #include <mutex> +#include <queue> #include <thread> -#include <condition_variable> - -#include "generic-event.h" - -#define DECLARE_THREAD_EVENT(eventType, methodName) \ - void Event(eventType &&event) { \ - using This = std::decay_t<decltype(*this)>; \ - ::SecurityManager::ServiceThread::EventMake( \ - &::SecurityManager::ServiceThread::EventCall< \ - This, decltype(&This::methodName), &This::methodName, eventType>, \ - new eventType(std::move(event))); \ - } namespace SecurityManager { +template <class DerivedService, class Event> class ServiceThread { -public: - enum class State : bool { - NoThread, - Work, - }; - - ServiceThread(); - - void StartThread(); - void FinishThread(); - - virtual ~ServiceThread(); - -private: - - struct EventDescription; - typedef void (ServiceThread::*EventFunctionPtr)(EventDescription &event); - - struct EventDescription { - EventFunctionPtr eventFunctionPtr; - GenericEvent* eventPtr; - }; - - void ThreadLoop(); - std::thread m_thread; std::mutex m_eventQueueMutex; - std::queue<EventDescription> m_eventQueue; + std::queue<Event *> m_eventQueue; std::condition_variable m_waitCondition; - State m_state; - bool m_quit; - -protected: + bool m_quit = false; +public: + ServiceThread() : m_thread([&]{ this->ThreadLoop(); }) {} + + ~ServiceThread() { + { + std::lock_guard<std::mutex> lock(m_eventQueueMutex); + m_quit = true; + } + m_waitCondition.notify_one(); + m_thread.join(); + + // clear the event queue + while (!m_eventQueue.empty()) { + delete m_eventQueue.front(); + m_eventQueue.pop(); + } + } - void EventMake(EventFunctionPtr eventFunctionPtr, GenericEvent *eventPtr); + template <class...T> + void PutEvent(T&&...arg) { + const auto event = new Event{ std::forward<T>(arg)... }; + { + std::lock_guard<std::mutex> lock(m_eventQueueMutex); + m_eventQueue.emplace(event); + } + m_waitCondition.notify_one(); + } - template <class Service, class ServiceMemFunPtr, ServiceMemFunPtr FN, class T> - void EventCall(EventDescription &desc) { - T& eventLocale = *(static_cast<T*>(desc.eventPtr)); - (static_cast<Service*>(this)->*FN)(std::move(eventLocale)); +private: + void ThreadLoop() { + for (;;) { + Event *event; + { + std::unique_lock<std::mutex> ulock(m_eventQueueMutex); + for (;;) { + if (m_quit) + return; + if (!m_eventQueue.empty()) { + event = m_eventQueue.front(); + m_eventQueue.pop(); + break; + } + m_waitCondition.wait(ulock); + } + } + + UNHANDLED_EXCEPTION_HANDLER_BEGIN + { + const auto eventGuard = makeUnique(event); + static_cast<DerivedService*>(this)->processEvent(std::move(*event)); + } + UNHANDLED_EXCEPTION_HANDLER_END + } } }; diff --git a/src/server/main/include/socket-manager.h b/src/server/main/include/socket-manager.h index 7c9a7907..f5683de2 100644 --- a/src/server/main/include/socket-manager.h +++ b/src/server/main/include/socket-manager.h @@ -36,32 +36,39 @@ #include <dpl/exception.h> -#include <generic-socket-manager.h> - namespace SecurityManager { -class SocketManager : public GenericSocketManager { +class Service; + +class SocketManager final { public: + struct ServiceDescription { + std::string serviceHandlerPath; // Path to file + std::string smackLabel; // Smack label for socket + }; + + struct ConnectionID { + int sock; // Socket file descriptor number. + unsigned counter; // Unique counter per that descriptor number. + }; + class Exception { public: DECLARE_EXCEPTION_TYPE(SecurityManager::Exception, Base) DECLARE_EXCEPTION_TYPE(Base, InitFailed) }; SocketManager(); - virtual ~SocketManager(); - virtual void MainLoop(); + ~SocketManager(); + void MainLoop(); - virtual void RegisterSocketService(GenericSocketService *service); - virtual void Close(ConnectionID connectionID); - virtual void Write(ConnectionID connectionID, MessageBuffer &&messageBuffer); + void RegisterSocketService(Service &service); + void Close(ConnectionID connectionID); + void Write(ConnectionID connectionID, MessageBuffer &&messageBuffer); -protected: - void CreateDomainSocket( - const GenericSocketService::ServiceDescription &desc); - int CreateDomainSocketHelp( - const GenericSocketService::ServiceDescription &desc); - int GetSocketFromSystemD( - const GenericSocketService::ServiceDescription &desc); +private: + void CreateDomainSocket(const ServiceDescription &desc); + int CreateDomainSocketHelp(const ServiceDescription &desc); + int GetSocketFromSystemD(const ServiceDescription &desc); void ReadyForRead(int sock); void ReadyForWrite(int sock); @@ -99,7 +106,7 @@ protected: }; SocketDescriptionVector m_socketDescriptionVector; - GenericSocketService *m_service = nullptr; + Service *m_service = nullptr; fd_set m_readSet; fd_set m_writeSet; int m_maxDesc = 0; diff --git a/src/server/main/server-main.cpp b/src/server/main/server-main.cpp index 432fa3b8..e6a37e14 100644 --- a/src/server/main/server-main.cpp +++ b/src/server/main/server-main.cpp @@ -49,12 +49,11 @@ T* registerSocketService(SecurityManager::SocketManager &manager, const std::string& serviceName, Channel channel) { - T *service = NULL; + T *service = nullptr; try { service = new T(T::Offline::no); service->RegisterChannel(std::move(channel)); - service->Start(); - manager.RegisterSocketService(service); + manager.RegisterSocketService(*service); return service; } catch (const SecurityManager::Exception &exception) { LogError("Error in creating service " << serviceName << @@ -66,10 +65,7 @@ T* registerSocketService(SecurityManager::SocketManager &manager, LogError("Error in creating service " << serviceName << ", unknown exception occured"); } - if (service) { - service->Stop(); - delete service; - } + delete service; return nullptr; } diff --git a/src/server/main/service-thread.cpp b/src/server/main/service-thread.cpp deleted file mode 100644 index 176fd648..00000000 --- a/src/server/main/service-thread.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2020-2022 Samsung Electronics Co., Ltd. All rights reserved. - * - * This file is licensed under the terms of MIT License or the Apache License - * Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details. - * See the LICENSE file or the notice below for Apache License Version 2.0 - * details. - * - * 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. - */ - -#include <cassert> - -#include <dpl/exception.h> - -#include <service-thread.h> - -namespace SecurityManager { - -ServiceThread::ServiceThread() - : m_state(State::NoThread) - , m_quit(false) -{} - -void ServiceThread::StartThread() { - assert(m_state == State::NoThread); - m_thread = std::thread([](auto ptr) { ptr->ThreadLoop(); }, this); - m_state = State::Work; -} - -void ServiceThread::FinishThread() { - // finish the thread if necessary - if (m_state != State::NoThread) { - { - std::lock_guard<std::mutex> lock(m_eventQueueMutex); - m_quit = true; - m_waitCondition.notify_one(); - } - m_thread.join(); - m_state = State::NoThread; - } - - // clear the event queue - while (!m_eventQueue.empty()) { - auto front = m_eventQueue.front(); - delete front.eventPtr; - m_eventQueue.pop(); - } -} - -ServiceThread::~ServiceThread() { - // FinishThread() has to be called before destructor - assert(m_state == State::NoThread); -} - -void ServiceThread::ThreadLoop() { - for (;;) { - EventDescription description; - { - std::unique_lock<std::mutex> ulock(m_eventQueueMutex); - for (;;) { - if (m_quit) - return; - if (!m_eventQueue.empty()) { - description = m_eventQueue.front(); - m_eventQueue.pop(); - break; - } - m_waitCondition.wait(ulock); - } - } - - UNHANDLED_EXCEPTION_HANDLER_BEGIN - { - (this->*description.eventFunctionPtr)(description); - delete description.eventPtr; - } - UNHANDLED_EXCEPTION_HANDLER_END - } -} - -void ServiceThread::EventMake(EventFunctionPtr eventFunctionPtr, GenericEvent *eventPtr) { - EventDescription description = { eventFunctionPtr, eventPtr }; - { - std::lock_guard<std::mutex> lock(m_eventQueueMutex); - m_eventQueue.push(description); - } - m_waitCondition.notify_one(); -} - -} // namespace SecurityManager diff --git a/src/server/main/socket-manager.cpp b/src/server/main/socket-manager.cpp index 7950dc45..08f89cb2 100644 --- a/src/server/main/socket-manager.cpp +++ b/src/server/main/socket-manager.cpp @@ -49,6 +49,7 @@ #include <dpl/errno_string.h> #include <credentials.h> +#include <service.h> #include <smack-check.h> #include <socket-manager.h> #include <utils.h> @@ -116,10 +117,7 @@ SocketManager::SocketManager() } SocketManager::~SocketManager() { - if (m_service) { - m_service->Stop(); - delete m_service; - } + delete m_service; for (size_t i = 0; i < m_socketDescriptionVector.size(); ++i) if (m_socketDescriptionVector[i].isOpen) @@ -199,10 +197,9 @@ void SocketManager::ReadyForRead(int sock) { case MessageBuffer::InputResult::Done: buffer.ModeStreaming(); FD_CLR(sock, &m_readSet); // the one and only call on this socket is complete - m_service->Event( - GenericSocketService::MessageEvent(ConnectionID{sock, desc.counter}, - Credentials::getCredentialsFromSocket(sock), - std::move(buffer))); + m_service->PutEvent(ConnectionID{sock, desc.counter}, + Credentials::getCredentialsFromSocket(sock), + std::move(buffer)); break; } } @@ -364,8 +361,7 @@ void SocketManager::MainLoop() { } } -int SocketManager::GetSocketFromSystemD( - const GenericSocketService::ServiceDescription &desc) +int SocketManager::GetSocketFromSystemD(const ServiceDescription &desc) { int fd; @@ -393,8 +389,7 @@ int SocketManager::GetSocketFromSystemD( return -1; } -int SocketManager::CreateDomainSocketHelp( - const GenericSocketService::ServiceDescription &desc) +int SocketManager::CreateDomainSocketHelp(const ServiceDescription &desc) { int sockfd; @@ -461,8 +456,7 @@ int SocketManager::CreateDomainSocketHelp( return sockfd; } -void SocketManager::CreateDomainSocket( - const GenericSocketService::ServiceDescription &desc) +void SocketManager::CreateDomainSocket(const ServiceDescription &desc) { int sockfd = GetSocketFromSystemD(desc); if (-1 == sockfd) @@ -475,10 +469,10 @@ void SocketManager::CreateDomainSocket( " Handler: " << desc.serviceHandlerPath.c_str()); } -void SocketManager::RegisterSocketService(GenericSocketService *service) { - service->SetSocketManager(this); - CreateDomainSocket(service->GetServiceDescription()); - m_service = service; +void SocketManager::RegisterSocketService(Service &service) { + service.SetSocketManager(this); + CreateDomainSocket(Service::DESCRIPTION); + m_service = &service; } void SocketManager::Close(ConnectionID connectionID) { diff --git a/src/server/service/base-service.cpp b/src/server/service/base-service.cpp deleted file mode 100644 index 7fa17527..00000000 --- a/src/server/service/base-service.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2014-2022 Samsung Electronics Co., Ltd. All rights reserved. - * - * This file is licensed under the terms of MIT License or the Apache License - * Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details. - * See the LICENSE file or the notice below for Apache License Version 2.0 - * details. - * - * 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 base-service.cpp - * @author Lukasz Kostyra <l.kostyra@samsung.com> - * @author Rafal Krypa <r.krypa@samsung.com> - * @brief Implementation of security-manager base service. - */ - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/smack.h> - -#include <cstring> -#include <unordered_set> - -#include <dpl/log/log.h> - -#include "base-service.h" - -namespace SecurityManager { - -BaseService::BaseService(Offline offline) - : serviceImpl(offline) -{ -} - -void BaseService::process(MessageEvent &&event) -{ - LogDebug("Message event for socket " << event.connectionID.sock << - " counter " << event.connectionID.counter); - - processOne(event.connectionID, event.creds, event.messageBuffer); -} - -void BaseService::Start() -{ - StartThread(); -} - -void BaseService::Stop() -{ - FinishThread(); -} - -} // namespace SecurityManager diff --git a/src/server/service/include/base-service.h b/src/server/service/include/base-service.h deleted file mode 100644 index f89e09a4..00000000 --- a/src/server/service/include/base-service.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2014-2022 Samsung Electronics Co., Ltd. All rights reserved. - * - * This file is licensed under the terms of MIT License or the Apache License - * Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details. - * See the LICENSE file or the notice below for Apache License Version 2.0 - * details. - * - * 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 base-service.h - * @author Lukasz Kostyra <l.kostyra@samsung.com> - * @author Rafal Krypa <r.krypa@samsung.com> - * @brief Implementation of security-manager base service - */ - -#pragma once - -#include <service-thread.h> -#include <generic-socket-manager.h> -#include <message-buffer.h> -#include <service_impl.h> - -namespace SecurityManager { - -class BaseServiceException -{ -public: - DECLARE_EXCEPTION_TYPE(SecurityManager::Exception, Base) - DECLARE_EXCEPTION_TYPE(Base, InvalidAction) -}; - -class BaseService : - public SecurityManager::GenericSocketService, - public SecurityManager::ServiceThread -{ -public: - using Offline = ServiceImpl::Offline; - explicit BaseService(Offline offline); - virtual const ServiceDescription &GetServiceDescription() const = 0; - - DECLARE_THREAD_EVENT(MessageEvent, process) - - void process(MessageEvent &&event); - - void Start(); - void Stop(); - -protected: - ServiceImpl serviceImpl; - - /** - * Handle request from a client - * - * @param conn Socket connection information - * @param buffer Received message buffer - * @return true on success - */ - virtual void processOne(const ConnectionID &conn, Credentials &creds, MessageBuffer &buffer) = 0; -}; - -} // namespace SecurityManager diff --git a/src/server/service/include/service.h b/src/server/service/include/service.h index 7fe5dede..028a837b 100644 --- a/src/server/service/include/service.h +++ b/src/server/service/include/service.h @@ -28,40 +28,50 @@ #pragma once -#include "base-service.h" -#include "credentials.h" -#include "service_impl.h" #include <channel.h> +#include <credentials.h> +#include <message-buffer.h> +#include <service_impl.h> +#include <service-thread.h> +#include <socket-manager.h> namespace SecurityManager { -class ServiceException -{ -public: - DECLARE_EXCEPTION_TYPE(SecurityManager::Exception, Base) - DECLARE_EXCEPTION_TYPE(Base, InvalidAction) +struct Event { + SocketManager::ConnectionID connectionID; + Credentials creds; + MessageBuffer buffer; }; -class Service : - public SecurityManager::BaseService +class Service final : public ServiceThread<Service, Event> { + ServiceImpl m_serviceImpl; + SocketManager *m_serviceManager = nullptr; public: - using Offline = BaseService::Offline; - explicit Service(Offline offline); - const ServiceDescription &GetServiceDescription() const override; + static inline const SocketManager::ServiceDescription DESCRIPTION{ + SERVICE_SOCKET, /* path */ + "*" /* smackLabel label (not used, we rely on systemd) */ + }; + + using Offline = ServiceImpl::Offline; + explicit Service(Offline offline) : m_serviceImpl(offline) {} void RegisterChannel(Channel channel) { - serviceImpl.RegisterChannel(std::move(channel)); + m_serviceImpl.RegisterChannel(std::move(channel)); + } + + void SetSocketManager(SocketManager *manager) { + m_serviceManager = manager; } -private: /** * Handle request from a client * - * @param conn Socket connection information - * @param buffer Input/output message buffer - * @return true on success + * @param conn Socket connection information + * @param msg A message */ - void processOne(const ConnectionID &conn, Credentials &creds, MessageBuffer &buffer) override; + void processEvent(Event &&msg); + +private: /** * Process getting application manifest policy diff --git a/src/server/service/service.cpp b/src/server/service/service.cpp index 3a3c8e10..17ebf940 100644 --- a/src/server/service/service.cpp +++ b/src/server/service/service.cpp @@ -33,134 +33,131 @@ #include <dpl/serialization.h> #include <sys/smack.h> -#include "connection.h" -#include "protocols.h" -#include "service.h" -#include "service_impl.h" -#include "utils.h" +#include <connection.h> +#include <protocols.h> +#include <service.h> +#include <utils.h> namespace SecurityManager { -Service::Service(Offline offline) : BaseService(offline) {} - -static const GenericSocketService::ServiceDescription serviceDesc{ - SERVICE_SOCKET, /* path */ - "*" /* smackLabel label (not used, we rely on systemd) */ -}; - -const GenericSocketService::ServiceDescription &Service::GetServiceDescription() const +namespace { +class ServiceException { - return serviceDesc; -} +public: + DECLARE_EXCEPTION_TYPE(SecurityManager::Exception, Base) + DECLARE_EXCEPTION_TYPE(Base, InvalidAction) +}; +} // namespace -void Service::processOne(const ConnectionID &conn, Credentials &creds, MessageBuffer &buffer) +void Service::processEvent(Event &&msg) { - LogDebug("Iteration begin."); + LogDebug("Processing message for socket " << msg.connectionID.sock << + " counter " << msg.connectionID.counter); Try { // deserialize API call type int call_type_int; - Deserialization::Deserialize(buffer, call_type_int); + Deserialization::Deserialize(msg.buffer, call_type_int); SecurityModuleCall call_type = static_cast<SecurityModuleCall>(call_type_int); - LOG_EXECUTION_TIME(SecurityModuleCallToString(call_type), creds); + LOG_EXECUTION_TIME(SecurityModuleCallToString(call_type), msg.creds); switch (call_type) { case SecurityModuleCall::NOOP: LogDebug("call_type: SecurityModuleCall::NOOP"); - Serialization::Serialize(buffer, static_cast<int>(SECURITY_MANAGER_SUCCESS)); + Serialization::Serialize(msg.buffer, static_cast<int>(SECURITY_MANAGER_SUCCESS)); break; case SecurityModuleCall::APP_INSTALL: LogDebug("call_type: SecurityModuleCall::APP_INSTALL"); - processAppInstall(buffer, creds); + processAppInstall(msg.buffer, msg.creds); break; case SecurityModuleCall::APP_UPDATE: LogDebug("call_type: SecurityModuleCall::APP_UPDATE"); - processAppUpdate(buffer, creds); + processAppUpdate(msg.buffer, msg.creds); break; case SecurityModuleCall::APP_UNINSTALL: LogDebug("call_type: SecurityModuleCall::APP_UNINSTALL"); - processAppUninstall(buffer, creds); + processAppUninstall(msg.buffer, msg.creds); break; case SecurityModuleCall::APP_GET_PKG_NAME: LogDebug("call_type: SecurityModuleCall::APP_GET_PKG_NAME"); - processGetPkgName(buffer); + processGetPkgName(msg.buffer); break; case SecurityModuleCall::USER_ADD: LogDebug("call_type: SecurityModuleCall::USER_ADD"); - processUserAdd(buffer, creds); + processUserAdd(msg.buffer, msg.creds); break; case SecurityModuleCall::USER_DELETE: LogDebug("call_type: SecurityModuleCall::USER_DELETE"); - processUserDelete(buffer, creds); + processUserDelete(msg.buffer, msg.creds); break; case SecurityModuleCall::POLICY_UPDATE: LogDebug("call_type: SecurityModuleCall::POLICY_UPDATE"); - processPolicyUpdate(buffer, creds); + processPolicyUpdate(msg.buffer, msg.creds); break; case SecurityModuleCall::GET_CONF_POLICY_ADMIN: LogDebug("call_type: SecurityModuleCall::GET_CONF_POLICY_ADMIN"); - processGetConfiguredPolicy(buffer, creds, true); + processGetConfiguredPolicy(msg.buffer, msg.creds, true); break; case SecurityModuleCall::GET_CONF_POLICY_SELF: LogDebug("call_type: SecurityModuleCall::GET_CONF_POLICY_SELF"); - processGetConfiguredPolicy(buffer, creds, false); + processGetConfiguredPolicy(msg.buffer, msg.creds, false); break; case SecurityModuleCall::GET_POLICY: LogDebug("call_type: SecurityModuleCall::GET_POLICY"); - processGetPolicy(buffer, creds); + processGetPolicy(msg.buffer, msg.creds); break; case SecurityModuleCall::POLICY_GET_DESCRIPTIONS: LogDebug("call_type: SecurityModuleCall::POLICY_GET_DESCRIPTIONS"); - processPolicyGetDesc(buffer); + processPolicyGetDesc(msg.buffer); break; case SecurityModuleCall::GROUPS_GET: LogDebug("call_type: SecurityModuleCall::GROUPS_GET"); - processGetForbiddenAndAllowedGroups(buffer, creds); + processGetForbiddenAndAllowedGroups(msg.buffer, msg.creds); break; case SecurityModuleCall::GROUPS_FOR_UID: - processGroupsForUid(buffer); + processGroupsForUid(msg.buffer); break; case SecurityModuleCall::APP_HAS_PRIVILEGE: LogDebug("call_type: SecurityModuleCall::APP_HAS_PRIVILEGE"); - processAppHasPrivilege(buffer, creds); + processAppHasPrivilege(msg.buffer, msg.creds); break; case SecurityModuleCall::APP_APPLY_PRIVATE_SHARING: LogDebug("call_type: SecurityModuleCall::APP_APPLY_PRIVATE_SHARING"); - processApplyPrivateSharing(buffer, creds); + processApplyPrivateSharing(msg.buffer, msg.creds); break; case SecurityModuleCall::APP_DROP_PRIVATE_SHARING: LogDebug("call_type: SecurityModuleCall::APP_DROP_PRIVATE_SHARING"); - processDropPrivateSharing(buffer, creds); + processDropPrivateSharing(msg.buffer, msg.creds); break; case SecurityModuleCall::PATHS_REGISTER: - processPathsRegister(buffer, creds); + processPathsRegister(msg.buffer, msg.creds); break; case SecurityModuleCall::SHM_APP_NAME: - processShmAppName(buffer, creds); + processShmAppName(msg.buffer, msg.creds); break; case SecurityModuleCall::GET_APP_DEFINED_PRIVILEGE_PROVIDER: LogDebug("call_type: SecurityModuleCall::GET_APP_DEFINED_PRIVILEGE_PROVIDER"); - processGetAppDefinedPrivilegeProvider(buffer); + processGetAppDefinedPrivilegeProvider(msg.buffer); break; case SecurityModuleCall::GET_APP_DEFINED_PRIVILEGE_LICENSE: LogDebug("call_type: SecurityModuleCall::GET_APP_DEFINED_PRIVILEGE_LICENSE"); - processGetAppDefinedPrivilegeLicense(buffer); + processGetAppDefinedPrivilegeLicense(msg.buffer); break; case SecurityModuleCall::GET_CLIENT_PRIVILEGE_LICENSE: LogDebug("call_type: SecurityModuleCall::GET_CLIENT_PRIVILEGE_PROVIDER"); - processGetClientPrivilegeLicense(buffer); + processGetClientPrivilegeLicense(msg.buffer); break; case SecurityModuleCall::APP_CLEAN_NAMESPACE: LogDebug("call_type: SecurityModuleCall::APP_CLEAN_NAMESPACE"); - processAppCleanNamespace(buffer, creds); + processAppCleanNamespace(msg.buffer, msg.creds); break; case SecurityModuleCall::GET_APP_MANIFEST_POLICY: LogDebug("call_type: SecurityModuleCall::GET_APP_MANIFEST_POLICY"); - processAppGetManifestPolicy(buffer, creds); + processAppGetManifestPolicy(msg.buffer, msg.creds); break; case SecurityModuleCall::GET_PROCESS_LABEL: - processGetProcessLabel(buffer); + processGetProcessLabel(msg.buffer); break; case SecurityModuleCall::PREPARE_APP: - prepareApp(buffer, creds); + prepareApp(msg.buffer, msg.creds); break; default: LogError("Invalid call: " << call_type_int); @@ -168,7 +165,7 @@ void Service::processOne(const ConnectionID &conn, Credentials &creds, MessageBu } // if we reach this point, the protocol is OK LogDebug("Writing response to client."); - return m_serviceManager->Write(conn, std::move(buffer)); + return m_serviceManager->Write(msg.connectionID, std::move(msg.buffer)); } Catch(MessageBuffer::Exception::Base) { LogError("Broken protocol."); } Catch(ServiceException::Base) { @@ -180,7 +177,7 @@ void Service::processOne(const ConnectionID &conn, Credentials &creds, MessageBu } LogError("Closing socket because of error"); - m_serviceManager->Close(conn); + m_serviceManager->Close(msg.connectionID); } void Service::processAppGetManifestPolicy(MessageBuffer &buffer, const Credentials &creds) @@ -193,7 +190,7 @@ void Service::processAppGetManifestPolicy(MessageBuffer &buffer, const Credentia Deserialization::Deserialize(buffer, appName); Deserialization::Deserialize(buffer, uid); - ret = serviceImpl.getAppManifestPolicy(creds, appName, uid, privileges); + ret = m_serviceImpl.getAppManifestPolicy(creds, appName, uid, privileges); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); @@ -210,7 +207,7 @@ void Service::processAppInstall(MessageBuffer &buffer, const Credentials &creds) Deserialization::Deserialize(buffer, req); buffer.ModeStreaming(); - Serialization::Serialize(buffer, serviceImpl.appInstall(creds, req)); + Serialization::Serialize(buffer, m_serviceImpl.appInstall(creds, req)); } void Service::processAppUpdate(MessageBuffer &buffer, const Credentials &creds) @@ -219,7 +216,7 @@ void Service::processAppUpdate(MessageBuffer &buffer, const Credentials &creds) Deserialization::Deserialize(buffer, req); buffer.ModeStreaming(); - Serialization::Serialize(buffer, serviceImpl.appUpdate(creds, req)); + Serialization::Serialize(buffer, m_serviceImpl.appUpdate(creds, req)); } void Service::processAppUninstall(MessageBuffer &buffer, const Credentials &creds) @@ -228,7 +225,7 @@ void Service::processAppUninstall(MessageBuffer &buffer, const Credentials &cred Deserialization::Deserialize(buffer, req); buffer.ModeStreaming(); - Serialization::Serialize(buffer, serviceImpl.appUninstall(creds, req)); + Serialization::Serialize(buffer, m_serviceImpl.appUninstall(creds, req)); } void Service::processGetPkgName(MessageBuffer &buffer) @@ -238,7 +235,7 @@ void Service::processGetPkgName(MessageBuffer &buffer) int ret; Deserialization::Deserialize(buffer, appName); - ret = serviceImpl.getPkgName(appName, pkgName); + ret = m_serviceImpl.getPkgName(appName, pkgName); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); if (ret == SECURITY_MANAGER_SUCCESS) @@ -254,7 +251,7 @@ void Service::processUserAdd(MessageBuffer &buffer, const Credentials &creds) Deserialization::Deserialize(buffer, uidAdded); Deserialization::Deserialize(buffer, userType); - ret = serviceImpl.userAdd(creds, uidAdded, userType); + ret = m_serviceImpl.userAdd(creds, uidAdded, userType); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); } @@ -266,7 +263,7 @@ void Service::processUserDelete(MessageBuffer &buffer, const Credentials &creds) Deserialization::Deserialize(buffer, uidRemoved); - ret = serviceImpl.userDelete(creds, uidRemoved); + ret = m_serviceImpl.userDelete(creds, uidRemoved); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); } @@ -278,7 +275,7 @@ void Service::processPolicyUpdate(MessageBuffer &buffer, const Credentials &cred Deserialization::Deserialize(buffer, policyEntries); - ret = serviceImpl.policyUpdate(creds, policyEntries); + ret = m_serviceImpl.policyUpdate(creds, policyEntries); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); } @@ -290,7 +287,7 @@ void Service::processGetConfiguredPolicy(MessageBuffer &buffer, const Credential Deserialization::Deserialize(buffer, filter); std::vector<policy_entry> policyEntries; - ret = serviceImpl.getConfiguredPolicy(creds, forAdmin, filter, policyEntries); + ret = m_serviceImpl.getConfiguredPolicy(creds, forAdmin, filter, policyEntries); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); @@ -307,7 +304,7 @@ void Service::processGetPolicy(MessageBuffer &buffer, const Credentials &creds) Deserialization::Deserialize(buffer, filter); std::vector<policy_entry> policyEntries; - ret = serviceImpl.getPolicy(creds, filter, policyEntries); + ret = m_serviceImpl.getPolicy(creds, filter, policyEntries); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); @@ -322,7 +319,7 @@ void Service::processPolicyGetDesc(MessageBuffer &buffer) int ret; std::vector<std::string> descriptions; - ret = serviceImpl.policyGetDesc(descriptions); + ret = m_serviceImpl.policyGetDesc(descriptions); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); @@ -342,11 +339,11 @@ void Service::processGetForbiddenAndAllowedGroups(MessageBuffer &buffer, const C Deserialization::Deserialize(buffer, appName); - std::string label = serviceImpl.getProcessLabel(appName); + std::string label = m_serviceImpl.getProcessLabel(appName); std::vector<std::string> allowedPrivileges; - int ret = serviceImpl.getAppAllowedPrivileges(label, creds.uid, allowedPrivileges); + int ret = m_serviceImpl.getAppAllowedPrivileges(label, creds.uid, allowedPrivileges); if (ret == SECURITY_MANAGER_SUCCESS) - ret = serviceImpl.getForbiddenAndAllowedGroups(label, allowedPrivileges, forbiddenGroups, + ret = m_serviceImpl.getForbiddenAndAllowedGroups(label, allowedPrivileges, forbiddenGroups, allowedGroups); else LogError("Failed to fetch allowed privileges for " << label); @@ -365,7 +362,7 @@ void Service::processGroupsForUid(MessageBuffer &buffer) Deserialization::Deserialize(buffer, uid); - int ret = serviceImpl.policyGroupsForUid(uid, groups); + int ret = m_serviceImpl.policyGroupsForUid(uid, groups); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); @@ -385,7 +382,7 @@ void Service::processAppHasPrivilege(MessageBuffer &buffer, const Credentials &c Deserialization::Deserialize(buffer, uid); bool result; - int ret = serviceImpl.appHasPrivilege(creds, appName, privilege, uid, result); + int ret = m_serviceImpl.appHasPrivilege(creds, appName, privilege, uid, result); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); @@ -400,7 +397,7 @@ void Service::processApplyPrivateSharing(MessageBuffer &buffer, const Credential Deserialization::Deserialize(buffer, ownerAppName); Deserialization::Deserialize(buffer, targetAppName); Deserialization::Deserialize(buffer, paths); - int ret = serviceImpl.applyPrivatePathSharing(creds, ownerAppName, targetAppName, paths); + int ret = m_serviceImpl.applyPrivatePathSharing(creds, ownerAppName, targetAppName, paths); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); } @@ -412,7 +409,7 @@ void Service::processDropPrivateSharing(MessageBuffer &buffer, const Credentials Deserialization::Deserialize(buffer, ownerAppName); Deserialization::Deserialize(buffer, targetAppName); Deserialization::Deserialize(buffer, paths); - int ret = serviceImpl.dropPrivatePathSharing(creds, ownerAppName, targetAppName, paths); + int ret = m_serviceImpl.dropPrivatePathSharing(creds, ownerAppName, targetAppName, paths); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); } @@ -424,7 +421,7 @@ void Service::processPathsRegister(MessageBuffer &buffer, const Credentials &cre Deserialization::Deserialize(buffer, req.uid); Deserialization::Deserialize(buffer, req.pkgPaths); Deserialization::Deserialize(buffer, req.installationType); - int ret = serviceImpl.pathsRegister(creds, std::move(req)); + int ret = m_serviceImpl.pathsRegister(creds, std::move(req)); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); } @@ -433,7 +430,7 @@ void Service::processShmAppName(MessageBuffer &buffer, const Credentials &creds) { std::string shmName, appName; Deserialization::Deserialize(buffer, shmName, appName); - int ret = serviceImpl.shmAppName(creds, shmName, appName); + int ret = m_serviceImpl.shmAppName(creds, shmName, appName); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); } @@ -445,7 +442,7 @@ void Service::processGetAppDefinedPrivilegeProvider(MessageBuffer &buffer) uid_t uid; Deserialization::Deserialize(buffer, uid, privilege); - ret = serviceImpl.getAppDefinedPrivilegeProvider(uid, privilege, appName, pkgName); + ret = m_serviceImpl.getAppDefinedPrivilegeProvider(uid, privilege, appName, pkgName); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); if (ret == SECURITY_MANAGER_SUCCESS) @@ -459,7 +456,7 @@ void Service::processGetAppDefinedPrivilegeLicense(MessageBuffer &buffer) uid_t uid; Deserialization::Deserialize(buffer, uid, privilege); - ret = serviceImpl.getAppDefinedPrivilegeLicense(uid, privilege, license); + ret = m_serviceImpl.getAppDefinedPrivilegeLicense(uid, privilege, license); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); if (ret == SECURITY_MANAGER_SUCCESS) @@ -473,7 +470,7 @@ void Service::processGetClientPrivilegeLicense(MessageBuffer &buffer) uid_t uid; Deserialization::Deserialize(buffer, appName, pkgName, uid, privilege); - ret = serviceImpl.getClientPrivilegeLicense(appName, pkgName, uid, privilege, license); + ret = m_serviceImpl.getClientPrivilegeLicense(appName, pkgName, uid, privilege, license); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); if (ret == SECURITY_MANAGER_SUCCESS) @@ -486,7 +483,7 @@ void Service::processAppCleanNamespace(MessageBuffer &buffer, const Credentials uid_t uid; pid_t pid; Deserialization::Deserialize(buffer, appName, uid, pid); - int ret = serviceImpl.appCleanNamespace(creds, appName, uid, pid); + int ret = m_serviceImpl.appCleanNamespace(creds, appName, uid, pid); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); } @@ -497,7 +494,7 @@ void Service::processGetProcessLabel(MessageBuffer &buffer) Deserialization::Deserialize(buffer, appName); buffer.ModeStreaming(); Serialization::Serialize(buffer, SECURITY_MANAGER_SUCCESS); - Serialization::Serialize(buffer, serviceImpl.getProcessLabel(appName)); + Serialization::Serialize(buffer, m_serviceImpl.getProcessLabel(appName)); } void Service::prepareApp(MessageBuffer &buffer, const Credentials &creds) @@ -508,7 +505,7 @@ void Service::prepareApp(MessageBuffer &buffer, const Credentials &creds) std::vector<gid_t> forbiddenGroups, allowedGroups; std::vector<bool> privPathsStatusVector; Deserialization::Deserialize(buffer, appName, privPathsVector); - int ret = serviceImpl.prepareApp(creds, appName, privPathsVector, + int ret = m_serviceImpl.prepareApp(creds, appName, privPathsVector, label, pkgName, prepareAppFlags, forbiddenGroups, allowedGroups, privPathsStatusVector); buffer.ModeStreaming(); Serialization::Serialize(buffer, ret); |