2 * Copyright (C) 2010 Wim Taymans <wim.taymans at gmail.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
22 #include "rtsp-auth.h"
30 GST_DEBUG_CATEGORY_STATIC (rtsp_auth_debug);
31 #define GST_CAT_DEFAULT rtsp_auth_debug
33 static void gst_rtsp_auth_get_property (GObject * object, guint propid,
34 GValue * value, GParamSpec * pspec);
35 static void gst_rtsp_auth_set_property (GObject * object, guint propid,
36 const GValue * value, GParamSpec * pspec);
37 static void gst_rtsp_auth_finalize (GObject * obj);
39 static gboolean default_setup_auth (GstRTSPAuth * auth, GstRTSPClient * client,
40 GQuark hint, GstRTSPClientState * state);
41 static gboolean default_check_method (GstRTSPAuth * auth,
42 GstRTSPClient * client, GQuark hint, GstRTSPClientState * state);
44 G_DEFINE_TYPE (GstRTSPAuth, gst_rtsp_auth, G_TYPE_OBJECT);
47 gst_rtsp_auth_class_init (GstRTSPAuthClass * klass)
49 GObjectClass *gobject_class;
51 gobject_class = G_OBJECT_CLASS (klass);
53 gobject_class->get_property = gst_rtsp_auth_get_property;
54 gobject_class->set_property = gst_rtsp_auth_set_property;
55 gobject_class->finalize = gst_rtsp_auth_finalize;
57 klass->setup_auth = default_setup_auth;
58 klass->check_method = default_check_method;
60 GST_DEBUG_CATEGORY_INIT (rtsp_auth_debug, "rtspauth", 0, "GstRTSPAuth");
64 gst_rtsp_auth_init (GstRTSPAuth * auth)
66 g_mutex_init (&auth->lock);
67 /* bitwise or of all methods that need authentication */
68 auth->methods = GST_RTSP_DESCRIBE |
70 GST_RTSP_GET_PARAMETER |
71 GST_RTSP_SET_PARAMETER |
73 GST_RTSP_PLAY | GST_RTSP_RECORD | GST_RTSP_SETUP | GST_RTSP_TEARDOWN;
77 gst_rtsp_auth_finalize (GObject * obj)
79 GstRTSPAuth *auth = GST_RTSP_AUTH (obj);
81 GST_INFO ("finalize auth %p", auth);
83 g_mutex_clear (&auth->lock);
85 G_OBJECT_CLASS (gst_rtsp_auth_parent_class)->finalize (obj);
89 gst_rtsp_auth_get_property (GObject * object, guint propid,
90 GValue * value, GParamSpec * pspec)
94 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
99 gst_rtsp_auth_set_property (GObject * object, guint propid,
100 const GValue * value, GParamSpec * pspec)
104 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
111 * Create a new #GstRTSPAuth instance.
113 * Returns: a new #GstRTSPAuth
116 gst_rtsp_auth_new (void)
120 result = g_object_new (GST_TYPE_RTSP_AUTH, NULL);
126 * gst_rtsp_auth_set_basic:
127 * @auth: a #GstRTSPAuth
128 * @basic: the basic token
130 * Set the basic token for the default authentication algorithm.
133 gst_rtsp_auth_set_basic (GstRTSPAuth * auth, const gchar * basic)
135 g_return_if_fail (GST_IS_RTSP_AUTH (auth));
137 g_mutex_lock (&auth->lock);
138 g_free (auth->basic);
139 auth->basic = g_strdup (basic);
140 g_mutex_unlock (&auth->lock);
144 default_setup_auth (GstRTSPAuth * auth, GstRTSPClient * client,
145 GQuark hint, GstRTSPClientState * state)
147 if (state->response == NULL)
150 /* we only have Basic for now */
151 gst_rtsp_message_add_header (state->response, GST_RTSP_HDR_WWW_AUTHENTICATE,
152 "Basic realm=\"GStreamer RTSP Server\"");
158 * gst_rtsp_auth_setup_auth:
159 * @auth: a #GstRTSPAuth
160 * @client: the client
164 * Add authentication tokens to @response.
166 * Returns: FALSE if something is wrong.
169 gst_rtsp_auth_setup_auth (GstRTSPAuth * auth, GstRTSPClient * client,
170 GQuark hint, GstRTSPClientState * state)
172 gboolean result = FALSE;
173 GstRTSPAuthClass *klass;
175 g_return_val_if_fail (GST_IS_RTSP_AUTH (auth), FALSE);
176 g_return_val_if_fail (GST_IS_RTSP_CLIENT (client), FALSE);
177 g_return_val_if_fail (state != NULL, FALSE);
179 klass = GST_RTSP_AUTH_GET_CLASS (auth);
181 GST_DEBUG_OBJECT (auth, "setup auth");
183 if (klass->setup_auth)
184 result = klass->setup_auth (auth, client, hint, state);
190 default_check_method (GstRTSPAuth * auth, GstRTSPClient * client,
191 GQuark hint, GstRTSPClientState * state)
193 gboolean result = TRUE;
196 if ((state->method & auth->methods) != 0) {
197 gchar *authorization;
202 gst_rtsp_message_get_header (state->request, GST_RTSP_HDR_AUTHORIZATION,
208 if (g_ascii_strncasecmp (authorization, "basic ", 6) == 0) {
209 GST_DEBUG_OBJECT (auth, "check Basic auth");
210 g_mutex_lock (&auth->lock);
211 if (auth->basic && strcmp (&authorization[6], auth->basic) == 0)
213 g_mutex_unlock (&auth->lock);
214 } else if (g_ascii_strncasecmp (authorization, "digest ", 7) == 0) {
215 GST_DEBUG_OBJECT (auth, "check Digest auth");
216 /* not implemented yet */
224 GST_DEBUG_OBJECT (auth, "no authorization header found");
230 * gst_rtsp_auth_check:
231 * @auth: a #GstRTSPAuth
232 * @client: the client
234 * @state: client state
236 * Check if @client is allowed to perform the actions of @state.
238 * Returns: FALSE if the action is not allowed.
241 gst_rtsp_auth_check (GstRTSPAuth * auth, GstRTSPClient * client,
242 GQuark hint, GstRTSPClientState * state)
244 gboolean result = FALSE;
245 GstRTSPAuthClass *klass;
247 g_return_val_if_fail (GST_IS_RTSP_AUTH (auth), FALSE);
248 g_return_val_if_fail (GST_IS_RTSP_CLIENT (client), FALSE);
249 g_return_val_if_fail (state != NULL, FALSE);
251 klass = GST_RTSP_AUTH_GET_CLASS (auth);
253 GST_DEBUG_OBJECT (auth, "check state");
255 if (klass->check_method)
256 result = klass->check_method (auth, client, hint, state);
262 * gst_rtsp_auth_make_basic:
266 * Construct a Basic authorisation token from @user and @pass.
268 * Returns: the base64 encoding of the string @user:@pass. g_free()
272 gst_rtsp_auth_make_basic (const gchar * user, const gchar * pass)
277 g_return_val_if_fail (user != NULL, NULL);
278 g_return_val_if_fail (pass != NULL, NULL);
280 user_pass = g_strjoin (":", user, pass, NULL);
281 result = g_base64_encode ((guchar *) user_pass, strlen (user_pass));