void admin_handle_request(client_t *client, const char *uri) { const char *mount, *command_string; int command; DEBUG1("Admin request (%s)", uri); if (!((strcmp(uri, "/admin.cgi") == 0) || (strncmp("/admin/", uri, 7) == 0))) { ERROR0("Internal error: admin request isn't"); client_send_401(client); return; } if (strcmp(uri, "/admin.cgi") == 0) { command_string = uri + 1; } else { command_string = uri + 7; } DEBUG1("Got command (%s)", command_string); command = admin_get_command(command_string); if(command < 0) { ERROR1("Error parsing command string or unrecognised command: %s", command_string); client_send_400(client, "Unrecognised command"); return; } if (command == COMMAND_SHOUTCAST_METADATA_UPDATE) { ice_config_t *config; const char *sc_mount; const char *pass = httpp_get_query_param (client->parser, "pass"); listener_t *listener; if (pass == NULL) { client_send_400 (client, "missing pass parameter"); return; } config = config_get_config (); sc_mount = config->shoutcast_mount; listener = config_get_listen_sock (config, client->con); if (listener && listener->shoutcast_mount) sc_mount = listener->shoutcast_mount; httpp_set_query_param (client->parser, "mount", sc_mount); httpp_setvar (client->parser, HTTPP_VAR_PROTOCOL, "ICY"); httpp_setvar (client->parser, HTTPP_VAR_ICYPASSWORD, pass); config_release_config (); } mount = httpp_get_query_param(client->parser, "mount"); if(mount != NULL) { source_t *source; /* this request does not require auth but can apply to files on webroot */ if (command == COMMAND_BUILDM3U) { command_buildm3u (client, mount); return; } /* This is a mount request, handle it as such */ if (!connection_check_admin_pass(client->parser)) { if (!connection_check_source_pass(client->parser, mount)) { INFO1("Bad or missing password on mount modification admin " "request (command: %s)", command_string); client_send_401(client); return; } } avl_tree_rlock(global.source_tree); source = source_find_mount_raw(mount); if (source == NULL) { WARN2("Admin command %s on non-existent source %s", command_string, mount); avl_tree_unlock(global.source_tree); client_send_400(client, "Source does not exist"); } else { if (source->running == 0 && source->on_demand == 0) { avl_tree_unlock (global.source_tree); INFO2("Received admin command %s on unavailable mount \"%s\"", command_string, mount); client_send_400 (client, "Source is not available"); return; } if (command == COMMAND_SHOUTCAST_METADATA_UPDATE && source->shoutcast_compat == 0) { avl_tree_unlock (global.source_tree); ERROR0 ("illegal change of metadata on non-shoutcast " "compatible stream"); client_send_400 (client, "illegal metadata call"); return; } INFO2("Received admin command %s on mount \"%s\"", command_string, mount); admin_handle_mount_request(client, source, command); avl_tree_unlock(global.source_tree); } } else { if (command == COMMAND_PLAINTEXT_LISTSTREAM) { /* this request is used by a slave relay to retrieve mounts from the master, so handle this request validating against the relay password */ if(!connection_check_relay_pass(client->parser)) { INFO1("Bad or missing password on admin command " "request (command: %s)", command_string); client_send_401(client); return; } } else { if(!connection_check_admin_pass(client->parser)) { INFO1("Bad or missing password on admin command " "request (command: %s)", command_string); client_send_401(client); return; } } admin_handle_general_request(client, command); } }
int admin_handle_request (client_t *client, const char *uri) { const char *mount = httpp_get_query_param(client->parser, "mount"); if (strcmp (uri, "/admin.cgi") == 0) { const char *pass = httpp_get_query_param (client->parser, "pass"); if (pass == NULL) return client_send_400 (client, "missing pass parameter"); uri++; if (mount == NULL) { if (client->server_conn && client->server_conn->shoutcast_mount) httpp_set_query_param (client->parser, "mount", client->server_conn->shoutcast_mount); mount = httpp_get_query_param (client->parser, "mount"); } httpp_setvar (client->parser, HTTPP_VAR_PROTOCOL, "ICY"); httpp_setvar (client->parser, HTTPP_VAR_ICYPASSWORD, pass); client->username = strdup ("source"); client->password = strdup (pass); } else uri += 7; if (connection_check_admin_pass (client->parser)) client->flags |= CLIENT_AUTHENTICATED; else { /* special case for slaves requesting a streamlist for authenticated relaying */ if (strcmp (uri, "streams") == 0 || strcmp (uri, "streamlist.txt") == 0) { if (connection_check_relay_pass (client->parser)) client->flags |= CLIENT_AUTHENTICATED; } } if (mount) { /* no auth/stream required for this */ if (strcmp (uri, "buildm3u") == 0) return command_buildm3u (client, mount); if (strcmp (uri, "showimage") == 0) return command_show_image (client, mount); /* This is a mount request, but admin user is allowed */ if ((client->flags & CLIENT_AUTHENTICATED) == 0) { switch (auth_check_source (client, mount)) { case 0: break; default: INFO1("Bad or missing password on mount modification " "admin request (%s)", uri); return client_send_401 (client, NULL); /* fall through */ case 1: return 0; } } if (strcmp (uri, "streams") == 0) return auth_add_listener ("/admin/streams", client); return admin_mount_request (client, uri); } return admin_handle_general_request (client, uri); }