auth: add auth checks
authorWim Taymans <wim.taymans@collabora.co.uk>
Mon, 8 Jul 2013 14:29:01 +0000 (16:29 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 8 Jul 2013 14:29:01 +0000 (16:29 +0200)
Add an enum with auth checks and implement the checks in the auth object.
Perform the checks from the client.

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

index 15843d1..75455de 100644 (file)
@@ -65,6 +65,8 @@ main (int argc, char *argv[])
   GstRTSPToken *token;
   gchar *basic;
   GstStructure *s;
+  gchar *role_user[] = { "user", NULL };
+  gchar *role_admin[] = { "admin", NULL };
 
   gst_init (&argc, &argv);
 
@@ -109,7 +111,8 @@ main (int argc, char *argv[])
   /* 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);
+  gst_structure_set (s, "manager.role", G_TYPE_STRING, "user", NULL);
+  gst_structure_set (s, "factory.media.roles", G_TYPE_STRV, role_user, NULL);
   basic = gst_rtsp_auth_make_basic ("user", "password");
   gst_rtsp_auth_add_basic (auth, basic, token);
   g_free (basic);
@@ -118,7 +121,8 @@ main (int argc, char *argv[])
   /* 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);
+  gst_structure_set (s, "manager.role", G_TYPE_STRING, "admin", NULL);
+  gst_structure_set (s, "factory.media.roles", G_TYPE_STRV, role_admin, NULL);
   basic = gst_rtsp_auth_make_basic ("admin", "power");
   gst_rtsp_auth_add_basic (auth, basic, token);
   g_free (basic);
@@ -127,7 +131,8 @@ main (int argc, char *argv[])
   /* 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);
+  gst_structure_set (s, "manager.role", G_TYPE_STRING, "admin", NULL);
+  gst_structure_set (s, "factory.media.roles", G_TYPE_STRV, role_admin, NULL);
   basic = gst_rtsp_auth_make_basic ("admin2", "power2");
   gst_rtsp_auth_add_basic (auth, basic, token);
   g_free (basic);
index 6f115ff..ac3fb3e 100644 (file)
@@ -283,35 +283,48 @@ no_auth:
 
 static gboolean
 default_check (GstRTSPAuth * auth, GstRTSPClient * client,
-    GQuark hint, GstRTSPClientState * state)
+    GstRTSPAuthCheck check, GstRTSPClientState * state)
 {
   GstRTSPAuthPrivate *priv = auth->priv;
   GstRTSPAuthClass *klass;
+  gboolean need_authorized = FALSE;
+  gboolean res = FALSE;
 
   klass = GST_RTSP_AUTH_GET_CLASS (auth);
 
-  if ((state->method & priv->methods) != 0) {
-    /* we need an authgroup to check */
+  switch (check) {
+    case GST_RTSP_AUTH_CHECK_URL:
+      if ((state->method & priv->methods) != 0)
+        need_authorized = TRUE;
+      else
+        res = TRUE;
+      break;
+    case GST_RTSP_AUTH_CHECK_FACTORY:
+      res = TRUE;
+      break;
+  }
+
+  if (need_authorized) {
+    /* we need a token to check */
     if (state->token == NULL) {
       if (klass->authenticate) {
         if (!klass->authenticate (auth, client, state))
           goto authenticate_failed;
       }
     }
-
     if (state->token == NULL)
       goto no_auth;
   }
-  return TRUE;
+  return res;
 
 authenticate_failed:
   {
-    GST_DEBUG_OBJECT (auth, "check failed");
+    GST_DEBUG_OBJECT (auth, "authenticate failed");
     return FALSE;
   }
 no_auth:
   {
-    GST_DEBUG_OBJECT (auth, "no authorization group found");
+    GST_DEBUG_OBJECT (auth, "no authorization token found");
     return FALSE;
   }
 }
@@ -320,17 +333,17 @@ no_auth:
  * gst_rtsp_auth_check:
  * @auth: a #GstRTSPAuth
  * @client: the client
- * @hint: a hint
+ * @check: the item to check
  * @state: client state
  *
- * Check if @client with state is authorized to perform @hint in the
+ * Check if @client with state is authorized to perform @check in the
  * current @state.
  *
  * Returns: FALSE if check failed.
  */
 gboolean
 gst_rtsp_auth_check (GstRTSPAuth * auth, GstRTSPClient * client,
-    GQuark hint, GstRTSPClientState * state)
+    GstRTSPAuthCheck check, GstRTSPClientState * state)
 {
   gboolean result = FALSE;
   GstRTSPAuthClass *klass;
@@ -344,7 +357,7 @@ gst_rtsp_auth_check (GstRTSPAuth * auth, GstRTSPClient * client,
   GST_DEBUG_OBJECT (auth, "check auth");
 
   if (klass->check)
-    result = klass->check (auth, client, hint, state);
+    result = klass->check (auth, client, check, state);
 
   return result;
 }
index 4da1dbf..55c5faf 100644 (file)
@@ -41,6 +41,18 @@ G_BEGIN_DECLS
 #define GST_RTSP_AUTH_CLASS_CAST(klass) ((GstRTSPAuthClass*)(klass))
 
 /**
+ * GstRTSPAuthCheck:
+ * @GST_RTSP_AUTH_CHECK_URL: Check url and method
+ * @GST_RTSP_AUTH_CHECK_FACTORY: Check access to factory
+ *
+ * Different authorization checks
+ */
+typedef enum {
+  GST_RTSP_AUTH_CHECK_URL,
+  GST_RTSP_AUTH_CHECK_FACTORY,
+} GstRTSPAuthCheck;
+
+/**
  * GstRTSPAuth:
  *
  * The authentication structure.
@@ -75,7 +87,7 @@ struct _GstRTSPAuthClass {
   gboolean           (*authenticate) (GstRTSPAuth *auth, GstRTSPClient * client,
                                       GstRTSPClientState *state);
   gboolean           (*check)        (GstRTSPAuth *auth, GstRTSPClient * client,
-                                      GQuark hint, GstRTSPClientState *state);
+                                      GstRTSPAuthCheck check, GstRTSPClientState *state);
 };
 
 GType               gst_rtsp_auth_get_type          (void);
@@ -90,7 +102,7 @@ gboolean            gst_rtsp_auth_setup             (GstRTSPAuth *auth, GstRTSPC
                                                      GstRTSPClientState *state);
 
 gboolean            gst_rtsp_auth_check             (GstRTSPAuth *auth, GstRTSPClient * client,
-                                                     GQuark hint, GstRTSPClientState *state);
+                                                     GstRTSPAuthCheck check, GstRTSPClientState *state);
 
 /* helpers */
 gchar *             gst_rtsp_auth_make_basic        (const gchar * user, const gchar * pass);
index 47956e5..542c44d 100644 (file)
@@ -500,6 +500,12 @@ find_media (GstRTSPClient * client, GstRTSPClientState * state, gint * matched)
               path, matched)))
     goto no_factory;
 
+  state->factory = factory;
+
+  if (!gst_rtsp_auth_check (priv->auth, client, GST_RTSP_AUTH_CHECK_FACTORY,
+          state))
+    goto not_authorized;
+
   if (matched)
     path_len = *matched;
   else
@@ -537,6 +543,7 @@ find_media (GstRTSPClient * client, GstRTSPClientState * state, gint * matched)
   }
 
   g_object_unref (factory);
+  state->factory = NULL;
 
   if (media)
     g_object_ref (media);
@@ -556,11 +563,18 @@ no_factory:
     send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
     return NULL;
   }
+not_authorized:
+  {
+    GST_ERROR ("client %p: not authorized for factory %p", client, factory);
+    handle_unauthorized_request (client, priv->auth, state);
+    return NULL;
+  }
 no_media:
   {
     GST_ERROR ("client %p: can't create media", client);
     send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
     g_object_unref (factory);
+    state->factory = NULL;
     return NULL;
   }
 no_prepare:
@@ -568,7 +582,9 @@ no_prepare:
     GST_ERROR ("client %p: can't prepare media", client);
     send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
     g_object_unref (media);
+    state->media = media;
     g_object_unref (factory);
+    state->factory = NULL;
     return NULL;
   }
 }
@@ -1824,7 +1840,8 @@ handle_request (GstRTSPClient * client, GstRTSPMessage * request)
   state.session = session;
 
   if (priv->auth) {
-    if (!gst_rtsp_auth_check (priv->auth, client, 0, &state))
+    if (!gst_rtsp_auth_check (priv->auth, client, GST_RTSP_AUTH_CHECK_URL,
+            &state))
       goto not_authorized;
 
     state.auth = priv->auth;