Add an enum with auth checks and implement the checks in the auth object.
Perform the checks from the client.
GstRTSPToken *token;
gchar *basic;
GstStructure *s;
+ gchar *role_user[] = { "user", NULL };
+ gchar *role_admin[] = { "admin", NULL };
gst_init (&argc, &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);
/* 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);
/* 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);
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;
}
}
* 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;
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;
}
#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.
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);
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);
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
}
g_object_unref (factory);
+ state->factory = NULL;
if (media)
g_object_ref (media);
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:
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;
}
}
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;