[xiph-cvs] cvs commit: icecast/src config.c connection.c util.c util.h

Michael Smith msmith at xiph.org
Sun Aug 11 07:00:56 PDT 2002



msmith      02/08/11 10:00:56

  Modified:    src      config.c connection.c util.c util.h
  Log:
  URI decoding and path normalisation pass one (stuff needed for fileserving
  later on)

Revision  Changes    Path
1.16      +3 -0      icecast/src/config.c

Index: config.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/config.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- config.c	10 Aug 2002 03:22:44 -0000	1.15
+++ config.c	11 Aug 2002 14:00:56 -0000	1.16
@@ -302,6 +302,9 @@
                 } else if (strcmp(node->name, "webroot") == 0) {
                         if (_configuration.webroot_dir && _configuration.webroot_dir != CONFIG_DEFAULT_WEBROOT_DIR) xmlFree(_configuration.webroot_dir);
                         _configuration.webroot_dir = (char *)xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+            if(_configuration.webroot_dir[strlen(_configuration.webroot_dir)-1] == '/')
+                _configuration.webroot_dir[strlen(_configuration.webroot_dir)-1] = 0;
+
                 }
         } while ((node = node->next));
 }

<p><p>1.19      +5 -6      icecast/src/connection.c

Index: connection.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/connection.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- connection.c	10 Aug 2002 08:01:56 -0000	1.18
+++ connection.c	11 Aug 2002 14:00:56 -0000	1.19
@@ -343,7 +343,7 @@
         client_t *client;
         int bytes;
         struct stat statbuf;
-	char	fullPath[4096];
+	char *fullpath;
     char *uri;
 
         while (global.running == ICE_RUNNING) {
@@ -456,15 +456,14 @@
                                         ** if the extension is .xsl, if so, then process
                                         ** this request as an XSLT request
                                         */
-					if (util_check_valid_extension(uri) == XSLT_CONTENT) {
-						util_get_full_path(uri, fullPath, sizeof(fullPath));
-							
+                    fullpath = util_get_path_from_uri(uri);
+					if (fullpath && util_check_valid_extension(fullpath) == XSLT_CONTENT) {
                                                 /* If the file exists, then transform it, otherwise, write a 404 error */
-						if (stat(fullPath, &statbuf) == 0) {
+						if (stat(fullpath, &statbuf) == 0) {
                             DEBUG0("Stats request, sending XSL transformed stats");
                                                         bytes = sock_write(client->con->sock, "HTTP/1.0 200 OK\r\nContent-Type: text/html\r\n\r\n");
                             if(bytes > 0) client->con->sent_bytes = bytes;
-                            stats_transform_xslt(client, fullPath);
+                            stats_transform_xslt(client, fullpath);
                                                 }
                                                 else {
                                                         bytes = sock_write(client->con->sock, "HTTP/1.0 404 File Not Found\r\nContent-Type: text/html\r\n\r\n"\

<p><p>1.7       +116 -10   icecast/src/util.c

Index: util.c
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/util.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- util.c	10 Aug 2002 08:01:56 -0000	1.6
+++ util.c	11 Aug 2002 14:00:56 -0000	1.7
@@ -1,6 +1,7 @@
 #include <sys/types.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdlib.h>
 
 #ifndef _WIN32
 #include <sys/time.h>
@@ -23,6 +24,14 @@
 #include "config.h"
 #include "util.h"
 #include "os.h"
+#include "refbuf.h"
+#include "connection.h"
+#include "client.h"
+
+#define CATMODULE "util"
+
+#include "log.h"
+#include "logging.h"
 
 /* Abstract out an interface to use either poll or select depending on which
  * is available (poll is preferred) to watch a single fd.
@@ -92,16 +101,6 @@
         return ret;
 }
 
-int util_get_full_path(char *uri, char *fullPath, int fullPathLen) {
-	int ret = 0;
-	if (uri) {
-		memset(fullPath, '\000', fullPathLen);
-		snprintf(fullPath, fullPathLen-1, "%s%s", config_get_config()->webroot_dir, uri);
-		ret = 1;
-	}
-	return ret;
-}
-
 char *util_get_extension(char *path) {
     char *ext = strrchr(path, '.');
 
@@ -143,4 +142,111 @@
         return ret;
 }
 
+static int hex(char c)
+{
+    if(c >= '0' && c <= '9')
+        return c - '0';
+    else if(c >= 'A' && c <= 'F')
+        return c - 'A' + 10;
+    else if(c >= 'a' && c <= 'f')
+        return c - 'a' + 10;
+    else
+        return -1;
+}
+
+static int verify_path(char *path) {
+    int dir = 0, indotseq = 0;
+
+    while(*path) {
+        if(*path == '/' || *path == '\\') {
+            if(indotseq)
+                return 0;
+            if(dir)
+                return 0;
+            dir = 1;
+            path++;
+            continue;
+        }
+
+        if(dir || indotseq) {
+            if(*path == '.')
+                indotseq = 1;
+            else
+                indotseq = 0;
+        }
+        
+        dir = 0;
+        path++;
+    }
+
+    return 1;
+}
+
+/* Get an absolute path (from the webroot dir) from a URI. Return NULL if the
+ * path contains 'disallowed' sequences like foo/../ (which could be used to
+ * escape from the webroot) or if it cannot be URI-decoded.
+ * Caller should free the path.
+ */
+char *util_get_path_from_uri(char *uri) {
+    char *root = config_get_config()->webroot_dir;
+    int urilen = strlen(uri);
+    unsigned char *path;
+    char *dst;
+    int i;
+    int done = 0;
+
+    if(uri[0] != '/')
+        return NULL;
+
+    path = calloc(1, urilen + strlen(root) + 1);
+
+    strcpy(path, root);
+
+    dst = path+strlen(root);
+
+
+    for(i=0; i < urilen; i++) {
+        switch(uri[i]) {
+            case '%':
+                if(i+2 >= urilen) {
+                    free(path);
+                    return NULL;
+                }
+                if(hex(uri[i+1]) == -1 || hex(uri[i+2]) == -1 ) {
+                    free(path);
+                    return NULL;
+                }
+
+                *dst++ = hex(uri[i+1]) * 16  + hex(uri[i+2]);
+                i+= 2;
+                break;
+            case '#':
+                done = 1;
+                break;
+            case 0:
+                ERROR0("Fatal internal logic error in util_get_path_from_uri()");
+                free(path);
+                return NULL;
+                break;
+            default:
+                *dst++ = uri[i];
+                break;
+        }
+        if(done)
+            break;
+    }
+
+    DEBUG1("After URI-decode path is \"%s\"", path);
+
+    *dst = 0; /* null terminator */
+
+    /* We now have a full URI-decoded path. Check it for allowability */
+    if(verify_path(path))
+        return (char *)path;
+    else {
+        WARN1("Rejecting invalid path \"%s\"", path);
+        free(path);
+        return NULL;
+    }
+}
 

<p><p>1.5       +1 -1      icecast/src/util.h

Index: util.h
===================================================================
RCS file: /usr/local/cvsroot/icecast/src/util.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- util.h	10 Aug 2002 08:01:56 -0000	1.4
+++ util.h	11 Aug 2002 14:00:56 -0000	1.5
@@ -6,8 +6,8 @@
 
 int util_timed_wait_for_fd(int fd, int timeout);
 int util_read_header(int sock, char *buff, unsigned long len);
-int util_get_full_path(char *uri, char *fullPath, int fullPathLen);
 int util_check_valid_extension(char *uri);
 char *util_get_extension(char *path);
+char *util_get_path_from_uri(char *uri);
 
 #endif  /* __UTIL_H__ */

<p><p>--- >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