From 78bc979690210662067a8adada5c17122f37f9c7 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 4 Jul 2013 14:33:59 +0200 Subject: [PATCH] auth: add support for multiple basic auth tokens Make it possible to add multiple basic authorisation tokens to one authorization object. Associate with each token an authorization group that will define what capabilities are allowed. --- examples/test-auth.c | 16 ++++++---- gst/rtsp-server/rtsp-auth.c | 58 ++++++++++++++++++++++++++++------- gst/rtsp-server/rtsp-auth.h | 4 ++- gst/rtsp-server/rtsp-client.h | 2 ++ 4 files changed, 62 insertions(+), 18 deletions(-) diff --git a/examples/test-auth.c b/examples/test-auth.c index a810b4df7a..ee8af5728f 100644 --- a/examples/test-auth.c +++ b/examples/test-auth.c @@ -89,8 +89,11 @@ main (int argc, char *argv[]) /* make a new authentication manager */ auth = gst_rtsp_auth_new (); - basic = gst_rtsp_auth_make_basic ("user", "admin"); - gst_rtsp_auth_set_basic (auth, basic); + basic = gst_rtsp_auth_make_basic ("user", "password"); + gst_rtsp_auth_add_basic (auth, basic, "user"); + g_free (basic); + basic = gst_rtsp_auth_make_basic ("admin", "power"); + gst_rtsp_auth_add_basic (auth, basic, "admin"); g_free (basic); gst_rtsp_media_factory_set_auth (factory, auth); g_object_unref (auth); @@ -104,8 +107,8 @@ main (int argc, char *argv[]) "x264enc ! rtph264pay name=pay0 pt=96 )"); /* make a new authentication manager */ auth = gst_rtsp_auth_new (); - basic = gst_rtsp_auth_make_basic ("user2", "admin2"); - gst_rtsp_auth_set_basic (auth, basic); + basic = gst_rtsp_auth_make_basic ("admin2", "power2"); + gst_rtsp_auth_add_basic (auth, basic, "admin"); g_free (basic); gst_rtsp_media_factory_set_auth (factory, auth); g_object_unref (auth); @@ -123,8 +126,9 @@ main (int argc, char *argv[]) g_timeout_add_seconds (10, (GSourceFunc) remove_sessions, server); /* start serving */ - g_print ("stream with user:admin ready at rtsp://127.0.0.1:8554/test\n"); - g_print ("stream with user2:admin2 ready at rtsp://127.0.0.1:8554/test2\n"); + g_print ("stream with user:password ready at rtsp://127.0.0.1:8554/test\n"); + g_print ("stream with admin:power ready at rtsp://127.0.0.1:8554/test\n"); + g_print ("stream with admin2:power2 ready at rtsp://127.0.0.1:8554/test2\n"); g_main_loop_run (loop); return 0; diff --git a/gst/rtsp-server/rtsp-auth.c b/gst/rtsp-server/rtsp-auth.c index faaf0f7e52..6ed627fd68 100644 --- a/gst/rtsp-server/rtsp-auth.c +++ b/gst/rtsp-server/rtsp-auth.c @@ -27,7 +27,7 @@ struct _GstRTSPAuthPrivate { GMutex lock; - gchar *basic; /* protected by lock */ + GHashTable *basic; /* protected by lock */ GstRTSPMethod methods; }; @@ -75,11 +75,16 @@ gst_rtsp_auth_class_init (GstRTSPAuthClass * klass) static void gst_rtsp_auth_init (GstRTSPAuth * auth) { - auth->priv = GST_RTSP_AUTH_GET_PRIVATE (auth); + GstRTSPAuthPrivate *priv; + + auth->priv = priv = GST_RTSP_AUTH_GET_PRIVATE (auth); + + g_mutex_init (&priv->lock); + + priv->basic = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); - g_mutex_init (&auth->priv->lock); /* bitwise or of all methods that need authentication */ - auth->priv->methods = GST_RTSP_DESCRIBE | + priv->methods = GST_RTSP_DESCRIBE | GST_RTSP_ANNOUNCE | GST_RTSP_GET_PARAMETER | GST_RTSP_SET_PARAMETER | @@ -94,7 +99,7 @@ gst_rtsp_auth_finalize (GObject * obj) GstRTSPAuthPrivate *priv = auth->priv; GST_INFO ("finalize auth %p", auth); - g_free (priv->basic); + g_hash_table_unref (priv->basic); g_mutex_clear (&priv->lock); G_OBJECT_CLASS (gst_rtsp_auth_parent_class)->finalize (obj); @@ -138,24 +143,51 @@ gst_rtsp_auth_new (void) } /** - * gst_rtsp_auth_set_basic: + * gst_rtsp_auth_add_basic: * @auth: a #GstRTSPAuth * @basic: the basic token + * @authgroup: authorisation group * - * Set the basic token for the default authentication algorithm. + * Add a basic token for the default authentication algorithm that + * enables the client qith privileges from @authgroup. */ void -gst_rtsp_auth_set_basic (GstRTSPAuth * auth, const gchar * basic) +gst_rtsp_auth_add_basic (GstRTSPAuth * auth, const gchar * basic, + const gchar * authgroup) { GstRTSPAuthPrivate *priv; g_return_if_fail (GST_IS_RTSP_AUTH (auth)); + g_return_if_fail (basic != NULL); + g_return_if_fail (authgroup != NULL); priv = auth->priv; g_mutex_lock (&priv->lock); - g_free (priv->basic); - priv->basic = g_strdup (basic); + g_hash_table_replace (priv->basic, g_strdup (basic), g_strdup (authgroup)); + g_mutex_unlock (&priv->lock); +} + +/** + * gst_rtsp_auth_remove_basic: + * @auth: a #GstRTSPAuth + * @basic: (transfer none): the basic token + * + * Add a basic token for the default authentication algorithm that + * enables the client qith privileges from @authgroup. + */ +void +gst_rtsp_auth_remove_basic (GstRTSPAuth * auth, const gchar * basic) +{ + GstRTSPAuthPrivate *priv; + + g_return_if_fail (GST_IS_RTSP_AUTH (auth)); + g_return_if_fail (basic != NULL); + + priv = auth->priv; + + g_mutex_lock (&priv->lock); + g_hash_table_remove (priv->basic, basic); g_mutex_unlock (&priv->lock); } @@ -226,10 +258,14 @@ default_check_method (GstRTSPAuth * auth, GstRTSPClient * client, /* parse type */ if (g_ascii_strncasecmp (authorization, "basic ", 6) == 0) { + gchar *authgroup; + GST_DEBUG_OBJECT (auth, "check Basic auth"); g_mutex_lock (&priv->lock); - if (priv->basic && strcmp (&authorization[6], priv->basic) == 0) + if ((authgroup = g_hash_table_lookup (priv->basic, &authorization[6]))) { result = TRUE; + state->authgroup = authgroup; + } g_mutex_unlock (&priv->lock); } else if (g_ascii_strncasecmp (authorization, "digest ", 7) == 0) { GST_DEBUG_OBJECT (auth, "check Digest auth"); diff --git a/gst/rtsp-server/rtsp-auth.h b/gst/rtsp-server/rtsp-auth.h index 6fd1a2f5f9..425413b3c3 100644 --- a/gst/rtsp-server/rtsp-auth.h +++ b/gst/rtsp-server/rtsp-auth.h @@ -63,7 +63,9 @@ GType gst_rtsp_auth_get_type (void); GstRTSPAuth * gst_rtsp_auth_new (void); -void gst_rtsp_auth_set_basic (GstRTSPAuth *auth, const gchar * basic); +void gst_rtsp_auth_add_basic (GstRTSPAuth *auth, const gchar * basic, + const gchar *authgroup); +void gst_rtsp_auth_remove_basic (GstRTSPAuth *auth, const gchar * basic); gboolean gst_rtsp_auth_setup_auth (GstRTSPAuth *auth, GstRTSPClient * client, GQuark hint, GstRTSPClientState *state); diff --git a/gst/rtsp-server/rtsp-client.h b/gst/rtsp-server/rtsp-client.h index 741fed24e6..b5adc104f3 100644 --- a/gst/rtsp-server/rtsp-client.h +++ b/gst/rtsp-server/rtsp-client.h @@ -51,6 +51,7 @@ typedef struct _GstRTSPClientPrivate GstRTSPClientPrivate; * @request: the complete request * @uri: the complete url parsed from @request * @method: the parsed method of @uri + * @authgroup: authorisation group * @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. @@ -64,6 +65,7 @@ struct _GstRTSPClientState { GstRTSPMessage *request; GstRTSPUrl *uri; GstRTSPMethod method; + const gchar *authgroup; GstRTSPSession *session; GstRTSPSessionMedia *sessmedia; GstRTSPMediaFactory *factory;