108 lines
3.3 KiB
Nix
108 lines
3.3 KiB
Nix
|
{ config, pkgs, lib, ... }:
|
||
|
let
|
||
|
cfg = config.programs.gpg;
|
||
|
in
|
||
|
{
|
||
|
# TODO: Create proper descriptions
|
||
|
options = {
|
||
|
programs.gpg.fetch-keys = {
|
||
|
enable = lib.mkEnableOption "auto fetching of gpg keys by fingerprint";
|
||
|
keys = lib.mkOption {
|
||
|
description = "";
|
||
|
default = { };
|
||
|
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
|
||
|
options = {
|
||
|
id = lib.mkOption {
|
||
|
description = "";
|
||
|
default = name;
|
||
|
example = "";
|
||
|
type = lib.types.str;
|
||
|
};
|
||
|
|
||
|
keyserver = lib.mkOption {
|
||
|
description = "If marked as null, use config";
|
||
|
default = null;
|
||
|
example = "hkps://keys.openpgp.org";
|
||
|
type = with lib.types; nullOr str;
|
||
|
apply = v: if v == null then "@NULL@" else v;
|
||
|
};
|
||
|
|
||
|
trust = lib.mkOption {
|
||
|
description = "If marked as null, it's mutable";
|
||
|
default = null;
|
||
|
example = 4;
|
||
|
type = with lib.types; nullOr (ints.between 1 5);
|
||
|
};
|
||
|
};
|
||
|
}));
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
|
||
|
config = {
|
||
|
# TODO: Fix the module so that this unit runs whenever something changes
|
||
|
systemd.user.services.gpg-fetch-keys = let
|
||
|
fetchKeysApplication = let
|
||
|
recvKeysByKeyserver = lib.pipe cfg.fetch-keys.keys [
|
||
|
lib.attrValues
|
||
|
(lib.foldl (acc: key: acc // {
|
||
|
${key.keyserver} = (acc.${key.keyserver} or []) ++ [ key.id ];
|
||
|
}) { })
|
||
|
(lib.mapAttrsToList (keyserver: ids:
|
||
|
if keyserver == "@NULL@"
|
||
|
then "gpg --recv-keys ${lib.escapeShellArgs ids}"
|
||
|
else "gpg --keyserver ${lib.escapeShellArg keyserver} --recv-keys ${lib.escapeShellArgs ids}"))
|
||
|
(lib.concatStringsSep "\n")
|
||
|
];
|
||
|
|
||
|
# Taken from modules/programs/gpg.nix
|
||
|
# Slightly modified in order not to read files
|
||
|
importTrustBashFunctions = let
|
||
|
gpg = "${cfg.package}/bin/gpg";
|
||
|
in ''
|
||
|
function importTrust() {
|
||
|
local keyId trust
|
||
|
keyId="$1"
|
||
|
trust="$2"
|
||
|
{ echo trust; echo "$trust"; (( trust == 5 )) && echo y; echo quit; } \
|
||
|
| ${gpg} --no-tty --command-fd 0 --edit-key "$keyId"
|
||
|
}
|
||
|
'';
|
||
|
|
||
|
trustKeys = lib.pipe cfg.fetch-keys.keys [
|
||
|
lib.attrValues
|
||
|
(lib.filter (key: key.trust != null))
|
||
|
(map ({ id, trust, ... }: "importTrust '${id}' '${toString trust}'"))
|
||
|
(lib.concatStringsSep "\n")
|
||
|
];
|
||
|
in pkgs.writeShellApplication {
|
||
|
name = "fetch-gpg-keys";
|
||
|
runtimeInputs = [ cfg.package ];
|
||
|
text = lib.concatStringsSep "\n" [
|
||
|
recvKeysByKeyserver
|
||
|
importTrustBashFunctions
|
||
|
trustKeys
|
||
|
];
|
||
|
};
|
||
|
in lib.mkIf cfg.fetch-keys.enable {
|
||
|
Unit = {
|
||
|
Description = "Fetch declaratively listed gpg keys";
|
||
|
Documentation = [ "man:gpg(1)" ];
|
||
|
X-Restart-Triggers = [ "${fetchKeysApplication}" ];
|
||
|
X-SwitchMethod = "restart";
|
||
|
};
|
||
|
|
||
|
Service = {
|
||
|
Type = "oneshot";
|
||
|
CPUSchedulingPolicy = "idle";
|
||
|
IOSchedulingClass = "idle";
|
||
|
ExecStart = "${lib.getExe fetchKeysApplication}";
|
||
|
|
||
|
Environment = [
|
||
|
"GNUPGHOME=${cfg.homedir}"
|
||
|
];
|
||
|
};
|
||
|
};
|
||
|
};
|
||
|
}
|