#!/usr/bin/bash # vim:ft=sh:fdm=marker:fmr={,} # archlabs installer library script file # this file is not meant to be run directly # sourcing this file in a non bash shell is not advised declare -g LUKS=0 declare -g LUKS_DEV="" declare -g LUKS_PART="" declare -g LUKS_PASS="" declare -g LUKS_UUID="" declare -g LUKS_NAME="cryptroot" luks_open() { LUKS_PART="" modprobe -a dm-mod dm_crypt unmount_partitions find_partitions 'part|crypt|lvm' || return 1 tput civis if (( COUNT == 1 )); then LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")" infobox "$_LuksOpen" "${_OnlyOne}: $LUKS_PART\n" 1 else tput civis LUKS_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" \ --title " $_LuksOpen " --menu "$_LuksMenuBody" 0 0 0 $PARTS)" [[ $? != 0 || $LUKS_PART == "" ]] && return 1 fi # get password and name for encryption luks_pass "$_LuksOpen" "$LUKS_NAME" || return 1 infobox "$_LuksOpen" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" 0 cryptsetup open --type luks $LUKS_PART "$LUKS_NAME" <<< "$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$LUKS_PASS")" 2>$ERR check_for_errors "cryptsetup open --type luks $LUKS_PART $LUKS_NAME" LUKS=1 luks_show return 0 } luks_pass() { local title="$1" local name="$2" LUKS_PASS="" LUKS_NAME="" tput cnorm local values values="$(dialog --stdout --separator '~' --ok-label "Submit" --backtitle "$BT" \ --title " $title " --insecure --mixedform "$_LuksOpenBody" 16 75 4 \ "$_Name" 1 1 "$name" 1 $((${#_Name} + 2)) 71 0 0 \ "$_Password" 2 1 "" 2 $((${#_Password} + 2)) 71 0 1 \ "$_Password2" 3 1 "" 3 $((${#_Password2} + 2)) 71 0 1 | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)" [[ $? != 0 || $values == "" ]] && return 1 name="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" | awk -F'~' '{print $1}')" # all of this is a bit hacky, but we don't ever want the passwords to be stored in plain text # so it decrypts the string '$values', gets the field we want, and re-encrypts it local pass pass2 pass="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" | awk -F'~' '{print $2}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)" pass2="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" | awk -F'~' '{print $3}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)" # due to the encryption the string while encrypted will not be empty local empty empty="$(openssl enc -pbkdf2 -a -salt -pass pass:$SALT <<< "")" if [[ $pass == "$empty" || "$pass" != "$pass2" ]]; then msgbox "$_ErrTitle" "$_PassErr\n$_TryAgain" luks_pass "$title" "$name" || return 1 fi LUKS_PASS="$pass" LUKS_NAME="$name" return 0 } luks_setup() { LUKS_PART="" modprobe -a dm-mod dm_crypt unmount_partitions if [[ $ROOT_PART == "" || $LVM -eq 1 ]]; then find_partitions 'part|lvm' || return 1 [[ $BOOT_PART != "" ]] && decr_count "$BOOT_PART" if (( COUNT == 1 )); then LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")" infobox "$_LuksEncrypt" "${_OnlyOne}: $LUKS_PART\n" 1 else tput civis LUKS_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" \ --title " $_LuksEncrypt " --menu "$_LuksEncryptBody" 0 0 0 $PARTS)" [[ $? != 0 || $LUKS_PART == "" ]] && return 1 fi else infobox "$_PrepMount" "\nUsing root partition created earlier: $ROOT_PART\n" 1 LUKS_PART="$ROOT_PART" fi # get password and name for encrypted device luks_pass "$_LuksEncrypt" "$LUKS_NAME" || return 1 return 0 } luks_default() { luks_setup || return 1 infobox "$_LuksEncrypt" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" 0 cryptsetup -q luksFormat $LUKS_PART <<< "$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$LUKS_PASS")" 2>$ERR check_for_errors "cryptsetup -q luksFormat $LUKS_PART" cryptsetup open $LUKS_PART "$LUKS_NAME" <<< "$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$LUKS_PASS")" 2>$ERR check_for_errors "cryptsetup open $LUKS_PART $LUKS_NAME" LUKS=1 luks_show return 0 } luks_keycmd() { if luks_setup; then tput cnorm local cipher cipher="$(getinput "$_PrepLUKS" "$_LuksCipherKey" "-s 512 -c aes-xts-plain64")" [[ $? != 0 || $cipher == "" ]] && return 1 infobox "$_LuksEncryptAdv" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" 0 cryptsetup -q $cipher luksFormat $LUKS_PART <<< "$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$LUKS_PASS")" 2>$ERR check_for_errors "cryptsetup -q $cipher luksFormat $LUKS_PART" cryptsetup open $LUKS_PART "$LUKS_NAME" <<< "$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$LUKS_PASS")" 2>$ERR check_for_errors "cryptsetup open $LUKS_PART $LUKS_NAME" luks_show return 0 fi return 1 } luks_show() { tput civis sleep 0.5 echo -e "$_LuksEncryptSucc" > /tmp/.devlist lsblk -o NAME,TYPE,FSTYPE,SIZE $LUKS_PART >> /tmp/.devlist dialog --cr-wrap --backtitle "$BT" --title " $_LuksEncrypt " --textbox /tmp/.devlist 0 0 } luks_menu() { tput civis local choice choice="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PrepLUKS " \ --menu "${_LuksMenuBody}${_LuksMenuBody2}${_LuksMenuBody3}" 0 0 0 \ "$_LuksEncrypt" "cryptsetup -q luksFormat" \ "$_LuksOpen" "cryptsetup open --type luks" \ "$_LuksEncryptAdv" "cryptsetup -q -s -c luksFormat" \ "$_Back" "-")" case $choice in "$_LuksEncrypt") luks_default && return 0 ;; "$_LuksOpen") luks_open && return 0 ;; "$_LuksEncryptAdv") luks_keycmd && return 0 ;; *) return 0 esac luks_menu } luks_keyfile() { # Only used when choosing grub as bootloader. # Without a keyfile, during boot the user will be asked # to enter password for decryption twice, this is annoying if [[ ! -e $MNT/crypto_keyfile.bin ]]; then infobox "$_LuksKeyFileTitle" "$_LuksKeyFileCreate" 0 echo -e "$_LuksKeyFileCreate" local n n="$(lsblk -lno NAME,UUID,TYPE | awk "/$LUKS_UUID/"' && /part|crypt|lvm/ {print $1}')" local mkkey="dd bs=512 count=8 if=/dev/urandom of=/crypto_keyfile.bin" mkkey="$mkkey && chmod 000 /crypto_keyfile.bin" mkkey="$mkkey && cryptsetup luksAddKey /dev/$n /crypto_keyfile.bin <<< '$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$LUKS_PASS")'" chroot_cmd "$mkkey" sed -i 's/FILES=()/FILES=(\/crypto_keyfile.bin)/g' $MNT/etc/mkinitcpio.conf 2>$ERR fi return 0 }