diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index f361163ca631..f362efbd4e51 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -811,6 +811,7 @@ ./services/security/torsocks.nix ./services/security/usbguard.nix ./services/security/vault.nix + ./services/security/yubikey-agent.nix ./services/system/cloud-init.nix ./services/system/dbus.nix ./services/system/earlyoom.nix diff --git a/nixos/modules/programs/gnupg.nix b/nixos/modules/programs/gnupg.nix index 7a3cb588ee71..ce8799b21d69 100644 --- a/nixos/modules/programs/gnupg.nix +++ b/nixos/modules/programs/gnupg.nix @@ -70,6 +70,7 @@ in agent.pinentryFlavor = mkOption { type = types.nullOr (types.enum pkgs.pinentry.flavors); example = "gnome3"; + default = defaultPinentryFlavor; description = '' Which pinentry interface to use. If not null, the path to the pinentry binary will be passed to gpg-agent via commandline and @@ -91,8 +92,6 @@ in }; config = mkIf cfg.agent.enable { - programs.gnupg.agent.pinentryFlavor = mkDefault defaultPinentryFlavor; - # This overrides the systemd user unit shipped with the gnupg package systemd.user.services.gpg-agent = mkIf (cfg.agent.pinentryFlavor != null) { serviceConfig.ExecStart = [ "" '' diff --git a/nixos/modules/services/security/yubikey-agent.nix b/nixos/modules/services/security/yubikey-agent.nix new file mode 100644 index 000000000000..ac5d7054b2bb --- /dev/null +++ b/nixos/modules/services/security/yubikey-agent.nix @@ -0,0 +1,61 @@ +# Global configuration for yubikey-agent. + +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.yubikey-agent; + + # reuse the pinentryFlavor option from the gnupg module + pinentryFlavor = config.programs.gnupg.agent.pinentryFlavor; +in +{ + ###### interface + + meta.maintainers = with maintainers; [ philandstuff rawkode ]; + + options = { + + services.yubikey-agent = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to start yubikey-agent when you log in. Also sets + SSH_AUTH_SOCK to point at yubikey-agent. + + Note that yubikey-agent will use whatever pinentry is + specified in programs.gnupg.agent.pinentryFlavor. + ''; + }; + + package = mkOption { + type = types.package; + default = pkgs.yubikey-agent; + defaultText = "pkgs.yubikey-agent"; + description = '' + The package used for the yubikey-agent daemon. + ''; + }; + }; + }; + + config = { + environment.systemPackages = [ cfg.package ]; + systemd.packages = [ cfg.package ]; + + # This overrides the systemd user unit shipped with the + # yubikey-agent package + systemd.user.services.yubikey-agent = mkIf (pinentryFlavor != null) { + path = [ pkgs.pinentry.${pinentryFlavor} ]; + }; + + environment.extraInit = optionalString cfg.enable + '' + if [ -z "$SSH_AUTH_SOCK" -a -n "$XDG_RUNTIME_DIR" ]; then + export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/yubikey-agent/yubikey-agent.sock" + fi + ''; + }; +} diff --git a/pkgs/tools/security/yubikey-agent/default.nix b/pkgs/tools/security/yubikey-agent/default.nix new file mode 100644 index 000000000000..c3b2329d472d --- /dev/null +++ b/pkgs/tools/security/yubikey-agent/default.nix @@ -0,0 +1,54 @@ +{ stdenv, lib, fetchFromGitHub, buildGoModule, libnotify, makeWrapper, pcsclite, pinentry_mac, pkgconfig, darwin }: + +buildGoModule rec { + pname = "yubikey-agent"; + version = "0.1.3"; + + src = fetchFromGitHub { + owner = "FiloSottile"; + repo = pname; + rev = "v${version}"; + sha256 = "07gix5wrakn4z846zhvl66lzwx58djrfnn6m8v7vc69l9jr3kihr"; + }; + + buildInputs = + lib.optional stdenv.isLinux (lib.getDev pcsclite) + ++ lib.optional stdenv.isDarwin (darwin.apple_sdk.frameworks.PCSC); + + nativeBuildInputs = [ makeWrapper pkgconfig ]; + + # pull in go-piv/piv-go#75 + # once go-piv/piv-go#75 is merged and released, we should + # use the released version (and push upstream to do the same) + patches = [ ./use-piv-go-75.patch ]; + postPatch = lib.optionalString stdenv.isLinux '' + substituteInPlace main.go --replace 'notify-send' ${libnotify}/bin/notify-send + ''; + + vendorSha256 = "1x7934p6522i0yyv08xzb4134d0kr5x6igsrp26vh79d8fndbywr"; + + subPackages = [ "." ]; + + # On macOS, there isn't a choice of pinentry program, so let's + # ensure the nixpkgs-provided one is available + postInstall = lib.optionalString stdenv.isDarwin '' + wrapProgram $out/bin/yubikey-agent --suffix PATH : $(dirname ${pinentry_mac}/${pinentry_mac.binaryPath}) + '' + # Note: in the next release, upstream provides + # contrib/systemd/user/yubikey-agent.service, which we should use + # instead + # See https://github.com/FiloSottile/yubikey-agent/pull/43 + + lib.optionalString stdenv.isLinux '' + mkdir -p $out/lib/systemd/user + substitute ${./yubikey-agent.service} $out/lib/systemd/user/yubikey-agent.service \ + --replace 'ExecStart=yubikey-agent' "ExecStart=$out/bin/yubikey-agent" + ''; + + meta = with lib; { + description = "A seamless ssh-agent for YubiKeys"; + license = licenses.bsd3; + homepage = "https://filippo.io/yubikey-agent"; + maintainers = with lib.maintainers; [ philandstuff rawkode ]; + platforms = platforms.darwin ++ platforms.linux; + }; +} diff --git a/pkgs/tools/security/yubikey-agent/use-piv-go-75.patch b/pkgs/tools/security/yubikey-agent/use-piv-go-75.patch new file mode 100644 index 000000000000..cd7337292229 --- /dev/null +++ b/pkgs/tools/security/yubikey-agent/use-piv-go-75.patch @@ -0,0 +1,24 @@ +From 56a465d463273b2a2a24cf668c4c33938b198b16 Mon Sep 17 00:00:00 2001 +From: Philip Potter +Date: Sun, 12 Jul 2020 16:54:57 +0100 +Subject: [PATCH] Pull in go-piv/piv-go#75 + +--- + go.mod | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/go.mod b/go.mod +index d4d13c8..e24d53d 100644 +--- a/go.mod ++++ b/go.mod +@@ -2,6 +2,7 @@ module filippo.io/yubikey-agent + + go 1.14 + ++replace github.com/go-piv/piv-go => github.com/rawkode/piv-go v1.5.1-0.20200711221619-a4158f9b8204 + require ( + github.com/go-piv/piv-go v1.5.1-0.20200523071327-a3e5767e8b72 + github.com/gopasspw/gopass v1.9.1 +-- +2.27.0 + diff --git a/pkgs/tools/security/yubikey-agent/yubikey-agent.service b/pkgs/tools/security/yubikey-agent/yubikey-agent.service new file mode 100644 index 000000000000..7a91f902544e --- /dev/null +++ b/pkgs/tools/security/yubikey-agent/yubikey-agent.service @@ -0,0 +1,35 @@ +[Unit] +Description=Seamless ssh-agent for YubiKeys +Documentation=https://filippo.io/yubikey-agent + +[Service] +ExecStart=yubikey-agent -l %t/yubikey-agent/yubikey-agent.sock +ExecReload=/bin/kill -HUP $MAINPID +ProtectSystem=strict +ProtectKernelLogs=yes +ProtectKernelModules=yes +ProtectKernelTunables=yes +ProtectControlGroups=yes +ProtectClock=yes +ProtectHostname=yes +PrivateTmp=yes +PrivateDevices=yes +PrivateUsers=yes +IPAddressDeny=any +RestrictAddressFamilies=AF_UNIX +RestrictNamespaces=yes +RestrictRealtime=yes +RestrictSUIDSGID=yes +LockPersonality=yes +CapabilityBoundingSet= +SystemCallFilter=@system-service +SystemCallFilter=~@privileged @resources +SystemCallErrorNumber=EPERM +SystemCallArchitectures=native +NoNewPrivileges=yes +KeyringMode=private +UMask=0177 +RuntimeDirectory=yubikey-agent + +[Install] +WantedBy=default.target diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index f75b3a41a2e6..20334c820f3d 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -15435,6 +15435,8 @@ in yubikey-personalization-gui = libsForQt5.callPackage ../tools/misc/yubikey-personalization-gui { }; + yubikey-agent = callPackage ../tools/security/yubikey-agent { }; + zchunk = callPackage ../development/libraries/zchunk { }; zeitgeist = callPackage ../development/libraries/zeitgeist { };