diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-05-26 03:05:37 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:17:02 -0500 |
commit | 44d2a46580da126866f704e5cf9b6599635f5f01 (patch) | |
tree | 59410b0ba2fd51788153a879d9a01d013453b9aa | |
parent | e8e8eab400fbc310bcf1af8dd1d5436fe9e1cac4 (diff) | |
download | samba-44d2a46580da126866f704e5cf9b6599635f5f01.tar.gz samba-44d2a46580da126866f704e5cf9b6599635f5f01.tar.bz2 samba-44d2a46580da126866f704e5cf9b6599635f5f01.zip |
r6987: - make sure esp pages cannot read data outside of the swat directory
- don't expose the real system path to esp scripts
- fixed absolute paths in include() calls
(This used to be commit 6535611aa22f51b7376be3c15715e8040a059736)
-rw-r--r-- | source4/web_server/esp/esp.h | 2 | ||||
-rw-r--r-- | source4/web_server/esp/espProcs.c | 8 | ||||
-rw-r--r-- | source4/web_server/http.c | 79 |
3 files changed, 44 insertions, 45 deletions
diff --git a/source4/web_server/esp/esp.h b/source4/web_server/esp/esp.h index 33ab9d7ac9..4503cacbb7 100644 --- a/source4/web_server/esp/esp.h +++ b/source4/web_server/esp/esp.h @@ -99,7 +99,7 @@ typedef struct Esp { char *(*getSessionId)(EspHandle handle); int (*mapToStorage)(EspHandle handle, char *path, int len, char *uri, int flags); - int (*readFile)(EspHandle handle, char **buf, int *len, char *path); + int (*readFile)(EspHandle handle, char **buf, int *len, const char *path); void (*redirect)(EspHandle handle, int code, char *url); void (*setCookie)(EspHandle handle, char *name, char *value, int lifetime, char *path, bool secure); diff --git a/source4/web_server/esp/espProcs.c b/source4/web_server/esp/espProcs.c index a8da800213..5c99e092c9 100644 --- a/source4/web_server/esp/espProcs.c +++ b/source4/web_server/esp/espProcs.c @@ -77,8 +77,12 @@ static int includeProc(EspRequest *ep, int argc, char **argv) esp = ep->esp; mprAssert(argv); for (i = 0; i < argc; i++) { - mprGetDirName(dir, sizeof(dir), ep->docPath); - mprSprintf(path, sizeof(path), "%s/%s", dir, argv[i]); + if (argv[i][0] != '/') { + mprGetDirName(dir, sizeof(dir), ep->docPath); + mprSprintf(path, sizeof(path), "%s/%s", dir, argv[i]); + } else { + mprSprintf(path, sizeof(path), "%s", argv[i]); + } if (esp->readFile(ep->requestHandle, &buf, &size, path) < 0) { espError(ep, "Can't read include file: %s", path); diff --git a/source4/web_server/http.c b/source4/web_server/http.c index 5f89e47163..fa03830295 100644 --- a/source4/web_server/http.c +++ b/source4/web_server/http.c @@ -97,14 +97,45 @@ static void http_output_headers(struct websrv_context *web) } /* + return the local path for a URL +*/ +static const char *http_local_path(struct websrv_context *web, const char *url) +{ + int i; + char *path; + + /* check that the url is OK */ + if (url[0] != '/') return NULL; + + for (i=0;url[i];i++) { + if ((!isalnum(url[i]) && !strchr("./", url[i])) || + (url[i] == '.' && strchr("/.", url[i+1]))) { + return NULL; + } + } + + path = talloc_asprintf(web, "%s/%s", lp_swat_directory(), url+1); + if (path == NULL) return NULL; + + if (directory_exist(path)) { + path = talloc_asprintf_append(path, "/index.html"); + } + return path; +} + +/* called when esp wants to read a file to support include() calls */ -static int http_readFile(EspHandle handle, char **buf, int *len, char *path) +static int http_readFile(EspHandle handle, char **buf, int *len, const char *path) { + struct websrv_context *web = talloc_get_type(handle, struct websrv_context); int fd = -1; struct stat st; *buf = NULL; + path = http_local_path(web, path); + if (path == NULL) goto failed; + fd = open(path, O_RDONLY); if (fd == -1 || fstat(fd, &st) != 0 || !S_ISREG(st.st_mode)) goto failed; @@ -263,33 +294,6 @@ void http_error_unix(struct websrv_context *web, const char *info) http_error(web, code, info); } -/* - return the local path for a URL -*/ -static const char *http_local_path(struct websrv_context *web, const char *url) -{ - int i; - char *path; - - /* check that the url is OK */ - if (url[0] != '/') return NULL; - - for (i=0;url[i];i++) { - if ((!isalnum(url[i]) && !strchr("./", url[i])) || - (url[i] == '.' && strchr("/.", url[i+1]))) { - return NULL; - } - } - - path = talloc_asprintf(web, "%s/%s", lp_swat_directory(), url+1); - if (path == NULL) return NULL; - - if (directory_exist(path)) { - path = talloc_asprintf_append(path, "/index.html"); - } - return path; -} - /* a simple file request @@ -356,6 +360,7 @@ static void http_setup_arrays(struct esp_state *esp) espSetStringVar(req, ESP_SERVER_OBJ, "SERVER_PORT", talloc_asprintf(esp, "%u", socket_get_my_port(web->conn->socket))); espSetStringVar(req, ESP_SERVER_OBJ, "SERVER_PROTOCOL", "http"); + espSetStringVar(esp->req, ESP_REQUEST_OBJ, "SCRIPT_FILENAME", web->input.url); } @@ -369,34 +374,24 @@ static void esp_request(struct esp_state *esp) { struct websrv_context *web = esp->web; const char *url = web->input.url; - const char *path; size_t size; int res; char *emsg = NULL, *buf; http_setup_arrays(esp); - path = http_local_path(web, url); - if (path == NULL) goto invalid; - - espSetStringVar(esp->req, ESP_REQUEST_OBJ, "SCRIPT_FILENAME", path); - - if (http_readFile(web, &buf, &size, path) != 0) { - http_error_unix(web, path); + if (http_readFile(web, &buf, &size, url) != 0) { + http_error_unix(web, url); return; } - res = espProcessRequest(esp->req, path, buf, &emsg); + res = espProcessRequest(esp->req, url, buf, &emsg); if (res != 0 && emsg) { - http_writeBlock(esp, emsg, strlen(emsg)); + http_writeBlock(web, emsg, strlen(emsg)); } talloc_free(buf); http_output_headers(web); EVENT_FD_WRITEABLE(web->conn->event.fde); - return; - -invalid: - http_error(web, 400, "Malformed URL"); } |