mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-12-07 02:31:01 +01:00
[MINOR] acl: support loading values from files
The "acl XXX -f <file>" syntax was supported but nothing was read from the file. This is now possible. All lines are merged verbatim, even if they contain spaces (useful for user-agents). There are shortcomings though. The worst one is that error reporting is too approximative.
This commit is contained in:
parent
b1a34b68ca
commit
2b5285da33
@ -5886,9 +5886,27 @@ performance, they just consume a small amount of memory.
|
||||
|
||||
The following ACL flags are currently supported :
|
||||
|
||||
-i : ignore case during matching.
|
||||
-i : ignore case during matching of all subsequent patterns.
|
||||
-f : load patterns from a file.
|
||||
-- : force end of flags. Useful when a string looks like one of the flags.
|
||||
|
||||
The "-f" flag is special as it loads all of the lines it finds in the file
|
||||
specified in argument and loads all of them before continuing. It is even
|
||||
possible to pass multiple "-f" arguments if the patterns are to be loaded from
|
||||
multiple files. Also, note that the "-i" flag applies to subsequent entries and
|
||||
not to entries loaded from files preceeding it. For instance :
|
||||
|
||||
acl valid-ua hdr(user-agent) -f exact-ua.lst -i -f generic-ua.lst test
|
||||
|
||||
In this example, each line of "exact-ua.lst" will be exactly matched against
|
||||
the "user-agent" header of the request. Then each line of "generic-ua" will be
|
||||
case-insensitively matched. Then the word "test" will be insensitively matched
|
||||
too.
|
||||
|
||||
Note that right now it is difficult for the ACL parsers to report errors, so if
|
||||
a file is unreadable or unparsable, the most you'll get is a parse error in the
|
||||
ACL. Thus, file-based ACLs should only be produced by reliable processes.
|
||||
|
||||
Supported types of values are :
|
||||
|
||||
- integers or integer ranges
|
||||
|
||||
55
src/acl.c
55
src/acl.c
@ -19,6 +19,8 @@
|
||||
#include <common/standard.h>
|
||||
#include <common/uri_auth.h>
|
||||
|
||||
#include <types/global.h>
|
||||
|
||||
#include <proto/acl.h>
|
||||
#include <proto/auth.h>
|
||||
#include <proto/log.h>
|
||||
@ -658,6 +660,52 @@ static struct acl_expr *prune_acl_expr(struct acl_expr *expr)
|
||||
return expr;
|
||||
}
|
||||
|
||||
static int acl_read_patterns_from_file( struct acl_keyword *aclkw,
|
||||
struct acl_expr *expr,
|
||||
const char *filename, int patflags)
|
||||
{
|
||||
FILE *file;
|
||||
char *c;
|
||||
const char *args[2];
|
||||
struct acl_pattern *pattern;
|
||||
int opaque;
|
||||
|
||||
file = fopen(filename, "r");
|
||||
if (!file)
|
||||
return 0;
|
||||
|
||||
/* now parse all patterns. The file may contain only one pattern per
|
||||
* line. If the line contains spaces, they will be part of the pattern.
|
||||
* The pattern stops at the first CR, LF or EOF encountered.
|
||||
*/
|
||||
opaque = 0;
|
||||
args[0] = trash;
|
||||
args[1] = "";
|
||||
while (fgets(trash, sizeof(trash), file) != NULL) {
|
||||
|
||||
c = trash;
|
||||
while (*c && *c != '\n' && *c != '\r')
|
||||
c++;
|
||||
*c = 0;
|
||||
|
||||
pattern = (struct acl_pattern *)calloc(1, sizeof(*pattern));
|
||||
if (!pattern)
|
||||
goto out_close;
|
||||
pattern->flags = patflags;
|
||||
|
||||
if (!aclkw->parse(args, pattern, &opaque))
|
||||
goto out_free_pattern;
|
||||
LIST_ADDQ(&expr->patterns, &pattern->list);
|
||||
}
|
||||
return 1;
|
||||
|
||||
out_free_pattern:
|
||||
free_pattern(pattern);
|
||||
out_close:
|
||||
fclose(file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse an ACL expression starting at <args>[0], and return it.
|
||||
* Right now, the only accepted syntax is :
|
||||
* <subject> [<value>...]
|
||||
@ -711,8 +759,11 @@ struct acl_expr *parse_acl_expr(const char **args)
|
||||
while (**args == '-') {
|
||||
if ((*args)[1] == 'i')
|
||||
patflags |= ACL_PAT_F_IGNORE_CASE;
|
||||
else if ((*args)[1] == 'f')
|
||||
patflags |= ACL_PAT_F_FROM_FILE;
|
||||
else if ((*args)[1] == 'f') {
|
||||
if (!acl_read_patterns_from_file(aclkw, expr, args[1], patflags | ACL_PAT_F_FROM_FILE))
|
||||
goto out_free_expr;
|
||||
args++;
|
||||
}
|
||||
else if ((*args)[1] == '-') {
|
||||
args++;
|
||||
break;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user