From f349c3bf3ea31f7b13746b07b84092f8aac5a664 Mon Sep 17 00:00:00 2001 From: Michael Smith Date: Sun, 11 Aug 2002 14:23:39 +0000 Subject: [PATCH] More path handling cleanups, and memory leak fixes. svn path=/trunk/icecast/; revision=3804 --- src/connection.c | 36 +++++++++++++++++++++++++++++++----- src/util.c | 39 ++++++++++++++++++++++++++++++--------- src/util.h | 2 ++ 3 files changed, 63 insertions(+), 14 deletions(-) diff --git a/src/connection.c b/src/connection.c index 8c8b2ec8..b2b62725 100644 --- a/src/connection.c +++ b/src/connection.c @@ -344,7 +344,7 @@ static void *_handle_connection(void *arg) int bytes; struct stat statbuf; char *fullpath; - char *uri; + char *rawuri, *uri; while (global.running == ICE_RUNNING) { memset(header, 0, 4096); @@ -377,7 +377,17 @@ static void *_handle_connection(void *arg) continue; } - uri = httpp_getvar(parser, HTTPP_VAR_URI); + rawuri = httpp_getvar(parser, HTTPP_VAR_URI); + uri = util_normalise_uri(rawuri); + + if(!uri) { + client = client_create(con, parser); + bytes = sock_write(client->con->sock, "HTTP/1.0 404 File Not Found\r\nContent-Type: text/html\r\n\r\n"\ + "The path you requested was invalid.\r\n"); + if(bytes > 0) client->con->sent_bytes = bytes; + client_destroy(client); + continue; + } if (parser->req_type == httpp_req_source) { INFO1("Source logging in at mountpoint \"%s\"", uri); @@ -387,6 +397,7 @@ static void *_handle_connection(void *arg) INFO1("Source (%s) attempted to login with bad password", uri); connection_close(con); httpp_destroy(parser); + free(uri); continue; } @@ -399,6 +410,7 @@ static void *_handle_connection(void *arg) INFO1("Source tried to log in as %s, but is already used", uri); connection_close(con); httpp_destroy(parser); + free(uri); avl_tree_unlock(global.source_tree); continue; } @@ -407,6 +419,7 @@ static void *_handle_connection(void *arg) if (!connection_create_source(con, parser, uri)) { connection_close(con); httpp_destroy(parser); + free(uri); } continue; @@ -417,6 +430,7 @@ static void *_handle_connection(void *arg) ERROR0("Bad password for stats connection"); connection_close(con); httpp_destroy(parser); + free(uri); continue; } @@ -428,7 +442,8 @@ static void *_handle_connection(void *arg) stats->con = con; thread_create("Stats Connection", stats_connection, (void *)stats, THREAD_DETACHED); - + + free(uri); continue; } else if (parser->req_type == httpp_req_play || parser->req_type == httpp_req_get) { DEBUG0("Client connected"); @@ -449,6 +464,7 @@ static void *_handle_connection(void *arg) DEBUG0("Stats request, sending xml stats"); stats_sendxml(client); client_destroy(client); + free(uri); continue; } @@ -456,8 +472,8 @@ static void *_handle_connection(void *arg) ** if the extension is .xsl, if so, then process ** this request as an XSLT request */ - fullpath = util_get_path_from_uri(uri); - if (fullpath && util_check_valid_extension(fullpath) == XSLT_CONTENT) { + fullpath = util_get_path_from_normalised_uri(uri); + if (util_check_valid_extension(fullpath) == XSLT_CONTENT) { /* If the file exists, then transform it, otherwise, write a 404 error */ if (stat(fullpath, &statbuf) == 0) { DEBUG0("Stats request, sending XSL transformed stats"); @@ -470,9 +486,12 @@ static void *_handle_connection(void *arg) "The file you requested could not be found.\r\n"); if(bytes > 0) client->con->sent_bytes = bytes; } + free(fullpath); + free(uri); client_destroy(client); continue; } + free(fullpath); if(strcmp(util_get_extension(uri), "m3u") == 0) { char *sourceuri = strdup(uri); @@ -496,6 +515,8 @@ static void *_handle_connection(void *arg) } avl_tree_unlock(global.source_tree); if(bytes > 0) client->con->sent_bytes = bytes; + free(sourceuri); + free(uri); client_destroy(client); continue; } @@ -526,6 +547,7 @@ static void *_handle_connection(void *arg) } avl_tree_unlock(global.source_tree); } + free(uri); client_destroy(client); continue; } @@ -540,6 +562,7 @@ static void *_handle_connection(void *arg) } client_destroy(client); global_unlock(); + free(uri); continue; } global_unlock(); @@ -557,6 +580,7 @@ static void *_handle_connection(void *arg) "The server is already full. Try again later.\r\n"); if (bytes > 0) client->con->sent_bytes = bytes; } + free(uri); client_destroy(client); global_unlock(); continue; @@ -605,11 +629,13 @@ static void *_handle_connection(void *arg) client_destroy(client); } + free(uri); continue; } else { ERROR0("Wrong request type from client"); connection_close(con); httpp_destroy(parser); + free(uri); continue; } } else { diff --git a/src/util.c b/src/util.c index 941aa549..61265a4a 100644 --- a/src/util.c +++ b/src/util.c @@ -182,13 +182,39 @@ static int verify_path(char *path) { return 1; } +char *util_get_path_from_uri(char *uri) { + char *path = util_normalise_uri(uri); + char *fullpath; + + if(!path) + return NULL; + else { + fullpath = util_get_path_from_normalised_uri(path); + free(path); + return fullpath; + } +} + +char *util_get_path_from_normalised_uri(char *uri) { + char *fullpath; + + fullpath = malloc(strlen(uri) + strlen(config_get_config()->webroot_dir) + 1); + strcpy(fullpath, config_get_config()->webroot_dir); + + strcat(fullpath, uri); + + return fullpath; +} + + + + /* 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; +char *util_normalise_uri(char *uri) { int urilen = strlen(uri); unsigned char *path; char *dst; @@ -198,12 +224,9 @@ char *util_get_path_from_uri(char *uri) { if(uri[0] != '/') return NULL; - path = calloc(1, urilen + strlen(root) + 1); - - strcpy(path, root); - - dst = path+strlen(root); + path = calloc(1, urilen + 1); + dst = path; for(i=0; i < urilen; i++) { switch(uri[i]) { @@ -236,8 +259,6 @@ char *util_get_path_from_uri(char *uri) { 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 */ diff --git a/src/util.h b/src/util.h index b46ca270..3f384b89 100644 --- a/src/util.h +++ b/src/util.h @@ -9,5 +9,7 @@ int util_read_header(int sock, char *buff, unsigned long len); int util_check_valid_extension(char *uri); char *util_get_extension(char *path); char *util_get_path_from_uri(char *uri); +char *util_get_path_from_normalised_uri(char *uri); +char *util_normalise_uri(char *uri); #endif /* __UTIL_H__ */