diff options
author | Wim Taymans <wim.taymans@collabora.co.uk> | 2011-01-12 00:17:54 +0100 |
---|---|---|
committer | Wim Taymans <wim.taymans@gmail.com> | 2011-01-12 00:22:27 +0100 |
commit | 5fb5f750208c7f35422a7fc3405fdb9b35b86fdc (patch) | |
tree | d9f92a72f3aefd9c59fdf2615d1b78eb968a44ce /gst/rtsp-server/rtsp-auth.c | |
parent | 61bee9985a228428f6cf9b14f4ae8d009bd1f153 (diff) |
auth: add authentication object
Add an object that can check the authorization of requests.
Implement basic authentication.
Add example authentication to test-video
Diffstat (limited to 'gst/rtsp-server/rtsp-auth.c')
-rw-r--r-- | gst/rtsp-server/rtsp-auth.c | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/gst/rtsp-server/rtsp-auth.c b/gst/rtsp-server/rtsp-auth.c new file mode 100644 index 0000000..ff83c1b --- /dev/null +++ b/gst/rtsp-server/rtsp-auth.c @@ -0,0 +1,220 @@ +/* GStreamer + * Copyright (C) 2010 Wim Taymans <wim.taymans at gmail.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include <string.h> + +#include "rtsp-auth.h" + +enum +{ + PROP_0, + PROP_LAST +}; + +GST_DEBUG_CATEGORY_STATIC (rtsp_auth_debug); +#define GST_CAT_DEFAULT rtsp_auth_debug + +static void gst_rtsp_auth_get_property (GObject * object, guint propid, + GValue * value, GParamSpec * pspec); +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_check_method (GstRTSPAuth * auth, GstRTSPMethod method, + GstRTSPClient * client, GstRTSPUrl * uri, GstRTSPSession * session, + GstRTSPMessage * request); + +G_DEFINE_TYPE (GstRTSPAuth, gst_rtsp_auth, G_TYPE_OBJECT); + +static void +gst_rtsp_auth_class_init (GstRTSPAuthClass * klass) +{ + GObjectClass *gobject_class; + + gobject_class = G_OBJECT_CLASS (klass); + + gobject_class->get_property = gst_rtsp_auth_get_property; + gobject_class->set_property = gst_rtsp_auth_set_property; + gobject_class->finalize = gst_rtsp_auth_finalize; + + klass->check_method = default_check_method; + + GST_DEBUG_CATEGORY_INIT (rtsp_auth_debug, "rtspauth", 0, "GstRTSPAuth"); +} + +static void +gst_rtsp_auth_init (GstRTSPAuth * auth) +{ + /* bitwise or of all methods that need authentication */ + auth->methods = GST_RTSP_DESCRIBE | + GST_RTSP_ANNOUNCE | + GST_RTSP_GET_PARAMETER | + GST_RTSP_SET_PARAMETER | + GST_RTSP_PAUSE | + GST_RTSP_PLAY | GST_RTSP_RECORD | GST_RTSP_SETUP | GST_RTSP_TEARDOWN; +} + +static void +gst_rtsp_auth_finalize (GObject * obj) +{ + GstRTSPAuth *auth = GST_RTSP_AUTH (obj); + + GST_INFO ("finalize auth %p", auth); + + G_OBJECT_CLASS (gst_rtsp_auth_parent_class)->finalize (obj); +} + +static void +gst_rtsp_auth_get_property (GObject * object, guint propid, + GValue * value, GParamSpec * pspec) +{ + GstRTSPAuth *auth = GST_RTSP_AUTH (object); + + switch (propid) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); + } +} + +static void +gst_rtsp_auth_set_property (GObject * object, guint propid, + const GValue * value, GParamSpec * pspec) +{ + GstRTSPAuth *auth = GST_RTSP_AUTH (object); + + switch (propid) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec); + } +} + +/** + * gst_rtsp_auth_new: + * + * Create a new #GstRTSPAuth instance. + * + * Returns: a new #GstRTSPAuth + */ +GstRTSPAuth * +gst_rtsp_auth_new (void) +{ + GstRTSPAuth *result; + + result = g_object_new (GST_TYPE_RTSP_AUTH, NULL); + + return result; +} + +/** + * gst_rtsp_auth_set_basic: + * @auth: a #GstRTSPAuth + * @basic: the basic token + * + * Set the basic token for the default authentication algorithm. + */ +void +gst_rtsp_auth_set_basic (GstRTSPAuth * auth, const gchar * basic) +{ + g_free (auth->basic); + auth->basic = g_strdup (basic); +} + +static gboolean +default_check_method (GstRTSPAuth * auth, GstRTSPMethod method, + GstRTSPClient * client, GstRTSPUrl * uri, GstRTSPSession * session, + GstRTSPMessage * request) +{ + gboolean result = TRUE; + GstRTSPResult res; + + if (method & auth->methods != 0) { + gchar *authorization; + + result = FALSE; + + res = + gst_rtsp_message_get_header (request, GST_RTSP_HDR_AUTHORIZATION, + &authorization, 0); + if (res < 0) + goto no_auth; + + /* parse type */ + if (g_ascii_strncasecmp (authorization, "basic ", 6) == 0) { + GST_DEBUG_OBJECT (auth, "check Basic auth"); + if (auth->basic && strcmp (&authorization[6], auth->basic) == 0) + result = TRUE; + } else if (g_ascii_strncasecmp (authorization, "digest ", 7) == 0) { + GST_DEBUG_OBJECT (auth, "check Digest auth"); + /* not implemented yet */ + result = FALSE; + } + } + return result; + +no_auth: + { + GST_DEBUG_OBJECT (auth, "no authorization header found"); + return FALSE; + } +} + +/** + * gst_rtsp_auth_check_method: + * @auth: a #GstRTSPAuth + * @method: method to check + * @client: the client + * @uri: the requested uri + * @session: the session + * @request: the request + * + * Check if @client is allowed to perform @method for the @uri in + * @session and with @request. + * + * Returns: FALSE if the method is not allowed. + */ +gboolean +gst_rtsp_auth_check_method (GstRTSPAuth * auth, GstRTSPMethod method, + GstRTSPClient * client, GstRTSPUrl * uri, GstRTSPSession * session, + GstRTSPMessage * request) +{ + gboolean result = FALSE; + GstRTSPAuthClass *klass; + + klass = GST_RTSP_AUTH_GET_CLASS (auth); + + GST_DEBUG_OBJECT (auth, "check method %d", method); + + if (klass->check_method) + result = klass->check_method (auth, method, client, uri, session, request); + + return result; +} + +gchar * +gst_rtsp_auth_make_basic (const gchar * user, const gchar * pass) +{ + gchar *user_pass; + gchar *result; + + user_pass = g_strjoin (":", user, pass, NULL); + result = g_base64_encode ((guchar *) user_pass, strlen (user_pass)); + g_free (user_pass); + + return result; +} |