#!/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

## Required since this package uses debconf - this is mandatory even though
## the postinst itself does not use debconf commands.
source /usr/share/debconf/confmodule

set -e

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

permission_hardening_legacy_config_folder() {
    if ! test -d /etc/permission-hardening.d ; then
        return 0
    fi
    rmdir --verbose --ignore-fail-on-non-empty /etc/permission-hardening.d || true
}

permission_hardening() {
    echo "Running SUID Disabler and Permission Hardener... See also:"
    echo "https://www.kicksecure.com/wiki/SUID_Disabler_and_Permission_Hardener"
    echo "$0: INFO: running: permission-hardener enable"
    ## By design: report error but return 0 to avoid breaking APT.
    ## A failing postinst would leave the package in a broken state.
    if ! permission-hardener enable ; then
        echo "$0: ERROR: Permission hardening failed." >&2
        return 0
    fi
    echo "$0: INFO: Permission hardening success."
}

fix_pkexec_remembered_permissions() {
   if [ -f "/var/lib/security-misc/do_once/${FUNCNAME[0]}_version_1" ]; then
      return 0
   fi
   mkdir --parents '/var/lib/security-misc/do_once'

   if ! [ -f "/var/lib/permission-hardener-v2/existing_mode/statoverride" ]; then
      ## 'statoverride' file does not exist yet. Therefore no need to fix it using 'str_replace'.
      touch "/var/lib/security-misc/do_once/${FUNCNAME[0]}_version_1"
      return 0
   fi

   ## The existing_mode database may incorrectly list the original permissions
   ## of pkexec as '755'. They should be '4755'. Fix this with str_replace. If
   ## this issue is not present, str_replace will do nothing.
   str_replace 'root root 755 /usr/bin/pkexec' \
      'root root 4755 /usr/bin/pkexec' \
      /var/lib/permission-hardener-v2/existing_mode/statoverride

   touch "/var/lib/security-misc/do_once/${FUNCNAME[0]}_version_1"
}

install_permission_hardener_base_state() {
   local state_str

   if [ -f "/var/lib/security-misc/do_once/${FUNCNAME[0]}_version_1" ]; then
      return 0
   fi
   mkdir --parents '/var/lib/security-misc/do_once'

   if [ -f "/var/lib/permission-hardener-v2/existing_mode/statoverride" ]; then
      ## 'statoverride' file already exists. Therefore no need to pre-populate it.
      touch "/var/lib/security-misc/do_once/${FUNCNAME[0]}_version_1"
      return 0
   fi

   mkdir --parents -- '/var/lib/permission-hardener-v2/existing_mode'
   state_str="root root 644 /etc/passwd-
root root 755 /etc/cron.monthly
root root 755 /etc/sudoers.d
root shadow 2755 /usr/bin/expiry
root root 4755 /usr/bin/umount
root root 4755 /usr/bin/gpasswd
root root 755 /usr/lib/modules
root root 644 /etc/issue.net
root root 644 /etc/group-
root root 4755 /usr/bin/newgrp
root root 755 /etc/cron.weekly
root root 4755 /usr/lib/polkit-1/polkit-agent-helper-1
root root 644 /etc/hosts.deny
root root 4755 /usr/bin/newgidmap
root root 644 /etc/issue.kicksecure
root root 4755 /usr/bin/pkexec
root root 4755 /usr/bin/su
root root 644 /etc/hosts.allow
root root 700 /root
root root 755 /etc/cron.daily
root root 644 /etc/motd
root root 4755 /usr/bin/newuidmap
root root 755 /boot
root root 755 /home
root shadow 2755 /usr/bin/chage
root root 4755 /usr/lib/openssh/ssh-keysign
root root 4755 /usr/bin/ntfs-3g
root root 4755 /usr/bin/chsh
root root 644 /etc/motd.kicksecure
root root 755 /usr/bin/su-to-root
root root 4755 /usr/bin/passwd
root root 4755 /usr/bin/chfn
root root 644 /etc/group
root root 4755 /usr/bin/sudo
root root 644 /etc/passwd
root root 755 /usr/src
root root 4755 /usr/bin/mount
root root 644 /etc/issue
root root 755 /etc/cron.d"

   printf '%s\n' "$state_str" | tee /var/lib/permission-hardener-v2/existing_mode/statoverride

   touch "/var/lib/security-misc/do_once/${FUNCNAME[0]}_version_1"
}

build_fm_shim_backend() {
  /usr/libexec/security-misc/build-fm-shim-backend
}

case "$1" in
    configure)
        if [ -d /etc/skel/.gnupg ]; then
            ## Lintian warns against use of chmod --recursive.
            chmod 700 /etc/skel/.gnupg
        fi

        ## /usr/share/glib-2.0/schemas/30_security-misc.gschema.override
        glib-compile-schemas /usr/share/glib-2.0/schemas || true

        ## state dir for PAM 'faillock'
        mkdir -p /var/lib/security-misc/faillock

        ## Fix pkexec remembered permissions if necessary.
        fix_pkexec_remembered_permissions

        ## Pre-populate permission-hardener state on first postinst run.
        ## Necessary because the first permission-hardener run may occur
        ## before all permissions are set properly by package postinst
        ## scripts. In particular, pkexec is not SUID-root until after its
        ## postinst runs.
        install_permission_hardener_base_state

        ## Fix usbguard config permissions, this seemingly can't be done
        ## during the unpack stage
        usbguard_config_file_list=(
          '/etc/usbguard/rules.d/30_security-misc.conf'
          '/etc/usbguard/usbguard-daemon.conf.security-misc'
          '/etc/usbguard/IPCAccessControl.d/:sudo'
          '/etc/usbguard/IPCAccessControl.d/:qubes'
        )
        for usbguard_config_file in "${usbguard_config_file_list[@]}"; do
          if test -f "${usbguard_config_file}"; then
            chmod 0600 "${usbguard_config_file}"
          fi
        done

        ## Build the org.freedesktop.FileManager1 shim backend.
        build_fm_shim_backend
    ;;

    abort-upgrade|abort-remove|abort-deconfigure)
    ;;

    triggered)
      echo "INFO: triggered $DPKG_MAINTSCRIPT_PACKAGE: '$DPKG_MAINTSCRIPT_PACKAGE' $DPKG_MAINTSCRIPT_PACKAGE DPKG_MAINTSCRIPT_NAME: '$DPKG_MAINTSCRIPT_NAME' $\*: '$*' 2: '$2'"
      /usr/share/security-misc/lkrg/lkrg-virtualbox || true
      /usr/libexec/security-misc/mmap-rnd-bits || true
      permission_hardening
      exit 0
    ;;

    *)
        echo "$DPKG_MAINTSCRIPT_NAME called with unknown argument \`$1'" >&2
        exit 1
    ;;
esac

pam-auth-update --package

/usr/libexec/security-misc/permission-lockdown

permission_hardening

## https://phabricator.whonix.org/T377
## Debian has no update-grub trigger yet:
## https://bugs.debian.org/481542
if command -v update-grub >/dev/null 2>&1; then
   update-grub || \
      echo "$DPKG_MAINTSCRIPT_PACKAGE $DPKG_MAINTSCRIPT_NAME ERROR: Running \
'update-grub' failed with exit code $?. $DPKG_MAINTSCRIPT_PACKAGE is most \
likely only the trigger, not the cause. Unless you know this is not an issue, \
you should fix running 'update-grub', otherwise your system might no longer \
boot." >&2
fi

/usr/libexec/security-misc/mmap-rnd-bits || true

true "INFO: debhelper beginning here."

#DEBHELPER#

true "INFO: Done with debhelper."

permission_hardening_legacy_config_folder

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

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