/* wrapper function for auth thread to authenticate new listener * connection details */ static void auth_new_listener (auth_t *auth, auth_client *auth_user) { client_t *client = auth_user->client; /* make sure there is still a client at this point, a slow backend request * can be avoided if client has disconnected */ if (is_listener_connected (client) == 0) { ICECAST_LOG_DEBUG("listener is no longer connected"); client->respcode = 400; auth_release (client->auth); client->auth = NULL; return; } if (auth->authenticate) { if (auth->authenticate (auth_user) != AUTH_OK) { auth_release (client->auth); client->auth = NULL; return; } } if (auth_postprocess_listener (auth_user) < 0) { auth_release (client->auth); client->auth = NULL; ICECAST_LOG_INFO("client %lu failed", client->con->id); } }
static void config_clear_mount (mount_proxy *mount) { config_options_t *option; if (mount->mountname) xmlFree (mount->mountname); if (mount->username) xmlFree (mount->username); if (mount->password) xmlFree (mount->password); 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); if (mount->auth_type) xmlFree (mount->auth_type); option = mount->auth_options; while (option) { config_options_t *nextopt = option->next; if (option->name) xmlFree (option->name); if (option->value) xmlFree (option->value); free (option); option = nextopt; } auth_release (mount->auth); free (mount); }
/* wrapper function for auth thread to drop listener connections */ static void auth_remove_listener (auth_t *auth, auth_client *auth_user) { client_t *client = auth_user->client; if (client->auth->release_listener) client->auth->release_listener (auth_user); auth_release (client->auth); client->auth = NULL; /* client is going, so auth is not an issue at this point */ client->authenticated = 0; }
static inline void __add_authstack (auth_stack_t *stack, xmlNodePtr parent) { xmlNodePtr authentication; authentication = xmlNewTextChild(parent, NULL, XMLSTR("authentication"), NULL); auth_stack_addref(stack); while (stack) { auth_t *auth = auth_stack_get(stack); admin_add_role_to_authentication(auth, authentication); auth_release(auth); auth_stack_next(&stack); } }
/* Called from auth thread to process any request for source client * authentication. Only applies to source clients, not relays. */ static void stream_auth_callback (auth_t *auth, auth_client *auth_user) { client_t *client = auth_user->client; if (auth->stream_auth) auth->stream_auth (auth_user); auth_release (auth); client->auth = NULL; if (client->authenticated) auth_postprocess_source (auth_user); else ICECAST_LOG_WARN("Failed auth for source \"%s\"", auth_user->mount); }
static void url_stream_end (auth_client *auth_user) { char *mount, *server; ice_config_t *config = config_get_config (); mount_proxy *mountinfo = config_find_mount (config, auth_user->mount, MOUNT_TYPE_NORMAL); auth_t *auth = mountinfo->auth; auth_url *url = auth->state; char *stream_end_url; int port; char post [4096]; if (url->stream_end == NULL) { config_release_config (); return; } server = util_url_escape (config->hostname); port = config->port; stream_end_url = strdup (url->stream_end); /* we don't want this auth disappearing from under us while * the connection is in progress */ mountinfo->auth->refcount++; config_release_config (); mount = util_url_escape (auth_user->mount); snprintf (post, sizeof (post), "action=mount_remove&mount=%s&server=%s&port=%d", mount, server, port); free (server); free (mount); if (strchr (url->stream_end, '@') == NULL) { if (url->userpwd) curl_easy_setopt (url->handle, CURLOPT_USERPWD, url->userpwd); else curl_easy_setopt (url->handle, CURLOPT_USERPWD, ""); } else curl_easy_setopt (url->handle, CURLOPT_USERPWD, ""); curl_easy_setopt (url->handle, CURLOPT_URL, url->stream_end); curl_easy_setopt (url->handle, CURLOPT_POSTFIELDS, post); curl_easy_setopt (url->handle, CURLOPT_WRITEHEADER, auth_user); if (curl_easy_perform (url->handle)) ICECAST_LOG_WARN("auth to server %s failed with %s", stream_end_url, url->errormsg); auth_release (auth); free (stream_end_url); return; }
static void config_clear_mount (mount_proxy *mount) { config_options_t *option; if (mount->username) xmlFree (mount->username); if (mount->password) xmlFree (mount->password); 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->subtype) xmlFree (mount->subtype); if (mount->charset) xmlFree (mount->charset); if (mount->cluster_password) xmlFree (mount->cluster_password); if (mount->auth_type) xmlFree (mount->auth_type); option = mount->auth_options; while (option) { config_options_t *nextopt = option->next; if (option->name) xmlFree (option->name); if (option->value) xmlFree (option->value); free (option); option = nextopt; } if (mount->auth) { thread_mutex_lock (&mount->auth->lock); auth_release (mount->auth); } if (mount->access_log.logid >= 0) log_close (mount->access_log.logid); xmlFree (mount->access_log.name); xmlFree (mount->access_log.exclude_ext); xmlFree (mount->mountname); free (mount); }
/* The auth thread main loop. */ static void *auth_run_thread (void *arg) { auth_thread_t *handler = arg; auth_t *auth = handler->auth; DEBUG2 ("Authentication thread %d started for %s", handler->id, auth->mount); thread_rwlock_rlock (&auth_lock); while (1) { thread_mutex_lock (&auth->lock); if (auth->head) { auth_client *auth_user = auth->head; DEBUG2 ("%d client(s) pending on %s", auth->pending_count, auth->mount); auth->head = auth_user->next; if (auth->head == NULL) auth->tailp = &auth->head; auth->pending_count--; thread_mutex_unlock (&auth->lock); auth_user->next = NULL; /* associate per-thread data with auth_user here */ auth_user->thread_data = handler->data; auth_user->handler = handler->id; if (auth_user->process) auth_user->process (auth_user); auth_client_free (auth_user); continue; } handler->thread = NULL; break; } DEBUG1 ("Authenication thread %d shutting down", handler->id); auth_release (auth); thread_rwlock_unlock (&auth_lock); return NULL; }
/* Callback from auth thread to handle a stream start event, this applies * to both source clients and relays. */ static void stream_end_callback (auth_t *auth, auth_client *auth_user) { if (auth->stream_end) auth->stream_end (auth_user); auth_release (auth); }
/* Callback from auth thread to handle a stream start event, this applies * to both source clients and relays. */ static void stream_start_callback (auth_t *auth, auth_client *auth_user) { if (auth->stream_start) auth->stream_start (auth_user); auth_release (auth); }