/* source: xio-tcpwrap.c */ /* Copyright Gerhard Rieger 2006-2008 */ /* Published under the GNU General Public License V.2, see file COPYING */ /* this file contains the source for tcpwrapper handling stuff */ #include "xiosysincludes.h" #if WITH_LIBWRAP #include "tcpd.h" #endif #include "xioopen.h" #include "xio-tcpwrap.h" #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP const struct optdesc opt_tcpwrappers = { "tcpwrappers", "tcpwrap", OPT_TCPWRAPPERS, GROUP_RANGE, PH_ACCEPT, TYPE_STRING_NULL, OFUNC_SPEC }; const struct optdesc opt_tcpwrap_etc = { "tcpwrap-etc", "tcpwrap-dir", OPT_TCPWRAP_ETC, GROUP_RANGE, PH_ACCEPT, TYPE_FILENAME, OFUNC_SPEC }; #if defined(HAVE_HOSTS_ALLOW_TABLE) const struct optdesc opt_tcpwrap_hosts_allow_table = { "tcpwrap-hosts-allow-table", "allow-table", OPT_TCPWRAP_HOSTS_ALLOW_TABLE, GROUP_RANGE, PH_ACCEPT, TYPE_FILENAME, OFUNC_SPEC }; #endif #if defined(HAVE_HOSTS_DENY_TABLE) const struct optdesc opt_tcpwrap_hosts_deny_table = { "tcpwrap-hosts-deny-table", "deny-table", OPT_TCPWRAP_HOSTS_DENY_TABLE, GROUP_RANGE, PH_ACCEPT, TYPE_FILENAME, OFUNC_SPEC }; #endif /* they are declared only externally with libwrap and would be unresolved without these definitions */ int allow_severity=10, deny_severity=10; /* returns 0 if option was found and could be applied returns 1 if option was not found returns -1 if option was found but failed */ int xio_retropt_tcpwrap(xiosingle_t *xfd, struct opt *opts) { bool dolibwrap = false; dolibwrap = retropt_string(opts, OPT_TCPWRAPPERS, &xfd->para.socket.ip.libwrapname) >= 0 || dolibwrap; dolibwrap = retropt_string(opts, OPT_TCPWRAP_ETC, &xfd->para.socket.ip.tcpwrap_etc) >= 0 || dolibwrap; #if defined(HAVE_HOSTS_ALLOW_TABLE) dolibwrap = retropt_string(opts, OPT_TCPWRAP_HOSTS_ALLOW_TABLE, &xfd->para.socket.ip.hosts_allow_table) >= 0 || dolibwrap; #endif #if defined(HAVE_HOSTS_DENY_TABLE) dolibwrap = retropt_string(opts, OPT_TCPWRAP_HOSTS_DENY_TABLE, &xfd->para.socket.ip.hosts_deny_table) >= 0 || dolibwrap; #endif if (dolibwrap) { xfd->para.socket.ip.dolibwrap = true; if (xfd->para.socket.ip.libwrapname == NULL) { xfd->para.socket.ip.libwrapname = (char *)diag_get_string('p'); } #if defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE) if (xfd->para.socket.ip.tcpwrap_etc) { if (xfd->para.socket.ip.hosts_allow_table == NULL) { xfd->para.socket.ip.hosts_allow_table = Malloc(strlen(xfd->para.socket.ip.tcpwrap_etc)+1+11+1); sprintf(xfd->para.socket.ip.hosts_allow_table, "%s/hosts.allow", xfd->para.socket.ip.tcpwrap_etc); } if (xfd->para.socket.ip.hosts_deny_table == NULL) { xfd->para.socket.ip.hosts_deny_table = Malloc(strlen(xfd->para.socket.ip.tcpwrap_etc)+1+10+1); sprintf(xfd->para.socket.ip.hosts_deny_table, "%s/hosts.deny", xfd->para.socket.ip.tcpwrap_etc); } } #endif /* defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE) */ return 0; } return 1; } /* returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitely allowed */ int xio_tcpwrap_check(xiosingle_t *xfd, union sockaddr_union *us, union sockaddr_union *them) { char *save_hosts_allow_table, *save_hosts_deny_table; struct request_info ri; #if WITH_IP6 char clientaddr[INET6_ADDRSTRLEN] = "", serveraddr[INET6_ADDRSTRLEN] = ""; #else char clientaddr[INET_ADDRSTRLEN] = "", serveraddr[INET_ADDRSTRLEN] = ""; #endif int allow; if (!xfd->para.socket.ip.dolibwrap) { return 0; } if (us == NULL || them == NULL) { return -1; } #if defined(HAVE_HOSTS_ALLOW_TABLE) save_hosts_allow_table = hosts_allow_table; if (xfd->para.socket.ip.hosts_allow_table) { Debug1("hosts_allow_table = \"%s\"", xfd->para.socket.ip.hosts_allow_table); hosts_allow_table = xfd->para.socket.ip.hosts_allow_table; } #endif /* defined(HAVE_HOSTS_ALLOW_TABLE) */ #if defined(HAVE_HOSTS_DENY_TABLE) save_hosts_deny_table = hosts_deny_table; if (xfd->para.socket.ip.hosts_deny_table) { Debug1("hosts_deny_table = \"%s\"", xfd->para.socket.ip.hosts_deny_table); hosts_deny_table = xfd->para.socket.ip.hosts_deny_table; } #endif /* defined(HAVE_HOSTS_DENY_TABLE) */ hosts_access_verbose = 32767; if (inet_ntop(them->soa.sa_family, #if WITH_IP6 them->soa.sa_family==PF_INET6 ? (void *)&them->ip6.sin6_addr : #endif (void *)&them->ip4.sin_addr, clientaddr, sizeof(clientaddr)) == NULL) { Warn1("inet_ntop(): %s", strerror(errno)); } if (inet_ntop(us->soa.sa_family, #if WITH_IP6 us->soa.sa_family==PF_INET6 ? (void *)&us->ip6.sin6_addr : #endif (void *)&us->ip4.sin_addr, serveraddr, sizeof(serveraddr)) == NULL) { Warn1("inet_ntop(): %s", strerror(errno)); } Debug7("request_init(%p, RQ_FILE, %d, RQ_CLIENT_SIN, {%s:%u}, RQ_SERVER_SIN, {%s:%u}, RQ_DAEMON, \"%s\", 0", &ri, xfd->fd, clientaddr, ntohs(((struct sockaddr_in *)them)->sin_port), serveraddr, ntohs(us->ip4.sin_port), xfd->para.socket.ip.libwrapname?xfd->para.socket.ip.libwrapname:(char *)diag_get_string('p')); request_init(&ri, RQ_FILE, xfd->fd, RQ_CLIENT_SIN, them, RQ_SERVER_SIN, &us->soa, RQ_DAEMON, xfd->para.socket.ip.libwrapname?xfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'), 0); Debug("request_init() ->"); Debug1("sock_methods(%p)", &ri); sock_methods(&ri); Debug("sock_methods() ->"); Debug1("hosts_access(%p)", &ri); allow = hosts_access(&ri); Debug1("hosts_access() -> %d", allow); #if defined(HAVE_HOSTS_ALLOW_TABLE) hosts_allow_table = save_hosts_allow_table; #endif #if defined(HAVE_HOSTS_DENY_TABLE) hosts_deny_table = save_hosts_deny_table; #endif if (allow == 0) { return -1; } return 1; } #endif /* (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */