#!/bin/sh

# The reference version of this script is maintained in:
#   kali-installer/simple-cdd/profiles/kali.postinst
#   kali-live/kali-config/common/includes.installer/kali-finish-install
#   kali-live/kali-config/common/includes.chroot/usr/lib/live/config/0031-kali-user-setup
#   kali-vm/scripts/finish-install.sh
# (sometimes with small variations)
#
# It is used in multiple places to finish configuring the target system
# and build.sh copies it where required (in the simple-cdd configuration
# and in the live-build configuration).

configure_apt_sources_list() {
    echo "INFO: setting up kali.sources as the only APT data source"

    rm -f /etc/apt/sources.list.d/* /etc/apt/sources.list
    cat  >/etc/apt/sources.list.d/kali.sources <<END
# See https://www.kali.org/docs/general-use/kali-apt-sources/
Types: deb
URIs: http://http.kali.org/kali/
Suites: kali-rolling
Components: main contrib non-free non-free-firmware
Signed-By: /usr/share/keyrings/kali-archive-keyring.gpg
END

    apt-get update
}

get_user_list() {
    for user in $(cd /home && ls); do
        if ! getent passwd "$user" >/dev/null; then
            echo "WARNING: user '$user' is invalid but /home/$user exists" >&2
            continue
        fi
        echo "$user"
    done
    echo "root"
}

configure_zsh() {
    if grep -q 'nozsh' /proc/cmdline; then
        echo "INFO: user opted out of zsh by default"
        return
    fi
    if [ ! -x /usr/bin/zsh ]; then
        echo "INFO: /usr/bin/zsh is not available"
        return
    fi
    for user in $(get_user_list); do
        echo "INFO: changing default shell of user '$user' to zsh"
        chsh --shell /usr/bin/zsh $user
    done
}

configure_usergroups() {
    # Ensure those groups exist
    addgroup --system kaboxer || true
    addgroup --system wireshark || true

    # adm - read access to log files
    # dialout - for serial access
    # kaboxer - for kaboxer
    # vboxsf - shared folders for virtualbox guest
    # wireshark - capture sessions in wireshark
    kali_groups="adm dialout kaboxer vboxsf wireshark"

    for user in $(get_user_list | grep -xv root); do
        echo "INFO: adding user '$user' to groups '$kali_groups'"
        for grp in $kali_groups; do
            getent group $grp >/dev/null || continue
            usermod -a -G $grp $user
        done
    done
}

pkg_installed() {
    dpkg -s "$1" 2>/dev/null | grep -q "ok installed"
}

configure_terminal() {
    while read -r desktop terminal; do
        pkg_installed kali-desktop-$desktop || continue
        echo "INFO: setting x-terminal-emulator alternative to '$terminal'"
        update-alternatives --verbose --set x-terminal-emulator /usr/bin/$terminal || true
        break
    done <<END
e17   terminology
gnome gnome-terminal.wrapper
i3    kitty
kde   konsole
lxde  lxterminal
mate  mate-terminal.wrapper
xfce  qterminal
END
}

remove_unneeded_firmware() {
    # Detect virtualization
    command -v systemd-detect-virt >/dev/null || return 0
    virt=$(systemd-detect-virt) || return 0
    echo "INFO: detected virtual environment: $virt"

    # We are running in a virtualized environment, no need for microcode or
    # graphics firmware. Let's check if those packages are installed.
    to_remove=
    while read -r pkg; do
        pkg_installed $pkg || continue
        to_remove="$to_remove $pkg"
    done <<END
amd64-microcode
intel-microcode
firmware-amd-graphics
firmware-intel-graphics
firmware-nvidia-graphics
kali-linux-firmware-graphics
END
    if [ -z "$to_remove" ]; then
        echo "INFO: no package to remove"
        return 0
    fi

    # Use dpkg to remove packages, in order to fail if there are any reverse
    # dependency (there shouldn't be any), rather than taking the risk of
    # removing it (what apt would do).
    #
    # We're not sure if the initrd will be rebuilt automatically (it depends
    # on which packages get removed), so check and rebuild if needed.
    echo "INFO: removing microcode and graphics firmware below:"
    echo "INFO:" $to_remove
    initrd=$(ls /boot/initrd.img* | tail -1)
    timestamp_before=$(stat -c %Y "$initrd")
    dpkg --purge $to_remove || true
    timestamp_after=$(stat -c %Y "$initrd")
    if [ "$timestamp_before" = "$timestamp_after" ]; then
        echo "INFO: rebuilding the initrd"
        update-initramfs -u -k all || true
    fi
}

configure_apt_sources_list
configure_zsh
configure_usergroups
configure_terminal
remove_unneeded_firmware
