diff options
author | 2014-10-22 09:48:03 +0000 | |
---|---|---|
committer | 2014-10-22 09:48:03 +0000 | |
commit | a383dca2acc82286c172284b56d8c7693e1a9a7c (patch) | |
tree | cc334e417abd023455670ba62d892a153549f1dc | |
parent | Sync offsetof() definition with what we have in <stddef.h> for (diff) | |
download | wireguard-openbsd-a383dca2acc82286c172284b56d8c7693e1a9a7c.tar.xz wireguard-openbsd-a383dca2acc82286c172284b56d8c7693e1a9a7c.zip |
URL-decode the request path.
Tested by ajacoutot@ and others
OK doug@
-rw-r--r-- | usr.sbin/httpd/httpd.c | 42 | ||||
-rw-r--r-- | usr.sbin/httpd/httpd.h | 3 | ||||
-rw-r--r-- | usr.sbin/httpd/server_http.c | 3 |
3 files changed, 45 insertions, 3 deletions
diff --git a/usr.sbin/httpd/httpd.c b/usr.sbin/httpd/httpd.c index 34f2f3dee70..d8c61d41017 100644 --- a/usr.sbin/httpd/httpd.c +++ b/usr.sbin/httpd/httpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: httpd.c,v 1.22 2014/09/29 19:30:47 deraadt Exp $ */ +/* $OpenBSD: httpd.c,v 1.23 2014/10/22 09:48:03 reyk Exp $ */ /* * Copyright (c) 2014 Reyk Floeter <reyk@openbsd.org> @@ -536,6 +536,46 @@ canonicalize_host(const char *host, char *name, size_t len) } const char * +url_decode(char *url) +{ + char *p, *q; + char hex[3]; + u_long x; + + hex[2] = '\0'; + p = q = url; + + while (*p != '\0') { + switch (*p) { + case '%': + /* Encoding character is followed by two hex chars */ + if (!(isxdigit(p[1]) && isxdigit(p[2]))) + return (NULL); + + hex[0] = p[1]; + hex[1] = p[2]; + + /* + * We don't have to validate "hex" because it is + * guaranteed to include two hex chars followed by nul. + */ + x = strtoul(hex, NULL, 16); + *q = (char)x; + p += 2; + break; + default: + *q = *p; + break; + } + p++; + q++; + } + *q = '\0'; + + return(url); +} + +const char * canonicalize_path(const char *input, char *path, size_t len) { const char *i; diff --git a/usr.sbin/httpd/httpd.h b/usr.sbin/httpd/httpd.h index 9ddf3c0d6b0..7b86efaf701 100644 --- a/usr.sbin/httpd/httpd.h +++ b/usr.sbin/httpd/httpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: httpd.h,v 1.59 2014/09/10 15:39:57 reyk Exp $ */ +/* $OpenBSD: httpd.h,v 1.60 2014/10/22 09:48:03 reyk Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org> @@ -543,6 +543,7 @@ int fcgi_add_stdin(struct client *, struct evbuffer *); void event_again(struct event *, int, short, void (*)(int, short, void *), struct timeval *, struct timeval *, void *); +const char *url_decode(char *); const char *canonicalize_host(const char *, char *, size_t); const char *canonicalize_path(const char *, char *, size_t); size_t path_info(char *); diff --git a/usr.sbin/httpd/server_http.c b/usr.sbin/httpd/server_http.c index 6632b105a59..b0a8986287b 100644 --- a/usr.sbin/httpd/server_http.c +++ b/usr.sbin/httpd/server_http.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_http.c,v 1.52 2014/10/21 13:00:33 reyk Exp $ */ +/* $OpenBSD: server_http.c,v 1.53 2014/10/22 09:48:03 reyk Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org> @@ -784,6 +784,7 @@ server_response(struct httpd *httpd, struct client *clt) /* Canonicalize the request path */ if (desc->http_path == NULL || + url_decode(desc->http_path) == NULL || canonicalize_path(desc->http_path, path, sizeof(path)) == NULL) goto fail; free(desc->http_path); |