2 * (c) Copyright 2001-2002 by Steve Grubb
3 * All rights reserved. The file named COPYRIGHT specifies the terms
4 * and conditions for redistribution.
9 #include <sys/socket.h>
23 * This is the globals for the Sensor. The Sensor will add the incoming IP
24 * address to the global_no_access table for whatever the configured time is.
26 static pset_h global_no_access = NULL; /* global no_access list */
27 static pset_h global_no_access_time = NULL; /* time of the infraction */
28 static int timer_id = 0; /* Timer ID */
30 /* This function is called via a timer callback every 60 seconds */
31 static void scrub_global_access_list( void );
34 void init_sensor( void )
36 if ( global_no_access == NULL )
37 global_no_access = pset_create(10, 10);
38 if ( global_no_access_time == NULL )
39 global_no_access_time = pset_create(10, 10);
43 * This function runs in the parent context and updates the global_no_access
46 void process_sensor( const struct service *sp, const union xsockaddr *addr)
48 const char *func = "process_sensor";
50 if (SC_DENY_TIME(SVC_CONF(sp)) != 0) /* 0 simply logs it */
52 if ( pset_count( global_no_access ) < MAX_GLOBAL_NO_ACCESS)
54 int item_matched = addrlist_match( global_no_access, SA(addr) );
56 if ( item_matched == 0)
57 { /* no match...adding to the list */
58 char *dup_addr = new_string(xaddrname( addr ) );
60 if (dup_addr == NULL )
63 if (addrlist_add(global_no_access, dup_addr) == FAILED)
65 "Failed adding %s to the global_no_access list", dup_addr);
69 char time_buf[40], *tmp;
73 "Adding %s to the global_no_access list for %d minutes",
74 dup_addr, SC_DENY_TIME(SVC_CONF(sp)));
76 if (SC_DENY_TIME(SVC_CONF(sp)) == -1)
77 strcpy(time_buf, "-1");
79 strx_nprint(time_buf, 38, "%ld",
80 (time_t)nowtime+(60*SC_DENY_TIME(SVC_CONF(sp))));
82 tmp = new_string(time_buf);
85 if (pset_add(global_no_access_time, tmp) == NULL)
88 "Failed adding %s to the global_no_access_time list. "
89 "global_no_access list is broken, xinetd needs "
90 "restarting.", dup_addr);
91 /* ideally, we should rollback the previous addr addition. */
94 if (pset_count(global_no_access) && (timer_id == 0) )
95 timer_id = xtimer_add( scrub_global_access_list, 60 );
101 /* Here again, eh?...update time stamp. */
105 item_matched--; /* Is # plus 1, to even get here must be >= 1 */
106 exp_time = pset_pointer( global_no_access_time, item_matched ) ;
107 if (exp_time == NULL)
110 if ( parse_base10(exp_time, (int *)&stored_time) )
111 { /* if never let them off, bypass */
112 if (stored_time != -1)
114 time_t nowtime, new_time;
116 nowtime = time(NULL);
117 new_time = (time_t)nowtime+(60*SC_DENY_TIME(SVC_CONF(sp))); if (difftime(new_time, (time_t)stored_time) > 0.0)
118 { /* new_time is longer save it */
119 char time_buf[40], *new_exp_time;
121 strx_nprint(time_buf, 38, "%ld", (long)new_time);
122 new_exp_time = new_string(time_buf);
126 global_no_access_time->ptrs[
127 (unsigned)item_matched ] = new_exp_time;
135 msg(LOG_ERR, func, "Maximum global_no_access count reached.");
139 /* They hit a real server...note, this is likely to be a child process. */
140 status_e check_sensor( const union xsockaddr *addr)
143 if ( (global_no_access) && pset_count( global_no_access ) )
145 if (addrlist_match( global_no_access, SA(addr)))
152 static void scrub_global_access_list( void )
155 const char *func = "scrub_global_no_access_list";
157 if ( global_no_access == NULL )
160 count = pset_count( global_no_access );
166 time_t nowtime = time(NULL);
168 for (u=0; u < count; u++)
173 exp_time = pset_pointer( global_no_access_time, u ) ;
174 stored_time = atol(exp_time);
176 if (stored_time == -1) /* never let them off */
179 if (difftime(nowtime, (time_t)stored_time) >= 0.0)
183 pset_pointer(global_no_access, u) = NULL;
184 ptr = global_no_access_time->ptrs[ u ];
186 pset_pointer(global_no_access_time, u ) = NULL;
192 pset_compact( global_no_access );
193 pset_compact( global_no_access_time );
195 "At least 1 DENY_TIME has expired, global_no_access list updated");
198 /* If there's still more on the list, start another callback. */
199 count = pset_count( global_no_access );
201 timer_id = xtimer_add( scrub_global_access_list, 60 );
206 "global_no_access list is empty.");
211 void destroy_global_access_list( void )
213 if ( global_no_access ) {
214 pset_apply( global_no_access, free, NULL ) ;
215 pset_destroy( global_no_access ) ;
218 if ( global_no_access_time ) {
219 pset_apply( global_no_access_time, free, NULL ) ;
220 pset_destroy( global_no_access_time ) ;