summaryrefslogtreecommitdiff
path: root/p11-kit/server.c
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@redhat.com>2018-06-20 10:43:24 +0200
committerDaiki Ueno <ueno@gnu.org>2018-06-20 13:19:23 +0200
commit53a7e915b2694bc1957d98493a7aee9abfa3c6c5 (patch)
tree82d4bdce9a6d8559a698cd40fda4bb96990489c7 /p11-kit/server.c
parentd4a4039f97b2e1f67d09d7cd8c05fb2dd129b23c (diff)
server: Enable socket activation through systemd
This enables socket activation of "p11-kit server" through systemd. The feature provided is essentially the same as commit a4fb2bb5 (reverted), but implemented with "p11-kit server" and libsystemd API instead of wrapping "p11-kit remote" in the unit file. Note that, while it exposes all tokens through the socket, it doesn't increase attack surface beyond the PKCS#11 binary interface provided by p11-kit-proxy.so, because the service is per-user.
Diffstat (limited to 'p11-kit/server.c')
-rw-r--r--p11-kit/server.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/p11-kit/server.c b/p11-kit/server.c
index e64890c..0c0092b 100644
--- a/p11-kit/server.c
+++ b/p11-kit/server.c
@@ -62,6 +62,10 @@
#include <sys/wait.h>
#include <unistd.h>
+#ifdef WITH_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
#ifdef HAVE_SIGHANDLER_T
#define SIGHANDLER_T sighandler_t
#elif HAVE_SIG_T
@@ -273,10 +277,16 @@ create_socket (const char *address,
umask (066);
rc = bind (sd, (struct sockaddr *)&sa, SUN_LEN (&sa));
if (rc == -1) {
- p11_message_err (errno, "could not create socket %s", socket_file);
+ p11_message_err (errno, "could not bind socket %s", socket_file);
return -1;
}
+ rc = listen (sd, 1024);
+ if (rc == -1) {
+ p11_message_err (errno, "could not listen to socket %s", socket_file);
+ return 1;
+ }
+
if (uid != -1 && gid != -1) {
rc = chown (socket_file, uid, gid);
if (rc == -1) {
@@ -356,7 +366,7 @@ server_loop (Server *server,
bool foreground,
struct timespec *timeout)
{
- int ret = 1, rc;
+ int ret;
int cfd;
pid_t pid;
socklen_t sa_len;
@@ -377,10 +387,6 @@ server_loop (Server *server,
ocsignal (SIGTERM, handle_term);
ocsignal (SIGINT, handle_term);
- server->socket = create_socket (server->socket_name, server->uid, server->gid);
- if (server->socket == -1)
- return 1;
-
/* run as daemon */
if (!foreground) {
pid = fork ();
@@ -403,10 +409,19 @@ server_loop (Server *server,
}
}
- rc = listen (server->socket, 1024);
- if (rc == -1) {
- p11_message_err (errno, "could not listen to socket %s", server->socket_name);
+#ifdef WITH_SYSTEMD
+ ret = sd_listen_fds (0);
+ if (ret > 1) {
+ p11_message ("too many file descriptors received");
return 1;
+ } else if (ret == 1) {
+ server->socket = SD_LISTEN_FDS_START + 0;
+ } else
+#endif
+ {
+ server->socket = create_socket (server->socket_name, server->uid, server->gid);
+ if (server->socket == -1)
+ return 1;
}
sigprocmask (SIG_BLOCK, &blockset, NULL);