unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
* [bug#62612] [PATCH] home: Add gpg-agent service.
@ 2023-04-02 10:54 Ludovic Courtès
  2023-04-09  7:33 ` bug#62612: " Ludovic Courtès
  0 siblings, 1 reply; 4+ messages in thread
From: Ludovic Courtès @ 2023-04-02 10:54 UTC (permalink / raw)
  To: 62612; +Cc: Ludovic Courtès, paren, Andrew Tropin

* gnu/home/services/gnupg.scm: New file.
* gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
* doc/guix.texi (GNU Privacy Guard): New node.
(Secure Shell): Link to it.
---
 doc/guix.texi               |  93 +++++++++++++++++++++-
 gnu/home/services/gnupg.scm | 150 ++++++++++++++++++++++++++++++++++++
 gnu/local.mk                |   1 +
 3 files changed, 240 insertions(+), 4 deletions(-)
 create mode 100644 gnu/home/services/gnupg.scm

Hello!

This patch adds a service for ‘gpg-agent’, allowing you to use
it both for OpenPGP keys (its main job) and for OpenSSH keys, with
Pinentry integration.

Comments welcome!

Ludo’.

diff --git a/doc/guix.texi b/doc/guix.texi
index a58ea8f9ec..29e8d27029 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -41787,11 +41787,12 @@ services)}.
 * Power Management: Power Management Home Services.  Services for battery power.
 * Shepherd: Shepherd Home Service.  Managing User's Daemons.
 * SSH: Secure Shell.            Setting up the secure shell client.
+* GPG: GNU Privacy Guard.       Setting up GPG and related tools.
 * Desktop: Desktop Home Services.  Services for graphical environments.
 * Guix: Guix Home Services.     Services for Guix.
 * Fonts: Fonts Home Services.   Services for managing User's fonts.
 * Sound: Sound Home Services.   Dealing with audio.
-* Messaging: Messaging Home Services.   Services for managing messaging.
+* Messaging: Messaging Home Services.  Services for managing messaging.
 * Media: Media Home Services.   Services for managing media.
 @end menu
 @c In addition to that Home Services can provide
@@ -42557,15 +42558,18 @@ The @uref{https://www.openssh.com, OpenSSH package} includes a daemon,
 the @command{ssh-agent} command, that manages keys to connect to remote
 machines using the @acronym{SSH, secure shell} protocol.  With the
 @code{(gnu home services ssh-agent)} service, you can configure the
-OpenSSH ssh-agent to run upon login.
+OpenSSH ssh-agent to run upon login.  @xref{GNU Privacy Guard,
+@code{home-gpg-agent-service-type}}, for an alternative to OpenSSH's
+@command{ssh-agent}.
+
 
 Here is an example of a service and its configuration that you could add
 to the @code{services} field of your @code{home-environment}:
 
 @lisp
 (service home-ssh-agent-service-type
-  (home-ssh-agent-configuration
-   (extra-options '("-t" "1h30m"))))
+         (home-ssh-agent-configuration
+          (extra-options '("-t" "1h30m"))))
 @end lisp
 
 @defvar home-ssh-agent-service-type
@@ -42590,6 +42594,87 @@ Extra options will be passed to @command{ssh-agent}, please run
 @end table
 @end deftp
 
+@node GNU Privacy Guard
+@subsection GNU Privacy Guard
+
+@cindex GNU Privacy Guard, Home service
+@cindex GPG, Home service
+The @code{(gnu home services gnupg)} modules provides services that help
+you set up the GNU Privacy Guard, also known as GnuPG or GPG, in your
+home environment.
+
+@cindex gpg-agent, Home service
+@cindex SSH agent, with gpg-agent
+The @code{gpg-agent} service configures and sets up GPG's agent, the
+program that is responsible for managing OpenPGP private keys and,
+optionally, OpenSSH (secure shell) private keys (@pxref{Invoking
+GPG-AGENT,,, gnupg, Using the GNU Privacy Guard}).
+
+As an example, here is how you would configure @code{gpg-agent} with SSH
+support such that it uses the Emacs-based Pinentry interface when
+prompting for a passphrase:
+
+@lisp
+(service home-gpg-agent-service-type
+         (home-gpg-agent-configuration
+          (pinentry-program
+           (file-append pinentry-emacs "/bin/pinentry-emacs"))
+          (ssh-support? #t)))
+@end lisp
+
+The service reference is given below.
+
+@defvar home-gpg-agent-service-type
+This is the service type for @command{gpg-agent} (@pxref{Invoking
+GPG-AGENT,,, gnupg, Using the GNU Privacy Guard}).  Its value must be a
+@code{home-gpg-agent-configuration}, as shown below.
+@end defvar
+
+@c %start of fragment
+
+@deftp {Data Type} home-gpg-agent-configuration
+Available @code{home-gpg-agent-configuration} fields are:
+
+@table @asis
+@item @code{gnupg} (default: @code{gnupg}) (type: file-like)
+The GnuPG package to use.
+
+@item @code{pinentry-program} (type: file-like)
+Pinentry program to use.  Pinentry is a small user interface that
+@command{gpg-agent} delegates to anytime it needs user input for a
+passphrase or @acronym{PIN,personal identification number}
+(@pxref{Top,,, pinentry,Using the PIN-Entry}).
+
+@item @code{ssh-support?} (default: @code{#f}) (type: boolean)
+Whether to enable @acronym{SSH,secure shell} support.  When true,
+@command{gpg-agent} acts as a drop-in replacement for OpenSSH's
+@command{ssh-agent} program, taking care of OpenSSH secret keys and
+directing passphrase requests to the chosen Pinentry program.
+
+@item @code{default-cache-ttl} (default: @code{600}) (type: integer)
+Time a cache entry is valid, in seconds.
+
+@item @code{max-cache-ttl} (default: @code{7200}) (type: integer)
+Maximum time a cache entry is valid, in seconds.  After this time a
+cache entry will be expired even if it has been accessed recently.
+
+@item @code{default-cache-ttl-ssh} (default: @code{1800}) (type: integer)
+Time a cache entry for SSH keys is valid, in seconds.
+
+@item @code{max-cache-ttl-ssh} (default: @code{7200}) (type: integer)
+Maximum time a cache entry for SSH keys is valid, in seconds.
+
+@item @code{extra-content} (default: @code{""}) (type: raw-configuration-string)
+Raw content to add to the end of @file{~/.gnupg/gpg-agent.conf}.
+
+@end table
+
+@end deftp
+
+
+@c %end of fragment
+
+
 @node Desktop Home Services
 @subsection Desktop Home Services
 
diff --git a/gnu/home/services/gnupg.scm b/gnu/home/services/gnupg.scm
new file mode 100644
index 0000000000..7e9e02a3cc
--- /dev/null
+++ b/gnu/home/services/gnupg.scm
@@ -0,0 +1,150 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2023 Ludovic Courtès <ludo@gnu.org>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix is distributed in the hope that it will be useful, but
+;;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu home services gnupg)
+  #:use-module (guix gexp)
+  #:use-module ((guix records) #:select (match-record))
+  #:use-module (gnu services)
+  #:use-module (gnu services configuration)
+  #:use-module (gnu home services)
+  #:use-module (gnu home services shepherd)
+  #:autoload   (gnu packages gnupg) (gnupg pinentry)
+  #:export (home-gpg-agent-configuration
+            home-gpg-agent-configuration?
+            home-gpg-agent-configuration-gnupg
+            home-gpg-agent-configuration-pinentry-program
+            home-gpg-agent-configuration-ssh-support?
+            home-gpg-agent-configuration-default-cache-ttl
+            home-gpg-agent-configuration-max-cache-ttl
+            home-gpg-agent-configuration-max-cache-ttl-ssh
+            home-gpg-agent-configuration-extra-content
+
+            home-gpg-agent-service-type))
+
+(define raw-configuration-string? string?)
+
+;; Configuration of 'gpg-agent'.
+(define-configuration/no-serialization home-gpg-agent-configuration
+  (gnupg
+   (file-like gnupg)
+   "The GnuPG package to use.")
+  (pinentry-program
+   (file-like (file-append pinentry "/bin/pinentry-curses"))
+   "Pinentry program to use.  Pinentry is a small user interface that
+@command{gpg-agent} delegates to anytime it needs user input for a passphrase
+or @acronym{PIN, personal identification number} (@pxref{Top,,, pinentry,
+Using the PIN-Entry}).")
+  (ssh-support?
+   (boolean #f)
+   "Whether to enable @acronym{SSH, secure shell} support.  When true,
+@command{gpg-agent} acts as a drop-in replacement for OpenSSH's
+@command{ssh-agent} program, taking care of OpenSSH secret keys and directing
+passphrase requests to the chosen Pinentry program.")
+  (default-cache-ttl
+    (integer 600)
+    "Time a cache entry is valid, in seconds.")
+  (max-cache-ttl
+   (integer 7200)
+   "Maximum time a cache entry is valid, in seconds.  After this time a cache
+entry will be expired even if it has been accessed recently.")
+  (default-cache-ttl-ssh
+    (integer 1800)
+    "Time a cache entry for SSH keys is valid, in seconds.")
+  (max-cache-ttl-ssh
+   (integer 7200)
+   "Maximum time a cache entry for SSH keys is valid, in seconds.")
+  (extra-content
+   (raw-configuration-string "")
+   "Raw content to add to the end of @file{~/.gnupg/gpg-agent.conf}."))
+
+(define (home-gpg-agent-configuration-file config)
+  "Return the @file{gpg-agent.conf} file for @var{config}."
+  (match-record config <home-gpg-agent-configuration>
+    (pinentry-program default-cache-ttl max-cache-ttl
+                      default-cache-ttl-ssh max-cache-ttl-ssh
+                      extra-content)
+    (mixed-text-file "gpg-agent.conf"
+                     "pinentry-program " pinentry-program "\n"
+                     "default-cache-ttl "
+                     (number->string default-cache-ttl) "\n"
+                     "max-cache-ttl "
+                     (number->string max-cache-ttl) "\n"
+                     "default-cache-ttl-ssh "
+                     (number->string default-cache-ttl-ssh) "\n"
+                     "max-cache-ttl-ssh "
+                     (number->string max-cache-ttl-ssh) "\n"
+                     extra-content)))
+
+(define (home-gpg-agent-shepherd-services config)
+  "Return the possibly-empty list of Shepherd services for @var{config}."
+  (match-record config <home-gpg-agent-configuration>
+    (gnupg ssh-support?)
+    ;; 'gpg-agent' is started on demand by GnuPG's programs, but it has to be
+    ;; started explicitly when OpenSSH support is enabled (info "(gnupg) Agent
+    ;; Options").
+    (if ssh-support?
+        (let ((endpoint (lambda (name socket)
+                          #~(endpoint
+                             (make-socket-address
+                              AF_UNIX
+                              (string-append %user-runtime-dir
+                                             "/gnupg/" #$socket))
+                             #:name #$name
+                             #:socket-directory-permissions #o700))))
+          (list (shepherd-service
+                 (provision '(gpg-agent ssh-agent))
+                 (modules '((shepherd support)))  ;for '%user-runtime-dir'
+                 (start #~(make-systemd-constructor
+                           (list #$(file-append gnupg "/bin/gpg-agent")
+                                 "--supervised" "--enable-ssh-support")
+                           (list #$(endpoint "ssh" "S.gpg-agent.ssh")
+                                 #$(endpoint "browser" "S.gpg-agent.browser")
+                                 #$(endpoint "extra" "S.gpg-agent.extra")
+                                 ;; #$(endpoint "scdaemon" "S.scdaemon")
+                                 #$(endpoint "std" "S.gpg-agent"))))
+                 (stop #~(make-systemd-destructor))
+                 (documentation "Start 'gpg-agent', the GnuPG passphrase
+agent, with support for handling OpenSSH material."))))
+        '())))
+
+(define (home-gpg-agent-files config)
+  `((".gnupg/gpg-agent.conf" ,(home-gpg-agent-configuration-file config))))
+
+(define (home-gpg-agent-environment-variables config)
+  "Return GnuPG environment variables needed for @var{config}."
+  (if (home-gpg-agent-configuration-ssh-support? config)
+      `(("SSH_AUTH_SOCK"
+         . "$XDG_RUNTIME_DIR/gnupg/S.gpg-agent.ssh"))
+      '()))
+
+(define home-gpg-agent-service-type
+  (service-type
+   (name 'home-gpg-agent)
+   (extensions
+    (list (service-extension home-files-service-type
+                             home-gpg-agent-files)
+          (service-extension home-shepherd-service-type
+                             home-gpg-agent-shepherd-services)
+          (service-extension home-environment-variables-service-type
+                             home-gpg-agent-environment-variables)))
+   (default-value (home-gpg-agent-configuration))
+   (description
+    "Configure GnuPG's agent, @command{gpg-agent}, which is responsible for
+managing OpenPGP and optionally SSH private keys.  When SSH support is
+enabled, @command{gpg-agent} acts as a drop-in replacement for OpenSSH's
+@command{ssh-agent}.")))
diff --git a/gnu/local.mk b/gnu/local.mk
index 3a93ab50dd..77243b7c2f 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -91,6 +91,7 @@ GNU_SYSTEM_MODULES =				\
   %D%/home/services/desktop.scm			\
   %D%/home/services/symlink-manager.scm		\
   %D%/home/services/fontutils.scm		\
+  %D%/home/services/gnupg.scm			\
   %D%/home/services/guix.scm			\
   %D%/home/services/media.scm			\
   %D%/home/services/messaging.scm		\

base-commit: e7558d16479158f893bca7c295986c08c151caa9
-- 
2.39.2





^ permalink raw reply related	[flat|nested] 4+ messages in thread

* bug#62612: [PATCH] home: Add gpg-agent service.
  2023-04-02 10:54 [bug#62612] [PATCH] home: Add gpg-agent service Ludovic Courtès
@ 2023-04-09  7:33 ` Ludovic Courtès
  2023-04-09 10:00   ` [bug#62612] " ( via Guix-patches via
  0 siblings, 1 reply; 4+ messages in thread
From: Ludovic Courtès @ 2023-04-09  7:33 UTC (permalink / raw)
  To: 62612-done; +Cc: paren, Andrew Tropin

Ludovic Courtès <ludo@gnu.org> skribis:

> * gnu/home/services/gnupg.scm: New file.
> * gnu/local.mk (GNU_SYSTEM_MODULES): Add it.
> * doc/guix.texi (GNU Privacy Guard): New node.
> (Secure Shell): Link to it.

I went ahead and pushed it as 6420015e6d3300e7a73da9a8253428d8386954d6.

Ludo’.




^ permalink raw reply	[flat|nested] 4+ messages in thread

* [bug#62612] [PATCH] home: Add gpg-agent service.
  2023-04-09  7:33 ` bug#62612: " Ludovic Courtès
@ 2023-04-09 10:00   ` ( via Guix-patches via
  2023-04-20 10:19     ` Ludovic Courtès
  0 siblings, 1 reply; 4+ messages in thread
From: ( via Guix-patches via @ 2023-04-09 10:00 UTC (permalink / raw)
  To: Ludovic Courtès, 62612-done; +Cc: Andrew Tropin

[-- Attachment #1: Type: text/plain, Size: 637 bytes --]

On Sun Apr 9, 2023 at 8:33 AM BST, Ludovic Courtès wrote:
> I went ahead and pushed it as 6420015e6d3300e7a73da9a8253428d8386954d6.

YES!  This will definitely be useful.  Thanks!  (Though could you consider
adding EMACS-SUPPORT? {'allow-emacs-pinentry'} and ALLOW-LOOPBACK?
{'allow-loopback-pinentry'} options to the record?  It's no big deal, since
there's an extra options section, but it'd be nice to fully integrate support
for permitting EPG's pinentry to do its thing.)

Side note: I didn't know about %USER-RUNTIME-DIR; i'd better look in the
Shepherd sources sometime to see what other gems they hide :)

    -- (

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [bug#62612] [PATCH] home: Add gpg-agent service.
  2023-04-09 10:00   ` [bug#62612] " ( via Guix-patches via
@ 2023-04-20 10:19     ` Ludovic Courtès
  0 siblings, 0 replies; 4+ messages in thread
From: Ludovic Courtès @ 2023-04-20 10:19 UTC (permalink / raw)
  To: (; +Cc: 62612-done, Andrew Tropin

Hi,

"(" <paren@disroot.org> skribis:

> On Sun Apr 9, 2023 at 8:33 AM BST, Ludovic Courtès wrote:
>> I went ahead and pushed it as 6420015e6d3300e7a73da9a8253428d8386954d6.
>
> YES!  This will definitely be useful.  Thanks!  (Though could you consider
> adding EMACS-SUPPORT? {'allow-emacs-pinentry'} and ALLOW-LOOPBACK?
> {'allow-loopback-pinentry'} options to the record?  It's no big deal, since
> there's an extra options section, but it'd be nice to fully integrate support
> for permitting EPG's pinentry to do its thing.)

What would these options do?  Well maybe send a patch and I’ll learn.
:-)

(For me, setting ‘pinentry-program’ was enough to get Emacs support.)

> Side note: I didn't know about %USER-RUNTIME-DIR; i'd better look in the
> Shepherd sources sometime to see what other gems they hide :)

Heheh.

Thanks for your feedback,
Ludo’.




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2023-04-20 10:20 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-04-02 10:54 [bug#62612] [PATCH] home: Add gpg-agent service Ludovic Courtès
2023-04-09  7:33 ` bug#62612: " Ludovic Courtès
2023-04-09 10:00   ` [bug#62612] " ( via Guix-patches via
2023-04-20 10:19     ` Ludovic Courtès

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).