aboutsummaryrefslogtreecommitdiffstats
path: root/rc.d
diff options
context:
space:
mode:
authorMiloslav Trmac <mitr@volny.cz>2006-06-01 02:41:11 +0000
committerMiloslav Trmac <mitr@volny.cz>2006-06-01 02:41:11 +0000
commitd8a3e16c701778a2774b54eb238a43b0e51719c5 (patch)
tree0cae42b824c9b25c56e6d7e7a5729fe2aa7d2395 /rc.d
parent361d52729d1534fdbb454d7abc41069a353b1541 (diff)
downloadinitscripts-d8a3e16c701778a2774b54eb238a43b0e51719c5.tar
initscripts-d8a3e16c701778a2774b54eb238a43b0e51719c5.tar.gz
initscripts-d8a3e16c701778a2774b54eb238a43b0e51719c5.tar.bz2
initscripts-d8a3e16c701778a2774b54eb238a43b0e51719c5.tar.xz
initscripts-d8a3e16c701778a2774b54eb238a43b0e51719c5.zip
Add encrypted swap and non-root filesystem support (#127378, based on
a patch by W. Michael Petullo <redhat@flyn.org> and Debian's cryptsetup package)
Diffstat (limited to 'rc.d')
-rwxr-xr-xrc.d/init.d/halt32
-rwxr-xr-xrc.d/rc.sysinit125
2 files changed, 156 insertions, 1 deletions
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