auth: add support for multiple basic auth tokens
authorWim Taymans <wim.taymans@collabora.co.uk>
Thu, 4 Jul 2013 12:33:59 +0000 (14:33 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Thu, 4 Jul 2013 12:33:59 +0000 (14:33 +0200)
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
gst/rtsp-server/rtsp-auth.c
gst/rtsp-server/rtsp-auth.h
gst/rtsp-server/rtsp-client.h

index a810b4d..ee8af57 100644 (file)
@@ -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;
index faaf0f7..6ed627f 100644 (file)
@@ -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");
index 6fd1a2f..425413b 100644 (file)
@@ -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);
index 741fed2..b5adc10 100644 (file)
@@ -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;