summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <dueno@src.gnome.org>2021-02-12 10:14:24 +0100
committerDaiki Ueno <ueno@gnu.org>2021-03-26 17:36:32 +0000
commitd38011124e554c6c1dd57d859acfae4389c05699 (patch)
treecc22870f45f1ff712f36e4b54fddbf4fa0c85331
parent23294af736984655d03b5c58b504a96fe58cdd33 (diff)
downloadgnome-keyring-d38011124e554c6c1dd57d859acfae4389c05699.tar.gz
daemon: Make it systemd-activatable through the control socket
This enables gnome-keyring-daemon to be launched through the systemd socket activation mechanism, rather than through pam_gnome_keyring.so.
-rw-r--r--configure.ac25
-rw-r--r--daemon/.gitignore1
-rw-r--r--daemon/Makefile.am14
-rw-r--r--daemon/control/gkd-control-server.c60
-rw-r--r--daemon/gkd-main.c1
-rw-r--r--daemon/gnome-keyring-daemon.service.in14
-rw-r--r--daemon/gnome-keyring-daemon.socket11
7 files changed, 105 insertions, 21 deletions
diff --git a/configure.ac b/configure.ac
index 752d2ffa..c1f8afe4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -435,6 +435,30 @@ AC_SUBST(LIBSELINUX)
AM_CONDITIONAL([HAVE_LIBSELINUX], [test ! -z "$LIBSELINUX"])
# ----------------------------------------------------------------------
+# systemd
+
+AC_ARG_WITH([systemd],
+ AS_HELP_STRING([--without-systemd],
+ [Disable systemd socket activation]))
+
+AS_IF([test "$with_systemd" != "no"], [
+ PKG_CHECK_MODULES([LIBSYSTEMD], [libsystemd], [],
+ [with_systemd=no])
+
+ PKG_CHECK_VAR([systemduserunitdir], [systemd], [systemduserunitdir], [],
+ [with_systemd=no])
+
+ AS_IF([test "$with_systemd" != "no"], [
+ with_systemd=yes
+ AC_DEFINE_UNQUOTED(WITH_SYSTEMD, 1, [Build with systemd socket activation])
+ DAEMON_CFLAGS="$DAEMON_CFLAGS $LIBSYSTEMD_CFLAGS"
+ DAEMON_LIBS="$DAEMON_LIBS $LIBSYSTEMD_LIBS"
+ ])
+])
+
+AM_CONDITIONAL(WITH_SYSTEMD, [test "$with_systemd" = "yes"])
+
+# ----------------------------------------------------------------------
# dotlock.c support
AC_DEFINE(DOTLOCK_USE_PTHREAD,1,[Define if POSIX threads are in use.])
@@ -662,6 +686,7 @@ echo "OPTIONAL DEPENDENCIES"
echo " PAM: $pam_status"
echo " Linux capabilities: $libcapng_status"
echo " SELinux: $selinux_status"
+echo " systemd: $with_systemd"
echo
echo "CONFIGURATION"
echo " SSH Agent: $ssh_status"
diff --git a/daemon/.gitignore b/daemon/.gitignore
index 4db92394..47cec83d 100644
--- a/daemon/.gitignore
+++ b/daemon/.gitignore
@@ -1,4 +1,5 @@
/gnome-keyring-daemon
+/gnome-keyring-daemon.service
/org.gnome.keyring.service
/org.freedesktop.secrets.service
/org.freedesktop.impl.portal.Secret.service
diff --git a/daemon/Makefile.am b/daemon/Makefile.am
index 60b2f794..910f0095 100644
--- a/daemon/Makefile.am
+++ b/daemon/Makefile.am
@@ -37,6 +37,20 @@ service_in_files = \
servicedir = $(DBUS_SERVICES_DIR)
service_DATA = $(service_in_files:.service.in=.service)
+if WITH_SYSTEMD
+daemon/gnome-keyring-daemon.service: daemon/gnome-keyring-daemon.service.in
+ $(AM_V_GEN)rm -f $@-t $@ && \
+ sed 's|@bindir[@]|$(bindir)|g' $< > $@-t && \
+ mv -f $@-t $@
+
+CLEANFILES += daemon/gnome-keyring-daemon.service
+
+systemduserunit_DATA = \
+ daemon/gnome-keyring-daemon.socket \
+ daemon/gnome-keyring-daemon.service \
+ $(NULL)
+endif
+
desktopdir = $(sysconfdir)/xdg/autostart
desktop_in_in_files = \
daemon/gnome-keyring-pkcs11.desktop.in.in \
diff --git a/daemon/control/gkd-control-server.c b/daemon/control/gkd-control-server.c
index 11254feb..5ef307d6 100644
--- a/daemon/control/gkd-control-server.c
+++ b/daemon/control/gkd-control-server.c
@@ -41,6 +41,10 @@
#include <sys/types.h>
#include <sys/un.h>
+#ifdef WITH_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
typedef struct _ControlData {
EggBuffer buffer;
gsize position;
@@ -401,34 +405,48 @@ gkd_control_stop (void)
gboolean
gkd_control_listen (void)
{
- struct sockaddr_un addr;
GIOChannel *channel;
int sock;
- control_path = g_strdup_printf ("%s/control", gkd_util_get_master_directory ());
- egg_cleanup_register ((GDestroyNotify)gkd_control_stop, NULL);
+#ifdef WITH_SYSTEMD
+ int res;
- unlink (control_path);
-
- sock = socket (AF_UNIX, SOCK_STREAM, 0);
- if (sock < 0) {
- g_warning ("couldn't open socket: %s", g_strerror (errno));
+ res = sd_listen_fds (0);
+ if (res > 1) {
+ g_message ("too many file descriptors received");
return FALSE;
- }
+ } else if (res == 1) {
+ sock = SD_LISTEN_FDS_START + 0;
+ } else
+#endif
+ {
+ struct sockaddr_un addr;
- memset (&addr, 0, sizeof (addr));
- addr.sun_family = AF_UNIX;
- g_strlcpy (addr.sun_path, control_path, sizeof (addr.sun_path));
- if (bind (sock, (struct sockaddr*) &addr, sizeof (addr)) < 0) {
- g_warning ("couldn't bind to control socket: %s: %s", control_path, g_strerror (errno));
- close (sock);
- return FALSE;
- }
+ control_path = g_strdup_printf ("%s/control", gkd_util_get_master_directory ());
+ egg_cleanup_register ((GDestroyNotify)gkd_control_stop, NULL);
- if (listen (sock, 128) < 0) {
- g_warning ("couldn't listen on control socket: %s: %s", control_path, g_strerror (errno));
- close (sock);
- return FALSE;
+ unlink (control_path);
+
+ sock = socket (AF_UNIX, SOCK_STREAM, 0);
+ if (sock < 0) {
+ g_warning ("couldn't open socket: %s", g_strerror (errno));
+ return FALSE;
+ }
+
+ memset (&addr, 0, sizeof (addr));
+ addr.sun_family = AF_UNIX;
+ g_strlcpy (addr.sun_path, control_path, sizeof (addr.sun_path));
+ if (bind (sock, (struct sockaddr*) &addr, sizeof (addr)) < 0) {
+ g_warning ("couldn't bind to control socket: %s: %s", control_path, g_strerror (errno));
+ close (sock);
+ return FALSE;
+ }
+
+ if (listen (sock, 128) < 0) {
+ g_warning ("couldn't listen on control socket: %s: %s", control_path, g_strerror (errno));
+ close (sock);
+ return FALSE;
+ }
}
if (egg_unix_credentials_setup (sock) < 0) {
diff --git a/daemon/gkd-main.c b/daemon/gkd-main.c
index 5a9c58e9..33a38e21 100644
--- a/daemon/gkd-main.c
+++ b/daemon/gkd-main.c
@@ -585,6 +585,7 @@ discover_other_daemon (DiscoverFunc callback, gboolean acquire)
control = g_build_filename (control_env, "keyring", NULL);
ret = (callback) (control);
g_free (control);
+ g_printerr ("discover_other_daemon: %d", ret);
if (ret == TRUE)
return TRUE;
}
diff --git a/daemon/gnome-keyring-daemon.service.in b/daemon/gnome-keyring-daemon.service.in
new file mode 100644
index 00000000..fbce5ea5
--- /dev/null
+++ b/daemon/gnome-keyring-daemon.service.in
@@ -0,0 +1,14 @@
+[Unit]
+Description=GNOME Keyring daemon
+
+Requires=gnome-keyring-daemon.socket
+
+[Service]
+Type=simple
+StandardError=journal
+ExecStart=@bindir@/gnome-keyring-daemon --foreground --components="pkcs11,secrets" --control-directory=%t/keyring
+Restart=on-failure
+
+[Install]
+Also=gnome-keyring-daemon.socket
+WantedBy=default.target
diff --git a/daemon/gnome-keyring-daemon.socket b/daemon/gnome-keyring-daemon.socket
new file mode 100644
index 00000000..18077cad
--- /dev/null
+++ b/daemon/gnome-keyring-daemon.socket
@@ -0,0 +1,11 @@
+[Unit]
+Description=GNOME Keyring daemon
+
+[Socket]
+Priority=6
+Backlog=5
+ListenStream=%t/keyring/control
+DirectoryMode=0700
+
+[Install]
+WantedBy=sockets.target