test-sdp
test-video
test-uri
+test-auth
-noinst_PROGRAMS = test-video test-ogg test-mp4 test-readme test-launch test-sdp test-uri
+noinst_PROGRAMS = test-video test-ogg test-mp4 test-readme test-launch test-sdp test-uri test-auth
INCLUDES = -I$(top_srcdir) -I$(srcdir)
--- /dev/null
+/* GStreamer
+ * Copyright (C) 2008 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 <gst/gst.h>
+
+#include <gst/rtsp-server/rtsp-server.h>
+
+
+static gboolean
+timeout (GstRTSPServer * server, gboolean ignored)
+{
+ GstRTSPSessionPool *pool;
+
+ pool = gst_rtsp_server_get_session_pool (server);
+ gst_rtsp_session_pool_cleanup (pool);
+ g_object_unref (pool);
+
+ return TRUE;
+}
+
+int
+main (int argc, char *argv[])
+{
+ GMainLoop *loop;
+ GstRTSPServer *server;
+ GstRTSPMediaMapping *mapping;
+ GstRTSPMediaFactory *factory;
+ GstRTSPAuth *auth;
+ gchar *basic;
+
+ gst_init (&argc, &argv);
+
+ loop = g_main_loop_new (NULL, FALSE);
+
+ /* create a server instance */
+ server = gst_rtsp_server_new ();
+
+ /* get the mapping for this server, every server has a default mapper object
+ * that be used to map uri mount points to media factories */
+ mapping = gst_rtsp_server_get_media_mapping (server);
+
+
+ /* make a media factory for a test stream. The default media factory can use
+ * gst-launch syntax to create pipelines.
+ * any launch line works as long as it contains elements named pay%d. Each
+ * element with pay%d names will be a stream */
+ factory = gst_rtsp_media_factory_new ();
+ gst_rtsp_media_factory_set_launch (factory, "( "
+ "videotestsrc ! video/x-raw-yuv,width=352,height=288,framerate=15/1 ! "
+ "x264enc ! rtph264pay name=pay0 pt=96 "
+ "audiotestsrc ! audio/x-raw-int,rate=8000 ! "
+ "alawenc ! rtppcmapay name=pay1 pt=97 " ")");
+
+ /* make a new authentication manager */
+ auth = gst_rtsp_auth_new ();
+ basic = gst_rtsp_auth_make_basic ("user", "admin");
+ gst_rtsp_auth_set_basic (auth, basic);
+ g_free (basic);
+ gst_rtsp_media_factory_set_auth (factory, auth);
+ g_object_unref (auth);
+ /* attach the test factory to the /test url */
+ gst_rtsp_media_mapping_add_factory (mapping, "/test", factory);
+
+ /* make another factory */
+ factory = gst_rtsp_media_factory_new ();
+ gst_rtsp_media_factory_set_launch (factory, "( "
+ "videotestsrc ! video/x-raw-yuv,width=352,height=288,framerate=30/1 ! "
+ "x264enc ! rtph264pay name=pay0 pt=96 )");
+ /* make a new authentication manager */
+ auth = gst_rtsp_auth_new ();
+ basic = gst_rtsp_auth_make_basic ("user2", "admin2");
+ gst_rtsp_auth_set_basic (auth, basic);
+ g_free (basic);
+ gst_rtsp_media_factory_set_auth (factory, auth);
+ g_object_unref (auth);
+ /* attach the test factory to the /test url */
+ gst_rtsp_media_mapping_add_factory (mapping, "/test2", factory);
+
+ /* don't need the ref to the mapper anymore */
+ g_object_unref (mapping);
+
+ /* attach the server to the default maincontext */
+ if (gst_rtsp_server_attach (server, NULL) == 0)
+ goto failed;
+
+ g_timeout_add_seconds (2, (GSourceFunc) timeout, server);
+
+ /* start serving */
+ g_main_loop_run (loop);
+
+ return 0;
+
+ /* ERRORS */
+failed:
+ {
+ g_print ("failed to attach the server\n");
+ return -1;
+ }
+}
GstRTSPServer *server;
GstRTSPMediaMapping *mapping;
GstRTSPMediaFactory *factory;
+#if 0
GstRTSPAuth *auth;
gchar *basic;
+#endif
gst_init (&argc, &argv);
* that be used to map uri mount points to media factories */
mapping = gst_rtsp_server_get_media_mapping (server);
+#if 0
/* make a new authentication manager */
auth = gst_rtsp_auth_new ();
basic = gst_rtsp_auth_make_basic ("user", "admin");
g_free (basic);
/* configure in the server */
gst_rtsp_server_set_auth (server, auth);
+#endif
/* make a media factory for a test stream. The default media factory can use
* gst-launch syntax to create pipelines.
static void gst_rtsp_auth_finalize (GObject * obj);
static gboolean default_setup_auth (GstRTSPAuth * auth, GstRTSPClient * client,
- GstRTSPClientState * state);
+ GQuark hint, GstRTSPClientState * state);
static gboolean default_check_method (GstRTSPAuth * auth,
- GstRTSPClient * client, GstRTSPClientState * state);
+ GstRTSPClient * client, GQuark hint, GstRTSPClientState * state);
G_DEFINE_TYPE (GstRTSPAuth, gst_rtsp_auth, G_TYPE_OBJECT);
static gboolean
default_setup_auth (GstRTSPAuth * auth, GstRTSPClient * client,
- GstRTSPClientState * state)
+ GQuark hint, GstRTSPClientState * state)
{
if (state->response == NULL)
return FALSE;
*/
gboolean
gst_rtsp_auth_setup_auth (GstRTSPAuth * auth, GstRTSPClient * client,
- GstRTSPClientState * state)
+ GQuark hint, GstRTSPClientState * state)
{
gboolean result = FALSE;
GstRTSPAuthClass *klass;
GST_DEBUG_OBJECT (auth, "setup auth");
if (klass->setup_auth)
- result = klass->setup_auth (auth, client, state);
+ result = klass->setup_auth (auth, client, hint, state);
return result;
}
static gboolean
default_check_method (GstRTSPAuth * auth, GstRTSPClient * client,
- GstRTSPClientState * state)
+ GQuark hint, GstRTSPClientState * state)
{
gboolean result = TRUE;
GstRTSPResult res;
* gst_rtsp_auth_check_method:
* @auth: a #GstRTSPAuth
* @client: the client
+ * @hint: a hint
* @state: client state
*
* Check if @client is allowed to perform the actions of @state.
*/
gboolean
gst_rtsp_auth_check (GstRTSPAuth * auth, GstRTSPClient * client,
- GstRTSPClientState * state)
+ GQuark hint, GstRTSPClientState * state)
{
gboolean result = FALSE;
GstRTSPAuthClass *klass;
GST_DEBUG_OBJECT (auth, "check state");
if (klass->check_method)
- result = klass->check_method (auth, client, state);
+ result = klass->check_method (auth, client, hint, state);
return result;
}
struct _GstRTSPAuthClass {
GObjectClass parent_class;
- gboolean (*setup_auth) (GstRTSPAuth *auth, GstRTSPClient * client, GstRTSPClientState *state);
- gboolean (*check_method) (GstRTSPAuth *auth, GstRTSPClient * client, GstRTSPClientState *state);
+ gboolean (*setup_auth) (GstRTSPAuth *auth, GstRTSPClient * client,
+ GQuark hint, GstRTSPClientState *state);
+ gboolean (*check_method) (GstRTSPAuth *auth, GstRTSPClient * client,
+ GQuark hint, GstRTSPClientState *state);
};
GType gst_rtsp_auth_get_type (void);
void gst_rtsp_auth_set_basic (GstRTSPAuth *auth, const gchar * basic);
gboolean gst_rtsp_auth_setup_auth (GstRTSPAuth *auth, GstRTSPClient * client,
- GstRTSPClientState *state);
+ GQuark hint, GstRTSPClientState *state);
gboolean gst_rtsp_auth_check_method (GstRTSPAuth *auth, GstRTSPClient * client,
- GstRTSPClientState *state);
+ GQuark hint, GstRTSPClientState *state);
/* helpers */
gchar * gst_rtsp_auth_make_basic (const gchar * user, const gchar * pass);
}
static void
-handle_unauthorized_request (GstRTSPClient * client, GstRTSPClientState * state)
+handle_unauthorized_request (GstRTSPClient * client, GstRTSPAuth * auth,
+ GstRTSPClientState * state)
{
GstRTSPMessage response = { 0 };
state->response = &response;
- if (client->auth) {
+ if (auth) {
/* and let the authentication manager setup the auth tokens */
- gst_rtsp_auth_setup_auth (client->auth, client, state);
+ gst_rtsp_auth_setup_auth (auth, client, 0, state);
}
send_response (client, state->session, &response);
{
GstRTSPMediaFactory *factory;
GstRTSPMedia *media;
+ GstRTSPAuth *auth;
if (!compare_uri (client->uri, state->uri)) {
/* remove any previously cached values before we try to construct a new
state->factory = factory;
+ /* check if we have access to the factory */
+ if ((auth = gst_rtsp_media_factory_get_auth (factory))) {
+ if (!gst_rtsp_auth_check (auth, client, 0, state))
+ goto not_allowed;
+
+ g_object_unref (auth);
+ }
+
/* prepare the media and add it to the pipeline */
if (!(media = gst_rtsp_media_factory_construct (factory, state->uri)))
goto no_media;
+ g_object_unref (factory);
+
/* set ipv6 on the media before preparing */
media->is_ipv6 = client->is_ipv6;
state->media = media;
send_generic_response (client, GST_RTSP_STS_NOT_FOUND, state);
return NULL;
}
+not_allowed:
+ {
+ handle_unauthorized_request (client, auth, state);
+ g_object_unref (factory);
+ g_object_unref (auth);
+ return NULL;
+ }
no_media:
{
send_generic_response (client, GST_RTSP_STS_SERVICE_UNAVAILABLE, state);
}
not_authorized:
{
- handle_unauthorized_request (client, &state);
+ handle_unauthorized_request (client, client->auth, &state);
return;
}
}
}
}
-
/**
* gst_rtsp_media_factory_get_auth:
* @factory: a #GstRTSPMediaFactory
* usage.
*/
GstRTSPAuth *
-gst_rtsp_factory_get_auth (GstRTSPMediaFactory * factory)
+gst_rtsp_media_factory_get_auth (GstRTSPMediaFactory * factory)
{
GstRTSPAuth *result;
return result;
}
-
static gboolean
compare_media (gpointer key, GstRTSPMedia * media1, GstRTSPMedia * media2)
{
default_configure (GstRTSPMediaFactory * factory, GstRTSPMedia * media)
{
gboolean shared, eos_shutdown;
+ GstRTSPAuth *auth;
/* configure the sharedness */
GST_RTSP_MEDIA_FACTORY_LOCK (factory);
gst_rtsp_media_set_shared (media, shared);
gst_rtsp_media_set_eos_shutdown (media, eos_shutdown);
+
+ if ((auth = gst_rtsp_media_factory_get_auth (factory))) {
+ gst_rtsp_media_set_auth (media, auth);
+ g_object_unref (auth);
+ }
}
}
/**
+ * gst_rtsp_media_set_auth:
+ * @media: a #GstRTSPMedia
+ * @auth: a #GstRTSPAuth
+ *
+ * configure @auth to be used as the authentication manager of @media.
+ */
+void
+gst_rtsp_media_set_auth (GstRTSPMedia * media, GstRTSPAuth * auth)
+{
+ GstRTSPAuth *old;
+
+ g_return_if_fail (GST_IS_RTSP_MEDIA (media));
+
+ old = media->auth;
+
+ if (old != auth) {
+ if (auth)
+ g_object_ref (auth);
+ media->auth = auth;
+ if (old)
+ g_object_unref (old);
+ }
+}
+
+/**
+ * gst_rtsp_media_get_auth:
+ * @media: a #GstRTSPMedia
+ *
+ * Get the #GstRTSPAuth used as the authentication manager of @media.
+ *
+ * Returns: the #GstRTSPAuth of @media. g_object_unref() after
+ * usage.
+ */
+GstRTSPAuth *
+gst_rtsp_media_get_auth (GstRTSPMedia * media)
+{
+ GstRTSPAuth *result;
+
+ g_return_val_if_fail (GST_IS_RTSP_MEDIA (media), NULL);
+
+ if ((result = media->auth))
+ g_object_ref (result);
+
+ return result;
+}
+
+
+/**
* gst_rtsp_media_n_streams:
* @media: a #GstRTSPMedia
*
GObject *rtpsource;
};
+#include "rtsp-auth.h"
+
/**
* GstRTSPMediaStream:
* @srcpad: the srcpad of the stream
gboolean reused;
gboolean is_ipv6;
gboolean eos_shutdown;
+ GstRTSPAuth *auth;
GstElement *element;
GArray *streams;
void gst_rtsp_media_set_eos_shutdown (GstRTSPMedia *media, gboolean eos_shutdown);
gboolean gst_rtsp_media_is_eos_shutdown (GstRTSPMedia *media);
+void gst_rtsp_media_set_auth (GstRTSPMedia *media, GstRTSPAuth *auth);
+GstRTSPAuth * gst_rtsp_media_get_auth (GstRTSPMedia *media);
+
/* prepare the media for playback */
gboolean gst_rtsp_media_prepare (GstRTSPMedia *media);
gboolean gst_rtsp_media_is_prepared (GstRTSPMedia *media);
#ifndef __GST_RTSP_SESSION_POOL_H__
#define __GST_RTSP_SESSION_POOL_H__
-#include "rtsp-session.h"
G_BEGIN_DECLS
+typedef struct _GstRTSPSessionPool GstRTSPSessionPool;
+typedef struct _GstRTSPSessionPoolClass GstRTSPSessionPoolClass;
+
+#include "rtsp-session.h"
+
#define GST_TYPE_RTSP_SESSION_POOL (gst_rtsp_session_pool_get_type ())
#define GST_IS_RTSP_SESSION_POOL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_RTSP_SESSION_POOL))
#define GST_IS_RTSP_SESSION_POOL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_RTSP_SESSION_POOL))
#define GST_RTSP_SESSION_POOL_CAST(obj) ((GstRTSPSessionPool*)(obj))
#define GST_RTSP_SESSION_POOL_CLASS_CAST(klass) ((GstRTSPSessionPoolClass*)(klass))
-typedef struct _GstRTSPSessionPool GstRTSPSessionPool;
-typedef struct _GstRTSPSessionPoolClass GstRTSPSessionPoolClass;
-
/**
* GstRTSPSessionPool:
* @max_sessions: the maximum number of sessions.
#include <gst/rtsp/gstrtsptransport.h>
-#include "rtsp-media.h"
-
#ifndef __GST_RTSP_SESSION_H__
#define __GST_RTSP_SESSION_H__
typedef struct _GstRTSPSessionStream GstRTSPSessionStream;
typedef struct _GstRTSPSessionMedia GstRTSPSessionMedia;
+#include "rtsp-media.h"
+
/**
* GstRTSPSessionStream:
* @trans: the media transport