fail2ban: update whitelist
[sourcephile-nix.git] / shell / modules / tools / security / gnupg.nix
index 39d968f9cf0c10e8e6d978bfe0b7a688a1e66300..f096017e142f1afaf30628d511a476b9809992c5 100644 (file)
@@ -14,13 +14,14 @@ let
    , expire ? "-"
    , passPath
    , subKeys ? {}
+   , postRun ? ""
    , ...
    }@primary:
     ''
     info "generateKey uid=\"${uid}\""
     if ! ${gpg-with-home}/bin/gpg-with-home --list-secret-keys -- "=${uid}" >/dev/null 2>/dev/null
      then
-      ${pkgs.pass}/bin/pass "${passPath}" |
+      ${if passPath != "" then "${pkgs.pass}/bin/pass '${passPath}'" else "cat /dev/null"} |
       ${gpg-with-home}/bin/gpg-with-home \
         --batch --pinentry-mode loopback --passphrase-fd 0 \
         --quick-generate-key "${uid}" "${algo}" "${unwords usage}" "${expire}"
@@ -35,6 +36,7 @@ let
     ''
     + unlines (map (generateSubKey primary) subKeys)
     + generateBackupKey "$fpr" primary
+    + postRun
     ;
   generateSubKey =
    primary:
@@ -47,7 +49,7 @@ let
     info "  generateSubKey usage=[${unwords usage}]"
     if ! printf '%s\n' "$caps" | ${pkgs.gnugrep}/bin/grep -Fqx "${lettersKeyUsage usage}"
      then
-      ${pkgs.pass}/bin/pass "${primary.passPath}" |
+      ${if primary.passPath != "" then "${pkgs.pass}/bin/pass '${primary.passPath}'" else "cat /dev/null"} |
       ${gpg-with-home}/bin/gpg-with-home \
         --batch --pinentry-mode loopback --passphrase-fd 0 \
         --quick-add-key "$fpr" "${algo}" "${unwords usage}" "${expire}"
@@ -74,9 +76,10 @@ let
      fi
     '' + (if backupRecipients == [""] then
     ''
-    if ! test -s "${gnupg.gnupgHome}/backup/${uid}/${fpr}.revoke.asc"
+    if ! test -s "${gnupg.gnupgHome}/backup/${uid}/${fpr}.revoke.asc" &&
+     ${gpg-with-home}/bin/gpg-with-home --list-secret-keys "${fpr}" | grep -q "sec "
      then
-      ${pkgs.pass}/bin/pass "${passPath}" |
+      ${if passPath != "" then "${pkgs.pass}/bin/pass '${passPath}'" else "cat /dev/null"} |
       ${gpg-with-home}/bin/gpg-with-home \
         --pinentry-mode loopback --passphrase-fd 0 \
         --armor --yes --output "${gnupg.gnupgHome}/backup/${uid}/${fpr}.revoke.asc" \
@@ -84,7 +87,7 @@ let
      fi
     if ! test -s "${gnupg.gnupgHome}/backup/${uid}/${fpr}.privkey.sec"
      then
-      ${pkgs.pass}/bin/pass "${passPath}" |
+      ${if passPath != "" then "${pkgs.pass}/bin/pass '${passPath}'" else "cat /dev/null"} |
       ${gpg-with-home}/bin/gpg-with-home \
         --batch --pinentry-mode loopback --passphrase-fd 0 \
         --armor --yes --output "${gnupg.gnupgHome}/backup/${uid}/${fpr}.privkey.sec" \
@@ -93,7 +96,7 @@ let
      fi
     if ! test -s "${gnupg.gnupgHome}/backup/${uid}/${fpr}.subkeys.sec"
      then
-      ${pkgs.pass}/bin/pass "${passPath}" |
+      ${if passPath != "" then "${pkgs.pass}/bin/pass '${passPath}'" else "cat /dev/null"} |
       ${gpg-with-home}/bin/gpg-with-home \
         --batch --pinentry-mode loopback --passphrase-fd 0 \
         --armor --yes --output "${gnupg.gnupgHome}/backup/${uid}/${fpr}.subkeys.sec" \
@@ -103,7 +106,7 @@ let
     '' else ''
     if ! test -s "${gnupg.gnupgHome}/backup/${uid}/${fpr}.revoke.asc.gpg"
      then
-      ${pkgs.pass}/bin/pass "${passPath}" |
+      ${if passPath != "" then "${pkgs.pass}/bin/pass '${passPath}'" else "cat /dev/null"} |
       ${gpg-with-home}/bin/gpg-with-home \
         --pinentry-mode loopback --passphrase-fd 0 \
         --armor --gen-revoke "${fpr}" |
@@ -112,7 +115,7 @@ let
      fi
     if ! test -s "${gnupg.gnupgHome}/backup/${uid}/${fpr}.privkey.sec.gpg"
      then
-      ${pkgs.pass}/bin/pass "${passPath}" |
+      ${if passPath != "" then "${pkgs.pass}/bin/pass '${passPath}'" else "cat /dev/null"} |
       ${gpg-with-home}/bin/gpg-with-home \
         --batch --pinentry-mode loopback --passphrase-fd 0 \
         --armor --export-options export-backup \
@@ -122,7 +125,7 @@ let
      fi
     if ! test -s "${gnupg.gnupgHome}/backup/${uid}/${fpr}.subkeys.sec.gpg"
      then
-      ${pkgs.pass}/bin/pass "${passPath}" |
+      ${if passPath != "" then "${pkgs.pass}/bin/pass '${passPath}'" else "cat /dev/null"} |
       ${gpg-with-home}/bin/gpg-with-home \
         --batch --pinentry-mode loopback --passphrase-fd 0 \
         --armor --export-options export-backup \
@@ -202,10 +205,6 @@ let
     set -eu
     set -o pipefail
     ${info}
-    ${pkgs.coreutils}/bin/install -dm0700 -D ${gnupg.gnupgHome}
-    ${pkgs.coreutils}/bin/ln -snf ${gnupg.gpgConf}      ${gnupg.gnupgHome}/gpg.conf
-    ${pkgs.coreutils}/bin/ln -snf ${gnupg.gpgAgentConf} ${gnupg.gnupgHome}/gpg-agent.conf
-    ${pkgs.coreutils}/bin/ln -snf ${gnupg.dirmngrConf}  ${gnupg.gnupgHome}/dirmngr.conf
     '' +
     generateKeys gnupg.keys
   );
@@ -302,13 +301,12 @@ options.gnupg = {
           backupRecipients = ["@john@doe.pro"];
         };
       };
-    type = types.attrsOf (types.submodule ({uid, ...}: {
-      #config.uid = lib.mkDefault uid;
+    type = types.attrsOf (types.submodule ({name, ...}: {
       options = {
         uid = lib.mkOption {
           type        = types.str;
           example     = "John Doe <john.doe@example.coop>";
-          default     = uid;
+          default     = name;
           description = ''
             User ID.
           '';
@@ -323,7 +321,7 @@ options.gnupg = {
         };
         expire = lib.mkOption {
           type        = types.str;
-          default     = "1y";
+          default     = "0";
           example     = "1y";
           description = ''
             Expiration timeout.
@@ -357,7 +355,7 @@ options.gnupg = {
               };
               expire = lib.mkOption {
                 type        = types.str;
-                default     = "1y";
+                default     = "0";
                 example     = "1y";
                 description = ''
                   Expiration timeout.
@@ -382,6 +380,13 @@ options.gnupg = {
             Backup keys used to encrypt the a backup copy of the secret keys.
           '';
         };
+        postRun = lib.mkOption {
+          type = types.lines;
+          default = "";
+          description = ''
+            Shell code to run after the key has been generated or tested to exist.
+          '';
+        };
       };
     }));
   };
@@ -392,7 +397,7 @@ options.gnupg = {
       allow-ocsp
       hkp-cacert ${gnupg.keyserverPEM}
       keyserver hkps://keys.mayfirst.org
-      use-tor
+      #use-tor
       #log-file ${gnupg.gnupgHome}/dirmngr.log
       #standard-resolver
     '';
@@ -411,14 +416,32 @@ options.gnupg = {
   gpgAgentConf = lib.mkOption {
     type = types.lines;
     apply = s: pkgs.writeText "gpg-agent.conf" s;
-    default = ''
+    default =
+      let pinentry = pkgs.writeShellScript "pinentry" ''
+        #!${pkgs.runtimeShell}
+        # choose pinentry depending on PINENTRY_USER_DATA
+        # this *only works* with gpg2
+        # see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=802020
+        case "''${PINENTRY_USER_DATA:-tty}" in
+        curses) exec ${pkgs.pinentry.curses}/bin/pinentry-curses "$@";;
+        #emacs)  exec ''${pkgs.pinentry.emacs}/bin/pinentry-emacs "$@";;
+        #gnome3) exec ''${pkgs.pinentry.gnome3}/bin/pinentry-gnome3 "$@";;
+        gtk-2)  exec ${pkgs.pinentry.gtk2}/bin/pinentry-gtk-2 "$@";;
+        none)   exit 1;; # do not ask for passphrase
+        #qt)     exec ''${pkgs.pinentry.qt}/bin/pinentry-qt "$@";;
+        tty)    exec ${pkgs.pinentry.tty}/bin/pinentry-tty "$@";;
+        esac
+      '';
+    in ''
+      allow-loopback-pinentry
       allow-preset-passphrase
       default-cache-ttl 17200
       default-cache-ttl-ssh 17200
       enable-ssh-support
       max-cache-ttl 17200
       max-cache-ttl-ssh 17200
-      pinentry-program ${pkgs.pinentry}/bin/pinentry
+      no-allow-external-cache
+      pinentry-program ${pinentry}
     '';
     description = ''
       GnuPG's gpg-agent.conf content.
@@ -472,6 +495,10 @@ config = lib.mkIf gnupg.enable {
   ];
   nix-shell.shellHook = ''
     # gnupg
+    ${pkgs.coreutils}/bin/install -dm0700 -D ${gnupg.gnupgHome}
+    ${pkgs.coreutils}/bin/ln -snf ${gnupg.gpgConf}      ${gnupg.gnupgHome}/gpg.conf
+    ${pkgs.coreutils}/bin/ln -snf ${gnupg.gpgAgentConf} ${gnupg.gnupgHome}/gpg-agent.conf
+    ${pkgs.coreutils}/bin/ln -snf ${gnupg.dirmngrConf}  ${gnupg.gnupgHome}/dirmngr.conf
     export GNUPGHOME=${gnupg.gnupgHome}
     install -dm700 "$GNUPGHOME"
     export GPG_TTY=$(${pkgs.coreutils}/bin/tty)