mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-09-01 01:33:52 +00:00
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:
parent
fb7c9b8122
commit
a63f4a2a4c
4 changed files with 64 additions and 17 deletions
|
@ -65,6 +65,8 @@ main (int argc, char *argv[])
|
||||||
GstRTSPToken *token;
|
GstRTSPToken *token;
|
||||||
gchar *basic;
|
gchar *basic;
|
||||||
GstStructure *s;
|
GstStructure *s;
|
||||||
|
gchar *role_user[] = { "user", NULL };
|
||||||
|
gchar *role_admin[] = { "admin", NULL };
|
||||||
|
|
||||||
gst_init (&argc, &argv);
|
gst_init (&argc, &argv);
|
||||||
|
|
||||||
|
@ -109,7 +111,8 @@ main (int argc, char *argv[])
|
||||||
/* make user token */
|
/* make user token */
|
||||||
token = gst_rtsp_token_new ();
|
token = gst_rtsp_token_new ();
|
||||||
s = gst_rtsp_token_writable_structure (token);
|
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");
|
basic = gst_rtsp_auth_make_basic ("user", "password");
|
||||||
gst_rtsp_auth_add_basic (auth, basic, token);
|
gst_rtsp_auth_add_basic (auth, basic, token);
|
||||||
g_free (basic);
|
g_free (basic);
|
||||||
|
@ -118,7 +121,8 @@ main (int argc, char *argv[])
|
||||||
/* make admin token */
|
/* make admin token */
|
||||||
token = gst_rtsp_token_new ();
|
token = gst_rtsp_token_new ();
|
||||||
s = gst_rtsp_token_writable_structure (token);
|
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");
|
basic = gst_rtsp_auth_make_basic ("admin", "power");
|
||||||
gst_rtsp_auth_add_basic (auth, basic, token);
|
gst_rtsp_auth_add_basic (auth, basic, token);
|
||||||
g_free (basic);
|
g_free (basic);
|
||||||
|
@ -127,7 +131,8 @@ main (int argc, char *argv[])
|
||||||
/* make admin2 token */
|
/* make admin2 token */
|
||||||
token = gst_rtsp_token_new ();
|
token = gst_rtsp_token_new ();
|
||||||
s = gst_rtsp_token_writable_structure (token);
|
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");
|
basic = gst_rtsp_auth_make_basic ("admin2", "power2");
|
||||||
gst_rtsp_auth_add_basic (auth, basic, token);
|
gst_rtsp_auth_add_basic (auth, basic, token);
|
||||||
g_free (basic);
|
g_free (basic);
|
||||||
|
|
|
@ -283,35 +283,48 @@ no_auth:
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
default_check (GstRTSPAuth * auth, GstRTSPClient * client,
|
default_check (GstRTSPAuth * auth, GstRTSPClient * client,
|
||||||
GQuark hint, GstRTSPClientState * state)
|
GstRTSPAuthCheck check, GstRTSPClientState * state)
|
||||||
{
|
{
|
||||||
GstRTSPAuthPrivate *priv = auth->priv;
|
GstRTSPAuthPrivate *priv = auth->priv;
|
||||||
GstRTSPAuthClass *klass;
|
GstRTSPAuthClass *klass;
|
||||||
|
gboolean need_authorized = FALSE;
|
||||||
|
gboolean res = FALSE;
|
||||||
|
|
||||||
klass = GST_RTSP_AUTH_GET_CLASS (auth);
|
klass = GST_RTSP_AUTH_GET_CLASS (auth);
|
||||||
|
|
||||||
if ((state->method & priv->methods) != 0) {
|
switch (check) {
|
||||||
/* we need an authgroup to 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 (state->token == NULL) {
|
||||||
if (klass->authenticate) {
|
if (klass->authenticate) {
|
||||||
if (!klass->authenticate (auth, client, state))
|
if (!klass->authenticate (auth, client, state))
|
||||||
goto authenticate_failed;
|
goto authenticate_failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->token == NULL)
|
if (state->token == NULL)
|
||||||
goto no_auth;
|
goto no_auth;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return res;
|
||||||
|
|
||||||
authenticate_failed:
|
authenticate_failed:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (auth, "check failed");
|
GST_DEBUG_OBJECT (auth, "authenticate failed");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
no_auth:
|
no_auth:
|
||||||
{
|
{
|
||||||
GST_DEBUG_OBJECT (auth, "no authorization group found");
|
GST_DEBUG_OBJECT (auth, "no authorization token found");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,17 +333,17 @@ no_auth:
|
||||||
* gst_rtsp_auth_check:
|
* gst_rtsp_auth_check:
|
||||||
* @auth: a #GstRTSPAuth
|
* @auth: a #GstRTSPAuth
|
||||||
* @client: the client
|
* @client: the client
|
||||||
* @hint: a hint
|
* @check: the item to check
|
||||||
* @state: client state
|
* @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.
|
* current @state.
|
||||||
*
|
*
|
||||||
* Returns: FALSE if check failed.
|
* Returns: FALSE if check failed.
|
||||||
*/
|
*/
|
||||||
gboolean
|
gboolean
|
||||||
gst_rtsp_auth_check (GstRTSPAuth * auth, GstRTSPClient * client,
|
gst_rtsp_auth_check (GstRTSPAuth * auth, GstRTSPClient * client,
|
||||||
GQuark hint, GstRTSPClientState * state)
|
GstRTSPAuthCheck check, GstRTSPClientState * state)
|
||||||
{
|
{
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
GstRTSPAuthClass *klass;
|
GstRTSPAuthClass *klass;
|
||||||
|
@ -344,7 +357,7 @@ gst_rtsp_auth_check (GstRTSPAuth * auth, GstRTSPClient * client,
|
||||||
GST_DEBUG_OBJECT (auth, "check auth");
|
GST_DEBUG_OBJECT (auth, "check auth");
|
||||||
|
|
||||||
if (klass->check)
|
if (klass->check)
|
||||||
result = klass->check (auth, client, hint, state);
|
result = klass->check (auth, client, check, state);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,18 @@ G_BEGIN_DECLS
|
||||||
#define GST_RTSP_AUTH_CAST(obj) ((GstRTSPAuth*)(obj))
|
#define GST_RTSP_AUTH_CAST(obj) ((GstRTSPAuth*)(obj))
|
||||||
#define GST_RTSP_AUTH_CLASS_CAST(klass) ((GstRTSPAuthClass*)(klass))
|
#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:
|
* GstRTSPAuth:
|
||||||
*
|
*
|
||||||
|
@ -75,7 +87,7 @@ struct _GstRTSPAuthClass {
|
||||||
gboolean (*authenticate) (GstRTSPAuth *auth, GstRTSPClient * client,
|
gboolean (*authenticate) (GstRTSPAuth *auth, GstRTSPClient * client,
|
||||||
GstRTSPClientState *state);
|
GstRTSPClientState *state);
|
||||||
gboolean (*check) (GstRTSPAuth *auth, GstRTSPClient * client,
|
gboolean (*check) (GstRTSPAuth *auth, GstRTSPClient * client,
|
||||||
GQuark hint, GstRTSPClientState *state);
|
GstRTSPAuthCheck check, GstRTSPClientState *state);
|
||||||
};
|
};
|
||||||
|
|
||||||
GType gst_rtsp_auth_get_type (void);
|
GType gst_rtsp_auth_get_type (void);
|
||||||
|
@ -90,7 +102,7 @@ gboolean gst_rtsp_auth_setup (GstRTSPAuth *auth, GstRTSPC
|
||||||
GstRTSPClientState *state);
|
GstRTSPClientState *state);
|
||||||
|
|
||||||
gboolean gst_rtsp_auth_check (GstRTSPAuth *auth, GstRTSPClient * client,
|
gboolean gst_rtsp_auth_check (GstRTSPAuth *auth, GstRTSPClient * client,
|
||||||
GQuark hint, GstRTSPClientState *state);
|
GstRTSPAuthCheck check, GstRTSPClientState *state);
|
||||||
|
|
||||||
/* helpers */
|
/* helpers */
|
||||||
gchar * gst_rtsp_auth_make_basic (const gchar * user, const gchar * pass);
|
gchar * gst_rtsp_auth_make_basic (const gchar * user, const gchar * pass);
|
||||||
|
|
|
@ -500,6 +500,12 @@ find_media (GstRTSPClient * client, GstRTSPClientState * state, gint * matched)
|
||||||
path, matched)))
|
path, matched)))
|
||||||
goto no_factory;
|
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)
|
if (matched)
|
||||||
path_len = *matched;
|
path_len = *matched;
|
||||||
else
|
else
|
||||||
|
@ -537,6 +543,7 @@ find_media (GstRTSPClient * client, GstRTSPClientState * state, gint * matched)
|
||||||
}
|
}
|
||||||
|
|
||||||
g_object_unref (factory);
|
g_object_unref (factory);
|
||||||
|
state->factory = NULL;
|
||||||
|
|
||||||
if (media)
|
if (media)
|
||||||
g_object_ref (media);
|
g_object_ref (media);
|
||||||
|
@ -556,11 +563,18 @@ no_factory:
|
||||||
send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
|
send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
|
||||||
return NULL;
|
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:
|
no_media:
|
||||||
{
|
{
|
||||||
GST_ERROR ("client %p: can't create media", client);
|
GST_ERROR ("client %p: can't create media", client);
|
||||||
send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
|
send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
|
||||||
g_object_unref (factory);
|
g_object_unref (factory);
|
||||||
|
state->factory = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
no_prepare:
|
no_prepare:
|
||||||
|
@ -568,7 +582,9 @@ no_prepare:
|
||||||
GST_ERROR ("client %p: can't prepare media", client);
|
GST_ERROR ("client %p: can't prepare media", client);
|
||||||
send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
|
send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
|
||||||
g_object_unref (media);
|
g_object_unref (media);
|
||||||
|
state->media = media;
|
||||||
g_object_unref (factory);
|
g_object_unref (factory);
|
||||||
|
state->factory = NULL;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1824,7 +1840,8 @@ handle_request (GstRTSPClient * client, GstRTSPMessage * request)
|
||||||
state.session = session;
|
state.session = session;
|
||||||
|
|
||||||
if (priv->auth) {
|
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;
|
goto not_authorized;
|
||||||
|
|
||||||
state.auth = priv->auth;
|
state.auth = priv->auth;
|
||||||
|
|
Loading…
Reference in a new issue