From: Willy Tarreau Date: Sun, 2 Dec 2007 17:45:09 +0000 (+0100) Subject: [MEDIUM] restrict the set of allowed characters for identifiers X-Git-Tag: v1.3.14~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2e74c3f2023cff6cd5ca6f1a265422f2306ae306;p=thirdparty%2Fhaproxy.git [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. --- diff --git a/include/common/standard.h b/include/common/standard.h index 80f6d2a28a..0dde6db37b 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 f7ac06c0e8..aa095c5bd2 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 232ae1c7bf..b64d4c6b47 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 0b1629659d..07aa5e48d8 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 0000000000..1842a78138 --- /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 +