From 40f72a41b9d72ec34738e169cb4ba54e7fffe27b Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Tue, 25 Apr 2017 11:12:53 -0400 Subject: [PATCH] [core] omit default port from normalized host str omit default scheme port from normalized host string --- src/configparser.y | 10 +++++----- src/mod_extforward.c | 7 ++++++- src/request.c | 15 ++++++++++----- src/request.h | 4 ++-- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/configparser.y b/src/configparser.y index b46651ce..eddc6694 100644 --- a/src/configparser.y +++ b/src/configparser.y @@ -129,7 +129,7 @@ static int configparser_remoteip_normalize_compat(buffer *rvalue) { buffer_append_string_buffer(b, rvalue); } - rc = http_request_host_normalize(b); + rc = http_request_host_normalize(b, 0); if (0 == rc) { /* remove surrounding '[]' */ @@ -636,7 +636,7 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio int rc; buffer_string_set_length(rvalue, (size_t)(slash - rvalue->ptr)); /*(truncate)*/ rc = (NULL == colon) - ? http_request_host_normalize(rvalue) + ? http_request_host_normalize(rvalue, 0) : configparser_remoteip_normalize_compat(rvalue); buffer_append_string_len(rvalue, CONST_STR_LEN("/")); buffer_append_int(rvalue, (int)nm_bits); @@ -648,7 +648,7 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio } else { int rc = (NULL == colon) - ? http_request_host_normalize(rvalue) + ? http_request_host_normalize(rvalue, 0) : configparser_remoteip_normalize_compat(rvalue); if (0 != rc) { fprintf(stderr, "invalid IP addr: %s\n", rvalue->ptr); @@ -660,7 +660,7 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio /*(redundant with parsing in network.c; not actually required here)*/ if (rvalue->ptr[0] != ':' /*(network.c special-cases ":" and "[]")*/ && !(rvalue->ptr[0] == '[' && rvalue->ptr[1] == ']')) { - if (http_request_host_normalize(rvalue)) { + if (http_request_host_normalize(rvalue, 0)) { fprintf(stderr, "invalid IP addr: %s\n", rvalue->ptr); ctx->ok = 0; } @@ -668,7 +668,7 @@ context ::= DOLLAR SRVVARNAME(B) LBRACKET stringop(C) RBRACKET cond(E) expressio } else if (COMP_HTTP_HOST == dc->comp) { if (dc->cond == CONFIG_COND_EQ || dc->cond == CONFIG_COND_NE) { - if (http_request_host_normalize(rvalue)) { + if (http_request_host_normalize(rvalue, 0)) { fprintf(stderr, "invalid IP addr: %s\n", rvalue->ptr); ctx->ok = 0; } diff --git a/src/mod_extforward.c b/src/mod_extforward.c index 83284bd2..cfb6fb30 100644 --- a/src/mod_extforward.c +++ b/src/mod_extforward.c @@ -849,6 +849,10 @@ static handler_t mod_extforward_Forwarded (server *srv, connection *con, plugin_ * - due to need to decode and unescape host=..., some extra work is * done in the case where host matches current Host header. * future: might add code to check if Host has actually changed or not + * + * note: change host after mod_extforward_set_proto() since that may + * affect scheme port used in http_request_host_policy() host + * normalization */ /* find host param set by earliest trusted proxy in proxy chain @@ -886,7 +890,8 @@ static handler_t mod_extforward_Forwarded (server *srv, connection *con, plugin_ buffer_copy_string_len(con->request.http_host, s+v, vlen-v); } - if (0 != http_request_host_policy(con, con->request.http_host)) { + if (0 != http_request_host_policy(con, con->request.http_host, + con->uri.scheme)) { /*(reject invalid chars in Host)*/ log_error_write(srv, __FILE__, __LINE__, "s", "invalid host= value in Forwarded header"); diff --git a/src/request.c b/src/request.c index 65dc9580..94fe5580 100644 --- a/src/request.c +++ b/src/request.c @@ -201,7 +201,7 @@ static int request_check_hostname(buffer *host) { return 0; } -int http_request_host_normalize(buffer *b) { +int http_request_host_normalize(buffer *b, int scheme_port) { /* * check for and canonicalize numeric IP address and portnum (optional) * (IP address may be followed by ":portnum" (optional)) @@ -308,7 +308,7 @@ int http_request_host_normalize(buffer *b) { #endif } - if (port) { + if (0 != port && port != scheme_port) { buffer_append_string_len(b, CONST_STR_LEN(":")); buffer_append_int(b, (int)port); } @@ -316,11 +316,16 @@ int http_request_host_normalize(buffer *b) { return 0; } -int http_request_host_policy (connection *con, buffer *b) { +static int scheme_port (const buffer *scheme) +{ + return buffer_is_equal_string(scheme, CONST_STR_LEN("https")) ? 443 : 80; +} + +int http_request_host_policy (connection *con, buffer *b, const buffer *scheme) { return (((con->conf.http_parseopts & HTTP_PARSEOPT_HOST_STRICT) && 0 != request_check_hostname(b)) || ((con->conf.http_parseopts & HTTP_PARSEOPT_HOST_NORMALIZE) - && 0 != http_request_host_normalize(b))); + && 0 != http_request_host_normalize(b, scheme_port(scheme)))); } #if 0 @@ -1170,7 +1175,7 @@ int http_request_parse(server *srv, connection *con) { /* check hostname field if it is set */ if (!buffer_is_empty(con->request.http_host) && - 0 != http_request_host_policy(con, con->request.http_host)) { + 0 != http_request_host_policy(con, con->request.http_host, con->proto)) { if (srv->srvconf.log_request_header_on_error) { log_error_write(srv, __FILE__, __LINE__, "s", diff --git a/src/request.h b/src/request.h index 1f35f178..b5458a7e 100644 --- a/src/request.h +++ b/src/request.h @@ -12,7 +12,7 @@ typedef enum { int http_request_parse(server *srv, connection *con); int http_request_header_finished(server *srv, connection *con); -int http_request_host_normalize(buffer *b); -int http_request_host_policy(connection *con, buffer *b); +int http_request_host_normalize(buffer *b, int scheme_port); +int http_request_host_policy(connection *con, buffer *b, const buffer *scheme); #endif