git: ee75c991acdc - main - syslogd: Add syslog forwarded message format tests

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Mon, 23 Dec 2024 15:49:53 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=ee75c991acdca2103e0bc1e763a4ba67c148d132

commit ee75c991acdca2103e0bc1e763a4ba67c148d132
Author:     Michal Scigocki <michal.os@hotmail.com>
AuthorDate: 2024-12-23 02:57:13 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2024-12-23 15:45:45 +0000

    syslogd: Add syslog forwarded message format tests
    
    Reviewed by:    markj
    MFC after:      3 weeks
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/1536
---
 usr.sbin/syslogd/tests/Makefile                    |   1 +
 .../syslogd/tests/syslogd_basic_format_test.sh     |   1 -
 .../syslogd/tests/syslogd_format_test_common.sh    |  56 ++++++
 .../syslogd/tests/syslogd_forwarded_format_test.sh | 213 +++++++++++++++++++++
 4 files changed, 270 insertions(+), 1 deletion(-)

diff --git a/usr.sbin/syslogd/tests/Makefile b/usr.sbin/syslogd/tests/Makefile
index 65d08d75fcd1..36b7798d317c 100644
--- a/usr.sbin/syslogd/tests/Makefile
+++ b/usr.sbin/syslogd/tests/Makefile
@@ -1,6 +1,7 @@
 PACKAGE=	tests
 
 ATF_TESTS_SH=	syslogd_basic_format_test \
+		syslogd_forwarded_format_test \
 		syslogd_test
 
 # Run in jail with new vnet so we don't need to worry about address conflicts
diff --git a/usr.sbin/syslogd/tests/syslogd_basic_format_test.sh b/usr.sbin/syslogd/tests/syslogd_basic_format_test.sh
index 7ee7cd0e1e91..1969ce180f66 100644
--- a/usr.sbin/syslogd/tests/syslogd_basic_format_test.sh
+++ b/usr.sbin/syslogd/tests/syslogd_basic_format_test.sh
@@ -4,7 +4,6 @@
 # Copyright (c) 2024 Michal Scigocki <michal.os@hotmail.com>
 #
 
-. $(atf_get_srcdir)/syslogd_test_common.sh
 . $(atf_get_srcdir)/syslogd_format_test_common.sh
 
 # Basic format tests
diff --git a/usr.sbin/syslogd/tests/syslogd_format_test_common.sh b/usr.sbin/syslogd/tests/syslogd_format_test_common.sh
index 199fb746839c..995bb048881b 100644
--- a/usr.sbin/syslogd/tests/syslogd_format_test_common.sh
+++ b/usr.sbin/syslogd/tests/syslogd_format_test_common.sh
@@ -4,6 +4,8 @@
 # Copyright (c) 2024 Michal Scigocki <michal.os@hotmail.com>
 #
 
+. $(atf_get_srcdir)/syslogd_test_common.sh
+
 # REGEX Components
 readonly PRI="<15>"
 readonly VERSION="1"
@@ -30,3 +32,57 @@ readonly REGEX_RFC3164_LEGACY_PAYLOAD="${PRI}${REGEX_RFC3164_LEGACY}$"
 readonly REGEX_RFC5424="${PRI}${VERSION} ${TIMESPEC_RFC5424} ${HOSTNAME_REGEX} ${TAG} - - - ${MSG}"
 readonly REGEX_RFC5424_LOGFILE="^${REGEX_RFC5424}$"
 readonly REGEX_RFC5424_PAYLOAD="${REGEX_RFC5424}$"
+
+# Filename helper functions
+config_filename()
+{ local ref="$1"; echo "${PWD}/syslog_${ref}.conf"; }
+
+local_socket_filename()
+{ local ref="$1"; echo "${PWD}/log_${ref}.sock"; }
+
+pid_filename()
+{ local ref="$1"; echo "${PWD}/syslogd_${ref}.pid"; }
+
+local_privsocket_filename()
+{ local ref="$1"; echo "${PWD}/logpriv_${ref}.sock"; }
+
+confirm_INET_support_or_skip()
+{
+    if ! sysctl kern.conftxt | grep -qw INET; then
+        atf_skip "Running kernel does not support INET"
+    fi
+}
+
+set_common_atf_metadata()
+{
+    atf_set timeout 5
+    atf_set require.user root
+}
+
+# Wrapper with better semantic name for networking context
+syslogd_start_on_port()
+{
+    local port="$1"
+    shift 1
+
+    syslogd_start \
+        -b ":${port}" \
+        -f "$(config_filename ${port})" \
+        -p "$(local_socket_filename ${port})" \
+        -P "$(pid_filename ${port})" \
+        -S "$(local_privsocket_filename ${port})" \
+        $@
+}
+
+# Wrapper with better semantic name for networking context
+syslogd_stop_on_ports()
+{
+    local ports="$@"
+
+    for port in "${ports}"; do
+        syslogd_stop \
+            "$(pid_filename ${port})" \
+            "$(local_socket_filename ${port})" \
+            "$(local_privsocket_filename ${port})"
+    done
+}
diff --git a/usr.sbin/syslogd/tests/syslogd_forwarded_format_test.sh b/usr.sbin/syslogd/tests/syslogd_forwarded_format_test.sh
new file mode 100644
index 000000000000..3d220a80b7e8
--- /dev/null
+++ b/usr.sbin/syslogd/tests/syslogd_forwarded_format_test.sh
@@ -0,0 +1,213 @@
+#-
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2024 Michal Scigocki <michal.os@hotmail.com>
+#
+
+. $(atf_get_srcdir)/syslogd_format_test_common.sh
+
+SERVER_1_PORT="5140"
+SERVER_2_PORT="5141"
+
+# Forwarded Message Tests
+# Two servers, one sending syslog messages to the other over UDP
+setup_forwarded_format_test()
+{
+    local format="$1"
+    local logfile="$2"
+    local pcapfile="$3"
+
+    confirm_INET_support_or_skip
+
+    # Begin packet capture for single packet
+    tcpdump --immediate-mode -c 1 -i lo0 -w "${pcapfile}" \
+        dst port "${SERVER_1_PORT}" &
+    tcpdump_pid="$!"
+
+    # Start first server: receive UDP, log to file
+    printf "user.debug\t${logfile}\n" > "$(config_filename ${SERVER_1_PORT})"
+    syslogd_start_on_port "${SERVER_1_PORT}" -O "${format}"
+
+    # Start second server: send UDP, log to first server
+    printf "user.debug\t@127.0.0.1:${SERVER_1_PORT}\n" \
+        > "$(config_filename ${SERVER_2_PORT})"
+    syslogd_start_on_port "${SERVER_2_PORT}" -O "${format}"
+
+    # Send test syslog message
+    syslogd_log -4 -p user.debug -t "${TAG}" -h 127.0.0.1 \
+        -P "${SERVER_2_PORT}" -H "${HOSTNAME}" "${MSG}"
+
+    wait "${tcpdump_pid}" # Wait for packet capture to finish
+}
+
+atf_test_case "O_flag_bsd_forwarded" "cleanup"
+O_flag_bsd_forwarded_head()
+{
+    atf_set descr "bsd format test on a forwarded syslog message"
+    set_common_atf_metadata
+}
+O_flag_bsd_forwarded_body()
+{
+    local format="bsd"
+    local logfile="${PWD}/${format}_forwarded.log"
+    local pcapfile="${PWD}/${format}_forwarded.pcap"
+
+    setup_forwarded_format_test "${format}" "${logfile}" "${pcapfile}"
+
+    atf_expect_fail \
+        "PR 220246 syslog -O bsd deviates from RFC 3164 recommendations"
+    atf_check -s exit:0 -o match:"${REGEX_RFC3164_LOGFILE}" cat "${logfile}"
+    atf_check -s exit:0 -e ignore -o match:"${REGEX_RFC3164_PAYLOAD}" \
+        tcpdump -A -r "${pcapfile}"
+}
+O_flag_bsd_forwarded_cleanup()
+{
+    syslogd_stop_on_ports \
+        "${SERVER_1_PORT}" \
+        "${SERVER_2_PORT}"
+}
+
+atf_test_case "O_flag_rfc3164_forwarded" "cleanup"
+O_flag_rfc3164_forwarded_head()
+{
+    atf_set descr "rfc3164 format test on a forwarded syslog message"
+    set_common_atf_metadata
+}
+O_flag_rfc3164_forwarded_body()
+{
+    local format="rfc3164"
+    local logfile="${PWD}/${format}_forwarded.log"
+    local pcapfile="${PWD}/${format}_forwarded.pcap"
+
+    setup_forwarded_format_test "${format}" "${logfile}" "${pcapfile}"
+
+    atf_expect_fail \
+        "PR 220246 syslog -O rfc3164 deviates from RFC 3164 recommendations"
+    atf_check -s exit:0 -o match:"${REGEX_RFC3164_LOGFILE}" cat "${logfile}"
+    atf_check -s exit:0 -e ignore -o match:"${REGEX_RFC3164_PAYLOAD}" \
+        tcpdump -A -r "${pcapfile}"
+}
+O_flag_rfc3164_forwarded_cleanup()
+{
+    syslogd_stop_on_ports \
+        "${SERVER_1_PORT}" \
+        "${SERVER_2_PORT}"
+}
+
+atf_test_case "O_flag_syslog_forwarded" "cleanup"
+O_flag_syslog_forwarded_head()
+{
+    atf_set descr "syslog format test on a forwarded syslog message"
+    set_common_atf_metadata
+}
+O_flag_syslog_forwarded_body()
+{
+    local format="syslog"
+    local logfile="${PWD}/${format}_forwarded.log"
+    local pcapfile="${PWD}/${format}_forwarded.pcap"
+
+    setup_forwarded_format_test "${format}" "${logfile}" "${pcapfile}"
+
+    atf_check -s exit:0 -o match:"${REGEX_RFC5424_LOGFILE}" cat "${logfile}"
+    atf_check -s exit:0 -e ignore -o match:"${REGEX_RFC5424_PAYLOAD}" \
+        tcpdump -A -r "${pcapfile}"
+}
+O_flag_syslog_forwarded_cleanup()
+{
+    syslogd_stop_on_ports \
+        "${SERVER_1_PORT}" \
+        "${SERVER_2_PORT}"
+}
+
+atf_test_case "O_flag_rfc5424_forwarded" "cleanup"
+O_flag_rfc5424_forwarded_head()
+{
+    atf_set descr "rfc5424 format test on a forwarded syslog message"
+    set_common_atf_metadata
+}
+O_flag_rfc5424_forwarded_body()
+{
+    local format="rfc5424"
+    local logfile="${PWD}/${format}_forwarded.log"
+    local pcapfile="${PWD}/${format}_forwarded.pcap"
+
+    setup_forwarded_format_test "${format}" "${logfile}" "${pcapfile}"
+
+    atf_check -s exit:0 -o match:"${REGEX_RFC5424_LOGFILE}" cat "${logfile}"
+    atf_check -s exit:0 -e ignore -o match:"${REGEX_RFC5424_PAYLOAD}" \
+        tcpdump -A -r "${pcapfile}"
+}
+O_flag_rfc5424_forwarded_cleanup()
+{
+    syslogd_stop_on_ports \
+        "${SERVER_1_PORT}" \
+        "${SERVER_2_PORT}"
+}
+
+# Legacy bsd/rfc3164 format tests
+# The legacy syntax was introduced in FreeBSD PR 7055, circa 1998
+atf_test_case "O_flag_bsd_forwarded_legacy" "cleanup"
+O_flag_bsd_forwarded_legacy_head()
+{
+    atf_set descr "legacy bsd format test on a forwarded syslog message"
+    set_common_atf_metadata
+}
+O_flag_bsd_forwarded_legacy_body()
+{
+    local format="bsd"
+    local logfile="${PWD}/${format}_forwarded_legacy.log"
+    local pcapfile="${PWD}/${format}_forwarded.pcap"
+
+    setup_forwarded_format_test "${format}" "${logfile}" "${pcapfile}"
+
+    atf_check -s exit:0 -o match:"${REGEX_RFC3164_LEGACY_LOGFILE}" \
+        cat "${logfile}"
+    atf_check -s exit:0 -e ignore \
+        -o match:"${REGEX_RFC3164_LEGACY_PAYLOAD}" \
+        tcpdump -A -r "${pcapfile}"
+}
+O_flag_bsd_forwarded_legacy_cleanup()
+{
+    syslogd_stop_on_ports \
+        "${SERVER_1_PORT}" \
+        "${SERVER_2_PORT}"
+}
+
+atf_test_case "O_flag_rfc3164_forwarded_legacy" "cleanup"
+O_flag_rfc3164_forwarded_legacy_head()
+{
+    atf_set descr \
+        "legacy rfc3164 format test on a forwarded syslog message"
+    set_common_atf_metadata
+}
+O_flag_rfc3164_forwarded_legacy_body()
+{
+    local format="rfc3164"
+    local logfile="${PWD}/${format}_forwarded_legacy.log"
+    local pcapfile="${PWD}/${format}_forwarded.pcap"
+
+    setup_forwarded_format_test "${format}" "${logfile}" "${pcapfile}"
+
+    atf_check -s exit:0 -o match:"${REGEX_RFC3164_LEGACY_LOGFILE}" \
+        cat "${logfile}"
+    atf_check -s exit:0 -e ignore \
+        -o match:"${REGEX_RFC3164_LEGACY_PAYLOAD}" \
+        tcpdump -A -r "${pcapfile}"
+}
+O_flag_rfc3164_forwarded_legacy_cleanup()
+{
+    syslogd_stop_on_ports \
+        "${SERVER_1_PORT}" \
+        "${SERVER_2_PORT}"
+}
+
+atf_init_test_cases()
+{
+    atf_add_test_case "O_flag_bsd_forwarded"
+    atf_add_test_case "O_flag_rfc3164_forwarded"
+    atf_add_test_case "O_flag_syslog_forwarded"
+    atf_add_test_case "O_flag_rfc5424_forwarded"
+
+    atf_add_test_case "O_flag_bsd_forwarded_legacy"
+    atf_add_test_case "O_flag_rfc3164_forwarded_legacy"
+}