Convert to systemd API.
authorBartlomiej Grzelewski <b.grzelewski@samsung.com>
Fri, 5 Jul 2013 16:54:23 +0000 (18:54 +0200)
committerBartlomiej Grzelewski <b.grzelewski@samsung.com>
Thu, 6 Feb 2014 16:13:20 +0000 (17:13 +0100)
- enable socket activation
- enable sn_notify (start-up completion notification).

[Issue#]   SSDWSSP-146
[Bug]      N/A
[Cause]    N/A
[Problem]  Socket activation is required in security-server.
[Solution] Add support for socket activation in security-server.

[Verification] Reinstall security-server. Reboot target. Run tests.

Change-Id: I4d8c4f79bf1979df5e9e48b24bae9725441a9a14

13 files changed:
CMakeLists.txt
packaging/security-server.spec
src/CMakeLists.txt
src/communication/security-server-comm.c
src/include/security-server-comm.h
src/server/security-server-main.c
src/server2/common/protocols.cpp
src/server2/main/socket-manager.cpp
src/server2/main/socket-manager.h
systemd/CMakeLists.txt [new file with mode: 0644]
systemd/security-server-data-share.socket [new file with mode: 0644]
systemd/security-server.service [new file with mode: 0644]
systemd/security-server.socket [new file with mode: 0644]

index e440690..6b02ab3 100644 (file)
@@ -63,5 +63,13 @@ SET(TARGET_SECURITY_SERVER "security-server")
 SET(TARGET_SECURITY_CLIENT "security-server-client")
 SET(TARGET_SERVER_COMMON "security-server-commons")
 
+INSTALL(FILES
+    ${CMAKE_SOURCE_DIR}/packaging/libsecurity-server-client.manifest
+    ${CMAKE_SOURCE_DIR}/packaging/security-server.manifest
+    DESTINATION
+    /usr/share
+)
+
 ADD_SUBDIRECTORY(src)
 ADD_SUBDIRECTORY(build)
+ADD_SUBDIRECTORY(systemd)
index 7af2dbe..0e23ab6 100644 (file)
@@ -5,9 +5,6 @@ Release:    1
 Group:      Security/Service
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
-Source2:    libsecurity-server-client.manifest
-Source3:    security-server.service
-Source1001: %{name}.manifest
 BuildRequires: cmake
 BuildRequires: zip
 BuildRequires: pkgconfig(dlog)
@@ -18,6 +15,8 @@ Requires(preun):  systemd
 Requires(post):   systemd
 Requires(postun): systemd
 BuildRequires: pkgconfig(libprivilege-control)
+BuildRequires: pkgconfig(libsystemd-daemon)
+%{?systemd_requires}
 
 %description
 Tizen security server and utilities
@@ -76,6 +75,12 @@ cp LICENSE %{buildroot}/usr/share/license/libsecurity-server-client
 %make_install
 
 mkdir -p %{buildroot}/usr/lib/systemd/system/multi-user.target.wants
+mkdir -p %{buildroot}/usr/lib/systemd/system/sockets.target.wants
+ln -s ../security-server.service %{buildroot}/usr/lib/systemd/system/multi-user.target.wants/security-server.service
+ln -s ../security-server.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server.socket
+ln -s ../security-server-data-share.socket %{buildroot}/usr/lib/systemd/system/sockets.target.wants/security-server-data-share.socket
+
+mkdir -p %{buildroot}/usr/lib/systemd/system/multi-user.target.wants
 install -m 0644 %{SOURCE3} %{buildroot}/usr/lib/systemd/system/security-server.service
 ln -s ../security-server.service %{buildroot}/usr/lib/systemd/system/multi-user.target.wants/security-server.service
 
@@ -105,6 +110,12 @@ systemctl daemon-reload
 /usr/lib/systemd/system/security-server.service
 %attr(755,root,root) /usr/bin/security-server
 %{_libdir}/libsecurity-server-commons.so.*
+%attr(-,root,root) /usr/lib/systemd/system/multi-user.target.wants/security-server.service
+%attr(-,root,root) /usr/lib/systemd/system/security-server.service
+%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server.socket
+%attr(-,root,root) /usr/lib/systemd/system/security-server.socket
+%attr(-,root,root) /usr/lib/systemd/system/sockets.target.wants/security-server-data-share.socket
+%attr(-,root,root) /usr/lib/systemd/system/security-server-data-share.socket
 
 %{_datadir}/license/%{name}
 
index ebb3e56..937e0d7 100644 (file)
@@ -3,6 +3,7 @@ PKG_CHECK_MODULES(SECURITY_SERVER_DEP
     openssl
     libsmack
     libprivilege-control
+    libsystemd-daemon
     REQUIRED
     )
 
index 31c29f3..87ea71d 100644 (file)
@@ -35,6 +35,8 @@
 #include <limits.h>
 #include <ctype.h>
 
+#include <systemd/sd-daemon.h>
+
 #include "security-server-common.h"
 #include "security-server-comm.h"
 
@@ -157,6 +159,23 @@ int safe_server_sock_close(int client_sockfd)
     return SECURITY_SERVER_SUCCESS;
 }
 
+/* Get socket from systemd */
+int get_socket_from_systemd(int *sockfd)
+{
+    int n = sd_listen_fds(0);
+    int fd;
+
+    for(fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) {
+        if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1,
+                                  SECURITY_SERVER_SOCK_PATH, 0))
+        {
+            *sockfd = fd;
+            return SECURITY_SERVER_SUCCESS;
+        }
+    }
+    return SECURITY_SERVER_ERROR_SOCKET;
+}
+
 /* Create a Unix domain socket and bind */
 int create_new_socket(int *sockfd)
 {
index 37b20ce..1469250 100644 (file)
@@ -156,5 +156,6 @@ int send_reset_pwd_request(int sock_fd,
                            const unsigned int max_challenge,
                            const unsigned int valid_period_in_days);
 int send_set_pwd_history_request(int sock_fd, int num);
+int get_socket_from_systemd(int *sockfd);
 
 #endif
index 77d7eee..0756e31 100644 (file)
@@ -1576,17 +1576,23 @@ void *security_server_main_thread(void *data)
     initiate_try();
 
     /* Create and bind a Unix domain socket */
-    retval = create_new_socket(&server_sockfd);
-    if (retval != SECURITY_SERVER_SUCCESS)
+    if(SECURITY_SERVER_SUCCESS != get_socket_from_systemd(&server_sockfd))
     {
-        SEC_SVR_ERR("%s", "cannot create socket. exiting...");
-        goto error;
-    }
+        SEC_SVR_ERR("%s", "Error in get_socket_from_systemd");
+        retval = create_new_socket(&server_sockfd);
+        if (retval != SECURITY_SERVER_SUCCESS)
+        {
+            SEC_SVR_ERR("%s", "cannot create socket. exiting...");
+            goto error;
+        }
 
-    if (listen(server_sockfd, 5) < 0)
-    {
-        SEC_SVR_ERR("%s", "listen() failed. exiting...");
-        goto error;
+        if (listen(server_sockfd, 5) < 0)
+        {
+            SEC_SVR_ERR("%s", "listen() failed. exiting...");
+            goto error;
+        }
+    } else {
+        SEC_SVR_ERR("%s", "Socket was passed by systemd");
     }
 
     /* Create a default cookie --> Cookie for root process */
index cee95f0..dea97c8 100644 (file)
@@ -27,9 +27,9 @@
 namespace SecurityServer {
 
 char const * const SERVICE_SOCKET_SHARED_MEMORY =
-    "/tmp/security-server-api-data-share";
+    "/tmp/.security-server-api-data-share.sock";
 char const * const SERVICE_SOCKET_ECHO =
-    "/tmp/security-server-api-echo";
+    "/tmp/.security-server-api-echo.sock";
 
 } // namespace SecurityServer
 
index 5769c38..a1683be 100644 (file)
@@ -34,6 +34,8 @@
 #include <errno.h>
 #include <time.h>
 
+#include <systemd/sd-daemon.h>
+
 #include <dpl/log/log.h>
 #include <dpl/assert.h>
 
@@ -111,7 +113,7 @@ SocketManager::SocketManager()
 }
 
 SocketManager::~SocketManager() {
-
+    // TODO clean up all services!
 }
 
 void SocketManager::ReadyForAccept(int sock) {
@@ -208,6 +210,13 @@ void SocketManager::ReadyForWrite(int sock) {
 }
 
 void SocketManager::MainLoop() {
+    // remove evironment values passed by systemd
+    // uncomment it after removing old security-server code
+    // sd_listen_fds(1);
+
+    // Daemon is ready to work.
+    sd_notify(0, "READY=1");
+
     m_working = true;
     while(m_working) {
         fd_set readSet = m_readSet;
@@ -311,11 +320,39 @@ void SocketManager::MainLoop() {
     }
 }
 
-void SocketManager::CreateDomainSocket(
-    GenericSocketService *service,
+int SocketManager::GetSocketFromSystemD(
     const GenericSocketService::ServiceDescription &desc)
 {
-    int sockfd = -1;
+    int fd;
+
+    // TODO optimalization - do it once in object constructor
+    //                       and remember all information path->sockfd
+    int n = sd_listen_fds(0);
+
+    LogInfo("sd_listen_fds returns: " << n);
+
+    if (n < 0) {
+        LogError("Error in sd_listend_fds");
+        ThrowMsg(Exception::InitFailed, "Error in sd_listend_fds");
+    }
+
+    for(fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START+n; ++fd) {
+        if (0 < sd_is_socket_unix(fd, SOCK_STREAM, 1,
+                                  desc.serviceHandlerPath.c_str(), 0))
+        {
+            LogInfo("Useable socket " << desc.serviceHandlerPath <<
+                " was passed by SystemD");
+            return fd;
+        }
+    }
+    LogInfo("No useable sockets were passed by systemd.");
+    return -1;
+}
+
+int SocketManager::CreateDomainSocketHelp(
+    const GenericSocketService::ServiceDescription &desc)
+{
+    int sockfd;
 
     if (-1 == (sockfd = socket(AF_UNIX, SOCK_STREAM, 0))) {
         int err = errno;
@@ -370,6 +407,17 @@ void SocketManager::CreateDomainSocket(
         ThrowMsg(Exception::InitFailed, "Error in listen: " << strerror(err));
     }
 
+    return sockfd;
+}
+
+void SocketManager::CreateDomainSocket(
+    GenericSocketService *service,
+    const GenericSocketService::ServiceDescription &desc)
+{
+    int sockfd = GetSocketFromSystemD(desc);
+    if (-1 == sockfd)
+        sockfd = CreateDomainSocketHelp(desc);
+
     auto &description = CreateDefaultReadSocketDescription(sockfd, false);
 
     description.isListen = true;
index 534281c..12203fe 100644 (file)
@@ -57,6 +57,11 @@ protected:
     void CreateDomainSocket(
         GenericSocketService *service,
         const GenericSocketService::ServiceDescription &desc);
+    int CreateDomainSocketHelp(
+        const GenericSocketService::ServiceDescription &desc);
+    int GetSocketFromSystemD(
+        const GenericSocketService::ServiceDescription &desc);
+
     void ReadyForRead(int sock);
     void ReadyForWrite(int sock);
     void ReadyForAccept(int sock);
diff --git a/systemd/CMakeLists.txt b/systemd/CMakeLists.txt
new file mode 100644 (file)
index 0000000..75342f8
--- /dev/null
@@ -0,0 +1,8 @@
+INSTALL(FILES
+    ${CMAKE_SOURCE_DIR}/systemd/security-server.service
+    ${CMAKE_SOURCE_DIR}/systemd/security-server.socket
+    ${CMAKE_SOURCE_DIR}/systemd/security-server-data-share.socket
+    DESTINATION
+    /usr/lib/systemd/system
+)
+
diff --git a/systemd/security-server-data-share.socket b/systemd/security-server-data-share.socket
new file mode 100644 (file)
index 0000000..95ac056
--- /dev/null
@@ -0,0 +1,10 @@
+[Socket]
+ListenStream=/tmp/.security-server-api-data-share.sock
+SocketMode=0777
+SmackLabelIPIn=security-server::api-data-share
+SmackLabelIPOut=@
+
+Service=security-server.service
+
+[Install]
+WantedBy=sockets.target
diff --git a/systemd/security-server.service b/systemd/security-server.service
new file mode 100644 (file)
index 0000000..a15a84c
--- /dev/null
@@ -0,0 +1,11 @@
+[Unit]
+Description=Start the security server
+
+[Service]
+Type=notify
+ExecStart=/usr/bin/security-server
+Sockets=security-server.socket
+Sockets=security-server-data-share.socket
+
+[Install]
+WantedBy=multi-user.target
diff --git a/systemd/security-server.socket b/systemd/security-server.socket
new file mode 100644 (file)
index 0000000..fb715d5
--- /dev/null
@@ -0,0 +1,8 @@
+[Socket]
+ListenStream=/tmp/.security_server.sock
+SocketMode=0777
+SmackLabelIPIn=*
+SmackLabelIPOut=@
+
+[Install]
+WantedBy=sockets.target