[gcr/wip/dueno/ssh-agent: 1/2] ssh-agent: wire up systemd activation




commit 15ac6ce2e1f05f42af626e88700cac0606fccf98
Author: Daiki Ueno <dueno src gnome org>
Date:   Thu Feb 11 18:32:56 2021 +0100

    ssh-agent: wire up systemd activation

 gcr/gcr-ssh-agent-service.c | 70 +++++++++++++++++++++++++++++++++------------
 gcr/meson.build             |  4 +--
 meson.build                 | 11 +++++++
 meson_options.txt           |  5 ++++
 4 files changed, 70 insertions(+), 20 deletions(-)
---
diff --git a/gcr/gcr-ssh-agent-service.c b/gcr/gcr-ssh-agent-service.c
index d677726..bb43369 100644
--- a/gcr/gcr-ssh-agent-service.c
+++ b/gcr/gcr-ssh-agent-service.c
@@ -39,6 +39,10 @@
 #include <glib/gstdio.h>
 #include <gcr/gcr-base.h>
 
+#ifdef WITH_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
 #include <glib/gi18n-lib.h>
 
 EGG_SECURE_DECLARE (ssh_agent);
@@ -370,27 +374,57 @@ on_closed (GcrSshAgentProcess *process,
 gboolean
 gcr_ssh_agent_service_start (GcrSshAgentService *self)
 {
-       gchar *path;
-       GError *error;
+       GError *error = NULL;
 
-       path = g_strdup_printf ("%s/ssh", self->path);
-       g_unlink (path);
-       self->address = g_unix_socket_address_new (path);
-       g_free (path);
+#if WITH_SYSTEMD
+       int ret;
 
-       error = NULL;
-       if (!g_socket_listener_add_address (self->listener,
-                                           self->address,
-                                           G_SOCKET_TYPE_STREAM,
-                                           G_SOCKET_PROTOCOL_DEFAULT,
-                                           NULL,
-                                           NULL,
-                                           &error)) {
-               g_warning ("couldn't listen on %s: %s",
-                          g_unix_socket_address_get_path (G_UNIX_SOCKET_ADDRESS (self->address)),
-                          error->message);
-               g_error_free (error);
+       ret = sd_listen_fds (0);
+       if (ret > 1) {
+               g_warning ("too many file descriptors received");
                return FALSE;
+       } else if (ret == 1) {
+               GSocket *socket;
+
+               socket = g_socket_new_from_fd (SD_LISTEN_FDS_START + 0, &error);
+               if (!socket) {
+                       g_warning ("couldn't create a socket: %s", error->message);
+                       g_error_free (error);
+                       return FALSE;
+               }
+               if (!g_socket_listener_add_socket (self->listener,
+                                                  socket,
+                                                  self,
+                                                  &error)) {
+                       g_warning ("couldn't bind socket on %d: %s",
+                                  g_socket_get_fd (socket),
+                                  error->message);
+                       g_object_unref (socket);
+                       g_error_free (error);
+                       return FALSE;
+               }
+       } else
+#endif
+       {
+               gchar *path;
+               path = g_strdup_printf ("%s/ssh", self->path);
+               g_unlink (path);
+               self->address = g_unix_socket_address_new (path);
+               g_free (path);
+
+               if (!g_socket_listener_add_address (self->listener,
+                                                   self->address,
+                                                   G_SOCKET_TYPE_STREAM,
+                                                   G_SOCKET_PROTOCOL_DEFAULT,
+                                                   NULL,
+                                                   NULL,
+                                                   &error)) {
+                       g_warning ("couldn't listen on %s: %s",
+                                  g_unix_socket_address_get_path (G_UNIX_SOCKET_ADDRESS (self->address)),
+                                  error->message);
+                       g_error_free (error);
+                       return FALSE;
+               }
        }
 
        g_signal_connect (self->listener, "run", G_CALLBACK (on_run), self);
diff --git a/gcr/meson.build b/gcr/meson.build
index 87923f3..2dc2b21 100644
--- a/gcr/meson.build
+++ b/gcr/meson.build
@@ -250,7 +250,7 @@ if get_option('ssh_agent')
 
   gcr_ssh_agent = executable('gcr-ssh-agent',
     gcr_ssh_agent_lib_sources + [ 'gcr-ssh-agent.c' ],
-    dependencies: [ gcr_base_deps, gcr_base_dep, libsecret_dep ],
+    dependencies: [ gcr_base_deps, gcr_base_dep, libsecret_dep, libsystemd_deps ],
     c_args: [
       '-DGCR_COMPILATION',
       '-DGCR_API_SUBJECT_TO_CHANGE',
@@ -267,7 +267,7 @@ if get_option('ssh_agent')
 
   gcr_ssh_agent_test_lib = static_library('gcr-ssh-agent-test',
     sources: gcr_ssh_agent_lib_sources + [ 'gcr-ssh-agent-test.c' ],
-    dependencies: [ gcr_base_deps, gcr_base_dep, libsecret_dep ],
+    dependencies: [ gcr_base_deps, gcr_base_dep, libsecret_dep, libsystemd_deps ],
     c_args: [
       '-DGCR_COMPILATION',
       '-DGCR_API_SUBJECT_TO_CHANGE',
diff --git a/meson.build b/meson.build
index 98b8f35..fa0e3a0 100644
--- a/meson.build
+++ b/meson.build
@@ -55,6 +55,16 @@ libsecret_dep = dependency('libsecret-1', version: '>= 0.20', required: get_opti
 ssh_add_path = find_program('ssh-add', required: get_option('ssh_agent')).path()
 ssh_agent_path = find_program('ssh-agent', required: get_option('ssh_agent')).path()
 
+with_systemd = false
+libsystemd_deps = []
+libsystemd = dependency('libsystemd', required: get_option('systemd'))
+systemd = dependency('systemd', required: get_option('systemd'))
+if libsystemd.found() and systemd.found()
+  systemduserunitdir = systemd.get_pkgconfig_variable('systemduserunitdir')
+  libsystemd_deps += libsystemd
+  with_systemd = true
+endif
+
 if get_option('gtk')
   gtk_min_version = '3.22'
   gtk_dep = dependency('gtk+-3.0', version: '>=' + gtk_min_version)
@@ -74,6 +84,7 @@ conf.set_quoted('GPG_EXECUTABLE', gpg_path)
 conf.set_quoted('LIBGCRYPT_VERSION', libgcrypt_dep.version())
 conf.set_quoted('SSH_ADD_EXECUTABLE', ssh_add_path)
 conf.set_quoted('SSH_AGENT_EXECUTABLE', ssh_agent_path)
+conf.set10('WITH_SYSTEMD', with_systemd)
 config_file = configure_file(
   output: 'config.h',
   configuration: conf,
diff --git a/meson_options.txt b/meson_options.txt
index 17683d9..f96a47c 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -23,3 +23,8 @@ option('ssh_agent',
   value: true,
   description: 'Build ssh-agent binary',
 )
+option('systemd',
+  type: 'feature',
+  value: 'auto',
+  description: 'Use systemd socket activation for server programs'
+)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]