Commit f349c3bf authored by Michael Smith's avatar Michael Smith

More path handling cleanups, and memory leak fixes.

svn path=/trunk/icecast/; revision=3804
parent 850cf995
...@@ -344,7 +344,7 @@ static void *_handle_connection(void *arg) ...@@ -344,7 +344,7 @@ static void *_handle_connection(void *arg)
int bytes; int bytes;
struct stat statbuf; struct stat statbuf;
char *fullpath; char *fullpath;
char *uri; char *rawuri, *uri;
while (global.running == ICE_RUNNING) { while (global.running == ICE_RUNNING) {
memset(header, 0, 4096); memset(header, 0, 4096);
...@@ -377,7 +377,17 @@ static void *_handle_connection(void *arg) ...@@ -377,7 +377,17 @@ static void *_handle_connection(void *arg)
continue; 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"\
"<b>The path you requested was invalid.</b>\r\n");
if(bytes > 0) client->con->sent_bytes = bytes;
client_destroy(client);
continue;
}
if (parser->req_type == httpp_req_source) { if (parser->req_type == httpp_req_source) {
INFO1("Source logging in at mountpoint \"%s\"", uri); INFO1("Source logging in at mountpoint \"%s\"", uri);
...@@ -387,6 +397,7 @@ static void *_handle_connection(void *arg) ...@@ -387,6 +397,7 @@ static void *_handle_connection(void *arg)
INFO1("Source (%s) attempted to login with bad password", uri); INFO1("Source (%s) attempted to login with bad password", uri);
connection_close(con); connection_close(con);
httpp_destroy(parser); httpp_destroy(parser);
free(uri);
continue; continue;
} }
...@@ -399,6 +410,7 @@ static void *_handle_connection(void *arg) ...@@ -399,6 +410,7 @@ static void *_handle_connection(void *arg)
INFO1("Source tried to log in as %s, but is already used", uri); INFO1("Source tried to log in as %s, but is already used", uri);
connection_close(con); connection_close(con);
httpp_destroy(parser); httpp_destroy(parser);
free(uri);
avl_tree_unlock(global.source_tree); avl_tree_unlock(global.source_tree);
continue; continue;
} }
...@@ -407,6 +419,7 @@ static void *_handle_connection(void *arg) ...@@ -407,6 +419,7 @@ static void *_handle_connection(void *arg)
if (!connection_create_source(con, parser, uri)) { if (!connection_create_source(con, parser, uri)) {
connection_close(con); connection_close(con);
httpp_destroy(parser); httpp_destroy(parser);
free(uri);
} }
continue; continue;
...@@ -417,6 +430,7 @@ static void *_handle_connection(void *arg) ...@@ -417,6 +430,7 @@ static void *_handle_connection(void *arg)
ERROR0("Bad password for stats connection"); ERROR0("Bad password for stats connection");
connection_close(con); connection_close(con);
httpp_destroy(parser); httpp_destroy(parser);
free(uri);
continue; continue;
} }
...@@ -428,7 +442,8 @@ static void *_handle_connection(void *arg) ...@@ -428,7 +442,8 @@ static void *_handle_connection(void *arg)
stats->con = con; stats->con = con;
thread_create("Stats Connection", stats_connection, (void *)stats, THREAD_DETACHED); thread_create("Stats Connection", stats_connection, (void *)stats, THREAD_DETACHED);
free(uri);
continue; continue;
} else if (parser->req_type == httpp_req_play || parser->req_type == httpp_req_get) { } else if (parser->req_type == httpp_req_play || parser->req_type == httpp_req_get) {
DEBUG0("Client connected"); DEBUG0("Client connected");
...@@ -449,6 +464,7 @@ static void *_handle_connection(void *arg) ...@@ -449,6 +464,7 @@ static void *_handle_connection(void *arg)
DEBUG0("Stats request, sending xml stats"); DEBUG0("Stats request, sending xml stats");
stats_sendxml(client); stats_sendxml(client);
client_destroy(client); client_destroy(client);
free(uri);
continue; continue;
} }
...@@ -456,8 +472,8 @@ static void *_handle_connection(void *arg) ...@@ -456,8 +472,8 @@ static void *_handle_connection(void *arg)
** if the extension is .xsl, if so, then process ** if the extension is .xsl, if so, then process
** this request as an XSLT request ** this request as an XSLT request
*/ */
fullpath = util_get_path_from_uri(uri); fullpath = util_get_path_from_normalised_uri(uri);
if (fullpath && util_check_valid_extension(fullpath) == XSLT_CONTENT) { if (util_check_valid_extension(fullpath) == XSLT_CONTENT) {
/* If the file exists, then transform it, otherwise, write a 404 error */ /* 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"); DEBUG0("Stats request, sending XSL transformed stats");
...@@ -470,9 +486,12 @@ static void *_handle_connection(void *arg) ...@@ -470,9 +486,12 @@ static void *_handle_connection(void *arg)
"<b>The file you requested could not be found.</b>\r\n"); "<b>The file you requested could not be found.</b>\r\n");
if(bytes > 0) client->con->sent_bytes = bytes; if(bytes > 0) client->con->sent_bytes = bytes;
} }
free(fullpath);
free(uri);
client_destroy(client); client_destroy(client);
continue; continue;
} }
free(fullpath);
if(strcmp(util_get_extension(uri), "m3u") == 0) { if(strcmp(util_get_extension(uri), "m3u") == 0) {
char *sourceuri = strdup(uri); char *sourceuri = strdup(uri);
...@@ -496,6 +515,8 @@ static void *_handle_connection(void *arg) ...@@ -496,6 +515,8 @@ static void *_handle_connection(void *arg)
} }
avl_tree_unlock(global.source_tree); avl_tree_unlock(global.source_tree);
if(bytes > 0) client->con->sent_bytes = bytes; if(bytes > 0) client->con->sent_bytes = bytes;
free(sourceuri);
free(uri);
client_destroy(client); client_destroy(client);
continue; continue;
} }
...@@ -526,6 +547,7 @@ static void *_handle_connection(void *arg) ...@@ -526,6 +547,7 @@ static void *_handle_connection(void *arg)
} }
avl_tree_unlock(global.source_tree); avl_tree_unlock(global.source_tree);
} }
free(uri);
client_destroy(client); client_destroy(client);
continue; continue;
} }
...@@ -540,6 +562,7 @@ static void *_handle_connection(void *arg) ...@@ -540,6 +562,7 @@ static void *_handle_connection(void *arg)
} }
client_destroy(client); client_destroy(client);
global_unlock(); global_unlock();
free(uri);
continue; continue;
} }
global_unlock(); global_unlock();
...@@ -557,6 +580,7 @@ static void *_handle_connection(void *arg) ...@@ -557,6 +580,7 @@ static void *_handle_connection(void *arg)
"<b>The server is already full. Try again later.</b>\r\n"); "<b>The server is already full. Try again later.</b>\r\n");
if (bytes > 0) client->con->sent_bytes = bytes; if (bytes > 0) client->con->sent_bytes = bytes;
} }
free(uri);
client_destroy(client); client_destroy(client);
global_unlock(); global_unlock();
continue; continue;
...@@ -605,11 +629,13 @@ static void *_handle_connection(void *arg) ...@@ -605,11 +629,13 @@ static void *_handle_connection(void *arg)
client_destroy(client); client_destroy(client);
} }
free(uri);
continue; continue;
} else { } else {
ERROR0("Wrong request type from client"); ERROR0("Wrong request type from client");
connection_close(con); connection_close(con);
httpp_destroy(parser); httpp_destroy(parser);
free(uri);
continue; continue;
} }
} else { } else {
......
...@@ -182,13 +182,39 @@ static int verify_path(char *path) { ...@@ -182,13 +182,39 @@ static int verify_path(char *path) {
return 1; 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 /* 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 * path contains 'disallowed' sequences like foo/../ (which could be used to
* escape from the webroot) or if it cannot be URI-decoded. * escape from the webroot) or if it cannot be URI-decoded.
* Caller should free the path. * Caller should free the path.
*/ */
char *util_get_path_from_uri(char *uri) { char *util_normalise_uri(char *uri) {
char *root = config_get_config()->webroot_dir;
int urilen = strlen(uri); int urilen = strlen(uri);
unsigned char *path; unsigned char *path;
char *dst; char *dst;
...@@ -198,12 +224,9 @@ char *util_get_path_from_uri(char *uri) { ...@@ -198,12 +224,9 @@ char *util_get_path_from_uri(char *uri) {
if(uri[0] != '/') if(uri[0] != '/')
return NULL; return NULL;
path = calloc(1, urilen + strlen(root) + 1); path = calloc(1, urilen + 1);
strcpy(path, root);
dst = path+strlen(root);
dst = path;
for(i=0; i < urilen; i++) { for(i=0; i < urilen; i++) {
switch(uri[i]) { switch(uri[i]) {
...@@ -236,8 +259,6 @@ char *util_get_path_from_uri(char *uri) { ...@@ -236,8 +259,6 @@ char *util_get_path_from_uri(char *uri) {
break; break;
} }
DEBUG1("After URI-decode path is \"%s\"", path);
*dst = 0; /* null terminator */ *dst = 0; /* null terminator */
/* We now have a full URI-decoded path. Check it for allowability */ /* We now have a full URI-decoded path. Check it for allowability */
......
...@@ -9,5 +9,7 @@ int util_read_header(int sock, char *buff, unsigned long len); ...@@ -9,5 +9,7 @@ int util_read_header(int sock, char *buff, unsigned long len);
int util_check_valid_extension(char *uri); int util_check_valid_extension(char *uri);
char *util_get_extension(char *path); char *util_get_extension(char *path);
char *util_get_path_from_uri(char *uri); 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__ */ #endif /* __UTIL_H__ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment