mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 14:56:36 +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;
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue