[xiph-commits] r9714 - in icecast/trunk/icecast: . src
karl at svn.xiph.org
karl at svn.xiph.org
Sun Aug 7 16:29:16 PDT 2005
Author: karl
Date: 2005-08-07 16:29:12 -0700 (Sun, 07 Aug 2005)
New Revision: 9714
Added:
icecast/trunk/icecast/src/auth_url.c
icecast/trunk/icecast/src/auth_url.h
Modified:
icecast/trunk/icecast/configure.in
icecast/trunk/icecast/src/Makefile.am
icecast/trunk/icecast/src/auth.c
Log:
merge URL listener auth
Modified: icecast/trunk/icecast/configure.in
===================================================================
--- icecast/trunk/icecast/configure.in 2005-08-07 23:01:04 UTC (rev 9713)
+++ icecast/trunk/icecast/configure.in 2005-08-07 23:29:12 UTC (rev 9714)
@@ -106,24 +106,27 @@
XIPH_VAR_APPEND([XIPH_CPPFLAGS],[$PTHREAD_CPPFLAGS])
XIPH_VAR_PREPEND([XIPH_LIBS],[$PTHREAD_LIBS])
-dnl -- YP support --
-AC_ARG_ENABLE([yp],
- AC_HELP_STRING([--disable-yp],[disable YP directory support]),
- enable_yp="$enableval",
- enable_yp="yes")
-if test "x$enable_yp" = "xyes"
-then
XIPH_PATH_CURL([
AC_CHECK_DECL([CURLOPT_NOSIGNAL],
- [ AC_DEFINE([USE_YP], 1, [Define to compile in YP support code])
- ICECAST_OPTIONAL="$ICECAST_OPTIONAL yp.o"
+ [ AC_DEFINE([HAVE_AUTH_URL], 1, [Define to compile in auth URL support code])
+ ICECAST_OPTIONAL="$ICECAST_OPTIONAL auth_url.o"
+ enable_curl="yes"
XIPH_VAR_APPEND([XIPH_CPPFLAGS],[$CURL_CFLAGS])
XIPH_VAR_PREPEND([XIPH_LIBS],[$CURL_LIBS])
], [ AC_MSG_NOTICE([Your curl dev files are too old (7.10 or above required), YP disabled])
], [#include <curl/curl.h>
])
- ],[ AC_MSG_NOTICE([libcurl not found, YP disabled])
+ ],[ AC_MSG_NOTICE([libcurl not found])
])
+dnl -- YP support --
+AC_ARG_ENABLE([yp],
+ AC_HELP_STRING([--disable-yp],[disable YP directory support]),
+ enable_yp="$enableval",
+ enable_yp="yes")
+if test "x$enable_yp" = "xyes" -a "x$enable_curl" = xyes
+then
+ AC_DEFINE([USE_YP], 1, [Define to compile in YP support code])
+ ICECAST_OPTIONAL="$ICECAST_OPTIONAL yp.o"
else
AC_MSG_NOTICE([YP support disabled])
fi
Modified: icecast/trunk/icecast/src/Makefile.am
===================================================================
--- icecast/trunk/icecast/src/Makefile.am 2005-08-07 23:01:04 UTC (rev 9713)
+++ icecast/trunk/icecast/src/Makefile.am 2005-08-07 23:29:12 UTC (rev 9714)
@@ -9,7 +9,7 @@
noinst_HEADERS = admin.h cfgfile.h os.h logging.h sighandler.h connection.h \
global.h util.h slave.h source.h stats.h refbuf.h client.h \
compat.h fserve.h xslt.h yp.h event.h md5.h \
- auth.h auth_htpasswd.h \
+ auth.h auth_htpasswd.h auth_url.h \
format.h format_ogg.h format_mp3.h \
format_vorbis.h format_theora.h format_flac.h format_speex.h format_midi.h
icecast_SOURCES = cfgfile.c main.c logging.c sighandler.c connection.c global.c \
@@ -18,6 +18,7 @@
format.c format_ogg.c format_mp3.c format_midi.c format_flac.c \
auth.c auth_htpasswd.c
EXTRA_icecast_SOURCES = yp.c \
+ auth_url.c \
format_vorbis.c format_theora.c format_speex.c
icecast_DEPENDENCIES = @ICECAST_OPTIONAL@ net/libicenet.la thread/libicethread.la \
Modified: icecast/trunk/icecast/src/auth.c
===================================================================
--- icecast/trunk/icecast/src/auth.c 2005-08-07 23:01:04 UTC (rev 9713)
+++ icecast/trunk/icecast/src/auth.c 2005-08-07 23:29:12 UTC (rev 9714)
@@ -25,6 +25,7 @@
#include "auth.h"
#include "auth_htpasswd.h"
+#include "auth_url.h"
#include "source.h"
#include "client.h"
#include "cfgfile.h"
@@ -423,6 +424,13 @@
do
{
DEBUG1 ("type is %s", auth->type);
+#ifdef HAVE_AUTH_URL
+ if (strcmp (auth->type, "url") == 0)
+ {
+ auth_get_url_auth (auth, options);
+ break;
+ }
+#endif
if (strcmp (auth->type, "htpasswd") == 0)
{
auth_get_htpasswd_auth (auth, options);
Added: icecast/trunk/icecast/src/auth_url.c
===================================================================
--- icecast/trunk/icecast/src/auth_url.c 2005-08-07 23:01:04 UTC (rev 9713)
+++ icecast/trunk/icecast/src/auth_url.c 2005-08-07 23:29:12 UTC (rev 9714)
@@ -0,0 +1,421 @@
+/* Icecast
+ *
+ * This program is distributed under the GNU General Public License, version 2.
+ * A copy of this license is included with this source.
+ *
+ * Copyright 2000-2004, Jack Moffitt <jack at xiph.org>,
+ * Michael Smith <msmith at xiph.org>,
+ * oddsock <oddsock at xiph.org>,
+ * Karl Heyes <karl at xiph.org>
+ * and others (see AUTHORS for details).
+ */
+
+/*
+ * Client authentication via URL functions
+ *
+ * authenticate user via a URL, this is done via libcurl so https can also
+ * be handled. The request will have POST information about the request in
+ * the form of
+ *
+ * action=auth&client=1&server=host&port=8000&mount=/live&user=fred&pass=mypass&ip=127.0.0.1&agent=""
+ *
+ * For a user to be accecpted the following HTTP header needs
+ * to be returned (the actual string can be specified in the xml file)
+ *
+ * icecast-auth-user: 1
+ *
+ * On client disconnection another request can be sent to a URL with the POST
+ * information of
+ *
+ * action=remove&server=host&port=8000&client=1&mount=/live&user=fred&pass=mypass&duration=3600
+ *
+ * client refers to the icecast client identification number. mount refers
+ * to the mountpoint (beginning with / and may contain query parameters eg ?&
+ * encoded) and duration is the amount of time in seconds. user and pass
+ * setting can be blank
+ *
+ * On stream start and end, another url can be issued to help clear any user
+ * info stored at the auth server. Useful for abnormal outage/termination
+ * cases.
+ *
+ * action=start&mount=/live&server=myserver.com&port=8000
+ * action=end&mount=/live&server=myserver.com&port=8000
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <stdio.h>
+#ifndef _WIN32
+#include <sys/wait.h>
+#include <strings.h>
+#else
+#define snprintf _snprintf
+#define strncasecmp strnicmp
+#endif
+
+#include <curl/curl.h>
+
+#include "auth.h"
+#include "source.h"
+#include "client.h"
+#include "cfgfile.h"
+#include "httpp/httpp.h"
+
+#include "logging.h"
+#define CATMODULE "auth_url"
+
+typedef struct {
+ char *addurl;
+ char *removeurl;
+ char *stream_start;
+ char *stream_end;
+ char *username;
+ char *password;
+ char *auth_header;
+ int auth_header_len;
+ CURL *handle;
+ char errormsg [CURL_ERROR_SIZE];
+} auth_url;
+
+
+static void auth_url_clear(auth_t *self)
+{
+ auth_url *url = self->state;
+ curl_easy_cleanup (url->handle);
+ free (url->username);
+ free (url->password);
+ free (url->removeurl);
+ free (url->addurl);
+ free (url->stream_start);
+ free (url->stream_end);
+ free (url->auth_header);
+ free (url);
+}
+
+
+static int handle_returned_header (void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ auth_client *auth_user = stream;
+ unsigned bytes = size * nmemb;
+ client_t *client = auth_user->client;
+
+ if (client)
+ {
+ auth_t *auth = client->auth;
+ auth_url *url = auth->state;
+ if (strncasecmp (ptr, url->auth_header, url->auth_header_len) == 0)
+ client->authenticated = 1;
+ if (strncasecmp (ptr, "icecast-auth-message: ", 22) == 0)
+ {
+ char *eol;
+ snprintf (url->errormsg, sizeof (url->errormsg), "%s", (char*)ptr+22);
+ eol = strchr (url->errormsg, '\r');
+ if (eol == NULL)
+ eol = strchr (url->errormsg, '\n');
+ if (eol)
+ *eol = '\0';
+ }
+ }
+
+ return (int)bytes;
+}
+
+/* capture returned data, but don't do anything with it */
+static int handle_returned_data (void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ return (int)(size*nmemb);
+}
+
+
+static auth_result url_remove_client (auth_client *auth_user)
+{
+ client_t *client = auth_user->client;
+ auth_t *auth = client->auth;
+ auth_url *url = auth->state;
+ time_t duration = time(NULL) - client->con->con_time;
+ char *username, *password, *mount, *server;
+ ice_config_t *config;
+ int port;
+ char post [4096];
+
+ config = config_get_config ();
+ server = util_url_escape (config->hostname);
+ port = config->port;
+ config_release_config ();
+
+ if (client->username)
+ username = util_url_escape (client->username);
+ else
+ username = strdup ("");
+
+ if (client->password)
+ password = util_url_escape (client->password);
+ else
+ password = strdup ("");
+
+ /* get the full uri (with query params if available) */
+ mount = httpp_getvar (client->parser, HTTPP_VAR_RAWURI);
+ if (mount == NULL)
+ mount = httpp_getvar (client->parser, HTTPP_VAR_URI);
+ mount = util_url_escape (mount);
+
+ snprintf (post, sizeof (post),
+ "action=remove&server=%s&port=%d&client=%lu&mount=%s"
+ "&user=%s&pass=%s&duration=%lu",
+ server, port, client->con->id, mount, username,
+ password, (long unsigned)duration);
+ free (server);
+ free (mount);
+ free (username);
+ free (password);
+
+ curl_easy_setopt (url->handle, CURLOPT_URL, url->removeurl);
+ curl_easy_setopt (url->handle, CURLOPT_POSTFIELDS, post);
+ curl_easy_setopt (url->handle, CURLOPT_WRITEHEADER, auth_user);
+
+ if (curl_easy_perform (url->handle))
+ WARN2 ("auth to server %s failed with %s", url->removeurl, url->errormsg);
+
+ return AUTH_OK;
+}
+
+
+static auth_result url_add_client (auth_client *auth_user)
+{
+ client_t *client = auth_user->client;
+ auth_t *auth = client->auth;
+ auth_url *url = auth->state;
+ int res = 0, port;
+ char *agent, *user_agent, *username, *password;
+ char *mount, *ipaddr, *server;
+ ice_config_t *config;
+ char post [4096];
+
+ if (url->addurl == NULL)
+ return AUTH_OK;
+
+ config = config_get_config ();
+ server = util_url_escape (config->hostname);
+ port = config->port;
+ config_release_config ();
+ agent = httpp_getvar (client->parser, "user-agent");
+ if (agent == NULL)
+ agent = "-";
+ user_agent = util_url_escape (agent);
+ if (client->username)
+ username = util_url_escape (client->username);
+ else
+ username = strdup ("");
+ if (client->password)
+ password = util_url_escape (client->password);
+ else
+ password = strdup ("");
+
+ /* get the full uri (with query params if available) */
+ mount = httpp_getvar (client->parser, HTTPP_VAR_RAWURI);
+ if (mount == NULL)
+ mount = httpp_getvar (client->parser, HTTPP_VAR_URI);
+ mount = util_url_escape (mount);
+ ipaddr = util_url_escape (client->con->ip);
+
+ snprintf (post, sizeof (post),
+ "action=auth&server=%s&port=%d&client=%lu&mount=%s"
+ "&user=%s&pass=%s&ip=%s&agent=%s",
+ server, port, client->con->id, mount, username,
+ password, ipaddr, user_agent);
+ free (server);
+ free (mount);
+ free (user_agent);
+ free (username);
+ free (password);
+ free (ipaddr);
+
+ curl_easy_setopt (url->handle, CURLOPT_URL, url->addurl);
+ curl_easy_setopt (url->handle, CURLOPT_POSTFIELDS, post);
+ curl_easy_setopt (url->handle, CURLOPT_WRITEHEADER, auth_user);
+ url->errormsg[0] = '\0';
+
+ res = curl_easy_perform (url->handle);
+
+ if (res)
+ {
+ WARN2 ("auth to server %s failed with %s", url->addurl, url->errormsg);
+ return AUTH_FAILED;
+ }
+ /* we received a response, lets see what it is */
+ if (client->authenticated)
+ return AUTH_OK;
+ INFO2 ("client auth (%s) failed with \"%s\"", url->addurl, url->errormsg);
+ return AUTH_FAILED;
+}
+
+
+/* called by auth thread when a source starts, there is no client_t in
+ * this case
+ */
+static void url_stream_start (auth_client *auth_user)
+{
+ char *mount, *server;
+ ice_config_t *config = config_get_config ();
+ mount_proxy *mountinfo = config_find_mount (config, auth_user->mount);
+ auth_t *auth = mountinfo->auth;
+ auth_url *url = auth->state;
+ char *stream_start_url;
+ int port;
+ char post [4096];
+
+ if (url->stream_start == NULL)
+ {
+ config_release_config ();
+ return;
+ }
+ server = util_url_escape (config->hostname);
+ port = config->port;
+ stream_start_url = strdup (url->stream_start);
+ /* we don't want this auth disappearing from under us while
+ * the connection is in progress */
+ mountinfo->auth->refcount++;
+ config_release_config ();
+ mount = util_url_escape (auth_user->mount);
+
+ snprintf (post, sizeof (post),
+ "action=start&mount=%s&server=%s&port=%d", mount, server, port);
+ free (server);
+ free (mount);
+
+ curl_easy_setopt (url->handle, CURLOPT_URL, stream_start_url);
+ curl_easy_setopt (url->handle, CURLOPT_POSTFIELDS, post);
+ curl_easy_setopt (url->handle, CURLOPT_WRITEHEADER, auth_user);
+
+ if (curl_easy_perform (url->handle))
+ WARN2 ("auth to server %s failed with %s", stream_start_url, url->errormsg);
+
+ auth_release (auth);
+ free (stream_start_url);
+ return;
+}
+
+
+static void url_stream_end (auth_client *auth_user)
+{
+ char *mount, *server;
+ ice_config_t *config = config_get_config ();
+ mount_proxy *mountinfo = config_find_mount (config, auth_user->mount);
+ auth_t *auth = mountinfo->auth;
+ auth_url *url = auth->state;
+ char *stream_end_url;
+ int port;
+ char post [4096];
+
+ if (url->stream_end == NULL)
+ {
+ config_release_config ();
+ return;
+ }
+ server = util_url_escape (config->hostname);
+ port = config->port;
+ stream_end_url = strdup (url->stream_end);
+ /* we don't want this auth disappearing from under us while
+ * the connection is in progress */
+ mountinfo->auth->refcount++;
+ config_release_config ();
+ mount = util_url_escape (auth_user->mount);
+
+ snprintf (post, sizeof (post),
+ "action=end&mount=%s&server=%s&port=%d", mount, server, port);
+ free (server);
+ free (mount);
+
+ curl_easy_setopt (url->handle, CURLOPT_URL, stream_end_url);
+ curl_easy_setopt (url->handle, CURLOPT_POSTFIELDS, post);
+ curl_easy_setopt (url->handle, CURLOPT_WRITEHEADER, auth_user);
+
+ if (curl_easy_perform (url->handle))
+ WARN2 ("auth to server %s failed with %s", stream_end_url, url->errormsg);
+
+ auth_release (auth);
+ free (stream_end_url);
+ return;
+}
+
+
+static auth_result auth_url_adduser(auth_t *auth, const char *username, const char *password)
+{
+ return AUTH_FAILED;
+}
+
+static auth_result auth_url_deleteuser (auth_t *auth, const char *username)
+{
+ return AUTH_FAILED;
+}
+
+static auth_result auth_url_listuser (auth_t *auth, xmlNodePtr srcnode)
+{
+ return AUTH_FAILED;
+}
+
+int auth_get_url_auth (auth_t *authenticator, config_options_t *options)
+{
+ auth_url *url_info;
+
+ authenticator->authenticate = url_add_client;
+ authenticator->release_client = url_remove_client;
+
+ authenticator->free = auth_url_clear;
+ authenticator->adduser = auth_url_adduser;
+ authenticator->deleteuser = auth_url_deleteuser;
+ authenticator->listuser = auth_url_listuser;
+
+ authenticator->stream_start = url_stream_start;
+ authenticator->stream_end = url_stream_end;
+
+ url_info = calloc(1, sizeof(auth_url));
+ url_info->auth_header = strdup ("icecast-auth-user: 1\r\n");
+
+ while(options) {
+ if(!strcmp(options->name, "username"))
+ url_info->username = strdup (options->value);
+ if(!strcmp(options->name, "password"))
+ url_info->password = strdup (options->value);
+ if(!strcmp(options->name, "add"))
+ url_info->addurl = strdup (options->value);
+ if(!strcmp(options->name, "remove"))
+ url_info->removeurl = strdup (options->value);
+ if(!strcmp(options->name, "start"))
+ url_info->stream_start = strdup (options->value);
+ if(!strcmp(options->name, "end"))
+ url_info->stream_end = strdup (options->value);
+ if(!strcmp(options->name, "auth_header"))
+ {
+ free (url_info->auth_header);
+ url_info->auth_header = strdup (options->value);
+ }
+ options = options->next;
+ }
+ url_info->handle = curl_easy_init ();
+ if (url_info->handle == NULL)
+ {
+ free (url_info);
+ return -1;
+ }
+ if (url_info->auth_header)
+ url_info->auth_header_len = strlen (url_info->auth_header);
+
+ curl_easy_setopt (url_info->handle, CURLOPT_USERAGENT, ICECAST_VERSION_STRING);
+ curl_easy_setopt (url_info->handle, CURLOPT_HEADERFUNCTION, handle_returned_header);
+ curl_easy_setopt (url_info->handle, CURLOPT_WRITEFUNCTION, handle_returned_data);
+ curl_easy_setopt (url_info->handle, CURLOPT_WRITEDATA, url_info->handle);
+ curl_easy_setopt (url_info->handle, CURLOPT_NOSIGNAL, 1L);
+ curl_easy_setopt (url_info->handle, CURLOPT_TIMEOUT, 15L);
+ curl_easy_setopt (url_info->handle, CURLOPT_ERRORBUFFER, &url_info->errormsg[0]);
+
+ authenticator->state = url_info;
+ INFO0("URL based authentication setup");
+ return 0;
+}
+
Added: icecast/trunk/icecast/src/auth_url.h
===================================================================
--- icecast/trunk/icecast/src/auth_url.h 2005-08-07 23:01:04 UTC (rev 9713)
+++ icecast/trunk/icecast/src/auth_url.h 2005-08-07 23:29:12 UTC (rev 9714)
@@ -0,0 +1,24 @@
+/* Icecast
+ *
+ * This program is distributed under the GNU General Public License, version 2.
+ * A copy of this license is included with this source.
+ *
+ * Copyright 2000-2004, Jack Moffitt <jack at xiph.org,
+ * Michael Smith <msmith at xiph.org>,
+ * oddsock <oddsock at xiph.org>,
+ * Karl Heyes <karl at xiph.org>
+ * and others (see AUTHORS for details).
+ */
+
+#ifndef __AUTH_URL_H__
+#define __AUTH_URL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+int *auth_get_url_auth (auth_t *authenticator, config_options_t *options);
+
+#endif
+
+
More information about the commits
mailing list