mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-06 15:17:01 +02:00
MINOR: spoe: add register-var-names directive in spoe-agent configuration
In addition to "option force-set-var", recently added, this directive can be used to selectivelly register unknown variable names, without totally relaxing their registration during the runtime, like "option force-set-var" does. So there is no way for a malicious agent to exhaust memory by defining a too high number of variable names. In other hand, you need to enumerate all variable names. This could be painfull in some circumstances. Remember, this directive is only usefull when the variable names are not referenced anywhere in the HAProxy configuration or the SPOE one. Thanks to Etienne Carrire for his help on this part.
This commit is contained in:
parent
d651ba14d4
commit
336d3ef0e7
21
doc/SPOE.txt
21
doc/SPOE.txt
@ -172,8 +172,10 @@ spoe-agent <name>
|
|||||||
- [no] option pipelining
|
- [no] option pipelining
|
||||||
- [no] option send-frag-payload
|
- [no] option send-frag-payload
|
||||||
- option continue-on-error
|
- option continue-on-error
|
||||||
|
- option force-set-var
|
||||||
- option set-on-error
|
- option set-on-error
|
||||||
- option var-prefix
|
- option var-prefix
|
||||||
|
- register-var-names
|
||||||
- timeout hello|idle|processing
|
- timeout hello|idle|processing
|
||||||
- use-backend
|
- use-backend
|
||||||
|
|
||||||
@ -321,8 +323,24 @@ option var-prefix <prefix>
|
|||||||
|
|
||||||
By default, an agent will never set new variables at runtime: It can only set
|
By default, an agent will never set new variables at runtime: It can only set
|
||||||
new value for existing ones. If you want a different behaviour, see
|
new value for existing ones. If you want a different behaviour, see
|
||||||
force-set-var option
|
force-set-var option and register-var-names directive.
|
||||||
|
|
||||||
|
register-var-names <var name> ...
|
||||||
|
Register some variable names. By default, an agent will not be allowed to set
|
||||||
|
new variables at runtime. This rule can be totally relaxed by setting the
|
||||||
|
option "force-set-var". If you know all the variables you will need, this
|
||||||
|
directive is a good way to register them without letting an agent doing what
|
||||||
|
it want. This is only required if these variables are not referenced anywhere
|
||||||
|
in the HAProxy configuration or the SPOE one.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
<var name> is a variable name without the scope. The name may only
|
||||||
|
contain characters 'a-z', 'A-Z', '0-9', '.' and '_'.
|
||||||
|
|
||||||
|
The prefix will be automatically added during the registration. You can have
|
||||||
|
many "register-var-names" lines.
|
||||||
|
|
||||||
|
See also: "option force-set-var", "option var-prefix".
|
||||||
|
|
||||||
timeout hello <timeout>
|
timeout hello <timeout>
|
||||||
Set the maximum time to wait for an agent to receive the AGENT-HELLO frame.
|
Set the maximum time to wait for an agent to receive the AGENT-HELLO frame.
|
||||||
@ -391,7 +409,6 @@ spoe-message <name>
|
|||||||
|
|
||||||
|
|
||||||
acl <aclname> <criterion> [flags] [operator] <value> ...
|
acl <aclname> <criterion> [flags] [operator] <value> ...
|
||||||
|
|
||||||
Declare or complete an access list.
|
Declare or complete an access list.
|
||||||
|
|
||||||
See section 7 about ACL usage in the HAProxy Configuration Manual.
|
See section 7 about ACL usage in the HAProxy Configuration Manual.
|
||||||
|
@ -177,6 +177,13 @@ struct spoe_placeholder {
|
|||||||
struct list list; /* Use to chain SPOE placeholders */
|
struct list list; /* Use to chain SPOE placeholders */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Used during the config parsing, when SPOE agent section is parsed, to
|
||||||
|
* register some variable names. */
|
||||||
|
struct spoe_var_placeholder {
|
||||||
|
char *name; /* The variable name */
|
||||||
|
struct list list; /* Use to chain SPOE var placeholders */
|
||||||
|
};
|
||||||
|
|
||||||
/* Describe a message that will be sent in a NOTIFY frame. A message has a name,
|
/* Describe a message that will be sent in a NOTIFY frame. A message has a name,
|
||||||
* an argument list (see above) and it is linked to a specific event. */
|
* an argument list (see above) and it is linked to a specific event. */
|
||||||
struct spoe_message {
|
struct spoe_message {
|
||||||
|
@ -87,6 +87,7 @@ struct list curmsgs;
|
|||||||
struct list curgrps;
|
struct list curgrps;
|
||||||
struct list curmphs;
|
struct list curmphs;
|
||||||
struct list curgphs;
|
struct list curgphs;
|
||||||
|
struct list curvars;
|
||||||
|
|
||||||
/* Pools used to allocate SPOE structs */
|
/* Pools used to allocate SPOE structs */
|
||||||
static struct pool_head *pool_head_spoe_ctx = NULL;
|
static struct pool_head *pool_head_spoe_ctx = NULL;
|
||||||
@ -3483,6 +3484,33 @@ cfg_parse_spoe_agent(const char *file, int linenum, char **args, int kwm)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (!strcmp(args[0], "register-var-names")) {
|
||||||
|
int cur_arg;
|
||||||
|
|
||||||
|
if (!*args[1]) {
|
||||||
|
ha_alert("parsing [%s:%d] : '%s' expects one or more variable names.\n",
|
||||||
|
file, linenum, args[0]);
|
||||||
|
err_code |= ERR_ALERT | ERR_FATAL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
cur_arg = 1;
|
||||||
|
while (*args[cur_arg]) {
|
||||||
|
struct spoe_var_placeholder *vph;
|
||||||
|
|
||||||
|
if ((vph = calloc(1, sizeof(*vph))) == NULL) {
|
||||||
|
ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
|
||||||
|
err_code |= ERR_ALERT | ERR_ABORT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if ((vph->name = strdup(args[cur_arg])) == NULL) {
|
||||||
|
ha_alert("parsing [%s:%d] : out of memory.\n", file, linenum);
|
||||||
|
err_code |= ERR_ALERT | ERR_ABORT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
LIST_ADDQ(&curvars, &vph->list);
|
||||||
|
cur_arg++;
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (*args[0]) {
|
else if (*args[0]) {
|
||||||
ha_alert("parsing [%s:%d] : unknown keyword '%s' in spoe-agent section.\n",
|
ha_alert("parsing [%s:%d] : unknown keyword '%s' in spoe-agent section.\n",
|
||||||
file, linenum, args[0]);
|
file, linenum, args[0]);
|
||||||
@ -3779,6 +3807,7 @@ parse_spoe_flt(char **args, int *cur_arg, struct proxy *px,
|
|||||||
struct spoe_message *msg, *msgback;
|
struct spoe_message *msg, *msgback;
|
||||||
struct spoe_group *grp, *grpback;
|
struct spoe_group *grp, *grpback;
|
||||||
struct spoe_placeholder *ph, *phback;
|
struct spoe_placeholder *ph, *phback;
|
||||||
|
struct spoe_var_placeholder *vph, *vphback;
|
||||||
char *file = NULL, *engine = NULL;
|
char *file = NULL, *engine = NULL;
|
||||||
int ret, pos = *cur_arg + 1;
|
int ret, pos = *cur_arg + 1;
|
||||||
|
|
||||||
@ -3834,6 +3863,7 @@ parse_spoe_flt(char **args, int *cur_arg, struct proxy *px,
|
|||||||
LIST_INIT(&curgrps);
|
LIST_INIT(&curgrps);
|
||||||
LIST_INIT(&curmphs);
|
LIST_INIT(&curmphs);
|
||||||
LIST_INIT(&curgphs);
|
LIST_INIT(&curgphs);
|
||||||
|
LIST_INIT(&curvars);
|
||||||
ret = readcfgfile(file);
|
ret = readcfgfile(file);
|
||||||
curproxy = NULL;
|
curproxy = NULL;
|
||||||
|
|
||||||
@ -4061,6 +4091,25 @@ parse_spoe_flt(char **args, int *cur_arg, struct proxy *px,
|
|||||||
LIST_DEL(&ph->list);
|
LIST_DEL(&ph->list);
|
||||||
spoe_release_placeholder(ph);
|
spoe_release_placeholder(ph);
|
||||||
}
|
}
|
||||||
|
list_for_each_entry_safe(vph, vphback, &curvars, list) {
|
||||||
|
struct arg arg;
|
||||||
|
|
||||||
|
trash.len = snprintf(trash.str, trash.size, "proc.%s.%s",
|
||||||
|
curagent->var_pfx, vph->name);
|
||||||
|
|
||||||
|
arg.type = ARGT_STR;
|
||||||
|
arg.data.str.str = trash.str;
|
||||||
|
arg.data.str.len = trash.len;
|
||||||
|
if (!vars_check_arg(&arg, err)) {
|
||||||
|
memprintf(err, "SPOE agent '%s': failed to register variable %s.%s (%s)",
|
||||||
|
curagent->id, curagent->var_pfx, vph->name, *err);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
|
LIST_DEL(&vph->list);
|
||||||
|
free(vph->name);
|
||||||
|
free(vph);
|
||||||
|
}
|
||||||
list_for_each_entry_safe(grp, grpback, &curgrps, list) {
|
list_for_each_entry_safe(grp, grpback, &curgrps, list) {
|
||||||
LIST_DEL(&grp->list);
|
LIST_DEL(&grp->list);
|
||||||
spoe_release_group(grp);
|
spoe_release_group(grp);
|
||||||
@ -4081,6 +4130,11 @@ parse_spoe_flt(char **args, int *cur_arg, struct proxy *px,
|
|||||||
LIST_DEL(&ph->list);
|
LIST_DEL(&ph->list);
|
||||||
spoe_release_placeholder(ph);
|
spoe_release_placeholder(ph);
|
||||||
}
|
}
|
||||||
|
list_for_each_entry_safe(vph, vphback, &curvars, list) {
|
||||||
|
LIST_DEL(&vph->list);
|
||||||
|
free(vph->name);
|
||||||
|
free(vph);
|
||||||
|
}
|
||||||
list_for_each_entry_safe(grp, grpback, &curgrps, list) {
|
list_for_each_entry_safe(grp, grpback, &curgrps, list) {
|
||||||
LIST_DEL(&grp->list);
|
LIST_DEL(&grp->list);
|
||||||
spoe_release_group(grp);
|
spoe_release_group(grp);
|
||||||
|
Loading…
Reference in New Issue
Block a user