diff --git a/NEWS b/NEWS index 9f6befcf..83f72581 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,7 @@ NEWS * [core] fix memory leak in configparser_merge_data * [core] provide array_extract_element and use it * [core] configparser: error on duplicate keys in array merge (fixes #2685) + * [core] more careful parse of $SERVER["socket"] config str (prepare #2204) - 1.4.39 - 2016-01-02 * [core] fix memset_s call (fixes #2698) diff --git a/src/network.c b/src/network.c index 48491e0e..53aadb31 100644 --- a/src/network.c +++ b/src/network.c @@ -161,7 +161,6 @@ static int network_server_init(server *srv, buffer *host_token, specific_config int val; socklen_t addr_len; server_socket *srv_socket; - char *sp; unsigned int port = 0; const char *host; buffer *b; @@ -194,36 +193,39 @@ static int network_server_init(server *srv, buffer *host_token, specific_config b = buffer_init(); buffer_copy_buffer(b, host_token); - /* ipv4:port - * [ipv6]:port - */ - if (NULL == (sp = strrchr(b->ptr, ':'))) { - log_error_write(srv, __FILE__, __LINE__, "sb", "value of $SERVER[\"socket\"] has to be \"ip:port\".", b); - - goto error_free_socket; - } - host = b->ptr; - /* check for [ and ] */ - if (b->ptr[0] == '[' && *(sp-1) == ']') { - *(sp-1) = '\0'; - host++; - - s->use_ipv6 = 1; - } - - *(sp++) = '\0'; - - port = strtol(sp, NULL, 10); - if (host[0] == '/') { /* host is a unix-domain-socket */ is_unix_domain_socket = 1; - } else if (port == 0 || port > 65535) { - log_error_write(srv, __FILE__, __LINE__, "sd", "port out of range:", port); + } else { + /* ipv4:port + * [ipv6]:port + */ + size_t len = buffer_string_length(b); + char *sp = NULL; + if ((b->ptr[0] == '[' && b->ptr[len-1] == ']') || NULL == (sp = strrchr(b->ptr, ':'))) { + log_error_write(srv, __FILE__, __LINE__, "sb", "value of $SERVER[\"socket\"] has to be \"ip:port\".", b); + goto error_free_socket; + } else { + /* found ip:port separator at *sp; port doesn't end in ']', so *sp hopefully doesn't split an IPv6 address */ + *(sp++) = '\0'; + port = strtol(sp, NULL, 10); + } - goto error_free_socket; + /* check for [ and ] */ + if (b->ptr[0] == '[' && *(sp-1) == ']') { + *(sp-1) = '\0'; + host++; + + s->use_ipv6 = 1; + } + + if (port == 0 || port > 65535) { + log_error_write(srv, __FILE__, __LINE__, "sd", "port out of range:", port); + + goto error_free_socket; + } } if (*host == '\0') host = NULL;