1
0
mirror of https://gitlab.xiph.org/xiph/icecast-server.git synced 2024-06-30 06:35:23 +00:00
icecast-server/src/cfgfile.c

1881 lines
75 KiB
C
Raw Normal View History

/* 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@xiph.org,
* Michael Smith <msmith@xiph.org>,
* oddsock <oddsock@xiph.org>,
* Karl Heyes <karl@xiph.org>
* and others (see AUTHORS for details).
* Copyright 2011, Dave 'justdave' Miller <justdave@mozilla.com>.
* Copyright 2011-2014, Thomas B. "dm8tbr" Ruecker <thomas@ruecker.fi>,
* Copyright 2011-2014, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef _WIN32
#include <fnmatch.h>
#endif
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
#include "common/thread/thread.h"
#include "cfgfile.h"
#include "refbuf.h"
#include "client.h"
#include "logging.h"
#include "util.h"
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
#include "auth.h"
#define CATMODULE "CONFIG"
#define CONFIG_DEFAULT_LOCATION "Earth"
#define CONFIG_DEFAULT_ADMIN "icemaster@localhost"
#define CONFIG_DEFAULT_CLIENT_LIMIT 256
#define CONFIG_DEFAULT_SOURCE_LIMIT 16
#define CONFIG_DEFAULT_QUEUE_SIZE_LIMIT (500*1024)
#define CONFIG_DEFAULT_BURST_SIZE (64*1024)
#define CONFIG_DEFAULT_THREADPOOL_SIZE 4
#define CONFIG_DEFAULT_CLIENT_TIMEOUT 30
#define CONFIG_DEFAULT_HEADER_TIMEOUT 15
#define CONFIG_DEFAULT_SOURCE_TIMEOUT 10
#define CONFIG_DEFAULT_MASTER_USERNAME "relay"
#define CONFIG_DEFAULT_SHOUTCAST_MOUNT "/stream"
#define CONFIG_DEFAULT_FILESERVE 1
#define CONFIG_DEFAULT_TOUCH_FREQ 5
#define CONFIG_DEFAULT_HOSTNAME "localhost"
#define CONFIG_DEFAULT_PLAYLIST_LOG NULL
#define CONFIG_DEFAULT_ACCESS_LOG "access.log"
#define CONFIG_DEFAULT_ERROR_LOG "error.log"
#define CONFIG_DEFAULT_LOG_LEVEL 3
#define CONFIG_DEFAULT_CHROOT 0
#define CONFIG_DEFAULT_CHUID 0
#define CONFIG_DEFAULT_USER NULL
#define CONFIG_DEFAULT_GROUP NULL
#define CONFIG_MASTER_UPDATE_INTERVAL 120
#define CONFIG_YP_URL_TIMEOUT 10
#define CONFIG_DEFAULT_CIPHER_LIST "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"
#ifndef _WIN32
#define CONFIG_DEFAULT_BASE_DIR "/usr/local/icecast"
#define CONFIG_DEFAULT_LOG_DIR "/usr/local/icecast/logs"
#define CONFIG_DEFAULT_WEBROOT_DIR "/usr/local/icecast/webroot"
#define CONFIG_DEFAULT_ADMINROOT_DIR "/usr/local/icecast/admin"
#define CONFIG_DEFAULT_NULL_FILE "/dev/null"
#define MIMETYPESFILE "/etc/mime.types"
#else
#define CONFIG_DEFAULT_BASE_DIR ".\\"
#define CONFIG_DEFAULT_LOG_DIR ".\\logs"
#define CONFIG_DEFAULT_WEBROOT_DIR ".\\webroot"
#define CONFIG_DEFAULT_ADMINROOT_DIR ".\\admin"
#define CONFIG_DEFAULT_NULL_FILE "nul:"
#define MIMETYPESFILE ".\\mime.types"
#endif
static ice_config_t _current_configuration;
static ice_config_locks _locks;
static void _set_defaults(ice_config_t *c);
static void _parse_root(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_limits(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_directory(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_paths(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_logging(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_security(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node,
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
ice_config_t *c, char **source_password);
static void _parse_http_headers(xmlDocPtr doc, xmlNodePtr node,
ice_config_http_header_t **http_headers);
static void _parse_relay(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_mount(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *c);
static void _add_server(xmlDocPtr doc, xmlNodePtr node, ice_config_t *c);
static void merge_mounts(mount_proxy * dst, mount_proxy * src);
static inline void _merge_mounts_all(ice_config_t *c);
static void create_locks(void) {
thread_mutex_create(&_locks.relay_lock);
thread_rwlock_create(&_locks.config_lock);
}
static void release_locks(void) {
thread_mutex_destroy(&_locks.relay_lock);
thread_rwlock_destroy(&_locks.config_lock);
}
void config_initialize(void) {
create_locks();
}
void config_shutdown(void) {
config_get_config();
config_clear(&_current_configuration);
config_release_config();
release_locks();
}
void config_init_configuration(ice_config_t *configuration)
{
memset(configuration, 0, sizeof(ice_config_t));
_set_defaults(configuration);
}
static inline int __parse_public(const char *str) {
/* values that are not bool */
if (strcasecmp(str, "client") == 0)
return -1;
/* old way of doing so */
if (strcmp(str, "-1") == 0)
return -1;
/* ok, only normal bool left! */
return util_str_to_bool(str);
}
static inline int __parse_loglevel(const char *str) {
if (strcasecmp(str, "debug") == 0 || strcasecmp(str, "DBUG") == 0)
return 4;
if (strcasecmp(str, "information") == 0 || strcasecmp(str, "INFO") == 0)
return 3;
if (strcasecmp(str, "warning") == 0 || strcasecmp(str, "WARN") == 0)
return 2;
if (strcasecmp(str, "error") == 0 || strcasecmp(str, "EROR") == 0)
return 1;
/* gussing it is old-style numerical setting */
return atoi(str);
}
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
static void __append_old_style_auth(auth_stack_t **stack, const char *name, const char *type, const char *username, const char *password, const char *method, const char *allow_method, int allow_web, const char *allow_admin) {
xmlNodePtr role, user, pass;
auth_t *auth;
if (!type)
return;
role = xmlNewNode(NULL, XMLSTR("role"));
xmlSetProp(role, XMLSTR("type"), XMLSTR(type));
xmlSetProp(role, XMLSTR("deny-method"), XMLSTR("*"));
if (allow_method)
xmlSetProp(role, XMLSTR("allow-method"), XMLSTR(allow_method));
if (name)
xmlSetProp(role, XMLSTR("name"), XMLSTR(name));
if (method)
xmlSetProp(role, XMLSTR("method"), XMLSTR(method));
if (allow_web) {
xmlSetProp(role, XMLSTR("allow-web"), XMLSTR("*"));
} else {
xmlSetProp(role, XMLSTR("deny-web"), XMLSTR("*"));
}
if (allow_admin && strcmp(allow_admin, "*") == 0) {
xmlSetProp(role, XMLSTR("allow-admin"), XMLSTR("*"));
} else {
xmlSetProp(role, XMLSTR("deny-admin"), XMLSTR("*"));
if (allow_admin)
xmlSetProp(role, XMLSTR("allow-admin"), XMLSTR(allow_admin));
}
if (username) {
user = xmlNewChild(role, NULL, XMLSTR("option"), NULL);
xmlSetProp(user, XMLSTR("name"), XMLSTR("username"));
xmlSetProp(user, XMLSTR("value"), XMLSTR(username));
}
if (password) {
pass = xmlNewChild(role, NULL, XMLSTR("option"), NULL);
xmlSetProp(pass, XMLSTR("name"), XMLSTR("password"));
xmlSetProp(pass, XMLSTR("value"), XMLSTR(password));
}
auth = auth_get_authenticator(role);
auth_stack_push(stack, auth);
auth_release(auth);
xmlFreeNode(role);
}
static void __append_option_tag (xmlNodePtr parent, const char *name, const char *value) {
xmlNodePtr node;
if (!name || !value)
return;
node = xmlNewChild(parent, NULL, XMLSTR("option"), NULL);
xmlSetProp(node, XMLSTR("name"), XMLSTR(name));
xmlSetProp(node, XMLSTR("value"), XMLSTR(value));
}
static void __append_old_style_urlauth(auth_stack_t **stack, const char *client_add, const char *client_remove, const char *action_add, const char *action_remove, const char *username, const char *password, int is_source, const char *auth_header, const char *timelimit_header, const char *headers, const char *header_prefix) {
xmlNodePtr role;
auth_t *auth;
if (!stack || !client_add || !!client_remove)
return;
role = xmlNewNode(NULL, XMLSTR("role"));
xmlSetProp(role, XMLSTR("type"), XMLSTR("url"));
if (is_source) {
xmlSetProp(role, XMLSTR("method"), XMLSTR("source,put"));
xmlSetProp(role, XMLSTR("deny-method"), XMLSTR("*"));
xmlSetProp(role, XMLSTR("allow-method"), XMLSTR("source,put"));
xmlSetProp(role, XMLSTR("allow-web"), XMLSTR("*"));
xmlSetProp(role, XMLSTR("allow-admin"), XMLSTR("*"));
} else {
xmlSetProp(role, XMLSTR("method"), XMLSTR("get,post,head"));
xmlSetProp(role, XMLSTR("deny-method"), XMLSTR("*"));
xmlSetProp(role, XMLSTR("allow-method"), XMLSTR("get,post,head"));
xmlSetProp(role, XMLSTR("allow-web"), XMLSTR("*"));
xmlSetProp(role, XMLSTR("deny-admin"), XMLSTR("*"));
}
__append_option_tag(role, "client_add", client_add);
__append_option_tag(role, "client_remove", client_remove);
__append_option_tag(role, "action_add", action_add);
__append_option_tag(role, "action_remove", action_remove);
__append_option_tag(role, "username", username);
__append_option_tag(role, "password", password);
__append_option_tag(role, "auth_header", auth_header);
__append_option_tag(role, "timelimit_header", timelimit_header);
__append_option_tag(role, "headers", headers);
__append_option_tag(role, "header_prefix", header_prefix);
auth = auth_get_authenticator(role);
auth_stack_push(stack, auth);
auth_release(auth);
xmlFreeNode(role);
}
static void config_clear_http_header(ice_config_http_header_t *header) {
ice_config_http_header_t *old;
while (header) {
xmlFree(header->name);
xmlFree(header->value);
old = header;
header = header->next;
free(old);
}
}
static inline ice_config_http_header_t * config_copy_http_header(ice_config_http_header_t *header) {
ice_config_http_header_t *ret = NULL;
ice_config_http_header_t *cur = NULL;
ice_config_http_header_t *old = NULL;
while (header) {
if (cur) {
cur->next = calloc(1, sizeof(ice_config_http_header_t));
old = cur;
cur = cur->next;
} else {
ret = calloc(1, sizeof(ice_config_http_header_t));
cur = ret;
}
if (!cur) return ret; /* TODO: do better error handling */
cur->type = header->type;
cur->name = (char *)xmlCharStrdup(header->name);
cur->value = (char *)xmlCharStrdup(header->value);
cur->status = header->status;
if (!cur->name || !cur->value) {
if (cur->name) xmlFree(cur->name);
if (cur->value) xmlFree(cur->value);
if (old) {
old->next = NULL;
} else {
ret = NULL;
}
free(cur);
return ret;
}
header = header->next;
}
return ret;
}
static void config_clear_mount(mount_proxy *mount)
{
if (mount->mountname) xmlFree (mount->mountname);
if (mount->dumpfile) xmlFree (mount->dumpfile);
if (mount->intro_filename) xmlFree (mount->intro_filename);
if (mount->on_connect) xmlFree (mount->on_connect);
if (mount->on_disconnect) xmlFree (mount->on_disconnect);
if (mount->fallback_mount) xmlFree (mount->fallback_mount);
if (mount->stream_name) xmlFree (mount->stream_name);
if (mount->stream_description) xmlFree (mount->stream_description);
if (mount->stream_url) xmlFree (mount->stream_url);
if (mount->stream_genre) xmlFree (mount->stream_genre);
if (mount->bitrate) xmlFree (mount->bitrate);
if (mount->type) xmlFree (mount->type);
if (mount->charset) xmlFree (mount->charset);
if (mount->cluster_password) xmlFree (mount->cluster_password);
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if (mount->authstack) auth_stack_release(mount->authstack);
config_clear_http_header(mount->http_headers);
free (mount);
}
listener_t *config_clear_listener (listener_t *listener)
{
listener_t *next = NULL;
if (listener)
{
next = listener->next;
if (listener->bind_address) xmlFree (listener->bind_address);
if (listener->shoutcast_mount) xmlFree (listener->shoutcast_mount);
free (listener);
}
return next;
}
void config_clear(ice_config_t *c)
{
ice_config_dir_t *dirnode, *nextdirnode;
relay_server *relay, *nextrelay;
mount_proxy *mount, *nextmount;
aliases *alias, *nextalias;
#ifdef USE_YP
int i;
#endif
free(c->config_filename);
xmlFree (c->server_id);
if (c->location) xmlFree(c->location);
if (c->admin) xmlFree(c->admin);
if (c->hostname) xmlFree(c->hostname);
if (c->base_dir) xmlFree(c->base_dir);
if (c->log_dir) xmlFree(c->log_dir);
if (c->webroot_dir) xmlFree(c->webroot_dir);
if (c->adminroot_dir) xmlFree(c->adminroot_dir);
if (c->cert_file) xmlFree(c->cert_file);
if (c->cipher_list) xmlFree(c->cipher_list);
if (c->pidfile)
xmlFree(c->pidfile);
if (c->banfile) xmlFree(c->banfile);
if (c->allowfile) xmlFree(c->allowfile);
if (c->playlist_log) xmlFree(c->playlist_log);
if (c->access_log) xmlFree(c->access_log);
if (c->error_log) xmlFree(c->error_log);
if (c->shoutcast_mount) xmlFree(c->shoutcast_mount);
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if (c->authstack) auth_stack_release(c->authstack);
if (c->master_server) xmlFree(c->master_server);
if (c->master_username) xmlFree(c->master_username);
if (c->master_password) xmlFree(c->master_password);
if (c->user) xmlFree(c->user);
if (c->group) xmlFree(c->group);
if (c->mimetypes_fn) xmlFree (c->mimetypes_fn);
while ((c->listen_sock = config_clear_listener (c->listen_sock)))
;
thread_mutex_lock(&(_locks.relay_lock));
relay = c->relay;
while (relay) {
nextrelay = relay->next;
xmlFree(relay->server);
xmlFree(relay->mount);
xmlFree(relay->localmount);
free(relay);
relay = nextrelay;
}
thread_mutex_unlock(&(_locks.relay_lock));
mount = c->mounts;
while (mount) {
nextmount = mount->next;
config_clear_mount(mount);
mount = nextmount;
}
alias = c->aliases;
while (alias) {
nextalias = alias->next;
xmlFree(alias->source);
xmlFree(alias->destination);
xmlFree(alias->bind_address);
xmlFree(alias->vhost);
free(alias);
alias = nextalias;
}
dirnode = c->dir_list;
while (dirnode) {
nextdirnode = dirnode->next;
xmlFree(dirnode->host);
free(dirnode);
dirnode = nextdirnode;
}
#ifdef USE_YP
i = 0;
while (i < c->num_yp_directories)
{
xmlFree (c->yp_url[i]);
i++;
}
#endif
config_clear_http_header(c->http_headers);
memset(c, 0, sizeof(ice_config_t));
}
int config_initial_parse_file(const char *filename)
{
/* Since we're already pointing at it, we don't need to copy it in place */
return config_parse_file(filename, &_current_configuration);
}
int config_parse_file(const char *filename, ice_config_t *configuration)
{
xmlDocPtr doc;
xmlNodePtr node;
if (filename == NULL || strcmp(filename, "") == 0) return CONFIG_EINSANE;
doc = xmlParseFile(filename);
if (doc == NULL) {
return CONFIG_EPARSE;
}
node = xmlDocGetRootElement(doc);
if (node == NULL) {
xmlFreeDoc(doc);
return CONFIG_ENOROOT;
}
if (xmlStrcmp (node->name, XMLSTR("icecast")) != 0) {
xmlFreeDoc(doc);
return CONFIG_EBADROOT;
}
config_init_configuration(configuration);
configuration->config_filename = strdup (filename);
_parse_root(doc, node->xmlChildrenNode, configuration);
xmlFreeDoc(doc);
_merge_mounts_all(configuration);
return 0;
}
int config_parse_cmdline(int arg, char **argv)
{
return 0;
}
ice_config_locks *config_locks(void)
{
return &_locks;
}
void config_release_config(void)
{
thread_rwlock_unlock(&(_locks.config_lock));
}
ice_config_t *config_get_config(void)
{
thread_rwlock_rlock(&(_locks.config_lock));
return &_current_configuration;
}
ice_config_t *config_grab_config(void)
{
thread_rwlock_wlock(&(_locks.config_lock));
return &_current_configuration;
}
/* MUST be called with the lock held! */
void config_set_config(ice_config_t *config) {
memcpy(&_current_configuration, config, sizeof(ice_config_t));
}
ice_config_t *config_get_config_unlocked(void)
{
return &_current_configuration;
}
static void _set_defaults(ice_config_t *configuration)
{
configuration->location = (char *) xmlCharStrdup(CONFIG_DEFAULT_LOCATION);
configuration->server_id = (char *) xmlCharStrdup(ICECAST_VERSION_STRING);
configuration->admin = (char *) xmlCharStrdup(CONFIG_DEFAULT_ADMIN);
configuration->client_limit = CONFIG_DEFAULT_CLIENT_LIMIT;
configuration->source_limit = CONFIG_DEFAULT_SOURCE_LIMIT;
configuration->queue_size_limit = CONFIG_DEFAULT_QUEUE_SIZE_LIMIT;
configuration->client_timeout = CONFIG_DEFAULT_CLIENT_TIMEOUT;
configuration->header_timeout = CONFIG_DEFAULT_HEADER_TIMEOUT;
configuration->source_timeout = CONFIG_DEFAULT_SOURCE_TIMEOUT;
configuration->shoutcast_mount = (char *)xmlCharStrdup (CONFIG_DEFAULT_SHOUTCAST_MOUNT);
configuration->fileserve = CONFIG_DEFAULT_FILESERVE;
configuration->touch_interval = CONFIG_DEFAULT_TOUCH_FREQ;
configuration->on_demand = 0;
configuration->dir_list = NULL;
configuration->hostname = (char *)xmlCharStrdup (CONFIG_DEFAULT_HOSTNAME);
configuration->mimetypes_fn = (char *)xmlCharStrdup (MIMETYPESFILE);
configuration->master_server = NULL;
configuration->master_server_port = 0;
configuration->master_update_interval = CONFIG_MASTER_UPDATE_INTERVAL;
configuration->master_username = (char *)xmlCharStrdup (CONFIG_DEFAULT_MASTER_USERNAME);
configuration->master_password = NULL;
configuration->base_dir = (char *)xmlCharStrdup (CONFIG_DEFAULT_BASE_DIR);
configuration->log_dir = (char *)xmlCharStrdup (CONFIG_DEFAULT_LOG_DIR);
configuration->cipher_list = (char *)xmlCharStrdup (CONFIG_DEFAULT_CIPHER_LIST);
configuration->null_device = (char *)xmlCharStrdup (CONFIG_DEFAULT_NULL_FILE);
configuration->webroot_dir = (char *)xmlCharStrdup (CONFIG_DEFAULT_WEBROOT_DIR);
configuration->adminroot_dir = (char *)xmlCharStrdup (CONFIG_DEFAULT_ADMINROOT_DIR);
configuration->playlist_log = (char *)xmlCharStrdup (CONFIG_DEFAULT_PLAYLIST_LOG);
configuration->access_log = (char *)xmlCharStrdup (CONFIG_DEFAULT_ACCESS_LOG);
configuration->error_log = (char *)xmlCharStrdup (CONFIG_DEFAULT_ERROR_LOG);
configuration->loglevel = CONFIG_DEFAULT_LOG_LEVEL;
configuration->chroot = CONFIG_DEFAULT_CHROOT;
configuration->chuid = CONFIG_DEFAULT_CHUID;
configuration->user = NULL;
configuration->group = NULL;
configuration->num_yp_directories = 0;
/* default to a typical prebuffer size used by clients */
configuration->burst_size = CONFIG_DEFAULT_BURST_SIZE;
}
static inline void __check_hostname(ice_config_t *configuration) {
char *p;
// ensure we have a non-NULL buffer:
if (!configuration->hostname)
configuration->hostname = (char *)xmlCharStrdup (CONFIG_DEFAULT_HOSTNAME);
// convert to lower case:
for (p = configuration->hostname; *p; p++)
if ( *p >= 'A' && *p <= 'Z' )
*p += 'a' - 'A';
configuration->sane_hostname = 0;
switch (util_hostcheck(configuration->hostname)) {
case HOSTCHECK_SANE:
configuration->sane_hostname = 1;
break;
case HOSTCHECK_ERROR:
ICECAST_LOG_ERROR("Can not check hostname \"%s\".", configuration->hostname);
break;
case HOSTCHECK_NOT_FQDN:
ICECAST_LOG_WARN("Warning, <hostname> seems not to be set to a fully qualified fomain name (FQDN). This may cause problems, e.g. with YP directory listings.");
break;
case HOSTCHECK_IS_LOCALHOST:
ICECAST_LOG_WARN("Warning, <hostname> not configured, using default value \"%s\". This will cause problems, e.g. with YP directory listings.", CONFIG_DEFAULT_HOSTNAME);
break;
case HOSTCHECK_IS_IPV4:
ICECAST_LOG_WARN("Warning, <hostname> seems to be set to an IPv4 address. This may cause problems, e.g. with YP directory listings.");
break;
case HOSTCHECK_IS_IPV6:
ICECAST_LOG_WARN("Warning, <hostname> seems to be set to an IPv6 address. This may cause problems, e.g. with YP directory listings.");
break;
case HOSTCHECK_BADCHAR:
ICECAST_LOG_WARN("Warning, <hostname> configured to unusual characters. This may cause problems, e.g. with YP directory listings.");
break;
}
}
static void _parse_root(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration)
{
char *tmp;
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
char *source_password = NULL;
configuration->listen_sock = calloc (1, sizeof (*configuration->listen_sock));
configuration->listen_sock->port = 8000;
configuration->listen_sock_count = 1;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (xmlStrcmp (node->name, XMLSTR("location")) == 0) {
if (configuration->location) xmlFree(configuration->location);
configuration->location = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("admin")) == 0) {
if (configuration->admin) xmlFree(configuration->admin);
configuration->admin = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("server-id")) == 0) {
xmlFree (configuration->server_id);
configuration->server_id = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
ICECAST_LOG_WARN("Warning, server version string override detected. This may lead to unexpected client software behavior.");
} else if(xmlStrcmp (node->name, XMLSTR("authentication")) == 0) {
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
_parse_authentication(doc, node->xmlChildrenNode, configuration, &source_password);
} else if (xmlStrcmp (node->name, XMLSTR("source-password")) == 0) {
/* TODO: This is the backwards-compatibility location */
ICECAST_LOG_WARN("<source-password> defined outside <authentication>. This is deprecated and will be removed in version 2.5.");
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if (source_password)
xmlFree(source_password);
source_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("icelogin")) == 0) {
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
ICECAST_LOG_ERROR("<icelogin> has been removed.");
} else if (xmlStrcmp (node->name, XMLSTR("fileserve")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->fileserve = util_str_to_bool(tmp);
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("relays-on-demand")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->on_demand = util_str_to_bool(tmp);
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("hostname")) == 0) {
if (configuration->hostname) xmlFree(configuration->hostname);
configuration->hostname = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("mime-types")) == 0) {
if (configuration->mimetypes_fn) xmlFree(configuration->mimetypes_fn);
configuration->mimetypes_fn = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("listen-socket")) == 0) {
_parse_listen_socket(doc, node->xmlChildrenNode, configuration);
} else if (xmlStrcmp (node->name, XMLSTR("port")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
if (tmp) {
configuration->port = atoi(tmp);
configuration->listen_sock->port = atoi(tmp);
xmlFree(tmp);
} else {
ICECAST_LOG_WARN("<port> must not be empty.");
}
} else if (xmlStrcmp (node->name, XMLSTR("bind-address")) == 0) {
if (configuration->listen_sock->bind_address)
xmlFree(configuration->listen_sock->bind_address);
configuration->listen_sock->bind_address = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("master-server")) == 0) {
if (configuration->master_server) xmlFree(configuration->master_server);
configuration->master_server = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("master-username")) == 0) {
if (configuration->master_username) xmlFree(configuration->master_username);
configuration->master_username = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("master-password")) == 0) {
if (configuration->master_password) xmlFree(configuration->master_password);
configuration->master_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("master-server-port")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->master_server_port = atoi(tmp);
xmlFree (tmp);
} else if (xmlStrcmp (node->name, XMLSTR("master-update-interval")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->master_update_interval = atoi(tmp);
xmlFree (tmp);
} else if (xmlStrcmp (node->name, XMLSTR("shoutcast-mount")) == 0) {
if (configuration->shoutcast_mount) xmlFree(configuration->shoutcast_mount);
configuration->shoutcast_mount = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("limits")) == 0) {
_parse_limits(doc, node->xmlChildrenNode, configuration);
} else if (xmlStrcmp (node->name, XMLSTR("http-headers")) == 0) {
_parse_http_headers(doc, node->xmlChildrenNode, &(configuration->http_headers));
} else if (xmlStrcmp (node->name, XMLSTR("relay")) == 0) {
_parse_relay(doc, node->xmlChildrenNode, configuration);
} else if (xmlStrcmp (node->name, XMLSTR("mount")) == 0) {
_parse_mount(doc, node, configuration);
} else if (xmlStrcmp (node->name, XMLSTR("directory")) == 0) {
_parse_directory(doc, node->xmlChildrenNode, configuration);
} else if (xmlStrcmp (node->name, XMLSTR("paths")) == 0) {
_parse_paths(doc, node->xmlChildrenNode, configuration);
} else if (xmlStrcmp (node->name, XMLSTR("logging")) == 0) {
_parse_logging(doc, node->xmlChildrenNode, configuration);
} else if (xmlStrcmp (node->name, XMLSTR("security")) == 0) {
_parse_security(doc, node->xmlChildrenNode, configuration);
}
} while ((node = node->next));
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
/* global source password is set.
* We need to set it on default mount.
* If default mount has a authstack not NULL we don't need to do anything.
*/
if (source_password) {
mount_proxy *mount = config_find_mount(configuration, NULL, MOUNT_TYPE_DEFAULT);
if (!mount) {
/* create a default mount here */
xmlNodePtr node;
node = xmlNewNode(NULL, XMLSTR("mount"));
xmlSetProp(node, XMLSTR("type"), XMLSTR("default"));
_parse_mount(doc, node, configuration);
xmlFreeNode(node);
mount = config_find_mount(configuration, NULL, MOUNT_TYPE_DEFAULT);
}
if (mount) {
if (!mount->authstack)
__append_old_style_auth(&mount->authstack, "legacy-global-source", AUTH_TYPE_STATIC, "source", source_password, NULL, "source,put,get", 0, "*");
} else {
ICECAST_LOG_ERROR("Can not find nor create default mount but global lagency source password set. Bad.");
}
}
/* drop the first listening socket details if more than one is defined, as we only
* have port or listen-socket not both */
if (configuration->listen_sock_count > 1)
{
configuration->listen_sock = config_clear_listener (configuration->listen_sock);
configuration->listen_sock_count--;
}
if (configuration->port == 0)
configuration->port = 8000;
/* issue some warnings on bad configurations */
if (!configuration->fileserve)
ICECAST_LOG_WARN("Warning, serving of static files has been disabled in the config, this will also affect files used by the web interface (stylesheets, images).");
__check_hostname(configuration);
if (!configuration->location || strcmp(configuration->location, CONFIG_DEFAULT_LOCATION) == 0) {
ICECAST_LOG_WARN("Warning, <location> not configured, using default value \"%s\".", CONFIG_DEFAULT_LOCATION);
if (!configuration->location)
configuration->location = (char *)xmlCharStrdup (CONFIG_DEFAULT_LOCATION);
}
if (!configuration->admin || strcmp(configuration->admin, CONFIG_DEFAULT_ADMIN) == 0) {
ICECAST_LOG_WARN("Warning, <admin> contact not configured, using default value \"%s\".", CONFIG_DEFAULT_ADMIN);
if (!configuration->admin)
configuration->admin = (char *)xmlCharStrdup (CONFIG_DEFAULT_ADMIN);
}
}
static void _parse_limits(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration)
{
char *tmp;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (xmlStrcmp (node->name, XMLSTR("clients")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->client_limit = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("sources")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->source_limit = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("queue-size")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->queue_size_limit = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("threadpool")) == 0) {
ICECAST_LOG_WARN("<threadpool> deprecated and will be removed in version 2.5.");
} else if (xmlStrcmp (node->name, XMLSTR("client-timeout")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->client_timeout = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("header-timeout")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->header_timeout = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("source-timeout")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->source_timeout = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("burst-on-connect")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
if (atoi(tmp) == 0)
configuration->burst_size = 0;
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("burst-size")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->burst_size = atoi(tmp);
if (tmp) xmlFree(tmp);
}
} while ((node = node->next));
}
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
static void _parse_mount_oldstyle_authentication(mount_proxy *mount, xmlNodePtr node, auth_stack_t **authstack) {
int allow_duplicate_users = 1;
auth_t *auth;
char *type;
char *name;
char *value;
xmlNodePtr child;
child = node->xmlChildrenNode;
while (child) {
if (xmlStrcmp(node->name, XMLSTR("option")) == 0) {
name = (char *)xmlGetProp(node, XMLSTR("name"));
value = (char *)xmlGetProp(node, XMLSTR("value"));
if (name && value) {
if (strcmp(name, "allow_duplicate_users") == 0) {
allow_duplicate_users = util_str_to_bool(value);
}
}
if (name)
xmlFree(name);
if (value)
xmlFree(value);
}
child = child->next;
}
type = (char *)xmlGetProp(node, XMLSTR("type"));
if (strcmp(type, AUTH_TYPE_HTPASSWD) == 0) {
if (!allow_duplicate_users)
xmlSetProp(node, XMLSTR("connections-per-user"), XMLSTR("0"));
auth = auth_get_authenticator(node);
if (auth) {
auth_stack_push(authstack, auth);
auth_release(auth);
}
__append_old_style_auth(authstack, NULL, AUTH_TYPE_ANONYMOUS, NULL, NULL, "source,put", NULL, 0, NULL);
} else if (strcmp(type, AUTH_TYPE_URL) == 0) {
/* This block is super fun! Attention! Super fun ahead! Ladies and Gentlemans take care and watch your children! */
/* Stuff that was of help:
* $ sed 's/^.*name="\([^"]*\)".*$/ const char *\1 = NULL;/'
* $ sed 's/^.*name="\([^"]*\)".*$/ if (\1)\n xmlFree(\1);/'
* $ sed 's/^.*name="\([^"]*\)".*$/ } else if (strcmp(name, "\1") == 0) {\n \1 = value;\n value = NULL;/'
*/
/* urls */
char *mount_add = NULL;
char *mount_remove = NULL;
char *listener_add = NULL;
char *listener_remove = NULL;
char *stream_auth = NULL;
/* request credentials */
char *username = NULL;
char *password = NULL;
/* general options */
char *auth_header = NULL;
char *timelimit_header = NULL;
char *headers = NULL;
char *header_prefix = NULL;
child = node->xmlChildrenNode;
while (child) {
if (xmlStrcmp(node->name, XMLSTR("option")) == 0) {
name = (char *)xmlGetProp(node, XMLSTR("name"));
value = (char *)xmlGetProp(node, XMLSTR("value"));
if (name && value) {
if (strcmp(name, "mount_add") == 0) {
mount_add = value;
value = NULL;
} else if (strcmp(name, "mount_add") == 0) {
mount_add = value;
value = NULL;
} else if (strcmp(name, "mount_remove") == 0) {
mount_remove = value;
value = NULL;
} else if (strcmp(name, "listener_add") == 0) {
listener_add = value;
value = NULL;
} else if (strcmp(name, "listener_remove") == 0) {
listener_remove = value;
value = NULL;
} else if (strcmp(name, "username") == 0) {
username = value;
value = NULL;
} else if (strcmp(name, "password") == 0) {
password = value;
value = NULL;
} else if (strcmp(name, "auth_header") == 0) {
auth_header = value;
value = NULL;
} else if (strcmp(name, "timelimit_header") == 0) {
timelimit_header = value;
value = NULL;
} else if (strcmp(name, "headers") == 0) {
headers = value;
value = NULL;
} else if (strcmp(name, "header_prefix") == 0) {
header_prefix = value;
value = NULL;
} else if (strcmp(name, "stream_auth") == 0) {
stream_auth = value;
value = NULL;
}
}
if (name)
xmlFree(name);
if (value)
xmlFree(value);
}
child = child->next;
}
/* TODO: FIXME: XXX: implement support for mount_add and mount_remove (using only username and password) here. */
__append_old_style_urlauth(authstack, listener_add, listener_remove, "listener_add", "listener_remove", username, password, 0, auth_header, timelimit_header, headers, header_prefix);
__append_old_style_urlauth(authstack, stream_auth, NULL, "stream_auth", NULL, username, password, 1, auth_header, timelimit_header, headers, header_prefix);
if (listener_add)
__append_old_style_auth(authstack, NULL, AUTH_TYPE_ANONYMOUS, NULL, NULL, "get,put,head", NULL, 0, NULL);
if (stream_auth)
__append_old_style_auth(authstack, NULL, AUTH_TYPE_ANONYMOUS, NULL, NULL, "source,put", NULL, 0, NULL);
if (mount_add)
xmlFree(mount_add);
if (mount_remove)
xmlFree(mount_remove);
if (listener_add)
xmlFree(listener_add);
if (listener_remove)
xmlFree(listener_remove);
if (username)
xmlFree(username);
if (password)
xmlFree(password);
if (auth_header)
xmlFree(auth_header);
if (timelimit_header)
xmlFree(timelimit_header);
if (headers)
xmlFree(headers);
if (header_prefix)
xmlFree(header_prefix);
if (stream_auth)
xmlFree(stream_auth);
} else {
ICECAST_LOG_ERROR("Unknown authentication type in legacy mode. Disable anonymous login listener and global login for source.");
__append_old_style_auth(authstack, NULL, AUTH_TYPE_ANONYMOUS, NULL, NULL, NULL, NULL, 0, NULL);
}
xmlFree(type);
}
static void _parse_mount(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration)
{
char *tmp;
mount_proxy *mount = calloc(1, sizeof(mount_proxy));
mount_proxy *current = configuration->mounts;
mount_proxy *last=NULL;
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
char *username = NULL;
char *password = NULL;
auth_stack_t *authstack = NULL;
/* default <mount> settings */
mount->mounttype = MOUNT_TYPE_NORMAL;
mount->max_listeners = -1;
mount->burst_size = -1;
mount->mp3_meta_interval = -1;
mount->yp_public = -1;
mount->next = NULL;
tmp = (char *)xmlGetProp(node, XMLSTR("type"));
if (tmp) {
if (strcmp(tmp, "normal") == 0) {
mount->mounttype = MOUNT_TYPE_NORMAL;
}
else if (strcmp(tmp, "default") == 0) {
mount->mounttype = MOUNT_TYPE_DEFAULT;
}
else {
ICECAST_LOG_WARN("Unknown mountpoint type: %s", tmp);
config_clear_mount (mount);
return;
}
xmlFree(tmp);
}
node = node->xmlChildrenNode;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (xmlStrcmp (node->name, XMLSTR("mount-name")) == 0) {
mount->mountname = (char *)xmlNodeListGetString (doc, node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("username")) == 0) {
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
username = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("password")) == 0) {
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
password = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("dump-file")) == 0) {
mount->dumpfile = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("intro")) == 0) {
mount->intro_filename = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("fallback-mount")) == 0) {
mount->fallback_mount = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("fallback-when-full")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->fallback_when_full = util_str_to_bool(tmp);
if(tmp) xmlFree(tmp);
}
else if (xmlStrcmp (node->name, XMLSTR("max-listeners")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->max_listeners = atoi(tmp);
if(tmp) xmlFree(tmp);
}
else if (xmlStrcmp (node->name, XMLSTR("charset")) == 0) {
mount->charset = (char *)xmlNodeListGetString(doc,
node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("mp3-metadata-interval")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->mp3_meta_interval = atoi(tmp);
if(tmp) xmlFree(tmp);
}
else if (xmlStrcmp (node->name, XMLSTR("fallback-override")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->fallback_override = util_str_to_bool(tmp);
if(tmp) xmlFree(tmp);
}
else if (xmlStrcmp (node->name, XMLSTR("no-mount")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->no_mount = util_str_to_bool(tmp);
if(tmp) xmlFree(tmp);
}
else if (xmlStrcmp (node->name, XMLSTR("no-yp")) == 0) {
ICECAST_LOG_WARN("<no-yp> defined. Please use <public>. This is deprecated and will be removed in version 2.5.");
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->yp_public = util_str_to_bool(tmp) == 0 ? -1 : 0;
if(tmp) xmlFree(tmp);
}
else if (xmlStrcmp (node->name, XMLSTR("hidden")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->hidden = util_str_to_bool(tmp);
if(tmp) xmlFree(tmp);
}
else if (xmlStrcmp (node->name, XMLSTR("authentication")) == 0) {
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
tmp = (char *)xmlGetProp(node, XMLSTR("type"));
if (tmp) {
xmlFree(tmp);
_parse_mount_oldstyle_authentication(mount, node, &authstack);
} else {
xmlNodePtr child = node->xmlChildrenNode;
do {
if (child == NULL) break;
if (xmlIsBlankNode(child)) continue;
if (xmlStrcmp (child->name, XMLSTR("role")) == 0) {
auth_t *auth = auth_get_authenticator(child);
auth_stack_push(&authstack, auth);
auth_release(auth);
}
} while ((child = child->next));
}
}
else if (xmlStrcmp (node->name, XMLSTR("on-connect")) == 0) {
mount->on_connect = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("on-disconnect")) == 0) {
mount->on_disconnect = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("max-listener-duration")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->max_listener_duration = atoi(tmp);
if(tmp) xmlFree(tmp);
}
else if (xmlStrcmp (node->name, XMLSTR("queue-size")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->queue_size_limit = atoi (tmp);
if(tmp) xmlFree(tmp);
}
else if (xmlStrcmp (node->name, XMLSTR("source-timeout")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
if (tmp)
{
mount->source_timeout = atoi (tmp);
xmlFree(tmp);
}
} else if (xmlStrcmp (node->name, XMLSTR("burst-size")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->burst_size = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("cluster-password")) == 0) {
mount->cluster_password = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("stream-name")) == 0) {
mount->stream_name = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("stream-description")) == 0) {
mount->stream_description = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("stream-url")) == 0) {
mount->stream_url = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("genre")) == 0) {
mount->stream_genre = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("bitrate")) == 0) {
mount->bitrate = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("public")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
mount->yp_public = __parse_public(tmp);
if(tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("type")) == 0) {
mount->type = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("subtype")) == 0) {
mount->subtype = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("http-headers")) == 0) {
_parse_http_headers(doc, node->xmlChildrenNode, &(mount->http_headers));
}
} while ((node = node->next));
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if (password) {
auth_stack_t *old_style = NULL;
__append_old_style_auth(&old_style, "legacy-mount-source", AUTH_TYPE_STATIC, username ? username : "source", password, NULL, "source,put,get", 0, "*");
if (authstack) {
auth_stack_append(old_style, authstack);
auth_stack_release(authstack);
}
authstack = old_style;
}
if (username)
xmlFree(username);
if (password)
xmlFree(password);
if (mount->authstack)
auth_stack_release(mount->authstack);
auth_stack_addref(mount->authstack = authstack);
/* make sure we have at least the mountpoint name */
if (mount->mountname == NULL && mount->mounttype != MOUNT_TYPE_DEFAULT)
{
config_clear_mount (mount);
return;
}
else if (mount->mountname != NULL && mount->mounttype == MOUNT_TYPE_DEFAULT)
{
ICECAST_LOG_WARN("Default mount %s has mount-name set. This is not supported. Behavior may not be consistent.", mount->mountname);
}
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
while (authstack) {
auth_t *auth = auth_stack_get(authstack);
if (mount->mountname) {
auth->mount = strdup((char *)mount->mountname);
} else if (mount->mounttype == MOUNT_TYPE_DEFAULT ) {
auth->mount = strdup("(default mount)");
}
auth_release(auth);
auth_stack_next(&authstack);
}
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
while(current) {
last = current;
current = current->next;
}
if (!mount->fallback_mount && (mount->fallback_when_full || mount->fallback_override))
{
ICECAST_LOG_WARN("Config for mount %s contains fallback options but no fallback mount.", mount->mountname);
}
if(last)
last->next = mount;
else
configuration->mounts = mount;
}
static void _parse_http_headers(xmlDocPtr doc, xmlNodePtr node, ice_config_http_header_t **http_headers) {
ice_config_http_header_t *header;
ice_config_http_header_t *next;
char *name = NULL;
char *value = NULL;
char *tmp;
int status;
http_header_type type;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (xmlStrcmp (node->name, XMLSTR("header")) != 0) continue;
if (!(name = (char *)xmlGetProp(node, XMLSTR("name")))) break;
if (!(value = (char *)xmlGetProp(node, XMLSTR("value")))) break;
type = HTTP_HEADER_TYPE_STATIC; /* default */
if ((tmp = (char *)xmlGetProp(node, XMLSTR("type")))) {
if (strcmp(tmp, "static") == 0) {
type = HTTP_HEADER_TYPE_STATIC;
} else {
ICECAST_LOG_WARN("Unknown type %s for HTTP Header %s", tmp, name);
xmlFree(tmp);
break;
}
xmlFree(tmp);
}
status = 0; /* default: any */
if ((tmp = (char *)xmlGetProp(node, XMLSTR("status")))) {
status = atoi(tmp);
xmlFree(tmp);
}
header = calloc(1, sizeof(ice_config_http_header_t));
if (!header) break;
header->type = type;
header->name = name;
header->value = value;
header->status = status;
name = NULL;
value = NULL;
if (!*http_headers) {
*http_headers = header;
continue;
}
next = *http_headers;
while (next->next) next = next->next;
next->next = header;
} while ((node = node->next));
/* in case we used break we may need to clean those up */
if (name)
xmlFree(name);
if (value)
xmlFree(value);
}
static void _parse_relay(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration)
{
char *tmp;
relay_server *relay = calloc(1, sizeof(relay_server));
relay_server *current = configuration->relay;
relay_server *last=NULL;
while(current) {
last = current;
current = current->next;
}
if(last)
last->next = relay;
else
configuration->relay = relay;
relay->next = NULL;
relay->mp3metadata = 1;
relay->on_demand = configuration->on_demand;
relay->server = (char *) xmlCharStrdup("127.0.0.1");
relay->mount = (char *) xmlCharStrdup("/");
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (xmlStrcmp (node->name, XMLSTR("server")) == 0) {
if (relay->server) xmlFree (relay->server);
relay->server = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("port")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
if (tmp) {
relay->port = atoi(tmp);
xmlFree(tmp);
} else {
ICECAST_LOG_WARN("<port> must not be empty.");
}
}
else if (xmlStrcmp (node->name, XMLSTR("mount")) == 0) {
if (relay->mount) xmlFree (relay->mount);
relay->mount = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("local-mount")) == 0) {
if (relay->localmount) xmlFree (relay->localmount);
relay->localmount = (char *)xmlNodeListGetString(
doc, node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("relay-shoutcast-metadata")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
relay->mp3metadata = util_str_to_bool(tmp);
if(tmp) xmlFree(tmp);
}
else if (xmlStrcmp (node->name, XMLSTR("username")) == 0) {
if (relay->username) xmlFree (relay->username);
relay->username = (char *)xmlNodeListGetString(doc,
node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("password")) == 0) {
if (relay->password) xmlFree (relay->password);
relay->password = (char *)xmlNodeListGetString(doc,
node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("on-demand")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
relay->on_demand = util_str_to_bool(tmp);
if (tmp) xmlFree(tmp);
}
else if (xmlStrcmp (node->name, XMLSTR("bind")) == 0) {
if (relay->bind) xmlFree (relay->bind);
relay->bind = (char *)xmlNodeListGetString (doc, node->xmlChildrenNode, 1);
}
} while ((node = node->next));
if (relay->localmount == NULL)
relay->localmount = (char *)xmlStrdup (XMLSTR(relay->mount));
}
static void _parse_listen_socket(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration)
{
char *tmp;
listener_t *listener = calloc (1, sizeof(listener_t));
if (listener == NULL)
return;
listener->port = 8000;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (xmlStrcmp (node->name, XMLSTR("port")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
if (tmp) {
if(configuration->port == 0)
configuration->port = atoi(tmp);
listener->port = atoi(tmp);
xmlFree(tmp);
} else {
ICECAST_LOG_WARN("<port> must not be empty.");
}
}
else if (xmlStrcmp (node->name, XMLSTR("ssl")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
listener->ssl = util_str_to_bool(tmp);
if(tmp) xmlFree(tmp);
}
else if (xmlStrcmp (node->name, XMLSTR("shoutcast-compat")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
listener->shoutcast_compat = util_str_to_bool(tmp);
if(tmp) xmlFree(tmp);
}
else if (xmlStrcmp (node->name, XMLSTR("shoutcast-mount")) == 0) {
if (listener->shoutcast_mount) xmlFree (listener->shoutcast_mount);
listener->shoutcast_mount = (char *)xmlNodeListGetString(doc,
node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("bind-address")) == 0) {
if (listener->bind_address) xmlFree (listener->bind_address);
listener->bind_address = (char *)xmlNodeListGetString(doc,
node->xmlChildrenNode, 1);
}
else if (xmlStrcmp (node->name, XMLSTR("so-sndbuf")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
listener->so_sndbuf = atoi(tmp);
if(tmp) xmlFree(tmp);
}
} while ((node = node->next));
/* we know there's at least one of these, so add this new one after the first
* that way it can be removed easily later on */
listener->next = configuration->listen_sock->next;
configuration->listen_sock->next = listener;
configuration->listen_sock_count++;
if (listener->shoutcast_mount)
{
listener_t *sc_port = calloc (1, sizeof (listener_t));
sc_port->port = listener->port+1;
sc_port->shoutcast_compat = 1;
sc_port->shoutcast_mount = (char*)xmlStrdup (XMLSTR(listener->shoutcast_mount));
if (listener->bind_address)
sc_port->bind_address = (char*)xmlStrdup (XMLSTR(listener->bind_address));
sc_port->next = listener->next;
listener->next = sc_port;
configuration->listen_sock_count++;
}
}
static void _parse_authentication(xmlDocPtr doc, xmlNodePtr node,
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
ice_config_t *configuration, char **source_password)
{
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
char *admin_password = NULL, *admin_username = NULL;
char *relay_password = NULL, *relay_username = (char*)xmlCharStrdup(CONFIG_DEFAULT_MASTER_USERNAME);
auth_stack_t *old_style = NULL;
auth_stack_t *new_style = NULL;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (xmlStrcmp(node->name, XMLSTR("source-password")) == 0) {
if (xmlGetProp(node, XMLSTR("mount"))) {
ICECAST_LOG_ERROR("Mount level source password defined within global <authentication> section.");
}
else {
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if (*source_password) xmlFree(*source_password);
*source_password =
(char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
}
} else if (xmlStrcmp (node->name, XMLSTR("admin-password")) == 0) {
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if(admin_password) xmlFree(admin_password);
admin_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("admin-user")) == 0) {
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if(admin_username) xmlFree(admin_username);
admin_username = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("relay-password")) == 0) {
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if(relay_password) xmlFree(relay_password);
relay_password = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("relay-user")) == 0) {
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if(relay_username) xmlFree(relay_username);
relay_username = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("role")) == 0) {
auth_t *auth = auth_get_authenticator(node);
auth_stack_push(&new_style, auth);
auth_release(auth);
}
} while ((node = node->next));
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if (admin_password && admin_username)
__append_old_style_auth(&old_style, "legacy-admin", AUTH_TYPE_STATIC, admin_username, admin_password, NULL, "get,post,head", 1, "*");
if (relay_password && relay_username)
__append_old_style_auth(&old_style, "legacy-relay", AUTH_TYPE_STATIC, relay_username, relay_password, NULL, "get", 1, "streamlist.txt");
if (admin_password)
xmlFree(admin_password);
if (admin_username)
xmlFree(admin_username);
if (relay_password)
xmlFree(relay_password);
if (relay_username)
xmlFree(relay_username);
if (old_style && new_style) {
auth_stack_append(old_style, new_style);
auth_stack_release(new_style);
} else if (new_style) {
old_style = new_style;
}
/* default unauthed anonymous account */
__append_old_style_auth(&old_style, "anonymous", AUTH_TYPE_ANONYMOUS, NULL, NULL, NULL, "get,post,head", 1, NULL);
if (!old_style)
ICECAST_LOG_ERROR("BAD. old_style=NULL");
if (configuration->authstack)
auth_stack_release(configuration->authstack);
configuration->authstack = old_style;
}
static void _parse_directory(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration)
{
char *tmp;
if (configuration->num_yp_directories >= MAX_YP_DIRECTORIES) {
ICECAST_LOG_ERROR("Maximum number of yp directories exceeded!");
return;
}
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (xmlStrcmp (node->name, XMLSTR("yp-url")) == 0) {
if (configuration->yp_url[configuration->num_yp_directories])
xmlFree(configuration->yp_url[configuration->num_yp_directories]);
configuration->yp_url[configuration->num_yp_directories] =
(char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("yp-url-timeout")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->yp_url_timeout[configuration->num_yp_directories] =
atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("server")) == 0) {
_add_server(doc, node->xmlChildrenNode, configuration);
} else if (xmlStrcmp (node->name, XMLSTR("touch-interval")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->yp_touch_interval[configuration->num_yp_directories] =
atoi(tmp);
if (tmp) xmlFree(tmp);
}
} while ((node = node->next));
if (configuration->yp_url [configuration->num_yp_directories] == NULL)
return;
configuration->num_yp_directories++;
}
static void _parse_paths(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration)
{
char *temp;
aliases *alias, *current, *last;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (xmlStrcmp (node->name, XMLSTR("basedir")) == 0) {
if (configuration->base_dir) xmlFree(configuration->base_dir);
configuration->base_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("logdir")) == 0) {
if (!(temp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1))) {
ICECAST_LOG_WARN("<logdir> must not be empty.");
continue;
}
if (configuration->log_dir) xmlFree(configuration->log_dir);
configuration->log_dir = temp;
} else if (xmlStrcmp (node->name, XMLSTR("pidfile")) == 0) {
if (configuration->pidfile) xmlFree(configuration->pidfile);
configuration->pidfile = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("nulldevice")) == 0) {
if (configuration->null_device) xmlFree(configuration->null_device);
configuration->null_device = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("deny-ip")) == 0) {
if (configuration->banfile) xmlFree(configuration->banfile);
configuration->banfile = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("allow-ip")) == 0) {
if (configuration->allowfile) xmlFree(configuration->allowfile);
configuration->allowfile = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("ssl-certificate")) == 0) {
if (configuration->cert_file) xmlFree(configuration->cert_file);
configuration->cert_file = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("ssl-allowed-ciphers")) == 0) {
if (configuration->cipher_list) xmlFree(configuration->cipher_list);
configuration->cipher_list = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("webroot")) == 0) {
if (!(temp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1))) {
ICECAST_LOG_WARN("<webroot> must not be empty.");
continue;
}
if (configuration->webroot_dir) xmlFree(configuration->webroot_dir);
configuration->webroot_dir = temp;
if(configuration->webroot_dir[strlen(configuration->webroot_dir)-1] == '/')
configuration->webroot_dir[strlen(configuration->webroot_dir)-1] = 0;
} else if (xmlStrcmp (node->name, XMLSTR("adminroot")) == 0) {
if (!(temp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1))) {
ICECAST_LOG_WARN("<adminroot> must not be empty.");
continue;
}
if (configuration->adminroot_dir)
xmlFree(configuration->adminroot_dir);
configuration->adminroot_dir = (char *)temp;
if(configuration->adminroot_dir[strlen(configuration->adminroot_dir)-1] == '/')
configuration->adminroot_dir[strlen(configuration->adminroot_dir)-1] = 0;
} else if (xmlStrcmp (node->name, XMLSTR("alias")) == 0) {
alias = malloc(sizeof(aliases));
alias->next = NULL;
alias->source = (char *)xmlGetProp(node, XMLSTR("source"));
if(alias->source == NULL) {
free(alias);
continue;
}
alias->destination = (char *)xmlGetProp(node, XMLSTR("destination"));
if (!alias->destination)
alias->destination = (char *)xmlGetProp(node, XMLSTR("dest"));
if(alias->destination == NULL) {
xmlFree(alias->source);
free(alias);
continue;
}
temp = NULL;
temp = (char *)xmlGetProp(node, XMLSTR("port"));
if(temp != NULL) {
alias->port = atoi(temp);
xmlFree(temp);
}
else
alias->port = -1;
alias->bind_address = (char *)xmlGetProp(node, XMLSTR("bind-address"));
alias->vhost = (char *)xmlGetProp(node, XMLSTR("vhost"));
current = configuration->aliases;
last = NULL;
while (current) {
last = current;
current = current->next;
}
if(last)
last->next = alias;
else
configuration->aliases = alias;
}
} while ((node = node->next));
}
static void _parse_logging(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration)
{
char *tmp;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (xmlStrcmp (node->name, XMLSTR("accesslog")) == 0) {
if (!(tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1))) {
ICECAST_LOG_WARN("<accesslog> must not be empty.");
continue;
}
if (configuration->access_log) xmlFree(configuration->access_log);
configuration->access_log = tmp;
} else if (xmlStrcmp (node->name, XMLSTR("errorlog")) == 0) {
if (!(tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1))) {
ICECAST_LOG_WARN("<errorlog> must not be empty.");
continue;
}
if (configuration->error_log) xmlFree(configuration->error_log);
configuration->error_log = tmp;
} else if (xmlStrcmp (node->name, XMLSTR("playlistlog")) == 0) {
if (configuration->playlist_log) xmlFree(configuration->playlist_log);
configuration->playlist_log = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if (xmlStrcmp (node->name, XMLSTR("logsize")) == 0) {
char *tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->logsize = atoi(tmp);
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("loglevel")) == 0) {
char *tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->loglevel = __parse_loglevel(tmp);
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("logarchive")) == 0) {
char *tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->logarchive = atoi(tmp);
if (tmp) xmlFree(tmp);
}
} while ((node = node->next));
}
static void _parse_security(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration)
{
char *tmp;
xmlNodePtr oldnode;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (xmlStrcmp (node->name, XMLSTR("chroot")) == 0) {
tmp = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
configuration->chroot = util_str_to_bool(tmp);
if (tmp) xmlFree(tmp);
} else if (xmlStrcmp (node->name, XMLSTR("changeowner")) == 0) {
configuration->chuid = 1;
oldnode = node;
node = node->xmlChildrenNode;
do {
if(node == NULL) break;
if(xmlIsBlankNode(node)) continue;
if(xmlStrcmp (node->name, XMLSTR("user")) == 0) {
if(configuration->user) xmlFree(configuration->user);
configuration->user = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
} else if(xmlStrcmp (node->name, XMLSTR("group")) == 0) {
if(configuration->group) xmlFree(configuration->group);
configuration->group = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
}
} while((node = node->next));
node = oldnode;
}
} while ((node = node->next));
}
static void _add_server(xmlDocPtr doc, xmlNodePtr node,
ice_config_t *configuration)
{
ice_config_dir_t *dirnode, *server;
int addnode;
char *tmp;
server = (ice_config_dir_t *)malloc(sizeof(ice_config_dir_t));
server->touch_interval = configuration->touch_interval;
server->host = NULL;
addnode = 0;
do {
if (node == NULL) break;
if (xmlIsBlankNode(node)) continue;
if (xmlStrcmp(node->name, XMLSTR("host")) == 0) {
server->host = (char *) xmlNodeListGetString(doc,
node->xmlChildrenNode, 1);
addnode = 1;
} else if (xmlStrcmp(node->name, XMLSTR("touch-interval")) == 0) {
tmp = (char *) xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
server->touch_interval = atoi(tmp);
if (tmp) xmlFree(tmp);
}
server->next = NULL;
} while ((node = node->next));
if (addnode) {
dirnode = configuration->dir_list;
if (dirnode == NULL) {
configuration->dir_list = server;
} else {
while (dirnode->next) dirnode = dirnode->next;
dirnode->next = server;
}
server = NULL;
addnode = 0;
}
else {
free (server);
}
}
static void merge_mounts(mount_proxy * dst, mount_proxy * src) {
ice_config_http_header_t *http_header_next;
ice_config_http_header_t **http_header_tail;
if (!dst || !src)
return;
if (!dst->dumpfile)
dst->dumpfile = (char*)xmlStrdup((xmlChar*)src->dumpfile);
if (!dst->intro_filename)
dst->intro_filename = (char*)xmlStrdup((xmlChar*)src->intro_filename);
if (!dst->fallback_when_full)
dst->fallback_when_full = src->fallback_when_full;
if (dst->max_listeners == -1)
dst->max_listeners = src->max_listeners;
if (!dst->fallback_mount)
dst->fallback_mount = (char*)xmlStrdup((xmlChar*)src->fallback_mount);
if (!dst->fallback_override)
dst->fallback_override = src->fallback_override;
if (!dst->no_mount)
dst->no_mount = src->no_mount;
if (dst->burst_size == -1)
dst->burst_size = src->burst_size;
if (!dst->queue_size_limit)
dst->queue_size_limit = src->queue_size_limit;
if (!dst->hidden)
dst->hidden = src->hidden;
if (!dst->source_timeout)
dst->source_timeout = src->source_timeout;
if (!dst->charset)
dst->charset = (char*)xmlStrdup((xmlChar*)src->charset);
if (dst->mp3_meta_interval == -1)
dst->mp3_meta_interval = src->mp3_meta_interval;
if (!dst->cluster_password)
dst->cluster_password = (char*)xmlStrdup((xmlChar*)src->cluster_password);
if (!dst->on_connect)
dst->on_connect = (char*)xmlStrdup((xmlChar*)src->on_connect);
if (!dst->on_disconnect)
dst->on_disconnect = (char*)xmlStrdup((xmlChar*)src->on_disconnect);
if (!dst->max_listener_duration)
dst->max_listener_duration = src->max_listener_duration;
if (!dst->stream_name)
dst->stream_name = (char*)xmlStrdup((xmlChar*)src->stream_name);
if (!dst->stream_description)
dst->stream_description = (char*)xmlStrdup((xmlChar*)src->stream_description);
if (!dst->stream_url)
dst->stream_url = (char*)xmlStrdup((xmlChar*)src->stream_url);
if (!dst->stream_genre)
dst->stream_genre = (char*)xmlStrdup((xmlChar*)src->stream_genre);
if (!dst->bitrate)
dst->bitrate = (char*)xmlStrdup((xmlChar*)src->bitrate);
if (!dst->type)
dst->type = (char*)xmlStrdup((xmlChar*)src->type);
if (!dst->subtype)
dst->subtype = (char*)xmlStrdup((xmlChar*)src->subtype);
if (dst->yp_public == -1)
dst->yp_public = src->yp_public;
if (dst->http_headers) {
http_header_next = dst->http_headers;
while (http_header_next->next) http_header_next = http_header_next->next;
http_header_tail = &(http_header_next->next);
} else {
http_header_tail = &(dst->http_headers);
}
*http_header_tail = config_copy_http_header(src->http_headers);
}
static inline void _merge_mounts_all(ice_config_t *c) {
mount_proxy *mountinfo = c->mounts;
mount_proxy *default_mount;
for (; mountinfo; mountinfo = mountinfo->next)
{
if (mountinfo->mounttype != MOUNT_TYPE_NORMAL)
continue;
default_mount = config_find_mount(c, mountinfo->mountname, MOUNT_TYPE_DEFAULT);
merge_mounts(mountinfo, default_mount);
}
}
/* return the mount details that match the supplied mountpoint */
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
mount_proxy *config_find_mount (ice_config_t *config, const char *mount, mount_type type) {
mount_proxy *mountinfo = config->mounts;
for (; mountinfo; mountinfo = mountinfo->next)
{
if (mountinfo->mounttype != type)
continue;
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if (!mount && !mountinfo->mountname)
break;
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if (mountinfo->mounttype == MOUNT_TYPE_NORMAL) {
if (!mount || !mountinfo->mountname)
continue;
if (strcmp(mountinfo->mountname, mount) == 0)
break;
} else if (mountinfo->mounttype == MOUNT_TYPE_DEFAULT) {
if (!mountinfo->mountname)
break;
#ifndef _WIN32
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if (fnmatch(mountinfo->mountname, mount, FNM_PATHNAME) == 0)
break;
#else
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
if (strcmp(mountinfo->mountname, mount) == 0)
break;
#endif
Wow. Mega patch! This patch *replaces* the authentication system completly. What is new: - <authentication> in mount section is now a container object. - <authentication> in root and mount section may hold any number of <role>-Tags. - <role> tags: Those tags define a 'role' and it's ACL rules. A role is a instance of an authentication module (see below). <role> takes the following options. All but type are optional. - authentication related: - type: Type of the authentication module (values: anonymous, static, legacy-password, url or htpasswd; symbolic constants in auth.h) - name: Name for the role. For later matching. (values: any string; default: (none)) - method: This rule is only active on the given list of HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - ACL related: - allow-method: Allowed HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: get) - deny-method: Rejected HTTP methods. (list of enum values: methods as recognized by httpp/ (e.g: get,post); default: *) - allow-admin: Allowed admin commands. (list of enum values: admin command; default: buildm3u) - deny-admin: Rejected admin commands. (list of enum values: admin command; default: *) - allow-web: Allowed web pages. (values: empty or *; default: *) - deny-web: Rejected web pages. (values: empty or *; default: (empty)) - connections-per-user: maximum number of simultaneous connections per role and username. This is only active on active sources. (values: unlimited or number of connections; default: unlimited) - connection-duration: maximum time of a connection. This is only active on active sources. (values: unlimited or number of secounds; default: unlimited) <role> takes <option> child tags. <option> tags contain a name and a value option. Meaning of <option> tags is up to the authentication module. - <role>s are considered to build a stack. If a role returns with AUTH_NOMATCH the next one will be tried. - <role>s are tested in this order: mount specific, default mount specific, global, internal fallback. Internal fallback is set to allow web/ access via GET, POST and HEAD (only GET supported by this time) and rejects all other requests. - New authentication module: anonymous This module matches all requests. No options taken. - New authentication module: static This module matches with a static username and password. It takes two <option>s. One with name="username" and one with name="password" to set username and password. This replaces old style <*-username> and <*-password> tags. - New authentication module: legacy-password This module matches with a statich password. It takes one <option> with name="password" to set password. This replaces old ICE and ICY (shoutcast compat mode) authentication. - Parsing <authentication> in <mount> with a type set in a special way to allow 100% backward compatibility. - Parsing of <source-password>, <admin-password>, <admin-user>, <relay-password> and <relay-user> in global <authentication> for 100% backward compatibility. - <alias> is now proccessed very early. This enables them to be used for all kinds of requests. To Do List & What does not yet work: - type="url" auth: mount_add and mount_remove. This should be replaced by an unique feature I would call '<event>'. - Admin commands manageauth and manageauth.xsl are disabled as they need more review: This code needs to be ported to support multiple <role>s per <mount>. - url authentication module can not yet return AUTH_NOMATCH. This needs to be reviewed and discussed on how to handle this case best way. - Default config files needs to be updated to reflect the changes. As this is quite some political act it should be done in dicussion with the whole team and permission of the release manager. - Docs need to be updated to reflect the changes. How does it work: Code has been changed so that authentification is done early for all clients. This allows accessing the ACL data (client->acl) from nearly everywhere in the code. After accept() and initial client setup the request is parsed. In the next step all <alias>es are resolved. After this the client is passed for authentication. After authentication it is passed to the corresponding subsystem depending on kind of request. All authentication instances have a thread running for doing the authentication. This thread works on a queue of clients. Hints for testers: - Test with default config. - Test with diffrent authentication modules in <mount>. - Test shoutcast compatibility mode. - Test with new style <authentication> and any amount of <role> (zero to quite some). - Test <alias> lookup on all kinds of objects. - Test source level credential login into the admin interface. - Test shoucast style meta data updates. - Test playlist generation. Thank you for reading this long commit message. Have fun reading the full patch! svn path=/icecast/trunk/icecast/; revision=19358
2014-11-28 23:46:08 +00:00
}
}
/* retry with default mount */
if (!mountinfo && type == MOUNT_TYPE_NORMAL)
mountinfo = config_find_mount(config, mount, MOUNT_TYPE_DEFAULT);
return mountinfo;
}
/* Helper function to locate the configuration details of the listening
* socket
*/
listener_t *config_get_listen_sock(ice_config_t *config, connection_t *con)
{
listener_t *listener;
int i = 0;
listener = config->listen_sock;
while (listener)
{
if (i >= global.server_sockets)
listener = NULL;
else
{
if (global.serversock[i] == con->serversock)
break;
listener = listener->next;
i++;
}
}
return listener;
}