auth: use the token after authentication

After we authenticated a user, keep the Token around in the state.
This commit is contained in:
Wim Taymans 2013-07-05 20:48:18 +02:00
parent 12583e819c
commit fb7c9b8122
4 changed files with 73 additions and 31 deletions

View file

@ -62,7 +62,9 @@ main (int argc, char *argv[])
GstRTSPMountPoints *mounts; GstRTSPMountPoints *mounts;
GstRTSPMediaFactory *factory; GstRTSPMediaFactory *factory;
GstRTSPAuth *auth; GstRTSPAuth *auth;
GstRTSPToken *token;
gchar *basic; gchar *basic;
GstStructure *s;
gst_init (&argc, &argv); gst_init (&argc, &argv);
@ -103,15 +105,34 @@ 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 ();
/* 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);
basic = gst_rtsp_auth_make_basic ("user", "password"); basic = gst_rtsp_auth_make_basic ("user", "password");
gst_rtsp_auth_add_basic (auth, basic, "user"); gst_rtsp_auth_add_basic (auth, basic, token);
g_free (basic); g_free (basic);
gst_rtsp_token_unref (token);
/* 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);
basic = gst_rtsp_auth_make_basic ("admin", "power"); basic = gst_rtsp_auth_make_basic ("admin", "power");
gst_rtsp_auth_add_basic (auth, basic, "admin"); gst_rtsp_auth_add_basic (auth, basic, token);
g_free (basic); g_free (basic);
gst_rtsp_token_unref (token);
/* 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);
basic = gst_rtsp_auth_make_basic ("admin2", "power2"); basic = gst_rtsp_auth_make_basic ("admin2", "power2");
gst_rtsp_auth_add_basic (auth, basic, "admin"); gst_rtsp_auth_add_basic (auth, basic, token);
g_free (basic); g_free (basic);
gst_rtsp_token_unref (token);
/* set as the server authentication manager */ /* set as the server authentication manager */
gst_rtsp_server_set_auth (server, auth); gst_rtsp_server_set_auth (server, auth);
g_object_unref (auth); g_object_unref (auth);

View file

@ -48,7 +48,7 @@ static void gst_rtsp_auth_finalize (GObject * obj);
static gboolean default_setup (GstRTSPAuth * auth, GstRTSPClient * client, static gboolean default_setup (GstRTSPAuth * auth, GstRTSPClient * client,
GstRTSPClientState * state); GstRTSPClientState * state);
static gboolean default_validate (GstRTSPAuth * auth, static gboolean default_authenticate (GstRTSPAuth * auth,
GstRTSPClient * client, GstRTSPClientState * state); GstRTSPClient * client, GstRTSPClientState * state);
static gboolean default_check (GstRTSPAuth * auth, GstRTSPClient * client, static gboolean default_check (GstRTSPAuth * auth, GstRTSPClient * client,
GQuark hint, GstRTSPClientState * state); GQuark hint, GstRTSPClientState * state);
@ -69,7 +69,7 @@ gst_rtsp_auth_class_init (GstRTSPAuthClass * klass)
gobject_class->finalize = gst_rtsp_auth_finalize; gobject_class->finalize = gst_rtsp_auth_finalize;
klass->setup = default_setup; klass->setup = default_setup;
klass->validate = default_validate; klass->authenticate = default_authenticate;
klass->check = default_check; klass->check = default_check;
GST_DEBUG_CATEGORY_INIT (rtsp_auth_debug, "rtspauth", 0, "GstRTSPAuth"); GST_DEBUG_CATEGORY_INIT (rtsp_auth_debug, "rtspauth", 0, "GstRTSPAuth");
@ -84,7 +84,8 @@ gst_rtsp_auth_init (GstRTSPAuth * auth)
g_mutex_init (&priv->lock); g_mutex_init (&priv->lock);
priv->basic = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); priv->basic = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) gst_rtsp_token_unref);
/* bitwise or of all methods that need authentication */ /* bitwise or of all methods that need authentication */
priv->methods = GST_RTSP_DESCRIBE | priv->methods = GST_RTSP_DESCRIBE |
@ -156,18 +157,19 @@ gst_rtsp_auth_new (void)
*/ */
void void
gst_rtsp_auth_add_basic (GstRTSPAuth * auth, const gchar * basic, gst_rtsp_auth_add_basic (GstRTSPAuth * auth, const gchar * basic,
const gchar * authgroup) GstRTSPToken * token)
{ {
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 (basic != NULL);
g_return_if_fail (authgroup != NULL); g_return_if_fail (GST_IS_RTSP_TOKEN (token));
priv = auth->priv; priv = auth->priv;
g_mutex_lock (&priv->lock); g_mutex_lock (&priv->lock);
g_hash_table_replace (priv->basic, g_strdup (basic), g_strdup (authgroup)); g_hash_table_replace (priv->basic, g_strdup (basic),
gst_rtsp_token_ref (token));
g_mutex_unlock (&priv->lock); g_mutex_unlock (&priv->lock);
} }
@ -240,14 +242,14 @@ gst_rtsp_auth_setup (GstRTSPAuth * auth, GstRTSPClient * client,
} }
static gboolean static gboolean
default_validate (GstRTSPAuth * auth, GstRTSPClient * client, default_authenticate (GstRTSPAuth * auth, GstRTSPClient * client,
GstRTSPClientState * state) GstRTSPClientState * state)
{ {
GstRTSPAuthPrivate *priv = auth->priv; GstRTSPAuthPrivate *priv = auth->priv;
GstRTSPResult res; GstRTSPResult res;
gchar *authorization; gchar *authorization;
GST_DEBUG_OBJECT (auth, "validate"); GST_DEBUG_OBJECT (auth, "authenticate");
res = res =
gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_AUTHORIZATION, gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_AUTHORIZATION,
@ -257,13 +259,13 @@ default_validate (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; GstRTSPToken *token;
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 ((authgroup = g_hash_table_lookup (priv->basic, &authorization[6]))) { if ((token = g_hash_table_lookup (priv->basic, &authorization[6]))) {
GST_DEBUG_OBJECT (auth, "setting authgroup %s", authgroup); GST_DEBUG_OBJECT (auth, "setting token %p", token);
state->authgroup = authgroup; state->token = token;
} }
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) {
@ -290,21 +292,21 @@ default_check (GstRTSPAuth * auth, GstRTSPClient * client,
if ((state->method & priv->methods) != 0) { if ((state->method & priv->methods) != 0) {
/* we need an authgroup to check */ /* we need an authgroup to check */
if (state->authgroup == NULL) { if (state->token == NULL) {
if (klass->validate) { if (klass->authenticate) {
if (!klass->validate (auth, client, state)) if (!klass->authenticate (auth, client, state))
goto validate_failed; goto authenticate_failed;
} }
} }
if (state->authgroup == NULL) if (state->token == NULL)
goto no_auth; goto no_auth;
} }
return TRUE; return TRUE;
validate_failed: authenticate_failed:
{ {
GST_DEBUG_OBJECT (auth, "validation failed"); GST_DEBUG_OBJECT (auth, "check failed");
return FALSE; return FALSE;
} }
no_auth: no_auth:

View file

@ -27,6 +27,7 @@ typedef struct _GstRTSPAuthClass GstRTSPAuthClass;
typedef struct _GstRTSPAuthPrivate GstRTSPAuthPrivate; typedef struct _GstRTSPAuthPrivate GstRTSPAuthPrivate;
#include "rtsp-client.h" #include "rtsp-client.h"
#include "rtsp-token.h"
G_BEGIN_DECLS G_BEGIN_DECLS
@ -50,12 +51,28 @@ struct _GstRTSPAuth {
GstRTSPAuthPrivate *priv; GstRTSPAuthPrivate *priv;
}; };
/**
* GstRTSPAuthClass:
* @setup: called when an unauthorized resource has been accessed and
* authentication needs to be requested to the client. The default
* implementation adds basic authentication to the response.
* @authenticate: check the authentication of a client. The default implementation
* checks if the authentication in the header matches one of the basic
* authentication tokens. This function should set the authgroup field
* in the state.
* @check: check if a resource can be accessed. this function should
* call validate to authenticate the client when needed. The default
* implementation disallows unauthenticated access to all methods
* except OPTIONS.
*
* The authentication class.
*/
struct _GstRTSPAuthClass { struct _GstRTSPAuthClass {
GObjectClass parent_class; GObjectClass parent_class;
gboolean (*setup) (GstRTSPAuth *auth, GstRTSPClient * client, gboolean (*setup) (GstRTSPAuth *auth, GstRTSPClient * client,
GstRTSPClientState *state); GstRTSPClientState *state);
gboolean (*validate) (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); GQuark hint, GstRTSPClientState *state);
@ -66,7 +83,7 @@ GType gst_rtsp_auth_get_type (void);
GstRTSPAuth * gst_rtsp_auth_new (void); GstRTSPAuth * gst_rtsp_auth_new (void);
void gst_rtsp_auth_add_basic (GstRTSPAuth *auth, const gchar * basic, void gst_rtsp_auth_add_basic (GstRTSPAuth *auth, const gchar * basic,
const gchar *authgroup); GstRTSPToken *token);
void gst_rtsp_auth_remove_basic (GstRTSPAuth *auth, const gchar * basic); void gst_rtsp_auth_remove_basic (GstRTSPAuth *auth, const gchar * basic);
gboolean gst_rtsp_auth_setup (GstRTSPAuth *auth, GstRTSPClient * client, gboolean gst_rtsp_auth_setup (GstRTSPAuth *auth, GstRTSPClient * client,

View file

@ -35,6 +35,7 @@ typedef struct _GstRTSPClientPrivate GstRTSPClientPrivate;
#include "rtsp-session-pool.h" #include "rtsp-session-pool.h"
#include "rtsp-session-media.h" #include "rtsp-session-media.h"
#include "rtsp-auth.h" #include "rtsp-auth.h"
#include "rtsp-token.h"
#include "rtsp-sdp.h" #include "rtsp-sdp.h"
#define GST_TYPE_RTSP_CLIENT (gst_rtsp_client_get_type ()) #define GST_TYPE_RTSP_CLIENT (gst_rtsp_client_get_type ())
@ -51,7 +52,8 @@ 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 * @auth: the current auth object or NULL
* @token: authorisation token
* @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.
@ -66,7 +68,7 @@ struct _GstRTSPClientState {
GstRTSPUrl *uri; GstRTSPUrl *uri;
GstRTSPMethod method; GstRTSPMethod method;
GstRTSPAuth *auth; GstRTSPAuth *auth;
const gchar *authgroup; GstRTSPToken *token;
GstRTSPSession *session; GstRTSPSession *session;
GstRTSPSessionMedia *sessmedia; GstRTSPSessionMedia *sessmedia;
GstRTSPMediaFactory *factory; GstRTSPMediaFactory *factory;