[MEDIUM] restrict the set of allowed characters for identifiers

In order to avoid issues in the future, we want to restrict
the set of allowed characters for identifiers. Starting from
now, only A-Z, a-z, 0-9, '-', '_', '.' and ':' will be allowed
for a proxy, a server or an ACL name.

A test file has been added to check the restriction.
This commit is contained in:
Willy Tarreau 2007-12-02 18:45:09 +01:00
parent c7246fcdf3
commit 2e74c3f202
5 changed files with 88 additions and 0 deletions

View File

@ -117,6 +117,13 @@ extern const char *limit_r(unsigned long n, char *buffer, int size, const char *
*/
extern int ishex(char s);
/*
* Checks <name> for invalid characters. Valid chars are [A-Za-z0-9_:.-]. If an
* invalid character is found, a pointer to it is returned. If everything is
* fine, NULL is returned.
*/
extern const char *invalid_char(const char *name);
/*
* converts <str> to a struct sockaddr_in* which is locally allocated.
* The format is "addr:port", where "addr" can be a dotted IPv4 address,

View File

@ -580,6 +580,9 @@ struct acl *parse_acl(const char **args, struct list *known_acl)
struct acl_expr *acl_expr;
char *name;
if (invalid_char(*args))
goto out_return;
acl_expr = parse_acl_expr(args + 1);
if (!acl_expr)
goto out_return;

View File

@ -534,6 +534,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
return -1;
}
err = invalid_char(args[1]);
if (err) {
Alert("parsing [%s:%d] : character '%c' is not permitted in '%s' name '%s'.\n",
file, linenum, *err, args[0], args[1]);
return -1;
}
for (curproxy = proxy; curproxy != NULL; curproxy = curproxy->next) {
/*
* If there are two proxies with the same name only following
@ -759,6 +766,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
curproxy->state = PR_STNEW;
}
else if (!strcmp(args[0], "acl")) { /* add an ACL */
err = invalid_char(args[1]);
if (err) {
Alert("parsing [%s:%d] : character '%c' is not permitted in acl name '%s'.\n",
file, linenum, *err, args[1]);
return -1;
}
if (parse_acl((const char **)args + 1, &curproxy->acl) == NULL) {
Alert("parsing [%s:%d] : error detected while parsing ACL '%s'.\n",
file, linenum, args[1]);
@ -1414,6 +1428,14 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
file, linenum, args[0]);
return -1;
}
err = invalid_char(args[1]);
if (err) {
Alert("parsing [%s:%d] : character '%c' is not permitted in server name '%s'.\n",
file, linenum, *err, args[1]);
return -1;
}
if ((newsrv = (struct server *)calloc(1, sizeof(struct server))) == NULL) {
Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
return -1;

View File

@ -10,6 +10,7 @@
*
*/
#include <ctype.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
@ -98,6 +99,24 @@ int ishex(char s)
return 0;
}
/*
* Checks <name> for invalid characters. Valid chars are [A-Za-z0-9_:.-]. If an
* invalid character is found, a pointer to it is returned. If everything is
* fine, NULL is returned.
*/
const char *invalid_char(const char *name)
{
if (!*name)
return name;
while (*name) {
if (!isalnum(*name) && *name != '.' && *name != ':' &&
*name != '_' && *name != '-')
return name;
name++;
}
return NULL;
}
/*
* converts <str> to a struct sockaddr_in* which is locally allocated.

View File

@ -0,0 +1,37 @@
# This is a test configuration.
# It checks instances, servers and acl names.
listen valid_listen1
bind :8000
clitimeout 5000
contimeout 5000
srvtimeout 5000
balance roundrobin
server srv1 127.0.0.1:80
frontend www.valid-frontend.net:80
bind :8001
clitimeout 5000
acl host_www.valid-frontend.net:80 hdr(host) www.valid-frontend.net
backend Valid_BK-1
contimeout 5000
srvtimeout 5000
balance roundrobin
server bk1_srv-1:80 127.0.0.1:80
frontend www.test-frontend.net:8002/invalid
bind :8002
clitimeout 5000
frontend ft1_acl
bind :8003
clitimeout 5000
acl invalid!name url /
backend bk2_srv
contimeout 5000
srvtimeout 5000
balance roundrobin
server bk2/srv-1 127.0.0.1:80