From ed266a5dc7b330dd90de0413cb97dd79a3f79731 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Thu, 13 Sep 2018 11:34:01 +0000 Subject: [PATCH] Feature: Added per --- src/cfgfile.c | 18 ++++++++++++++++++ src/cfgfile.h | 1 + src/connection.c | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 2 deletions(-) diff --git a/src/cfgfile.c b/src/cfgfile.c index e3a426ff..2e9a70b2 100644 --- a/src/cfgfile.c +++ b/src/cfgfile.c @@ -616,6 +616,7 @@ listener_t *config_clear_listener(listener_t *listener) if (listener->on_behalf_of) free(listener->on_behalf_of); if (listener->bind_address) xmlFree(listener->bind_address); if (listener->shoutcast_mount) xmlFree(listener->shoutcast_mount); + if (listener->authstack) auth_stack_release(listener->authstack); free (listener); } return next; @@ -1893,6 +1894,19 @@ static void _parse_listen_socket(xmlDocPtr doc, node->xmlChildrenNode, 1); } else if (xmlStrcmp(node->name, XMLSTR("so-sndbuf")) == 0) { __read_int(doc, node, &listener->so_sndbuf, " must not be empty."); + } else if (xmlStrcmp(node->name, XMLSTR("authentication")) == 0) { + 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(&(listener->authstack), auth); + auth_release(auth); + } + } while ((child = child->next)); } } while ((node = node->next)); @@ -2613,5 +2627,9 @@ listener_t *config_copy_listener_one(const listener_t *listener) { n->shoutcast_mount = (char*)xmlStrdup(XMLSTR(listener->shoutcast_mount)); n->tls = listener->tls; + if (listener->authstack) { + auth_stack_addref(n->authstack = listener->authstack); + } + return n; } diff --git a/src/cfgfile.h b/src/cfgfile.h index f83ac78d..35a2e6e2 100644 --- a/src/cfgfile.h +++ b/src/cfgfile.h @@ -165,6 +165,7 @@ typedef struct _listener_t { int shoutcast_compat; char *shoutcast_mount; tlsmode_t tls; + auth_stack_t *authstack; } listener_t; typedef struct _config_tls_context { diff --git a/src/connection.c b/src/connection.c index 0abf4e31..b56bd5dc 100644 --- a/src/connection.c +++ b/src/connection.c @@ -1411,16 +1411,46 @@ static void _handle_authentication_mount_default(client_t *client, void *uri, au _handle_authentication_mount_generic(client, uri, MOUNT_TYPE_DEFAULT, _handle_authentication_global); } -static void _handle_authentication_mount_normal(client_t *client, char *uri) +static void _handle_authentication_mount_normal(client_t *client, void *uri, auth_result result) { + auth_stack_release(client->authstack); + client->authstack = NULL; + + if (result != AUTH_NOMATCH && + !(result == AUTH_OK && client->admin_command != ADMIN_COMMAND_ERROR && acl_test_admin(client->acl, client->admin_command) == ACL_POLICY_DENY)) { + _handle_authed_client(client, uri, result); + return; + } + ICECAST_LOG_DEBUG("Trying specific authenticators for client %p.", client); _handle_authentication_mount_generic(client, uri, MOUNT_TYPE_NORMAL, _handle_authentication_mount_default); } +static void _handle_authentication_listen_socket(client_t *client, char *uri) +{ + auth_stack_t *stack = NULL; + const listener_t *listener; + + listener = listensocket_get_listener(client->con->listensocket_effective); + if (listener) { + if (listener->authstack) { + auth_stack_addref(stack = listener->authstack); + } + listensocket_release_listener(client->con->listensocket_effective); + } + + if (stack) { + auth_stack_add_client(stack, client, _handle_authentication_mount_normal, uri); + auth_stack_release(stack); + } else { + _handle_authentication_mount_normal(client, uri, AUTH_NOMATCH); + } +} + static void _handle_authentication(client_t *client, char *uri) { fastevent_emit(FASTEVENT_TYPE_CLIENT_READY_FOR_AUTH, FASTEVENT_FLAG_MODIFICATION_ALLOWED, FASTEVENT_DATATYPE_CLIENT, client); - _handle_authentication_mount_normal(client, uri); + _handle_authentication_listen_socket(client, uri); } static void __prepare_shoutcast_admin_cgi_request(client_t *client)