From a63f4a2a4c428be58e32e3f08d1fcbb99f5ac29b Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 8 Jul 2013 16:29:01 +0200 Subject: [PATCH] auth: add auth checks Add an enum with auth checks and implement the checks in the auth object. Perform the checks from the client. --- examples/test-auth.c | 11 ++++++++--- gst/rtsp-server/rtsp-auth.c | 35 ++++++++++++++++++++++++----------- gst/rtsp-server/rtsp-auth.h | 16 ++++++++++++++-- gst/rtsp-server/rtsp-client.c | 19 ++++++++++++++++++- 4 files changed, 64 insertions(+), 17 deletions(-) diff --git a/examples/test-auth.c b/examples/test-auth.c index 15843d1..75455de 100644 --- a/examples/test-auth.c +++ b/examples/test-auth.c @@ -65,6 +65,8 @@ main (int argc, char *argv[]) GstRTSPToken *token; gchar *basic; GstStructure *s; + gchar *role_user[] = { "user", NULL }; + gchar *role_admin[] = { "admin", NULL }; gst_init (&argc, &argv); @@ -109,7 +111,8 @@ main (int argc, char *argv[]) /* make user token */ token = gst_rtsp_token_new (); s = gst_rtsp_token_writable_structure (token); - gst_structure_set (s, "manager.cgroup", G_TYPE_STRING, "user", NULL); + gst_structure_set (s, "manager.role", G_TYPE_STRING, "user", NULL); + gst_structure_set (s, "factory.media.roles", G_TYPE_STRV, role_user, NULL); basic = gst_rtsp_auth_make_basic ("user", "password"); gst_rtsp_auth_add_basic (auth, basic, token); g_free (basic); @@ -118,7 +121,8 @@ main (int argc, char *argv[]) /* make admin token */ token = gst_rtsp_token_new (); s = gst_rtsp_token_writable_structure (token); - gst_structure_set (s, "manager.cgroup", G_TYPE_STRING, "admin", NULL); + gst_structure_set (s, "manager.role", G_TYPE_STRING, "admin", NULL); + gst_structure_set (s, "factory.media.roles", G_TYPE_STRV, role_admin, NULL); basic = gst_rtsp_auth_make_basic ("admin", "power"); gst_rtsp_auth_add_basic (auth, basic, token); g_free (basic); @@ -127,7 +131,8 @@ main (int argc, char *argv[]) /* make admin2 token */ token = gst_rtsp_token_new (); s = gst_rtsp_token_writable_structure (token); - gst_structure_set (s, "manager.cgroup", G_TYPE_STRING, "admin", NULL); + gst_structure_set (s, "manager.role", G_TYPE_STRING, "admin", NULL); + gst_structure_set (s, "factory.media.roles", G_TYPE_STRV, role_admin, NULL); basic = gst_rtsp_auth_make_basic ("admin2", "power2"); gst_rtsp_auth_add_basic (auth, basic, token); g_free (basic); diff --git a/gst/rtsp-server/rtsp-auth.c b/gst/rtsp-server/rtsp-auth.c index 6f115ff..ac3fb3e 100644 --- a/gst/rtsp-server/rtsp-auth.c +++ b/gst/rtsp-server/rtsp-auth.c @@ -283,35 +283,48 @@ no_auth: static gboolean default_check (GstRTSPAuth * auth, GstRTSPClient * client, - GQuark hint, GstRTSPClientState * state) + GstRTSPAuthCheck check, GstRTSPClientState * state) { GstRTSPAuthPrivate *priv = auth->priv; GstRTSPAuthClass *klass; + gboolean need_authorized = FALSE; + gboolean res = FALSE; klass = GST_RTSP_AUTH_GET_CLASS (auth); - if ((state->method & priv->methods) != 0) { - /* we need an authgroup to check */ + switch (check) { + case GST_RTSP_AUTH_CHECK_URL: + if ((state->method & priv->methods) != 0) + need_authorized = TRUE; + else + res = TRUE; + break; + case GST_RTSP_AUTH_CHECK_FACTORY: + res = TRUE; + break; + } + + if (need_authorized) { + /* we need a token to check */ if (state->token == NULL) { if (klass->authenticate) { if (!klass->authenticate (auth, client, state)) goto authenticate_failed; } } - if (state->token == NULL) goto no_auth; } - return TRUE; + return res; authenticate_failed: { - GST_DEBUG_OBJECT (auth, "check failed"); + GST_DEBUG_OBJECT (auth, "authenticate failed"); return FALSE; } no_auth: { - GST_DEBUG_OBJECT (auth, "no authorization group found"); + GST_DEBUG_OBJECT (auth, "no authorization token found"); return FALSE; } } @@ -320,17 +333,17 @@ no_auth: * gst_rtsp_auth_check: * @auth: a #GstRTSPAuth * @client: the client - * @hint: a hint + * @check: the item to check * @state: client state * - * Check if @client with state is authorized to perform @hint in the + * Check if @client with state is authorized to perform @check in the * current @state. * * Returns: FALSE if check failed. */ gboolean gst_rtsp_auth_check (GstRTSPAuth * auth, GstRTSPClient * client, - GQuark hint, GstRTSPClientState * state) + GstRTSPAuthCheck check, GstRTSPClientState * state) { gboolean result = FALSE; GstRTSPAuthClass *klass; @@ -344,7 +357,7 @@ gst_rtsp_auth_check (GstRTSPAuth * auth, GstRTSPClient * client, GST_DEBUG_OBJECT (auth, "check auth"); if (klass->check) - result = klass->check (auth, client, hint, state); + result = klass->check (auth, client, check, state); return result; } diff --git a/gst/rtsp-server/rtsp-auth.h b/gst/rtsp-server/rtsp-auth.h index 4da1dbf..55c5faf 100644 --- a/gst/rtsp-server/rtsp-auth.h +++ b/gst/rtsp-server/rtsp-auth.h @@ -41,6 +41,18 @@ G_BEGIN_DECLS #define GST_RTSP_AUTH_CLASS_CAST(klass) ((GstRTSPAuthClass*)(klass)) /** + * GstRTSPAuthCheck: + * @GST_RTSP_AUTH_CHECK_URL: Check url and method + * @GST_RTSP_AUTH_CHECK_FACTORY: Check access to factory + * + * Different authorization checks + */ +typedef enum { + GST_RTSP_AUTH_CHECK_URL, + GST_RTSP_AUTH_CHECK_FACTORY, +} GstRTSPAuthCheck; + +/** * GstRTSPAuth: * * The authentication structure. @@ -75,7 +87,7 @@ struct _GstRTSPAuthClass { gboolean (*authenticate) (GstRTSPAuth *auth, GstRTSPClient * client, GstRTSPClientState *state); gboolean (*check) (GstRTSPAuth *auth, GstRTSPClient * client, - GQuark hint, GstRTSPClientState *state); + GstRTSPAuthCheck check, GstRTSPClientState *state); }; GType gst_rtsp_auth_get_type (void); @@ -90,7 +102,7 @@ gboolean gst_rtsp_auth_setup (GstRTSPAuth *auth, GstRTSPC GstRTSPClientState *state); gboolean gst_rtsp_auth_check (GstRTSPAuth *auth, GstRTSPClient * client, - GQuark hint, GstRTSPClientState *state); + GstRTSPAuthCheck check, GstRTSPClientState *state); /* helpers */ gchar * gst_rtsp_auth_make_basic (const gchar * user, const gchar * pass); diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c index 47956e5..542c44d 100644 --- a/gst/rtsp-server/rtsp-client.c +++ b/gst/rtsp-server/rtsp-client.c @@ -500,6 +500,12 @@ find_media (GstRTSPClient * client, GstRTSPClientState * state, gint * matched) path, matched))) goto no_factory; + state->factory = factory; + + if (!gst_rtsp_auth_check (priv->auth, client, GST_RTSP_AUTH_CHECK_FACTORY, + state)) + goto not_authorized; + if (matched) path_len = *matched; else @@ -537,6 +543,7 @@ find_media (GstRTSPClient * client, GstRTSPClientState * state, gint * matched) } g_object_unref (factory); + state->factory = NULL; if (media) g_object_ref (media); @@ -556,11 +563,18 @@ no_factory: send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state); return NULL; } +not_authorized: + { + GST_ERROR ("client %p: not authorized for factory %p", client, factory); + handle_unauthorized_request (client, priv->auth, state); + return NULL; + } no_media: { GST_ERROR ("client %p: can't create media", client); send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state); g_object_unref (factory); + state->factory = NULL; return NULL; } no_prepare: @@ -568,7 +582,9 @@ no_prepare: GST_ERROR ("client %p: can't prepare media", client); send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state); g_object_unref (media); + state->media = media; g_object_unref (factory); + state->factory = NULL; return NULL; } } @@ -1824,7 +1840,8 @@ handle_request (GstRTSPClient * client, GstRTSPMessage * request) state.session = session; if (priv->auth) { - if (!gst_rtsp_auth_check (priv->auth, client, 0, &state)) + if (!gst_rtsp_auth_check (priv->auth, client, GST_RTSP_AUTH_CHECK_URL, + &state)) goto not_authorized; state.auth = priv->auth; -- 2.7.4