const GValue * value, GParamSpec * pspec);
static void gst_rtsp_auth_finalize (GObject * obj);
-static gboolean default_setup (GstRTSPAuth * auth, GstRTSPClient * client,
- GstRTSPClientState * state);
+static gboolean default_setup (GstRTSPAuth * auth, GstRTSPClientState * state);
static gboolean default_authenticate (GstRTSPAuth * auth,
- GstRTSPClient * client, GstRTSPClientState * state);
-static gboolean default_check (GstRTSPAuth * auth, GstRTSPClient * client,
- GQuark hint, GstRTSPClientState * state);
+ GstRTSPClientState * state);
+static gboolean default_check (GstRTSPAuth * auth, GstRTSPClientState * state,
+ const gchar * check);
G_DEFINE_TYPE (GstRTSPAuth, gst_rtsp_auth, G_TYPE_OBJECT);
}
static gboolean
-default_setup (GstRTSPAuth * auth, GstRTSPClient * client,
- GstRTSPClientState * state)
+default_setup (GstRTSPAuth * auth, GstRTSPClientState * state)
{
if (state->response == NULL)
return FALSE;
* Returns: FALSE if something is wrong.
*/
gboolean
-gst_rtsp_auth_setup (GstRTSPAuth * auth, GstRTSPClient * client,
- GstRTSPClientState * state)
+gst_rtsp_auth_setup (GstRTSPAuth * auth, GstRTSPClientState * state)
{
gboolean result = FALSE;
GstRTSPAuthClass *klass;
g_return_val_if_fail (GST_IS_RTSP_AUTH (auth), FALSE);
- g_return_val_if_fail (GST_IS_RTSP_CLIENT (client), FALSE);
g_return_val_if_fail (state != NULL, FALSE);
klass = GST_RTSP_AUTH_GET_CLASS (auth);
GST_DEBUG_OBJECT (auth, "setup auth");
if (klass->setup)
- result = klass->setup (auth, client, state);
+ result = klass->setup (auth, state);
return result;
}
static gboolean
-default_authenticate (GstRTSPAuth * auth, GstRTSPClient * client,
- GstRTSPClientState * state)
+default_authenticate (GstRTSPAuth * auth, GstRTSPClientState * state)
{
GstRTSPAuthPrivate *priv = auth->priv;
GstRTSPResult res;
}
static gboolean
-default_check (GstRTSPAuth * auth, GstRTSPClient * client,
- GstRTSPAuthCheck check, GstRTSPClientState * state)
+ensure_authenticated (GstRTSPAuth * auth, GstRTSPClientState * state)
{
- GstRTSPAuthPrivate *priv = auth->priv;
GstRTSPAuthClass *klass;
- gboolean need_authorized = FALSE;
- gboolean res = FALSE;
klass = GST_RTSP_AUTH_GET_CLASS (auth);
- 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;
- }
+ /* we need a token to check */
+ if (state->token == NULL) {
+ if (klass->authenticate) {
+ if (!klass->authenticate (auth, state))
+ goto authenticate_failed;
}
- if (state->token == NULL)
- goto no_auth;
}
- return res;
+ if (state->token == NULL)
+ goto no_auth;
+
+ return TRUE;
+/* ERRORS */
authenticate_failed:
{
GST_DEBUG_OBJECT (auth, "authenticate failed");
}
}
+static gboolean
+default_check (GstRTSPAuth * auth, GstRTSPClientState * state,
+ const gchar * check)
+{
+ GstRTSPAuthPrivate *priv = auth->priv;
+ gboolean res = FALSE;
+
+ if (g_str_equal (check, GST_RTSP_AUTH_CHECK_URL)) {
+ if ((state->method & priv->methods) != 0)
+ res = ensure_authenticated (auth, state);
+ else
+ res = TRUE;
+ } else if (g_str_has_prefix (check, "auth.check.media.factory.")) {
+ const gchar *role;
+ GstRTSPPermissions *perms;
+
+ if (!(role =
+ gst_rtsp_token_get_string (state->token,
+ GST_RTSP_MEDIA_FACTORY_ROLE)))
+ goto done;
+ if (!(perms = gst_rtsp_media_factory_get_permissions (state->factory)))
+ goto done;
+
+ if (g_str_equal (check, "auth.check.media.factory.access"))
+ res =
+ gst_rtsp_permissions_is_allowed (perms, role,
+ GST_RTSP_MEDIA_FACTORY_PERM_ACCESS);
+ else if (g_str_equal (check, "auth.check.media.factory.construct"))
+ res =
+ gst_rtsp_permissions_is_allowed (perms, role,
+ GST_RTSP_MEDIA_FACTORY_PERM_CONSTRUCT);
+ }
+done:
+ return res;
+}
+
/**
* gst_rtsp_auth_check:
- * @auth: a #GstRTSPAuth
- * @client: the client
* @check: the item to check
- * @state: client state
*
- * Check if @client with state is authorized to perform @check in the
- * current @state.
+ * Check if @check is allowed in the current context.
*
* Returns: FALSE if check failed.
*/
gboolean
-gst_rtsp_auth_check (GstRTSPAuth * auth, GstRTSPClient * client,
- GstRTSPAuthCheck check, GstRTSPClientState * state)
+gst_rtsp_auth_check (const gchar * check)
{
gboolean result = FALSE;
GstRTSPAuthClass *klass;
+ GstRTSPClientState *state;
+ GstRTSPAuth *auth;
- g_return_val_if_fail (GST_IS_RTSP_AUTH (auth), FALSE);
- g_return_val_if_fail (GST_IS_RTSP_CLIENT (client), FALSE);
- g_return_val_if_fail (state != NULL, FALSE);
+ g_return_val_if_fail (check != NULL, FALSE);
+
+ if (!(state = gst_rtsp_client_state_get_current ()))
+ goto no_state;
+
+ /* no auth, we don't need to check */
+ if (!(auth = state->auth))
+ return TRUE;
klass = GST_RTSP_AUTH_GET_CLASS (auth);
GST_DEBUG_OBJECT (auth, "check auth");
if (klass->check)
- result = klass->check (auth, client, check, state);
+ result = klass->check (auth, state, check);
return result;
+
+ /* ERRORS */
+no_state:
+ {
+ GST_ERROR ("no clientstate found");
+ return FALSE;
+ }
}
/**
#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.
struct _GstRTSPAuthClass {
GObjectClass parent_class;
- gboolean (*setup) (GstRTSPAuth *auth, GstRTSPClient * client,
- GstRTSPClientState *state);
- gboolean (*authenticate) (GstRTSPAuth *auth, GstRTSPClient * client,
- GstRTSPClientState *state);
- gboolean (*check) (GstRTSPAuth *auth, GstRTSPClient * client,
- GstRTSPAuthCheck check, GstRTSPClientState *state);
+ gboolean (*setup) (GstRTSPAuth *auth, GstRTSPClientState *state);
+ gboolean (*authenticate) (GstRTSPAuth *auth, GstRTSPClientState *state);
+ gboolean (*check) (GstRTSPAuth *auth, GstRTSPClientState *state,
+ const gchar *check);
};
GType gst_rtsp_auth_get_type (void);
GstRTSPToken *token);
void gst_rtsp_auth_remove_basic (GstRTSPAuth *auth, const gchar * basic);
-gboolean gst_rtsp_auth_setup (GstRTSPAuth *auth, GstRTSPClient * client,
- GstRTSPClientState *state);
+gboolean gst_rtsp_auth_setup (GstRTSPAuth *auth, GstRTSPClientState *state);
+
+gboolean gst_rtsp_auth_check (const gchar *check);
-gboolean gst_rtsp_auth_check (GstRTSPAuth *auth, GstRTSPClient * client,
- GstRTSPAuthCheck check, GstRTSPClientState *state);
/* helpers */
gchar * gst_rtsp_auth_make_basic (const gchar * user, const gchar * pass);
+/* checks */
+/**
+ * GST_RTSP_AUTH_CHECK_URL:
+ *
+ * Check the URL and methods
+ */
+#define GST_RTSP_AUTH_CHECK_URL "auth.check.url"
+/**
+ * GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_ACCESS:
+ *
+ * Check if access is allowed to a factory
+ */
+#define GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_ACCESS "auth.check.media.factory.access"
+/**
+ * GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_CONSTRUCT:
+ *
+ * Check if media can be constructed from a media factory
+ */
+#define GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_CONSTRUCT "auth.check.media.factory.construct"
+
+
+/* tokens */
+/**
+ * GST_RTSP_MEDIA_FACTORY_ROLE:
+ *
+ * G_TYPE_STRING, the role to use when dealing with media factories
+ */
+#define GST_RTSP_MEDIA_FACTORY_ROLE "media.factory.role"
+
+/* permissions */
+/**
+ * GST_RTSP_MEDIA_FACTORY_PERM_ACCESS:
+ *
+ * G_TYPE_BOOLEAN, %TRUE if the media can be accessed, %FALSE will
+ * return a 404 Not Found error when trying to access the media.
+ */
+#define GST_RTSP_MEDIA_FACTORY_PERM_ACCESS "media.factory.access"
+/**
+ * GST_RTSP_MEDIA_FACTORY_PERM_CONSTRUCT:
+ *
+ * G_TYPE_BOOLEAN, %TRUE if the media can be constructed, %FALSE will
+ * return a 404 Not Found error when trying to access the media.
+ */
+#define GST_RTSP_MEDIA_FACTORY_PERM_CONSTRUCT "media.factory.construct"
+
+
G_END_DECLS
#endif /* __GST_RTSP_AUTH_H__ */
if (auth) {
/* and let the authentication manager setup the auth tokens */
- gst_rtsp_auth_setup (auth, client, state);
+ gst_rtsp_auth_setup (auth, state);
}
send_message (client, state->session, state->response, FALSE);
state->factory = factory;
- if (!gst_rtsp_auth_check (priv->auth, client, GST_RTSP_AUTH_CHECK_FACTORY,
- state))
+ if (!gst_rtsp_auth_check (GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_ACCESS))
+ goto no_factory_access;
+
+ if (!gst_rtsp_auth_check (GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_CONSTRUCT))
goto not_authorized;
if (matched)
send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
return NULL;
}
+no_factory_access:
+ {
+ GST_ERROR ("client %p: not authorized to see factory uri %s", client, path);
+ 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);
+ GST_ERROR ("client %p: not authorized for factory uri %s", client, path);
handle_unauthorized_request (client, priv->auth, state);
return NULL;
}
state.uri = uri;
state.session = session;
- if (priv->auth) {
- if (!gst_rtsp_auth_check (priv->auth, client, GST_RTSP_AUTH_CHECK_URL,
- &state))
- goto not_authorized;
-
- state.auth = priv->auth;
- }
+ if (!gst_rtsp_auth_check (GST_RTSP_AUTH_CHECK_URL))
+ goto not_authorized;
/* now see what is asked and dispatch to a dedicated handler */
switch (method) {