diff --git a/bin/omarchy-drive-password b/bin/omarchy-drive-password index 3fdf9b08..2fbbb187 100755 --- a/bin/omarchy-drive-password +++ b/bin/omarchy-drive-password @@ -13,8 +13,16 @@ if [[ -n $encrypted_drives ]]; then fi if [[ -n $drive_to_change ]]; then + new_password=$(gum input --password --header "New encryption password") || exit 1 + [[ -n $new_password ]] || { echo "Password cannot be empty."; exit 1; } + + confirmation=$(gum input --password --header "Confirm new encryption password") || exit 1 + [[ $new_password == "$confirmation" ]] || { echo "Passwords do not match."; exit 1; } + echo "Changing full-disk encryption password for $drive_to_change" - sudo cryptsetup luksChangeKey --pbkdf argon2id --iter-time 2000 "$drive_to_change" + # The new key travels over stdin and reaches cryptsetup as a keyfile via + # <(cat), leaving the tty free for the current-passphrase prompt. + printf "%s" "$new_password" | sudo bash -c 'exec cryptsetup luksChangeKey --pbkdf argon2id --iter-time 2000 "$1" <(cat) "$tmp_dir/blkid" <<'EOF' +#!/bin/bash +echo /dev/test-luks +EOF + +cat >"$tmp_dir/gum" <<'EOF' +#!/bin/bash +head -n 1 "$TEST_INPUTS" +sed -i '1d' "$TEST_INPUTS" +EOF + +cat >"$tmp_dir/sudo" <<'EOF' +#!/bin/bash +printf '%s\n' "$@" >"$TEST_ARGS" +cat >"$TEST_STDIN" +EOF + +chmod +x "$tmp_dir/blkid" "$tmp_dir/gum" "$tmp_dir/sudo" +export PATH="$tmp_dir:$ROOT/bin:$PATH" +export TEST_ARGS="$tmp_dir/args" TEST_INPUTS="$tmp_dir/inputs" TEST_STDIN="$tmp_dir/stdin" + +printf '\n' >"$TEST_INPUTS" +if "$ROOT/bin/omarchy-drive-password" >/dev/null; then + fail "drive password rejects an empty passphrase" +fi +[[ ! -e $TEST_ARGS ]] || fail "drive password does not run cryptsetup for an empty passphrase" + +printf 'secret123\n*\n' >"$TEST_INPUTS" +if "$ROOT/bin/omarchy-drive-password" >/dev/null; then + fail "drive password rejects a mismatched confirmation" +fi +[[ ! -e $TEST_ARGS ]] || fail "drive password does not run cryptsetup for a mismatched confirmation" + +printf 'new password\nnew password\n' >"$TEST_INPUTS" +"$ROOT/bin/omarchy-drive-password" >/dev/null + +[[ $(<"$TEST_STDIN") == "new password" ]] || fail "drive password passes the validated passphrase without a newline" +grep -F 'cryptsetup luksChangeKey' "$TEST_ARGS" >/dev/null || fail "drive password changes the LUKS key" +grep -Fx /dev/test-luks "$TEST_ARGS" >/dev/null || fail "drive password targets the selected drive" +pass "drive password rejects empty and mismatched passphrases and passes validated input to cryptsetup"