ubuntu-22.04.3-desktop-amd64/casper/filesystem/usr/bin/blockdev-keygen

222 lines
4.6 KiB
Bash
Executable File

#!/bin/sh
#
# usage: $0 description keytype keyfile [keybits]
#
# This handles sensitive data that must not be swapped out
# or written out to disk unencrypted.
#
# Important: before running this script the caller has
# to check for unsafe swap partitions. This is done in
# choose_method/encrypt/do_options.
#
# Assumption: This runs as part of d-i. Therefore, temp
# files outside of /target reside in a ramdisk. Process
# information (think [ "$pass" ]) is not exposed to anyone
# but the installing user.
#
# Released under the GNU GPL.
# Copyright 2005, Max Vozeler <xam@debian.org>
#
. /usr/share/debconf/confmodule
umask 077
# When changing minlen care must be taken about the
# consequences for translations, see #326482
minlen=8
passphrase_is_weak () {
test $(printf %s "$1" | wc -c) -lt $minlen
}
get_passphrase () {
local pass_ok
pass_ok=0
while [ $pass_ok -eq 0 ]; do
templ="partman-crypto/passphrase"
db_subst $templ DEVICE "$description"
db_input critical $templ
templ="partman-crypto/passphrase-again"
db_input critical $templ
db_go || return 1
db_get partman-crypto/passphrase || RET=''
pass=$RET
if [ -z "$pass" ]; then
db_set partman-crypto/passphrase ""
db_set partman-crypto/passphrase-again ""
templ="partman-crypto/passphrase-empty"
db_fset $templ seen false
db_input critical $templ
db_fset partman-crypto/passphrase seen false
db_fset partman-crypto/passphrase-again seen false
continue
fi
db_get partman-crypto/passphrase-again || RET=''
if [ "$pass" != "$RET" ]; then
db_set partman-crypto/passphrase ""
db_set partman-crypto/passphrase-again ""
templ="partman-crypto/passphrase-mismatch"
db_fset $templ seen false
db_input critical $templ
db_fset partman-crypto/passphrase seen false
db_fset partman-crypto/passphrase-again seen false
continue
fi
if passphrase_is_weak "$pass"; then
templ="partman-crypto/weak_passphrase"
db_subst $templ MINIMUM $minlen
db_input critical $templ || true
db_go || true
db_get $templ || RET=''
if [ "$RET" != true ]; then
# user doesn't want to force weak passphrase
db_set partman-crypto/passphrase ""
db_set partman-crypto/passphrase-again ""
db_fset partman-crypto/passphrase seen false
db_fset partman-crypto/passphrase-again seen false
continue
fi
db_set $templ false
db_fset $templ seen false
fi
pass_ok=1
done
db_set partman-crypto/passphrase ""
db_set partman-crypto/passphrase-again ""
if [ $pass_ok -eq 1 ]; then
echo "$pass"
fi
}
have_entropy_plugin () {
db_capb
set -- $RET
for cap; do
if [ "$cap" = plugin-entropy ]; then
return 0
fi
done
return 1
}
# Fifo provided by cdebconf-entropy plugins
randfifo=/var/run/random.fifo
call_entropy_plugin () {
local keybytes
keybytes=$1
db_capb backup align
templ=partman-crypto/entropy
db_fset $templ seen false
db_subst $templ DEVICE "$description"
db_subst $templ FIFO $randfifo
db_subst $templ KEYSIZE "$keybytes"
db_subst $templ SUCCESS partman-crypto/entropy-success
db_input critical $templ
db_go || return 1
return 0
}
# Create a one-time random keyfile for use during install
create_random_keyfile() {
local keyfile keybytes
keyfile=$1
keybytes=$2
# Fork off file writer
(while [ ! -p $randfifo ]; do
sleep 1
done
cat $randfifo > $keyfile
) &
writer_pid=$!
# Call plugin to feed randfifo
call_entropy_plugin $keybytes
if [ $? -ne 0 ] || ! wait $writer_pid; then
rm $keyfile
kill $writer_pid
return 1
fi
return 0
}
problem_dialog () {
db_fset partman-crypto/keyfile-problem seen false
db_input critical partman-crypto/keyfile-problem
db_go || true
}
description=$1
keytype=$2
keyfile=$3
keybits=$4
if ! ([ "$description" ] && [ "$keytype" ] && [ "$keyfile" ]); then
# bad options
problem_dialog
exit 1
fi
# Log available entropy
logger -t partman-crypto "kernel entropy_avail: $(cat /proc/sys/kernel/random/entropy_avail) bits"
if [ "$keytype" = random ]; then
if ! have_entropy_plugin; then
db_fset partman-crypto/tools_missing seen false
db_input critical partman-crypto/tools_missing
db_go || true
exit 1
fi
fi
case $keytype in
passphrase)
pass=$(get_passphrase)
if [ -z "$pass" ]; then
problem_dialog
exit 1
fi
printf %s "$pass" > $keyfile
;;
random)
if [ -z "$keybits" ]; then
problem_dialog
exit 1
fi
# Round keybits up to closest byte
keybytes=$(( (keybits + 7)/8 ))
if [ $keybytes -lt 1 ]; then
# key size invalid
problem_dialog
exit 1
fi
if ! create_random_keyfile $keyfile $keybytes; then
problem_dialog
exit 1
fi
;;
*)
problem_dialog
exit 1
;;
esac