From ac841f3af1120b9daf6616cd3d0cf9569ea54bcb Mon Sep 17 00:00:00 2001 From: Sebastian Benoit Date: Wed, 15 Nov 2017 19:03:27 +0000 Subject: make the maximum size of http headers configurable in the protocol. ok bluhm@, >8k makes sense claudio@ --- usr.sbin/relayd/parse.y | 55 +++++++++++++++++++++++++++++++------------ usr.sbin/relayd/relay_http.c | 7 +++--- usr.sbin/relayd/relayd.conf.5 | 13 ++++++++-- usr.sbin/relayd/relayd.h | 6 +++-- 4 files changed, 59 insertions(+), 22 deletions(-) diff --git a/usr.sbin/relayd/parse.y b/usr.sbin/relayd/parse.y index 5e357bb7eb2..707ed593d9c 100644 --- a/usr.sbin/relayd/parse.y +++ b/usr.sbin/relayd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.216 2017/08/28 06:00:05 florian Exp $ */ +/* $OpenBSD: parse.y,v 1.217 2017/11/15 19:03:26 benno Exp $ */ /* * Copyright (c) 2007 - 2014 Reyk Floeter @@ -164,13 +164,13 @@ typedef struct { %token ALL APPEND BACKLOG BACKUP BUFFER CA CACHE SET CHECK CIPHERS CODE %token COOKIE DEMOTE DIGEST DISABLE ERROR EXPECT PASS BLOCK EXTERNAL FILENAME -%token FORWARD FROM HASH HEADER HOST ICMP INCLUDE INET INET6 INTERFACE -%token INTERVAL IP LABEL LISTEN VALUE LOADBALANCE LOG LOOKUP METHOD MODE NAT -%token NO DESTINATION NODELAY NOTHING ON PARENT PATH PFTAG PORT PREFORK -%token PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY REMOVE REQUEST RESPONSE -%token RETRY QUICK RETURN ROUNDROBIN ROUTE SACK SCRIPT SEND SESSION SNMP -%token SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG TAGGED TCP TIMEOUT TLS TO -%token ROUTER RTLABEL TRANSPARENT TRAP UPDATES URL VIRTUAL WITH TTL RTABLE +%token FORWARD FROM HASH HEADER HEADERLEN HOST HTTP ICMP INCLUDE INET INET6 +%token INTERFACE INTERVAL IP LABEL LISTEN VALUE LOADBALANCE LOG LOOKUP METHOD +%token MODE NAT NO DESTINATION NODELAY NOTHING ON PARENT PATH PFTAG PORT +%token PREFORK PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY REMOVE REQUEST +%token RESPONSE RETRY QUICK RETURN ROUNDROBIN ROUTE SACK SCRIPT SEND SESSION +%token SNMP SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG TAGGED TCP TIMEOUT TLS +%token TO ROUTER RTLABEL TRANSPARENT TRAP UPDATES URL VIRTUAL WITH TTL RTABLE %token MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE PASSWORD ECDH %token EDH CURVE TICKETS %token STRING @@ -237,11 +237,10 @@ opttlsclient : /*empty*/ { $$ = 0; } | WITH ssltls { $$ = 1; } ; -http_type : STRING { +http_type : HTTP { $$ = 0; } + | STRING { if (strcmp("https", $1) == 0) { $$ = 1; - } else if (strcmp("http", $1) == 0) { - $$ = 0; } else { yyerror("invalid check type: %s", $1); free($1); @@ -265,10 +264,9 @@ hostname : /* empty */ { relay_proto : /* empty */ { $$ = RELAY_PROTO_TCP; } | TCP { $$ = RELAY_PROTO_TCP; } + | HTTP { $$ = RELAY_PROTO_HTTP; } | STRING { - if (strcmp("http", $1) == 0) { - $$ = RELAY_PROTO_HTTP; - } else if (strcmp("dns", $1) == 0) { + if (strcmp("dns", $1) == 0) { $$ = RELAY_PROTO_DNS; } else { yyerror("invalid protocol type: %s", $1); @@ -311,7 +309,15 @@ eflags : STYLE STRING } ; -port : PORT STRING { +port : PORT HTTP { + int p = 0; + $$.op = PF_OP_EQ; + if ((p = getservice("http")) == -1) + YYERROR; + $$.val[0] = p; + $$.val[1] = 0; + } + | PORT STRING { char *a, *b; int p[2]; @@ -996,6 +1002,7 @@ proto : relay_proto PROTO STRING { p->tcpflags = TCPFLAG_DEFAULT; p->tlsflags = TLSFLAG_DEFAULT; p->tcpbacklog = RELAY_BACKLOG; + p->httpheaderlen = RELAY_DEFHEADERLENGTH; TAILQ_INIT(&p->rules); (void)strlcpy(p->tlsciphers, TLSCIPHERS_DEFAULT, sizeof(p->tlsciphers)); @@ -1034,12 +1041,28 @@ protoptsl : ssltls tlsflags | ssltls '{' tlsflags_l '}' | TCP tcpflags | TCP '{' tcpflags_l '}' + | HTTP httpflags + | HTTP '{' httpflags_l '}' | RETURN ERROR opteflags { proto->flags |= F_RETURN; } | RETURN ERROR '{' eflags_l '}' { proto->flags |= F_RETURN; } | filterrule | include ; + +httpflags_l : httpflags comma httpflags_l + | httpflags + ; + +httpflags : HEADERLEN NUMBER { + if ($2 < 0 || $2 > RELAY_MAXHEADERLENGTH) { + yyerror("invalid headerlen: %d", $2); + YYERROR; + } + proto->httpheaderlen = $2; + } + ; + tcpflags_l : tcpflags comma tcpflags_l | tcpflags ; @@ -2210,7 +2233,9 @@ lookup(char *s) { "from", FROM }, { "hash", HASH }, { "header", HEADER }, + { "headerlen", HEADERLEN }, { "host", HOST }, + { "http", HTTP }, { "icmp", ICMP }, { "include", INCLUDE }, { "inet", INET }, diff --git a/usr.sbin/relayd/relay_http.c b/usr.sbin/relayd/relay_http.c index 2bd6952bbeb..3b6f8e84e37 100644 --- a/usr.sbin/relayd/relay_http.c +++ b/usr.sbin/relayd/relay_http.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay_http.c,v 1.67 2017/09/23 11:56:57 bluhm Exp $ */ +/* $OpenBSD: relay_http.c,v 1.68 2017/11/15 19:03:26 benno Exp $ */ /* * Copyright (c) 2006 - 2016 Reyk Floeter @@ -187,9 +187,10 @@ relay_read_http(struct bufferevent *bev, void *arg) /* Limit the total header length minus \r\n */ cre->headerlen += linelen; - if (cre->headerlen > RELAY_MAXHEADERLENGTH) { + if (cre->headerlen > proto->httpheaderlen) { free(line); - relay_abort_http(con, 413, "request too large", 0); + relay_abort_http(con, 413, + "request headers too large", 0); return; } diff --git a/usr.sbin/relayd/relayd.conf.5 b/usr.sbin/relayd/relayd.conf.5 index f79b0800a74..3fecd791c24 100644 --- a/usr.sbin/relayd/relayd.conf.5 +++ b/usr.sbin/relayd/relayd.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: relayd.conf.5,v 1.178 2017/07/11 13:00:59 bluhm Exp $ +.\" $OpenBSD: relayd.conf.5,v 1.179 2017/11/15 19:03:26 benno Exp $ .\" .\" Copyright (c) 2006 - 2016 Reyk Floeter .\" Copyright (c) 2006, 2007 Pierre-Yves Ritschard @@ -15,7 +15,7 @@ .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: July 11 2017 $ +.Dd $Mdocdate: November 15 2017 $ .Dt RELAYD.CONF 5 .Os .Sh NAME @@ -991,6 +991,15 @@ Enable the TLSv1.1 protocol. The default is .Ic no tlsv1.1 . .El +.It Ic http Ar option +Set the HTTP options and session settings. +This is only used if HTTP is enabled in the relay. +Valid options are: +.Bl -tag -width Ds +.It Ic headerlen Ar number +Set the maximum size of all HTTP headers in bytes. +The default value is 8192 and it is limited to a maximum of 131072. +.El .El .Sh FILTER RULES Relays have the ability to filter connections based diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h index 6d1ed6e1b0a..a4fda62d2e9 100644 --- a/usr.sbin/relayd/relayd.h +++ b/usr.sbin/relayd/relayd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.h,v 1.242 2017/07/28 13:58:52 bluhm Exp $ */ +/* $OpenBSD: relayd.h,v 1.243 2017/11/15 19:03:26 benno Exp $ */ /* * Copyright (c) 2006 - 2016 Reyk Floeter @@ -73,7 +73,8 @@ #define RELAY_CACHESIZE -1 /* use default size */ #define RELAY_NUMPROC 3 #define RELAY_MAXHOSTS 32 -#define RELAY_MAXHEADERLENGTH 8192 +#define RELAY_MAXHEADERLENGTH 131072 +#define RELAY_DEFHEADERLENGTH 8192 #define RELAY_STATINTERVAL 60 #define RELAY_BACKLOG 10 #define RELAY_MAXLOOKUPLEVELS 5 @@ -698,6 +699,7 @@ struct protocol { int tcpbacklog; u_int8_t tcpipttl; u_int8_t tcpipminttl; + size_t httpheaderlen; u_int8_t tlsflags; char tlsciphers[768]; char tlsdhparams[128]; -- cgit v1.2.3