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 */
4 
5 /* this file contains the source for tcpwrapper handling stuff */
6 
7 #include "xiosysincludes.h"
8 #if WITH_LIBWRAP
9 #include "tcpd.h"
10 #endif
11 #include "xioopen.h"
12 
13 #include "xio-tcpwrap.h"
14 
15 
16 #if (WITH_TCP || WITH_UDP) && WITH_LIBWRAP
17 
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
26 
27 
28 /* they are declared only externally with libwrap and would be unresolved
29    without these definitions */
30 //int allow_severity=10, deny_severity=10;
31 
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 */
xio_retropt_tcpwrap(xiosingle_t * xfd,struct opt * opts)35 int xio_retropt_tcpwrap(xiosingle_t *xfd, struct opt *opts) {
36    bool dolibwrap = false;
37    dolibwrap =
38       retropt_string(opts, OPT_TCPWRAPPERS,
39 		     &xfd->para.socket.ip.libwrapname) >= 0 || dolibwrap;
40    dolibwrap =
41       retropt_string(opts, OPT_TCPWRAP_ETC,
42 		     &xfd->para.socket.ip.tcpwrap_etc) >= 0 || dolibwrap;
43 #if defined(HAVE_HOSTS_ALLOW_TABLE)
44    dolibwrap =
45       retropt_string(opts, OPT_TCPWRAP_HOSTS_ALLOW_TABLE,
46 		     &xfd->para.socket.ip.hosts_allow_table) >= 0 || dolibwrap;
47 #endif
48 #if defined(HAVE_HOSTS_DENY_TABLE)
49    dolibwrap =
50       retropt_string(opts, OPT_TCPWRAP_HOSTS_DENY_TABLE,
51 		     &xfd->para.socket.ip.hosts_deny_table) >= 0 || dolibwrap;
52 #endif
53    if (dolibwrap) {
54       xfd->para.socket.ip.dolibwrap = true;
55       if (xfd->para.socket.ip.libwrapname == NULL) {
56 	 xfd->para.socket.ip.libwrapname = (char *)diag_get_string('p');
57       }
58 #if defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE)
59       if (xfd->para.socket.ip.tcpwrap_etc) {
60 	 if (xfd->para.socket.ip.hosts_allow_table == NULL) {
61 	    xfd->para.socket.ip.hosts_allow_table =
62 	       Malloc(strlen(xfd->para.socket.ip.tcpwrap_etc)+1+11+1);
63 	    sprintf(xfd->para.socket.ip.hosts_allow_table, "%s/hosts.allow",
64 		    xfd->para.socket.ip.tcpwrap_etc);
65 	 }
66 	 if (xfd->para.socket.ip.hosts_deny_table == NULL) {
67 	    xfd->para.socket.ip.hosts_deny_table =
68 	       Malloc(strlen(xfd->para.socket.ip.tcpwrap_etc)+1+10+1);
69 	    sprintf(xfd->para.socket.ip.hosts_deny_table, "%s/hosts.deny",
70 		    xfd->para.socket.ip.tcpwrap_etc);
71 	 }
72       }
73 #endif /* defined(HAVE_HOSTS_ALLOW_TABLE) || defined(HAVE_HOSTS_DENY_TABLE) */
74       return 0;
75    }
76    return 1;
77 }
78 
79 
80 /* returns -1 if forbidden, 0 if no tcpwrap check, or 1 if explicitely allowed
81    */
xio_tcpwrap_check(xiosingle_t * xfd,union sockaddr_union * us,union sockaddr_union * them)82 int xio_tcpwrap_check(xiosingle_t *xfd, union sockaddr_union *us,
83 		      union sockaddr_union *them) {
84    char *save_hosts_allow_table, *save_hosts_deny_table;
85    struct request_info ri;
86 #if WITH_IP6
87    char clientaddr[INET6_ADDRSTRLEN] = "", serveraddr[INET6_ADDRSTRLEN] = "";
88 #else
89    char clientaddr[INET_ADDRSTRLEN] = "", serveraddr[INET_ADDRSTRLEN] = "";
90 #endif
91    int allow;
92 
93    if (!xfd->para.socket.ip.dolibwrap) {
94       return 0;
95    }
96    if (us == NULL || them == NULL)  { return -1; }
97 
98 #if defined(HAVE_HOSTS_ALLOW_TABLE)
99    save_hosts_allow_table = hosts_allow_table;
100    if (xfd->para.socket.ip.hosts_allow_table) {
101       Debug1("hosts_allow_table = \"%s\"",
102 	     xfd->para.socket.ip.hosts_allow_table);
103       hosts_allow_table = xfd->para.socket.ip.hosts_allow_table;
104    }
105 #endif /* defined(HAVE_HOSTS_ALLOW_TABLE) */
106 #if defined(HAVE_HOSTS_DENY_TABLE)
107    save_hosts_deny_table  = hosts_deny_table;
108    if (xfd->para.socket.ip.hosts_deny_table) {
109       Debug1("hosts_deny_table = \"%s\"",
110 	     xfd->para.socket.ip.hosts_deny_table);
111       hosts_deny_table  = xfd->para.socket.ip.hosts_deny_table;
112    }
113 #endif /* defined(HAVE_HOSTS_DENY_TABLE) */
114 
115    hosts_access_verbose = 32767;
116    if (inet_ntop(them->soa.sa_family,
117 #if WITH_IP6
118 		 them->soa.sa_family==PF_INET6 ?
119 		 (void *)&them->ip6.sin6_addr :
120 #endif
121 		 (void *)&them->ip4.sin_addr,
122 		 clientaddr, sizeof(clientaddr)) == NULL) {
123       Warn1("inet_ntop(): %s", strerror(errno));
124    }
125    if (inet_ntop(us->soa.sa_family,
126 #if WITH_IP6
127 		 us->soa.sa_family==PF_INET6 ?
128 		 (void *)&us->ip6.sin6_addr :
129 #endif
130 		 (void *)&us->ip4.sin_addr,
131 		 serveraddr, sizeof(serveraddr)) == NULL) {
132       Warn1("inet_ntop(): %s", strerror(errno));
133    }
134    Debug7("request_init(%p, RQ_FILE, %d, RQ_CLIENT_SIN, {%s:%u}, RQ_SERVER_SIN, {%s:%u}, RQ_DAEMON, \"%s\", 0",
135 	   &ri, xfd->fd, clientaddr,
136 	   ntohs(((struct sockaddr_in *)them)->sin_port),
137 	   serveraddr, ntohs(us->ip4.sin_port),
138 	   xfd->para.socket.ip.libwrapname?xfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'));
139    request_init(&ri, RQ_FILE, xfd->fd,
140 		RQ_CLIENT_SIN, them,
141 		RQ_SERVER_SIN, &us->soa,
142 		RQ_DAEMON, xfd->para.socket.ip.libwrapname?xfd->para.socket.ip.libwrapname:(char *)diag_get_string('p'), 0);
143    Debug("request_init() ->");
144 
145    Debug1("sock_methods(%p)", &ri);
146    sock_methods(&ri);
147    Debug("sock_methods() ->");
148 
149    Debug1("hosts_access(%p)", &ri);
150    allow = hosts_access(&ri);
151    Debug1("hosts_access() -> %d", allow);
152 
153 #if defined(HAVE_HOSTS_ALLOW_TABLE)
154    hosts_allow_table = save_hosts_allow_table;
155 #endif
156 #if defined(HAVE_HOSTS_DENY_TABLE)
157    hosts_deny_table  = save_hosts_deny_table;
158 #endif
159    if (allow == 0) {
160       return -1;
161    }
162    return 1;
163 }
164 
165 #endif /* (WITH_TCP || WITH_UDP) && WITH_LIBWRAP */
166 
167