#!/bin/bash

## Copyright (C) 2012 - 2025 ENCRYPTED SUPPORT LLC <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

if [ -f /usr/libexec/helper-scripts/pre.bsh ]; then
   source /usr/libexec/helper-scripts/pre.bsh
fi
source /usr/libexec/helper-scripts/user_create.bsh

set -e

true "
#####################################################################
## INFO: BEGIN: $DPKG_MAINTSCRIPT_PACKAGE $DPKG_MAINTSCRIPT_NAME $@
#####################################################################
"

enable_systemd_repart_maybe() {
   if ! [ -f "/var/lib/kicksecure/status-files/repart-version-1" ]; then
      true "INFO: Skipping $FUNCNAME because file /var/lib/kicksecure/status-files/repart-version-1 does not exist. (This is expected during the initial build process. A chroot-script will later run the /usr/libexec/derivative-base-files/repart-enable script.)"
      return 0
   fi

   ## NOTE: This is also done in initializer-dist chroot-scripts.
   ## This is also done in dist-base-files postinst for the purpose of updates.
   /usr/libexec/derivative-base-files/repart-enable
   true "INFO: $FUNCNAME OK."
}

check_linux_account_specific() {
   if command -v qubesdb-read >/dev/null 2>&1 ; then
      ## Leave account 'user' creation to Qubes.
      true "INFO: Skipping because Qubes detected."
      return 1
   fi

   ## Don't create a new user during distribution morphing, only do it when building an ISO or VM image.
   if [ ! "$derivative_maker" = "true" ] && ! [ -f '/var/lib/dist-base-files/live_build' ]; then
      true "INFO: Skipping since not running under derivative-maker and /var/lib/dist-base-files/live_build does not exist (during the build process)."
      return 1
   fi

   true "INFO: Continuing..."
   return 0
}

add_linux_user_account_named_user() {
   if [ -f "/var/lib/dist-base-files/do_once/${FUNCNAME}_version_1" ]; then
      return 0
   fi
   mkdir --parents "/var/lib/dist-base-files/do_once"

   if ! check_linux_account_specific ; then
      true "INFO: Skipping ${FUNCNAME}."
      return 0
   fi

   USER_CREATE_USERNAME="$user_to_be_created"
   add_linux_user_account

   touch "/var/lib/dist-base-files/do_once/${FUNCNAME}_version_1"
}

password_empty_for_user_account_named_user() {
   if [ -f "/var/lib/dist-base-files/do_once/${FUNCNAME}_version_1" ]; then
      return 0
   fi
   mkdir --parents "/var/lib/dist-base-files/do_once"

   if ! check_linux_account_specific ; then
      true "INFO: Skipping ${FUNCNAME}."
      return 0
   fi

   USER_CREATE_USERNAME="$user_to_be_created"
   password_empty_for_user_account

   touch "/var/lib/dist-base-files/do_once/${FUNCNAME}_version_1"
}

add_groups_to_linux_user_account_named_user() {
   if [ -f "/var/lib/dist-base-files/do_once/${FUNCNAME}_version_1" ]; then
      return 0
   fi
   mkdir --parents "/var/lib/dist-base-files/do_once"

   if ! check_linux_account_specific ; then
      true "INFO: Skipping ${FUNCNAME}."
      return 0
   fi

   USER_CREATE_USERNAME="$user_to_be_created"
   ## security-misc-shared: Console Lockdown.
   ## Make sure group 'console' exists. Might not exist if security-misc-shared is not (yet) installed.
   ##
   ## Adding group 'sudo' is OK even when using user-sysmaint-split, because
   ## limited accounts can no longer execute privilege escalation tools when
   ## user-sysmaint-split is installed. See also:
   ## https://www.kicksecure.com/wiki/Dev/user-sysmaint-split#No_Access_to_Privilege_Escalation_Tools_for_Limited_Accounts
   ##
   ## Required by 'debian/security-misc-shared.preinst' function 'sudo_users_check'.
   USER_CREATE_GROUP_ADD_LIST=( 'sudo' 'console' 'ssh' )
   add_groups_to_linux_user_account

   touch "/var/lib/dist-base-files/do_once/${FUNCNAME}_version_1"
}

console_lockdown() {
   if [ -f "/var/lib/dist-base-files/do_once/${FUNCNAME}_version_1" ]; then
      return 0
   fi
   mkdir --parents "/var/lib/dist-base-files/do_once"

   if ! check_linux_account_specific ; then
      true "INFO: Skipping ${FUNCNAME}."
      return 0
   fi

   ## No longer enable pam mkhomedir here.
   ## This is done by the security-misc-shared package. File:
   ## /usr/share/pam-configs/mkhomedir-security-misc
   ## pam-auth-update --enable mkhomedir

   ## By package security-misc-shared.
   pam-auth-update --enable console-lockdown-security-misc

   ## In Qubes and for existing installations Console Lockdown is
   ## is handled by legacy-dist package.

   touch "/var/lib/dist-base-files/do_once/${FUNCNAME}_version_1"
}

lock_root_account() {
   if [ -f "/var/lib/dist-base-files/do_once/${FUNCNAME}_version_1" ]; then
      return 0
   fi
   mkdir --parents "/var/lib/dist-base-files/do_once"

   if ! check_linux_account_specific ; then
      true "INFO: Skipping ${FUNCNAME}."
      return 0
   fi

   ## https://www.whonix.org/wiki/Root
   ## https://www.whonix.org/wiki/Dev/Strong_Linux_User_Account_Isolation

   echo "INFO: Locking account '$account_to_be_locked'..."
   passwd --lock "$account_to_be_locked"

   ## Disabled because it breaks `adduser`.
   ## https://forums.whonix.org/t/restrict-root-access/7658/59
   ## Expire the account to prevent SSH login.
   ## https://www.cyberciti.biz/faq/linux-locking-an-account/
   #chage --expiredate 0 "$account_to_be_locked"

   ## Debugging.
   #chage --list "$account_to_be_locked"

   ## To undo:
   #sudo chage --expiredate -1 "$account_to_be_locked"
   #sudo passwd

   touch "/var/lib/dist-base-files/do_once/${FUNCNAME}_version_1"
}

user_shell_to_zsh() {
   if [ -f "/var/lib/dist-base-files/do_once/${FUNCNAME}_version_3" ]; then
      return 0
   fi
   mkdir --parents "/var/lib/dist-base-files/do_once"

   USER_CREATE_USERNAME="$user_to_be_created"
   linux_user_account_shell_to_zsh
   USER_CREATE_USERNAME='root'
   linux_user_account_shell_to_zsh

   touch "/var/lib/dist-base-files/do_once/${FUNCNAME}_version_3"
}

## Define variables here to make this easier to software fork.
user_to_be_created="user"
account_to_be_locked="root"
build_version_file="/var/lib/dist-base-files/build_version"

case "$1" in
   configure)
      true "INFO: Configuring $DPKG_MAINTSCRIPT_PACKAGE..."

      enable_systemd_repart_maybe

      if [ ! -f "$build_version_file" ]; then
         ## Sanity test.
         if [ "$dist_build_version" = "" ]; then
            ## Package dpkg-dev provides dpkg-parsechangelog.
            ## If dist_build_version is empty, use the version number of the package.
            dist_build_version="$(zless "/usr/share/doc/$DPKG_MAINTSCRIPT_PACKAGE/changelog.Debian.gz" | dpkg-parsechangelog -l- -SVersion)" || true
         fi
         if [ "$dist_build_version" = "" ]; then
            echo "ERROR: Could not determine variable 'dist_build_version'."
         else
            mkdir --parents "$(dirname "$build_version_file")"
            echo "INFO: Logging dist_build_version '$dist_build_version' to '$build_version_file'..."
            ## Debugging.
            touch "$build_version_file"
            ## Logging.
            echo "$dist_build_version" | sponge -- "$build_version_file"
            ## Debugging.
            cat "$build_version_file"
         fi
      fi

      add_linux_user_account_named_user
      password_empty_for_user_account_named_user
      add_groups_to_linux_user_account_named_user
      console_lockdown
      lock_root_account
      user_shell_to_zsh

      true "INFO: End configuring $DPKG_MAINTSCRIPT_PACKAGE."

      ;;

   *)
      ;;
esac

true "INFO: debhelper beginning here."

#DEBHELPER#

true "INFO: Done with debhelper."

true "
#####################################################################
## INFO: END  : $DPKG_MAINTSCRIPT_PACKAGE $DPKG_MAINTSCRIPT_NAME $@
#####################################################################
"

## Explicitly "exit 0", so eventually trapped errors can be ignored.
exit 0
