mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
[MEDIUM] provide default ACLs
The following ACLs are predefined : LOCALHOST = src 127.0.0.1/8 HTTP_1.0 = req_ver 1.0 HTTP_1.1 = req_ver 1.1 METH_CONNECT = method CONNECT METH_GET = method GET HEAD METH_HEAD = method HEAD METH_OPTIONS = method OPTIONS METH_POST = method POST METH_TRACE = method TRACE HTTP_URL_ABS = url_reg ^[^/:]*:// HTTP_URL_SLASH = url_beg / HTTP_URL_STAR = url * HTTP_CONTENT = hdr_val(content-length) gt 0
This commit is contained in:
parent
8aeae4af23
commit
16fbe82bfc
85
src/acl.c
85
src/acl.c
@ -584,6 +584,76 @@ struct acl *parse_acl(const char **args, struct list *known_acl)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Some useful ACLs provided by default. Only those used are allocated. */
|
||||||
|
|
||||||
|
const struct {
|
||||||
|
const char *name;
|
||||||
|
const char *expr[4]; /* put enough for longest expression */
|
||||||
|
} default_acl_list[] = {
|
||||||
|
{ .name = "LOCALHOST", .expr = {"src","127.0.0.1/8",""}},
|
||||||
|
{ .name = "HTTP_1.0", .expr = {"req_ver","1.0",""}},
|
||||||
|
{ .name = "HTTP_1.1", .expr = {"req_ver","1.1",""}},
|
||||||
|
{ .name = "METH_CONNECT", .expr = {"method","CONNECT",""}},
|
||||||
|
{ .name = "METH_GET", .expr = {"method","GET","HEAD",""}},
|
||||||
|
{ .name = "METH_HEAD", .expr = {"method","HEAD",""}},
|
||||||
|
{ .name = "METH_OPTIONS", .expr = {"method","OPTIONS",""}},
|
||||||
|
{ .name = "METH_POST", .expr = {"method","POST",""}},
|
||||||
|
{ .name = "METH_TRACE", .expr = {"method","TRACE",""}},
|
||||||
|
{ .name = "HTTP_URL_ABS", .expr = {"url_reg","^[^/:]*://",""}},
|
||||||
|
{ .name = "HTTP_URL_SLASH", .expr = {"url_beg","/",""}},
|
||||||
|
{ .name = "HTTP_URL_STAR", .expr = {"url","*",""}},
|
||||||
|
{ .name = "HTTP_CONTENT", .expr = {"hdr_val(content-length)","gt","0",""}},
|
||||||
|
{ .name = NULL, .expr = {""}}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Find a default ACL from the default_acl list, compile it and return it.
|
||||||
|
* If the ACL is not found, NULL is returned. In theory, it cannot fail,
|
||||||
|
* except when default ACLs are broken, in which case it will return NULL.
|
||||||
|
* If <known_acl> is not NULL, the ACL will be queued at its tail.
|
||||||
|
*/
|
||||||
|
struct acl *find_acl_default(const char *acl_name, struct list *known_acl)
|
||||||
|
{
|
||||||
|
__label__ out_return, out_free_acl_expr, out_free_name;
|
||||||
|
struct acl *cur_acl;
|
||||||
|
struct acl_expr *acl_expr;
|
||||||
|
char *name;
|
||||||
|
int index;
|
||||||
|
|
||||||
|
for (index = 0; default_acl_list[index].name != NULL; index++) {
|
||||||
|
if (strcmp(acl_name, default_acl_list[index].name) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (default_acl_list[index].name == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
acl_expr = parse_acl_expr((const char **)default_acl_list[index].expr);
|
||||||
|
if (!acl_expr)
|
||||||
|
goto out_return;
|
||||||
|
|
||||||
|
name = strdup(acl_name);
|
||||||
|
if (!name)
|
||||||
|
goto out_free_acl_expr;
|
||||||
|
cur_acl = (struct acl *)calloc(1, sizeof(*cur_acl));
|
||||||
|
if (cur_acl == NULL)
|
||||||
|
goto out_free_name;
|
||||||
|
|
||||||
|
cur_acl->name = name;
|
||||||
|
LIST_INIT(&cur_acl->expr);
|
||||||
|
LIST_ADDQ(&cur_acl->expr, &acl_expr->list);
|
||||||
|
if (known_acl)
|
||||||
|
LIST_ADDQ(known_acl, &cur_acl->list);
|
||||||
|
|
||||||
|
return cur_acl;
|
||||||
|
|
||||||
|
out_free_name:
|
||||||
|
free(name);
|
||||||
|
out_free_acl_expr:
|
||||||
|
prune_acl_expr(acl_expr);
|
||||||
|
free(acl_expr);
|
||||||
|
out_return:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Purge everything in the acl_cond <cond>, then return <cond>. */
|
/* Purge everything in the acl_cond <cond>, then return <cond>. */
|
||||||
struct acl_cond *prune_acl_cond(struct acl_cond *cond)
|
struct acl_cond *prune_acl_cond(struct acl_cond *cond)
|
||||||
@ -639,17 +709,24 @@ struct acl_cond *parse_acl_cond(const char **args, struct list *known_acl, int p
|
|||||||
if (!*word)
|
if (!*word)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (strcasecmp(word, "or") == 0) {
|
if (strcasecmp(word, "or") == 0 || strcmp(word, "||") == 0) {
|
||||||
/* new term suite */
|
/* new term suite */
|
||||||
cur_suite = NULL;
|
cur_suite = NULL;
|
||||||
neg = 0;
|
neg = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* search for <word> in the known ACL names */
|
/* search for <word> in the known ACL names. If we do not find
|
||||||
|
* it, let's look for it in the default ACLs, and if found, add
|
||||||
|
* it to the list of ACLs of this proxy. This makes it possible
|
||||||
|
* to override them.
|
||||||
|
*/
|
||||||
cur_acl = find_acl_by_name(word, known_acl);
|
cur_acl = find_acl_by_name(word, known_acl);
|
||||||
if (cur_acl == NULL)
|
if (cur_acl == NULL) {
|
||||||
goto out_free_suite;
|
cur_acl = find_acl_default(word, known_acl);
|
||||||
|
if (cur_acl == NULL)
|
||||||
|
goto out_free_suite;
|
||||||
|
}
|
||||||
|
|
||||||
cur_term = (struct acl_term *)calloc(1, sizeof(*cur_term));
|
cur_term = (struct acl_term *)calloc(1, sizeof(*cur_term));
|
||||||
if (cur_term == NULL)
|
if (cur_term == NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user