X-Original-To: alpine-devel@lists.alpinelinux.org Delivered-To: alpine-devel@mail.alpinelinux.org Received: from out2-smtp.messagingengine.com (out2-smtp.messagingengine.com [66.111.4.26]) (using TLSv1 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.alpinelinux.org (Postfix) with ESMTPS id 08F5BDC008C for ; Thu, 27 Jun 2013 06:12:10 +0000 (UTC) Received: from compute5.internal (compute5.nyi.mail.srv.osa [10.202.2.45]) by gateway1.nyi.mail.srv.osa (Postfix) with ESMTP id A748120EF1 for ; Thu, 27 Jun 2013 02:12:05 -0400 (EDT) Received: from frontend2.nyi.mail.srv.osa ([10.202.2.161]) by compute5.internal (MEProxy); Thu, 27 Jun 2013 02:12:05 -0400 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d= messagingengine.com; h=from:to:subject:date:message-id; s= smtpout; bh=9nxA7aHHQyI39BvLdKhVxTQT4DM=; b=QexqF+0/rHMXCaWc+qJo aH5meMbyx91LH6CxB012hN6JP13mi57q9wplWCnecsbb8ZCVUTRazBVDQ9Sf+H23 /WjMDJayDwuPrAZYKPQflN62gNLtRoOqOfS9IUIX+UWFQaQLLyl7UuqgPmfpnLI/ o2JwaH3MxsZBmBQjw9dCnPU= X-Sasl-enc: K0OEPh+WT2Tg9RMfYFBFDrguIFYhYtvXUGTgFwHdq0vA 1372313524 Received: from localhost (unknown [69.86.161.244]) by mail.messagingengine.com (Postfix) with ESMTPA id EB194680274 for ; Thu, 27 Jun 2013 02:12:04 -0400 (EDT) From: Dubiousjim To: alpine-devel@lists.alpinelinux.org Subject: [alpine-devel] [PATCH 1/2] main/cryptsetup: add rc script from Gentoo Date: Thu, 27 Jun 2013 02:12:03 -0400 Message-Id: <91763992d9005781f59c99577620f15f8e794988.1372313524.git.dubiousjim@gmail.com> X-Mailer: git-send-email 1.8.3.1 X-Mailinglist: alpine-devel Precedence: list List-Id: Alpine Development List-Unsubscribe: List-Post: List-Help: List-Subscribe: One can already open a crypted / at startup using cryptroot= and cryptdm= options in the kernel command line, thanks to mkinitfs's init script. This patch enables opening OTHER crypted volumes at startup, and also using a crypted swap. --- main/cryptsetup/APKBUILD | 19 ++- main/cryptsetup/dmcrypt.confd | 100 ++++++++++++ main/cryptsetup/dmcrypt.initd | 351 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 466 insertions(+), 4 deletions(-) create mode 100644 main/cryptsetup/dmcrypt.confd create mode 100644 main/cryptsetup/dmcrypt.initd diff --git a/main/cryptsetup/APKBUILD b/main/cryptsetup/APKBUILD index 96ddee1..5026770 100644 --- a/main/cryptsetup/APKBUILD +++ b/main/cryptsetup/APKBUILD @@ -9,7 +9,10 @@ license="GPL" depends= makedepends="lvm2-dev openssl-dev popt-dev util-linux-dev !libiconv-dev" subpackages="$pkgname-dev $pkgname-doc $pkgname-libs" -source="http://$pkgname.googlecode.com/files/$pkgname-$pkgver.tar.bz2" +source="http://$pkgname.googlecode.com/files/$pkgname-$pkgver.tar.bz2 + dmcrypt.initd + dmcrypt.confd + " build() { cd "$srcdir"/$pkgname-$pkgver @@ -26,6 +29,8 @@ package() { cd "$srcdir"/$pkgname-$pkgver make DESTDIR=$pkgdir install || return 1 rm "$pkgdir"/lib/*.la + install -Dm755 "$srcdir"/dmcrypt.initd "$pkgdir"/etc/init.d/dmcrypt + install -Dm644 "$srcdir"/dmcrypt.confd "$pkgdir"/etc/conf.d/dmcrypt } libs() { @@ -34,6 +39,12 @@ libs() { mv "$pkgdir"/lib "$subpkgdir"/ } -md5sums="f374d11e3b0e7ca0f805756fd02e34ff cryptsetup-1.6.1.tar.bz2" -sha256sums="baf36e663c03eb6440482d91c486d61ed47ce5c9268ad04c18ca09082755149c cryptsetup-1.6.1.tar.bz2" -sha512sums="6d85720a33e05f2687f0ac9dd6730d025a14389091c06c047983b4875edc55db1b5c4878f7dee1720be192fa1ab06df2c7d0a0edfea0fb5bd787ee73a33302ca cryptsetup-1.6.1.tar.bz2" +md5sums="f374d11e3b0e7ca0f805756fd02e34ff cryptsetup-1.6.1.tar.bz2 +00e86ec09734b4175815d2c62403e11c dmcrypt.initd +ebd6cb30eb012f685329ffd4f3ff3fdb dmcrypt.confd" +sha256sums="baf36e663c03eb6440482d91c486d61ed47ce5c9268ad04c18ca09082755149c cryptsetup-1.6.1.tar.bz2 +2d9a7ce340fa4655b7c721998552e2bdfdec8d0f529b51f6e61e3f545c679782 dmcrypt.initd +02ed489b1a339e41a8721a07546bb9a33e13c61337666a6b3c3318f8e0dbd16f dmcrypt.confd" +sha512sums="6d85720a33e05f2687f0ac9dd6730d025a14389091c06c047983b4875edc55db1b5c4878f7dee1720be192fa1ab06df2c7d0a0edfea0fb5bd787ee73a33302ca cryptsetup-1.6.1.tar.bz2 +6ad41cd8e0f538bafbf341613a58e5509c2b6c8bbfa9fb40f85952af6a872a5809b451278cf6ae6c635b426611a09ff840070bcea462fd4656ce3bce4e85c021 dmcrypt.initd +16f16feccda8173892953f945b1cf16ae42d121fee591f0cc786f89e7eaf6dac30b2cf7ff6687a183c7865d556d7c7478ea0335f64da9fc4d772b9b946561213 dmcrypt.confd" diff --git a/main/cryptsetup/dmcrypt.confd b/main/cryptsetup/dmcrypt.confd new file mode 100644 index 0000000..86a745a --- /dev/null +++ b/main/cryptsetup/dmcrypt.confd @@ -0,0 +1,100 @@ +# /etc/conf.d/dmcrypt +# Based on https://raw.github.com/udeved/pkgbuilds/master/scripts/openrc-plugins/cryptsetup/conf.d/1.0.6-dmcrypt.confd + +# For people who run dmcrypt on top of some other layer (like raid), +# use rc_need to specify that requirement. See the runscript(8) man +# page for more information. + +#-------------------- +# Instructions +#-------------------- + +# Note regarding the syntax of this file. This file is *almost* sh, +# but each line is evaluated separately. Separate swaps/targets can be +# specified. The init-script which reads this file assumes that a +# swap= or target= line starts a new section, similar to lilo or grub +# configuration. + +# Note when using gpg keys and /usr on a separate partition, you will +# have to copy /usr/bin/gpg to /bin/gpg so that it will work properly +# and ensure that gpg has been compiled statically. +# See http://bugs.gentoo.org/90482 for more information. + +# Note that the init-script which reads this file detects whether your +# partition is LUKS or not. No mkfs is run unless you specify a makefs +# option. + +# Global options: +#---------------- + +# Max number of checks to perform (1 per second) +#dmcrypt_max_timeout=120 + +# Arguments: +#----------- +# target= == Mapping name for partition. +# swap= == Mapping name for swap partition. +# source='' == Real device for partition. +# key='[:]' == Fullpath from / or from inside removable media. +# remdev='' == Device that will be assigned to removable media. +# gpg_options='' == Default are --quiet --decrypt +# options='' == cryptsetup, for LUKS you can only use --readonly +# loop_file='' == Loopback file. +# pre_mount='cmds' == commands to execute before mounting partition. +# post_mount='cmds' == commands to execute after mounting partition. +#----------- +# Supported Modes +# gpg == decrypt and pipe key into cryptsetup. +# Note: new-line character must not be part of key. +# Command to erase \n char: 'cat key | tr -d '\n' > cleanKey' + +#-------------------- +# dm-crypt examples +#-------------------- + +## swap +# Swap partitions. These should come first so that no keys make their +# way into unencrypted swap. +# If no options are given, they will default to: -c aes -h sha1 -d /dev/urandom +# If no makefs is given then mkswap will be assumed +#swap=crypt-swap +#source='/dev/hda2' + +## /home with passphrase +#target=crypt-home +#source='/dev/hda5' + +## /home with regular keyfile +#target=crypt-home +#source='/dev/hda5' +#key='/full/path/to/homekey' + +## /home with gpg protected key +#target=crypt-home +#source='/dev/hda5' +#key='/full/path/to/homekey:gpg' + +## /home with regular keyfile on removable media(such as usb-stick) +#target=crypt-home +#source='/dev/hda5' +#key='/full/path/to/homekey' +#remdev='/dev/sda1' + +##/home with gpg protected key on removable media(such as usb-stick) +#target=crypt-home +#source='/dev/hda5' +#key='/full/path/to/homekey:gpg' +#remdev='/dev/sda1' + +##/tmp with regular keyfile +#target=crypt-tmp +#source='/dev/hda6' +#key='/full/path/to/tmpkey' +#pre_mount='/sbin/mkreiserfs -f -f ${dev}' +#post_mount='chown root:root ${mount_point}; chmod 1777 ${mount_point}' + +## Loopback file example +#mount='crypt-loop-home' +#source='/dev/loop0' +#loop_file='/mnt/crypt/home' + diff --git a/main/cryptsetup/dmcrypt.initd b/main/cryptsetup/dmcrypt.initd new file mode 100644 index 0000000..3ed42c0 --- /dev/null +++ b/main/cryptsetup/dmcrypt.initd @@ -0,0 +1,351 @@ +#!/sbin/runscript +# Copyright 1999-2013 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# Based on https://raw.github.com/udeved/pkgbuilds/master/scripts/openrc-plugins/cryptsetup/init.d/1.5.1-dmcrypt.rc + +depend() { + before checkfs fsck +} + +# We support multiple dmcrypt instances based on $SVCNAME +execute_hook="dm_crypt_execute_dmcrypt" +# XXX: Should we drop this ? +# execute_hook="dm_crypt_execute_localmount" +conf_file="/etc/conf.d/${SVCNAME}" + +# Get splash helpers if available. +if [ -e /sbin/splash-functions.sh ] ; then + . /sbin/splash-functions.sh +fi + +# Setup mappings for an individual target/swap +# Note: This relies on variables localized in the main body below. +dm_crypt_execute_dmcrypt() { + local dev ret mode foo + + if [ -n "${target}" ] ; then + # let user set options, otherwise leave empty + : ${options:=' '} + elif [ -n "${swap}" ] ; then + if cryptsetup isLuks ${source} 2>/dev/null ; then + ewarn "The swap you have defined is a LUKS partition. Aborting crypt-swap setup." + return + fi + target=${swap} + # swap contents do not need to be preserved between boots, luks not required. + # suspend2 users should have initramfs's init handling their swap partition either way. + : ${options:='-c aes -h sha1 -d /dev/urandom'} + : ${pre_mount:='mkswap ${dev}'} + else + return + fi + if [ "x${source#UUID}" != "x${source}" ]; then + source=${source#UUID=} + source="$(blkid -U ${source})" + fi + if [ -z "${source}" ] && [ ! -e "${source}" ] ; then + ewarn "source \"${source}\" for ${target} missing, skipping..." + return + fi + + if [ -n "${loop_file}" ] ; then + dev="/dev/mapper/${target}" + ebegin " Setting up loop device ${source}" + losetup ${source} ${loop_file} + fi + + # cryptsetup: + # luksOpen # is $source + # create # is $target + local arg1="create" arg2="${target}" arg3="${source}" luks=0 + + cryptsetup isLuks ${source} 2>/dev/null && { arg1="luksOpen"; arg2="${source}"; arg3="${target}"; luks=1; } + + # Older versions reported: + # ${target} is active: + # Newer versions report: + # ${target} is active[ and is in use.] + if cryptsetup status ${target} | egrep -q ' is active' ; then + einfo "dm-crypt mapping ${target} is already configured" + return + fi + splash svc_input_begin ${SVCNAME} >/dev/null 2>&1 + + # Handle keys + if [ -n "${key}" ] ; then + read_abort() { + # some colors + local ans savetty resettty + [ -z "${NORMAL}" ] && eval $(eval_ecolors) + einfon " $1? (${WARN}yes${NORMAL}/${GOOD}No${NORMAL}) " + shift + # This is ugly as s**t. But POSIX doesn't provide `read -t`, so + # we end up having to implement our own crap with stty/etc... + savetty=$(stty -g) + resettty='stty ${savetty}; trap - EXIT HUP INT TERM' + trap 'eval "${resettty}"' EXIT HUP INT TERM + stty -icanon + [ "${1}" = -t ] && stty min 0 time "$(( $2 * 10 ))" + ans=$(dd count=1 bs=1 2>/dev/null) || ans='' + eval "${resettty}" + if [ -z "${ans}" ] ; then + printf '\r' + else + echo + fi + case ${ans} in + [yY]) return 0;; + *) return 1;; + esac + } + + # Notes: sed not used to avoid case where /usr partition is encrypted. + mode=${key/*:/} && ( [ "${mode}" = "${key}" ] || [ -z "${mode}" ] ) && mode=reg + key=${key/:*/} + case "${mode}" in + gpg|reg) + # handle key on removable device + if [ -n "${remdev}" ] ; then + # temp directory to mount removable device + local mntrem="${RC_SVCDIR}/dm-crypt-remdev.$$" + if [ ! -d "${mntrem}" ] ; then + if ! mkdir -p "${mntrem}" ; then + ewarn "${source} will not be decrypted ..." + einfo "Reason: Unable to create temporary mount point '${mntrem}'" + return + fi + fi + i=0 + einfo "Please insert removable device for ${target}" + while [ ${i} -lt ${dmcrypt_max_timeout:-120} ] ; do + foo="" + if mount -n -o ro "${remdev}" "${mntrem}" 2>/dev/null >/dev/null ; then + # keyfile exists? + if [ ! -e "${mntrem}${key}" ] ; then + umount -n "${mntrem}" + rmdir "${mntrem}" + einfo "Cannot find ${key} on removable media." + read_abort "Abort" ${read_timeout:--t 1} && return + else + key="${mntrem}${key}" + break + fi + else + [ -e "${remdev}" ] \ + && foo="mount failed" \ + || foo="mount source not found" + fi + : $((i += 1)) + read_abort "Stop waiting after $i attempts (${foo})" -t 1 && return + done + else # keyfile ! on removable device + if [ ! -e "${key}" ] ; then + ewarn "${source} will not be decrypted ..." + einfo "Reason: keyfile ${key} does not exist." + return + fi + fi + ;; + *) + ewarn "${source} will not be decrypted ..." + einfo "Reason: mode ${mode} is invalid." + return + ;; + esac + else + mode=none + fi + ebegin " ${target} using: ${options} ${arg1} ${arg2} ${arg3}" + if [ "${mode}" = "gpg" ] ; then + : ${gpg_options:='-q -d'} + # gpg available ? + if type -p gpg >/dev/null ; then + for i in 0 1 2 ; do + # paranoid, don't store key in a variable, pipe it so it stays very little in ram unprotected. + # save stdin stdout stderr "values" + gpg ${gpg_options} ${key} 2>/dev/null | cryptsetup ${options} ${arg1} ${arg2} ${arg3} + ret=$? + [ ${ret} -eq 0 ] && break + done + eend ${ret} "failure running cryptsetup" + else + ewarn "${source} will not be decrypted ..." + einfo "Reason: cannot find gpg application." + einfo "You have to install app-crypt/gnupg first." + einfo "If you have /usr on its own partition, try copying gpg to /bin ." + fi + else + if [ "${mode}" = "reg" ] ; then + cryptsetup ${options} -d ${key} ${arg1} ${arg2} ${arg3} + ret=$? + eend ${ret} "failure running cryptsetup" + else + cryptsetup ${options} ${arg1} ${arg2} ${arg3} + ret=$? + eend ${ret} "failure running cryptsetup" + fi + fi + if [ -d "${mntrem}" ] ; then + umount -n ${mntrem} 2>/dev/null >/dev/null + rmdir ${mntrem} 2>/dev/null >/dev/null + fi + splash svc_input_end ${SVCNAME} >/dev/null 2>&1 + + if [ ${ret} -ne 0 ] ; then + cryptfs_status=1 + else + if [ -n "${pre_mount}" ] ; then + dev="/dev/mapper/${target}" + ebegin " pre_mount: ${pre_mount}" + eval "${pre_mount}" > /dev/null + ewend $? || cryptfs_status=1 + fi + fi +} + +# Run any post_mount commands for an individual mount +# +# Note: This relies on variables localized in the main body below. +dm_crypt_execute_localmount() { + local mount_point + + [ -z "${target}" ] && [ -z "${post_mount}" ] && return + + if ! cryptsetup status ${target} | egrep -q '\/dev/null + eend $? || cryptfs_status=1 + fi +} + +# Lookup optional bootparams +get_bootparam_val() { + # We're given something like: + # foo=bar=cow + # Return the "bar=cow" part. + case $1 in + *\=*) + local key=$(echo "$1" | cut -f1 -d=) + echo "$1" | cut -c $(( ${#key} + 2 )) + ;; + esac +} + +start() { + local header=true cryptfs_status=0 + local gpg_options key loop_file target targetline options pre_mount post_mount source swap remdev + + local x + for x in $(cat /proc/cmdline) ; do + case "${x}" in + key_timeout\=*) + local KEY_TIMEOUT=$(get_bootparam_val "${x}") + if [ ${KEY_TIMEOUT} -gt 0 ] ; then + read_timeout="-t ${KEY_TIMEOUT}" + fi + ;; + esac + done + + while read -u 3 targetline ; do + case ${targetline} in + # skip comments and blank lines + ""|"#"*) continue ;; + # skip service-specific openrc configs #377927 + rc_*) continue ;; + esac + + ${header} && ebegin "Setting up dm-crypt mappings" + header=false + + # check for the start of a new target/swap + case ${targetline} in + target=*|swap=*) + # If we have a target queued up, then execute it + ${execute_hook} + + # Prepare for the next target/swap by resetting variables + unset gpg_options key loop_file target options pre_mount post_mount source swap remdev + ;; + + gpg_options=*|remdev=*|key=*|loop_file=*|options=*|pre_mount=*|post_mount=*|source=*) + if [ -z "${target}${swap}" ] ; then + ewarn "Ignoring setting outside target/swap section: ${targetline}" + continue + fi + ;; + + dmcrypt_max_timeout=*) + # ignore global options + continue + ;; + + *) + ewarn "Skipping invalid line in ${conf_file}: ${targetline}" + ;; + esac + + # Queue this setting for the next call to dm_crypt_execute_xxx + eval "${targetline}" + done 3< ${conf_file} + + # If we have a target queued up, then execute it + ${execute_hook} + + ewend ${cryptfs_status} "Failed to setup dm-crypt devices" +} + +stop() { + local line header + + # Break down all mappings + header=true + egrep "^(target|swap)=" ${conf_file} | \ + while read line ; do + ${header} && einfo "Removing dm-crypt mappings" + header=false + + target= swap= + eval ${line} + + [ -n "${swap}" ] && target=${swap} + if [ -z "${target}" ] ; then + ewarn "invalid line in ${conf_file}: ${line}" + continue + fi + + ebegin " ${target}" + cryptsetup remove ${target} + eend $? + done + + # Break down loop devices + header=true + grep '^source=./dev/loop' ${conf_file} | \ + while read line ; do + ${header} && einfo "Detaching dm-crypt loop devices" + header=false + + source= + eval ${line} + + ebegin " ${source}" + losetup -d "${source}" + eend $? + done + + return 0 +} + -- 1.8.3.1 --- Unsubscribe: alpine-devel+unsubscribe@lists.alpinelinux.org Help: alpine-devel+help@lists.alpinelinux.org ---