summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib.c49
-rw-r--r--src/lib.h2
-rw-r--r--src/main.c10
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);