From 2e74c3f2023cff6cd5ca6f1a265422f2306ae306 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 2 Dec 2007 18:45:09 +0100 Subject: [PATCH] [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. --- include/common/standard.h | 7 +++++++ src/acl.c | 3 +++ src/cfgparse.c | 22 ++++++++++++++++++++++ src/standard.c | 19 +++++++++++++++++++ tests/test-valid-names.cfg | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 tests/test-valid-names.cfg 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 +