auth: add support for multiple basic auth tokens

Make it possible to add multiple basic authorisation tokens to one authorization
object. Associate with each token an authorization group that will define what
capabilities are allowed.
This commit is contained in:
Wim Taymans 2013-07-04 14:33:59 +02:00
parent a1e5bde58d
commit 78bc979690
4 changed files with 62 additions and 18 deletions

View file

@ -89,8 +89,11 @@ main (int argc, char *argv[])
/* make a new authentication manager */ /* make a new authentication manager */
auth = gst_rtsp_auth_new (); auth = gst_rtsp_auth_new ();
basic = gst_rtsp_auth_make_basic ("user", "admin"); basic = gst_rtsp_auth_make_basic ("user", "password");
gst_rtsp_auth_set_basic (auth, basic); 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); g_free (basic);
gst_rtsp_media_factory_set_auth (factory, auth); gst_rtsp_media_factory_set_auth (factory, auth);
g_object_unref (auth); g_object_unref (auth);
@ -104,8 +107,8 @@ main (int argc, char *argv[])
"x264enc ! rtph264pay name=pay0 pt=96 )"); "x264enc ! rtph264pay name=pay0 pt=96 )");
/* make a new authentication manager */ /* make a new authentication manager */
auth = gst_rtsp_auth_new (); auth = gst_rtsp_auth_new ();
basic = gst_rtsp_auth_make_basic ("user2", "admin2"); basic = gst_rtsp_auth_make_basic ("admin2", "power2");
gst_rtsp_auth_set_basic (auth, basic); gst_rtsp_auth_add_basic (auth, basic, "admin");
g_free (basic); g_free (basic);
gst_rtsp_media_factory_set_auth (factory, auth); gst_rtsp_media_factory_set_auth (factory, auth);
g_object_unref (auth); g_object_unref (auth);
@ -123,8 +126,9 @@ main (int argc, char *argv[])
g_timeout_add_seconds (10, (GSourceFunc) remove_sessions, server); g_timeout_add_seconds (10, (GSourceFunc) remove_sessions, server);
/* start serving */ /* start serving */
g_print ("stream with user:admin ready at rtsp://127.0.0.1:8554/test\n"); g_print ("stream with user:password ready at rtsp://127.0.0.1:8554/test\n");
g_print ("stream with user2:admin2 ready at rtsp://127.0.0.1:8554/test2\n"); g_print ("stream with admin:power ready at rtsp://127.0.0.1:8554/test\n");
g_print ("stream with admin2:power2 ready at rtsp://127.0.0.1:8554/test2\n");
g_main_loop_run (loop); g_main_loop_run (loop);
return 0; return 0;

View file

@ -27,7 +27,7 @@
struct _GstRTSPAuthPrivate struct _GstRTSPAuthPrivate
{ {
GMutex lock; GMutex lock;
gchar *basic; /* protected by lock */ GHashTable *basic; /* protected by lock */
GstRTSPMethod methods; GstRTSPMethod methods;
}; };
@ -75,11 +75,16 @@ gst_rtsp_auth_class_init (GstRTSPAuthClass * klass)
static void static void
gst_rtsp_auth_init (GstRTSPAuth * auth) gst_rtsp_auth_init (GstRTSPAuth * auth)
{ {
auth->priv = GST_RTSP_AUTH_GET_PRIVATE (auth); GstRTSPAuthPrivate *priv;
auth->priv = priv = GST_RTSP_AUTH_GET_PRIVATE (auth);
g_mutex_init (&priv->lock);
priv->basic = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
g_mutex_init (&auth->priv->lock);
/* bitwise or of all methods that need authentication */ /* bitwise or of all methods that need authentication */
auth->priv->methods = GST_RTSP_DESCRIBE | priv->methods = GST_RTSP_DESCRIBE |
GST_RTSP_ANNOUNCE | GST_RTSP_ANNOUNCE |
GST_RTSP_GET_PARAMETER | GST_RTSP_GET_PARAMETER |
GST_RTSP_SET_PARAMETER | GST_RTSP_SET_PARAMETER |
@ -94,7 +99,7 @@ gst_rtsp_auth_finalize (GObject * obj)
GstRTSPAuthPrivate *priv = auth->priv; GstRTSPAuthPrivate *priv = auth->priv;
GST_INFO ("finalize auth %p", auth); GST_INFO ("finalize auth %p", auth);
g_free (priv->basic); g_hash_table_unref (priv->basic);
g_mutex_clear (&priv->lock); g_mutex_clear (&priv->lock);
G_OBJECT_CLASS (gst_rtsp_auth_parent_class)->finalize (obj); G_OBJECT_CLASS (gst_rtsp_auth_parent_class)->finalize (obj);
@ -138,24 +143,51 @@ gst_rtsp_auth_new (void)
} }
/** /**
* gst_rtsp_auth_set_basic: * gst_rtsp_auth_add_basic:
* @auth: a #GstRTSPAuth * @auth: a #GstRTSPAuth
* @basic: the basic token * @basic: the basic token
* @authgroup: authorisation group
* *
* Set the basic token for the default authentication algorithm. * Add a basic token for the default authentication algorithm that
* enables the client qith privileges from @authgroup.
*/ */
void void
gst_rtsp_auth_set_basic (GstRTSPAuth * auth, const gchar * basic) gst_rtsp_auth_add_basic (GstRTSPAuth * auth, const gchar * basic,
const gchar * authgroup)
{ {
GstRTSPAuthPrivate *priv; GstRTSPAuthPrivate *priv;
g_return_if_fail (GST_IS_RTSP_AUTH (auth)); g_return_if_fail (GST_IS_RTSP_AUTH (auth));
g_return_if_fail (basic != NULL);
g_return_if_fail (authgroup != NULL);
priv = auth->priv; priv = auth->priv;
g_mutex_lock (&priv->lock); g_mutex_lock (&priv->lock);
g_free (priv->basic); g_hash_table_replace (priv->basic, g_strdup (basic), g_strdup (authgroup));
priv->basic = g_strdup (basic); g_mutex_unlock (&priv->lock);
}
/**
* gst_rtsp_auth_remove_basic:
* @auth: a #GstRTSPAuth
* @basic: (transfer none): the basic token
*
* Add a basic token for the default authentication algorithm that
* enables the client qith privileges from @authgroup.
*/
void
gst_rtsp_auth_remove_basic (GstRTSPAuth * auth, const gchar * basic)
{
GstRTSPAuthPrivate *priv;
g_return_if_fail (GST_IS_RTSP_AUTH (auth));
g_return_if_fail (basic != NULL);
priv = auth->priv;
g_mutex_lock (&priv->lock);
g_hash_table_remove (priv->basic, basic);
g_mutex_unlock (&priv->lock); g_mutex_unlock (&priv->lock);
} }
@ -226,10 +258,14 @@ default_check_method (GstRTSPAuth * auth, GstRTSPClient * client,
/* parse type */ /* parse type */
if (g_ascii_strncasecmp (authorization, "basic ", 6) == 0) { if (g_ascii_strncasecmp (authorization, "basic ", 6) == 0) {
gchar *authgroup;
GST_DEBUG_OBJECT (auth, "check Basic auth"); GST_DEBUG_OBJECT (auth, "check Basic auth");
g_mutex_lock (&priv->lock); g_mutex_lock (&priv->lock);
if (priv->basic && strcmp (&authorization[6], priv->basic) == 0) if ((authgroup = g_hash_table_lookup (priv->basic, &authorization[6]))) {
result = TRUE; result = TRUE;
state->authgroup = authgroup;
}
g_mutex_unlock (&priv->lock); g_mutex_unlock (&priv->lock);
} else if (g_ascii_strncasecmp (authorization, "digest ", 7) == 0) { } else if (g_ascii_strncasecmp (authorization, "digest ", 7) == 0) {
GST_DEBUG_OBJECT (auth, "check Digest auth"); GST_DEBUG_OBJECT (auth, "check Digest auth");

View file

@ -63,7 +63,9 @@ GType gst_rtsp_auth_get_type (void);
GstRTSPAuth * gst_rtsp_auth_new (void); GstRTSPAuth * gst_rtsp_auth_new (void);
void gst_rtsp_auth_set_basic (GstRTSPAuth *auth, const gchar * basic); void gst_rtsp_auth_add_basic (GstRTSPAuth *auth, const gchar * basic,
const gchar *authgroup);
void gst_rtsp_auth_remove_basic (GstRTSPAuth *auth, const gchar * basic);
gboolean gst_rtsp_auth_setup_auth (GstRTSPAuth *auth, GstRTSPClient * client, gboolean gst_rtsp_auth_setup_auth (GstRTSPAuth *auth, GstRTSPClient * client,
GQuark hint, GstRTSPClientState *state); GQuark hint, GstRTSPClientState *state);

View file

@ -51,6 +51,7 @@ typedef struct _GstRTSPClientPrivate GstRTSPClientPrivate;
* @request: the complete request * @request: the complete request
* @uri: the complete url parsed from @request * @uri: the complete url parsed from @request
* @method: the parsed method of @uri * @method: the parsed method of @uri
* @authgroup: authorisation group
* @session: the session, can be NULL * @session: the session, can be NULL
* @sessmedia: the session media for the url can be NULL * @sessmedia: the session media for the url can be NULL
* @factory: the media factory for the url, can be NULL. * @factory: the media factory for the url, can be NULL.
@ -64,6 +65,7 @@ struct _GstRTSPClientState {
GstRTSPMessage *request; GstRTSPMessage *request;
GstRTSPUrl *uri; GstRTSPUrl *uri;
GstRTSPMethod method; GstRTSPMethod method;
const gchar *authgroup;
GstRTSPSession *session; GstRTSPSession *session;
GstRTSPSessionMedia *sessmedia; GstRTSPSessionMedia *sessmedia;
GstRTSPMediaFactory *factory; GstRTSPMediaFactory *factory;