mirror of
https://gitlab.xiph.org/xiph/icecast-server.git
synced 2024-12-04 14:46:30 -05:00
Per mountpoint usernames, passwords, and some infrastructure for other
per-mountpoint configuration (some of these are given as examples in the config file, but they aren't yet used). svn path=/trunk/icecast/; revision=4338
This commit is contained in:
parent
9f85a1e7c3
commit
9acef4801e
7
TODO
7
TODO
@ -2,14 +2,12 @@ BUGS
|
|||||||
----
|
----
|
||||||
- stats get off? this needs testing more testing.
|
- stats get off? this needs testing more testing.
|
||||||
|
|
||||||
- autoconf doesn't set HAVE_POLL
|
- autoconf doesn't set HAVE_POLL (still true?)
|
||||||
|
|
||||||
- some stuff (like 'genre') isn't making it into the stats dump
|
- some stuff (like 'genre') isn't making it into the stats dump
|
||||||
|
|
||||||
- make install - doesn't install configs?
|
- make install - doesn't install configs?
|
||||||
|
|
||||||
- pthread/bsd: -pthread instead of -lpthread (autoconf)
|
|
||||||
|
|
||||||
FEATURES
|
FEATURES
|
||||||
--------
|
--------
|
||||||
|
|
||||||
@ -48,8 +46,7 @@ FEATURES
|
|||||||
|
|
||||||
- httpp - split out query string for further processing
|
- httpp - split out query string for further processing
|
||||||
|
|
||||||
- finish mp3 metadata: http://server:ip/admin.cgi?pass=%s&mode=updinfo&mount=%s&song=%s
|
- binding to multiple ports (possibly including full ipv6 support)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,6 +45,17 @@
|
|||||||
</relay>
|
</relay>
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
<mount>
|
||||||
|
<mount-name>/example1.ogg</mount-name>
|
||||||
|
<username>othersource</username>
|
||||||
|
<password>hackmemore</password>
|
||||||
|
|
||||||
|
<!-- These next three aren't yet implemented -->
|
||||||
|
<max-listeners>1</max-listeners>
|
||||||
|
<dump-file>/tmp/dump-example1.ogg</dump-file>
|
||||||
|
<fallback-mount>/example2.ogg</fallback-mount>
|
||||||
|
</mount>
|
||||||
|
|
||||||
<fileserve>1</fileserve>
|
<fileserve>1</fileserve>
|
||||||
|
|
||||||
<paths>
|
<paths>
|
||||||
|
64
src/config.c
64
src/config.c
@ -56,6 +56,7 @@ static void _parse_logging(xmlDocPtr doc, xmlNodePtr node);
|
|||||||
static void _parse_security(xmlDocPtr doc, xmlNodePtr node);
|
static void _parse_security(xmlDocPtr doc, xmlNodePtr node);
|
||||||
static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node);
|
static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node);
|
||||||
static void _parse_relay(xmlDocPtr doc, xmlNodePtr node);
|
static void _parse_relay(xmlDocPtr doc, xmlNodePtr node);
|
||||||
|
static void _parse_mount(xmlDocPtr doc, xmlNodePtr node);
|
||||||
static void _add_server(xmlDocPtr doc, xmlNodePtr node);
|
static void _add_server(xmlDocPtr doc, xmlNodePtr node);
|
||||||
|
|
||||||
void config_initialize(void)
|
void config_initialize(void)
|
||||||
@ -70,6 +71,7 @@ void config_shutdown(void)
|
|||||||
ice_config_dir_t *dirnode, *nextdirnode;
|
ice_config_dir_t *dirnode, *nextdirnode;
|
||||||
ice_config_t *c = &_configuration;
|
ice_config_t *c = &_configuration;
|
||||||
relay_server *relay, *nextrelay;
|
relay_server *relay, *nextrelay;
|
||||||
|
mount_proxy *mount, *nextmount;
|
||||||
|
|
||||||
if (_config_filename) free(_config_filename);
|
if (_config_filename) free(_config_filename);
|
||||||
|
|
||||||
@ -110,6 +112,17 @@ void config_shutdown(void)
|
|||||||
free(relay);
|
free(relay);
|
||||||
relay = nextrelay;
|
relay = nextrelay;
|
||||||
}
|
}
|
||||||
|
mount = _configuration.mounts;
|
||||||
|
while(mount) {
|
||||||
|
nextmount = mount->next;
|
||||||
|
xmlFree(mount->mountname);
|
||||||
|
xmlFree(mount->username);
|
||||||
|
xmlFree(mount->password);
|
||||||
|
xmlFree(mount->dumpfile);
|
||||||
|
xmlFree(mount->fallback_mount);
|
||||||
|
free(mount);
|
||||||
|
mount = nextmount;
|
||||||
|
}
|
||||||
dirnode = _configuration.dir_list;
|
dirnode = _configuration.dir_list;
|
||||||
while(dirnode) {
|
while(dirnode) {
|
||||||
nextdirnode = dirnode->next;
|
nextdirnode = dirnode->next;
|
||||||
@ -273,6 +286,8 @@ static void _parse_root(xmlDocPtr doc, xmlNodePtr node)
|
|||||||
_parse_limits(doc, node->xmlChildrenNode);
|
_parse_limits(doc, node->xmlChildrenNode);
|
||||||
} else if (strcmp(node->name, "relay") == 0) {
|
} else if (strcmp(node->name, "relay") == 0) {
|
||||||
_parse_relay(doc, node->xmlChildrenNode);
|
_parse_relay(doc, node->xmlChildrenNode);
|
||||||
|
} else if (strcmp(node->name, "mount") == 0) {
|
||||||
|
_parse_mount(doc, node->xmlChildrenNode);
|
||||||
} else if (strcmp(node->name, "directory") == 0) {
|
} else if (strcmp(node->name, "directory") == 0) {
|
||||||
_parse_directory(doc, node->xmlChildrenNode);
|
_parse_directory(doc, node->xmlChildrenNode);
|
||||||
} else if (strcmp(node->name, "paths") == 0) {
|
} else if (strcmp(node->name, "paths") == 0) {
|
||||||
@ -321,6 +336,55 @@ static void _parse_limits(xmlDocPtr doc, xmlNodePtr node)
|
|||||||
} while ((node = node->next));
|
} while ((node = node->next));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _parse_mount(xmlDocPtr doc, xmlNodePtr node)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
mount_proxy *mount = calloc(1, sizeof(mount_proxy));
|
||||||
|
mount_proxy *current = _configuration.mounts;
|
||||||
|
mount_proxy *last=NULL;
|
||||||
|
|
||||||
|
while(current) {
|
||||||
|
last = current;
|
||||||
|
current = current->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(last)
|
||||||
|
last->next = mount;
|
||||||
|
else
|
||||||
|
_configuration.mounts = mount;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (node == NULL) break;
|
||||||
|
if (xmlIsBlankNode(node)) continue;
|
||||||
|
|
||||||
|
if (strcmp(node->name, "mount-name") == 0) {
|
||||||
|
mount->mountname = (char *)xmlNodeListGetString(
|
||||||
|
doc, node->xmlChildrenNode, 1);
|
||||||
|
}
|
||||||
|
else if (strcmp(node->name, "username") == 0) {
|
||||||
|
mount->username = (char *)xmlNodeListGetString(
|
||||||
|
doc, node->xmlChildrenNode, 1);
|
||||||
|
}
|
||||||
|
else if (strcmp(node->name, "password") == 0) {
|
||||||
|
mount->password = (char *)xmlNodeListGetString(
|
||||||
|
doc, node->xmlChildrenNode, 1);
|
||||||
|
}
|
||||||
|
else if (strcmp(node->name, "dump-file") == 0) {
|
||||||
|
mount->dumpfile = (char *)xmlNodeListGetString(
|
||||||
|
doc, node->xmlChildrenNode, 1);
|
||||||
|
}
|
||||||
|
else if (strcmp(node->name, "fallback-mount") == 0) {
|
||||||
|
mount->fallback_mount = (char *)xmlNodeListGetString(
|
||||||
|
doc, node->xmlChildrenNode, 1);
|
||||||
|
}
|
||||||
|
else if (strcmp(node->name, "max-listeners") == 0) {
|
||||||
|
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
|
||||||
|
mount->max_listeners = atoi(tmp);
|
||||||
|
if(tmp) xmlFree(tmp);
|
||||||
|
}
|
||||||
|
} while ((node = node->next));
|
||||||
|
}
|
||||||
|
|
||||||
static void _parse_relay(xmlDocPtr doc, xmlNodePtr node)
|
static void _parse_relay(xmlDocPtr doc, xmlNodePtr node)
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
16
src/config.h
16
src/config.h
@ -22,6 +22,20 @@ typedef struct _relay_server {
|
|||||||
struct _relay_server *next;
|
struct _relay_server *next;
|
||||||
} relay_server;
|
} relay_server;
|
||||||
|
|
||||||
|
typedef struct _mount_proxy {
|
||||||
|
char *mountname; /* The mountpoint this proxy is used for */
|
||||||
|
|
||||||
|
char *username; /* Username and password for this mountpoint. If unset, */
|
||||||
|
char *password; /* falls back to global source password */
|
||||||
|
|
||||||
|
char *dumpfile; /* Filename to dump this stream to (will be appended). NULL
|
||||||
|
to not dump. */
|
||||||
|
int max_listeners; /* Max listeners for this mountpoint only. -1 to not
|
||||||
|
limit here (i.e. only use the global limit) */
|
||||||
|
char *fallback_mount;
|
||||||
|
struct _mount_proxy *next;
|
||||||
|
} mount_proxy;
|
||||||
|
|
||||||
typedef struct ice_config_tag
|
typedef struct ice_config_tag
|
||||||
{
|
{
|
||||||
char *location;
|
char *location;
|
||||||
@ -54,6 +68,8 @@ typedef struct ice_config_tag
|
|||||||
|
|
||||||
relay_server *relay;
|
relay_server *relay;
|
||||||
|
|
||||||
|
mount_proxy *mounts;
|
||||||
|
|
||||||
char *base_dir;
|
char *base_dir;
|
||||||
char *log_dir;
|
char *log_dir;
|
||||||
char *webroot_dir;
|
char *webroot_dir;
|
||||||
|
@ -321,7 +321,7 @@ int connection_create_source(client_t *client, connection_t *con, http_parser_t
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
format_type_t format = FORMAT_TYPE_MP3;
|
format_type_t format = FORMAT_TYPE_MP3;
|
||||||
ERROR0("No content-type header, falling back to backwards compatiblity mode for icecast 1.x relays. Assuming content is mp3.");
|
ERROR0("No content-type header, falling back to backwards compatibility mode for icecast 1.x relays. Assuming content is mp3.");
|
||||||
source = source_create(client, con, parser, mount, format);
|
source = source_create(client, con, parser, mount, format);
|
||||||
}
|
}
|
||||||
client->respcode = 200;
|
client->respcode = 200;
|
||||||
@ -418,11 +418,24 @@ static int _check_admin_pass(http_parser_t *parser)
|
|||||||
static int _check_source_pass(http_parser_t *parser, char *mount)
|
static int _check_source_pass(http_parser_t *parser, char *mount)
|
||||||
{
|
{
|
||||||
char *pass = config_get_config()->source_password;
|
char *pass = config_get_config()->source_password;
|
||||||
|
char *user = "source";
|
||||||
int ret;
|
int ret;
|
||||||
if(!pass)
|
|
||||||
pass = "";
|
|
||||||
|
|
||||||
ret = _check_pass_http(parser, "source", pass);
|
mount_proxy *mountinfo = config_get_config()->mounts;
|
||||||
|
while(mountinfo) {
|
||||||
|
if(!strcmp(mountinfo->mountname, mount)) {
|
||||||
|
pass = mountinfo->password;
|
||||||
|
user = mountinfo->username;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!pass) {
|
||||||
|
WARN0("No source password set, rejecting source");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = _check_pass_http(parser, user, pass);
|
||||||
if(!ret && config_get_config()->ice_login)
|
if(!ret && config_get_config()->ice_login)
|
||||||
{
|
{
|
||||||
ret = _check_pass_ice(parser, pass);
|
ret = _check_pass_ice(parser, pass);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "source.h"
|
#include "source.h"
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
#include "format_vorbis.h"
|
#include "format_vorbis.h"
|
||||||
#include "format_mp3.h"
|
#include "format_mp3.h"
|
||||||
@ -111,6 +112,9 @@ void format_send_general_headers(format_plugin_t *format,
|
|||||||
"%s: %s\r\n", var->name, var->value);
|
"%s: %s\r\n", var->name, var->value);
|
||||||
if(bytes > 0) client->con->sent_bytes += bytes;
|
if(bytes > 0) client->con->sent_bytes += bytes;
|
||||||
}
|
}
|
||||||
|
bytes = sock_write(client->con->sock,
|
||||||
|
"Server: %s\r\n", ICECAST_VERSION_STRING);
|
||||||
|
if(bytes > 0) client->con->sent_bytes += bytes;
|
||||||
node = avl_get_next(node);
|
node = avl_get_next(node);
|
||||||
}
|
}
|
||||||
avl_tree_unlock(source->parser->vars);
|
avl_tree_unlock(source->parser->vars);
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#define ICE_RUNNING 1
|
#define ICE_RUNNING 1
|
||||||
#define ICE_HALTING 2
|
#define ICE_HALTING 2
|
||||||
|
|
||||||
|
#define ICECAST_VERSION_STRING "Icecast 2.0-alpha2/cvs"
|
||||||
|
|
||||||
#include "thread/thread.h"
|
#include "thread/thread.h"
|
||||||
|
|
||||||
typedef struct ice_global_tag
|
typedef struct ice_global_tag
|
||||||
|
@ -28,7 +28,8 @@ typedef struct source_tag
|
|||||||
rwlock_t *shutdown_rwlock;
|
rwlock_t *shutdown_rwlock;
|
||||||
ypdata_t *ypdata[MAX_YP_DIRECTORIES];
|
ypdata_t *ypdata[MAX_YP_DIRECTORIES];
|
||||||
int num_yp_directories;
|
int num_yp_directories;
|
||||||
long listeners;
|
long listeners;
|
||||||
|
long max_listeners;
|
||||||
} source_t;
|
} source_t;
|
||||||
|
|
||||||
source_t *source_create(client_t *client, connection_t *con, http_parser_t *parser, const char *mount, format_type_t type);
|
source_t *source_create(client_t *client, connection_t *con, http_parser_t *parser, const char *mount, format_type_t type);
|
||||||
|
Loading…
Reference in New Issue
Block a user