Store udiskie passwords in GNOME Keyring

This commit is contained in:
Fabio Scotto di Santolo
2026-04-14 14:46:20 +02:00
parent 5e8a1b7bc2
commit 461dea9a5c
6 changed files with 113 additions and 3 deletions

View File

@@ -21,7 +21,7 @@ exec-once = wireplumber
exec-once = /usr/libexec/xfce-polkit
exec-once = nm-applet
exec-once = blueman-applet
exec-once = udiskie --tray --automount
exec-once = udiskie
env = XCURSOR_THEME,Yaru
env = XCURSOR_SIZE,24

View File

@@ -26,7 +26,7 @@ exec --no-startup-id dunst
exec --no-startup-id /usr/libexec/xfce-polkit
exec --no-startup-id nm-applet
exec --no-startup-id blueman-applet
exec --no-startup-id udiskie --tray --automount
exec --no-startup-id udiskie
exec --no-startup-id volumeicon
exec --no-startup-id xfce4-clipman

View File

@@ -33,7 +33,7 @@ exec swayosd-server
exec /usr/libexec/xfce-polkit
exec nm-applet
exec blueman-applet
exec udiskie --tray --automount
exec udiskie
exec xfce4-clipman
# Input and output defaults

View File

@@ -0,0 +1,13 @@
---
program_options:
tray: auto
automount: true
notify: true
password_cache: false
password_prompt:
- /bin/sh
- -c
- 'exec "$HOME/.local/bin/udiskie-password" "$1" "$2"'
- sh
- '{id_uuid}'
- '{device_presentation}'

View File

@@ -0,0 +1,89 @@
#!/bin/sh
set -eu
id_uuid=${1:-}
device_presentation=${2:-Encrypted disk}
pinentry_program=pinentry-gtk-2
if [ -z "$id_uuid" ]; then
printf '%s\n' "udiskie-password: missing device UUID" >&2
exit 1
fi
assuan_escape() {
python3 -c 'import sys
value = sys.argv[1]
value = value.replace("%", "%25").replace("\n", "%0A").replace("\r", "%0D")
sys.stdout.write(value)' "$1"
}
pinentry_getpin() {
title=$(assuan_escape "Unlock disk")
prompt=$(assuan_escape "Passphrase:")
description=$(assuan_escape "Enter passphrase for $device_presentation")
response=$(
{
printf 'SETTITLE %s\n' "$title"
printf 'SETPROMPT %s\n' "$prompt"
printf 'SETDESC %s\n' "$description"
printf 'GETPIN\n'
} | "$pinentry_program"
) || return 1
printf '%s\n' "$response" |
python3 -c 'import sys
for line in sys.stdin.read().splitlines():
if line.startswith("D "):
value = line[2:].replace("%0A", "\n").replace("%0D", "\r")
i = 0
out = []
while i < len(value):
if value[i] == "%" and i + 2 < len(value):
out.append(chr(int(value[i + 1:i + 3], 16)))
i += 3
else:
out.append(value[i])
i += 1
sys.stdout.write("".join(out))
break
else:
sys.exit(1)'
}
pinentry_confirm_save() {
title=$(assuan_escape "Save disk password")
description=$(assuan_escape "Save the unlock passphrase for $device_presentation in GNOME Keyring?")
button_ok=$(assuan_escape "Save")
button_cancel=$(assuan_escape "Skip")
{
printf 'SETTITLE %s\n' "$title"
printf 'SETDESC %s\n' "$description"
printf 'SETOK %s\n' "$button_ok"
printf 'SETCANCEL %s\n' "$button_cancel"
printf 'CONFIRM\n'
} | "$pinentry_program" >/dev/null 2>&1
}
if password=$(secret-tool lookup app udiskie id_uuid "$id_uuid" 2>/dev/null); then
if [ -n "$password" ]; then
printf '%s' "$password"
exit 0
fi
fi
password=$(pinentry_getpin) || exit 1
if [ -z "$password" ]; then
exit 1
fi
if pinentry_confirm_save; then
printf '%s' "$password" | secret-tool store \
--label="udiskie LUKS $device_presentation" \
app udiskie \
id_uuid "$id_uuid" >/dev/null
fi
printf '%s' "$password"