From 06a53c87bf2870967ced8af0b32927dfbd7363ca Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Mon, 28 Jul 2014 12:38:56 +0530 Subject: server: Verify the UDP client list during token validation --- src/lib.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.h | 2 ++ src/main.c | 10 ++++++++-- 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/lib.c b/src/lib.c index cc36292..ec32660 100644 --- a/src/lib.c +++ b/src/lib.c @@ -88,6 +88,55 @@ stp_validate_token_server (GInetAddressMask *mask, return ret; } +gboolean stp_clients_is_subset (char *superset, + char *subset) +{ + gsize i, n; + gboolean ret; + char **supersetv, **subsetv; + GHashTable *superset_table = NULL; + + if (!subset) + return TRUE; + + if (!superset) + return FALSE; + + /* Simplest case */ + if (g_strcmp0 (superset, subset) == 0) + return TRUE; + + subsetv = g_strsplit (subset, ",", 0); + supersetv = g_strsplit (superset, ",", 0); + + if (sizeof(supersetv)/sizeof(supersetv[0]) <= 1 || + sizeof(subsetv)/sizeof(subsetv[0]) < 1) + /* If there's one client in the superset, and the subset didn't match, + * it won't match. Same if there's less than one client in either list. */ + goto fail; + + /* Easiest way to check. Add superset clients to a table, and then check + * whether every subset client is in that table. */ + superset_table = g_hash_table_new (g_str_hash, g_str_equal); + for (i = 0, n = sizeof(supersetv)/sizeof(supersetv[0]); i < n; i++) + g_hash_table_add (superset_table, supersetv[i]); + + for (i = 0, n = sizeof(subsetv)/sizeof(subsetv[0]); i < n; i++) + if (!g_hash_table_contains (superset_table, subsetv[i])) + goto fail; + + ret = TRUE; +out: + if (superset_table) + g_hash_table_destroy (superset_table); + g_strfreev (supersetv); + g_strfreev (subsetv); + return ret; +fail: + ret = FALSE; + goto out; +} + gboolean stp_on_gst_bus_message (GstBus *bus, GstMessage *msg, diff --git a/src/lib.h b/src/lib.h index f97b0de..6c0f771 100644 --- a/src/lib.h +++ b/src/lib.h @@ -104,6 +104,8 @@ guint stp_get_stream_type_from_string (const char *type); gboolean stp_validate_token_server (GInetAddressMask *mask, SoupClientContext *client); +gboolean stp_clients_is_subset (char *superset, + char *subset); void stp_server_ctx_cleanup (STPServerCtx *ctx); void stp_client_ctx_cleanup (STPClientCtx *ctx); diff --git a/src/main.c b/src/main.c index 8d13d7c..e88ccae 100644 --- a/src/main.c +++ b/src/main.c @@ -123,12 +123,18 @@ stp_validate_fetch_token_from_query (GHashTable *tokens, /* Only needed for RTP streaming */ udp_clients = g_hash_table_lookup (query, "udp-clients"); - if (!udp_clients) { + token->udp_clients = g_strdup (udp_clients); + + if (!token->udp_clients) { *http_status_code = SOUP_STATUS_BAD_REQUEST; goto err; } - token->udp_clients = g_strdup (udp_clients); + if (!stp_clients_is_subset (perms_token->udp_clients, + token->udp_clients)) { + *http_status_code = SOUP_STATUS_FORBIDDEN; + goto err; + } out: g_hash_table_destroy (query); -- cgit v0.11.2-2-gd1dd