|
@@ -0,0 +1,292 @@
|
|
|
+From 12a0624e4c275f14cee9a6b4f36e714d2ced8544 Mon Sep 17 00:00:00 2001
|
|
|
+From: therandomstring <bal.horv.98@gmail.com>
|
|
|
+Date: Wed, 07 May 2025 09:30:36 +0530
|
|
|
+Subject: [PATCH] Merge commit from fork
|
|
|
+
|
|
|
+Fix transport accepting incorrect wildcards
|
|
|
+
|
|
|
+CVE: CVE-2024-47619
|
|
|
+Upstream-Status: Backport [https://github.com/syslog-ng/syslog-ng/commit/12a0624e4c275f14cee9a6b4f36e714d2ced8544]
|
|
|
+
|
|
|
+Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
|
|
|
+---
|
|
|
+ lib/transport/tests/CMakeLists.txt | 1 +
|
|
|
+ lib/transport/tests/Makefile.am | 9 +-
|
|
|
+ lib/transport/tests/test_tls_wildcard_match.c | 104 ++++++++++++++++++
|
|
|
+ lib/transport/tls-verifier.c | 86 +++++++++++++--
|
|
|
+ lib/transport/tls-verifier.h | 2 +
|
|
|
+ 5 files changed, 190 insertions(+), 12 deletions(-)
|
|
|
+ create mode 100644 lib/transport/tests/test_tls_wildcard_match.c
|
|
|
+
|
|
|
+diff --git a/lib/transport/tests/CMakeLists.txt b/lib/transport/tests/CMakeLists.txt
|
|
|
+index 834f456..ce1d033 100644
|
|
|
+--- a/lib/transport/tests/CMakeLists.txt
|
|
|
++++ b/lib/transport/tests/CMakeLists.txt
|
|
|
+@@ -3,3 +3,4 @@ add_unit_test(CRITERION TARGET test_transport_factory_id)
|
|
|
+ add_unit_test(CRITERION TARGET test_transport_factory)
|
|
|
+ add_unit_test(CRITERION TARGET test_transport_factory_registry)
|
|
|
+ add_unit_test(CRITERION TARGET test_multitransport)
|
|
|
++add_unit_test(CRITERION TARGET test_tls_wildcard_match)
|
|
|
+diff --git a/lib/transport/tests/Makefile.am b/lib/transport/tests/Makefile.am
|
|
|
+index 7eac994..ae2426c 100644
|
|
|
+--- a/lib/transport/tests/Makefile.am
|
|
|
++++ b/lib/transport/tests/Makefile.am
|
|
|
+@@ -3,7 +3,8 @@ lib_transport_tests_TESTS = \
|
|
|
+ lib/transport/tests/test_transport_factory_id \
|
|
|
+ lib/transport/tests/test_transport_factory \
|
|
|
+ lib/transport/tests/test_transport_factory_registry \
|
|
|
+- lib/transport/tests/test_multitransport
|
|
|
++ lib/transport/tests/test_multitransport \
|
|
|
++ lib/transport/tests/test_tls_wildcard_match
|
|
|
+
|
|
|
+ EXTRA_DIST += lib/transport/tests/CMakeLists.txt
|
|
|
+
|
|
|
+@@ -38,3 +39,9 @@ lib_transport_tests_test_multitransport_CFLAGS = $(TEST_CFLAGS) \
|
|
|
+ lib_transport_tests_test_multitransport_LDADD = $(TEST_LDADD)
|
|
|
+ lib_transport_tests_test_multitransport_SOURCES = \
|
|
|
+ lib/transport/tests/test_multitransport.c
|
|
|
++
|
|
|
++lib_transport_tests_test_tls_wildcard_match_CFLAGS = $(TEST_CFLAGS) \
|
|
|
++ -I${top_srcdir}/lib/transport/tests
|
|
|
++lib_transport_tests_test_tls_wildcard_match_LDADD = $(TEST_LDADD)
|
|
|
++lib_transport_tests_test_tls_wildcard_match_SOURCES = \
|
|
|
++ lib/transport/tests/test_tls_wildcard_match.c
|
|
|
+diff --git a/lib/transport/tests/test_tls_wildcard_match.c b/lib/transport/tests/test_tls_wildcard_match.c
|
|
|
+new file mode 100644
|
|
|
+index 0000000..90cecb0
|
|
|
+--- /dev/null
|
|
|
++++ b/lib/transport/tests/test_tls_wildcard_match.c
|
|
|
+@@ -0,0 +1,104 @@
|
|
|
++/*
|
|
|
++ * Copyright (c) 2024 One Identity LLC.
|
|
|
++ * Copyright (c) 2024 Franco Fichtner
|
|
|
++ *
|
|
|
++ * This library is free software; you can redistribute it and/or
|
|
|
++ * modify it under the terms of the GNU Lesser General Public
|
|
|
++ * License as published by the Free Software Foundation; either
|
|
|
++ * version 2.1 of the License, or (at your option) any later version.
|
|
|
++ *
|
|
|
++ * This library is distributed in the hope that it will be useful,
|
|
|
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
++ * Lesser General Public License for more details.
|
|
|
++ *
|
|
|
++ * You should have received a copy of the GNU Lesser General Public
|
|
|
++ * License along with this library; if not, write to the Free Software
|
|
|
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
++ *
|
|
|
++ * As an additional exemption you are allowed to compile & link against the
|
|
|
++ * OpenSSL libraries as published by the OpenSSL project. See the file
|
|
|
++ * COPYING for details.
|
|
|
++ *
|
|
|
++ */
|
|
|
++
|
|
|
++
|
|
|
++#include <criterion/criterion.h>
|
|
|
++
|
|
|
++#include "transport/tls-verifier.h"
|
|
|
++
|
|
|
++TestSuite(tls_wildcard, .init = NULL, .fini = NULL);
|
|
|
++
|
|
|
++Test(tls_wildcard, test_wildcard_match_pattern_acceptance)
|
|
|
++{
|
|
|
++ cr_assert_eq(tls_wildcard_match("test", "test"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test", "*"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test", "t*t"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test", "t*"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("", ""), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.one", "test.one"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.one.two", "test.one.two"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("192.0.2.0", "192.0.2.0"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("2001:0000:130F:0000:0000:09C0:876A:130B", "2001:0000:130F:0000:0000:09C0:876A:130B"),
|
|
|
++ TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("2001:0000:130F:0000:0000:09C0:876A:130B", "2001:0:130F:0:0:9C0:876A:130B"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("2001:0:130F:0:0:9C0:876A:130B", "2001:0000:130F:0000:0000:09C0:876A:130B"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("2001:0000:130F::09C0:876A:130B", "2001:0000:130F:0000:0000:09C0:876A:130B"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("2001:0000:130F:0000:0000:09C0:876A:130B", "2001:0000:130F::09C0:876A:130B"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("2001:0000:130F:0000:0000:09C0:876A:130B", "2001:0:130F::9C0:876A:130B"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("2001:0:130F::9C0:876A:130B", "2001:0000:130F:0000:0000:09C0:876A:130B"), TRUE);
|
|
|
++}
|
|
|
++
|
|
|
++Test(tls_wildcard, test_wildcard_match_wildcard_rejection)
|
|
|
++{
|
|
|
++ cr_assert_eq(tls_wildcard_match("test", "**"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test", "*es*"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test", "t*?"), FALSE);
|
|
|
++}
|
|
|
++
|
|
|
++Test(tls_wildcard, test_wildcard_match_pattern_rejection)
|
|
|
++{
|
|
|
++ cr_assert_eq(tls_wildcard_match("test", "tset"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test", "set"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("", "*"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test", ""), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.two", "test.one"), FALSE);
|
|
|
++}
|
|
|
++
|
|
|
++Test(tls_wildcard, test_wildcard_match_format_rejection)
|
|
|
++{
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.two", "test.*"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.two", "test.t*o"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test", "test.two"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.two", "test"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.one.two", "test.one"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.one", "test.one.two"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.three", "three.test"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.one.two", "test.one.*"), FALSE);
|
|
|
++}
|
|
|
++
|
|
|
++Test(tls_wildcard, test_wildcard_match_complex_rejection)
|
|
|
++{
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.two", "test.???"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.one.two", "test.one.?wo"), FALSE);
|
|
|
++}
|
|
|
++
|
|
|
++Test(tls_wildcard, test_ip_wildcard_rejection)
|
|
|
++{
|
|
|
++ cr_assert_eq(tls_wildcard_match("192.0.2.0", "*.0.2.0"), FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("2001:0000:130F:0000:0000:09C0:876A:130B", "*:0000:130F:0000:0000:09C0:876A:130B"),
|
|
|
++ FALSE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("2001:0:130F::9C0:876A:130B", "*:0000:130F:0000:0000:09C0:876A:130B"), FALSE);
|
|
|
++}
|
|
|
++
|
|
|
++Test(tls_wildcard, test_case_insensivity)
|
|
|
++{
|
|
|
++ cr_assert_eq(tls_wildcard_match("test", "TEST"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("TEST", "test"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("TeST", "TEst"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.one", "test.ONE"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.TWO", "test.two"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("test.three", "*T.three"), TRUE);
|
|
|
++ cr_assert_eq(tls_wildcard_match("2001:0000:130F:0000:0000:09C0:876A:130B", "2001:0000:130f:0000:0000:09c0:876a:130b"),
|
|
|
++ TRUE);
|
|
|
++}
|
|
|
+diff --git a/lib/transport/tls-verifier.c b/lib/transport/tls-verifier.c
|
|
|
+index 606ad02..dde00d9 100644
|
|
|
+--- a/lib/transport/tls-verifier.c
|
|
|
++++ b/lib/transport/tls-verifier.c
|
|
|
+@@ -1,4 +1,6 @@
|
|
|
+ /*
|
|
|
++ * Copyright (c) 2024 One Identity LLC.
|
|
|
++ * Copyright (c) 2024 Franco Fichtner
|
|
|
+ * Copyright (c) 2002-2011 Balabit
|
|
|
+ * Copyright (c) 1998-2011 Balázs Scheidler
|
|
|
+ *
|
|
|
+@@ -75,7 +77,7 @@ tls_verifier_unref(TLSVerifier *self)
|
|
|
+
|
|
|
+ /* helper functions */
|
|
|
+
|
|
|
+-static gboolean
|
|
|
++gboolean
|
|
|
+ tls_wildcard_match(const gchar *host_name, const gchar *pattern)
|
|
|
+ {
|
|
|
+ gchar **pattern_parts, **hostname_parts;
|
|
|
+@@ -86,22 +88,84 @@ tls_wildcard_match(const gchar *host_name, const gchar *pattern)
|
|
|
+
|
|
|
+ pattern_parts = g_strsplit(pattern, ".", 0);
|
|
|
+ hostname_parts = g_strsplit(host_name, ".", 0);
|
|
|
+- for (i = 0; pattern_parts[i]; i++)
|
|
|
++
|
|
|
++ if(g_strrstr(pattern, "\?"))
|
|
|
++ {
|
|
|
++ /* Glib would treat any question marks as jokers */
|
|
|
++ success = FALSE;
|
|
|
++ }
|
|
|
++ else if (g_hostname_is_ip_address(host_name))
|
|
|
++ {
|
|
|
++ /* no wildcards in IP */
|
|
|
++ if (g_strrstr(pattern, "*"))
|
|
|
++ {
|
|
|
++ success = FALSE;
|
|
|
++ }
|
|
|
++ else
|
|
|
++ {
|
|
|
++ struct in6_addr host_buffer, pattern_buffer;
|
|
|
++ gint INET_TYPE, INET_ADDRLEN;
|
|
|
++ if(strstr(host_name, ":"))
|
|
|
++ {
|
|
|
++ INET_TYPE = AF_INET6;
|
|
|
++ INET_ADDRLEN = INET6_ADDRSTRLEN;
|
|
|
++ }
|
|
|
++ else
|
|
|
++ {
|
|
|
++ INET_TYPE = AF_INET;
|
|
|
++ INET_ADDRLEN = INET_ADDRSTRLEN;
|
|
|
++ }
|
|
|
++ char host_ip[INET_ADDRLEN], pattern_ip[INET_ADDRLEN];
|
|
|
++ gint host_ip_ok = inet_pton(INET_TYPE, host_name, &host_buffer);
|
|
|
++ gint pattern_ip_ok = inet_pton(INET_TYPE, pattern, &pattern_buffer);
|
|
|
++ inet_ntop(INET_TYPE, &host_buffer, host_ip, INET_ADDRLEN);
|
|
|
++ inet_ntop(INET_TYPE, &pattern_buffer, pattern_ip, INET_ADDRLEN);
|
|
|
++ success = (host_ip_ok && pattern_ip_ok && strcmp(host_ip, pattern_ip) == 0);
|
|
|
++ }
|
|
|
++ }
|
|
|
++ else
|
|
|
+ {
|
|
|
+- if (!hostname_parts[i])
|
|
|
++ if (pattern_parts[0] == NULL)
|
|
|
+ {
|
|
|
+- /* number of dot separated entries is not the same in the hostname and the pattern spec */
|
|
|
+- goto exit;
|
|
|
++ if (hostname_parts[0] == NULL)
|
|
|
++ success = TRUE;
|
|
|
++ else
|
|
|
++ success = FALSE;
|
|
|
+ }
|
|
|
++ else
|
|
|
++ {
|
|
|
++ success = TRUE;
|
|
|
++ for (i = 0; pattern_parts[i]; i++)
|
|
|
++ {
|
|
|
++ if (hostname_parts[i] == NULL)
|
|
|
++ {
|
|
|
++ /* number of dot separated entries is not the same in the hostname and the pattern spec */
|
|
|
++ success = FALSE;
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ char *wildcard_matched = g_strrstr(pattern_parts[i], "*");
|
|
|
++ if (wildcard_matched && (i != 0 || wildcard_matched != strstr(pattern_parts[i], "*")))
|
|
|
++ {
|
|
|
++ /* wildcard only on leftmost part and never as multiple wildcards as per both RFC 6125 and 9525 */
|
|
|
++ success = FALSE;
|
|
|
++ break;
|
|
|
++ }
|
|
|
+
|
|
|
+- lower_pattern = g_ascii_strdown(pattern_parts[i], -1);
|
|
|
+- lower_hostname = g_ascii_strdown(hostname_parts[i], -1);
|
|
|
++ lower_pattern = g_ascii_strdown(pattern_parts[i], -1);
|
|
|
++ lower_hostname = g_ascii_strdown(hostname_parts[i], -1);
|
|
|
+
|
|
|
+- if (!g_pattern_match_simple(lower_pattern, lower_hostname))
|
|
|
+- goto exit;
|
|
|
++ if (!g_pattern_match_simple(lower_pattern, lower_hostname))
|
|
|
++ {
|
|
|
++ success = FALSE;
|
|
|
++ break;
|
|
|
++ }
|
|
|
++ }
|
|
|
++ if (hostname_parts[i])
|
|
|
++ /* hostname has more parts than the pattern */
|
|
|
++ success = FALSE;
|
|
|
++ }
|
|
|
+ }
|
|
|
+- success = TRUE;
|
|
|
+-exit:
|
|
|
++
|
|
|
+ g_free(lower_pattern);
|
|
|
+ g_free(lower_hostname);
|
|
|
+ g_strfreev(pattern_parts);
|
|
|
+diff --git a/lib/transport/tls-verifier.h b/lib/transport/tls-verifier.h
|
|
|
+index 5642afa..98ab858 100644
|
|
|
+--- a/lib/transport/tls-verifier.h
|
|
|
++++ b/lib/transport/tls-verifier.h
|
|
|
+@@ -44,5 +44,7 @@ void tls_verifier_unref(TLSVerifier *self);
|
|
|
+
|
|
|
+ gboolean tls_verify_certificate_name(X509 *cert, const gchar *hostname);
|
|
|
+
|
|
|
++gboolean tls_wildcard_match(const gchar *host_name, const gchar *pattern);
|
|
|
++
|
|
|
+
|
|
|
+ #endif
|
|
|
+--
|
|
|
+2.40.0
|