diff options
author | Sebastian Benoit <benno@cvs.openbsd.org> | 2021-10-22 08:51:51 +0000 |
---|---|---|
committer | Sebastian Benoit <benno@cvs.openbsd.org> | 2021-10-22 08:51:51 +0000 |
commit | d9e4f2ef3bf645ee713aaeef531d5881352a0aff (patch) | |
tree | c07d448e891303adabd854ecca4b0b44c227ac39 /usr.sbin/httpd | |
parent | 1818320a955b317695435c35d74f735d3daa9496 (diff) |
return unsupported version for version less than HTTP/0.9 and higher
than HTTP/1.9. Downgrade version >= HTTP/1.2++ to 1.1.
Found by "J. K." (openbsd DOT list AT krottmayer DOT com)
ok claudio@
Diffstat (limited to 'usr.sbin/httpd')
-rw-r--r-- | usr.sbin/httpd/server_http.c | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/usr.sbin/httpd/server_http.c b/usr.sbin/httpd/server_http.c index 6a74f3e45c5..153829f4201 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.144 2021/10/21 11:48:30 benno Exp $ */ +/* $OpenBSD: server_http.c,v 1.145 2021/10/22 08:51:50 benno Exp $ */ /* * Copyright (c) 2020 Matthias Pressfreund <mpfr@fn.de> @@ -51,6 +51,7 @@ int server_http_authenticate(struct server_config *, struct client *); char *server_expand_http(struct client *, const char *, char *, size_t); +int http_version_num(char *); static struct http_method http_methods[] = HTTP_METHODS; static struct http_error http_errors[] = HTTP_ERRORS; @@ -198,6 +199,20 @@ done: return (ret); } +int +http_version_num(char *version) +{ + if (strcmp(version, "HTTP/0.9") == 0) + return (9); + if (strcmp(version, "HTTP/1.0") == 0) + return (10); + /* any other version 1.x gets downgraded to 1.1 */ + if (strncmp(version, "HTTP/1", 6) == 0) + return (11); + + return (0); +} + void server_read_http(struct bufferevent *bev, void *arg) { @@ -206,7 +221,9 @@ server_read_http(struct bufferevent *bev, void *arg) struct evbuffer *src = EVBUFFER_INPUT(bev); char *line = NULL, *key, *value; const char *errstr; + char *http_version; size_t size, linelen; + int version; struct kv *hdr = NULL; getmonotime(&clt->clt_tv_last); @@ -317,24 +334,39 @@ server_read_http(struct bufferevent *bev, void *arg) if (desc->http_path == NULL) goto fail; - desc->http_version = strchr(desc->http_path, ' '); - if (desc->http_version == NULL) { + http_version = strchr(desc->http_path, ' '); + if (http_version == NULL) { server_abort_http(clt, 400, "malformed"); goto abort; } - *desc->http_version++ = '\0'; + *http_version++ = '\0'; desc->http_query = strchr(desc->http_path, '?'); if (desc->http_query != NULL) *desc->http_query++ = '\0'; /* - * Have to allocate the strings because they could + * We have to allocate the strings because they could * be changed independently by the filters later. + * Allow HTTP version 0.9 to 1.1. + * Downgrade http version > 1.1 <= 1.9 to version 1.1. + * Return HTTP Version Not Supported for anything else. */ - if ((desc->http_version = - strdup(desc->http_version)) == NULL) - goto fail; + + version = http_version_num(http_version); + + if (version == 0) { + server_abort_http(clt, 505, "bad http version"); + goto abort; + } else if (version == 11) { + if ((desc->http_version = + strdup("HTTP/1.1")) == NULL) + goto fail; + } else { + if ((desc->http_version = + strdup(http_version)) == NULL) + goto fail; + } if (desc->http_query != NULL && (desc->http_query = |