MEDIUM: acl: use temp_pattern to store any string-type information
Now strings and data blocks are stored in the temp_pattern's chunk
and matched against this one.
The rdp_cookie currently makes extensive use of acl_fetch_rdp_cookie()
and will be a good candidate for the initial rework so that ACLs use
the patterns framework and not the other way around.
diff --git a/src/acl.c b/src/acl.c
index c23e5c3..9a20cc2 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -423,8 +423,8 @@
name_len = (data[7] << 8) + data[8];
if (name_type == 0) { /* hostname */
- test->ptr = data + 9;
- test->len = name_len;
+ temp_pattern.data.str.str = data + 9;
+ temp_pattern.data.str.len = name_len;
test->flags = ACL_TEST_F_VOLATILE;
//fprintf(stderr, "found SNI : <");
//write(2, test->ptr, test->len);
@@ -513,8 +513,8 @@
}
/* data points to cookie value */
- test->ptr = (char *)data;
- test->len = 0;
+ temp_pattern.data.str.str = (char *)data;
+ temp_pattern.data.str.len = 0;
while (bleft > 0 && *data != '\r') {
data++;
@@ -527,7 +527,7 @@
if (data[0] != '\r' || data[1] != '\n')
goto not_cookie;
- test->len = (char *)data - test->ptr;
+ temp_pattern.data.str.len = (char *)data - temp_pattern.data.str.str;
test->flags = ACL_TEST_F_VOLATILE;
return 1;
@@ -545,8 +545,8 @@
ret = acl_fetch_rdp_cookie(px, l4, l7, dir, expr, test);
- test->ptr = NULL;
- test->len = 0;
+ temp_pattern.data.str.str = NULL;
+ temp_pattern.data.str.len = 0;
if (test->flags & ACL_TEST_F_MAY_CHANGE)
return 0;
@@ -587,12 +587,12 @@
{
int icase;
- if (pattern->len != test->len)
+ if (pattern->len != temp_pattern.data.str.len)
return ACL_PAT_FAIL;
icase = pattern->flags & ACL_PAT_F_IGNORE_CASE;
- if ((icase && strncasecmp(pattern->ptr.str, test->ptr, test->len) == 0) ||
- (!icase && strncmp(pattern->ptr.str, test->ptr, test->len) == 0))
+ if ((icase && strncasecmp(pattern->ptr.str, temp_pattern.data.str.str, temp_pattern.data.str.len) == 0) ||
+ (!icase && strncmp(pattern->ptr.str, temp_pattern.data.str.str, temp_pattern.data.str.len) == 0))
return ACL_PAT_PASS;
return ACL_PAT_FAIL;
}
@@ -607,12 +607,12 @@
char prev;
/* we may have to force a trailing zero on the test pattern */
- prev = test->ptr[test->len];
+ prev = temp_pattern.data.str.str[temp_pattern.data.str.len];
if (prev)
- test->ptr[test->len] = '\0';
- node = ebst_lookup(&expr->pattern_tree, test->ptr);
+ temp_pattern.data.str.str[temp_pattern.data.str.len] = '\0';
+ node = ebst_lookup(&expr->pattern_tree, temp_pattern.data.str.str);
if (prev)
- test->ptr[test->len] = prev;
+ temp_pattern.data.str.str[temp_pattern.data.str.len] = prev;
return node;
}
@@ -629,28 +629,28 @@
if (unlikely(test->flags & ACL_TEST_F_READ_ONLY)) {
char *new_str;
- new_str = calloc(1, test->len + 1);
+ new_str = calloc(1, temp_pattern.data.str.len + 1);
if (!new_str)
return ACL_PAT_FAIL;
- memcpy(new_str, test->ptr, test->len);
- new_str[test->len] = 0;
+ memcpy(new_str, temp_pattern.data.str.str, temp_pattern.data.str.len);
+ new_str[temp_pattern.data.str.len] = 0;
if (test->flags & ACL_TEST_F_MUST_FREE)
- free(test->ptr);
- test->ptr = new_str;
+ free(temp_pattern.data.str.str);
+ temp_pattern.data.str.str = new_str;
test->flags |= ACL_TEST_F_MUST_FREE;
test->flags &= ~ACL_TEST_F_READ_ONLY;
}
- old_char = test->ptr[test->len];
- test->ptr[test->len] = 0;
+ old_char = temp_pattern.data.str.str[temp_pattern.data.str.len];
+ temp_pattern.data.str.str[temp_pattern.data.str.len] = 0;
- if (regexec(pattern->ptr.reg, test->ptr, 0, NULL, 0) == 0)
+ if (regexec(pattern->ptr.reg, temp_pattern.data.str.str, 0, NULL, 0) == 0)
ret = ACL_PAT_PASS;
else
ret = ACL_PAT_FAIL;
- test->ptr[test->len] = old_char;
+ temp_pattern.data.str.str[temp_pattern.data.str.len] = old_char;
return ret;
}
@@ -659,12 +659,12 @@
{
int icase;
- if (pattern->len > test->len)
+ if (pattern->len > temp_pattern.data.str.len)
return ACL_PAT_FAIL;
icase = pattern->flags & ACL_PAT_F_IGNORE_CASE;
- if ((icase && strncasecmp(pattern->ptr.str, test->ptr, pattern->len) != 0) ||
- (!icase && strncmp(pattern->ptr.str, test->ptr, pattern->len) != 0))
+ if ((icase && strncasecmp(pattern->ptr.str, temp_pattern.data.str.str, pattern->len) != 0) ||
+ (!icase && strncmp(pattern->ptr.str, temp_pattern.data.str.str, pattern->len) != 0))
return ACL_PAT_FAIL;
return ACL_PAT_PASS;
}
@@ -674,11 +674,11 @@
{
int icase;
- if (pattern->len > test->len)
+ if (pattern->len > temp_pattern.data.str.len)
return ACL_PAT_FAIL;
icase = pattern->flags & ACL_PAT_F_IGNORE_CASE;
- if ((icase && strncasecmp(pattern->ptr.str, test->ptr + test->len - pattern->len, pattern->len) != 0) ||
- (!icase && strncmp(pattern->ptr.str, test->ptr + test->len - pattern->len, pattern->len) != 0))
+ if ((icase && strncasecmp(pattern->ptr.str, temp_pattern.data.str.str + temp_pattern.data.str.len - pattern->len, pattern->len) != 0) ||
+ (!icase && strncmp(pattern->ptr.str, temp_pattern.data.str.str + temp_pattern.data.str.len - pattern->len, pattern->len) != 0))
return ACL_PAT_FAIL;
return ACL_PAT_PASS;
}
@@ -692,20 +692,20 @@
char *end;
char *c;
- if (pattern->len > test->len)
+ if (pattern->len > temp_pattern.data.str.len)
return ACL_PAT_FAIL;
- end = test->ptr + test->len - pattern->len;
+ end = temp_pattern.data.str.str + temp_pattern.data.str.len - pattern->len;
icase = pattern->flags & ACL_PAT_F_IGNORE_CASE;
if (icase) {
- for (c = test->ptr; c <= end; c++) {
+ for (c = temp_pattern.data.str.str; c <= end; c++) {
if (tolower(*c) != tolower(*pattern->ptr.str))
continue;
if (strncasecmp(pattern->ptr.str, c, pattern->len) == 0)
return ACL_PAT_PASS;
}
} else {
- for (c = test->ptr; c <= end; c++) {
+ for (c = temp_pattern.data.str.str; c <= end; c++) {
if (*c != *pattern->ptr.str)
continue;
if (strncmp(pattern->ptr.str, c, pattern->len) == 0)
@@ -761,13 +761,13 @@
while (pl > 0 && is_delimiter(ps[pl - 1], delimiters))
pl--;
- if (pl > test->len)
+ if (pl > temp_pattern.data.str.len)
return ACL_PAT_FAIL;
may_match = 1;
icase = pattern->flags & ACL_PAT_F_IGNORE_CASE;
- end = test->ptr + test->len - pl;
- for (c = test->ptr; c <= end; c++) {
+ end = temp_pattern.data.str.str + temp_pattern.data.str.len - pl;
+ for (c = temp_pattern.data.str.str; c <= end; c++) {
if (is_delimiter(*c, delimiters)) {
may_match = 1;
continue;
@@ -822,8 +822,8 @@
/* Checks that the length of the pattern in <test> is included between min and max */
int acl_match_len(struct acl_test *test, struct acl_pattern *pattern)
{
- if ((!pattern->val.range.min_set || pattern->val.range.min <= test->len) &&
- (!pattern->val.range.max_set || test->len <= pattern->val.range.max))
+ if ((!pattern->val.range.min_set || pattern->val.range.min <= temp_pattern.data.str.len) &&
+ (!pattern->val.range.max_set || temp_pattern.data.str.len <= pattern->val.range.max))
return ACL_PAT_PASS;
return ACL_PAT_FAIL;
}
@@ -1851,8 +1851,8 @@
/* now we may have some cleanup to do */
if (test.flags & ACL_TEST_F_MUST_FREE) {
- free(test.ptr);
- test.len = 0;
+ free(temp_pattern.data.str.str);
+ temp_pattern.data.str.len = 0;
}
/* we're ORing these terms, so a single PASS is enough */
diff --git a/src/backend.c b/src/backend.c
index 0f3bccd..5e88f62 100644
--- a/src/backend.c
+++ b/src/backend.c
@@ -413,7 +413,9 @@
expr.arg_len = px->hh_len;
ret = acl_fetch_rdp_cookie(px, s, NULL, ACL_DIR_REQ, &expr, &test);
- if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || test.len == 0)
+ len = temp_pattern.data.str.len;
+
+ if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || len == 0)
return NULL;
/* note: we won't hash if there's only one server left */
@@ -423,8 +425,7 @@
/* Found a the hh_name in the headers.
* we will compute the hash based on this value ctx.val.
*/
- len = test.len;
- p = (char *)test.ptr;
+ p = temp_pattern.data.str.str;
while (len) {
hash = *p + (hash << 6) + (hash << 16) - hash;
len--;
@@ -1112,14 +1113,14 @@
expr.arg_len = s->be->rdp_cookie_len;
ret = acl_fetch_rdp_cookie(px, s, NULL, ACL_DIR_REQ, &expr, &test);
- if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || test.len == 0)
+ if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || temp_pattern.data.str.len == 0)
goto no_cookie;
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
- /* Considering an rdp cookie detected using acl, test.ptr ended with <cr><lf> and should return */
- addr.sin_addr.s_addr = strtoul(test.ptr, &p, 10);
+ /* Considering an rdp cookie detected using acl, str ended with <cr><lf> and should return */
+ addr.sin_addr.s_addr = strtoul(temp_pattern.data.str.str, &p, 10);
if (*p != '.')
goto no_cookie;
p++;
diff --git a/src/proto_http.c b/src/proto_http.c
index b60048e..10a4bdd 100644
--- a/src/proto_http.c
+++ b/src/proto_http.c
@@ -7866,8 +7866,8 @@
if (len <= 0)
return 0;
- test->ptr = ptr;
- test->len = len;
+ temp_pattern.data.str.str = ptr;
+ temp_pattern.data.str.len = len;
test->flags = ACL_TEST_F_READ_ONLY | ACL_TEST_F_VOL_1ST;
return 1;
@@ -7894,8 +7894,8 @@
if (len <= 0)
return 0;
- test->ptr = ptr;
- test->len = len;
+ temp_pattern.data.str.str = ptr;
+ temp_pattern.data.str.len = len;
test->flags = ACL_TEST_F_READ_ONLY | ACL_TEST_F_VOL_1ST;
return 1;
@@ -7941,8 +7941,8 @@
/* ensure the indexes are not affected */
return 0;
- test->len = txn->req.sl.rq.u_l;
- test->ptr = txn->req.sol + txn->req.sl.rq.u;
+ temp_pattern.data.str.len = txn->req.sl.rq.u_l;
+ temp_pattern.data.str.str = txn->req.sol + txn->req.sl.rq.u;
/* we do not need to set READ_ONLY because the data is in a buffer */
test->flags = ACL_TEST_F_VOL_1ST;
@@ -8031,8 +8031,9 @@
if (http_find_header2(expr->arg.str, expr->arg_len, sol, idx, ctx)) {
test->flags |= ACL_TEST_F_FETCH_MORE;
test->flags |= ACL_TEST_F_VOL_HDR;
- test->len = ctx->vlen;
- test->ptr = (char *)ctx->line + ctx->val;
+ temp_pattern.data.str.str = (char *)ctx->line + ctx->val;
+ temp_pattern.data.str.len = ctx->vlen;
+
return 1;
}
@@ -8292,12 +8293,12 @@
return 0;
/* OK, we got the '/' ! */
- test->ptr = ptr;
+ temp_pattern.data.str.str = ptr;
while (ptr < end && *ptr != '?')
ptr++;
- test->len = ptr - test->ptr;
+ temp_pattern.data.str.len = ptr - temp_pattern.data.str.str;
/* we do not need to set READ_ONLY because the data is in a buffer */
test->flags = ACL_TEST_F_VOL_1ST;
diff --git a/src/proto_tcp.c b/src/proto_tcp.c
index 207fec0..ea3692c 100644
--- a/src/proto_tcp.c
+++ b/src/proto_tcp.c
@@ -1580,11 +1580,10 @@
expr.arg_len = arg_p[0].data.str.len;
ret = acl_fetch_rdp_cookie(px, l4, NULL, ACL_DIR_REQ, &expr, &test);
- if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || test.len == 0)
+ if (ret == 0 || (test.flags & ACL_TEST_F_MAY_CHANGE) || temp_pattern.data.str.len == 0)
return 0;
- /* init chunk as read only */
- chunk_initlen(&data->str, test.ptr, 0, test.len);
+ data->str = temp_pattern.data.str;
return 1;
}