From d8a3e16c701778a2774b54eb238a43b0e51719c5 Mon Sep 17 00:00:00 2001 From: Miloslav Trmac Date: Thu, 1 Jun 2006 02:41:11 +0000 Subject: Add encrypted swap and non-root filesystem support (#127378, based on a patch by W. Michael Petullo and Debian's cryptsetup package) --- rc.d/init.d/halt | 32 +++++++++++++- rc.d/rc.sysinit | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 1 deletion(-) diff --git a/rc.d/init.d/halt b/rc.d/init.d/halt index 60485da7..e0d269f8 100755 --- a/rc.d/init.d/halt +++ b/rc.d/init.d/halt @@ -22,6 +22,21 @@ action() { echo } +halt_crypto() { + fnval=0 + while read dst src key; do + [ -z "$dst" -o "${dst#\#}" != "$dst" ] && continue + if [ -b "/dev/mapper/$dst" ]; then + if /sbin/dmsetup info "$dst" | grep -q '^Open count: *0$'; then + /sbin/cryptsetup remove "$dst" + else + fnval=1 + fi + fi + done < /etc/crypttab + return $fnval +} + # See how we were called. case "$0" in *halt) @@ -120,7 +135,19 @@ tmpfs=$(awk '$2 ~ /^\/($|proc|dev)/ { next; } # Turn off swap, then unmount file systems. [ -f /proc/swaps ] && SWAPS=`awk '! /^Filename/ { print $1 }' /proc/swaps` -[ -n "$SWAPS" ] && action $"Turning off swap: " swapoff $SWAPS +if [ -n "$SWAPS" ]; then + action $"Turning off swap: " swapoff $SWAPS + for dst in $SWAPS; do + if [[ "$dst" =~ "^/dev/mapper" ]] \ + && [ "$(dmsetup status "$dst" | cut -d ' ' -f 3)" = crypt ]; then + backdev=$(/sbin/cryptsetup status "$dst" \ + | awk '$1 == "device:" { print $2 }') + /sbin/cryptsetup remove "$dst" + # Leave partition with a blank plain-text swap + mkswap "$backdev" > /dev/null + fi + done +fi [ -x /sbin/quotaoff ] && action $"Turning off quotas: " /sbin/quotaoff -aug @@ -145,6 +172,9 @@ LANG=C __umount_loop '$2 ~ /^\/$|^\/proc|^\/dev/{next} [ -f /proc/bus/usb/devices ] && umount /proc/bus/usb +[ -f /etc/crypttab ] && \ + LANG=C action $"Stopping disk encryption: " halt_crypto + # remove the crash indicator flag rm -f /.autofsck diff --git a/rc.d/rc.sysinit b/rc.d/rc.sysinit index 85864ecf..21f457ad 100755 --- a/rc.d/rc.sysinit +++ b/rc.d/rc.sysinit @@ -96,6 +96,117 @@ relabel_selinux() { fi } +key_is_random() { + [ "$1" = "/dev/urandom" -o "$1" = "/dev/hw_random" \ + -o "$1" = "/dev/random" ] +} + +# Because of a chicken/egg problem, init_crypto must be run twice. /var may be +# encrypted but /var/lib/random-seed is needed to initialize swap. +init_crypto() { + local have_random dst src key opt mode owner params makeswap skip arg opt + local param value ret + + ret=0 + have_random=$1 + while read dst src key opt; do + [ -z "$dst" -o "${dst#\#}" != "$dst" ] && continue + [ -b "/dev/mapper/$dst" ] && continue; + if [ "$have_random" = 0 ] && key_is_random "$key"; then + continue + fi + if [ -n "$key" -a "x$key" != "xnone" ]; then + if test -e "$key" ; then + mode=$(ls -l "$key" | cut -c 5-10) + owner=$(ls -l $key | awk '{ print $3 }') + if [ "$mode" != "------" ] && ! key_is_random "$key"; then + echo $"INSECURE MODE FOR $key" + fi + if [ "$owner" != root ]; then + echo $"INSECURE OWNER FOR $key" + fi + else + echo $"Key file for $dst not found, skipping" + ret=1 + continue + fi + else + key="" + fi + params="" + makeswap="" + skip="" + # Parse the options field, convert to cryptsetup parameters + # and contruct the command line + while [ -n "$opt" ]; do + arg=${opt%%,*} + opt=${opt##$arg} + opt=${opt##,} + param=${arg%%=*} + value=${arg##$param=} + + case "$param" in + cipher) + params="$params -c $value" + if [ -z "$value" ]; then + echo $"$dst: no value for cipher option, skipping" + skip="yes" + fi + ;; + size) + params="$params -s $value" + if [ -z "$value" ]; then + echo $"$dst: no value for size option, skipping" + skip="yes" + fi + ;; + hash) + params="$params -h $value" + if [ -z "$value" ]; then + echo $"$dst: no value for hash option, skipping" + skip="yes" + fi + ;; + verify) + params="$params -y" + ;; + swap) + makeswap=yes + esac + done + if [ "$skip" = "yes" ]; then + ret=1 + continue + fi + if [ "$makeswap" = "yes" ]; then + # init.d/halt should format $src as swap before shutdown + if [ "$(/sbin/blkid -o value -s TYPE "$src")" != "swap" ]; then + echo $"$src is not a swap partition" + makeswap=no + fi + fi + # FIXME: if [ -z key ], should we allow retries or handle rhgb? + if cryptsetup isLuks "$src" 2>/dev/null; then + if key_is_random "$key"; then + echo $"$dst: LUKS requires non-random key, skipping" + ret=1 + continue + fi + /sbin/cryptsetup $params ${key:+-d $key} luksOpen "$src" "$dst" <&1 + else + /sbin/cryptsetup $params ${key:+-d $key} create "$dst" "$src" <&1 + fi + if [ $? -ne 0 ]; then + ret=1 + continue + fi + if [ "$makeswap" = "yes" -a -b "/dev/mapper/$dst" ]; then + mkswap "/dev/mapper/$dst" 2>/dev/null >/dev/null + fi + done < /etc/crypttab + return $ret +} + if [ "$CONSOLETYPE" = "vt" -a -x /sbin/setsysfont ]; then /sbin/setsysfont fi @@ -259,6 +370,13 @@ if [ -f /etc/mdadm.conf ]; then /sbin/mdadm -A -s fi +if [ -f /etc/crypttab ]; then + s=$"Starting disk encryption:" + echo "$s" + init_crypto 0 && success "$s" || failure "$s" + echo +fi + # Device mapper & related initialization if ! LC_ALL=C fgrep -q "device-mapper" /proc/devices 2>/dev/null ; then modprobe dm-mod >/dev/null 2>&1 @@ -531,6 +649,13 @@ fi # Use the hardware RNG to seed the entropy pool, if available #[ -x /sbin/rngd -a -c /dev/hw_random ] && rngd +if [ -f /etc/crypttab ]; then + s=$"Starting disk encryption using the RNG:" + echo "$s" + init_crypto 1 && success "$s" || failure "$s" + echo +fi + # Configure machine if necessary. if [ -f /.unconfigured ]; then if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; then -- cgit v1.2.1