auth: use the token after authentication
authorWim Taymans <wim.taymans@collabora.co.uk>
Fri, 5 Jul 2013 18:48:18 +0000 (20:48 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 8 Jul 2013 09:10:20 +0000 (11:10 +0200)
After we authenticated a user, keep the Token around in the state.

examples/test-auth.c
gst/rtsp-server/rtsp-auth.c
gst/rtsp-server/rtsp-auth.h
gst/rtsp-server/rtsp-client.h

index f5a129c..15843d1 100644 (file)
@@ -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);
index a0df870..6f115ff 100644 (file)
@@ -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:
index fd9b679..4da1dbf 100644 (file)
@@ -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,
index 86ae980..d772b38 100644 (file)
@@ -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;