diff --git a/include/common/standard.h b/include/common/standard.h index 80f6d2a28..0dde6db37 100644 --- a/include/common/standard.h +++ b/include/common/standard.h @@ -117,6 +117,13 @@ extern const char *limit_r(unsigned long n, char *buffer, int size, const char * */ extern int ishex(char s); +/* + * Checks 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 to a struct sockaddr_in* which is locally allocated. * The format is "addr:port", where "addr" can be a dotted IPv4 address, diff --git a/src/acl.c b/src/acl.c index f7ac06c0e..aa095c5bd 100644 --- a/src/acl.c +++ b/src/acl.c @@ -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; diff --git a/src/cfgparse.c b/src/cfgparse.c index 232ae1c7b..b64d4c6b4 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -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; diff --git a/src/standard.c b/src/standard.c index 0b1629659..07aa5e48d 100644 --- a/src/standard.c +++ b/src/standard.c @@ -10,6 +10,7 @@ * */ +#include #include #include #include @@ -98,6 +99,24 @@ int ishex(char s) return 0; } +/* + * Checks 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 to a struct sockaddr_in* which is locally allocated. diff --git a/tests/test-valid-names.cfg b/tests/test-valid-names.cfg new file mode 100644 index 000000000..1842a7813 --- /dev/null +++ b/tests/test-valid-names.cfg @@ -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 +