auth: add auth checks

Add an enum with auth checks and implement the checks in the auth object.
Perform the checks from the client.
This commit is contained in:
Wim Taymans 2013-07-08 16:29:01 +02:00
parent fb7c9b8122
commit a63f4a2a4c
4 changed files with 64 additions and 17 deletions

View 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);

View 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;
}

View file

@ -40,6 +40,18 @@ G_BEGIN_DECLS
#define GST_RTSP_AUTH_CAST(obj) ((GstRTSPAuth*)(obj))
#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:
*
@ -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);

View 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;