summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordenis <denis@openbsd.org>2021-01-09 08:53:57 +0000
committerdenis <denis@openbsd.org>2021-01-09 08:53:57 +0000
commiteeb1fea4acc9c4cbc2c39aee16664ef34a5ef36c (patch)
treec834dbf96d439ed8d3e4171facc2b66c2a9b8cfc
parentSet chain on xsc on chain build failure. (diff)
downloadwireguard-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.y19
-rw-r--r--usr.sbin/relayd/relay.c11
-rw-r--r--usr.sbin/relayd/relay_http.c46
-rw-r--r--usr.sbin/relayd/relayd.conf.513
-rw-r--r--usr.sbin/relayd/relayd.h5
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 {