Blame SOURCES/0001-Tests-Add-test-for-host-header-validation.patch

495d73
From 125e957092083ea37cf8ac712fa62587e3817242 Mon Sep 17 00:00:00 2001
495d73
From: Jens Georg <mail@jensge.org>
495d73
Date: Mon, 10 May 2021 11:45:57 +0200
495d73
Subject: [PATCH] Tests: Add test for host header validation
495d73
495d73
---
495d73
 libgupnp/gupnp-context-private.h |  5 ++
495d73
 libgupnp/gupnp-context.c         | 25 ++++++++--
495d73
 tests/gtest/test-bugs.c          | 78 ++++++++++++++++++++++++++++++--
495d73
 3 files changed, 99 insertions(+), 9 deletions(-)
495d73
495d73
diff --git a/libgupnp/gupnp-context-private.h b/libgupnp/gupnp-context-private.h
495d73
index 5848d02..a8b4a75 100644
495d73
--- a/libgupnp/gupnp-context-private.h
495d73
+++ b/libgupnp/gupnp-context-private.h
495d73
@@ -42,6 +42,11 @@ gupnp_context_ip_is_ours (GUPnPContext *context, const char *address);
495d73
 G_GNUC_INTERNAL gboolean
495d73
 gupnp_context_validate_host_header (GUPnPContext *context, const char *host);
495d73
 
495d73
+gboolean
495d73
+validate_host_header (const char *host_header,
495d73
+                      const char *host_ip,
495d73
+                      guint context_port);
495d73
+
495d73
 G_END_DECLS
495d73
 
495d73
 #endif /* __GUPNP_CONTEXT_PRIVATE_H__ */
495d73
diff --git a/libgupnp/gupnp-context.c b/libgupnp/gupnp-context.c
495d73
index 0381474..ec88b93 100644
495d73
--- a/libgupnp/gupnp-context.c
495d73
+++ b/libgupnp/gupnp-context.c
495d73
@@ -1585,9 +1585,11 @@ out:
495d73
 }
495d73
 
495d73
 gboolean
495d73
-gupnp_context_validate_host_header (GUPnPContext *context,
495d73
-                                    const char *host_header)
495d73
+validate_host_header (const char *host_header,
495d73
+                      const char *host_ip,
495d73
+                      guint context_port)
495d73
 {
495d73
+
495d73
         gboolean retval = FALSE;
495d73
         // Be lazy and let GUri do the heavy lifting here, such as stripping the
495d73
         // [] from v6 addresses, splitting of the port etc.
495d73
@@ -1610,8 +1612,11 @@ gupnp_context_validate_host_header (GUPnPContext *context,
495d73
                 goto out;
495d73
         }
495d73
 
495d73
-        const char *host_ip = gssdp_client_get_host_ip (GSSDP_CLIENT (context));
495d73
-        gint context_port = gupnp_context_get_port (context);
495d73
+        // -1 means there was no :port; according to UDA this is allowed and
495d73
+        // defaults to 80, the HTTP port then
495d73
+        if (port == -1) {
495d73
+                port = 80;
495d73
+        }
495d73
 
495d73
         if (!g_str_equal (host, host_ip)) {
495d73
                 g_debug ("Mismatch between host header and host IP (%s, "
495d73
@@ -1631,6 +1636,18 @@ gupnp_context_validate_host_header (GUPnPContext *context,
495d73
 
495d73
 out:
495d73
         g_clear_error (&error);
495d73
+        g_free (host);
495d73
         g_free (uri_from_host);
495d73
+
495d73
         return retval;
495d73
 }
495d73
+
495d73
+gboolean
495d73
+gupnp_context_validate_host_header (GUPnPContext *context,
495d73
+                                    const char *host_header)
495d73
+{
495d73
+        return validate_host_header (
495d73
+                host_header,
495d73
+                gssdp_client_get_host_ip (GSSDP_CLIENT (context)),
495d73
+                gupnp_context_get_port (context));
495d73
+}
495d73
diff --git a/tests/gtest/test-bugs.c b/tests/gtest/test-bugs.c
495d73
index 0ffac76..24ec4ba 100644
495d73
--- a/tests/gtest/test-bugs.c
495d73
+++ b/tests/gtest/test-bugs.c
495d73
@@ -24,6 +24,7 @@
495d73
 #endif
495d73
 
495d73
 #include <libgupnp/gupnp.h>
495d73
+#include <libgupnp/gupnp-context-private.h>
495d73
 
495d73
 
495d73
 struct _GUPnPServiceAction {
495d73
@@ -468,14 +469,81 @@ test_bgo_743233 (void)
495d73
     g_object_unref (context);
495d73
 }
495d73
 
495d73
+static void
495d73
+test_ggo_24 (void)
495d73
+{
495d73
+        // IPv4
495d73
+        g_assert (
495d73
+                validate_host_header ("127.0.0.1:4711", "127.0.0.1", 4711));
495d73
+
495d73
+        g_assert (
495d73
+                validate_host_header ("127.0.0.1", "127.0.0.1", 80));
495d73
+
495d73
+        g_assert_false (
495d73
+                validate_host_header ("example.com", "127.0.0.1", 4711));
495d73
+
495d73
+        g_assert_false (
495d73
+                validate_host_header ("example.com:80", "127.0.0.1", 4711));
495d73
+
495d73
+        g_assert_false (
495d73
+                validate_host_header ("example.com:4711", "127.0.0.1", 4711));
495d73
+
495d73
+        g_assert_false (
495d73
+                validate_host_header ("192.168.1.2:4711", "127.0.0.1", 4711));
495d73
+
495d73
+        g_assert_false (
495d73
+                validate_host_header ("[fe80::01]", "127.0.0.1", 4711));
495d73
+
495d73
+        // Link ids should not be parsed
495d73
+        g_assert_false (
495d73
+                validate_host_header ("[fe80::01%1]", "127.0.0.1", 4711));
495d73
+
495d73
+        g_assert_false (
495d73
+                validate_host_header ("[fe80::01%eth0]", "127.0.0.1", 4711));
495d73
+
495d73
+        // IPv6
495d73
+        g_assert (
495d73
+                validate_host_header ("[::1]:4711", "::1", 4711));
495d73
+
495d73
+        g_assert (
495d73
+                validate_host_header ("[::1]", "::1", 80));
495d73
+
495d73
+        // Host header needs to be enclosed in [] even without port
495d73
+        g_assert_false (
495d73
+                validate_host_header ("::1", "::1", 80));
495d73
+
495d73
+        g_assert_false (
495d73
+                validate_host_header ("example.com", "::1", 4711));
495d73
+
495d73
+        g_assert_false (
495d73
+                validate_host_header ("example.com:80", "::1", 4711));
495d73
+
495d73
+        g_assert_false (
495d73
+                validate_host_header ("example.com:4711", "::1", 4711));
495d73
+
495d73
+        g_assert_false (
495d73
+                validate_host_header ("192.168.1.2:4711", "::1", 4711));
495d73
+
495d73
+        g_assert_false (
495d73
+                validate_host_header ("[fe80::01]", "::1", 4711));
495d73
+
495d73
+        // Link ids should not be parsed
495d73
+        g_assert_false (
495d73
+                validate_host_header ("[fe80::01%1]", "fe80::acab", 4711));
495d73
+
495d73
+        g_assert_false (
495d73
+                validate_host_header ("[fe80::01%eth0]", "fe80::acab", 4711));
495d73
+}
495d73
+
495d73
 int
495d73
 main (int argc, char *argv[]) {
495d73
     g_test_init (&argc, &argv, NULL);
495d73
-    g_test_add_func ("/bugs/696762", test_bgo_696762);
495d73
-    g_test_add_func ("/bugs/678701", test_bgo_678701);
495d73
-    g_test_add_func ("/bugs/690400", test_bgo_690400);
495d73
-    g_test_add_func ("/bugs/722696", test_bgo_722696);
495d73
-    g_test_add_func ("/bugs/743233", test_bgo_743233);
495d73
+    g_test_add_func ("/bugs/bgo/696762", test_bgo_696762);
495d73
+    g_test_add_func ("/bugs/bgo/678701", test_bgo_678701);
495d73
+    g_test_add_func ("/bugs/bgo/690400", test_bgo_690400);
495d73
+    g_test_add_func ("/bugs/bgo/722696", test_bgo_722696);
495d73
+    g_test_add_func ("/bugs/bgo/743233", test_bgo_743233);
495d73
+    g_test_add_func ("/bugs/ggo/24", test_ggo_24);
495d73
 
495d73
     return g_test_run ();
495d73
 }
495d73
-- 
495d73
2.31.1
495d73