#!/bin/bash

SCRIPT_VER="2.3"

APP="OpenVPN"
APP_CATEGORY="System Services"
APP_SCOPE="system"
APP_ENABLED="yes"
SYS_PKG_NAME="openvpn"
STORED_PASSWORD_SERVICE="user"
SUPPORTED_ON="CentOS7,CentOS8,CentOSStream8,Debian10,Ubuntu20.04,Ubuntu22.04,Ubuntu24.04"
LIBRARY="functions4.sh"

function ovpn_service_name () {
    echo "rsb-openvpn"
}

function ovpn_legacy_service_name () {
    echo "openvpn@rsb-server"
}

function ovpn_service_unit_path () {
    echo "/etc/systemd/system/$( ovpn_service_name ).service"
}

function ovpn_legacy_service_unit_path () {
    echo "/etc/systemd/system/openvpn@.service"
}

function ovpn_monit_path () {
    echo "/etc/monit/conf.d/$( ovpn_service_name )"
}

function ovpn_legacy_monit_path () {
    echo "/etc/monit/conf.d/openvpn@rsb-server"
}

function ovpn_remove_legacy_repos () {
    local _f
    local _updated="no"

    case "${LSB_VENDOR}" in
      "Debian"|"Ubuntu")
          for _f in \
              "openvpn24.list" \
              "openvpn24.list.BAK" \
              "openvpn25.list" \
              "openvpn25.list.BAK" \
              "openvpn26.list" \
              "openvpn26.list.BAK" 
          do
              if [ -e "/etc/apt/sources.list.d/${_f}" ] ; then
                  RM_FILES "/etc/apt/sources.list.d/${_f}" || return 1
                  _updated="yes"
              fi
          done
          if [ "${_updated}" = "yes" ] ; then
              APT_UPDATE || return 1
          fi
          ;;
    esac

    return 0
}

function ovpn_is_legacy_rsb_conf () {
    local _f="$1"

    [ -e "${_f}" ] || return 1
    grep -q -E '^server 10\.10\.10\.0 255\.255\.255\.0$' "${_f}" || return 1
    grep -q -E '^ca /etc/openvpn/rsb-ca\.crt$' "${_f}" || return 1
    grep -q -E '^cert /etc/openvpn/rsb-server\.crt$' "${_f}" || return 1
    grep -q -E '^key /etc/openvpn/rsb-server\.key$' "${_f}" || return 1
    grep -q -E '^up /etc/openvpn/rsb-server-up\.sh$' "${_f}" || return 1
    grep -q -E '^down /etc/openvpn/rsb-server-down\.sh$' "${_f}" || return 1
}

function ovpn_has_known_rsb_ca () {
    local _ca_file="${1:-/etc/openvpn/rsb-ca.crt}"
    local _fp

    [ -e "${_ca_file}" ] || return 1
    _fp="$({ openssl x509 -noout -fingerprint -sha256 -in "${_ca_file}" 2>/dev/null || true; } | cut -d'=' -f2)"
    [ -n "${_fp}" ] || return 1

    case "${_fp}" in
      "7C:88:FD:42:04:10:51:25:66:3E:BF:9A:50:3F:AC:F0:38:98:51:74:A1:9B:55:5A:BC:03:1D:D9:65:7C:B8:71"|\
      "9B:5A:A1:A6:EC:D7:5A:02:9A:CD:D7:A2:EA:B5:07:B7:37:84:C9:99:D7:E1:DA:CE:B2:3E:81:72:05:44:B0:A2"|\
      "B9:F5:14:5C:00:4B:3E:3F:91:09:2C:D3:51:40:F6:55:0D:08:8F:F7:6A:E4:BE:2D:6B:93:DE:11:09:4A:61:34")
          return 0
          ;;
    esac

    return 1
}

function ovpn_is_rsb_conf () {
    local _f="$1"

    [ -e "${_f}" ] || return 1
    grep -q -E '^# RSB_OPENVPN_MANAGED=1$' "${_f}" && return 0
    ovpn_is_legacy_rsb_conf "${_f}" || return 1
    ovpn_has_known_rsb_ca "/etc/openvpn/rsb-ca.crt"
}

function ovpn_stop_service () {
    local _service
    local _legacy_service
    local _monit_file
    local _legacy_monit_file

    _service="$( ovpn_service_name )"
    _legacy_service="$( ovpn_legacy_service_name )"
    _monit_file="$( ovpn_monit_path )"
    _legacy_monit_file="$( ovpn_legacy_monit_path )"

    [ -e "${_monit_file}" ] && RM_FILES "${_monit_file}"
    [ -e "${_legacy_monit_file}" ] && RM_FILES "${_legacy_monit_file}"
    [ -d "/etc/monit/conf.d" ] && MONIT_RELOAD

    SVC_STOP    "${_service}"
    SVC_DISABLE "${_service}"
    SVC_STOP    "${_legacy_service}"
    SVC_DISABLE "${_legacy_service}"

    return 0
}

function ovpn_remove_systemd_unit () {
    local _removed="no"
    local _unit_file
    local _legacy_unit_file

    _unit_file="$( ovpn_service_unit_path )"
    _legacy_unit_file="$( ovpn_legacy_service_unit_path )"

    if [ -e "${_unit_file}" ] ; then
        RM_FILES "${_unit_file}"
        _removed="yes"
    fi
    if [ -e "${_legacy_unit_file}" ] ; then
        RM_FILES "${_legacy_unit_file}"
        _removed="yes"
    fi

    [ "${_removed}" = "yes" ] && SYSTEMD_RELOAD
    return 0
}

function ovpn_cleanup_files () {
    local _f

    for _f in \
        "/etc/openvpn/dh4096.pem" \
        "/etc/openvpn/rsb-ca.crt" \
        "/etc/openvpn/rsb-server-acct.sh" \
        "/etc/openvpn/rsb-server-client-connect.sh" \
        "/etc/openvpn/rsb-server-client-disconnect.sh" \
        "/etc/openvpn/rsb-server.conf" \
        "/etc/openvpn/rsb-server.crt" \
        "/etc/openvpn/rsb-server-down.sh" \
        "/etc/openvpn/rsb-server.key" \
        "/etc/openvpn/rsb-server-up.sh" \
        "/etc/pam.d/openvpn"
    do
        [ -e "${_f}" ] && RM_FILES "${_f}"
    done

    rmdir "/etc/openvpn" > /dev/null 2>&1 || true
    return 0
}

if [ "${SUPPORT-}" = '' ]; then
    SUPPORT="https://installers.rapidseedbox.com/scripts/whmcs_client_installers/support"
fi

LOGFILE="/var/log/whmcs_client_installers/${0}.log"
[ ! -d "/var/log/whmcs_client_installers" ] && mkdir -p "/var/log/whmcs_client_installers"

wget -4 -nc -q --no-check-certificate --timeout=20 --tries=5 "${SUPPORT}/${LIBRARY}" >> "${LOGFILE}" 2>&1
if [ ! -f "./${LIBRARY}" ] ; then
    echo "55"
    echo "Error downloading \"${SUPPORT}/${LIBRARY}\"" >> "${LOGFILE}"
    exit 55
fi

# shellcheck source=support/functions4.sh
. "./${LIBRARY}"
SCRIPTENTRY

while : ; do

    main_rc=1

    CHECK_APP ; _rc=$?
    if [ ${_rc} -ne 0 ] ; then
        main_rc=${_rc}
        break
    fi

    if [ -e "/etc/openvpn/rsb-server.conf" ] \
       && ! ovpn_is_rsb_conf "/etc/openvpn/rsb-server.conf"
    then
        ERROR "OpenVPN: refusing to remove non-RSB config: /etc/openvpn/rsb-server.conf"
        JSON_MSG="Existing non-RSB OpenVPN config detected at /etc/openvpn/rsb-server.conf; refusing to remove"
        break
    fi

    ovpn_stop_service
    ${PKG_REMOVE} "openvpn"
    ${PKG_AUTOREMOVE}
    ovpn_cleanup_files
    ovpn_remove_systemd_unit
    ovpn_remove_legacy_repos || break

    main_rc=0
    break

done


SCRIPTEXIT
