#!/bin/bash

## Copyright (C) 2019 - 2023 ENCRYPTED SUPPORT LP <adrelanos@whonix.org>
## See the file COPYING for copying conditions.

## Redirect calls for pkexec to lxqt-sudo because pkexec is incompatible with
## hidepid.
## * https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=860040
## * https://forums.whonix.org/t/cannot-use-pkexec/8129

set -e

my_real_path="$(realpath "$0")" || true
identifier="$my_real_path wrapper"
exec > >(systemd-cat --identifier="$identifier output by program:") 2>&1

log_to_journal() {
   echo "$@" | systemd-cat --identifier="$identifier output by wrapper:" || true
}

log_to_journal "$0 $@"
log_to_journal "DISPLAY: '$DISPLAY'"
my_pstree="$(pstree -p $$)" || true
log_to_journal "my_pstree: '$my_pstree'"

## If hidepid is not in use, just use pkexec normally.
if ! mount | grep "/proc" | grep "hidepid=2" &>/dev/null ; then
   pkexec.security-misc-orig "$@"
   exit $?
fi

switch_user=false

original_args="$@"

## Thanks to:
## http://mywiki.wooledge.org/BashFAQ/035

while :
do
      case $1 in
         ## Should show 'pkexec --version' or fail?
         --version)
            shift
            pkexec.security-misc-orig "$original_args"
            exit $?
            ;;
         ## Should show 'pkexec --help' or fail?
         --help)
            shift
            pkexec.security-misc-orig "$original_args"
            exit $?
            ;;
         ## Drop --disable-internal-agent as not needed and breaking both,
         ## lxqt-sudo and sudo.
         --disable-internal-agent)
            shift
            ;;
         --user)
            ## lxqt-sudo does not support "--user".
            ## We should not make this wrapper run something as root which
            ## is supposed to run under a different user. Try using
            ## "sudo -A --user user --set-home" instead.
            user_pkexec_wrapper="$2"
            if [ "$user_pkexec_wrapper" = "" ]; then
               shift
            else
               shift 2
            fi
            switch_user=true
            maybe_switch_to_user="--user $user_pkexec_wrapper"
            ;;
         --)
            shift
            break
            ;;
         *)
            break
            ;;
      esac
done

## If there are input files (for example) that follow the options, they
## will remain in the "$@" positional parameters.

if [ "$PKEXEC_UID" = "" ]; then
   if [ ! "$user_pkexec_wrapper" = "" ]; then
      PKEXEC_UID="$user_pkexec_wrapper"
   elif [ ! "$SUDO_USER" = "" ]; then
      PKEXEC_UID="$SUDO_USER"
   else
      PKEXEC_UID="$(whoami)"
   fi
fi
export PKEXEC_UID

if [[ "$@" = "" ]]; then
   ## Call original pkexec in case there are no arguments.
   pkexec.security-misc-orig $original_args
   exit $?
fi

exit_code=0

## lxqt-sudo does not check /etc/sudoers / /etc/sudoers.d exceptions.
## Therefore use 'sudo -l' to see if there is any already existing sudoers exception.
## Did not work. 'sudo -l' will always exit with exit code '0'.
# if sudo -l --non-interactive $maybe_switch_to_user --set-home PKEXEC_UID="$PKEXEC_UID" "$@" ; then
#    log_to_journal "sudoers exception: yes"
#    sudo --non-interactive $maybe_switch_to_user --set-home PKEXEC_UID="$PKEXEC_UID" "$@" || { exit_code=$? ; true; };
#    log_to_journal "sudo --user | exit_code: '$exit_code'"
#    exit "$exit_code"
# fi
#
# log_to_journal "sudoers exception: no"

if [ "$switch_user" = "true" ]; then
   ## 'sudo --user user' clears environment variables such as PATH.
   lxqt-sudo sudo $maybe_switch_to_user --set-home PKEXEC_UID="$PKEXEC_UID" "$@" || { exit_code=$? ; true; };
else
   ## set PATH same as root
   ## This is required for gdebi.
   ## REVIEW: is it ok that users can find out the PATH setting of root?
   ## lxqt-sudo does not clear environment variable PATH.
   PATH="$(sudo --non-interactive /usr/libexec/security-misc/echo-path)"
   export PATH
   lxqt-sudo "$@" || { exit_code=$? ; true; };
fi

log_to_journal "exit_code: '$exit_code'"

exit "$exit_code"