From 19cffc79996fc3b73e597fa72949b9ed3559a313 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 5 Jul 2013 12:08:36 +0200 Subject: [PATCH] auth: remove auth from media and factory Remove the auth object from media and factory. We want to have the RTSPClient authenticate and authorize resources, there is no need to place another auth manager on the media/factory. --- examples/test-auth.c | 30 ++++----- gst/rtsp-server/rtsp-auth.c | 121 ++++++++++++++++++++++------------- gst/rtsp-server/rtsp-auth.h | 16 +++-- gst/rtsp-server/rtsp-client.c | 25 +------- gst/rtsp-server/rtsp-client.h | 1 + gst/rtsp-server/rtsp-media-factory.c | 64 ------------------ gst/rtsp-server/rtsp-media-factory.h | 3 - gst/rtsp-server/rtsp-media.c | 60 ----------------- gst/rtsp-server/rtsp-media.h | 3 - 9 files changed, 105 insertions(+), 218 deletions(-) diff --git a/examples/test-auth.c b/examples/test-auth.c index ee8af57..f5a129c 100644 --- a/examples/test-auth.c +++ b/examples/test-auth.c @@ -87,16 +87,6 @@ main (int argc, char *argv[]) "audiotestsrc ! audio/x-raw,rate=8000 ! " "alawenc ! rtppcmapay name=pay1 pt=97 " ")"); - /* make a new authentication manager */ - auth = gst_rtsp_auth_new (); - basic = gst_rtsp_auth_make_basic ("user", "password"); - gst_rtsp_auth_add_basic (auth, basic, "user"); - g_free (basic); - basic = gst_rtsp_auth_make_basic ("admin", "power"); - gst_rtsp_auth_add_basic (auth, basic, "admin"); - g_free (basic); - gst_rtsp_media_factory_set_auth (factory, auth); - g_object_unref (auth); /* attach the test factory to the /test url */ gst_rtsp_mount_points_add_factory (mounts, "/test", factory); @@ -105,18 +95,26 @@ main (int argc, char *argv[]) gst_rtsp_media_factory_set_launch (factory, "( " "videotestsrc ! video/x-raw,width=352,height=288,framerate=30/1 ! " "x264enc ! rtph264pay name=pay0 pt=96 )"); + /* attach the test factory to the /test url */ + gst_rtsp_mount_points_add_factory (mounts, "/test2", factory); + + /* don't need the ref to the mapper anymore */ + g_object_unref (mounts); + /* make a new authentication manager */ auth = gst_rtsp_auth_new (); + basic = gst_rtsp_auth_make_basic ("user", "password"); + gst_rtsp_auth_add_basic (auth, basic, "user"); + g_free (basic); + basic = gst_rtsp_auth_make_basic ("admin", "power"); + gst_rtsp_auth_add_basic (auth, basic, "admin"); + g_free (basic); basic = gst_rtsp_auth_make_basic ("admin2", "power2"); gst_rtsp_auth_add_basic (auth, basic, "admin"); g_free (basic); - gst_rtsp_media_factory_set_auth (factory, auth); + /* set as the server authentication manager */ + gst_rtsp_server_set_auth (server, auth); g_object_unref (auth); - /* attach the test factory to the /test url */ - gst_rtsp_mount_points_add_factory (mounts, "/test2", factory); - - /* don't need the ref to the mapper anymore */ - g_object_unref (mounts); /* attach the server to the default maincontext */ if (gst_rtsp_server_attach (server, NULL) == 0) diff --git a/gst/rtsp-server/rtsp-auth.c b/gst/rtsp-server/rtsp-auth.c index 6ed627f..a0df870 100644 --- a/gst/rtsp-server/rtsp-auth.c +++ b/gst/rtsp-server/rtsp-auth.c @@ -46,10 +46,12 @@ static void gst_rtsp_auth_set_property (GObject * object, guint propid, const GValue * value, GParamSpec * pspec); static void gst_rtsp_auth_finalize (GObject * obj); -static gboolean default_setup_auth (GstRTSPAuth * auth, GstRTSPClient * client, +static gboolean default_setup (GstRTSPAuth * auth, GstRTSPClient * client, + GstRTSPClientState * state); +static gboolean default_validate (GstRTSPAuth * auth, + GstRTSPClient * client, GstRTSPClientState * state); +static gboolean default_check (GstRTSPAuth * auth, GstRTSPClient * client, GQuark hint, GstRTSPClientState * state); -static gboolean default_check_method (GstRTSPAuth * auth, - GstRTSPClient * client, GQuark hint, GstRTSPClientState * state); G_DEFINE_TYPE (GstRTSPAuth, gst_rtsp_auth, G_TYPE_OBJECT); @@ -66,8 +68,9 @@ gst_rtsp_auth_class_init (GstRTSPAuthClass * klass) gobject_class->set_property = gst_rtsp_auth_set_property; gobject_class->finalize = gst_rtsp_auth_finalize; - klass->setup_auth = default_setup_auth; - klass->check_method = default_check_method; + klass->setup = default_setup; + klass->validate = default_validate; + klass->check = default_check; GST_DEBUG_CATEGORY_INIT (rtsp_auth_debug, "rtspauth", 0, "GstRTSPAuth"); } @@ -192,8 +195,8 @@ gst_rtsp_auth_remove_basic (GstRTSPAuth * auth, const gchar * basic) } static gboolean -default_setup_auth (GstRTSPAuth * auth, GstRTSPClient * client, - GQuark hint, GstRTSPClientState * state) +default_setup (GstRTSPAuth * auth, GstRTSPClient * client, + GstRTSPClientState * state) { if (state->response == NULL) return FALSE; @@ -206,10 +209,9 @@ default_setup_auth (GstRTSPAuth * auth, GstRTSPClient * client, } /** - * gst_rtsp_auth_setup_auth: + * gst_rtsp_auth_setup: * @auth: a #GstRTSPAuth * @client: the client - * @hint: TODO * @state: TODO * * Add authentication tokens to @response. @@ -217,8 +219,8 @@ default_setup_auth (GstRTSPAuth * auth, GstRTSPClient * client, * Returns: FALSE if something is wrong. */ gboolean -gst_rtsp_auth_setup_auth (GstRTSPAuth * auth, GstRTSPClient * client, - GQuark hint, GstRTSPClientState * state) +gst_rtsp_auth_setup (GstRTSPAuth * auth, GstRTSPClient * client, + GstRTSPClientState * state) { gboolean result = FALSE; GstRTSPAuthClass *klass; @@ -231,53 +233,83 @@ gst_rtsp_auth_setup_auth (GstRTSPAuth * auth, GstRTSPClient * client, GST_DEBUG_OBJECT (auth, "setup auth"); - if (klass->setup_auth) - result = klass->setup_auth (auth, client, hint, state); + if (klass->setup) + result = klass->setup (auth, client, state); return result; } static gboolean -default_check_method (GstRTSPAuth * auth, GstRTSPClient * client, - GQuark hint, GstRTSPClientState * state) +default_validate (GstRTSPAuth * auth, GstRTSPClient * client, + GstRTSPClientState * state) { GstRTSPAuthPrivate *priv = auth->priv; - gboolean result = TRUE; GstRTSPResult res; + gchar *authorization; - if ((state->method & priv->methods) != 0) { - gchar *authorization; + GST_DEBUG_OBJECT (auth, "validate"); - result = FALSE; + res = + gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_AUTHORIZATION, + &authorization, 0); + if (res < 0) + goto no_auth; - res = - gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_AUTHORIZATION, - &authorization, 0); - if (res < 0) - goto no_auth; + /* parse type */ + if (g_ascii_strncasecmp (authorization, "basic ", 6) == 0) { + gchar *authgroup; + + GST_DEBUG_OBJECT (auth, "check Basic auth"); + g_mutex_lock (&priv->lock); + if ((authgroup = g_hash_table_lookup (priv->basic, &authorization[6]))) { + GST_DEBUG_OBJECT (auth, "setting authgroup %s", authgroup); + state->authgroup = authgroup; + } + g_mutex_unlock (&priv->lock); + } else if (g_ascii_strncasecmp (authorization, "digest ", 7) == 0) { + GST_DEBUG_OBJECT (auth, "check Digest auth"); + /* not implemented yet */ + } + return TRUE; - /* parse type */ - if (g_ascii_strncasecmp (authorization, "basic ", 6) == 0) { - gchar *authgroup; +no_auth: + { + GST_DEBUG_OBJECT (auth, "no authorization header found"); + return TRUE; + } +} - GST_DEBUG_OBJECT (auth, "check Basic auth"); - g_mutex_lock (&priv->lock); - if ((authgroup = g_hash_table_lookup (priv->basic, &authorization[6]))) { - result = TRUE; - state->authgroup = authgroup; +static gboolean +default_check (GstRTSPAuth * auth, GstRTSPClient * client, + GQuark hint, GstRTSPClientState * state) +{ + GstRTSPAuthPrivate *priv = auth->priv; + GstRTSPAuthClass *klass; + + klass = GST_RTSP_AUTH_GET_CLASS (auth); + + if ((state->method & priv->methods) != 0) { + /* we need an authgroup to check */ + if (state->authgroup == NULL) { + if (klass->validate) { + if (!klass->validate (auth, client, state)) + goto validate_failed; } - g_mutex_unlock (&priv->lock); - } else if (g_ascii_strncasecmp (authorization, "digest ", 7) == 0) { - GST_DEBUG_OBJECT (auth, "check Digest auth"); - /* not implemented yet */ - result = FALSE; } + + if (state->authgroup == NULL) + goto no_auth; } - return result; + return TRUE; +validate_failed: + { + GST_DEBUG_OBJECT (auth, "validation failed"); + return FALSE; + } no_auth: { - GST_DEBUG_OBJECT (auth, "no authorization header found"); + GST_DEBUG_OBJECT (auth, "no authorization group found"); return FALSE; } } @@ -289,9 +321,10 @@ no_auth: * @hint: a hint * @state: client state * - * Check if @client is allowed to perform the actions of @state. + * Check if @client with state is authorized to perform @hint in the + * current @state. * - * Returns: FALSE if the action is not allowed. + * Returns: FALSE if check failed. */ gboolean gst_rtsp_auth_check (GstRTSPAuth * auth, GstRTSPClient * client, @@ -306,10 +339,10 @@ gst_rtsp_auth_check (GstRTSPAuth * auth, GstRTSPClient * client, klass = GST_RTSP_AUTH_GET_CLASS (auth); - GST_DEBUG_OBJECT (auth, "check state"); + GST_DEBUG_OBJECT (auth, "check auth"); - if (klass->check_method) - result = klass->check_method (auth, client, hint, state); + if (klass->check) + result = klass->check (auth, client, hint, state); return result; } diff --git a/gst/rtsp-server/rtsp-auth.h b/gst/rtsp-server/rtsp-auth.h index 425413b..fd9b679 100644 --- a/gst/rtsp-server/rtsp-auth.h +++ b/gst/rtsp-server/rtsp-auth.h @@ -53,10 +53,12 @@ struct _GstRTSPAuth { struct _GstRTSPAuthClass { GObjectClass parent_class; - gboolean (*setup_auth) (GstRTSPAuth *auth, GstRTSPClient * client, - GQuark hint, GstRTSPClientState *state); - gboolean (*check_method) (GstRTSPAuth *auth, GstRTSPClient * client, - GQuark hint, GstRTSPClientState *state); + gboolean (*setup) (GstRTSPAuth *auth, GstRTSPClient * client, + GstRTSPClientState *state); + gboolean (*validate) (GstRTSPAuth *auth, GstRTSPClient * client, + GstRTSPClientState *state); + gboolean (*check) (GstRTSPAuth *auth, GstRTSPClient * client, + GQuark hint, GstRTSPClientState *state); }; GType gst_rtsp_auth_get_type (void); @@ -67,10 +69,12 @@ void gst_rtsp_auth_add_basic (GstRTSPAuth *auth, const gc const gchar *authgroup); void gst_rtsp_auth_remove_basic (GstRTSPAuth *auth, const gchar * basic); -gboolean gst_rtsp_auth_setup_auth (GstRTSPAuth *auth, GstRTSPClient * client, - GQuark hint, GstRTSPClientState *state); +gboolean gst_rtsp_auth_setup (GstRTSPAuth *auth, GstRTSPClient * client, + GstRTSPClientState *state); + gboolean gst_rtsp_auth_check (GstRTSPAuth *auth, GstRTSPClient * client, GQuark hint, GstRTSPClientState *state); + /* helpers */ gchar * gst_rtsp_auth_make_basic (const gchar * user, const gchar * pass); diff --git a/gst/rtsp-server/rtsp-client.c b/gst/rtsp-server/rtsp-client.c index db82174..a597916 100644 --- a/gst/rtsp-server/rtsp-client.c +++ b/gst/rtsp-server/rtsp-client.c @@ -456,7 +456,7 @@ handle_unauthorized_request (GstRTSPClient * client, GstRTSPAuth * auth, if (auth) { /* and let the authentication manager setup the auth tokens */ - gst_rtsp_auth_setup_auth (auth, client, 0, state); + gst_rtsp_auth_setup (auth, client, state); } send_message (client, state->session, state->response, FALSE); @@ -487,7 +487,6 @@ find_media (GstRTSPClient * client, GstRTSPClientState * state, gint * matched) GstRTSPClientPrivate *priv = client->priv; GstRTSPMediaFactory *factory; GstRTSPMedia *media; - GstRTSPAuth *auth; gchar *path; gint path_len; @@ -518,17 +517,6 @@ find_media (GstRTSPClient * client, GstRTSPClientState * state, gint * matched) } priv->media = NULL; - /* check if we have access to the factory */ - if ((auth = gst_rtsp_media_factory_get_auth (factory))) { - state->factory = factory; - - if (!gst_rtsp_auth_check (auth, client, 0, state)) - goto not_allowed; - - state->factory = NULL; - g_object_unref (auth); - } - /* prepare the media and add it to the pipeline */ if (!(media = gst_rtsp_media_factory_construct (factory, state->uri))) goto no_media; @@ -568,15 +556,6 @@ no_factory: send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state); return NULL; } -not_allowed: - { - GST_ERROR ("client %p: unauthorized request", client); - handle_unauthorized_request (client, auth, state); - g_object_unref (factory); - state->factory = NULL; - g_object_unref (auth); - return NULL; - } no_media: { GST_ERROR ("client %p: can't create media", client); @@ -1847,6 +1826,8 @@ handle_request (GstRTSPClient * client, GstRTSPMessage * request) if (priv->auth) { if (!gst_rtsp_auth_check (priv->auth, client, 0, &state)) goto not_authorized; + + state.auth = priv->auth; } /* now see what is asked and dispatch to a dedicated handler */ diff --git a/gst/rtsp-server/rtsp-client.h b/gst/rtsp-server/rtsp-client.h index b5adc10..86ae980 100644 --- a/gst/rtsp-server/rtsp-client.h +++ b/gst/rtsp-server/rtsp-client.h @@ -65,6 +65,7 @@ struct _GstRTSPClientState { GstRTSPMessage *request; GstRTSPUrl *uri; GstRTSPMethod method; + GstRTSPAuth *auth; const gchar *authgroup; GstRTSPSession *session; GstRTSPSessionMedia *sessmedia; diff --git a/gst/rtsp-server/rtsp-media-factory.c b/gst/rtsp-server/rtsp-media-factory.c index f448276..b6fa8c0 100644 --- a/gst/rtsp-server/rtsp-media-factory.c +++ b/gst/rtsp-server/rtsp-media-factory.c @@ -33,7 +33,6 @@ struct _GstRTSPMediaFactoryPrivate gboolean shared; gboolean eos_shutdown; GstRTSPLowerTrans protocols; - GstRTSPAuth *auth; guint buffer_size; GstRTSPAddressPool *pool; @@ -194,8 +193,6 @@ gst_rtsp_media_factory_finalize (GObject * obj) g_mutex_clear (&priv->medias_lock); g_free (priv->launch); g_mutex_clear (&priv->lock); - if (priv->auth) - g_object_unref (priv->auth); if (priv->pool) g_object_unref (priv->pool); @@ -536,62 +533,6 @@ gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory) } /** - * gst_rtsp_media_factory_set_auth: - * @factory: a #GstRTSPMediaFactory - * @auth: a #GstRTSPAuth - * - * configure @auth to be used as the authentication manager of @factory. - */ -void -gst_rtsp_media_factory_set_auth (GstRTSPMediaFactory * factory, - GstRTSPAuth * auth) -{ - GstRTSPMediaFactoryPrivate *priv; - GstRTSPAuth *old; - - g_return_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory)); - - priv = factory->priv; - - GST_RTSP_MEDIA_FACTORY_LOCK (factory); - if ((old = priv->auth) != auth) - priv->auth = auth ? g_object_ref (auth) : NULL; - else - old = NULL; - GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); - - if (old) - g_object_unref (old); -} - -/** - * gst_rtsp_media_factory_get_auth: - * @factory: a #GstRTSPMediaFactory - * - * Get the #GstRTSPAuth used as the authentication manager of @factory. - * - * Returns: (transfer full): the #GstRTSPAuth of @factory. g_object_unref() after - * usage. - */ -GstRTSPAuth * -gst_rtsp_media_factory_get_auth (GstRTSPMediaFactory * factory) -{ - GstRTSPMediaFactoryPrivate *priv; - GstRTSPAuth *result; - - g_return_val_if_fail (GST_IS_RTSP_MEDIA_FACTORY (factory), NULL); - - priv = factory->priv; - - GST_RTSP_MEDIA_FACTORY_LOCK (factory); - if ((result = priv->auth)) - g_object_ref (result); - GST_RTSP_MEDIA_FACTORY_UNLOCK (factory); - - return result; -} - -/** * gst_rtsp_media_factory_set_protocols: * @factory: a #GstRTSPMediaFactory * @protocols: the new flags @@ -896,7 +837,6 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media) GstRTSPMediaFactoryPrivate *priv = factory->priv; gboolean shared, eos_shutdown; guint size; - GstRTSPAuth *auth; GstRTSPLowerTrans protocols; GstRTSPAddressPool *pool; @@ -913,10 +853,6 @@ default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media) gst_rtsp_media_set_buffer_size (media, size); gst_rtsp_media_set_protocols (media, protocols); - if ((auth = gst_rtsp_media_factory_get_auth (factory))) { - gst_rtsp_media_set_auth (media, auth); - g_object_unref (auth); - } if ((pool = gst_rtsp_media_factory_get_address_pool (factory))) { gst_rtsp_media_set_address_pool (media, pool); g_object_unref (pool); diff --git a/gst/rtsp-server/rtsp-media-factory.h b/gst/rtsp-server/rtsp-media-factory.h index d974fa0..a492422 100644 --- a/gst/rtsp-server/rtsp-media-factory.h +++ b/gst/rtsp-server/rtsp-media-factory.h @@ -114,9 +114,6 @@ gboolean gst_rtsp_media_factory_is_eos_shutdown (GstRTSPMediaFac void gst_rtsp_media_factory_set_protocols (GstRTSPMediaFactory *factory, GstRTSPLowerTrans protocols); GstRTSPLowerTrans gst_rtsp_media_factory_get_protocols (GstRTSPMediaFactory *factory); -void gst_rtsp_media_factory_set_auth (GstRTSPMediaFactory *factory, GstRTSPAuth *auth); -GstRTSPAuth * gst_rtsp_media_factory_get_auth (GstRTSPMediaFactory *factory); - void gst_rtsp_media_factory_set_address_pool (GstRTSPMediaFactory * factory, GstRTSPAddressPool * pool); GstRTSPAddressPool * gst_rtsp_media_factory_get_address_pool (GstRTSPMediaFactory * factory); diff --git a/gst/rtsp-server/rtsp-media.c b/gst/rtsp-server/rtsp-media.c index d20087d..4e25e15 100644 --- a/gst/rtsp-server/rtsp-media.c +++ b/gst/rtsp-server/rtsp-media.c @@ -40,7 +40,6 @@ struct _GstRTSPMediaPrivate gboolean reused; gboolean eos_shutdown; guint buffer_size; - GstRTSPAuth *auth; GstRTSPAddressPool *pool; GstElement *element; @@ -262,8 +261,6 @@ gst_rtsp_media_finalize (GObject * obj) if (priv->nettime) gst_object_unref (priv->nettime); gst_object_unref (priv->element); - if (priv->auth) - g_object_unref (priv->auth); if (priv->pool) g_object_unref (priv->pool); g_mutex_clear (&priv->lock); @@ -785,63 +782,6 @@ gst_rtsp_media_is_time_provider (GstRTSPMedia * media) } /** - * gst_rtsp_media_set_auth: - * @media: a #GstRTSPMedia - * @auth: a #GstRTSPAuth - * - * configure @auth to be used as the authentication manager of @media. - */ -void -gst_rtsp_media_set_auth (GstRTSPMedia * media, GstRTSPAuth * auth) -{ - GstRTSPMediaPrivate *priv; - GstRTSPAuth *old; - - g_return_if_fail (GST_IS_RTSP_MEDIA (media)); - - priv = media->priv; - - GST_LOG_OBJECT (media, "set auth %p", auth); - - g_mutex_lock (&priv->lock); - if ((old = priv->auth) != auth) - priv->auth = auth ? g_object_ref (auth) : NULL; - else - old = NULL; - g_mutex_unlock (&priv->lock); - - if (old) - g_object_unref (old); -} - -/** - * gst_rtsp_media_get_auth: - * @media: a #GstRTSPMedia - * - * Get the #GstRTSPAuth used as the authentication manager of @media. - * - * Returns: (transfer full): the #GstRTSPAuth of @media. g_object_unref() after - * usage. - */ -GstRTSPAuth * -gst_rtsp_media_get_auth (GstRTSPMedia * media) -{ - GstRTSPMediaPrivate *priv; - GstRTSPAuth *result; - - g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL); - - priv = media->priv; - - g_mutex_lock (&priv->lock); - if ((result = priv->auth)) - g_object_ref (result); - g_mutex_unlock (&priv->lock); - - return result; -} - -/** * gst_rtsp_media_set_address_pool: * @media: a #GstRTSPMedia * @pool: a #GstRTSPAddressPool diff --git a/gst/rtsp-server/rtsp-media.h b/gst/rtsp-server/rtsp-media.h index d6d2153..02be092 100644 --- a/gst/rtsp-server/rtsp-media.h +++ b/gst/rtsp-server/rtsp-media.h @@ -137,9 +137,6 @@ GstRTSPLowerTrans gst_rtsp_media_get_protocols (GstRTSPMedia *media); void gst_rtsp_media_set_eos_shutdown (GstRTSPMedia *media, gboolean eos_shutdown); gboolean gst_rtsp_media_is_eos_shutdown (GstRTSPMedia *media); -void gst_rtsp_media_set_auth (GstRTSPMedia *media, GstRTSPAuth *auth); -GstRTSPAuth * gst_rtsp_media_get_auth (GstRTSPMedia *media); - void gst_rtsp_media_set_address_pool (GstRTSPMedia *media, GstRTSPAddressPool *pool); GstRTSPAddressPool * gst_rtsp_media_get_address_pool (GstRTSPMedia *media); -- 2.7.4