forked from
lass.pds.lassul.us/superconfig
This repository has no description
4.1 kB
124 lines
1{ self, ... }:
2{
3 perSystem =
4 {
5 pkgs,
6 system,
7 ...
8 }:
9 {
10 packages.pass = self.wrapLib.makeWrapper {
11 pkgs = pkgs;
12 package = pkgs.passage;
13 runtimeInputs = [
14 pkgs.age-plugin-fido2-hmac
15 pkgs.age-plugin-yubikey
16 pkgs.age-plugin-tpm
17 self.packages.${system}.pass-otp
18 self.packages.${system}.age-detect
19 self.packages.${system}.pinentry-rofi-age
20 ]
21 ++ (pkgs.lib.optionals pkgs.stdenv.isDarwin [
22 pkgs.age-plugin-se
23 ])
24 ++ (pkgs.lib.optionals (!pkgs.stdenv.isDarwin) [
25 # Dummy age-plugin-se for Linux (encryption only, no Secure Enclave hardware)
26 (pkgs.writeShellScriptBin "age-plugin-se" ''
27 exec env PYTHONUNBUFFERED=1 ${
28 pkgs.python3.withPackages (ps: [ ps.cryptography ])
29 }/bin/python3 ${./age-plugin-se-dummy.py} "$@"
30 '')
31 ]);
32 aliases = [ "pass" ];
33 wrapper =
34 {
35 exePath,
36 envString,
37 preHook,
38 ...
39 }:
40 ''
41 set -x
42 ${envString}
43 ${preHook}
44
45 # Check if bulk key file should be used for decryption
46 if [[ -n "''${PASS_BULK_KEY_FILE:-}" ]]; then
47 if [[ ! -f "$PASS_BULK_KEY_FILE" ]] || [[ ! -s "$PASS_BULK_KEY_FILE" ]]; then
48 mkdir -p "$(dirname "$PASS_BULK_KEY_FILE")"
49 ${exePath} show bulk-operations/age-key > "$PASS_BULK_KEY_FILE" 2>/dev/null || true
50 fi
51 fi
52
53 # Set up identities for age decryption
54 if [[ -n "''${PASS_BULK_KEY_FILE:-}" ]] && [[ -f "$PASS_BULK_KEY_FILE" ]] && [[ -s "$PASS_BULK_KEY_FILE" ]]; then
55 # Use bulk key if available
56 export PASSAGE_IDENTITIES_FILE="$PASS_BULK_KEY_FILE"
57 else
58 # Detect available age keys
59 export AGE_DETECT_KEYS_DIR="${self}/keys"
60 eval "$(age-detect)"
61
62 # Set up identity file if detected
63 if [[ -n "''${IDENTITY_FILE:-}" ]]; then
64 export PASSAGE_IDENTITIES_FILE="$IDENTITY_FILE"
65 trap 'rm -f "$IDENTITY_FILE"' EXIT
66 fi
67 fi
68
69 maybe_set_tpm_pin() {
70 local target="''${1:-<stdin>}"
71 if [[ "''${KEY_TYPE:-}" != "tpm" ]]; then
72 return 0
73 fi
74 if [[ -n "''${AGE_TPM_PIN:-}" ]]; then
75 return 0
76 fi
77 AGE_TPM_PIN="$(${self.packages.${system}.pinentry-rofi-age}/bin/pinentry-rofi-age "$target")"
78 export AGE_TPM_PIN
79 }
80
81 decrypt_target=""
82 if [[ "''${1:-}" == "show" ]]; then
83 decrypt_target="''${2:-}"
84 elif [[ -n "''${1:-}" ]] && [[ "''${1:-}" != -* ]] && [[ "''${1:-}" != "otp" ]]; then
85 decrypt_target="''${1:-}"
86 fi
87
88 if [[ -n "$decrypt_target" ]]; then
89 maybe_set_tpm_pin "$decrypt_target"
90 fi
91
92 # Handle OTP commands by delegating to pass-otp
93 if [[ "''${1:-}" == "otp" ]]; then
94 shift
95 # Extract pass name and options
96 clip_arg=""
97 pass_name=""
98 for arg in "$@"; do
99 case "$arg" in
100 "--clip"|"-c")
101 clip_arg="--clip"
102 ;;
103 *)
104 pass_name="$arg"
105 ;;
106 esac
107 done
108
109 if [[ -z "$pass_name" ]]; then
110 echo "Usage: pass otp [--clip,-c] pass-name"
111 exit 1
112 fi
113
114 # Show pass and pipe to OTP (identities already set up by age-detect)
115 maybe_set_tpm_pin "$pass_name"
116 ${exePath} show "$pass_name" | pass-otp $clip_arg
117 else
118 # Pass all other commands directly to passage (identities already set up)
119 ${exePath} "$@"
120 fi
121 '';
122 };
123 };
124}