222 lines
4.6 KiB
Bash
Executable File
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
|