#!/bin/sh








PREREQ="cryptroot"
prereqs()
{
	echo "${PREREQ}"
}

case $1 in
(prereqs)
	prereqs
	exit 0
	;;
esac

. /usr/share/initramfs-tools/hook-functions




#********************************************************************************
#*** Check Whether This Hook-Script Needs To Be Applied                       ***
#********************************************************************************
#Note: The initramfs image needs only to be adapted for the usage of decrypt_openpgp when that is configured to be used for the “/-filesystem”. For the following check to work, it is necessary that this hook-script pre-requires the “cryptroot”-hook-script, which is set above.
if [ ! -x "${DESTDIR}"/lib/cryptsetup/scripts/decrypt_openpgp ]; then
	exit 0
fi




#********************************************************************************
#*** Initialisation                                                           ***
#********************************************************************************
#read all the options to cryptsetup, specified via the “/-filesystem”-entry in “/etc/crypttab”
cryptsetup_options="$( cat "${DESTDIR}"/conf/conf.d/cryptroot )"
#parse the options to cryptsetup required for this hook-script
target="$( printf "%s" "${cryptsetup_options}"  |  sed -n 's/^\(.*,\)*target=\([^,]*\)\(,.*\)*$/\2/p' )"

#read all the options to the Cryptsetup OpenPGP Scripts, specified via the third field of the “/-filesystem”-entry in “/etc/crypttab”
cryptsetup_openpgp_scripts_options="$( printf "%s" "${cryptsetup_options}"  |  sed -n 's/^\(.*,\)*key=\([^,]*\)\(,.*\)*$/\2/p' )"
#parse the options to the Cryptsetup OpenPGP Scripts required for this hook-script
pathname="$( printf "%s" "${cryptsetup_openpgp_scripts_options}"  |  sed -n 's/^\(.*:\)*pathname=\([^:]*\)\(:.*\)*$/\2/p' )"
device="$( printf "%s" "${cryptsetup_openpgp_scripts_options}"  |  sed -n 's/^\(.*:\)*device=\([^:]*\)\(:.*\)*$/\2/p' )"
key_file_in_initramfs_images="$( printf "%s" "${cryptsetup_openpgp_scripts_options}"  |  sed -n 's/^\(.*:\)*key_file_in_initramfs_images\(:.*\)*$/yes/p' )"


#check whether the “pathname”-option to the Cryptsetup OpenPGP Scripts is set
if [ -z "${pathname}" ]; then
	printf "Error: The third field of the “/-filesystem”-entry in “/etc/crypttab” does not set the “pathname”-option to the Cryptsetup OpenPGP Scripts.\n" >&2
	exit 2
fi

#check whether at least one of the “device”- and the “key_file_in_initramfs_images”-option to the Cryptsetup OpenPGP Scripts is set
if [ -z "${device}"  -a  "${key_file_in_initramfs_images}" != yes ]; then
	printf "Error: The third field of the “/-filesystem”-entry in “/etc/crypttab” neither sets the “device”- nor the “key_file_in_initramfs_images”-option to the Cryptsetup OpenPGP Scripts.\n" >&2
	exit 2
fi

#check whether both, the “device”- and the “key_file_in_initramfs_images”-option to the Cryptsetup OpenPGP Scripts are set and if so print a warning
if [ -n "${device}"  -a  "${key_file_in_initramfs_images}" = yes ]; then
	printf "Warning: The third field of the “/-filesystem”-entry in “/etc/crypttab” sets both, the “device”- and the “key_file_in_initramfs_images”-option to the Cryptsetup OpenPGP Scripts. The latter is ignored.\n" >&2
fi




#********************************************************************************
#*** Include Either “passdev” Or The Key File In The Initramfs Image          ***
#********************************************************************************
#Note: “Within” an initramfs image (during booting), there are only two possible locations for the key file: It is either part of a not yet mounted filesystem or part of the initramfs image itself. As it makes no sense to have both, this hook-script either includes “passdev” (when the “device”-option to the Cryptsetup OpenPGP Scripts is set in the third field of the “/-filesystem”-entry in “/etc/crypttab”) or the key file (when the “key_file_in_initramfs_images”-option to the Cryptsetup OpenPGP Scripts is set in the third field of the “/-filesystem”-entry in “/etc/crypttab”). For several reasons, including security reasons (it is for example usually a bad idea to include a key file in initramfs images themselves, because then it would get spread more easily), the former is preferred if both options are set.
if [ -n "${device}" ]; then
	#Note: “passdev” is part of the “cryptsetup”-package. This is also the package of the Cryptsetup OpenPGP Scripts, thus it is not necessary to check whether it is installed.
	
	#include “passdev” in the initramfs image
	copy_exec /lib/cryptsetup/scripts/passdev
elif [ "${key_file_in_initramfs_images}" = yes ]; then
	#set the directory and the new pathname of the key file “within” the initramfs image
	KEY_FILE_DIRECTORY='/etc/dm-crypt/keys'
	
	new_pathname="${KEY_FILE_DIRECTORY}"/"${target}"
	
	
	#check whether the “pathname”-option to the Cryptsetup OpenPGP Scripts specifies an existing, readable and regular file
	if [ ! -r "${pathname}"  -o  ! -f "${pathname}" ]; then
		printf "Error: The key file “${pathname}”, specified by the “pathname”-option to the Cryptsetup OpenPGP Scripts in the third field of the “/-filesystem”-entry in “/etc/crypttab”, does not exist, is not readable or is not a regular file.\n" >&2
		exit 1
	fi
	
	
	#include the key file in the initramfs image
	mkdir -p "${DESTDIR}"/"${KEY_FILE_DIRECTORY}"
	chmod u=rwx,go= "${DESTDIR}"/"${KEY_FILE_DIRECTORY}"
	
	#Note: For security reasons a key file should not be copied if this can be avoided. It is enough here to create a symbolic link, as it will be “dereferenced” later, when creating the initramfs image.
	ln -s "${pathname}" "${DESTDIR}"/"${new_pathname}"
	
	
	#print a warning that the key file is going to be included in the initramfs image
	printf "Warning: The key file “${pathname}” is going to be included in the initramfs image. This could be security problem.\n" >&2
	
	
	#store the new key file pathname to the cryptsetup configuration “within” the initramfs image
	quoted_new_pathname="$( printf "%s" "${new_pathname}"  |  sed 's/\//\\\//g' )"
	new_cryptsetup_openpgp_scripts_options="$( printf "%s" "${cryptsetup_openpgp_scripts_options}"  |  sed -n 's/^\(.*:\)*pathname=[^:]*/\1pathname='"${quoted_new_pathname}"'/p' )"
	quoted_new_cryptsetup_openpgp_scripts_options="$( printf "%s" "${new_cryptsetup_openpgp_scripts_options}"  |  sed 's/\//\\\//g' )"
	new_cryptsetup_options="$( printf "%s" "${cryptsetup_options}"  |  sed -n 's/^\(.*,\)*key=[^,]*/\1key='"${quoted_new_cryptsetup_openpgp_scripts_options}"'/p' )"
	
	printf "%s" "${new_cryptsetup_options}" > "${DESTDIR}"/conf/conf.d/cryptroot
fi




#********************************************************************************
#*** Include “base64” In The Initramfs Image                                  ***
#********************************************************************************
#Note: “base64” is part of the “coreutils”-package. This is an essential package, thus it is not necessary to check whether it is installed.

#include “base64” in the initramfs image
copy_exec /usr/bin/base64




#Note: “askpass” is already included in the initramfs image via the “cryptroot”-hook-script.




#TODO: Support other OpenPGP-implementations than “GnuPG”.
#********************************************************************************
#*** Include An OpenPGP-Implementation In The Initramfs Image                 ***
#********************************************************************************
#check for the package “gnupg” which contains “GnuPG”
if [ "$( dpkg-query --showformat='${Status}' --show gnupg 2> /dev/null )"  !=  "install ok installed" ]; then
	printf "Error: No known OpenPGP-implementation is installed.\n" >&2
	exit 1
fi

#include “GnuPG” in the initramfs image
copy_exec /usr/bin/gpg




exit 0
















#Copyright © 2008–2009, Christoph Anton Mitterer <mail@christoph.anton.mitterer.name>.
#All rights reserved.
#
#
#This program is free software: you can redistribute it and/or modify
#it under the terms of the GNU General Public License as published by
#the Free Software Foundation, either version 3 of the License, or
#(at your option) any later version.
#
#This program is distributed in the hope that it will be useful,
#but WITHOUT ANY WARRANTY; without even the implied warranty of
#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License
#along with this program.  If not, see <http://www.gnu.org/licenses/>.
