#!/bin/bash -p

set -euo pipefail

# sanitize environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
YKFDE_SLOT_CHECK=""
YKFDE_CHALLENGE_SLOT="2"
#DBG=""
YKFDE_CHALLENGE_PASSWORD_NEEDED=""
YKFDE_CHALLENGE=""
YKFDE_RESPONSE=""
YKFDE_PASSPHRASE=""

if [ -r /etc/ykfde.conf ]; then
  # shellcheck source=ykfde.conf
  . /etc/ykfde.conf
else
  echo "WARNING: Can't access /etc/ykfde.conf. Falling back to defaults."
fi

YKFDE_SLOT_CHECK="$(ykinfo -q -"$YKFDE_CHALLENGE_SLOT")"
[ "${DBG:-}" ] && printf '%s\n' " > YubiKey slot status 'ykinfo -q -$YKFDE_CHALLENGE_SLOT': $YKFDE_SLOT_CHECK"

if [ "$YKFDE_SLOT_CHECK" != 1 ]; then
  printf '%s\n' "ERROR: Chosen YubiKey slot '$YKFDE_CHALLENGE_SLOT' isn't configured. Please choose slot configured for 'HMAC-SHA1 Challenge-Response' mode in '/etc/ykfde.conf'"
  exit 1
fi

printf '%s\n' "WARNING: This script will run 'cryptsetup luksFormat $*'.  If this is not what you intended, please abort."

[ -z "$YKFDE_CHALLENGE" ] && YKFDE_CHALLENGE_PASSWORD_NEEDED=1
[ "$YKFDE_CHALLENGE_PASSWORD_NEEDED" ] && YKFDE_CHALLENGE=""

while [ -z "$YKFDE_CHALLENGE" ]; do
  echo " > Please provide the challenge."
  printf "   Enter challenge: "
  if [ "${DBG:-}" ]; then read -r YKFDE_CHALLENGE; else read -r -s YKFDE_CHALLENGE; fi
  printf "\\n > Please repeat the challenge.\\n"
  printf "   Enter challenge: "
  if [ "${DBG:-}" ]; then read -r YKFDE_CHALLENGE2; else read -r -s YKFDE_CHALLENGE2; fi
  if [ "$YKFDE_CHALLENGE" != "$YKFDE_CHALLENGE2" ]; then
    echo "WARNING: Challenges do not match. Try again."
    YKFDE_CHALLENGE=""
  fi
  [ "$YKFDE_CHALLENGE" ] && YKFDE_CHALLENGE="$(printf %s "$YKFDE_CHALLENGE" | sha256sum | awk '{print $1}')"
  # if /NOT/ DBG, we need to output \n here.
  [ "${DBG:-}" ] || echo
done

if [ -z "$YKFDE_CHALLENGE" ]; then
  echo "ERROR: ykfde challenge is empty. Operation aborted."
  exit 1
fi

while [ -z "$YKFDE_RESPONSE" ]; do
  [ "${DBG:-}" ] && printf '%s\n' "   Running: 'ykchalresp -$YKFDE_CHALLENGE_SLOT $YKFDE_CHALLENGE'..."
  echo "   Remember to touch the device if necessary."
  YKFDE_RESPONSE="$(printf %s "$YKFDE_CHALLENGE" | ykchalresp -"$YKFDE_CHALLENGE_SLOT" -i- | tr -d '\n')" || true
  [ "${DBG:-}" ] && printf '%s\n' "   Received response: '$YKFDE_RESPONSE'"
done

if [ "$YKFDE_RESPONSE" ]; then
  if [ "$YKFDE_CHALLENGE_PASSWORD_NEEDED" ]; then
    YKFDE_PASSPHRASE="$YKFDE_CHALLENGE$YKFDE_RESPONSE"
  else
    YKFDE_PASSPHRASE="$YKFDE_RESPONSE"
  fi
fi

if [ "$YKFDE_PASSPHRASE" ]; then
  [ "${DBG:-}" ] && printf '%s\n' " > Passing '$YKFDE_PASSPHRASE' to 'cryptsetup'"
  printf '%s\n' "$YKFDE_PASSPHRASE" | cryptsetup luksFormat "$@"
else
  echo "ERROR: ykfde passphrase is empty. Operation aborted."
  exit 1
fi

echo "   New LUKS device successfully formatted"

exit 0
