xiph / Icecast-Server

Icecast streaming media server (Mirror) - Please report bugs at https://gitlab.xiph.org/xiph/icecast-server/issues
https://icecast.org
GNU General Public License v2.0
465 stars 127 forks source link

/admin/listclients with URL authentication returns 403 Forbidden Mountpoint in use #66

Open TheRealMattLear opened 11 months ago

TheRealMattLear commented 11 months ago

Normally the /admin/listclients?mountpoint=/stream URL is accessible by authenticating with the <source-password> (when not using Mountpoint Authentication. However when specifying <authentication type="url"> with the stream_auth option the end-point returns 403 Forbidden with "Mountpoint in use".

A similar issue has been created 3 years ago at xiph.org, however i've created this with more information.

This end-point is specifically used by RadioCaster (possibly other encoders) to present the listeners on the connected mount.

In our testing:

Example configuration where "Mountpoint in use" error is presented (auth.php always returning header icecast-auth-user: 1), even if using authentication of source:source-password

<icecast>
    <limits>
        ...
    </limits>

    <authentication>
        <source-password>source-password</source-password>
        <admin-user>admin</admin-user>
        <admin-password>admin-password</admin-password>
    </authentication>
    <mount>
      <mount-name>/stream</mount-name>
      <charset>UTF-8</charset>
      <bitrate>128</bitrate>
      <authentication type="url">
        <option name="stream_auth" value="http://localhost/auth.php"/>
      </authentication>
    </mount>
    ...
</icecast>

Example configuration that works successfully with source:source-password

<icecast>
    <limits>
        ...
    </limits>

    <authentication>
        <source-password>source-password</source-password>
        <admin-user>admin</admin-user>
        <admin-password>admin-password</admin-password>
    </authentication>
    <mount>
      <mount-name>/stream</mount-name>
      <charset>UTF-8</charset>
      <bitrate>128</bitrate>
    </mount>
    ...
</icecast>

Notably in the log files

Here is the error.log[5] when using URL auth:

[2023-08-11  04:09:33] DBUG admin/admin_handle_request Got command (listclients)
[2023-08-11  04:09:33] INFO auth/auth_stream_authenticate request source auth for "/stream"
[2023-08-11  04:09:33] DBUG auth/queue_auth_client ...refcount on auth_t /stream is now 2
[2023-08-11  04:09:33] INFO auth/queue_auth_client auth on /stream has 1 pending
[2023-08-11  04:09:33] DBUG auth/auth_run_thread 1 client(s) pending on /stream
[2023-08-11  04:09:33] DBUG stats/modify_node_event update global clients (2)
[2023-08-11  04:09:33] DBUG stats/modify_node_event update global connections (587)
[2023-08-11  04:09:33] DBUG stats/modify_node_event update global client_connections (563)
[2023-08-11  04:09:33] DBUG auth/auth_release ...refcount on auth_t /stream is now 1
[2023-08-11  04:09:33] DBUG auth/auth_postprocess_source on mountpoint /stream
[2023-08-11  04:09:33] DBUG fserve/fserve_add_client Adding client to file serving engine
[2023-08-11  04:09:33] DBUG fserve/fserve_add_pending fserve handler waking up
[2023-08-11  04:09:33] WARN connection/source_startup Mountpoint /stream in use

Is it something to do with auth.c auth_postprocess_source only checking for admin.cgi and /admin/metadata? Should it also be looking for /admin/listclients and then pass admin_handle_request(client,"/admin/listclients") or something?


/* Decide whether we need to start a source or just process a source
 * admin request.
 */
void auth_postprocess_source (auth_client *auth_user)
{
    client_t *client = auth_user->client;
    const char *mount = auth_user->mount;
    const char *req = httpp_getvar (client->parser, HTTPP_VAR_URI);

    auth_user->client = NULL;
    client->authenticated = 1;
    if (strcmp (req, "/admin.cgi") == 0 || strncmp ("/admin/metadata", req, 15) == 0)
    {
        ICECAST_LOG_DEBUG("metadata request (%s, %s)", req, mount);
        admin_handle_request (client, "/admin/metadata");
    }
    else
    {
        ICECAST_LOG_DEBUG("on mountpoint %s", mount);
        source_startup (client, mount, 0);
    }
}