| /* source: xio-tcpwrap.c */ |
| /* Copyright Gerhard Rieger and contributors (see file CHANGES) */ |
| /* 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( |
| struct single *sfd, |
| struct opt *opts) { |
| bool dolibwrap = false; |
| dolibwrap = |
| retropt_string(opts, OPT_TCPWRAPPERS, |
| &sfd->para.socket.ip.libwrapname) >= 0 || dolibwrap; |
| dolibwrap = |
| retropt_string(opts, OPT_TCPWRAP_ETC, |
| &sfd->para.socket.ip.tcpwrap_etc) >= 0 || dolibwrap; |
| #if defined(HAVE_HOSTS_ALLOW_TABLE) |
| dolibwrap = |
| retropt_string(opts, OPT_TCPWRAP_HOSTS_ALLOW_TABLE, |
| &sfd->para.socket.ip.hosts_allow_table) >= 0 || dolibwrap; |
| #endif |
| #if defined(HAVE_HOSTS_DENY_TABLE) |
| dolibwrap = |
| retropt_string(opts, OPT_TCPWRAP_HOSTS_DENY_TABLE, |
| &sfd->para.socket.ip.hosts_deny_table) >= 0 || dolibwrap; |
| #endif |
| if (dolibwrap) { |
| sfd->para.socket.ip.dolibwrap = true; |
| if (sfd->para.socket.ip.libwrapname == NULL) { |
| sfd->para.socket.ip.libwrapname = (char *)diag_get_string('p'); |
| } |
| #if defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE) |
| if (sfd->para.socket.ip.tcpwrap_etc) { |
| if (sfd->para.socket.ip.hosts_allow_table == NULL) { |
| sfd->para.socket.ip.hosts_allow_table = |
| Malloc(strlen(sfd->para.socket.ip.tcpwrap_etc)+1+11+1); |
| sprintf(sfd->para.socket.ip.hosts_allow_table, "%s/hosts.allow", |
| sfd->para.socket.ip.tcpwrap_etc); |
| } |
| if (sfd->para.socket.ip.hosts_deny_table == NULL) { |
| sfd->para.socket.ip.hosts_deny_table = |
| Malloc(strlen(sfd->para.socket.ip.tcpwrap_etc)+1+10+1); |
| sprintf(sfd->para.socket.ip.hosts_deny_table, "%s/hosts.deny", |
| sfd->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( |
| struct single *sfd, |
| 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 (!sfd->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 (sfd->para.socket.ip.hosts_allow_table) { |
| Debug1("hosts_allow_table = \"%s\"", |
| sfd->para.socket.ip.hosts_allow_table); |
| hosts_allow_table = sfd->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 (sfd->para.socket.ip.hosts_deny_table) { |
| Debug1("hosts_deny_table = \"%s\"", |
| sfd->para.socket.ip.hosts_deny_table); |
| hosts_deny_table = sfd->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, sfd->fd, clientaddr, |
| ntohs(((struct sockaddr_in *)them)->sin_port), |
| serveraddr, ntohs(us->ip4.sin_port), |
| sfd->para.socket.ip.libwrapname?sfd->para.socket.ip.libwrapname:(char *)diag_get_string('p')); |
| request_init(&ri, RQ_FILE, sfd->fd, |
| RQ_CLIENT_SIN, them, |
| RQ_SERVER_SIN, &us->soa, |
| RQ_DAEMON, sfd->para.socket.ip.libwrapname?sfd->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 */ |
| |