From a3c688210f09367b3584f0527e5128506805438e Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sun, 24 Feb 2019 23:17:17 +0100 Subject: [PATCH] Removed dependency on gethostbyname() --- CHANGES | 4 ++++ config.h.in | 3 +++ configure.in | 2 +- sycls.c | 4 ++-- xio-ip4.c | 30 +++++++++++++----------------- xio-proxy.c | 25 ++++++++++++------------- 6 files changed, 35 insertions(+), 33 deletions(-) diff --git a/CHANGES b/CHANGES index 4587b48..f4dc5fd 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,10 @@ corrections: cross compiling. Thanks to Max Freisinger from Gentoo for seinding a patch. + Socat still depended on obsolete gethostbyname() function, thus + compiling with MUSL libc failed. + Problem reported by Kennedy33. + testing: test.sh: Show a warning when phase-1 (insecure phase) of a security test fails diff --git a/config.h.in b/config.h.in index 543326a..ecdefd2 100644 --- a/config.h.in +++ b/config.h.in @@ -99,6 +99,9 @@ /* Define if you have the nanosleep function. */ #undef HAVE_NANOSLEEP +/* Define if you have the gethostbyname function. */ +#undef HAVE_GETHOSTBYNAME + /* Define if you have the getaddrinfo function. */ #undef HAVE_GETADDRINFO diff --git a/configure.in b/configure.in index 82b8e68..64f9f02 100644 --- a/configure.in +++ b/configure.in @@ -740,7 +740,7 @@ AC_FUNC_MEMCMP AC_TYPE_SIGNAL AC_FUNC_STRFTIME AC_CHECK_FUNCS(putenv select poll socket strtod strtol) -AC_CHECK_FUNCS(strtoul uname getpgid getsid getaddrinfo) +AC_CHECK_FUNCS(strtoul uname getpgid getsid gethostbyname getaddrinfo) AC_CHECK_FUNCS(setgroups inet_aton) AC_CHECK_FUNCS() diff --git a/sycls.c b/sycls.c index befc291..b46aea8 100644 --- a/sycls.c +++ b/sycls.c @@ -1364,7 +1364,7 @@ int Pause(void) { return retval; } -#if WITH_IP4 || WITH_IP6 +#if ( _WITH_IP4 || _WITH_IP6 ) && HAVE_GETHOSTBYNAME struct hostent *Gethostbyname(const char *name) { struct hostent *hent; Debug1("gethostbyname(\"%s\")", name); @@ -1380,7 +1380,7 @@ struct hostent *Gethostbyname(const char *name) { } return hent; } -#endif /* WITH_IP4 || WITH_IP6 */ +#endif /* ( _WITH_IP4 || _WITH_IP6 ) && HAVE_GETHOSTBYNAME */ #if (_WITH_IP4 || _WITH_IP6) && HAVE_GETADDRINFO int Getaddrinfo(const char *node, const char *service, diff --git a/xio-ip4.c b/xio-ip4.c index 8bad5fc..36413cb 100644 --- a/xio-ip4.c +++ b/xio-ip4.c @@ -15,12 +15,14 @@ int xioparsenetwork_ip4(const char *rangename, struct xiorange *range) { - struct hostent *maskaddr; struct in_addr *netaddr_in = &range->netaddr.ip4.sin_addr; struct in_addr *netmask_in = &range->netmask.ip4.sin_addr; char *rangename1; /* a copy of rangename with writing allowed */ char *delimpos; /* absolute address of delimiter */ unsigned int bits; /* netmask bits */ + union sockaddr_union sau; + socklen_t socklen = sizeof(sau); + int rc; if ((rangename1 = strdup(rangename)) == NULL) { Error1("strdup(\"%s\"): out of memory", rangename); @@ -43,31 +45,25 @@ int xioparsenetwork_ip4(const char *rangename, struct xiorange *range) { netmask_in->s_addr = htonl((0xffffffff << (32-bits))); } } else if (delimpos = strchr(rangename1, ':')) { - if ((maskaddr = Gethostbyname(delimpos+1)) == NULL) { - /* note: cast is req on AIX: */ - Error2("gethostbyname(\"%s\"): %s", delimpos+1, - h_errno == NETDB_INTERNAL ? strerror(errno) : - (char *)hstrerror(h_errno)); - return STAT_NORETRY; + if ((rc = xiogetaddrinfo(delimpos+1, NULL, PF_UNSPEC, 0, 0, + &sau, &socklen, 0, 0)) + != STAT_OK) { + return rc; } - netmask_in->s_addr = *(uint32_t *)maskaddr->h_addr_list[0]; + netmask_in->s_addr = sau.ip4.sin_addr.s_addr; } else { Error1("xioparsenetwork_ip4(\"%s\",,): missing netmask delimiter", rangename); free(rangename1); return STAT_NORETRY; } { - struct hostent *nameaddr; *delimpos = 0; - if ((nameaddr = Gethostbyname(rangename1)) == NULL) { - /* note: cast is req on AIX: */ - Error2("gethostbyname(\"%s\"): %s", rangename1, - h_errno == NETDB_INTERNAL ? strerror(errno) : - (char *)hstrerror(h_errno)); - free(rangename1); - return STAT_NORETRY; + if ((rc = xiogetaddrinfo(rangename1, NULL, PF_UNSPEC, 0, 0, + &sau, &socklen, 0, 0)) + != STAT_OK) { + return rc; } - netaddr_in->s_addr = *(uint32_t *)nameaddr->h_addr_list[0]; + netaddr_in->s_addr = sau.ip4.sin_addr.s_addr; } free(rangename1); return STAT_OK; diff --git a/xio-proxy.c b/xio-proxy.c index bde0990..59198ed 100644 --- a/xio-proxy.c +++ b/xio-proxy.c @@ -11,6 +11,7 @@ #include "xioopen.h" #include "xio-socket.h" +#include "xio-ip.h" #include "xio-ipapp.h" #include "xio-ascii.h" /* for base64 encoding of authentication */ @@ -231,7 +232,9 @@ static int xioopen_proxy_connect(int argc, const char *argv[], struct opt *opts, int _xioopen_proxy_prepare(struct proxyvars *proxyvars, struct opt *opts, const char *targetname, const char *targetport) { - struct hostent *host; + union sockaddr_union host; + socklen_t socklen = sizeof(host); + int rc; retropt_bool(opts, OPT_IGNORECR, &proxyvars->ignorecr); retropt_bool(opts, OPT_PROXY_RESOLVE, &proxyvars->doresolve); @@ -241,14 +244,10 @@ int _xioopen_proxy_prepare(struct proxyvars *proxyvars, struct opt *opts, /* currently we only resolve to IPv4 addresses. This is in accordance to RFC 2396; however once it becomes clear how IPv6 addresses should be represented in CONNECT commands this code might be extended */ - host = Gethostbyname(targetname); - if (host == NULL) { - int level = E_WARN; - /* note: cast is req on AIX: */ - Msg2(level, "gethostbyname(\"%s\"): %s", targetname, - h_errno == NETDB_INTERNAL ? strerror(errno) : - (char *)hstrerror(h_errno)/*0 h_messages[h_errno-1]*/); - + rc = xiogetaddrinfo(targetname, targetport, PF_UNSPEC, + SOCK_STREAM, IPPROTO_TCP, + &host, &socklen, 0, 0); + if (rc != STAT_OK) { proxyvars->targetaddr = strdup(targetname); } else { #define LEN 16 /* www.xxx.yyy.zzz\0 */ @@ -256,10 +255,10 @@ int _xioopen_proxy_prepare(struct proxyvars *proxyvars, struct opt *opts, return STAT_RETRYLATER; } snprintf(proxyvars->targetaddr, LEN, "%u.%u.%u.%u", - (unsigned char)host->h_addr_list[0][0], - (unsigned char)host->h_addr_list[0][1], - (unsigned char)host->h_addr_list[0][2], - (unsigned char)host->h_addr_list[0][3]); + ((unsigned char *)&host.ip4.sin_addr.s_addr)[0], + ((unsigned char *)&host.ip4.sin_addr.s_addr)[1], + ((unsigned char *)&host.ip4.sin_addr.s_addr)[2], + ((unsigned char *)&host.ip4.sin_addr.s_addr)[3]); #undef LEN } } else {