Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions features/dialog/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Feature: dialog

This feature provides a wrapper around dialogs such as password prompts. Work
with dialogs becomes more challenging when using bootsplash/plymouth. Other
utilities can also be used to display the dialog.
3 changes: 3 additions & 0 deletions features/dialog/config.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# SPDX-License-Identifier: GPL-3.0-or-later

DIALOG_DATADIR ?= $(FEATURESDIR)/dialog/data
118 changes: 118 additions & 0 deletions features/dialog/data/bin/dialog-sh-functions
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-3.0-or-later

if [ -z "${__dialog_sh_functions-}" ]; then
__dialog_sh_functions=1

__dialog_plymouth_is_running=

# shellcheck disable=SC2120
dialog_plymouth_is_running()
{
local recheck="${1-}"

if [ -n "$recheck" ] || [ -z "${__dialog_plymouth_is_running-}" ]; then
type -P plymouth >/dev/null && plymouth --ping 2>/dev/null &&
__dialog_plymouth_is_running=1 ||
__dialog_plymouth_is_running=0
fi

[ "$__dialog_plymouth_is_running" = 1 ]
}

__ask_pass_directly()
{
local prompt tries cmd rc

prompt="$1"; shift
tries="$1"; shift
cmd="$1"; shift

! dialog_plymouth_is_running ||
plymouth hide-splash 2>/dev/null

rc=2

while [ "$rc" != 0 ] && [ "$tries" != 0 ]; do
"$cmd"
rc="$?"
tries=$(($tries - 1))
done

! dialog_plymouth_is_running ||
plymouth show-splash 2>/dev/null

return $rc
}

__ask_pass_with_unl0kr()
{
local prompt tries cmd rc

prompt="$1"; shift
tries="$1"; shift
cmd="$1"; shift

! dialog_plymouth_is_running ||
plymouth hide-splash 2>/dev/null

rc=2

while [ "$rc" != 0 ] && [ "$tries" != 0 ]; do
unl0kr 2>/dev/null | "$cmd"
rc="$?"
tries=$(($tries - 1))
done

! dialog_plymouth_is_running ||
plymouth show-splash 2>/dev/null

return $rc
}

__ask_pass_with_plymouth()
{
local prompt tries cmd

prompt="$1"; shift
tries="$1"; shift
cmd="$1"; shift

plymouth ask-for-password \
--prompt "$prompt" \
--number-of-tries="$tries" \
--command="$cmd"
}

dialog_ask_pass()
{
local rc tries ask

prompt="$1"; shift
tries="$1"; shift

ask=__ask_pass_directly

! dialog_plymouth_is_running || ask=__ask_pass_with_plymouth
! type -P unl0kr >/dev/null || ask=__ask_pass_with_unl0kr

# To avoid issues with quoting arguments for the utility, a temporary
# wrapper can be created.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too hacky, but OK.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wladmis What exactly seems like a hack to you?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A workaround with a wrapper file to solve quoting issues, but I don't know better solution.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, this is a simple and effective way to do it. If it doesn't happen very often, I don't see anything wrong with it.

local cmdwrapper
cmdwrapper="/.initrd/dialog-ask-pass-$$.$BASHPID"
{
printf '#!/bin/bash\n'
printf 'exec '
printf ' %q' "$@"
} > "$cmdwrapper"
chmod +x "$cmdwrapper"

rc=0
"$ask" "$prompt" "$tries" "$cmdwrapper" || rc="$?"

rm -f -- "$cmdwrapper"

return $rc
}

fi # __dialog_sh_functions
3 changes: 3 additions & 0 deletions features/dialog/rules.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# SPDX-License-Identifier: GPL-3.0-or-later

PUT_FEATURE_DIRS += $(DIALOG_DATADIR)
2 changes: 1 addition & 1 deletion features/luks/config.mk
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# SPDX-License-Identifier: GPL-3.0-or-later
$(call feature-requires,depmod-image devmapper modules-crypto-user-api system-glibc)
$(call feature-requires,depmod-image devmapper modules-crypto-user-api system-glibc dialog)

CRYPTSETUP_BIN ?= cryptsetup
LUKS_DATADIR ?= $(FEATURESDIR)/luks/data
Expand Down
84 changes: 8 additions & 76 deletions features/luks/data/lib/uevent/handlers/085-luks
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

. uevent-sh-functions
. initrd-sh-functions
. dialog-sh-functions
. crypttab-sh-functions

PROG="${QUEUE:--}: session=${SESSION:-0}: $PROG"
Expand Down Expand Up @@ -48,28 +49,6 @@ match_dev_in_array() {
return 1
}

luks_unl0kr_ask_pass() {
[ "$#" = 2 ] || return 1

local cmd tries rc

rc=2
cmd="$1"; shift
tries="$1"; shift

plymouth hide-splash 2>/dev/null

while [ "$rc" != 0 ] && [ "$tries" != 0 ]; do
unl0kr 2>/dev/null | $cmd
rc=$?
tries=$(($tries - 1))
done

plymouth show-splash 2>/dev/null

return $rc
}

read_pkcs11_key() {
local keyid="$1" tries=${luks_tries:-3}

Expand Down Expand Up @@ -104,25 +83,10 @@ read_pkcs11_key() {
type="data"
output_file="$path"
flags="-l -r"
if plymouth --ping 2>/dev/null; then
if type -P unl0kr >/dev/null; then
luks_unl0kr_ask_pass pkcs11-tool-wrapper $tries
rc=$?
else
add_new_line="true"\
plymouth ask-for-password \
--prompt "Please enter passphrase for smart card:" \
--number-of-tries=$tries \
--command="pkcs11-tool-wrapper"
rc=$?
fi
else
rc=1
while [ "$rc" != "0" ]; do
pkcs11-tool-wrapper
rc="$?"
done
fi

dialog_ask_pass "Please enter passphrase for smart card:" "$tries" \
"pkcs11-tool-wrapper"
rc="$?"

return "$rc"
}
Expand Down Expand Up @@ -194,40 +158,6 @@ findkey() {
return 2
}

cryptsetup_ask_pass() {
local rc=0 tries=${luks_tries:-3}

{
printf 'exec cryptsetup'
printf ' %q' "$@"
} > /.initrd/cryptsetup-ask-pass

if plymouth --ping 2>/dev/null; then
if type -P unl0kr >/dev/null; then
luks_unl0kr_ask_pass "bash /.initrd/cryptsetup-ask-pass" $tries
rc=$?
else
plymouth ask-for-password \
--prompt "Please enter passphrase for $LUKS_ROOT:" \
--number-of-tries=$tries \
--command="bash /.initrd/cryptsetup-ask-pass"
rc="$?"
fi
else
rc=2
# WARNING: Wait decrypt forever!
while [ "$rc" = 2 ] && [ "$tries" -ne 0 ]; do
bash /.initrd/cryptsetup-ask-pass
rc="$?"
tries=$(( $tries - 1 ))
done
fi

rm -f -- /.initrd/cryptsetup-ask-pass

return $rc
}

in_list() {
local a n="$1"
for a; do
Expand Down Expand Up @@ -427,7 +357,9 @@ handler() {
fi
if [ "$rc" -ne 0 ]; then
message "Trying to ask the user for a password."
cryptsetup_ask_pass "$@"
dialog_ask_pass \
"Please enter passphrase for $LUKS_ROOT:" "$luks_tries" \
"cryptsetup" "$@"
rc="$?"
fi
fi
Expand Down