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

boot.initrd.luks: add reusePassphrases support for YubiKey 2FA
This commit is contained in:
Guillaume Girol 2021-02-19 15:42:45 +00:00 committed by GitHub
commit 56923181e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -56,7 +56,7 @@ let
ykinfo -v 1>/dev/null 2>&1
if [ $? != 0 ]; then
echo -n "Waiting $secs seconds for Yubikey to appear..."
echo -n "Waiting $secs seconds for YubiKey to appear..."
local success=false
for try in $(seq $secs); do
echo -n .
@ -118,7 +118,7 @@ let
# Cryptsetup locking directory
mkdir -p /run/cryptsetup
# For Yubikey salt storage
# For YubiKey salt storage
mkdir -p /crypt-storage
${optionalString luks.gpgSupport ''
@ -218,7 +218,7 @@ let
}
${optionalString (luks.yubikeySupport && (yubikey != null)) ''
# Yubikey
# YubiKey
rbtohex() {
( od -An -vtx1 | tr -d ' \n' )
}
@ -244,7 +244,7 @@ let
local new_k_luks
mount -t ${yubikey.storage.fsType} ${yubikey.storage.device} /crypt-storage || \
die "Failed to mount Yubikey salt storage device"
die "Failed to mount YubiKey salt storage device"
salt="$(cat /crypt-storage${yubikey.storage.path} | sed -n 1p | tr -d '\n')"
iterations="$(cat /crypt-storage${yubikey.storage.path} | sed -n 2p | tr -d '\n')"
@ -254,8 +254,27 @@ let
for try in $(seq 3); do
${optionalString yubikey.twoFactor ''
echo -n "Enter two-factor passphrase: "
read -r k_user
echo
k_user=
while true; do
if [ -e /crypt-ramfs/passphrase ]; then
echo "reused"
k_user=$(cat /crypt-ramfs/passphrase)
break
else
# Try reading it from /dev/console with a timeout
IFS= read -t 1 -r k_user
if [ -n "$k_user" ]; then
${if luks.reusePassphrases then ''
# Remember it for the next device
echo -n "$k_user" > /crypt-ramfs/passphrase
'' else ''
# Don't save it to ramfs. We are very paranoid
''}
echo
break
fi
fi
done
''}
if [ ! -z "$k_user" ]; then
@ -268,6 +287,11 @@ let
if [ $? == 0 ]; then
opened=true
${if luks.reusePassphrases then ''
# We don't rm here because we might reuse it for the next device
'' else ''
rm -f /crypt-ramfs/passphrase
''}
break
else
opened=false
@ -317,7 +341,7 @@ let
if wait_yubikey ${toString yubikey.gracePeriod}; then
do_open_yubikey
else
echo "No yubikey found, falling back to non-yubikey open procedure"
echo "No YubiKey found, falling back to non-YubiKey open procedure"
open_normally
fi
}
@ -665,8 +689,8 @@ in
yubikey = mkOption {
default = null;
description = ''
The options to use for this LUKS device in Yubikey-PBA.
If null (the default), Yubikey-PBA will be disabled for this device.
The options to use for this LUKS device in YubiKey-PBA.
If null (the default), YubiKey-PBA will be disabled for this device.
'';
type = with types; nullOr (submodule {
@ -674,13 +698,13 @@ in
twoFactor = mkOption {
default = true;
type = types.bool;
description = "Whether to use a passphrase and a Yubikey (true), or only a Yubikey (false).";
description = "Whether to use a passphrase and a YubiKey (true), or only a YubiKey (false).";
};
slot = mkOption {
default = 2;
type = types.int;
description = "Which slot on the Yubikey to challenge.";
description = "Which slot on the YubiKey to challenge.";
};
saltLength = mkOption {
@ -704,7 +728,7 @@ in
gracePeriod = mkOption {
default = 10;
type = types.int;
description = "Time in seconds to wait for the Yubikey.";
description = "Time in seconds to wait for the YubiKey.";
};
/* TODO: Add to the documentation of the current module:
@ -779,9 +803,9 @@ in
default = false;
type = types.bool;
description = ''
Enables support for authenticating with a Yubikey on LUKS devices.
Enables support for authenticating with a YubiKey on LUKS devices.
See the NixOS wiki for information on how to properly setup a LUKS device
and a Yubikey to work with this feature.
and a YubiKey to work with this feature.
'';
};
@ -799,7 +823,7 @@ in
assertions =
[ { assertion = !(luks.gpgSupport && luks.yubikeySupport);
message = "Yubikey and GPG Card may not be used at the same time.";
message = "YubiKey and GPG Card may not be used at the same time.";
}
{ assertion = !(luks.gpgSupport && luks.fido2Support);
@ -807,7 +831,7 @@ in
}
{ assertion = !(luks.fido2Support && luks.yubikeySupport);
message = "FIDO2 and Yubikey may not be used at the same time.";
message = "FIDO2 and YubiKey may not be used at the same time.";
}
];