Merge pull request #107402 from ctem/fix/luksroot-master

boot.initrd.luks: add reusePassphrases support for YubiKey 2FA

authored by Guillaume Girol and committed by GitHub 56923181 675969a0

+40 -16
+40 -16
nixos/modules/system/boot/luksroot.nix
··· 56 56 57 57 ykinfo -v 1>/dev/null 2>&1 58 58 if [ $? != 0 ]; then 59 - echo -n "Waiting $secs seconds for Yubikey to appear..." 59 + echo -n "Waiting $secs seconds for YubiKey to appear..." 60 60 local success=false 61 61 for try in $(seq $secs); do 62 62 echo -n . ··· 118 118 # Cryptsetup locking directory 119 119 mkdir -p /run/cryptsetup 120 120 121 - # For Yubikey salt storage 121 + # For YubiKey salt storage 122 122 mkdir -p /crypt-storage 123 123 124 124 ${optionalString luks.gpgSupport '' ··· 218 218 } 219 219 220 220 ${optionalString (luks.yubikeySupport && (yubikey != null)) '' 221 - # Yubikey 221 + # YubiKey 222 222 rbtohex() { 223 223 ( od -An -vtx1 | tr -d ' \n' ) 224 224 } ··· 244 244 local new_k_luks 245 245 246 246 mount -t ${yubikey.storage.fsType} ${yubikey.storage.device} /crypt-storage || \ 247 - die "Failed to mount Yubikey salt storage device" 247 + die "Failed to mount YubiKey salt storage device" 248 248 249 249 salt="$(cat /crypt-storage${yubikey.storage.path} | sed -n 1p | tr -d '\n')" 250 250 iterations="$(cat /crypt-storage${yubikey.storage.path} | sed -n 2p | tr -d '\n')" ··· 254 254 for try in $(seq 3); do 255 255 ${optionalString yubikey.twoFactor '' 256 256 echo -n "Enter two-factor passphrase: " 257 - read -r k_user 258 - echo 257 + k_user= 258 + while true; do 259 + if [ -e /crypt-ramfs/passphrase ]; then 260 + echo "reused" 261 + k_user=$(cat /crypt-ramfs/passphrase) 262 + break 263 + else 264 + # Try reading it from /dev/console with a timeout 265 + IFS= read -t 1 -r k_user 266 + if [ -n "$k_user" ]; then 267 + ${if luks.reusePassphrases then '' 268 + # Remember it for the next device 269 + echo -n "$k_user" > /crypt-ramfs/passphrase 270 + '' else '' 271 + # Don't save it to ramfs. We are very paranoid 272 + ''} 273 + echo 274 + break 275 + fi 276 + fi 277 + done 259 278 ''} 260 279 261 280 if [ ! -z "$k_user" ]; then ··· 268 287 269 288 if [ $? == 0 ]; then 270 289 opened=true 290 + ${if luks.reusePassphrases then '' 291 + # We don't rm here because we might reuse it for the next device 292 + '' else '' 293 + rm -f /crypt-ramfs/passphrase 294 + ''} 271 295 break 272 296 else 273 297 opened=false ··· 317 341 if wait_yubikey ${toString yubikey.gracePeriod}; then 318 342 do_open_yubikey 319 343 else 320 - echo "No yubikey found, falling back to non-yubikey open procedure" 344 + echo "No YubiKey found, falling back to non-YubiKey open procedure" 321 345 open_normally 322 346 fi 323 347 } ··· 665 689 yubikey = mkOption { 666 690 default = null; 667 691 description = '' 668 - The options to use for this LUKS device in Yubikey-PBA. 669 - If null (the default), Yubikey-PBA will be disabled for this device. 692 + The options to use for this LUKS device in YubiKey-PBA. 693 + If null (the default), YubiKey-PBA will be disabled for this device. 670 694 ''; 671 695 672 696 type = with types; nullOr (submodule { ··· 674 698 twoFactor = mkOption { 675 699 default = true; 676 700 type = types.bool; 677 - description = "Whether to use a passphrase and a Yubikey (true), or only a Yubikey (false)."; 701 + description = "Whether to use a passphrase and a YubiKey (true), or only a YubiKey (false)."; 678 702 }; 679 703 680 704 slot = mkOption { 681 705 default = 2; 682 706 type = types.int; 683 - description = "Which slot on the Yubikey to challenge."; 707 + description = "Which slot on the YubiKey to challenge."; 684 708 }; 685 709 686 710 saltLength = mkOption { ··· 704 728 gracePeriod = mkOption { 705 729 default = 10; 706 730 type = types.int; 707 - description = "Time in seconds to wait for the Yubikey."; 731 + description = "Time in seconds to wait for the YubiKey."; 708 732 }; 709 733 710 734 /* TODO: Add to the documentation of the current module: ··· 779 803 default = false; 780 804 type = types.bool; 781 805 description = '' 782 - Enables support for authenticating with a Yubikey on LUKS devices. 806 + Enables support for authenticating with a YubiKey on LUKS devices. 783 807 See the NixOS wiki for information on how to properly setup a LUKS device 784 - and a Yubikey to work with this feature. 808 + and a YubiKey to work with this feature. 785 809 ''; 786 810 }; 787 811 ··· 799 823 800 824 assertions = 801 825 [ { assertion = !(luks.gpgSupport && luks.yubikeySupport); 802 - message = "Yubikey and GPG Card may not be used at the same time."; 826 + message = "YubiKey and GPG Card may not be used at the same time."; 803 827 } 804 828 805 829 { assertion = !(luks.gpgSupport && luks.fido2Support); ··· 807 831 } 808 832 809 833 { assertion = !(luks.fido2Support && luks.yubikeySupport); 810 - message = "FIDO2 and Yubikey may not be used at the same time."; 834 + message = "FIDO2 and YubiKey may not be used at the same time."; 811 835 } 812 836 ]; 813 837