#!/bin/bash
# Validate RainerScript parity for compatibility.* global options.
. ${srcdir:=.}/diag.sh init

modpath="${RSYSLOG_MODDIR}"
have_imtcp_module=0
if ls ../plugins/imtcp/.libs/imtcp.* >/dev/null 2>&1; then
    have_imtcp_module=1
fi

run_expect_success() {
    local cfg="$1"
    local log="$2"
    ../tools/rsyslogd -C -N1 -M"${modpath}" -f"${cfg}" >"${log}" 2>&1
    local rc=$?
    if [ $rc -ne 0 ]; then
        echo "FAIL: expected ${cfg} to validate"
        cat "${log}"
        error_exit 1
    fi
}

run_expect_failure() {
    local cfg="$1"
    local log="$2"
    ../tools/rsyslogd -C -N1 -M"${modpath}" -f"${cfg}" >"${log}" 2>&1
    local rc=$?
    if [ $rc -eq 0 ]; then
        echo "FAIL: expected ${cfg} to fail validation"
        cat "${log}"
        error_exit 1
    fi
}

cat >"${RSYSLOG_DYNNAME}.valid.conf" <<CONF_EOF
global(
  compatibility.configformat.legacy="enable"
  compatibility.configformat.syslogd="enable"
  compatibility.configformat.property="enable"
  compatibility.defaults.secure="backward-compatible"
)
action(type="omfile" file="${RSYSLOG_DYNNAME}.out")
CONF_EOF
run_expect_success "${RSYSLOG_DYNNAME}.valid.conf" "${RSYSLOG_DYNNAME}.valid.log"

cat >"${RSYSLOG_DYNNAME}.secure-default.conf" <<CONF_EOF
global(compatibility.configformat.legacy="enable")
action(type="omfile" file="${RSYSLOG_DYNNAME}.out")
CONF_EOF
run_expect_success "${RSYSLOG_DYNNAME}.secure-default.conf" "${RSYSLOG_DYNNAME}.secure-default.log"
content_check 'backward-compatible insecure default in use' "${RSYSLOG_DYNNAME}.secure-default.log"

cat >"${RSYSLOG_DYNNAME}.legacy-warn.conf" <<CONF_EOF
global(compatibility.configformat.legacy="warn")
\$MainMsgQueueTimeoutShutdown 10000
action(type="omfile" file="${RSYSLOG_DYNNAME}.out")
CONF_EOF
run_expect_success "${RSYSLOG_DYNNAME}.legacy-warn.conf" "${RSYSLOG_DYNNAME}.legacy-warn.log"
content_check 'obsolete $-directive syntax encountered' "${RSYSLOG_DYNNAME}.legacy-warn.log"

cat >"${RSYSLOG_DYNNAME}.legacy-disable.conf" <<CONF_EOF
global(compatibility.configformat.legacy="disable")
\$MainMsgQueueTimeoutShutdown 10000
action(type="omfile" file="${RSYSLOG_DYNNAME}.out")
CONF_EOF
run_expect_failure "${RSYSLOG_DYNNAME}.legacy-disable.conf" "${RSYSLOG_DYNNAME}.legacy-disable.log"
content_check 'global(compatibility.configformat.legacy="enable")' "${RSYSLOG_DYNNAME}.legacy-disable.log"

cat >"${RSYSLOG_DYNNAME}.syslogd-warn.conf" <<CONF_EOF
global(compatibility.configformat.syslogd="warn")
mail.* action(type="omfile" file="${RSYSLOG_DYNNAME}.out")
CONF_EOF
run_expect_success "${RSYSLOG_DYNNAME}.syslogd-warn.conf" "${RSYSLOG_DYNNAME}.syslogd-warn.log"
content_check 'obsolete classic syslogd filter syntax encountered' "${RSYSLOG_DYNNAME}.syslogd-warn.log"

cat >"${RSYSLOG_DYNNAME}.syslogd-disable.conf" <<CONF_EOF
global(compatibility.configformat.syslogd="disable")
mail.* action(type="omfile" file="${RSYSLOG_DYNNAME}.out")
action(type="omfile" file="${RSYSLOG_DYNNAME}.out2")
CONF_EOF
run_expect_failure "${RSYSLOG_DYNNAME}.syslogd-disable.conf" "${RSYSLOG_DYNNAME}.syslogd-disable.log"
content_check 'global(compatibility.configformat.syslogd="enable")' "${RSYSLOG_DYNNAME}.syslogd-disable.log"

cat >"${RSYSLOG_DYNNAME}.property-warn.conf" <<CONF_EOF
global(compatibility.configformat.property="warn")
:msg, contains, "hello" action(type="omfile" file="${RSYSLOG_DYNNAME}.out")
CONF_EOF
run_expect_success "${RSYSLOG_DYNNAME}.property-warn.conf" "${RSYSLOG_DYNNAME}.property-warn.log"
content_check 'obsolete classic property-based filter syntax encountered' "${RSYSLOG_DYNNAME}.property-warn.log"

if [ ${have_imtcp_module} -eq 1 ]; then
    cat >"${RSYSLOG_DYNNAME}.tls-warn.conf" <<CONF_EOF
global(compatibility.defaults.secure="warn")
module(load="../plugins/imtcp/.libs/imtcp")
input(type="imtcp" port="0" listenPortFileName="${RSYSLOG_DYNNAME}.tlswarn.port" streamdriver.mode="0"
      streamdriver.name="gtls" streamdriver.authmode="x509/name")
action(type="omfwd" target="127.0.0.1" protocol="udp")
CONF_EOF
    run_expect_success "${RSYSLOG_DYNNAME}.tls-warn.conf" "${RSYSLOG_DYNNAME}.tls-warn.log"
    content_check 'imtcp has TLS-related settings but streamdriver.mode="0"; mode 0 uses plain TCP so TLS is not active' "${RSYSLOG_DYNNAME}.tls-warn.log"
    content_check 'omfwd action uses protocol="udp" (without TLS)' "${RSYSLOG_DYNNAME}.tls-warn.log"

    cat >"${RSYSLOG_DYNNAME}.tls-anon-warn.conf" <<CONF_EOF
global(compatibility.defaults.secure="warn")
module(load="../plugins/imtcp/.libs/imtcp")
input(type="imtcp" port="0" listenPortFileName="${RSYSLOG_DYNNAME}.tlsanon.port" streamdriver.mode="1"
      streamdriver.name="gtls" streamdriver.authmode="anon")
action(type="omfwd" target="127.0.0.1" protocol="tcp" streamdriver.mode="1" streamdriver.authmode="anon")
CONF_EOF
    run_expect_success "${RSYSLOG_DYNNAME}.tls-anon-warn.conf" "${RSYSLOG_DYNNAME}.tls-anon-warn.log"
    content_check 'imtcp uses streamdriver.authmode="anon"; server identity is not authenticated, so MITM is possible' "${RSYSLOG_DYNNAME}.tls-anon-warn.log"
    content_check 'omfwd uses streamdriver.authmode="anon"; server identity is not authenticated, so MITM is possible' "${RSYSLOG_DYNNAME}.tls-anon-warn.log"
fi

cat >"${RSYSLOG_DYNNAME}.invalid.conf" <<CONF_EOF
global(compatibility.configformat.legacy="bad")
action(type="omfile" file="${RSYSLOG_DYNNAME}.out")
CONF_EOF
run_expect_failure "${RSYSLOG_DYNNAME}.invalid.conf" "${RSYSLOG_DYNNAME}.invalid.log"
content_check 'compatibility.configformat.legacy' "${RSYSLOG_DYNNAME}.invalid.log"

cat >"${RSYSLOG_DYNNAME}.strict-dirty.conf" <<CONF_EOF
global(compatibility.defaults.secure="strict")
global(typo.parameter="bad")
action(type="omfile" file="${RSYSLOG_DYNNAME}.out")
CONF_EOF
timeout 10s ../tools/rsyslogd -C -n -i"${RSYSLOG_DYNNAME}:strict.pid" -M"${modpath}" \
    -f"${RSYSLOG_DYNNAME}.strict-dirty.conf" >"${RSYSLOG_DYNNAME}.strict-dirty.log" 2>&1
rc=$?
if [ $rc -ne 2 ]; then
    echo "FAIL: expected secure strict mode to abort unclean config with rc 2"
    cat "${RSYSLOG_DYNNAME}.strict-dirty.log"
    error_exit 1
fi
content_check 'global(AbortOnUncleanConfig="on") is set' "${RSYSLOG_DYNNAME}.strict-dirty.log"

exit_test
