improve secrets prompting

This commit is contained in:
Niklas Gollenstede 2023-07-20 17:47:47 +02:00
parent 192dd6f179
commit 6a886a839d
4 changed files with 28 additions and 7 deletions

View File

@ -260,7 +260,7 @@ in rec {
generic-arg-help "${ownPath}" "$functionDoc" ${esc description} ${esc notesAndExamples} ${esc usageLine} || exit generic-arg-help "${ownPath}" "$functionDoc" ${esc description} ${esc notesAndExamples} ${esc usageLine} || exit
) ; \exit 0 ; fi ) ; \exit 0 ; fi
# generic-arg-verify || \exit 3 generic-arg-verify || \exit 3
# either call »argv[0]« with the remaining parameters as arguments, or if »$1« is »-c« eval »$2«. # either call »argv[0]« with the remaining parameters as arguments, or if »$1« is »-c« eval »$2«.
if [[ ''${args[trace]:-} ]] ; then set -x ; fi if [[ ''${args[trace]:-} ]] ; then set -x ; fi

View File

@ -7,7 +7,10 @@ function prompt-for-user-passwords { # (void)
userPasswords[$user]=@{config.users.users!catAttrSets.password[$user]} userPasswords[$user]=@{config.users.users!catAttrSets.password[$user]}
done done
local user ; for user in "@{!config.users.users!catAttrSets.passwordFile[@]}" ; do local user ; for user in "@{!config.users.users!catAttrSets.passwordFile[@]}" ; do
if ! userPasswords[$user]=$(prompt-new-password "for the user account »$user«") ; then true ; \return 1 ; fi for attempt in 2 3 x ; do
if userPasswords[$user]=$(prompt-new-password "for the user account »$user«") ; then break ; fi
if [[ $attempt == x ]] ; then \return 1 ; fi ; echo "Retrying ($attempt/3):"
done
done done
} }

View File

@ -87,11 +87,29 @@ function write-secret {( set -u # 1: path, 2?: owner[:[group]], 3?: mode
## Interactively prompts for a password to be entered and confirmed. ## Interactively prompts for a password to be entered and confirmed.
function prompt-new-password {( set -u # 1: usage function prompt-new-password {( set -u # 1: usage
read -s -p "Please enter the new password $1: " password1 || exit ; echo 1>&2 read -s -p "Please enter the new password $1: " password1 || exit ; echo 1>&2
if (( ${#password1} == 0 )) ; then printf 'Password empty.\n' 1>&2 ; \exit 1 ; fi
read -s -p "Please enter the same password again: " password2 || exit ; echo 1>&2 read -s -p "Please enter the same password again: " password2 || exit ; echo 1>&2
if (( ${#password1} == 0 )) || [[ "$password1" != "$password2" ]] ; then printf 'Passwords empty or mismatch, aborting.\n' 1>&2 ; \exit 1 ; fi if [[ "$password1" != "$password2" ]] ; then printf 'Passwords mismatch.\n' 1>&2 ; \exit 1 ; fi
printf %s "$password1" || exit printf %s "$password1" || exit
)} )}
## If »secretFile« does not exist, interactively prompts up to three times for the secret to be stored in that file.
function prompt-secret-as {( set -u # 1: what, 2: secretFile, 3?: owner[:[group]], 4?: mode
if [[ -e $2 ]] ; then \return ; fi
what=$1 ; shift
function prompt {
read -s -p "Please enter $what: " value || exit ; echo 1>&2
if (( ${#value} == 0 )) ; then printf 'Nothing entered. ' 1>&2 ; \return 1 ; fi
read -s -p "Please enter that again, or return empty to skip the check: " check || exit ; echo 1>&2
if [[ $check && $value != "$check" ]] ; then printf 'Entered values mismatch. ' 1>&2 ; \return 1 ; fi
}
for attempt in 2 3 x ; do
if prompt && printf %s "$value" | write-secret "$@" ; then break ; fi
if [[ $attempt == x ]] ; then echo "Aborting." 1>&2 ; \return 1 ; fi
echo "Retrying ($attempt/3):" 1>&2
done
)}
declare-flag install-system inspectScripts "" "When running installation hooks (»...*Commands« composed as Nix strings) print out and pause before each command. This works ... semi-well." declare-flag install-system inspectScripts "" "When running installation hooks (»...*Commands« composed as Nix strings) print out and pause before each command. This works ... semi-well."
## Runs an installer hook script, optionally stepping through the script. ## Runs an installer hook script, optionally stepping through the script.

View File

@ -56,7 +56,7 @@ function ensure-datasets {
local zfs=@{native.zfs}/bin/zfs local zfs=@{native.zfs}/bin/zfs
local name ; while IFS= read -u3 -r -d $'\0' name ; do local name ; while IFS= read -u3 -r -d $'\0' name ; do
if [[ ! $name =~ $filterExp ]] ; then printf 'Skipping dataset »%s« since it does not match »%s«\n' "$name" "$filterExp" >&2 ; continue ; fi if [[ ! $name =~ $filterExp ]] ; then : "Skipping dataset »$name« since it does not match »$filterExp«" ; continue ; fi
eval 'local -A dataset='"@{config.setup.zfs.datasets[$name]}" eval 'local -A dataset='"@{config.setup.zfs.datasets[$name]}"
eval 'local -A props='"${dataset[props]}" eval 'local -A props='"${dataset[props]}"
@ -118,9 +118,9 @@ function ensure-datasets {
( PATH=@{native.zfs}/bin ; ${_set_x:-:} ; zfs create "${zfsCreate[@]}" "${dataset[name]}" ) || exit ( PATH=@{native.zfs}/bin ; ${_set_x:-:} ; zfs create "${zfsCreate[@]}" "${dataset[name]}" ) || exit
fi fi
if [[ ${props[canmount]} != off ]] ; then ( if [[ ${props[canmount]} != off ]] ; then (
tmpMnt=$(mktemp -d) ; trap "" EXIT && @{native.util-linux}/bin/mount -t zfs -o zfsutil "${dataset[name]}" $tmpMnt && tmp=$( mktemp -d ) && mkdir $tmp/mnt && @{native.util-linux}/bin/mount -t zfs -o zfsutil "${dataset[name]}" $tmp/mnt || exit
trap "@{native.util-linux}/bin/umount '${dataset[name]}' ; rmdir $tmpMnt" EXIT && trap "@{native.util-linux}/bin/umount '${dataset[name]}' ; rmdir $tmp{/mnt,}" EXIT || exit
chmod 000 -- "$tmpMnt" && chown "${dataset[uid]}:${dataset[gid]}" -- "$tmpMnt" && chmod "${dataset[mode]}" -- "$tmpMnt" chmod 000 -- $tmp/mnt && ( cd $tmp ; chown "${dataset[uid]}:${dataset[gid]}" -- mnt && chmod "${dataset[mode]}" -- mnt ) || exit
) || exit ; fi ) || exit ; fi
if [[ $explicitKeylocation && $explicitKeylocation != "${props[keylocation]:-}" ]] ; then if [[ $explicitKeylocation && $explicitKeylocation != "${props[keylocation]:-}" ]] ; then
( PATH=@{native.zfs}/bin ; ${_set_x:-:} ; zfs set keylocation="$explicitKeylocation" "${dataset[name]}" ) || exit ( PATH=@{native.zfs}/bin ; ${_set_x:-:} ; zfs set keylocation="$explicitKeylocation" "${dataset[name]}" ) || exit