diff options
-rw-r--r-- | modules/programs/gnupg/agent-wrapper.c | 54 | ||||
-rw-r--r-- | modules/programs/gnupg/default.nix | 18 |
2 files changed, 52 insertions, 20 deletions
diff --git a/modules/programs/gnupg/agent-wrapper.c b/modules/programs/gnupg/agent-wrapper.c index b5e623bc..d9cb7a0e 100644 --- a/modules/programs/gnupg/agent-wrapper.c +++ b/modules/programs/gnupg/agent-wrapper.c @@ -11,21 +11,19 @@ #include <sys/un.h> #include <systemd/sd-daemon.h> +#ifndef SUPERVISOR_SUPPORT static int main_fd = 0; -static int ssh_fd = 0; static int scdaemon_fd = 0; +#endif -/* Get a systemd file descriptor corresponding to the specified socket path. - * - * Return values: - * -1 Socket path not a systemd socket - * -2 Provided socket path is not absolute - * -3 No suitable file descriptors in LISTEN_FDS - * -4 Error while determining LISTEN_FDS - */ -static int get_sd_fd(const char *sockpath) -{ +static int ssh_fd = 0; + +static int gather_sd_fds(void) { +#ifdef SUPERVISOR_SUPPORT + if (ssh_fd == 0) { +#else if (main_fd == 0 && ssh_fd == 0 && scdaemon_fd == 0) { +#endif int num_fds; char **fdmap = NULL; void *libsystemd = NULL; @@ -55,12 +53,14 @@ static int get_sd_fd(const char *sockpath) if (fdmap != NULL) { for (int i = 0; i < num_fds; i++) { - if (strncmp(fdmap[i], "main", 5) == 0) - main_fd = SD_LISTEN_FDS_START + i; - else if (strncmp(fdmap[i], "ssh", 4) == 0) + if (strncmp(fdmap[i], "ssh", 4) == 0) ssh_fd = SD_LISTEN_FDS_START + i; +#ifndef SUPERVISOR_SUPPORT + else if (strncmp(fdmap[i], "main", 5) == 0) + main_fd = SD_LISTEN_FDS_START + i; else if (strncmp(fdmap[i], "scdaemon", 9) == 0) scdaemon_fd = SD_LISTEN_FDS_START + i; +#endif free(fdmap[i]); } free(fdmap); @@ -70,6 +70,26 @@ static int get_sd_fd(const char *sockpath) return -1; } + return 0; +} + +#ifndef SUPERVISOR_SUPPORT + +/* Get a systemd file descriptor corresponding to the specified socket path. + * + * Return values: + * -1 Socket path not a systemd socket + * -2 Provided socket path is not absolute + * -3 No suitable file descriptors in LISTEN_FDS + * -4 Error while determining LISTEN_FDS + */ +static int get_sd_fd(const char *sockpath) +{ + int ret; + + if ((ret = gather_sd_fds()) != 0) + return ret; + char *basename = strrchr(sockpath, '/'); if (basename == NULL) return -2; @@ -215,6 +235,8 @@ pid_t fork(void) return _fork(); } +#endif /* !SUPERVISOR_SUPPORT */ + /* Get the PID of the client connected to the given socket FD. */ static pid_t get_socket_pid(int sockfd) { @@ -247,6 +269,10 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) last_pid = 0; +#ifdef SUPERVISOR_SUPPORT + if (ssh_fd == 0) gather_sd_fds(); +#endif + if (retval != -1 && ssh_fd != 0 && sockfd == ssh_fd) { pid_t client_pid = get_socket_pid(retval); if (client_pid == -1) { diff --git a/modules/programs/gnupg/default.nix b/modules/programs/gnupg/default.nix index d938a184..db9bdc6b 100644 --- a/modules/programs/gnupg/default.nix +++ b/modules/programs/gnupg/default.nix @@ -8,6 +8,8 @@ let hasXdgSupport = versionAtLeast (getVersion cfg.package) "2.1.13"; isDefaultHome = cfg.homeDir == ".gnupg"; + hasSupervisorSupport = versionAtLeast (getVersion cfg.package) "2.1.16"; + sockDir = if hasXdgSupport && isDefaultHome then "%t/gnupg" else "%h/${cfg.homeDir}"; @@ -28,11 +30,12 @@ let UNIX-CONNECT:"${shellSockDir}/S.scdaemon" ''; - agentWrapper = pkgs.runCommandCC "gpg-agent-wrapper" { + agentWrapper = withSupervisor: pkgs.runCommandCC "gpg-agent-wrapper" { buildInputs = with pkgs; [ pkgconfig systemd ]; inherit pinentryWrapper; } '' cc -Wall -shared -std=c11 \ + ${optionalString withSupervisor "-DSUPERVISOR_SUPPORT=1"} \ -DLIBSYSTEMD=\"${pkgs.systemd.lib}/lib/libsystemd.so\" \ -DPINENTRY_WRAPPER=\"$pinentryWrapper\" \ $(pkg-config --cflags libsystemd) -ldl \ @@ -110,7 +113,7 @@ in { (mkIf (cfg.enable && cfg.agent.enable) { systemd.user.services.gpg-agent = { description = "GnuPG Agent"; - environment.LD_PRELOAD = agentWrapper; + environment.LD_PRELOAD = agentWrapper hasSupervisorSupport; environment.GNUPGHOME = "~/${cfg.homeDir}"; serviceConfig.ExecStart = toString ([ @@ -119,8 +122,9 @@ in { (if cfg.agent.scdaemon.enable then "--scdaemon-program=${scdaemonRedirector}" else "--disable-scdaemon") - "--no-detach" - "--daemon" + (if hasSupervisorSupport + then "--supervised" + else "--no-detach --daemon") ] ++ optional cfg.agent.sshSupport "--enable-ssh-support"); serviceConfig.ExecReload = toString [ @@ -134,7 +138,9 @@ in { wantedBy = [ "sockets.target" ]; description = "Main Socket For GnuPG Agent"; listenStreams = singleton "${sockDir}/S.gpg-agent"; - socketConfig = agentSocketConfig "main"; + socketConfig = let + sockName = if hasSupervisorSupport then "std" else "main"; + in agentSocketConfig sockName; }; }) (mkIf (cfg.enable && cfg.agent.enable && cfg.agent.scdaemon.enable) { @@ -151,7 +157,7 @@ in { systemd.user.services.gnupg-scdaemon = { description = "GnuPG Smartcard Daemon"; - environment.LD_PRELOAD = agentWrapper; + environment.LD_PRELOAD = agentWrapper false; environment.GNUPGHOME = "~/${cfg.homeDir}"; serviceConfig.ExecStart = toString [ |