#! /bin/bash

# This script is run as root by GDM after user's login.
# It must return exit code 0, otherwise it totally breaks the logon process.

# Input
# =====
#
# * /etc/live/config.d/username.conf : $LIVE_USERNAME
# * /var/lib/gdm3/tails.locale : $TAILS_LOCALE_NAME, $TAILS_XKBMODEL,
#   $TAILS_XKBLAYOUT, $TAILS_XKBVARIANT, $TAILS_XKBOPTIONS, $CODESET
# * /var/lib/gdm3/tails.password : $TAILS_USER_PASSWORD
# * /var/lib/gdm3/tails.persistence : $TAILS_PERSISTENCE_ENABLED
# * /var/lib/gdm3/tails.camouflage : $TAILS_CAMOUFLAGE_OS
# * /var/lib/gdm3/tails.physical_security : $TAILS_MACSPOOF_ENABLED

# For whatever reason, /usr/sbin (needed by at least chpasswd)
# is not in our PATH
export PATH="/usr/sbin:${PATH}"
LIVE_PASSWORD=live
POLKIT=/etc/polkit-1/localauthority.conf.d/52-tails-greeter.conf
SUDOERS=/etc/sudoers.d/tails-greeter
NO_PASSWORD_LECTURE=/etc/sudoers.d/tails-greeter-no-password-lecture
KBDSET=/etc/default/keyboard
CONSET=/etc/default/console-setup
LOCALE_CFG=/etc/default/locale
CODSET="Uni1" # universal codeset to properly display glyphs in localized console

log_error() {
    echo "`date "+day %j of %Y [%T]"` $1" >> /var/log/gdm3/tails-greeter.errors
}

log_n_exit() {
    log_error "$1"
    exit 0
}

# enforce value $3 for variable $1 in file $2
force_set() {
    sed -i -e "s|^$1=.*$|$1=\"$3\"|" "$2"
}

# check if variable $1 is in file $2, if not - add with value $3 to file $2
# $4 enforce adding $3 only (without $1= prefix)
grep_n_set() {
    FCHK=yes
    grep -qs "$1" "$2" || FCHK=no
    if [ -n "$4" ] ; then
        if [ "$FCHK" = "no" ] ; then
	    echo "$3" >> "$2"
	fi
    else
	if [ "$FCHK" = "no" ] ; then
	    echo "$1=$3" >> "$2"
	else
	    force_set "$1" "$2" "$3"
	fi
    fi
}

### Gather general configuration

# Import the name of the live user
. /etc/live/config.d/username.conf || log_n_exit "Username file not found."
if [ -z "${LIVE_USERNAME}" ] ; then
    log_n_exit "Username variable not found."
fi

### Camouflage

CAMOUFLAGE_SETTINGS="/var/lib/gdm3/tails.camouflage"
if [ -r "${CAMOUFLAGE_SETTINGS}" ] ; then
    . "${CAMOUFLAGE_SETTINGS}"
    case "${TAILS_CAMOUFLAGE_OS}" in
	win8)
	    install -m 0644 \
	        /usr/share/applications/tails-activate-win8-theme.desktop \
	        /etc/xdg/autostart/
	    ;;
    esac
fi

### Physical security
# It's important we "export" this setting before unblocking the
# network; doing so will make the user-set MAC spoofing option apply
# (via the custom udev rule) when loading the modules for the
# previously blocked network devices.
PHYSICAL_SECURITY_SETTINGS="/var/lib/gdm3/tails.physical_security"
if [ -r "${PHYSICAL_SECURITY_SETTINGS}" ] ; then
   install -m 0640 -o root -g root \
      "${PHYSICAL_SECURITY_SETTINGS}" /var/lib/live/config/tails.physical_security
   sync
   . "${PHYSICAL_SECURITY_SETTINGS}"
   if [ "${TAILS_MACSPOOF_ENABLED}" = true ]; then
      /usr/local/sbin/tails-restricted-network-detector &
   fi
   if [ "${TAILS_NETCONF}" = "obstacle" ]; then
      . /usr/local/lib/tails-shell-library/tor.sh
      tor_set_in_torrc "DisableNetwork" "1"
   fi
fi

UNBLOCK_NETWORK_LOG="$(/usr/local/sbin/tails-unblock-network 2>&1)"
UNBLOCK_NETWORK_RET=$?
if [ "${UNBLOCK_NETWORK_RET}" -ne 0 ]; then
   log_error "tails-unblock-network exited with status ${UNBLOCK_NETWORK_RET} and said:
${UNBLOCK_NETWORK_LOG}"
fi

### Localization

# Import locale name
. /var/lib/gdm3/tails.locale || log_n_exit "Locale file not found."
if [ -z "${TAILS_LOCALE_NAME}" ] ; then
    log_n_exit "Locale variable not found."
fi

# Localize console
grep_n_set "XKBMODEL" ${KBDSET} ${TAILS_XKBMODEL}
grep_n_set "XKBLAYOUT" ${KBDSET} ${TAILS_XKBLAYOUT}
grep_n_set "XKBVARIANT" ${KBDSET} ${TAILS_XKBVARIANT}
grep_n_set "XKBOPTIONS" ${KBDSET} ${TAILS_XKBOPTIONS}
force_set "CODESET" ${CONSET} ${CODSET}
grep_n_set "LANG"       ${LOCALE_CFG} "${TAILS_LOCALE_NAME}.UTF-8"

# Save keyboard settings so that tails-configure-keyboard can set it
# in the GNOME session.
cat > /var/lib/tails-user-session/keyboard <<EOF
XKBMODEL="$TAILS_XKBMODEL"
XKBLAYOUT="$TAILS_XKBLAYOUT"
XKBVARIANT="$TAILS_XKBVARIANT"
XKBOPTIONS="$TAILS_XKBOPTIONS"
EOF

### Persistence

# Copy persistence configuration to a root-writable, world-readable place,
# so that software running as LIVE_USERNAME or tails-persistence-setup can
# get it.

if [ -r /var/lib/gdm3/tails.persistence ] ; then
   install -m 0644 -o root -g root \
      /var/lib/gdm3/tails.persistence /var/lib/live/config/tails.persistence
fi

# Install persistent packages
if [ -x /usr/local/sbin/tails-additional-software ] ; then
    /usr/local/sbin/tails-additional-software install
else
   log_n_exit "'/usr/local/sbin/tails-additional-software' does not exist or is not executable."
fi

# Reload CUPS configuration to take persistent printers into account if necessary
if grep -qs '^/etc/cups\s\+' /live/persistence/*_unlocked/persistence.conf ; then
    service cups force-reload
fi

### Password

# Import password for superuser access
. /var/lib/gdm3/tails.password

# Remove password file
rm --interactive=never -f /var/lib/gdm3/tails.password

# Check if password is actually set
if [ -z "${TAILS_USER_PASSWORD}" ] ; then
    rm -f "${POLKIT}" "${SUDOERS}"
    deluser "${LIVE_USERNAME}" sudo
    echo "Defaults:amnesia lecture=always" > "${NO_PASSWORD_LECTURE}"
    echo "Defaults:amnesia lecture_file=/usr/share/tails-greeter/no-password-lecture.txt" >> "${NO_PASSWORD_LECTURE}"
    echo "Defaults:amnesia badpass_message=\"The administration password is disabled.\"" >> "${NO_PASSWORD_LECTURE}"
    chmod 0440 "${NO_PASSWORD_LECTURE}"
    log_n_exit "Password variable not found."
fi

# Sets the password
echo "${LIVE_USERNAME}:${TAILS_USER_PASSWORD}" | chpasswd

# Reset the password for default value on logout
echo "echo \"${LIVE_USERNAME}:${LIVE_PASSWORD}\" | /usr/sbin/chpasswd" > /etc/gdm3/PostSession/${DISPLAY}
chmod +x /etc/gdm3/PostSession/${DISPLAY}

# Add sudoers entry
echo "${LIVE_USERNAME} ALL = (ALL) ALL" >> "${SUDOERS}"
chmod 0440 "${SUDOERS}"

# Add PolKit config
echo "[Configuration]" > "${POLKIT}"
echo "AdminIdentities=unix-user:${LIVE_USERNAME}" >> "${POLKIT}"

# Configure su-to-root to use sudo
sudo -u "${LIVE_USERNAME}" sh -c "echo 'SU_TO_ROOT_SU=sudo' >> /home/${LIVE_USERNAME}/.su-to-rootrc"

# Configure gksu to use sudo
sudo -u "${LIVE_USERNAME}" gconftool-2 -s -t bool /apps/gksu/sudo-mode true
