#!/bin/sh # cryptsetup functions for rc-scripts # if invoked standalone, processes /etc/cryptab like on boot/shutdown 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 local param value rc ret mke2fs mdir # call mknodes as the dm node could be missing if device was opened from # initrd. # XXX: shouldn't udev handle the nodes creation here? /sbin/dmsetup mknodes 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 nls "INSECURE MODE FOR %s" "$key" ret=1 fi if [ "$owner" != root ]; then nls "INSECURE OWNER FOR %s" "$key" ret=1 fi else nls "Key file for %s not found, skipping" "$dst" continue fi else key="" fi params="" makeswap="" mke2fs="" 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 nls "%s: no value for cipher option, skipping" "$dst" skip="yes" fi ;; size) params="$params -s $value" if [ -z "$value" ]; then nls "%s: no value for size option, skipping" "$dst" skip="yes" fi ;; hash) params="$params -h $value" if [ -z "$value" ]; then nls "%s: no value for hash option, skipping" "$dst" skip="yes" fi ;; verify) params="$params -y" ;; swap) makeswap=yes ;; tmp) mke2fs=yes esac done if [ "$skip" = "yes" ]; then ret=1 continue fi if echo "$src" | grep -q -E "^UUID=" ; then src="/dev/disk/by-uuid/${src##UUID=}" fi if [ ! -b "$src" ]; then nls "$src: No such device" ret=1 continue fi if /sbin/cryptsetup --disable-locks isLuks "$src" 2>/dev/null; then if key_is_random "$key"; then nls "%s: LUKS requires non-random key, skipping" "$dst" ret=1 continue fi if [ -n "$params" ]; then nls "%s: options are invalid for LUKS partitions, ignoring them" "$dst" fi /sbin/cryptsetup --disable-locks ${key:+-d $key} luksOpen "$src" "$dst" <&1 fi rc=$? if [ $rc -ne 0 ]; then ret=1 continue fi if [ -b "/dev/mapper/$dst" ]; then if [ "$makeswap" = "yes" ]; then mkswap "/dev/mapper/$dst" 2>/dev/null >/dev/null fi if [ "$mke2fs" = "yes" ]; then if mke2fs "/dev/mapper/$dst" 2>/dev/null >/dev/null \ && mdir=$(mktemp -d /tmp/mountXXXXXX); then mount "/dev/mapper/$dst" "$mdir" && chmod 1777 "$mdir" umount "$mdir" rmdir "$mdir" fi fi fi done < /etc/crypttab return $ret } halt_crypto() { local fnval=0 dst src key while read dst src key; do [ -z "$dst" -o "${dst#\#}" != "$dst" ] && continue if [ -b "/dev/mapper/$dst" ]; then if LC_ALL=C /sbin/dmsetup info "$dst" | grep -q '^Open count: *0$'; then /sbin/cryptsetup --disable-locks remove "$dst" else fnval=1 fi fi done < /etc/crypttab return $fnval } [ -f /etc/crypttab ] || return # if not invoked directly, return to caller case "$0" in *cryptsetup);; *) return;; esac . /etc/rc.d/init.d/functions RETVAL=0 # See how we were called. case "$1" in start) show "Starting disk encryption"; started init_crypto 1 && deltext; ok ;; stop) show "Stopping disk encryption"; started halt_crypto && deltext; ok ;; status) # this is way overkill, but at least we have some status output... if grep -qF dm_crypt /proc/modules; then nls "dm-crypt module is loaded" else nls "dm-crypt module is not loaded" fi ;; *) msg_usage "$0 {start|stop|status}" exit 3 esac exit $RETVAL