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;
GstRTSPMediaFactory *factory;
GstRTSPAuth *auth;
GstRTSPToken *token;
gchar *basic;
GstStructure *s;
gst_init (&argc, &argv);
@ -103,15 +105,34 @@ main (int argc, char *argv[])
/* make a new authentication manager */
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");
gst_rtsp_auth_add_basic (auth, basic, "user");
gst_rtsp_auth_add_basic (auth, basic, token);
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");
gst_rtsp_auth_add_basic (auth, basic, "admin");
gst_rtsp_auth_add_basic (auth, basic, token);
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");
gst_rtsp_auth_add_basic (auth, basic, "admin");
gst_rtsp_auth_add_basic (auth, basic, token);
g_free (basic);
gst_rtsp_token_unref (token);
/* set as the server authentication manager */
gst_rtsp_server_set_auth (server, 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,
GstRTSPClientState * state);
static gboolean default_validate (GstRTSPAuth * auth,
static gboolean default_authenticate (GstRTSPAuth * auth,
GstRTSPClient * client, GstRTSPClientState * state);
static gboolean default_check (GstRTSPAuth * auth, GstRTSPClient * client,
GQuark hint, GstRTSPClientState * state);
@ -69,7 +69,7 @@ gst_rtsp_auth_class_init (GstRTSPAuthClass * klass)
gobject_class->finalize = gst_rtsp_auth_finalize;
klass->setup = default_setup;
klass->validate = default_validate;
klass->authenticate = default_authenticate;
klass->check = default_check;
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);
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 */
priv->methods = GST_RTSP_DESCRIBE |
@ -156,18 +157,19 @@ gst_rtsp_auth_new (void)
*/
void
gst_rtsp_auth_add_basic (GstRTSPAuth * auth, const gchar * basic,
const gchar * authgroup)
GstRTSPToken * token)
{
GstRTSPAuthPrivate *priv;
g_return_if_fail (GST_IS_RTSP_AUTH (auth));
g_return_if_fail (basic != NULL);
g_return_if_fail (authgroup != NULL);
g_return_if_fail (GST_IS_RTSP_TOKEN (token));
priv = auth->priv;
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);
}
@ -240,14 +242,14 @@ gst_rtsp_auth_setup (GstRTSPAuth * auth, GstRTSPClient * client,
}
static gboolean
default_validate (GstRTSPAuth * auth, GstRTSPClient * client,
default_authenticate (GstRTSPAuth * auth, GstRTSPClient * client,
GstRTSPClientState * state)
{
GstRTSPAuthPrivate *priv = auth->priv;
GstRTSPResult res;
gchar *authorization;
GST_DEBUG_OBJECT (auth, "validate");
GST_DEBUG_OBJECT (auth, "authenticate");
res =
gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_AUTHORIZATION,
@ -257,13 +259,13 @@ default_validate (GstRTSPAuth * auth, GstRTSPClient * client,
/* parse type */
if (g_ascii_strncasecmp (authorization, "basic ", 6) == 0) {
gchar *authgroup;
GstRTSPToken *token;
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;
if ((token = g_hash_table_lookup (priv->basic, &authorization[6]))) {
GST_DEBUG_OBJECT (auth, "setting token %p", token);
state->token = token;
}
g_mutex_unlock (&priv->lock);
} 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) {
/* we need an authgroup to check */
if (state->authgroup == NULL) {
if (klass->validate) {
if (!klass->validate (auth, client, state))
goto validate_failed;
if (state->token == NULL) {
if (klass->authenticate) {
if (!klass->authenticate (auth, client, state))
goto authenticate_failed;
}
}
if (state->authgroup == NULL)
if (state->token == NULL)
goto no_auth;
}
return TRUE;
validate_failed:
authenticate_failed:
{
GST_DEBUG_OBJECT (auth, "validation failed");
GST_DEBUG_OBJECT (auth, "check failed");
return FALSE;
}
no_auth:

View file

@ -27,6 +27,7 @@ typedef struct _GstRTSPAuthClass GstRTSPAuthClass;
typedef struct _GstRTSPAuthPrivate GstRTSPAuthPrivate;
#include "rtsp-client.h"
#include "rtsp-token.h"
G_BEGIN_DECLS
@ -50,15 +51,31 @@ struct _GstRTSPAuth {
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 {
GObjectClass parent_class;
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);
gboolean (*setup) (GstRTSPAuth *auth, GstRTSPClient * client,
GstRTSPClientState *state);
gboolean (*authenticate) (GstRTSPAuth *auth, GstRTSPClient * client,
GstRTSPClientState *state);
gboolean (*check) (GstRTSPAuth *auth, GstRTSPClient * client,
GQuark hint, GstRTSPClientState *state);
};
GType gst_rtsp_auth_get_type (void);
@ -66,7 +83,7 @@ GType gst_rtsp_auth_get_type (void);
GstRTSPAuth * gst_rtsp_auth_new (void);
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);
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-media.h"
#include "rtsp-auth.h"
#include "rtsp-token.h"
#include "rtsp-sdp.h"
#define GST_TYPE_RTSP_CLIENT (gst_rtsp_client_get_type ())
@ -51,7 +52,8 @@ typedef struct _GstRTSPClientPrivate GstRTSPClientPrivate;
* @request: the complete request
* @uri: the complete url parsed from @request
* @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
* @sessmedia: the session media for the url can be NULL
* @factory: the media factory for the url, can be NULL.
@ -66,7 +68,7 @@ struct _GstRTSPClientState {
GstRTSPUrl *uri;
GstRTSPMethod method;
GstRTSPAuth *auth;
const gchar *authgroup;
GstRTSPToken *token;
GstRTSPSession *session;
GstRTSPSessionMedia *sessmedia;
GstRTSPMediaFactory *factory;