1 /*
2 * (c) Copyright 1992 by Panagiotis Tsirigotis
3 * (c) Sections Copyright 1998-2001 by Rob Braun
4 * All rights reserved. The file named COPYRIGHT specifies the terms
5 * and conditions for redistribution.
6 */
7
8
9 #include "config.h"
10 #include <time.h>
11 #include <unistd.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
15 #include <stdlib.h>
16
17 #ifdef HAVE_STDINT_H
18 #include <stdint.h>
19 #endif
20
21 #include "str.h"
22 #include "access.h"
23 #ifdef LIBWRAP
24 #include <tcpd.h>
25 #include <syslog.h>
26 int deny_severity = LOG_INFO;
27 int allow_severity = LOG_INFO;
28 #endif
29
30 #ifdef HAVE_LOADAVG
31 #include "xgetloadavg.h"
32 #endif
33
34 #include "msg.h"
35 #include "addr.h"
36 #include "sconf.h"
37 #include "log.h"
38 #include "main.h" /* for ps */
39 #include "sconst.h"
40 #include "sensor.h"
41 #include "state.h"
42 #include "timex.h"
43 #include "xconfig.h"
44 #include "xtimer.h"
45
46 #if !defined(NAME_MAX)
47 #ifdef FILENAME_MAX
48 #define NAME_MAX FILENAME_MAX
49 #else
50 #define NAME_MAX 256
51 #endif
52 #endif
53
54 const struct name_value access_code_names[] =
55 {
56 { "address", (int) AC_ADDRESS },
57 { "time", (int) AC_TIME },
58 { "fork", (int) AC_FORK },
59 { "service_limit", (int) AC_SERVICE_LIMIT },
60 { "per_source_limit", (int) AC_PER_SOURCE_LIMIT},
61 { "process_limit", (int) AC_PROCESS_LIMIT },
62 { "libwrap", (int) AC_LIBWRAP },
63 { "load", (int) AC_LOAD },
64 { "connections per second", (int) AC_CPS },
65 { CHAR_NULL, 1 },
66 { "UNKNOWN", 0 }
67 } ;
68
69
70 /* This is called by the flags processor */
cps_service_restart(void)71 static void cps_service_restart(void)
72 {
73 unsigned int i;
74 time_t nowtime;
75 const char *func = "cps_service_restart";
76
77 nowtime = time(NULL);
78 for( i=0; i < pset_count( SERVICES(ps) ); i++ ) {
79 struct service *sp;
80 struct service_config *scp;
81
82 sp = pset_pointer( SERVICES(ps), i);
83
84 if( SVC_STATE(sp) == SVC_DISABLED ) {
85 scp = SVC_CONF( sp );
86 if ( SC_TIME_REENABLE(scp) <= nowtime ) {
87 /* re-enable the service */
88 if( svc_activate(sp) == OK ) {
89 msg(LOG_ERR, func,
90 "Activating service %s", SC_NAME(scp));
91 } else {
92 msg(LOG_ERR, func,
93 "Error activating service %s",
94 SC_NAME(scp)) ;
95 } /* else */
96 }
97 }
98 } /* for */
99 }
100
101
cps_service_stop(struct service * sp,const char * reason)102 void cps_service_stop(struct service *sp, const char *reason)
103 {
104 struct service_config *scp = SVC_CONF( sp ) ;
105 time_t nowtime;
106
107 svc_deactivate( sp );
108 msg(LOG_ERR, "service_stop",
109 "Deactivating service %s due to %s. Restarting in %d seconds.",
110 SC_NAME(scp), reason, (int)SC_TIME_WAIT(scp));
111 nowtime = time(NULL);
112 SC_TIME_REENABLE(scp) = nowtime + SC_TIME_WAIT(scp);
113 xtimer_add(cps_service_restart, SC_TIME_WAIT(scp));
114 }
115
116
117 /*
118 * Returns OK if the IP address in sinp is acceptable to the access control
119 * lists of the specified service.
120 */
remote_address_check(const struct service * sp,const union xsockaddr * sinp)121 static status_e remote_address_check(const struct service *sp,
122 const union xsockaddr *sinp)
123 {
124 /*
125 * of means only_from, na means no_access
126 */
127 const char *func = "remote_addr_chk";
128 bool_int of_matched = FALSE;
129 bool_int na_matched = FALSE;
130
131 if (sinp == NULL )
132 return FAILED;
133
134 if ( SC_SENSOR( SVC_CONF(sp) ))
135 { /* They hit a sensor...return FAILED since this isn't a real service */
136 process_sensor( sp, sinp ) ;
137 return FAILED ;
138 }
139 /* They hit a real server...note, this is likely to be a child process. */
140 else if ( check_sensor( sinp ) == FAILED )
141 return FAILED ;
142
143 /*
144 * The addrlist_match function returns an offset+1 to a matching
145 * entry in the supplied list. It is not a true/false answer.
146 */
147 if ( SC_NO_ACCESS( SVC_CONF(sp) ) != NULL )
148 na_matched = addrlist_match( SC_NO_ACCESS( SVC_CONF(sp) ), CSA(sinp));
149
150 if ( SC_ONLY_FROM( SVC_CONF(sp) ) != NULL )
151 of_matched = addrlist_match( SC_ONLY_FROM( SVC_CONF(sp) ), CSA(sinp));
152
153 /*
154 * Check if the specified address is in both lists
155 */
156 if ( na_matched && of_matched )
157 {
158 /*
159 * If there is a match in both lists, this is an error in the
160 * service entry and we cannot allow a server to start.
161 * We do not disable the service entry (not our job).
162 */
163 msg( LOG_ERR, func,
164 "Service=%s: only_from list and no_access list match equally the address %s",
165 SVC_ID( sp ),
166 xaddrname( sinp ) ) ;
167 return FAILED ;
168 }
169
170 /* A no_access list was specified and the socket is on it, fail */
171 if ( SC_NO_ACCESS( SVC_CONF(sp) ) != NULL && (na_matched != 0) )
172 return FAILED ;
173
174 /* A only_from list was specified and the socket wasn't on the list, fail */
175 if ( SC_ONLY_FROM( SVC_CONF(sp) ) != NULL && (of_matched == 0) )
176 return FAILED ;
177
178 /* If no lists were specified, the default is to allow starting a server */
179 return OK ;
180 }
181
182 /*
183 * mp is the mask pointer, t is the check type
184 */
185 #define CHECK( mp, t ) ( ( (mp) == NULL ) || M_IS_SET( *(mp), t ) )
186
187 /*
188 * Perform the access controls specified by check_mask.
189 * If check_mask is NULL, perform all access controls
190 */
access_control(struct service * sp,const connection_s * cp,const mask_t * check_mask)191 access_e access_control( struct service *sp,
192 const connection_s *cp,
193 const mask_t *check_mask )
194 {
195 struct service_config *scp = SVC_CONF( sp ) ;
196 #ifdef LIBWRAP
197 const char *func = "access_control";
198 #endif
199
200 /* make sure it's not one of the special pseudo services */
201 if( (strncmp(SC_NAME( scp ), INTERCEPT_SERVICE_NAME, sizeof(INTERCEPT_SERVICE_NAME)) == 0) || (strncmp(SC_NAME( scp ), LOG_SERVICE_NAME, sizeof(LOG_SERVICE_NAME)) == 0) ) {
202 return (AC_OK);
203 }
204
205 /* This has to be before the TCP_WRAPPERS stuff to make sure that
206 the sensor gets a chance to see the address */
207 if ( CHECK( check_mask, CF_ADDRESS ) &&
208 remote_address_check( sp, CONN_XADDRESS( cp ) ) == FAILED )
209 return( AC_ADDRESS ) ;
210
211 if( ! SC_NOLIBWRAP( scp ) )
212 { /* LIBWRAP code block */
213 #ifdef LIBWRAP
214 struct request_info req;
215 char *server = NULL;
216
217 /* get the server name to pass to libwrap */
218 if( SC_NAMEINARGS( scp ) )
219 {
220 if ( SC_SERVER_ARGV(scp) )
221 server = strrchr( SC_SERVER_ARGV(scp)[0], '/' );
222 }
223 else {
224 if( SC_SERVER(scp) == NULL ) {
225 /* probably an internal server, use the service id instead */
226 server = SC_ID(scp);
227 server--; /* nasty. we increment it later... */
228 } else {
229 server = strrchr( SC_SERVER(scp), '/' );
230 }
231 }
232
233 /* If this is a redirection or internal , go by the service name,
234 * since the server name will be bogus.
235 */
236 if( (SC_REDIR_ADDR(scp) != NULL) || (SC_IS_INTERNAL(scp) )) {
237 server = SC_NAME(scp);
238 server--; /* nasty but ok. */
239 }
240
241 if( server == NULL )
242 {
243 if ( SC_SERVER_ARGV(scp))
244 server = SC_SERVER_ARGV(scp)[0];
245 }
246 else
247 server++;
248
249 if ( scp->sc_libwrap != NULL )
250 {
251 server = SC_LIBWRAP(scp);
252 }
253
254 if ( server == NULL )
255 {
256 msg(deny_severity, func,
257 "server param not provided to libwrap refusing connection to %s from %s",
258 SC_ID(scp), conn_addrstr(cp));
259 return(AC_LIBWRAP);
260 }
261 request_init(&req, RQ_DAEMON, server, RQ_FILE, cp->co_descriptor, 0);
262 fromhost(&req);
263 if (!hosts_access(&req)) {
264 msg(deny_severity, func,
265 "libwrap refused connection to %s (libwrap=%s) from %s",
266 SC_ID(scp), server, conn_addrstr(cp));
267 return(AC_LIBWRAP);
268 }
269 #endif
270 } /* LIBWRAP code block */
271
272 return( AC_OK ) ;
273 }
274
275
276 /* Do the "light weight" access control here */
parent_access_control(struct service * sp,const connection_s * cp)277 access_e parent_access_control( struct service *sp, const connection_s *cp )
278 {
279 struct service_config *scp = SVC_CONF( sp ) ;
280 int n;
281 time_t nowtime;
282
283 /* make sure it's not one of the special pseudo services */
284 if( (strncmp(SC_NAME( scp ), INTERCEPT_SERVICE_NAME, sizeof(INTERCEPT_SERVICE_NAME)) == 0) || (strncmp(SC_NAME( scp ), LOG_SERVICE_NAME, sizeof(LOG_SERVICE_NAME)) == 0) )
285 return (AC_OK);
286
287 /* CPS handler */
288 if( SC_TIME_CONN_MAX(scp) != 0 ) {
289 int time_diff;
290 nowtime = time(NULL);
291 time_diff = nowtime - SC_TIME_LIMIT(scp) ;
292
293 if( SC_TIME_CONN(scp) == 0 ) {
294 SC_TIME_CONN(scp)++;
295 SC_TIME_LIMIT(scp) = nowtime;
296 } else if( time_diff < SC_TIME_CONN_MAX(scp) ) {
297 SC_TIME_CONN(scp)++;
298 if( time_diff == 0 ) time_diff = 1;
299 if( SC_TIME_CONN(scp)/time_diff > SC_TIME_CONN_MAX(scp) ) {
300 cps_service_stop(sp, "excessive incoming connections");
301 return(AC_CPS);
302 }
303 } else {
304 SC_TIME_LIMIT(scp) = nowtime;
305 SC_TIME_CONN(scp) = 1;
306 }
307 }
308
309 #ifdef HAVE_LOADAVG
310 if ( SC_MAX_LOAD(scp) != 0 ) {
311 if ( xgetloadavg() >= SC_MAX_LOAD(scp) ) {
312 msg(LOG_ERR, "xinetd",
313 "refused connect from %s due to excessive load",
314 conn_addrstr(cp));
315 return( AC_LOAD );
316 }
317 }
318 #endif
319
320 if ( SC_ACCESS_TIMES( scp ) != NULL &&
321 ! ti_current_time_check( SC_ACCESS_TIMES( scp ) ) )
322 return( AC_TIME ) ;
323
324 if ( SC_INSTANCES( scp ) != UNLIMITED &&
325 SVC_RUNNING_SERVERS( sp ) >= (unsigned)SC_INSTANCES( scp ) )
326 return( AC_SERVICE_LIMIT ) ;
327
328 if( SC_PER_SOURCE(scp) != UNLIMITED ) {
329 if ( CONN_XADDRESS(cp) != NULL ) {
330 unsigned int u ;
331 n = 0 ;
332 for ( u = 0 ; u < pset_count( SERVERS( ps ) ) ; u++ ) {
333 struct server *serp = NULL;
334 connection_s *cop = NULL;
335 serp = SERP( pset_pointer( SERVERS( ps ), u ) ) ;
336 if ( (SERVER_SERVICE( serp ) == sp) &&
337 ( cop = SERVER_CONNECTION( serp ) ) ) {
338
339 if ( SC_IPV6( scp ) &&
340 IN6_ARE_ADDR_EQUAL( &(cop->co_remote_address.sa_in6.sin6_addr),
341 &((CONN_XADDRESS(cp))->sa_in6.sin6_addr)) )
342 n++;
343 if ( SC_IPV4( scp ) &&
344 (cop->co_remote_address.sa_in.sin_addr.s_addr ==
345 (CONN_XADDRESS(cp))->sa_in.sin_addr.s_addr) )
346 n++;
347 }
348 }
349
350 if ( n >= SC_PER_SOURCE(scp) )
351 return( AC_PER_SOURCE_LIMIT ) ;
352 }
353 }
354
355 if ( ps.ros.process_limit ) {
356 unsigned processes_to_create = SC_IS_INTERCEPTED( scp ) ? 2 : 1 ;
357
358 if ( pset_count( SERVERS( ps ) ) + processes_to_create >
359 ps.ros.process_limit ) {
360 return( AC_PROCESS_LIMIT ) ;
361 }
362 }
363
364 return (AC_OK);
365 }
366
367