#!/bin/sh function help() { echo "usage: ${0} [OPTIONS]" echo echo "where OPTIONS are:" echo " -1 use Yubico key slot 1" echo " -2 use Yubico key slot 2 (default)" echo " -d DEVICE add key to device DEVICE" echo " -h show this help" } TMPDIR="$(mktemp --directory --tmpdir=/tmp/ .$(basename ${0})-${$}-XXXXXX)" SLOT="2" SERIAL="$(ykinfo -sq)" while getopts "12d:h" opt; do case ${opt} in 1) SLOT="1" ;; 2) SLOT="2" ;; d) DEVICE="${OPTARG}" ;; h) help exit 0 ;; esac done # check we have all information if [ -z "${DEVICE}" ]; then echo "No device given." >&2 help exit 1 elif [ ! -b "${DEVICE}" ]; then echo "Device '${DEVICE}' does not exist or is not a block device." >&2 exit 1 elif ! cryptsetup isLuks "${DEVICE}" 2>/dev/null; then echo "Device '${DEVICE}' is not a LUKS device." >&2 exit 1 elif [ -z "${SERIAL}" ]; then echo "Did not get a serial number from key." >&2 exit 1 fi # This directroy should exist, but we create it in case it does not if [ ! -d "/etc/ykfde.d/" ]; then install -d -m 0700 "/etc/ykfde.d/" fi # generate the challenge if ! makepasswd --chars=64 | tr -d '\n' > "/etc/ykfde.d/challenge-${SERIAL}"; then exit 1 fi # generate response if ! ykchalresp -${SLOT} "$(cat "/etc/ykfde.d/challenge-${SERIAL}")" | tr -d '\n' > "${TMPDIR}/ykfde-response"; then # ykchalresp should have shouted, so do not complain here exit 1 fi # add key to LUKS device if ! cryptsetup luksAddKey "${DEVICE}" "${TMPDIR}/ykfde-response"; then # cryptsetup should have shouted, ... exit 1 fi # shred response and remove temporary directory shred --remove "${TMPDIR}/ykfde-response" rm -rf "${TMPDIR}" echo "Please do not forget to remove old keys when changing challenge!" echo "Now make sure /etc/crypttab.initramfs has the needed entry, then" echo "run 'mkinitcpio' to build a new initramfs!"