From fb7c9b812271c1d7d857c093fcb99ace38c6b0f4 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 5 Jul 2013 20:48:18 +0200 Subject: [PATCH] auth: use the token after authentication After we authenticated a user, keep the Token around in the state. --- examples/test-auth.c | 27 ++++++++++++++++++++++++--- gst/rtsp-server/rtsp-auth.c | 40 +++++++++++++++++++++------------------- gst/rtsp-server/rtsp-auth.h | 31 ++++++++++++++++++++++++------- gst/rtsp-server/rtsp-client.h | 6 ++++-- 4 files changed, 73 insertions(+), 31 deletions(-) diff --git a/examples/test-auth.c b/examples/test-auth.c index f5a129c..15843d1 100644 --- a/examples/test-auth.c +++ b/examples/test-auth.c @@ -62,7 +62,9 @@ main (int argc, char *argv[]) GstRTSPMountPoints *mounts; GstRTSPMediaFactory *factory; GstRTSPAuth *auth; + GstRTSPToken *token; gchar *basic; + GstStructure *s; gst_init (&argc, &argv); @@ -103,15 +105,34 @@ main (int argc, char *argv[]) /* make a new authentication manager */ auth = gst_rtsp_auth_new (); + + /* 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); basic = gst_rtsp_auth_make_basic ("user", "password"); - gst_rtsp_auth_add_basic (auth, basic, "user"); + gst_rtsp_auth_add_basic (auth, basic, token); g_free (basic); + gst_rtsp_token_unref (token); + + /* 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); basic = gst_rtsp_auth_make_basic ("admin", "power"); - gst_rtsp_auth_add_basic (auth, basic, "admin"); + gst_rtsp_auth_add_basic (auth, basic, token); g_free (basic); + gst_rtsp_token_unref (token); + + /* 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); basic = gst_rtsp_auth_make_basic ("admin2", "power2"); - gst_rtsp_auth_add_basic (auth, basic, "admin"); + gst_rtsp_auth_add_basic (auth, basic, token); g_free (basic); + gst_rtsp_token_unref (token); + /* set as the server authentication manager */ gst_rtsp_server_set_auth (server, auth); g_object_unref (auth); diff --git a/gst/rtsp-server/rtsp-auth.c b/gst/rtsp-server/rtsp-auth.c index a0df870..6f115ff 100644 --- a/gst/rtsp-server/rtsp-auth.c +++ b/gst/rtsp-server/rtsp-auth.c @@ -48,7 +48,7 @@ static void gst_rtsp_auth_finalize (GObject * obj); static gboolean default_setup (GstRTSPAuth * auth, GstRTSPClient * client, GstRTSPClientState * state); -static gboolean default_validate (GstRTSPAuth * auth, +static gboolean default_authenticate (GstRTSPAuth * auth, GstRTSPClient * client, GstRTSPClientState * state); static gboolean default_check (GstRTSPAuth * auth, GstRTSPClient * client, GQuark hint, GstRTSPClientState * state); @@ -69,7 +69,7 @@ gst_rtsp_auth_class_init (GstRTSPAuthClass * klass) gobject_class->finalize = gst_rtsp_auth_finalize; klass->setup = default_setup; - klass->validate = default_validate; + klass->authenticate = default_authenticate; klass->check = default_check; GST_DEBUG_CATEGORY_INIT (rtsp_auth_debug, "rtspauth", 0, "GstRTSPAuth"); @@ -84,7 +84,8 @@ gst_rtsp_auth_init (GstRTSPAuth * auth) g_mutex_init (&priv->lock); - priv->basic = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + priv->basic = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, + (GDestroyNotify) gst_rtsp_token_unref); /* bitwise or of all methods that need authentication */ priv->methods = GST_RTSP_DESCRIBE | @@ -156,18 +157,19 @@ gst_rtsp_auth_new (void) */ void gst_rtsp_auth_add_basic (GstRTSPAuth * auth, const gchar * basic, - const gchar * authgroup) + GstRTSPToken * token) { GstRTSPAuthPrivate *priv; g_return_if_fail (GST_IS_RTSP_AUTH (auth)); g_return_if_fail (basic != NULL); - g_return_if_fail (authgroup != NULL); + g_return_if_fail (GST_IS_RTSP_TOKEN (token)); priv = auth->priv; g_mutex_lock (&priv->lock); - g_hash_table_replace (priv->basic, g_strdup (basic), g_strdup (authgroup)); + g_hash_table_replace (priv->basic, g_strdup (basic), + gst_rtsp_token_ref (token)); g_mutex_unlock (&priv->lock); } @@ -240,14 +242,14 @@ gst_rtsp_auth_setup (GstRTSPAuth * auth, GstRTSPClient * client, } static gboolean -default_validate (GstRTSPAuth * auth, GstRTSPClient * client, +default_authenticate (GstRTSPAuth * auth, GstRTSPClient * client, GstRTSPClientState * state) { GstRTSPAuthPrivate *priv = auth->priv; GstRTSPResult res; gchar *authorization; - GST_DEBUG_OBJECT (auth, "validate"); + GST_DEBUG_OBJECT (auth, "authenticate"); res = gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_AUTHORIZATION, @@ -257,13 +259,13 @@ default_validate (GstRTSPAuth * auth, GstRTSPClient * client, /* parse type */ if (g_ascii_strncasecmp (authorization, "basic ", 6) == 0) { - gchar *authgroup; + GstRTSPToken *token; GST_DEBUG_OBJECT (auth, "check Basic auth"); g_mutex_lock (&priv->lock); - if ((authgroup = g_hash_table_lookup (priv->basic, &authorization[6]))) { - GST_DEBUG_OBJECT (auth, "setting authgroup %s", authgroup); - state->authgroup = authgroup; + if ((token = g_hash_table_lookup (priv->basic, &authorization[6]))) { + GST_DEBUG_OBJECT (auth, "setting token %p", token); + state->token = token; } g_mutex_unlock (&priv->lock); } else if (g_ascii_strncasecmp (authorization, "digest ", 7) == 0) { @@ -290,21 +292,21 @@ default_check (GstRTSPAuth * auth, GstRTSPClient * client, if ((state->method & priv->methods) != 0) { /* we need an authgroup to check */ - if (state->authgroup == NULL) { - if (klass->validate) { - if (!klass->validate (auth, client, state)) - goto validate_failed; + if (state->token == NULL) { + if (klass->authenticate) { + if (!klass->authenticate (auth, client, state)) + goto authenticate_failed; } } - if (state->authgroup == NULL) + if (state->token == NULL) goto no_auth; } return TRUE; -validate_failed: +authenticate_failed: { - GST_DEBUG_OBJECT (auth, "validation failed"); + GST_DEBUG_OBJECT (auth, "check failed"); return FALSE; } no_auth: diff --git a/gst/rtsp-server/rtsp-auth.h b/gst/rtsp-server/rtsp-auth.h index fd9b679..4da1dbf 100644 --- a/gst/rtsp-server/rtsp-auth.h +++ b/gst/rtsp-server/rtsp-auth.h @@ -27,6 +27,7 @@ typedef struct _GstRTSPAuthClass GstRTSPAuthClass; typedef struct _GstRTSPAuthPrivate GstRTSPAuthPrivate; #include "rtsp-client.h" +#include "rtsp-token.h" G_BEGIN_DECLS @@ -50,15 +51,31 @@ struct _GstRTSPAuth { GstRTSPAuthPrivate *priv; }; +/** + * GstRTSPAuthClass: + * @setup: called when an unauthorized resource has been accessed and + * authentication needs to be requested to the client. The default + * implementation adds basic authentication to the response. + * @authenticate: check the authentication of a client. The default implementation + * checks if the authentication in the header matches one of the basic + * authentication tokens. This function should set the authgroup field + * in the state. + * @check: check if a resource can be accessed. this function should + * call validate to authenticate the client when needed. The default + * implementation disallows unauthenticated access to all methods + * except OPTIONS. + * + * The authentication class. + */ struct _GstRTSPAuthClass { GObjectClass parent_class; - gboolean (*setup) (GstRTSPAuth *auth, GstRTSPClient * client, - GstRTSPClientState *state); - gboolean (*validate) (GstRTSPAuth *auth, GstRTSPClient * client, - GstRTSPClientState *state); - gboolean (*check) (GstRTSPAuth *auth, GstRTSPClient * client, - GQuark hint, GstRTSPClientState *state); + gboolean (*setup) (GstRTSPAuth *auth, GstRTSPClient * client, + GstRTSPClientState *state); + gboolean (*authenticate) (GstRTSPAuth *auth, GstRTSPClient * client, + GstRTSPClientState *state); + gboolean (*check) (GstRTSPAuth *auth, GstRTSPClient * client, + GQuark hint, GstRTSPClientState *state); }; GType gst_rtsp_auth_get_type (void); @@ -66,7 +83,7 @@ GType gst_rtsp_auth_get_type (void); GstRTSPAuth * gst_rtsp_auth_new (void); void gst_rtsp_auth_add_basic (GstRTSPAuth *auth, const gchar * basic, - const gchar *authgroup); + GstRTSPToken *token); void gst_rtsp_auth_remove_basic (GstRTSPAuth *auth, const gchar * basic); gboolean gst_rtsp_auth_setup (GstRTSPAuth *auth, GstRTSPClient * client, diff --git a/gst/rtsp-server/rtsp-client.h b/gst/rtsp-server/rtsp-client.h index 86ae980..d772b38 100644 --- a/gst/rtsp-server/rtsp-client.h +++ b/gst/rtsp-server/rtsp-client.h @@ -35,6 +35,7 @@ typedef struct _GstRTSPClientPrivate GstRTSPClientPrivate; #include "rtsp-session-pool.h" #include "rtsp-session-media.h" #include "rtsp-auth.h" +#include "rtsp-token.h" #include "rtsp-sdp.h" #define GST_TYPE_RTSP_CLIENT (gst_rtsp_client_get_type ()) @@ -51,7 +52,8 @@ typedef struct _GstRTSPClientPrivate GstRTSPClientPrivate; * @request: the complete request * @uri: the complete url parsed from @request * @method: the parsed method of @uri - * @authgroup: authorisation group + * @auth: the current auth object or NULL + * @token: authorisation token * @session: the session, can be NULL * @sessmedia: the session media for the url can be NULL * @factory: the media factory for the url, can be NULL. @@ -66,7 +68,7 @@ struct _GstRTSPClientState { GstRTSPUrl *uri; GstRTSPMethod method; GstRTSPAuth *auth; - const gchar *authgroup; + GstRTSPToken *token; GstRTSPSession *session; GstRTSPSessionMedia *sessmedia; GstRTSPMediaFactory *factory; -- 2.7.4