summaryrefslogtreecommitdiff
path: root/gst/rtsp-server/rtsp-auth.c
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@collabora.co.uk>2011-01-12 00:17:54 +0100
committerWim Taymans <wim.taymans@gmail.com>2011-01-12 00:22:27 +0100
commit5fb5f750208c7f35422a7fc3405fdb9b35b86fdc (patch)
treed9f92a72f3aefd9c59fdf2615d1b78eb968a44ce /gst/rtsp-server/rtsp-auth.c
parent61bee9985a228428f6cf9b14f4ae8d009bd1f153 (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.c220
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;
+}