#!/usr/bin/env bash
#
# Author: Dmitry Razumov <asmeron@ublinux.com>
# Copyright (c) 2021-2025 UBLinux <support@ublinux.com>
#
# Extended pattern matching: https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching
shopt -s extglob

ENABLED=yes
[[ ${ENABLED} == yes ]] || exit 0

SOURCE=/usr/lib/ublinux/functions; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=/usr/lib/ublinux/default; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null

SOURCE=${SYSCONF}/config; [[ -f ${SOURCE} ]] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/logging; [ -f ${SOURCE} ] && . ${SOURCE} 2>/dev/null
SOURCE=${SYSCONF}/network; [ -f ${SOURCE} ] && . ${SOURCE} 2>/dev/null

# https://github.com/openSUSE/cepces

# TODO:
# Не сделано
# Делаем настройку cepces и запрос сертификата машины после авторизации в домене с действительным ключом Kerberos
# Заполнение конфигурационного файла параметрами в файл: /etc/cepces/conf.d/ubconfig.conf
# При disable удаление файла /etc/cepces/conf.d/ubconfig.conf
# Проверить нужен ли запуск от root или достаточно под правами пользователя
# Выполнять после авторизации, т.к. клиент должен быть членом домена Windows с действительным ключом Kerberos
# Разобраться с созданием:
#   /etc/pki/tls/private/machine.key
#   /etc/pki/tls/certs/machine.crt
#   Что-то похожее https://wiki.archlinux.org/title/Easy-RSA
# Скорее всего выполнять один раз добавлении CA в certmonger после ввода в домен:
#   getcert add-ca -c CA-name -e '/usr/libexec/certmonger/cepces-submit --server=ca-dns-name.suse.de --keytab=/etc/krb5.keytab --principals=MY-HOST$@SUSE.DE'
# Настройки CA:
#   getcert list-cas
# Выпуска и отслеживания нового сертификата:
#   getcert request -c cepces -T Machine -I MachineCertificate -k /etc/pki/tls/private/machine.key -f /etc/pki/tls/certs/machine.crt
# Проверить ход выполнения:
#   getcert list


## Регистрации сертификатов через CEP и CES c службами сертификатов Microsoft Active Directory
## Клиент должен быть членом домена Windows с действительным ключом Kerberos
## CERTMONGER_CEPCES=enable|disable
## CERTMONGER_CEPCES[<PARAM>]=<VALUE>
##   <PARAM>
##     global:server            # Hostname of the issuing certification authority
##     global:type
##     global:auth=Anonymous|Kerberos|UsernamePassword|Certificate
##                              # Authentication mechanism used for connecting to the service, default=Kerberos
##     global:endpoint          # Default: https://%s/ADPolicyProvider_CEP_%s/service.svc/CEP
##     global:cas
##     global:poll_interval     # Time in seconds before re-checking if the certificate has been issued
##     global:openssl_seclevel  # The openssl security level
##     kerberos:keytab          # Use the specified keytab
##     kerberos:realm
##     kerberos:ccache
##     kerberos:principals      # A list of principals to try when requesting a ticket
##     kerberos:enctypes
##     kerberos:delegate
##     certificate:certfile
##     certificate:keyfile
## CERTMONGER_CEPCES[global:server]=ca-dns-server.win.com
## CERTMONGER_CEPCES[kerberos:keytab]=/etc/krb5.keytab
## CERTMONGER_CEPCES[kerberos:principals]=MYHOST$@WIN.COM
## CERTMONGER_CEPCES=enable
exec_01_certmonger_cepces(){
    [[ $1 == @("set="|"set+="|"set++="|"set-="|"set--="|"remove") ]] && local COMMAND=$1 && shift
    [[ -n ${COMMAND} ]] || local COMMAND="set="
    [[ $(declare -p CERTMONGER_CEPCES 2>/dev/null) =~ ^"declare -A" ]] || declare -gA CERTMONGER_CEPCES
    local PARAM="$@"
    if [[ -n ${PARAM} ]]; then
	local CERTMONGER_CEPCES=
	declare -A CERTMONGER_CEPCES=()
	[[ ${PARAM} =~ ^[[:alnum:]_]+("="|"[".*"]=") ]] && eval "${PARAM%%=*}=\${PARAM#*=}"
    fi
    if [[ ${COMMAND} == @("set="|"set+="|"set++=") ]] && [[ ${#CERTMONGER_CEPCES[@]} -ne 0 ]]; then
        true
    elif [[ ${COMMAND} == @("set-="|"set--="|"remove") ]]; then
	if [[ ${PARAM%%=*} =~ ^.*'['(.*)']' && ${BASH_REMATCH[1]} == @("*"|"**"|"/"|"//") ]]; then
	    PARAM_VALUE="${PARAM#*=}"
	    CERTMONGER_CEPCES+="${PARAM_VALUE// /,}"
	fi
	true
    fi
}

ubconfig_certmonger_cepces_live(){
    true
}

################
##### MAIN #####
################

    # Если файл подключен как ресурс с функциями, то выйти
    return 0 2>/dev/null && return 0
    if [[ -z $@ ]]; then
        while read -r FUNCTION; do
            $"${FUNCTION##* }"
        done < <(declare -F | grep "declare -f exec_")
    else
	FUNCTION=
	while [[ $# -gt 0 ]]; do
	    #[[ -z ${1} ]] || { declare -f "${1}" &>/dev/null && FUNCTION+="; ${1}" || FUNCTION+=" '${1}'"; }
	    # Что-бы передавать пустые параметры как аргументы, нужно для соблюдения очередности и кол-ва, отключил [[ -z ${1} ]] ||
	    declare -f "${1}" &>/dev/null && FUNCTION+="; ${1}" || FUNCTION+=" '${1}'"
	    shift
	done
	eval ${FUNCTION#*; }
    fi
    true
