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;