summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Strauss <gstrauss@gluelogic.com>2017-10-22 12:27:22 -0400
committerGlenn Strauss <gstrauss@gluelogic.com>2017-10-22 14:13:53 -0400
commit3549fc828005cd5ef5110f44f17b9ff0f5665bb9 (patch)
treef996ee04feda15a8f09b8258ad8322aa65a6e2c6
parent585206616d867c3bd3171331bf63cdadd8e5093d (diff)
downloadlighttpd-git-3549fc828005cd5ef5110f44f17b9ff0f5665bb9.tar.gz
[core] normalize config addrs for != match (#2830)
address strings need to have DNS resolved and port added for consistency when matching other config conditionals x-ref: "1.4.46 regression: $SERVER["socket"] matches when it shouldn't" https://redmine.lighttpd.net/issues/2830
-rw-r--r--src/network.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/network.c b/src/network.c
index d284da50..6c67d876 100644
--- a/src/network.c
+++ b/src/network.c
@@ -69,6 +69,73 @@ static handler_t network_server_handle_fdevent(server *srv, void *context, int r
return HANDLER_GO_ON;
}
+static void network_host_normalize_addr_str(buffer *host, sock_addr *addr) {
+ buffer_reset(host);
+ if (addr->plain.sa_family == AF_INET6)
+ buffer_append_string_len(host, CONST_STR_LEN("["));
+ sock_addr_inet_ntop_append_buffer(host, addr);
+ if (addr->plain.sa_family == AF_INET6)
+ buffer_append_string_len(host, CONST_STR_LEN("]"));
+ if (addr->plain.sa_family != AF_UNIX) {
+ unsigned short port = (addr->plain.sa_family == AF_INET)
+ ? ntohs(addr->ipv4.sin_port)
+ : ntohs(addr->ipv6.sin6_port);
+ buffer_append_string_len(host, CONST_STR_LEN(":"));
+ buffer_append_int(host, (int)port);
+ }
+}
+
+static int network_host_parse_addr(server *srv, sock_addr *addr, socklen_t *addr_len, buffer *host, int use_ipv6) {
+ char *h;
+ char *colon = NULL;
+ const char *chost;
+ sa_family_t family = use_ipv6 ? AF_INET6 : AF_INET;
+ unsigned int port = srv->srvconf.port;
+ if (buffer_string_is_empty(host)) {
+ log_error_write(srv, __FILE__, __LINE__, "s", "value of $SERVER[\"socket\"] must not be empty");
+ return -1;
+ }
+ h = host->ptr;
+ if (h[0] == '/') {
+ #ifdef HAVE_SYS_UN_H
+ return (1 == sock_addr_from_str_hints(srv,addr,addr_len,h,AF_UNIX,0))
+ ? 0
+ : -1;
+ #else
+ log_error_write(srv, __FILE__, __LINE__, "s",
+ "ERROR: Unix Domain sockets are not supported.");
+ return -1;
+ #endif
+ }
+ buffer_copy_buffer(srv->tmp_buf, host);
+ h = srv->tmp_buf->ptr;
+ if (h[0] == '[') {
+ family = AF_INET6;
+ if ((h = strchr(h, ']'))) {
+ *h++ = '\0';
+ if (*h == ':') colon = h;
+ } /*(else should not happen; validated in configparser.y)*/
+ h = srv->tmp_buf->ptr+1;
+ }
+ else {
+ colon = strrchr(h, ':');
+ }
+ if (colon) {
+ *colon++ = '\0';
+ port = strtol(colon, NULL, 10);
+ if (port == 0 || port > 65535) {
+ log_error_write(srv, __FILE__, __LINE__, "sd",
+ "port not set or out of range:", port);
+ return -1;
+ }
+ }
+ chost = *h ? h : family == AF_INET ? "0.0.0.0" : "::";
+ if (1 != sock_addr_from_str_hints(srv,addr,addr_len,chost,family,port)) {
+ return -1;
+ }
+ return 0;
+}
+
static int network_server_init(server *srv, buffer *host_token, size_t sidx, int stdin_fd) {
socklen_t addr_len;
server_socket *srv_socket;
@@ -495,6 +562,16 @@ int network_init(server *srv, int stdin_fd) {
/* not our stage */
if (COMP_SERVER_SOCKET != dc->comp) continue;
+ if (dc->cond == CONFIG_COND_NE) {
+ socklen_t addr_len = sizeof(sock_addr);
+ sock_addr addr;
+ if (0 != network_host_parse_addr(srv, &addr, &addr_len, dc->string, srv->config_storage[i]->use_ipv6)) {
+ return -1;
+ }
+ network_host_normalize_addr_str(dc->string, &addr);
+ continue;
+ }
+
if (dc->cond != CONFIG_COND_EQ) continue;
if (0 != network_server_init(srv, dc->string, i, -1)) return -1;