diff options
author | Jens Georg <mail@jensge.org> | 2021-05-10 11:45:57 +0200 |
---|---|---|
committer | Jens Georg <mail@jensge.org> | 2021-05-24 08:49:22 +0000 |
commit | 9751b5b6f598cff903f482c79336ebd8ed3cfef9 (patch) | |
tree | 2a3079c85b7aa014db5473c8b19096d9f3442ad9 | |
parent | ca6ec9dcb26fd7a2a630eb6a68118659b589afac (diff) | |
download | gupnp-wip/24.tar.gz |
Tests: Add test for host header validationwip/24
-rw-r--r-- | libgupnp/gupnp-context-private.h | 5 | ||||
-rw-r--r-- | libgupnp/gupnp-context.c | 25 | ||||
-rw-r--r-- | tests/gtest/test-bugs.c | 78 |
3 files changed, 99 insertions, 9 deletions
diff --git a/libgupnp/gupnp-context-private.h b/libgupnp/gupnp-context-private.h index a143885..111abd3 100644 --- a/libgupnp/gupnp-context-private.h +++ b/libgupnp/gupnp-context-private.h @@ -46,6 +46,11 @@ gupnp_context_ip_is_ours (GUPnPContext *context, const char *address); G_GNUC_INTERNAL gboolean gupnp_context_validate_host_header (GUPnPContext *context, const char *host); +gboolean +validate_host_header (const char *host_header, + const char *host_ip, + guint context_port); + G_END_DECLS #endif /* GUPNP_CONTEXT_PRIVATE_H */ diff --git a/libgupnp/gupnp-context.c b/libgupnp/gupnp-context.c index 66b1750..44e67e5 100644 --- a/libgupnp/gupnp-context.c +++ b/libgupnp/gupnp-context.c @@ -1711,9 +1711,11 @@ out: } gboolean -gupnp_context_validate_host_header (GUPnPContext *context, - const char *host_header) +validate_host_header (const char *host_header, + const char *host_ip, + guint context_port) { + gboolean retval = FALSE; // Be lazy and let GUri do the heavy lifting here, such as stripping the // [] from v6 addresses, splitting of the port etc. @@ -1736,8 +1738,11 @@ gupnp_context_validate_host_header (GUPnPContext *context, goto out; } - const char *host_ip = gssdp_client_get_host_ip (GSSDP_CLIENT (context)); - gint context_port = gupnp_context_get_port (context); + // -1 means there was no :port; according to UDA this is allowed and + // defaults to 80, the HTTP port then + if (port == -1) { + port = 80; + } if (!g_str_equal (host, host_ip)) { g_debug ("Mismatch between host header and host IP (%s, " @@ -1757,6 +1762,18 @@ gupnp_context_validate_host_header (GUPnPContext *context, out: g_clear_error (&error); + g_free (host); g_free (uri_from_host); + return retval; } + +gboolean +gupnp_context_validate_host_header (GUPnPContext *context, + const char *host_header) +{ + return validate_host_header ( + host_header, + gssdp_client_get_host_ip (GSSDP_CLIENT (context)), + gupnp_context_get_port (context)); +} diff --git a/tests/gtest/test-bugs.c b/tests/gtest/test-bugs.c index db94285..071febc 100644 --- a/tests/gtest/test-bugs.c +++ b/tests/gtest/test-bugs.c @@ -25,6 +25,7 @@ #include <libgupnp/gupnp.h> #include <libgupnp/gupnp-service-private.h> +#include <libgupnp/gupnp-context-private.h> static GUPnPContext * create_context (guint16 port, GError **error) { @@ -469,14 +470,81 @@ test_bgo_743233 (void) g_object_unref (context); } +static void +test_ggo_24 (void) +{ + // IPv4 + g_assert ( + validate_host_header ("127.0.0.1:4711", "127.0.0.1", 4711)); + + g_assert ( + validate_host_header ("127.0.0.1", "127.0.0.1", 80)); + + g_assert_false ( + validate_host_header ("example.com", "127.0.0.1", 4711)); + + g_assert_false ( + validate_host_header ("example.com:80", "127.0.0.1", 4711)); + + g_assert_false ( + validate_host_header ("example.com:4711", "127.0.0.1", 4711)); + + g_assert_false ( + validate_host_header ("192.168.1.2:4711", "127.0.0.1", 4711)); + + g_assert_false ( + validate_host_header ("[fe80::01]", "127.0.0.1", 4711)); + + // Link ids should not be parsed + g_assert_false ( + validate_host_header ("[fe80::01%1]", "127.0.0.1", 4711)); + + g_assert_false ( + validate_host_header ("[fe80::01%eth0]", "127.0.0.1", 4711)); + + // IPv6 + g_assert ( + validate_host_header ("[::1]:4711", "::1", 4711)); + + g_assert ( + validate_host_header ("[::1]", "::1", 80)); + + // Host header needs to be enclosed in [] even without port + g_assert_false ( + validate_host_header ("::1", "::1", 80)); + + g_assert_false ( + validate_host_header ("example.com", "::1", 4711)); + + g_assert_false ( + validate_host_header ("example.com:80", "::1", 4711)); + + g_assert_false ( + validate_host_header ("example.com:4711", "::1", 4711)); + + g_assert_false ( + validate_host_header ("192.168.1.2:4711", "::1", 4711)); + + g_assert_false ( + validate_host_header ("[fe80::01]", "::1", 4711)); + + // Link ids should not be parsed + g_assert_false ( + validate_host_header ("[fe80::01%1]", "fe80::acab", 4711)); + + g_assert_false ( + validate_host_header ("[fe80::01%eth0]", "fe80::acab", 4711)); +} + int main (int argc, char *argv[]) { g_test_init (&argc, &argv, NULL); - g_test_add_func ("/bugs/696762", test_bgo_696762); - g_test_add_func ("/bugs/678701", test_bgo_678701); - g_test_add_func ("/bugs/690400", test_bgo_690400); - g_test_add_func ("/bugs/722696", test_bgo_722696); - g_test_add_func ("/bugs/743233", test_bgo_743233); + g_test_add_func ("/bugs/bgo/696762", test_bgo_696762); + g_test_add_func ("/bugs/bgo/678701", test_bgo_678701); + g_test_add_func ("/bugs/bgo/690400", test_bgo_690400); + g_test_add_func ("/bugs/bgo/722696", test_bgo_722696); + g_test_add_func ("/bugs/bgo/743233", test_bgo_743233); + g_test_add_func ("/bugs/ggo/24", test_ggo_24); return g_test_run (); } |