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.
21 * @short_description: Authentication and authorization
22 * @see_also: #GstRTSPPermissions, #GstRTSPToken
24 * The #GstRTSPAuth object is responsible for checking if the current user is
25 * allowed to perform requested actions. The default implementation has some
26 * reasonable checks but subclasses can implement custom security policies.
28 * A new auth object is made with gst_rtsp_auth_new(). It is usually configured
29 * on the #GstRTSPServer object.
31 * The RTSP server will call gst_rtsp_auth_check() with a string describing the
32 * check to perform. The possible checks are prefixed with
33 * GST_RTSP_AUTH_CHECK_*. Depending on the check, the default implementation
34 * will use the current #GstRTSPToken, #GstRTSPContext and
35 * #GstRTSPPermissions on the object to check if an operation is allowed.
37 * The default #GstRTSPAuth object has support for basic authentication. With
38 * gst_rtsp_auth_add_basic() you can add a basic authentication string together
39 * with the #GstRTSPToken that will become active when successfully
42 * When a TLS certificate has been set with gst_rtsp_auth_set_tls_certificate(),
43 * the default auth object will require the client to connect with a TLS
46 * Last reviewed on 2013-07-16 (1.0.0)
51 #include "rtsp-auth.h"
53 #define GST_RTSP_AUTH_GET_PRIVATE(obj) \
54 (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_RTSP_AUTH, GstRTSPAuthPrivate))
56 struct _GstRTSPAuthPrivate
60 /* the TLS certificate */
61 GTlsCertificate *certificate;
62 GTlsDatabase *database;
63 GTlsAuthenticationMode mode;
64 GHashTable *basic; /* protected by lock */
65 GHashTable *digest, *nonces; /* protected by lock */
66 guint64 last_nonce_check;
67 GstRTSPToken *default_token;
68 GstRTSPMethod methods;
69 GstRTSPAuthMethod auth_methods;
87 gst_rtsp_digest_entry_free (GstRTSPDigestEntry * entry)
89 gst_rtsp_token_unref (entry->token);
95 gst_rtsp_digest_nonce_free (GstRTSPDigestNonce * nonce)
97 g_free (nonce->nonce);
110 SIGNAL_ACCEPT_CERTIFICATE,
114 static guint signals[SIGNAL_LAST] = { 0 };
116 GST_DEBUG_CATEGORY_STATIC (rtsp_auth_debug);
117 #define GST_CAT_DEFAULT rtsp_auth_debug
119 static void gst_rtsp_auth_get_property (GObject * object, guint propid,
120 GValue * value, GParamSpec * pspec);
121 static void gst_rtsp_auth_set_property (GObject * object, guint propid,
122 const GValue * value, GParamSpec * pspec);
123 static void gst_rtsp_auth_finalize (GObject * obj);
125 static gboolean default_authenticate (GstRTSPAuth * auth, GstRTSPContext * ctx);
126 static gboolean default_check (GstRTSPAuth * auth, GstRTSPContext * ctx,
127 const gchar * check);
128 static void default_generate_authenticate_header (GstRTSPAuth * auth,
129 GstRTSPContext * ctx);
132 G_DEFINE_TYPE (GstRTSPAuth, gst_rtsp_auth, G_TYPE_OBJECT);
135 gst_rtsp_auth_class_init (GstRTSPAuthClass * klass)
137 GObjectClass *gobject_class;
139 g_type_class_add_private (klass, sizeof (GstRTSPAuthPrivate));
141 gobject_class = G_OBJECT_CLASS (klass);
143 gobject_class->get_property = gst_rtsp_auth_get_property;
144 gobject_class->set_property = gst_rtsp_auth_set_property;
145 gobject_class->finalize = gst_rtsp_auth_finalize;
147 klass->authenticate = default_authenticate;
148 klass->check = default_check;
149 klass->generate_authenticate_header = default_generate_authenticate_header;
151 GST_DEBUG_CATEGORY_INIT (rtsp_auth_debug, "rtspauth", 0, "GstRTSPAuth");
154 * GstRTSPAuth::accept-certificate:
155 * @auth: a #GstRTSPAuth
156 * @connection: a #GTlsConnection
157 * @peer_cert: the peer's #GTlsCertificate
158 * @errors: the problems with @peer_cert.
160 * Emitted during the TLS handshake after the client certificate has
161 * been received. See also gst_rtsp_auth_set_tls_authentication_mode().
163 * Returns: %TRUE to accept @peer_cert (which will also
164 * immediately end the signal emission). %FALSE to allow the signal
165 * emission to continue, which will cause the handshake to fail if
166 * no one else overrides it.
170 signals[SIGNAL_ACCEPT_CERTIFICATE] = g_signal_new ("accept-certificate",
171 G_TYPE_FROM_CLASS (gobject_class),
173 G_STRUCT_OFFSET (GstRTSPAuthClass, accept_certificate),
174 g_signal_accumulator_true_handled, NULL, g_cclosure_marshal_generic,
175 G_TYPE_BOOLEAN, 3, G_TYPE_TLS_CONNECTION, G_TYPE_TLS_CERTIFICATE,
176 G_TYPE_TLS_CERTIFICATE_FLAGS);
180 gst_rtsp_auth_init (GstRTSPAuth * auth)
182 GstRTSPAuthPrivate *priv;
184 auth->priv = priv = GST_RTSP_AUTH_GET_PRIVATE (auth);
186 g_mutex_init (&priv->lock);
188 priv->basic = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
189 (GDestroyNotify) gst_rtsp_token_unref);
190 priv->digest = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
191 (GDestroyNotify) gst_rtsp_digest_entry_free);
192 priv->nonces = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
193 (GDestroyNotify) gst_rtsp_digest_nonce_free);
195 /* bitwise or of all methods that need authentication */
197 priv->auth_methods = GST_RTSP_AUTH_BASIC;
201 gst_rtsp_auth_finalize (GObject * obj)
203 GstRTSPAuth *auth = GST_RTSP_AUTH (obj);
204 GstRTSPAuthPrivate *priv = auth->priv;
206 GST_INFO ("finalize auth %p", auth);
208 if (priv->certificate)
209 g_object_unref (priv->certificate);
211 g_object_unref (priv->database);
212 g_hash_table_unref (priv->basic);
213 g_hash_table_unref (priv->digest);
214 g_hash_table_unref (priv->nonces);
215 g_mutex_clear (&priv->lock);
217 G_OBJECT_CLASS (gst_rtsp_auth_parent_class)->finalize (obj);
221 gst_rtsp_auth_get_property (GObject * object, guint propid,
222 GValue * value, GParamSpec * pspec)
226 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
231 gst_rtsp_auth_set_property (GObject * object, guint propid,
232 const GValue * value, GParamSpec * pspec)
236 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, propid, pspec);
243 * Create a new #GstRTSPAuth instance.
245 * Returns: (transfer full): a new #GstRTSPAuth
248 gst_rtsp_auth_new (void)
252 result = g_object_new (GST_TYPE_RTSP_AUTH, NULL);
258 * gst_rtsp_auth_set_tls_certificate:
259 * @auth: a #GstRTSPAuth
260 * @cert: (transfer none) (allow-none): a #GTlsCertificate
262 * Set the TLS certificate for the auth. Client connections will only
263 * be accepted when TLS is negotiated.
266 gst_rtsp_auth_set_tls_certificate (GstRTSPAuth * auth, GTlsCertificate * cert)
268 GstRTSPAuthPrivate *priv;
269 GTlsCertificate *old;
271 g_return_if_fail (GST_IS_RTSP_AUTH (auth));
278 g_mutex_lock (&priv->lock);
279 old = priv->certificate;
280 priv->certificate = cert;
281 g_mutex_unlock (&priv->lock);
284 g_object_unref (old);
288 * gst_rtsp_auth_get_tls_certificate:
289 * @auth: a #GstRTSPAuth
291 * Get the #GTlsCertificate used for negotiating TLS @auth.
293 * Returns: (transfer full): the #GTlsCertificate of @auth. g_object_unref() after
297 gst_rtsp_auth_get_tls_certificate (GstRTSPAuth * auth)
299 GstRTSPAuthPrivate *priv;
300 GTlsCertificate *result;
302 g_return_val_if_fail (GST_IS_RTSP_AUTH (auth), NULL);
306 g_mutex_lock (&priv->lock);
307 if ((result = priv->certificate))
308 g_object_ref (result);
309 g_mutex_unlock (&priv->lock);
315 * gst_rtsp_auth_set_tls_database:
316 * @auth: a #GstRTSPAuth
317 * @database: (transfer none) (allow-none): a #GTlsDatabase
319 * Sets the certificate database that is used to verify peer certificates.
320 * If set to %NULL (the default), then peer certificate validation will always
321 * set the %G_TLS_CERTIFICATE_UNKNOWN_CA error.
326 gst_rtsp_auth_set_tls_database (GstRTSPAuth * auth, GTlsDatabase * database)
328 GstRTSPAuthPrivate *priv;
331 g_return_if_fail (GST_IS_RTSP_AUTH (auth));
336 g_object_ref (database);
338 g_mutex_lock (&priv->lock);
339 old = priv->database;
340 priv->database = database;
341 g_mutex_unlock (&priv->lock);
344 g_object_unref (old);
348 * gst_rtsp_auth_get_tls_database:
349 * @auth: a #GstRTSPAuth
351 * Get the #GTlsDatabase used for verifying client certificate.
353 * Returns: (transfer full): the #GTlsDatabase of @auth. g_object_unref() after
358 gst_rtsp_auth_get_tls_database (GstRTSPAuth * auth)
360 GstRTSPAuthPrivate *priv;
361 GTlsDatabase *result;
363 g_return_val_if_fail (GST_IS_RTSP_AUTH (auth), NULL);
367 g_mutex_lock (&priv->lock);
368 if ((result = priv->database))
369 g_object_ref (result);
370 g_mutex_unlock (&priv->lock);
376 * gst_rtsp_auth_set_tls_authentication_mode:
377 * @auth: a #GstRTSPAuth
378 * @mode: (transfer none) (allow-none): a #GTlsAuthenticationMode
380 * The #GTlsAuthenticationMode to set on the underlying GTlsServerConnection.
381 * When set to another value than %G_TLS_AUTHENTICATION_NONE,
382 * #GstRTSPAuth::accept-certificate signal will be emitted and must be handled.
387 gst_rtsp_auth_set_tls_authentication_mode (GstRTSPAuth * auth,
388 GTlsAuthenticationMode mode)
390 GstRTSPAuthPrivate *priv;
392 g_return_if_fail (GST_IS_RTSP_AUTH (auth));
396 g_mutex_lock (&priv->lock);
398 g_mutex_unlock (&priv->lock);
402 * gst_rtsp_auth_get_tls_authentication_mode:
403 * @auth: a #GstRTSPAuth
405 * Get the #GTlsAuthenticationMode.
407 * Returns: (transfer full): the #GTlsAuthenticationMode.
409 GTlsAuthenticationMode
410 gst_rtsp_auth_get_tls_authentication_mode (GstRTSPAuth * auth)
412 GstRTSPAuthPrivate *priv;
413 GTlsAuthenticationMode result;
415 g_return_val_if_fail (GST_IS_RTSP_AUTH (auth), G_TLS_AUTHENTICATION_NONE);
419 g_mutex_lock (&priv->lock);
421 g_mutex_unlock (&priv->lock);
427 * gst_rtsp_auth_set_default_token:
428 * @auth: a #GstRTSPAuth
429 * @token: (transfer none) (allow-none): a #GstRTSPToken
431 * Set the default #GstRTSPToken to @token in @auth. The default token will
432 * be used for unauthenticated users.
435 gst_rtsp_auth_set_default_token (GstRTSPAuth * auth, GstRTSPToken * token)
437 GstRTSPAuthPrivate *priv;
440 g_return_if_fail (GST_IS_RTSP_AUTH (auth));
445 gst_rtsp_token_ref (token);
447 g_mutex_lock (&priv->lock);
448 old = priv->default_token;
449 priv->default_token = token;
450 g_mutex_unlock (&priv->lock);
453 gst_rtsp_token_unref (old);
457 * gst_rtsp_auth_get_default_token:
458 * @auth: a #GstRTSPAuth
460 * Get the default token for @auth. This token will be used for unauthenticated
463 * Returns: (transfer full): the #GstRTSPToken of @auth. gst_rtsp_token_unref() after
467 gst_rtsp_auth_get_default_token (GstRTSPAuth * auth)
469 GstRTSPAuthPrivate *priv;
470 GstRTSPToken *result;
472 g_return_val_if_fail (GST_IS_RTSP_AUTH (auth), NULL);
476 g_mutex_lock (&priv->lock);
477 if ((result = priv->default_token))
478 gst_rtsp_token_ref (result);
479 g_mutex_unlock (&priv->lock);
485 * gst_rtsp_auth_add_basic:
486 * @auth: a #GstRTSPAuth
487 * @basic: the basic token
488 * @token: (transfer none): authorisation token
490 * Add a basic token for the default authentication algorithm that
491 * enables the client with privileges listed in @token.
494 gst_rtsp_auth_add_basic (GstRTSPAuth * auth, const gchar * basic,
495 GstRTSPToken * token)
497 GstRTSPAuthPrivate *priv;
499 g_return_if_fail (GST_IS_RTSP_AUTH (auth));
500 g_return_if_fail (basic != NULL);
501 g_return_if_fail (GST_IS_RTSP_TOKEN (token));
505 g_mutex_lock (&priv->lock);
506 g_hash_table_replace (priv->basic, g_strdup (basic),
507 gst_rtsp_token_ref (token));
508 g_mutex_unlock (&priv->lock);
512 * gst_rtsp_auth_remove_basic:
513 * @auth: a #GstRTSPAuth
514 * @basic: (transfer none): the basic token
516 * Removes @basic authentication token.
519 gst_rtsp_auth_remove_basic (GstRTSPAuth * auth, const gchar * basic)
521 GstRTSPAuthPrivate *priv;
523 g_return_if_fail (GST_IS_RTSP_AUTH (auth));
524 g_return_if_fail (basic != NULL);
528 g_mutex_lock (&priv->lock);
529 g_hash_table_remove (priv->basic, basic);
530 g_mutex_unlock (&priv->lock);
534 * gst_rtsp_auth_add_digest:
535 * @auth: a #GstRTSPAuth
536 * @user: the digest user name
537 * @pass: the digest password
538 * @token: (transfer none): authorisation token
540 * Add a digest @user and @pass for the default authentication algorithm that
541 * enables the client with privileges listed in @token.
546 gst_rtsp_auth_add_digest (GstRTSPAuth * auth, const gchar * user,
547 const gchar * pass, GstRTSPToken * token)
549 GstRTSPAuthPrivate *priv;
550 GstRTSPDigestEntry *entry;
552 g_return_if_fail (GST_IS_RTSP_AUTH (auth));
553 g_return_if_fail (user != NULL);
554 g_return_if_fail (pass != NULL);
555 g_return_if_fail (GST_IS_RTSP_TOKEN (token));
559 entry = g_new0 (GstRTSPDigestEntry, 1);
560 entry->token = gst_rtsp_token_ref (token);
561 entry->pass = g_strdup (pass);
563 g_mutex_lock (&priv->lock);
564 g_hash_table_replace (priv->digest, g_strdup (user), entry);
565 g_mutex_unlock (&priv->lock);
569 * gst_rtsp_auth_remove_digest:
570 * @auth: a #GstRTSPAuth
571 * @user: (transfer none): the digest user name
573 * Removes a digest user.
578 gst_rtsp_auth_remove_digest (GstRTSPAuth * auth, const gchar * user)
580 GstRTSPAuthPrivate *priv;
582 g_return_if_fail (GST_IS_RTSP_AUTH (auth));
583 g_return_if_fail (user != NULL);
587 g_mutex_lock (&priv->lock);
588 g_hash_table_remove (priv->digest, user);
589 g_mutex_unlock (&priv->lock);
593 * gst_rtsp_auth_set_supported_methods:
594 * @auth: a #GstRTSPAuth
595 * @methods: supported methods
597 * Sets the supported authentication @methods for @auth.
602 gst_rtsp_auth_set_supported_methods (GstRTSPAuth * auth,
603 GstRTSPAuthMethod methods)
605 GstRTSPAuthPrivate *priv;
607 g_return_if_fail (GST_IS_RTSP_AUTH (auth));
611 g_mutex_lock (&priv->lock);
612 priv->auth_methods = methods;
613 g_mutex_unlock (&priv->lock);
617 * gst_rtsp_auth_get_supported_methods:
618 * @auth: a #GstRTSPAuth
620 * Gets the supported authentication methods of @auth.
622 * Returns: The supported authentication methods
627 gst_rtsp_auth_get_supported_methods (GstRTSPAuth * auth)
629 GstRTSPAuthPrivate *priv;
630 GstRTSPAuthMethod methods;
632 g_return_val_if_fail (GST_IS_RTSP_AUTH (auth), 0);
636 g_mutex_lock (&priv->lock);
637 methods = priv->auth_methods;
638 g_mutex_unlock (&priv->lock);
646 GstRTSPDigestNonce *nonce;
650 remove_nonce (gpointer data, GObject * object)
652 RemoveNonceData *remove_nonce_data = data;
654 g_mutex_lock (&remove_nonce_data->auth->priv->lock);
655 g_hash_table_remove (remove_nonce_data->auth->priv->nonces,
656 remove_nonce_data->nonce->nonce);
657 g_mutex_unlock (&remove_nonce_data->auth->priv->lock);
659 g_object_unref (remove_nonce_data->auth);
660 g_free (remove_nonce_data);
664 default_digest_auth (GstRTSPAuth * auth, GstRTSPContext * ctx,
665 GstRTSPAuthParam ** param)
667 const gchar *realm = NULL, *user = NULL, *nonce = NULL;
668 const gchar *response = NULL, *uri = NULL;
669 GstRTSPDigestNonce *nonce_entry = NULL;
670 GstRTSPDigestEntry *digest_entry;
671 gchar *expected_response = NULL;
672 gboolean ret = FALSE;
674 GST_DEBUG_OBJECT (auth, "check Digest auth");
680 if (!realm && strcmp ((*param)->name, "realm") == 0 && (*param)->value)
681 realm = (*param)->value;
682 else if (!user && strcmp ((*param)->name, "username") == 0
684 user = (*param)->value;
685 else if (!nonce && strcmp ((*param)->name, "nonce") == 0 && (*param)->value)
686 nonce = (*param)->value;
687 else if (!response && strcmp ((*param)->name, "response") == 0
689 response = (*param)->value;
690 else if (!uri && strcmp ((*param)->name, "uri") == 0 && (*param)->value)
691 uri = (*param)->value;
696 if (!realm || !user || !nonce || !response || !uri)
699 g_mutex_lock (&auth->priv->lock);
700 digest_entry = g_hash_table_lookup (auth->priv->digest, user);
703 nonce_entry = g_hash_table_lookup (auth->priv->nonces, nonce);
707 if (strcmp (nonce_entry->ip, gst_rtsp_connection_get_ip (ctx->conn)) != 0)
709 if (nonce_entry->client && nonce_entry->client != ctx->client)
713 gst_rtsp_generate_digest_auth_response (NULL,
714 gst_rtsp_method_as_text (ctx->method), "GStreamer RTSP Server", user,
715 digest_entry->pass, uri, nonce);
716 if (!expected_response || strcmp (response, expected_response) != 0)
719 ctx->token = digest_entry->token;
723 if (nonce_entry && !nonce_entry->client) {
724 RemoveNonceData *remove_nonce_data = g_new (RemoveNonceData, 1);
726 nonce_entry->client = ctx->client;
727 remove_nonce_data->nonce = nonce_entry;
728 remove_nonce_data->auth = g_object_ref (auth);
729 g_object_weak_ref (G_OBJECT (ctx->client), remove_nonce, remove_nonce_data);
731 g_mutex_unlock (&auth->priv->lock);
733 g_free (expected_response);
739 default_authenticate (GstRTSPAuth * auth, GstRTSPContext * ctx)
741 GstRTSPAuthPrivate *priv = auth->priv;
742 GstRTSPAuthCredential **credentials, **credential;
744 GST_DEBUG_OBJECT (auth, "authenticate");
746 g_mutex_lock (&priv->lock);
747 /* FIXME, need to ref but we have no way to unref when the ctx is
749 ctx->token = priv->default_token;
750 g_mutex_unlock (&priv->lock);
753 gst_rtsp_message_parse_auth_credentials (ctx->request,
754 GST_RTSP_HDR_AUTHORIZATION);
759 credential = credentials;
760 while (*credential) {
761 if ((*credential)->scheme == GST_RTSP_AUTH_BASIC) {
764 GST_DEBUG_OBJECT (auth, "check Basic auth");
765 g_mutex_lock (&priv->lock);
767 g_hash_table_lookup (priv->basic,
768 (*credential)->authorization))) {
769 GST_DEBUG_OBJECT (auth, "setting token %p", token);
771 g_mutex_unlock (&priv->lock);
774 g_mutex_unlock (&priv->lock);
775 } else if ((*credential)->scheme == GST_RTSP_AUTH_DIGEST) {
776 if (default_digest_auth (auth, ctx, (*credential)->params))
783 gst_rtsp_auth_credentials_free (credentials);
788 GST_DEBUG_OBJECT (auth, "no authorization header found");
794 default_generate_authenticate_header (GstRTSPAuth * auth, GstRTSPContext * ctx)
796 if (auth->priv->auth_methods & GST_RTSP_AUTH_BASIC) {
797 gst_rtsp_message_add_header (ctx->response, GST_RTSP_HDR_WWW_AUTHENTICATE,
798 "Basic realm=\"GStreamer RTSP Server\"");
801 if (auth->priv->auth_methods & GST_RTSP_AUTH_DIGEST) {
802 GstRTSPDigestNonce *nonce;
803 gchar *nonce_value, *auth_header;
806 g_strdup_printf ("%08x%08x", g_random_int (), g_random_int ());
810 ("Digest realm=\"GStreamer RTSP Server\", nonce=\"%s\"", nonce_value);
811 gst_rtsp_message_add_header (ctx->response, GST_RTSP_HDR_WWW_AUTHENTICATE,
813 g_free (auth_header);
815 nonce = g_new0 (GstRTSPDigestNonce, 1);
816 nonce->nonce = g_strdup (nonce_value);
817 nonce->timestamp = g_get_monotonic_time ();
818 nonce->ip = g_strdup (gst_rtsp_connection_get_ip (ctx->conn));
819 g_mutex_lock (&auth->priv->lock);
820 g_hash_table_replace (auth->priv->nonces, nonce_value, nonce);
822 if (auth->priv->last_nonce_check == 0)
823 auth->priv->last_nonce_check = nonce->timestamp;
825 /* 30 second nonce timeout */
826 if (nonce->timestamp - auth->priv->last_nonce_check >= 30 * G_USEC_PER_SEC) {
830 g_hash_table_iter_init (&iter, auth->priv->nonces);
831 while (g_hash_table_iter_next (&iter, &key, &value)) {
832 GstRTSPDigestNonce *tmp = value;
834 if (nonce->timestamp - tmp->timestamp >= 30 * G_USEC_PER_SEC)
835 g_hash_table_iter_remove (&iter);
837 auth->priv->last_nonce_check = nonce->timestamp;
840 g_mutex_unlock (&auth->priv->lock);
845 send_response (GstRTSPAuth * auth, GstRTSPStatusCode code, GstRTSPContext * ctx)
847 gst_rtsp_message_init_response (ctx->response, code,
848 gst_rtsp_status_as_text (code), ctx->request);
850 if (code == GST_RTSP_STS_UNAUTHORIZED) {
851 GstRTSPAuthClass *klass;
853 klass = GST_RTSP_AUTH_GET_CLASS (auth);
855 if (klass->generate_authenticate_header)
856 klass->generate_authenticate_header (auth, ctx);
858 gst_rtsp_client_send_message (ctx->client, ctx->session, ctx->response);
862 ensure_authenticated (GstRTSPAuth * auth, GstRTSPContext * ctx)
864 GstRTSPAuthClass *klass;
866 klass = GST_RTSP_AUTH_GET_CLASS (auth);
868 /* we need a token to check */
869 if (ctx->token == NULL) {
870 if (klass->authenticate) {
871 if (!klass->authenticate (auth, ctx))
872 goto authenticate_failed;
875 if (ctx->token == NULL)
883 GST_DEBUG_OBJECT (auth, "authenticate failed");
884 send_response (auth, GST_RTSP_STS_UNAUTHORIZED, ctx);
889 GST_DEBUG_OBJECT (auth, "no authorization token found");
890 send_response (auth, GST_RTSP_STS_UNAUTHORIZED, ctx);
896 accept_certificate_cb (GTlsConnection * conn, GTlsCertificate * peer_cert,
897 GTlsCertificateFlags errors, GstRTSPAuth * auth)
899 gboolean ret = FALSE;
901 g_signal_emit (auth, signals[SIGNAL_ACCEPT_CERTIFICATE], 0,
902 conn, peer_cert, errors, &ret);
909 check_connect (GstRTSPAuth * auth, GstRTSPContext * ctx, const gchar * check)
911 GstRTSPAuthPrivate *priv = auth->priv;
914 /* configure the connection */
916 if (priv->certificate) {
917 tls = gst_rtsp_connection_get_tls (ctx->conn, NULL);
918 g_tls_connection_set_certificate (tls, priv->certificate);
921 if (priv->mode != G_TLS_AUTHENTICATION_NONE) {
922 tls = gst_rtsp_connection_get_tls (ctx->conn, NULL);
923 g_tls_connection_set_database (tls, priv->database);
924 g_object_set (tls, "authentication-mode", priv->mode, NULL);
925 g_signal_connect (tls, "accept-certificate",
926 G_CALLBACK (accept_certificate_cb), auth);
932 /* check url and methods */
934 check_url (GstRTSPAuth * auth, GstRTSPContext * ctx, const gchar * check)
936 GstRTSPAuthPrivate *priv = auth->priv;
938 if ((ctx->method & priv->methods) != 0)
939 if (!ensure_authenticated (auth, ctx))
940 goto not_authenticated;
951 /* check access to media factory */
953 check_factory (GstRTSPAuth * auth, GstRTSPContext * ctx, const gchar * check)
956 GstRTSPPermissions *perms;
958 if (!ensure_authenticated (auth, ctx))
961 if (!(role = gst_rtsp_token_get_string (ctx->token,
962 GST_RTSP_TOKEN_MEDIA_FACTORY_ROLE)))
964 if (!(perms = gst_rtsp_media_factory_get_permissions (ctx->factory)))
967 if (g_str_equal (check, GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_ACCESS)) {
968 if (!gst_rtsp_permissions_is_allowed (perms, role,
969 GST_RTSP_PERM_MEDIA_FACTORY_ACCESS))
971 } else if (g_str_equal (check, GST_RTSP_AUTH_CHECK_MEDIA_FACTORY_CONSTRUCT)) {
972 if (!gst_rtsp_permissions_is_allowed (perms, role,
973 GST_RTSP_PERM_MEDIA_FACTORY_CONSTRUCT))
977 gst_rtsp_permissions_unref (perms);
984 GST_DEBUG_OBJECT (auth, "no media factory role found");
985 send_response (auth, GST_RTSP_STS_UNAUTHORIZED, ctx);
990 GST_DEBUG_OBJECT (auth, "no permissions on media factory found");
991 send_response (auth, GST_RTSP_STS_UNAUTHORIZED, ctx);
996 GST_DEBUG_OBJECT (auth, "no permissions to access media factory");
997 gst_rtsp_permissions_unref (perms);
998 send_response (auth, GST_RTSP_STS_NOT_FOUND, ctx);
1003 GST_DEBUG_OBJECT (auth, "no permissions to construct media factory");
1004 gst_rtsp_permissions_unref (perms);
1005 send_response (auth, GST_RTSP_STS_UNAUTHORIZED, ctx);
1011 check_client_settings (GstRTSPAuth * auth, GstRTSPContext * ctx,
1012 const gchar * check)
1014 if (!ensure_authenticated (auth, ctx))
1017 return gst_rtsp_token_is_allowed (ctx->token,
1018 GST_RTSP_TOKEN_TRANSPORT_CLIENT_SETTINGS);
1022 default_check (GstRTSPAuth * auth, GstRTSPContext * ctx, const gchar * check)
1024 gboolean res = FALSE;
1026 /* FIXME, use hastable or so */
1027 if (g_str_equal (check, GST_RTSP_AUTH_CHECK_CONNECT)) {
1028 res = check_connect (auth, ctx, check);
1029 } else if (g_str_equal (check, GST_RTSP_AUTH_CHECK_URL)) {
1030 res = check_url (auth, ctx, check);
1031 } else if (g_str_has_prefix (check, "auth.check.media.factory.")) {
1032 res = check_factory (auth, ctx, check);
1033 } else if (g_str_equal (check, GST_RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS)) {
1034 res = check_client_settings (auth, ctx, check);
1040 no_auth_check (const gchar * check)
1044 if (g_str_equal (check, GST_RTSP_AUTH_CHECK_TRANSPORT_CLIENT_SETTINGS))
1053 * gst_rtsp_auth_check:
1054 * @check: the item to check
1056 * Check if @check is allowed in the current context.
1058 * Returns: FALSE if check failed.
1061 gst_rtsp_auth_check (const gchar * check)
1063 gboolean result = FALSE;
1064 GstRTSPAuthClass *klass;
1065 GstRTSPContext *ctx;
1068 g_return_val_if_fail (check != NULL, FALSE);
1070 if (!(ctx = gst_rtsp_context_get_current ()))
1073 /* no auth, we don't need to check */
1074 if (!(auth = ctx->auth))
1075 return no_auth_check (check);
1077 klass = GST_RTSP_AUTH_GET_CLASS (auth);
1079 GST_DEBUG_OBJECT (auth, "check authorization '%s'", check);
1082 result = klass->check (auth, ctx, check);
1089 GST_ERROR ("no context found");
1095 * gst_rtsp_auth_make_basic:
1099 * Construct a Basic authorisation token from @user and @pass.
1101 * Returns: (transfer full): the base64 encoding of the string @user:@pass.
1102 * g_free() after usage.
1105 gst_rtsp_auth_make_basic (const gchar * user, const gchar * pass)
1110 g_return_val_if_fail (user != NULL, NULL);
1111 g_return_val_if_fail (pass != NULL, NULL);
1113 user_pass = g_strjoin (":", user, pass, NULL);
1114 result = g_base64_encode ((guchar *) user_pass, strlen (user_pass));