[xiph-cvs] r6711 - in icecast/trunk/icecast: conf doc src

oddsock at xiph.org oddsock at xiph.org
Sun May 16 21:33:47 PDT 2004



Author: oddsock
Date: 2004-05-17 00:33:46 -0400 (Mon, 17 May 2004)
New Revision: 6711

Modified:
   icecast/trunk/icecast/conf/icecast.xml.in
   icecast/trunk/icecast/doc/icecast2_config_file.html
   icecast/trunk/icecast/doc/icecast2_listenerauth.html
   icecast/trunk/icecast/src/auth.c
   icecast/trunk/icecast/src/auth.h
   icecast/trunk/icecast/src/client.c
   icecast/trunk/icecast/src/client.h
   icecast/trunk/icecast/src/connection.c
Log:
added ability to disallow concurrent connections from the same username if using htpasswd listener authentication.

<p>Modified: icecast/trunk/icecast/conf/icecast.xml.in
===================================================================
--- icecast/trunk/icecast/conf/icecast.xml.in	2004-05-17 03:58:54 UTC (rev 6710)
+++ icecast/trunk/icecast/conf/icecast.xml.in	2004-05-17 04:33:46 UTC (rev 6711)
@@ -86,6 +86,7 @@
         <fallback-mount>/example2.ogg</fallback-mount>
         <authentication type="htpasswd">
                 <option name="filename" value="myauth"/>
+                <option name="allow_duplicate_users" value="0"/>
         </authentication>
     </mount>
     -->

Modified: icecast/trunk/icecast/doc/icecast2_config_file.html
===================================================================
--- icecast/trunk/icecast/doc/icecast2_config_file.html	2004-05-17 03:58:54 UTC (rev 6710)
+++ icecast/trunk/icecast/doc/icecast2_config_file.html	2004-05-17 04:33:46 UTC (rev 6711)
@@ -273,6 +273,7 @@
         &lt;fallback-mount&gt;example2.ogg&lt;fallback-mount&gt;
         &lt;authentication type="htpasswd"&gt;
                 &lt;option name="filename" value="myauth"/&gt;
+                &lt;option name="allow_duplicate_users" value="0"/&gt;
         &lt;/authentication&gt;
 
     &lt;mount&gt;
@@ -305,7 +306,7 @@
 </div>
 <h4>authentication</h4>
 <div class=indentedbox>
-This specifies that the named mount point will require listener authentication.  Currently, we only support a file-based authentication scheme (type=htpasswd).  Users and encrypted password are placed in this file (separated by a :) and all requests for this mountpoint will require that a user and password be supplied for authentication purposes.  These values are passed in via normal HTTP Basic Authentication means (i.e. http://user:password@stream:port/mountpoint.ogg).  Users and Passwords are maintained via the web admin interface.  A mountpoint configured with an authenticator will display a red key next to the mount point name on the admin screens.
+This specifies that the named mount point will require listener authentication.  Currently, we only support a file-based authentication scheme (type=htpasswd).  Users and encrypted password are placed in this file (separated by a :) and all requests for this mountpoint will require that a user and password be supplied for authentication purposes.  These values are passed in via normal HTTP Basic Authentication means (i.e. http://user:password@stream:port/mountpoint.ogg).  Users and Passwords are maintained via the web admin interface.  A mountpoint configured with an authenticator will display a red key next to the mount point name on the admin screens.  You can read more about listener authentication here.
 </div>
 <br>
 <br>

Modified: icecast/trunk/icecast/doc/icecast2_listenerauth.html
===================================================================
--- icecast/trunk/icecast/doc/icecast2_listenerauth.html	2004-05-17 03:58:54 UTC (rev 6710)
+++ icecast/trunk/icecast/doc/icecast2_listenerauth.html	2004-05-17 04:33:46 UTC (rev 6711)
@@ -20,10 +20,11 @@
         &lt;mount-name&gt;/example-complex.ogg&lt;/mount-name&gt;
         &lt;authentication type="htpasswd"&gt;
                 &lt;option name="filename" value="myauth"/&gt;
+                &lt;option name="allow_duplicate_users" value="0"/&gt;
         &lt;/authentication&gt;
     &lt;/mount&gt;
 </pre>
-<p>To support listener authentication you MUST provide at a minimum &lt;mount-name&gt; and &lt;authentication&gt;.  The mount-name is the name of the mountpoint that you will use to connect your source client with and authentication configures what type of icecast2 authenticator to use.  Currently, only a single type "htpasswd" is implemented.  New authenticators will be added later.  Each authenticator has a variable number of options that are required and these are specified as shown in the example.  The htpasswd authenticator requires only a single parameter, filename, which specifies the name of the file to use to store users and passwords.  Note that this file need not exist (and probably will not exist when you first set it up).  Icecast has built-in support for managing users and passwords via the web admin interface.  More on this later in this section.</p>
+<p>To support listener authentication you MUST provide at a minimum &lt;mount-name&gt; and &lt;authentication&gt;.  The mount-name is the name of the mountpoint that you will use to connect your source client with and authentication configures what type of icecast2 authenticator to use.  Currently, only a single type "htpasswd" is implemented.  New authenticators will be added later.  Each authenticator has a variable number of options that are required and these are specified as shown in the example.  The htpasswd authenticator requires a few parameters.  The first, filename, specifies the name of the file to use to store users and passwords.  Note that this file need not exist (and probably will not exist when you first set it up).  Icecast has built-in support for managing users and passwords via the web admin interface.  More on this later in this section.  The second option, allow_duplicate_users, if set to 0, will prevent multiple connections using the same username.  Setting this value to 1 will enab
le mutltiple connections from the same username on a given mountpoint.  Note there is no way to specify a "max connections" for a particular user.
 
 <p>Icecast supports a mixture of streams that require listener authentication and those that do not.  Only mounts that are named in the config file can be configured for listener authentication.</p>
 <br>

Modified: icecast/trunk/icecast/src/auth.c
===================================================================
--- icecast/trunk/icecast/src/auth.c	2004-05-17 03:58:54 UTC (rev 6710)
+++ icecast/trunk/icecast/src/auth.c	2004-05-17 04:33:46 UTC (rev 6711)
@@ -34,6 +34,30 @@
 #define CATMODULE "auth"
 
 
+int auth_is_listener_connected(source_t *source, char *username)
+{
+    client_t *client;
+    avl_node *client_node;
+
+    avl_tree_rlock(source->client_tree);
+
+    client_node = avl_get_first(source->client_tree);
+    while(client_node) {
+        client = (client_t *)client_node->key;
+        if (client->username) {
+            if (!strcmp(client->username, username)) {
+                avl_tree_unlock(source->client_tree);
+                return 1;
+            }
+        }
+        client_node = avl_get_next(client_node);
+    }
+
+    avl_tree_unlock(source->client_tree);
+    return 0;
+
+}
+
 auth_result auth_check_client(source_t *source, client_t *client)
 {
     auth_t *authenticator = source->authenticator;
@@ -71,7 +95,7 @@
         password = tmp+1;
 
         result = authenticator->authenticate(
-                authenticator, username, password);
+                authenticator, source, username, password);
 
         if(result == AUTH_OK)
             client->username = strdup(username);
@@ -106,6 +130,7 @@
 
 typedef struct {
     char *filename;
+    int allow_duplicate_users;
     rwlock_t file_rwlock;
 } htpasswd_auth_state;
 
@@ -150,14 +175,21 @@
 #define MAX_LINE_LEN 512
 
 /* Not efficient; opens and scans the entire file for every request */
-static auth_result htpasswd_auth(auth_t *auth, char *username, char *password)
+static auth_result htpasswd_auth(auth_t *auth, source_t *source, char *username, char *password)
 {
     htpasswd_auth_state *state = auth->state;
-    FILE *passwdfile = fopen(state->filename, "rb");
+    FILE *passwdfile = NULL;
     char line[MAX_LINE_LEN];
     char *sep;
 
     thread_rwlock_rlock(&state->file_rwlock);
+    if (!state->allow_duplicate_users) {
+        if (auth_is_listener_connected(source, username)) {
+            thread_rwlock_unlock(&state->file_rwlock);
+            return AUTH_FORBIDDEN;
+        }
+    }
+    passwdfile = fopen(state->filename, "rb");
     if(passwdfile == NULL) {
         WARN2("Failed to open authentication database \"%s\": %s", 
                 state->filename, strerror(errno));
@@ -208,9 +240,12 @@
 
     state = calloc(1, sizeof(htpasswd_auth_state));
 
+    state->allow_duplicate_users = 1;
     while(options) {
         if(!strcmp(options->name, "filename"))
             state->filename = strdup(options->value);
+        if(!strcmp(options->name, "allow_duplicate_users"))
+            state->allow_duplicate_users = atoi(options->value);
         options = options->next;
     }
 
@@ -458,3 +493,4 @@
     }
     return ret;
 }
+

Modified: icecast/trunk/icecast/src/auth.h
===================================================================
--- icecast/trunk/icecast/src/auth.h	2004-05-17 03:58:54 UTC (rev 6710)
+++ icecast/trunk/icecast/src/auth.h	2004-05-17 04:33:46 UTC (rev 6711)
@@ -24,6 +24,7 @@
 {
     AUTH_OK,
     AUTH_FAILED,
+    AUTH_FORBIDDEN,
     AUTH_USERADDED,
     AUTH_USEREXISTS,
     AUTH_USERDELETED,
@@ -33,7 +34,7 @@
 {
     /* Authenticate using the given username and password */
     auth_result (*authenticate)(struct auth_tag *self, 
-            char *username, char *password);
+            source_t *source, char *username, char *password);
     void (*free)(struct auth_tag *self);
     void *state;
     void *type;

Modified: icecast/trunk/icecast/src/client.c
===================================================================
--- icecast/trunk/icecast/src/client.c	2004-05-17 03:58:54 UTC (rev 6710)
+++ icecast/trunk/icecast/src/client.c	2004-05-17 04:33:46 UTC (rev 6711)
@@ -115,3 +115,13 @@
     client->respcode = 401;
     client_destroy(client);
 }
+
+void client_send_403(client_t *client) {
+    int bytes = sock_write(client->con->sock, 
+            "HTTP/1.0 403 Forbidden\r\n"
+            "\r\n"
+            "Access restricted.\r\n");
+    if(bytes > 0) client->con->sent_bytes = bytes;
+    client->respcode = 403;
+    client_destroy(client);
+}

Modified: icecast/trunk/icecast/src/client.h
===================================================================
--- icecast/trunk/icecast/src/client.h	2004-05-17 03:58:54 UTC (rev 6710)
+++ icecast/trunk/icecast/src/client.h	2004-05-17 04:33:46 UTC (rev 6711)
@@ -53,6 +53,7 @@
 void client_send_504(client_t *client, char *message);
 void client_send_404(client_t *client, char *message);
 void client_send_401(client_t *client);
+void client_send_403(client_t *client);
 void client_send_400(client_t *client, char *message);
 
 #endif  /* __CLIENT_H__ */

Modified: icecast/trunk/icecast/src/connection.c
===================================================================
--- icecast/trunk/icecast/src/connection.c	2004-05-17 03:58:54 UTC (rev 6710)
+++ icecast/trunk/icecast/src/connection.c	2004-05-17 04:33:46 UTC (rev 6711)
@@ -753,6 +753,7 @@
     aliases *alias;
     ice_config_t *config;
     int client_limit;
+    int ret;
 
     config = config_get_config();
     fileserve = config->fileserve;
@@ -916,11 +917,20 @@
 
         /* Check for any required authentication first */
         if(source->authenticator != NULL) {
-            if(auth_check_client(source, client) != AUTH_OK) {
+            ret = auth_check_client(source, client);
+            if(ret != AUTH_OK) {
                 avl_tree_unlock(global.source_tree);
-                INFO1("Client attempted to log in to source (\"%s\")with "
+                if (ret == AUTH_FORBIDDEN) {
+                    INFO1("Client attempted to log multiple times to source "
+                        "(\"%s\")", uri);
+                    client_send_403(client);
+                }
+                else {
+                /* If not FORBIDDEN, default to 401 */
+                    INFO1("Client attempted to log in to source (\"%s\")with "
                         "incorrect or missing password", uri);
-                client_send_401(client);
+                    client_send_401(client);
+                }
                 return;
             }
         }

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'cvs-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.



More information about the commits mailing list