diff options
author | 2021-01-09 08:53:57 +0000 | |
---|---|---|
committer | 2021-01-09 08:53:57 +0000 | |
commit | eeb1fea4acc9c4cbc2c39aee16664ef34a5ef36c (patch) | |
tree | c834dbf96d439ed8d3e4171facc2b66c2a9b8cfc | |
parent | Set chain on xsc on chain build failure. (diff) | |
download | wireguard-openbsd-eeb1fea4acc9c4cbc2c39aee16664ef34a5ef36c.tar.xz wireguard-openbsd-eeb1fea4acc9c4cbc2c39aee16664ef34a5ef36c.zip |
Add 'strip' directive
Feedback by Olivier Cherrier, Hiltjo Posthuma, Mischa
OK benno@
-rw-r--r-- | usr.sbin/relayd/parse.y | 19 | ||||
-rw-r--r-- | usr.sbin/relayd/relay.c | 11 | ||||
-rw-r--r-- | usr.sbin/relayd/relay_http.c | 46 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.conf.5 | 13 | ||||
-rw-r--r-- | usr.sbin/relayd/relayd.h | 5 |
5 files changed, 76 insertions, 18 deletions
diff --git a/usr.sbin/relayd/parse.y b/usr.sbin/relayd/parse.y index eac2e2b6204..9523366749d 100644 --- a/usr.sbin/relayd/parse.y +++ b/usr.sbin/relayd/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.250 2020/12/29 19:48:06 benno Exp $ */ +/* $OpenBSD: parse.y,v 1.251 2021/01/09 08:53:57 denis Exp $ */ /* * Copyright (c) 2007 - 2014 Reyk Floeter <reyk@openbsd.org> @@ -175,7 +175,7 @@ typedef struct { %token LOOKUP METHOD MODE NAT NO DESTINATION NODELAY NOTHING ON PARENT PATH %token PFTAG PORT PREFORK PRIORITY PROTO QUERYSTR REAL REDIRECT RELAY REMOVE %token REQUEST RESPONSE RETRY QUICK RETURN ROUNDROBIN ROUTE SACK SCRIPT SEND -%token SESSION SOCKET SPLICE SSL STICKYADDR STYLE TABLE TAG TAGGED TCP +%token SESSION SOCKET SPLICE SSL STICKYADDR STRIP STYLE TABLE TAG TAGGED TCP %token TIMEOUT TLS TO ROUTER RTLABEL TRANSPARENT URL WITH TTL RTABLE %token MATCH PARAMS RANDOM LEASTSTATES SRCHASH KEY CERTIFICATE PASSWORD ECDHE %token EDH TICKETS CONNECTION CONNECTIONS CONTEXT ERRORS STATE CHANGES CHECKS @@ -1549,6 +1549,20 @@ ruleopts : METHOD STRING { rule->rule_kv[keytype].kv_option = $2; rule->rule_kv[keytype].kv_type = keytype; } + | PATH STRIP NUMBER { + char *strip = NULL; + + if ($3 < 0 || $3 > INT_MAX) { + yyerror("invalid strip number"); + YYERROR; + } + if (asprintf(&strip, "%lld", $3) <= 0) + fatal("can't parse strip"); + keytype = KEY_TYPE_PATH; + rule->rule_kv[keytype].kv_option = KEY_OPTION_STRIP; + rule->rule_kv[keytype].kv_value = strip; + rule->rule_kv[keytype].kv_type = keytype; + } | QUERYSTR key_option STRING value { switch ($2) { case KEY_OPTION_APPEND: @@ -2481,6 +2495,7 @@ lookup(char *s) { "ssl", SSL }, { "state", STATE }, { "sticky-address", STICKYADDR }, + { "strip", STRIP }, { "style", STYLE }, { "table", TABLE }, { "tag", TAG }, diff --git a/usr.sbin/relayd/relay.c b/usr.sbin/relayd/relay.c index 43b5c377fa5..89716209937 100644 --- a/usr.sbin/relayd/relay.c +++ b/usr.sbin/relayd/relay.c @@ -1,4 +1,4 @@ -/* $OpenBSD: relay.c,v 1.251 2020/05/14 17:27:38 pvk Exp $ */ +/* $OpenBSD: relay.c,v 1.252 2021/01/09 08:53:58 denis Exp $ */ /* * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org> @@ -214,6 +214,9 @@ relay_ruledebug(struct relay_rule *rule) case KEY_OPTION_LOG: fprintf(stderr, "log "); break; + case KEY_OPTION_STRIP: + fprintf(stderr, "strip "); + break; case KEY_OPTION_NONE: break; } @@ -227,13 +230,15 @@ relay_ruledebug(struct relay_rule *rule) break; } + int kvv = (kv->kv_option == KEY_OPTION_STRIP || + kv->kv_value == NULL); fprintf(stderr, "%s%s%s%s%s%s ", kv->kv_key == NULL ? "" : "\"", kv->kv_key == NULL ? "" : kv->kv_key, kv->kv_key == NULL ? "" : "\"", - kv->kv_value == NULL ? "" : " value \"", + kvv ? "" : " value \"", kv->kv_value == NULL ? "" : kv->kv_value, - kv->kv_value == NULL ? "" : "\""); + kvv ? "" : "\""); } if (rule->rule_tablename[0]) diff --git a/usr.sbin/relayd/relay_http.c b/usr.sbin/relayd/relay_http.c index ec10f2446b1..69b48697427 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.79 2020/09/04 13:09:14 bket Exp $ */ +/* $OpenBSD: relay_http.c,v 1.80 2021/01/09 08:53:58 denis Exp $ */ /* * Copyright (c) 2006 - 2016 Reyk Floeter <reyk@openbsd.org> @@ -77,6 +77,7 @@ int relay_match_actions(struct ctl_relay_event *, struct relay_rule *, struct kvlist *, struct kvlist *, struct relay_table **); void relay_httpdesc_free(struct http_descriptor *); +char * server_root_strip(char *, int); static struct relayd *env = NULL; @@ -1421,14 +1422,16 @@ relay_httppath_test(struct ctl_relay_event *cre, struct relay_rule *rule, if (cre->dir == RELAY_DIR_RESPONSE || kv->kv_type != KEY_TYPE_PATH) return (0); - else if (kv->kv_key == NULL) - return (0); - else if (fnmatch(kv->kv_key, desc->http_path, 0) == FNM_NOMATCH) - return (-1); - else if (kv->kv_value != NULL && kv->kv_option == KEY_OPTION_NONE) { - query = desc->http_query == NULL ? "" : desc->http_query; - if (fnmatch(kv->kv_value, query, FNM_CASEFOLD) == FNM_NOMATCH) + else if (kv->kv_option != KEY_OPTION_STRIP) { + if (kv->kv_key == NULL) + return (0); + else if (fnmatch(kv->kv_key, desc->http_path, 0) == FNM_NOMATCH) return (-1); + else if (kv->kv_value != NULL && kv->kv_option == KEY_OPTION_NONE) { + query = desc->http_query == NULL ? "" : desc->http_query; + if (fnmatch(kv->kv_value, query, FNM_CASEFOLD) == FNM_NOMATCH) + return (-1); + } } relay_match(actions, kv, match, NULL); @@ -1554,7 +1557,7 @@ relay_apply_actions(struct ctl_relay_event *cre, struct kvlist *actions, struct kv *host = NULL; const char *value; struct kv *kv, *match, *kp, *mp, kvcopy, matchcopy, key; - int addkv, ret; + int addkv, ret, nstrip; char buf[IBUF_READ_SIZE], *ptr; char *msg = NULL; const char *meth = NULL; @@ -1655,6 +1658,15 @@ relay_apply_actions(struct ctl_relay_event *cre, struct kvlist *actions, case KEY_OPTION_LOG: /* perform this later */ break; + case KEY_OPTION_STRIP: + nstrip = strtonum(kv->kv_value, 0, INT_MAX, NULL); + if (kv->kv_type == KEY_TYPE_PATH) { + if (kv_setkey(match, + server_root_strip(match->kv_key, + nstrip)) == -1) + goto fail; + } + break; default: fatalx("%s: invalid action", __func__); /* NOTREACHED */ @@ -1932,3 +1944,19 @@ relay_match(struct kvlist *actions, struct kv *kv, struct kv *match, TAILQ_INSERT_TAIL(actions, kv, kv_match_entry); } } + +char * +server_root_strip(char *path, int n) +{ + char *p; + + /* Strip strip leading directories. Leading '/' is ignored. */ + for (; n > 0 && *path != '\0'; n--) + if ((p = strchr(++path, '/')) != NULL) + path = p; + else + path--; + + return (path); +} + diff --git a/usr.sbin/relayd/relayd.conf.5 b/usr.sbin/relayd/relayd.conf.5 index 2e7bc1c7464..cecbae71f87 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.202 2020/10/30 09:47:35 martijn Exp $ +.\" $OpenBSD: relayd.conf.5,v 1.203 2021/01/09 08:53:58 denis Exp $ .\" .\" Copyright (c) 2006 - 2016 Reyk Floeter <reyk@openbsd.org> .\" Copyright (c) 2006, 2007 Pierre-Yves Ritschard <pyr@openbsd.org> @@ -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: October 30 2020 $ +.Dd $Mdocdate: January 9 2021 $ .Dt RELAYD.CONF 5 .Os .Sh NAME @@ -1289,6 +1289,15 @@ for example: block path "/index.html" block path "/cgi-bin/t.cgi" value "foo=bar*" .Ed +.It Ic path strip Ar number +Strip +.Ar number +path components from the beginning of the path of the requested URL +when using the +.Ic http +protocol. +This type is only available with the direction +.Ic request . .It Ic query Ar option Oo Ar key Oo Ic value Ar value Oc Oc Look up the entity as a query variable in the URL when using the .Ic http diff --git a/usr.sbin/relayd/relayd.h b/usr.sbin/relayd/relayd.h index 354c4e7d01f..5cc3dcdbe5e 100644 --- a/usr.sbin/relayd/relayd.h +++ b/usr.sbin/relayd/relayd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: relayd.h,v 1.262 2020/09/14 11:30:25 martijn Exp $ */ +/* $OpenBSD: relayd.h,v 1.263 2021/01/09 08:53:58 denis Exp $ */ /* * Copyright (c) 2006 - 2016 Reyk Floeter <reyk@openbsd.org> @@ -292,7 +292,8 @@ enum key_option { KEY_OPTION_SET, KEY_OPTION_REMOVE, KEY_OPTION_HASH, - KEY_OPTION_LOG + KEY_OPTION_LOG, + KEY_OPTION_STRIP }; enum key_type { |