From e47ffb0700c3a3cc5fd0c394f3f8921e4232e6f9 Mon Sep 17 00:00:00 2001 From: oddlama Date: Fri, 3 Jan 2020 00:29:17 +0100 Subject: [PATCH] Flush stdin before ask(); implement safe ctrl-c --- scripts/functions.sh | 76 ++++++++++++++++++++++-------------------- scripts/main.sh | 6 +++- scripts/main_chroot.sh | 3 ++ scripts/utils.sh | 17 ++++++++-- 4 files changed, 62 insertions(+), 40 deletions(-) diff --git a/scripts/functions.sh b/scripts/functions.sh index 3353fac..19f6eaf 100644 --- a/scripts/functions.sh +++ b/scripts/functions.sh @@ -13,12 +13,12 @@ check_has_program() { sync_time() { einfo "Syncing time" - ntpd -g -q >/dev/null \ + ntpd -g -q \ || die "Could not sync time with remote server" einfo "Current date: $(LANG=C date)" einfo "Writing time to hardware clock" - hwclock --systohc --utc >/dev/null \ + hwclock --systohc --utc \ || die "Could not save time to hardware clock" } @@ -40,22 +40,21 @@ prepare_installation_environment() { } partition_device_print_config_summary() { - echo "-------- Partition configuration --------" - echo "Device: $PARTITION_DEVICE" + elog "-------- Partition configuration --------" + elog "Device: $PARTITION_DEVICE" elog "Existing partition table:" - lsblk -n "$PARTITION_DEVICE" \ - || die "Error in lsblk" + for_line_in <(lsblk -n "$PARTITION_DEVICE" \ + || die "Error in lsblk") elog elog "New partition table:" - echo "$PARTITION_DEVICE" - echo "├─efi size=$PARTITION_EFI_SIZE" + elog "$PARTITION_DEVICE" + elog "├─efi size=$PARTITION_EFI_SIZE" if [[ "$ENABLE_SWAP" == true ]]; then - echo "├─swap size=$PARTITION_SWAP_SIZE" + elog "├─swap size=$PARTITION_SWAP_SIZE" fi - echo "└─linux size=[remaining]" + elog "└─linux size=[remaining]" if [[ "$ENABLE_SWAP" != true ]]; then - echo "swap: disabled" + elog "swap: disabled" fi - echo } partition_device() { @@ -93,7 +92,7 @@ partition_device() { || die "Could not create linux partition" # Print partition table - einfo "Applied partition table:" + einfo "Applied partition table" sgdisk -p "$PARTITION_DEVICE" \ || die "Could not print partition table" @@ -172,7 +171,7 @@ mount_root() { bind_bootstrap_dir() { # Use new location by default - GENTOO_BOOTSTRAP_DIR="$GENTOO_BOOTSTRAP_BIND" + export GENTOO_BOOTSTRAP_DIR="$GENTOO_BOOTSTRAP_BIND" # Bind the bootstrap dir to a location in /tmp, # so it can be accessed from within the chroot @@ -204,33 +203,38 @@ download_stage3() { || die "Could not parse list of tarballs" # Strip quotes CURRENT_STAGE3="${CURRENT_STAGE3:1:-1}" + # File to indiciate successful verification + CURRENT_STAGE3_VERIFIED="${CURRENT_STAGE3}.verified" # Download file if not already downloaded - if [[ -e "$CURRENT_STAGE3" ]] ; then - einfo "$STAGE3_BASENAME tarball already exists" + if [[ -e "$CURRENT_STAGE3_VERIFIED" ]]; then + einfo "$STAGE3_BASENAME tarball already downloaded and verified" else einfo "Downloading $STAGE3_BASENAME tarball" download "$STAGE3_RELEASES/${CURRENT_STAGE3}" "${CURRENT_STAGE3}" download "$STAGE3_RELEASES/${CURRENT_STAGE3}.DIGESTS.asc" "${CURRENT_STAGE3}.DIGESTS.asc" + + # Import gentoo keys + einfo "Importing gentoo gpg key" + local GENTOO_GPG_KEY="$TMP_DIR/gentoo-keys.gpg" + download "https://gentoo.org/.well-known/openpgpkey/hu/wtktzo4gyuhzu8a4z5fdj3fgmr1u6tob?l=releng" "$GENTOO_GPG_KEY" \ + || die "Could not retrieve gentoo gpg key" + gpg --quiet --import < "$GENTOO_GPG_KEY" \ + || die "Could not import gentoo gpg key" + + # Verify DIGESTS signature + einfo "Verifying DIGEST.asc signature" + gpg --quiet --verify "${CURRENT_STAGE3}.DIGESTS.asc" \ + || die "Signature of '${CURRENT_STAGE3}.DIGESTS.asc' invalid!" + + # Check hashes + einfo "Verifying tarball integrity" + rhash -P --check <(grep -B 1 'tar.xz$' "${CURRENT_STAGE3}.DIGESTS.asc") \ + || die "Checksum mismatch!" + + # Create verification file in case the script is restarted + touch "$CURRENT_STAGE3_VERIFIED" fi - - # Import gentoo keys - einfo "Importing gentoo gpg key" - local GENTOO_GPG_KEY="$TMP_DIR/gentoo-keys.gpg" - download "https://gentoo.org/.well-known/openpgpkey/hu/wtktzo4gyuhzu8a4z5fdj3fgmr1u6tob?l=releng" "$GENTOO_GPG_KEY" \ - || die "Could not retrieve gentoo gpg key" - gpg --import < "$GENTOO_GPG_KEY" \ - || die "Could not import gentoo gpg key" - - # Verify DIGESTS signature - einfo "Verifying DIGEST.asc signature" - gpg --verify "${CURRENT_STAGE3}.DIGESTS.asc" \ - || die "Signature of '${CURRENT_STAGE3}.DIGESTS.asc' invalid!" - - # Check hashes - einfo "Verifying tarball integrity" - rhash -P --check <(grep -B 1 'tar.xz$' "${CURRENT_STAGE3}.DIGESTS.asc") \ - || die "Checksum mismatch!" } extract_stage3() { @@ -263,9 +267,9 @@ disable_logging() { } gentoo_umount() { - einfo "Unmounting root filesystem" if mountpoint -q -- "$ROOT_MOUNTPOINT"; then - umount -R "$ROOT_MOUNTPOINT" \ + einfo "Unmounting root filesystem" + umount -R -l "$ROOT_MOUNTPOINT" \ || die "Could not unmount filesystems" fi } diff --git a/scripts/main.sh b/scripts/main.sh index a83bace..85bb5cd 100755 --- a/scripts/main.sh +++ b/scripts/main.sh @@ -88,6 +88,7 @@ main_install_gentoo_in_chroot() { main_install() { [[ $# == 0 ]] || die "Too many arguments" + gentoo_umount install_stage3 \ || die "Failed to install stage3" @@ -108,11 +109,14 @@ main_umount() { ################################################ # Main dispatch +# Instantly kill when pressing ctrl-c +trap "kill $GENTOO_BOOTSTRAP_SCRIPT_PID" INT + einfo "Verbose script output will be logged to: '$GENTOO_BOOTSTRAP_DIR/log-$LOGDATE.out'" # Save old stdout exec 3>&1 # Restore old filedescriptor on certain signals -trap 'exec 1>&3' 0 1 2 3 RETURN +trap 'exec 1>&3; exit 1' 0 1 2 3 RETURN # Replace stdout with logfole exec 1>"$GENTOO_BOOTSTRAP_DIR/log-$LOGDATE.out" # Link to latest log file diff --git a/scripts/main_chroot.sh b/scripts/main_chroot.sh index 2a5c733..29a3568 100755 --- a/scripts/main_chroot.sh +++ b/scripts/main_chroot.sh @@ -6,6 +6,9 @@ # Source the systems profile source /etc/profile +# Set safe umask +umask 0077 + # Export nproc variables export NPROC="$(nproc || echo 2)" export NPROC_ONE="$(($NPROC + 1))" diff --git a/scripts/utils.sh b/scripts/utils.sh index e9a4280..e96d3f2 100644 --- a/scripts/utils.sh +++ b/scripts/utils.sh @@ -36,7 +36,18 @@ die() { exit 1 } +for_line_in() { + while IFS="" read -r line || [[ -n "$line" ]]; do + "$2" "$line" + done <"$1" +} + ask() { + # Empty stdin + local empty_stdin + while read -r -t 0.01 empty_stdin; do true; done + unset empty_stdin + while true; do read -r -p "$* (Y/n) " response case "${response,,}" in @@ -49,15 +60,15 @@ ask() { } countdown() { - echo -n "$1" + echo -n "$1" >&3 local i="$2" while [[ $i -gt 0 ]]; do - echo -n "$i " + echo -n "$i " >&3 i=$((i - 1)) sleep 1 done - echo + echo >&3 } download_stdout() {