summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreyk <reyk@openbsd.org>2014-10-22 09:48:03 +0000
committerreyk <reyk@openbsd.org>2014-10-22 09:48:03 +0000
commita383dca2acc82286c172284b56d8c7693e1a9a7c (patch)
treecc334e417abd023455670ba62d892a153549f1dc
parentSync offsetof() definition with what we have in <stddef.h> for (diff)
downloadwireguard-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.c42
-rw-r--r--usr.sbin/httpd/httpd.h3
-rw-r--r--usr.sbin/httpd/server_http.c3
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);