#!/bin/bash

# !!!СКРИПТ НИ В КОЕМ СЛУЧАИ НЕ ДОЛЖЕН ВЕРНЁТ ЗНАЧЕНИЕ ОТЛИЧНОЕ ОТ 0!!!

#================================================================================
# Инициализация
#================================================================================

# Определяем местоположение скрипта
SCRIPT_PATH=$(dirname "$(readlink -f "$0")")
# Импортируем функции
source $SCRIPT_PATH/astra-mobile-clean-functions
source $SCRIPT_PATH/astra-mobile-clean-and-lock-config

if [[ $EUID -ne 0 ]]; then
    echo -e "Please run the script as superuser."
    # ВЕРНУТЬ ТОЛЬКО 0!
    exit 0
fi

if [ $(getAstraMode) == 0 ]; then
    echo "Current Astra Linux mode '${ASTRA_MODE[0]}'. Minimum mode '${ASTRA_MODE[1]}' required!"
    # ВЕРНУТЬ ТОЛЬКО 0!
    exit 0
fi

# https://geekthis.net/post/run-scripts-after-ssh-authentication/
# ${PAM_TYPE}
# ${PAM_USER}
# ${PAM_RHOST}

if [[ -z "${PAM_USER}" ]]; then
   echo "Failed to determine user's PAM!"
   # ВЕРНУТЬ ТОЛЬКО 0!
   exit 0
else
    echo "Check user: [${PAM_USER}]"
fi


#==============================================================================
# Возможные результаты детектирования
#==============================================================================
# Выходное значение детектора: "Детектор не сработал"
declare -i NOT_DETECTED=0
# Выходное значение детектора: "Сработал детектор среднего режима"
declare -i MIDDLE_DETECTED=1
# Выходное значение детектора: "Сработал детектор жёсткого режима"
declare -i HARD_DETECTED=2

#==============================================================================
# Обработка
#==============================================================================
## @userGetLoginAttemptFailedCount
## @brief - Функция вернёт количество проваленных попыток аутентификации пользователя
## @param $1 - Пользователь
## @return Вернётколичество проваленных попыток аутентификации пользователя
function userGetLoginAttemptFailedCount() {
    local USER="$1"
    local result='0'

    if command -v pam_tally > /dev/null 2>&1; then
        # awk '{ print $5 }': Take the fifth parameter from pam_tally --user
        result=$(pam_tally --user="$USER" | awk '{ print $5 }')
    elif command -v faillock > /dev/null 2>&1; then
        # tail -n +3: Skip the first 2 lines and read from the third from faillock --user
        # wc -l: We count the number of lines of incorrect logins from faillock --user
        result=$(faillock --user "$USER" | tail -n +3 | wc -l)
        # [faillock] Due to the fact that the login failure record is added after the script is called, we simply add 1 to the result
        result=$((result+1))
    else
        echo "Can't find 'failed login count' command!"
    fi

    echo "$result"
}

## @onDetected
## @brief - Обработчик события детектирования
## @param $1 - Пользователь
## @param $2 - Тип события
function onDetected() {
    local USER="$1"
    local EVENT_TYPE=$2

    if [ $EVENT_TYPE -eq $MIDDLE_DETECTED ]; then
        echo "[$(date +'%d.%m.%Y %T')] $USER MIDDLE DETECTED!"
        /bin/bash $SCRIPT_PATH/astra-mobile-clean-home "$USER"
    elif [ $EVENT_TYPE -eq $HARD_DETECTED ]; then
        echo "[$(date +'%d.%m.%Y %T')] $USER HARD DETECTED!"
        /bin/bash $SCRIPT_PATH/astra-mobile-clean-device "$USER"
    fi
}

## @detectUserExceededTheNumberOfAttempts
## @brief - Функция детектирования превышения пользователем допустимого количества попыток аутентификации
## @param $1 - Пользователь
## @param $2 - Максимально допустимое количество попыток аутентификации
## @return  Вернёт логический признак превышения пользователем допустимого количества попыток аутентификации
function detectUserExceededTheNumberOfAttempts() {
    local USER="$1"
    local MAX_ATTEMPTS_COUNT=$2

#    На случай если значение максимального количества попыток равно 0 (скорее всего конфиг не инициализирован или повреждён)
    if [ $MAX_ATTEMPTS_COUNT -eq 0 ]; then
#        Вернём ложь и не будем трогать файлы пользователя
        [ 1 == 0 ]
    else
#        Вернём логическое значение "Пользователь превысил максимальное количество попыток аутентификации" = true в противном случаи false
        [ $(userGetLoginAttemptFailedCount "$USER") -ge $MAX_ATTEMPTS_COUNT ]
    fi
}

## @detectMiddle
## @brief - Функция детектирования превышения пользователем допустимого количества попыток аутентификации (Middle Mode)
## @param $1 - Имя пользователя
## @return Вернёт логический признак превышения заданного времени отсутствия пользователя в системе
function detectMiddle() {
    local USER="$1"
    $(iniGetMiddleModeActive) && $(detectUserExceededTheNumberOfAttempts "$USER" $(iniGetMiddleModeAttemptCount))
}

## @detectHard
## @brief - Функция детектирования превышения пользователем допустимого количества попыток аутентификации  (Hard Mode)
## @param $1 - Имя пользователя
## @return Вернёт логический признак превышения заданного времени отсутствия пользователя в системе
function detectHard() {
    local USER="$1"
     $(iniGetHardModeActive) && $(detectUserExceededTheNumberOfAttempts "$USER" $(iniGetHardModeAttemptCount))
}

## @detector
## @brief - Функция детектирования продолжительного отсутствия пользователя в системе (All Modes)
## @param $1 - Имя пользователя
## @return Вернёт одно из значений детектора (MIDDLE_DETECTED|HARD_DETECTED|NOT_DETECTED)
function detector() {
    local USER="$1"
    local outResult=$NOT_DETECTED

    # Hard может перекрывать Middle

    if $(detectMiddle "$USER"); then
        outResult=$MIDDLE_DETECTED
    fi

    if $(detectHard "$USER"); then
        outResult=$HARD_DETECTED
    fi

    return $outResult
}

#==============================================================================
# Main
#==============================================================================

# Пропустим системных пользователей
if [ $(id -u "${PAM_USER}") -ge 1000 ]; then
    # Запускаем детектор
    detector "${PAM_USER}"
    detectResult=$?
    # Проверяем результат выполнения
    if [[ "$detectResult" != @($NOT_DETECTED) ]]; then
        # Обрабатываем событие детектирования
        onDetected "${PAM_USER}" $detectResult
    fi
fi

# !ОБЯЗАТЕЛЬНО ВЕРНЁМ ПРИЗНАК УСПЕШНОГО ЗАВЕРШЕНИЯ!
exit 0
#==============================================================================
