Browse Source

[core] use getaddrinfo,inet_pton vs gethostbyname (fixes #2783)

when available, use getaddrinfo(),inet_pton() instead of gethostbyname()

NOTE: behavior change: mod_scgi now listens to INADDR_LOOPBACK if "host"
      is not specified.  (Prior behavior was INADDR_ANY.)  Backends
      should not listen on potentially public IPs unless explicitly
      configured to do so.  This change matches a change to mod_fastcgi
      made in 2008.

x-ref
  "gethostbyname deprecated, should use getaddrinfo"
  https://redmine.lighttpd.net/issues/2783
personal/stbuehler/mod-csrf
Glenn Strauss 5 years ago
parent
commit
8981ca0467
  1. 19
      src/mod_fastcgi.c
  2. 23
      src/mod_scgi.c
  3. 19
      src/network.c

19
src/mod_fastcgi.c

@ -929,8 +929,15 @@ static int fcgi_spawn_connection(server *srv,
"ERROR: Unix Domain sockets are not supported.");
return -1;
#endif
} else if (buffer_string_is_empty(host->host)) {
memset(&fcgi_addr_in, 0, sizeof(fcgi_addr_in));
fcgi_addr_in.sin_family = AF_INET;
fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
fcgi_addr_in.sin_port = htons(proc->port);
servlen = sizeof(fcgi_addr_in);
fcgi_addr = (struct sockaddr *) &fcgi_addr_in;
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
} else if (host->family == AF_INET6 && !buffer_string_is_empty(host->host)) {
} else if (host->family == AF_INET6) {
memset(&fcgi_addr_in6, 0, sizeof(fcgi_addr_in6));
fcgi_addr_in6.sin6_family = AF_INET6;
inet_pton(AF_INET6, host->host->ptr, (char *) &fcgi_addr_in6.sin6_addr);
@ -941,16 +948,15 @@ static int fcgi_spawn_connection(server *srv,
} else {
memset(&fcgi_addr_in, 0, sizeof(fcgi_addr_in));
fcgi_addr_in.sin_family = AF_INET;
if (buffer_string_is_empty(host->host)) {
fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
} else {
#if defined(HAVE_INET_PTON)
inet_pton(AF_INET, host->host->ptr, (char *) &fcgi_addr_in.sin_addr);
#else
{
struct hostent *he;
/* set a useful default */
fcgi_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (NULL == (he = gethostbyname(host->host->ptr))) {
log_error_write(srv, __FILE__, __LINE__,
"sdb", "gethostbyname failed: ",
@ -971,6 +977,7 @@ static int fcgi_spawn_connection(server *srv,
memcpy(&(fcgi_addr_in.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
}
#endif
fcgi_addr_in.sin_port = htons(proc->port);
servlen = sizeof(fcgi_addr_in);

23
src/mod_scgi.c

@ -710,8 +710,15 @@ static int scgi_spawn_connection(server *srv,
"ERROR: Unix Domain sockets are not supported.");
return -1;
#endif
} else if (buffer_string_is_empty(host->host)) {
memset(&scgi_addr_in, 0, sizeof(scgi_addr_in));
scgi_addr_in.sin_family = AF_INET;
scgi_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
scgi_addr_in.sin_port = htons(proc->port);
servlen = sizeof(scgi_addr_in);
scgi_addr = (struct sockaddr *) &scgi_addr_in;
#if defined(HAVE_IPV6) && defined(HAVE_INET_PTON)
} else if (host->family == AF_INET6 && !buffer_string_is_empty(host->host)) {
} else if (host->family == AF_INET6) {
memset(&scgi_addr_in6, 0, sizeof(scgi_addr_in6));
scgi_addr_in6.sin6_family = AF_INET6;
inet_pton(AF_INET6, host->host->ptr, (char *) &scgi_addr_in6.sin6_addr);
@ -722,15 +729,14 @@ static int scgi_spawn_connection(server *srv,
} else {
memset(&scgi_addr_in, 0, sizeof(scgi_addr_in));
scgi_addr_in.sin_family = AF_INET;
if (buffer_string_is_empty(host->host)) {
scgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
} else {
#if defined(HAVE_INET_PTON)
inet_pton(AF_INET, host->host->ptr, (char *) &scgi_addr_in.sin_addr);
#else
{
struct hostent *he;
/* set a usefull default */
scgi_addr_in.sin_addr.s_addr = htonl(INADDR_ANY);
/* set a useful default */
scgi_addr_in.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
if (NULL == (he = gethostbyname(host->host->ptr))) {
log_error_write(srv, __FILE__, __LINE__,
@ -752,6 +758,7 @@ static int scgi_spawn_connection(server *srv,
memcpy(&(scgi_addr_in.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
}
#endif
scgi_addr_in.sin_port = htons(proc->port);
servlen = sizeof(scgi_addr_in);

19
src/network.c

@ -216,6 +216,24 @@ static int network_server_init(server *srv, buffer *host_token, size_t sidx) {
if (host == NULL) {
srv_socket->addr.ipv4.sin_addr.s_addr = htonl(INADDR_ANY);
} else {
#ifdef HAVE_INET_PTON /*(reuse HAVE_INET_PTON for presence of getaddrinfo())*/
struct addrinfo hints, *res;
int r;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (0 != (r = getaddrinfo(host, NULL, &hints, &res))) {
log_error_write(srv, __FILE__, __LINE__,
"sssss", "getaddrinfo failed: ",
gai_strerror(r), "'", host, "'");
goto error_free_socket;
}
memcpy(&(srv_socket->addr.ipv4), res->ai_addr, res->ai_addrlen);
freeaddrinfo(res);
#else
struct hostent *he;
if (NULL == (he = gethostbyname(host))) {
log_error_write(srv, __FILE__, __LINE__,
@ -235,6 +253,7 @@ static int network_server_init(server *srv, buffer *host_token, size_t sidx) {
}
memcpy(&(srv_socket->addr.ipv4.sin_addr.s_addr), he->h_addr_list[0], he->h_length);
#endif
}
srv_socket->addr.ipv4.sin_port = htons(port);
addr_len = sizeof(struct sockaddr_in);

Loading…
Cancel
Save