#!/bin/bash
SPOOL_DIR="/var/spool/systemd-bridge"
resolve_tty() {
    local raw_tty=""
    local who_tty=""

    if [ -n "${SSH_TTY:-}" ]; then
        printf '%s\n' "$SSH_TTY"
        return
    fi

    who_tty=$(who | awk -v user="$PAM_USER" -v ip="$PAM_RHOST" '
        $1 == user {
            host = $NF
            gsub(/[()]/, "", host)
            if (host == ip) {
                print "/dev/" $2
                exit
            }
        }
    ')
    if [ -n "$who_tty" ]; then
        printf '%s\n' "$who_tty"
        return
    fi

    raw_tty=$(ps -o tty= -p "$PPID" 2>/dev/null | awk 'NR==1 {print $1}')
    if [ -n "$raw_tty" ] && [ "$raw_tty" != "?" ] && [ "$raw_tty" != "notty" ]; then
        case "$raw_tty" in
            /dev/*) printf '%s\n' "$raw_tty" ;;
            *) printf '/dev/%s\n' "$raw_tty" ;;
        esac
        return
    fi

    raw_tty=$(tty 2>/dev/null || true)
    if [ -n "$raw_tty" ] && [ "$raw_tty" != "not a tty" ]; then
        printf '%s\n' "$raw_tty"
        return
    fi

    printf '%s\n' "${PAM_TTY:-unknown}"
}

find_session_file() {
    local preferred_tty="$1"
    local safe_tty=""
    local preferred_file=""
    local matches=()
    local match=""

    if [ -n "$preferred_tty" ]; then
        safe_tty=$(printf '%s' "$preferred_tty" | tr '/' '_')
        preferred_file="/tmp/ssh_audit_${PAM_USER}_${safe_tty}"
        if [ -f "$preferred_file" ]; then
            printf '%s\n' "$preferred_file"
            return
        fi
    fi

    mapfile -t matches < <(find /tmp -maxdepth 1 -type f -name "ssh_audit_${PAM_USER}_*" | sort)
    if [ -n "${matches[0]:-}" ]; then
        for match in "${matches[@]}"; do
            preferred_file="$match"
        done
        printf '%s\n' "$preferred_file"
        return
    fi
}

SESSION_TTY=$(resolve_tty)
SAFE_TTY=$(printf '%s' "$SESSION_TTY" | tr '/' '_')
SESSION_FILE="/tmp/ssh_audit_${PAM_USER}_${SAFE_TTY}"

if [ "$PAM_TYPE" = "open_session" ]; then
    {
        date +%s
        printf '%s\n' "$SESSION_TTY"
    } > "$SESSION_FILE"
elif [ "$PAM_TYPE" = "close_session" ]; then
    SESSION_FILE=$(find_session_file "$SESSION_TTY")
    if [ -f "$SESSION_FILE" ]; then
        mapfile -t SESSION_META < "$SESSION_FILE"
        START_TIME="${SESSION_META[0]}"
        if [ -n "${SESSION_META[1]:-}" ]; then
            SESSION_TTY="${SESSION_META[1]}"
        fi
        END_TIME=$(date +%s)
        JSON_FILE="${SPOOL_DIR}/${PAM_USER}_${END_TIME}.json"

        cat <<EOF > "$JSON_FILE"
{
    "user": "${PAM_USER}",
    "ip": "${PAM_RHOST}",
    "tty": "${SESSION_TTY}",
    "start": ${START_TIME},
    "end": ${END_TIME}
}
EOF
        rm -f "$SESSION_FILE"
    fi
fi
