Version 1.8.0.1
[socat.git] / xio-tcpwrap.c
blob26a3a1f3145b08cb32e752c7dda86b1a73e982ad
1 /* source: xio-tcpwrap.c */
2 /* Copyright Gerhard Rieger and contributors (see file CHANGES) */
3 /* Published under the GNU General Public License V.2, see file COPYING */
5 /* this file contains the source for tcpwrapper handling stuff */
7 #include "xiosysincludes.h"
8 #if WITH_LIBWRAP
9 #include "tcpd.h"
10 #endif
11 #include "xioopen.h"
13 #include "xio-tcpwrap.h"
16 #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
18 const struct optdesc opt_tcpwrappers = { "tcpwrappers", "tcpwrap", OPT_TCPWRAPPERS, GROUP_RANGE, PH_ACCEPT, TYPE_STRING_NULL, OFUNC_SPEC };
19 const struct optdesc opt_tcpwrap_etc = { "tcpwrap-etc", "tcpwrap-dir", OPT_TCPWRAP_ETC, GROUP_RANGE, PH_ACCEPT, TYPE_FILENAME, OFUNC_SPEC };
20 #if defined(HAVE_HOSTS_ALLOW_TABLE)
21 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 };
22 #endif
23 #if defined(HAVE_HOSTS_DENY_TABLE)
24 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 };
25 #endif
28 /* they are declared only externally with libwrap and would be unresolved
29 without these definitions */
30 int allow_severity=10, deny_severity=10;
32 /* returns 0 if option was found and could be applied
33 returns 1 if option was not found
34 returns -1 if option was found but failed */
35 int xio_retropt_tcpwrap(
36 struct single *sfd,
37 struct opt *opts) {
38 bool dolibwrap = false;
39 dolibwrap =
40 retropt_string(opts, OPT_TCPWRAPPERS,
41 &sfd->para.socket.ip.libwrapname) >= 0 || dolibwrap;
42 dolibwrap =
43 retropt_string(opts, OPT_TCPWRAP_ETC,
44 &sfd->para.socket.ip.tcpwrap_etc) >= 0 || dolibwrap;
45 #if defined(HAVE_HOSTS_ALLOW_TABLE)
46 dolibwrap =
47 retropt_string(opts, OPT_TCPWRAP_HOSTS_ALLOW_TABLE,
48 &sfd->para.socket.ip.hosts_allow_table) >= 0 || dolibwrap;
49 #endif
50 #if defined(HAVE_HOSTS_DENY_TABLE)
51 dolibwrap =
52 retropt_string(opts, OPT_TCPWRAP_HOSTS_DENY_TABLE,
53 &sfd->para.socket.ip.hosts_deny_table) >= 0 || dolibwrap;
54 #endif
55 if (dolibwrap) {
56 sfd->para.socket.ip.dolibwrap = true;
57 if (sfd->para.socket.ip.libwrapname == NULL) {
58 sfd->para.socket.ip.libwrapname = (char *)diag_get_string('p');
60 #if defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE)
61 if (sfd->para.socket.ip.tcpwrap_etc) {
62 if (sfd->para.socket.ip.hosts_allow_table == NULL) {
63 sfd->para.socket.ip.hosts_allow_table =
64 Malloc(strlen(sfd->para.socket.ip.tcpwrap_etc)+1+11+1);
65 sprintf(sfd->para.socket.ip.hosts_allow_table, "%s/hosts.allow",
66 sfd->para.socket.ip.tcpwrap_etc);
68 if (sfd->para.socket.ip.hosts_deny_table == NULL) {
69 sfd->para.socket.ip.hosts_deny_table =
70 Malloc(strlen(sfd->para.socket.ip.tcpwrap_etc)+1+10+1);
71 sprintf(sfd->para.socket.ip.hosts_deny_table, "%s/hosts.deny",
72 sfd->para.socket.ip.tcpwrap_etc);
75 #endif /* defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE) */
76 return 0;
78 return 1;
82 /* returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitely allowed
84 int xio_tcpwrap_check(
85 struct single *sfd,
86 union sockaddr_union *us,
87 union sockaddr_union *them) {
88 char *save_hosts_allow_table, *save_hosts_deny_table;
89 struct request_info ri;
90 #if WITH_IP6
91 char clientaddr[INET6_ADDRSTRLEN] = "", serveraddr[INET6_ADDRSTRLEN] = "";
92 #else
93 char clientaddr[INET_ADDRSTRLEN] = "", serveraddr[INET_ADDRSTRLEN] = "";
94 #endif
95 int allow;
97 if (!sfd->para.socket.ip.dolibwrap) {
98 return 0;
100 if (us == NULL || them == NULL) { return -1; }
102 #if defined(HAVE_HOSTS_ALLOW_TABLE)
103 save_hosts_allow_table = hosts_allow_table;
104 if (sfd->para.socket.ip.hosts_allow_table) {
105 Debug1("hosts_allow_table = \"%s\"",
106 sfd->para.socket.ip.hosts_allow_table);
107 hosts_allow_table = sfd->para.socket.ip.hosts_allow_table;
109 #endif /* defined(HAVE_HOSTS_ALLOW_TABLE) */
110 #if defined(HAVE_HOSTS_DENY_TABLE)
111 save_hosts_deny_table = hosts_deny_table;
112 if (sfd->para.socket.ip.hosts_deny_table) {
113 Debug1("hosts_deny_table = \"%s\"",
114 sfd->para.socket.ip.hosts_deny_table);
115 hosts_deny_table = sfd->para.socket.ip.hosts_deny_table;
117 #endif /* defined(HAVE_HOSTS_DENY_TABLE) */
119 hosts_access_verbose = 32767;
120 if (inet_ntop(them->soa.sa_family,
121 #if WITH_IP6
122 them->soa.sa_family==PF_INET6 ?
123 (void *)&them->ip6.sin6_addr :
124 #endif
125 (void *)&them->ip4.sin_addr,
126 clientaddr, sizeof(clientaddr)) == NULL) {
127 Warn1("inet_ntop(): %s", strerror(errno));
129 if (inet_ntop(us->soa.sa_family,
130 #if WITH_IP6
131 us->soa.sa_family==PF_INET6 ?
132 (void *)&us->ip6.sin6_addr :
133 #endif
134 (void *)&us->ip4.sin_addr,
135 serveraddr, sizeof(serveraddr)) == NULL) {
136 Warn1("inet_ntop(): %s", strerror(errno));
138 Debug7("request_init(%p, RQ_FILE, %d, RQ_CLIENT_SIN, {%s:%u}, RQ_SERVER_SIN, {%s:%u}, RQ_DAEMON, \"%s\", 0",
139 &ri, sfd->fd, clientaddr,
140 ntohs(((struct sockaddr_in *)them)->sin_port),
141 serveraddr, ntohs(us->ip4.sin_port),
142 sfd->para.socket.ip.libwrapname?sfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'));
143 request_init(&ri, RQ_FILE, sfd->fd,
144 RQ_CLIENT_SIN, them,
145 RQ_SERVER_SIN, &us->soa,
146 RQ_DAEMON, sfd->para.socket.ip.libwrapname?sfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'), 0);
147 Debug("request_init() ->");
149 Debug1("sock_methods(%p)", &ri);
150 sock_methods(&ri);
151 Debug("sock_methods() ->");
153 Debug1("hosts_access(%p)", &ri);
154 allow = hosts_access(&ri);
155 Debug1("hosts_access() -> %d", allow);
157 #if defined(HAVE_HOSTS_ALLOW_TABLE)
158 hosts_allow_table = save_hosts_allow_table;
159 #endif
160 #if defined(HAVE_HOSTS_DENY_TABLE)
161 hosts_deny_table = save_hosts_deny_table;
162 #endif
163 if (allow == 0) {
164 return -1;
166 return 1;
169 #endif /* (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */