1 /* This program is free software; you can redistribute it and/or modify
2  * it under the terms of the GNU General Public License as published by
3  * the Free Software Foundation; version 2 of the License. For a copy,
4  * see http://www.gnu.org/licenses/gpl-2.0.html.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  */
11 
12 #include "config.h"
13 #include <sys/types.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <unistd.h>
17 #include <dirent.h>
18 #include <pthread.h>
19 #include <sys/wait.h>
20 #include "global.h"
21 #include "client.h"
22 #include "tomahawk.h"
23 #include "monitor.h"
24 #include "log.h"
25 #include "memdbg.h"
26 
27 #define MAX_PASSWORD_DELAY_TIMER (int)(MINUTE / TASK_RUNNER_INTERVAL)
28 
29 typedef struct type_client {
30 	t_session *session;
31 	time_t remove_deadline;
32 
33 	struct type_client *next;
34 } t_client;
35 
36 typedef struct type_banned {
37 	t_ip_addr ip;
38 	time_t    deadline;
39 	int       bantime;
40 	unsigned long connect_attempts;
41 
42 	struct type_banned *next;
43 } t_banned;
44 
45 static int total_clients_connected = 0;
46 static t_client *client_list[256];
47 static pthread_mutex_t client_mutex[256];
48 static t_banned *banlist;
49 static pthread_mutex_t ban_mutex;
50 static t_ipcounterlist *wrong_password_list;
51 static pthread_mutex_t pwd_mutex;
52 static int password_delay_timer = 0;
53 
54 /* Initialize this module.
55  */
init_client_module(void)56 int init_client_module(void) {
57 	int i;
58 
59 	for (i = 0; i < 256; i++) {
60 		client_list[i] = NULL;
61 		if (pthread_mutex_init(&client_mutex[i], NULL) != 0) {
62 			return -1;
63 		}
64 	}
65 	banlist = NULL;
66 	if (pthread_mutex_init(&ban_mutex, NULL) != 0) {
67 		return -1;
68 	}
69 	wrong_password_list = NULL;
70 	if (pthread_mutex_init(&pwd_mutex, NULL) != 0) {
71 		return -1;
72 	}
73 
74 	return 0;
75 }
76 
77 /* Add the session record of a client to the client_list.
78  */
add_client(t_session * session)79 int add_client(t_session *session) {
80 	t_client *new;
81 	unsigned char i;
82 
83 	if ((new = (t_client*)malloc(sizeof(t_client))) == NULL) {
84 		return -1;
85 	}
86 
87 	new->session = session;
88 	new->remove_deadline = TIMER_OFF;
89 
90 	i = index_by_ip(&(session->ip_address));
91 	pthread_mutex_lock(&client_mutex[i]);
92 
93 	new->next = client_list[i];
94 	client_list[i] = new;
95 
96 	__sync_add_and_fetch(&total_clients_connected, 1);
97 
98 	pthread_mutex_unlock(&client_mutex[i]);
99 
100 	return 0;
101 }
102 
103 /* Change position in client list
104  */
reposition_client(t_session * session,t_ip_addr * ip_address)105 int reposition_client(t_session *session, t_ip_addr *ip_address) {
106 	t_client *to_be_repositioned = NULL, *list;
107 	unsigned char old_i, new_i;
108 
109 	new_i = index_by_ip(ip_address);
110 	old_i = index_by_ip(&(session->ip_address));
111 
112 	if (old_i == new_i) {
113 		return 0;
114 	}
115 
116 	pthread_mutex_lock(&client_mutex[old_i]);
117 
118 	if (client_list[old_i] != NULL) {
119 		if (client_list[old_i]->session == session) {
120 			to_be_repositioned = client_list[old_i];
121 			client_list[old_i] = client_list[old_i]->next;
122 		} else {
123 			list = client_list[old_i];
124 			while (list->next != NULL) {
125 				if (list->next->session == session) {
126 					to_be_repositioned = list->next;
127 					list->next = to_be_repositioned->next;
128 					break;
129 				}
130 				list = list->next;
131 			}
132 		}
133 	} else {
134 		log_error_session(session, "Client record not found.");
135 	}
136 
137 	pthread_mutex_unlock(&client_mutex[old_i]);
138 
139 	if (to_be_repositioned == NULL) {
140 		return -1;
141 	}
142 
143 	pthread_mutex_lock(&client_mutex[new_i]);
144 
145 	to_be_repositioned->next = client_list[new_i];
146 	client_list[new_i] = to_be_repositioned;
147 
148 	pthread_mutex_unlock(&client_mutex[new_i]);
149 
150 	return 1;
151 }
152 
153 /* Remember the client record for flooding prevention
154  */
mark_client_for_removal(t_session * session,int delay)155 int mark_client_for_removal(t_session *session, int delay) {
156 	t_client *list;
157 	unsigned char i;
158 	int result = 0;
159 
160 	i = index_by_ip(&(session->ip_address));
161 	pthread_mutex_lock(&client_mutex[i]);
162 
163 	list = client_list[i];
164 	while (list != NULL) {
165 		if (list->session == session) {
166 			list->remove_deadline = time(NULL) + delay;
167 			__sync_sub_and_fetch(&total_clients_connected, 1);
168 			result = 1;
169 			break;
170 		}
171 		list = list->next;
172 	}
173 
174 	pthread_mutex_unlock(&client_mutex[i]);
175 
176 	return result;
177 }
178 
179 /* Check the remove_deadline timers and remove client
180  * when timer has reached 0
181  */
check_remove_deadlines(t_config * config,time_t now)182 void check_remove_deadlines(t_config *config, time_t now) {
183 	t_client *client, *prev, *next;
184 	int i;
185 
186 	if (config->reconnect_delay <= 0) {
187 		return;
188 	}
189 
190 	for (i = 0; i < 256; i++) {
191 		pthread_mutex_lock(&client_mutex[i]);
192 
193 		prev = NULL;
194 		client = client_list[i];
195 		while (client != NULL) {
196 			next = client->next;
197 			if (client->remove_deadline == TIMER_OFF) {
198 				prev = client;
199 			} else if (now > client->remove_deadline) {
200 				free(client->session);
201 				free(client);
202 				if (prev == NULL) {
203 					client_list[i] = next;
204 				} else {
205 					prev->next = next;
206 				}
207 			} else {
208 				prev = client;
209 			}
210 			client = next;
211 		}
212 
213 		pthread_mutex_unlock(&client_mutex[i]);
214 	}
215 }
216 
217 /* Remove a client from the client_list.
218  */
remove_client(t_session * session)219 int remove_client(t_session *session) {
220 	t_client *to_be_removed = NULL, *list;
221 	unsigned char i;
222 
223 	i = index_by_ip(&(session->ip_address));
224 	pthread_mutex_lock(&client_mutex[i]);
225 
226 	if (client_list[i] != NULL) {
227 		if (client_list[i]->session == session) {
228 			to_be_removed = client_list[i];
229 			client_list[i] = client_list[i]->next;
230 			__sync_sub_and_fetch(&total_clients_connected, 1);
231 		} else {
232 			list = client_list[i];
233 			while (list->next != NULL) {
234 				if (list->next->session == session) {
235 					to_be_removed = list->next;
236 					list->next = to_be_removed->next;
237 					__sync_sub_and_fetch(&total_clients_connected, 1);
238 					break;
239 				}
240 				list = list->next;
241 			}
242 		}
243 	} else {
244 		log_error_session(session, "Client record not found.");
245 	}
246 
247 	pthread_mutex_unlock(&client_mutex[i]);
248 
249 	if (to_be_removed == NULL) {
250 		return -1;
251 	}
252 
253 	free(to_be_removed);
254 
255 	return 0;
256 }
257 
258 /* Check whether to allow or deny a new connection.
259  */
connection_allowed(t_ip_addr * ip,bool ip_of_proxy,int max_per_ip,int max_total)260 int connection_allowed(t_ip_addr *ip, bool ip_of_proxy, int max_per_ip, int max_total) {
261 	t_banned *ban;
262 	int perip = 1, total = 1, i;
263 	t_client *client;
264 	time_t now;
265 
266 	now = time(NULL);
267 
268 	if (ip_of_proxy == false) {
269 		/* Check for ban
270 		 */
271 		pthread_mutex_lock(&ban_mutex);
272 
273 		ban = banlist;
274 		while (ban != NULL) {
275 			if (same_ip(&(ban->ip), ip)) {
276 				/* Ban expired?
277 				 */
278 				if (now >= ban->deadline) {
279 					break;
280 				}
281 
282 				ban->connect_attempts++;
283 				pthread_mutex_unlock(&ban_mutex);
284 				return ca_BANNED;
285 			}
286 			ban = ban->next;
287 		}
288 
289 		pthread_mutex_unlock(&ban_mutex);
290 	}
291 
292 	/* Check maximum connections
293 	 */
294 	for (i = 0; i < 256; i++) {
295 		pthread_mutex_lock(&client_mutex[i]);
296 
297 		client = client_list[i];
298 		while (client != NULL) {
299 			if (same_ip(&(client->session->ip_address), ip)) {
300 				if ((client->remove_deadline == TIMER_OFF) || (now < client->remove_deadline)) {
301 					perip++;
302 				}
303 			}
304 			if (client->remove_deadline == TIMER_OFF) {
305 				total++;
306 			}
307 			client = client->next;
308 		}
309 
310 		pthread_mutex_unlock(&client_mutex[i]);
311 	}
312 
313 	if ((perip > max_per_ip) && (ip_of_proxy == false)) {
314 		return ca_TOOMUCH_PERIP;
315 	} else if (total > max_total) {
316 		return ca_TOOMUCH_TOTAL;
317 	} else {
318 		return total;
319 	}
320 }
321 
322 /* Return the number of total connections
323  */
count_registered_connections(void)324 int count_registered_connections(void) {
325 	return total_clients_connected;
326 }
327 
328 /* Disconnect all connected clients.
329  */
disconnect_clients(t_config * config)330 int disconnect_clients(t_config *config) {
331 	t_client *client;
332 	t_directory *dir;
333 	int max_wait = 10, i, kicked = 0;
334 
335 	for (i = 0; i < 256; i++) {
336 		pthread_mutex_lock(&client_mutex[i]);
337 
338 		client = client_list[i];
339 		while (client != NULL) {
340 			client->session->force_quit = true;
341 			client = client->next;
342 			kicked++;
343 		}
344 
345 		pthread_mutex_unlock(&client_mutex[i]);
346 	}
347 
348 	for (i = 0; i < 256; i++) {
349 		while ((client_list[i] != NULL) && (max_wait-- > 0)) {
350 			usleep(100000);
351 		}
352 	}
353 
354 	dir = config->directory;
355 	while (dir != NULL) {
356 		dir->nr_of_clients = 0;
357 		dir = dir->next;
358 	}
359 
360 	return kicked;
361 }
362 
363 /* Kick an IP address.
364  */
kick_ip(t_ip_addr * ip)365 int kick_ip(t_ip_addr *ip) {
366 	t_client *client;
367 	int result = 0;
368 	unsigned char i;
369 
370 	i = index_by_ip(ip);
371 	pthread_mutex_lock(&client_mutex[i]);
372 
373 	client = client_list[i];
374 	while (client != NULL) {
375 		if (same_ip(&(client->session->ip_address), ip)) {
376 			client->session->force_quit = true;
377 			result++;
378 		}
379 		client = client->next;
380 	}
381 
382 	pthread_mutex_unlock(&client_mutex[i]);
383 
384 	return result;
385 }
386 
387 /* Check if the client is flooding the server with requests
388  */
client_is_flooding(t_session * session)389 bool client_is_flooding(t_session *session) {
390 	time_t time_passed;
391 	int requests_allowed;
392 
393 	time_passed = session->time - session->flooding_timer;
394 
395 	if (time_passed < session->config->flooding_time) {
396 		requests_allowed = session->config->flooding_count;
397 	} else {
398 		requests_allowed = (session->config->flooding_count * time_passed) / session->config->flooding_time;
399 	}
400 
401 	return session->kept_alive > requests_allowed;
402 }
403 
404 /* Disconnect a client.
405  */
kick_client(int id)406 int kick_client(int id) {
407 	t_client *client;
408 	int i, result = 0;
409 
410 	for (i = 0; i < 256; i++) {
411 		pthread_mutex_lock(&client_mutex[i]);
412 
413 		client = client_list[i];
414 		while (client != NULL) {
415 			if (client->session->force_quit) {
416 				break;
417 			} else if (client->session->client_id == id) {
418 				client->session->force_quit = true;
419 				result = 1;
420 				break;
421 			}
422 			client = client->next;
423 		}
424 
425 		pthread_mutex_unlock(&client_mutex[i]);
426 	}
427 
428 	return result;
429 }
430 
431 /* IP ban functions
432  */
ban_ip(t_ip_addr * ip,int timer,bool kick_on_ban)433 int ban_ip(t_ip_addr *ip, int timer, bool kick_on_ban) {
434 	int retval = 0;
435 	t_banned *ban;
436 	bool new_ip = true;
437 
438 	pthread_mutex_lock(&ban_mutex);
439 
440 	ban = banlist;
441 	while (ban != NULL) {
442 		if (same_ip(&(ban->ip), ip)) {
443 			ban->bantime = timer;
444 			if (timer == TIMER_OFF) {
445 				ban->deadline = TIMER_OFF;
446 			} else {
447 				ban->deadline = time(NULL) + ban->bantime;
448 			}
449 			new_ip = false;
450 			break;
451 		}
452 		ban = ban->next;
453 	}
454 
455 	if (new_ip) {
456 		if ((ban = (t_banned*)malloc(sizeof(t_banned))) != NULL) {
457 			copy_ip(&(ban->ip), ip);
458 			ban->bantime = timer;
459 			if (timer == TIMER_OFF) {
460 				ban->deadline = TIMER_OFF;
461 			} else {
462 				ban->deadline = time(NULL) + ban->bantime;
463 			}
464 			ban->connect_attempts = 0;
465 			ban->next = banlist;
466 			banlist = ban;
467 
468 #ifdef ENABLE_TOMAHAWK
469 			increment_counter(COUNTER_BAN);
470 #endif
471 
472 			retval = 1;
473 		} else {
474 			retval = -1;
475 		}
476 	}
477 
478 	pthread_mutex_unlock(&ban_mutex);
479 
480 	if (kick_on_ban && new_ip) {
481 		retval = kick_ip(ip);
482 	}
483 
484 	return retval;
485 }
486 
487 /* Reset the timer of a banned IP address.
488  */
reban_ip(t_ip_addr * ip)489 void reban_ip(t_ip_addr *ip) {
490 	t_banned *ban;
491 
492 	pthread_mutex_lock(&ban_mutex);
493 
494 	ban = banlist;
495 	while (ban != NULL) {
496 		if (same_ip(&(ban->ip), ip)) {
497 			if (ban->bantime != TIMER_OFF) {
498 				ban->deadline = time(NULL) + ban->bantime;
499 			}
500 			break;
501 		}
502 		ban = ban->next;
503 	}
504 
505 	pthread_mutex_unlock(&ban_mutex);
506 }
507 
508 /* Check the timers of the banlist.
509  */
check_ban_list(t_config * config,time_t now)510 void check_ban_list(t_config *config, time_t now) {
511 	t_banned *ban, *prev = NULL, *next;
512 
513 	pthread_mutex_lock(&ban_mutex);
514 
515 	ban = banlist;
516 	while (ban != NULL) {
517 		next = ban->next;
518 		if (ban->deadline == TIMER_OFF) {
519 			/* Timer off
520 			 */
521 			prev = ban;
522 		} else if (ban->deadline <= now) {
523 			/* Deadline reached
524 			 */
525 			if (prev == NULL) {
526 				banlist = next;
527 			} else {
528 				prev->next = next;
529 			}
530 			log_unban(config, &(ban->ip), ban->connect_attempts);
531 			free(ban);
532 		} else {
533 			/* other
534 			 */
535 			prev = ban;
536 		}
537 		ban = next;
538 	}
539 
540 	pthread_mutex_unlock(&ban_mutex);
541 }
542 
543 /* Unban an IP address.
544  */
unban_ip(t_ip_addr * ip)545 int unban_ip(t_ip_addr *ip) {
546 	t_ip_addr any;
547 	bool any_ip;
548 	t_banned *ban, *prev = NULL, *next;
549 	int result = 0;
550 
551 	/* Unban all?
552 	 */
553 	default_ipv4(&any);
554 	any_ip = same_ip(ip, &any);
555 	if (any_ip == false) {
556 		default_ipv6(&any);
557 		any_ip = same_ip(ip, &any);
558 	}
559 
560 	pthread_mutex_lock(&ban_mutex);
561 
562 	ban = banlist;
563 	while (ban != NULL) {
564 		next = ban->next;
565 		if (same_ip(&(ban->ip), ip) || any_ip) {
566 			if (prev == NULL) {
567 				banlist = ban->next;
568 			} else {
569 				prev->next = ban->next;
570 			}
571 			free(ban);
572 			result++;
573 
574 			if (any_ip == false) {
575 				break;
576 			}
577 		} else {
578 			prev = ban;
579 		}
580 		ban = next;
581 	}
582 
583 	pthread_mutex_unlock(&ban_mutex);
584 
585 	return result;
586 }
587 
588 /* Remember a client that sent a wrong password for HTTP authentication
589  */
register_wrong_password(t_session * session)590 int register_wrong_password(t_session *session) {
591 	t_ipcounterlist *item;
592 
593 	if (session->config->ban_on_wrong_password == 0) {
594 		return 0;
595 	}
596 
597 	pthread_mutex_lock(&pwd_mutex);
598 
599 	item = wrong_password_list;
600 	while (item != NULL) {
601 		if (same_ip(&(item->ip), &(session->ip_address))) {
602 			if (++(item->count) >= session->config->max_wrong_passwords) {
603 				if (ip_allowed(&(session->ip_address), session->config->banlist_mask) != deny) {
604 					ban_ip(&(session->ip_address), session->config->ban_on_wrong_password, session->config->kick_on_ban);
605 					session->keep_alive = false;
606 					log_system_session(session, "Client banned because of too many wrong passwords");
607 #ifdef ENABLE_MONITOR
608 					if (session->config->monitor_enabled) {
609 						monitor_count_ban(session);
610 					}
611 #endif
612 				}
613 			}
614 
615 			pthread_mutex_unlock(&pwd_mutex);
616 			return 0;
617 		}
618 		item = item->next;
619 	}
620 
621 	if ((item = (t_ipcounterlist*)malloc(sizeof(t_ipcounterlist))) == NULL) {
622 		pthread_mutex_unlock(&pwd_mutex);
623 		return -1;
624 	}
625 
626 	copy_ip(&(item->ip), &(session->ip_address));
627 	item->count = 1;
628 	item->next = wrong_password_list;
629 	wrong_password_list = item;
630 
631 	pthread_mutex_unlock(&pwd_mutex);
632 
633 	return 0;
634 }
635 
636 /* Remove all clients from the wrong-password list
637  */
remove_wrong_password_list(t_config * config)638 void remove_wrong_password_list(t_config *config) {
639 	t_ipcounterlist *item, *remove;
640 
641 	if ((config->ban_on_wrong_password == 0) || (wrong_password_list == NULL)) {
642 		return;
643 	} else if (++password_delay_timer < MAX_PASSWORD_DELAY_TIMER) {
644 		return;
645 	}
646 
647 	pthread_mutex_lock(&pwd_mutex);
648 
649 	item = wrong_password_list;
650 	wrong_password_list = NULL;
651 
652 	pthread_mutex_unlock(&pwd_mutex);
653 
654 	while (item != NULL) {
655 		remove = item;
656 		item = item->next;
657 
658 		free(remove);
659 	}
660 
661 	password_delay_timer = 0;
662 }
663 
664 /* Close all client sockets to run a CGI program
665  */
close_client_sockets_for_cgi_run(void)666 void close_client_sockets_for_cgi_run(void) {
667 	t_client *client;
668 	int i;
669 
670 	for (i = 0; i < 256; i++) {
671 		client = client_list[i];
672 		while (client != NULL) {
673 			close(client->session->client_socket);
674 			client = client->next;
675 		}
676 	}
677 }
678 
679 #ifdef ENABLE_TOMAHAWK
680 /* Print the list of current connections.
681  */
print_client_list(FILE * fp)682 void print_client_list(FILE *fp) {
683 	t_client *client, *current;
684 	char ip_address[MAX_IP_STR_LEN];
685 	int i, count = 0;
686 	time_t now;
687 
688 	now = time(NULL);
689 
690 	for (i = 0; i < 256; i++) {
691 		pthread_mutex_lock(&client_mutex[i]);
692 
693 		client = client_list[i];
694 		while (client != NULL) {
695 			current = client;
696 			client = client->next;
697 
698 			if (current->session->force_quit) {
699 				continue;
700 			}
701 
702 			if ((current->remove_deadline != TIMER_OFF) && (now >= current->remove_deadline)) {
703 				continue;
704 			}
705 
706 			fprintf(fp, "  Client ID   : %d\n", current->session->client_id);
707 #ifdef ENABLE_DEBUG
708 			fprintf(fp, "  Current task: %s\n", current->session->current_task);
709 #endif
710 
711 			if (inet_ntop(current->session->ip_address.family, &(current->session->ip_address.value), ip_address, MAX_IP_STR_LEN) != NULL) {
712 				fprintf(fp, "  IP-address  : %s\n", ip_address);
713 			}
714 			if (current->session->last_host != NULL) {
715 				fprintf(fp, "  Hostname    : %s\n", *(current->session->last_host->hostname.item));
716 			}
717 			fprintf(fp, "  Socket      : %d\n", current->session->client_socket);
718 			if (current->session->remote_user != NULL) {
719 				fprintf(fp, "  Remote user : %s\n", current->session->remote_user);
720 			}
721 			fprintf(fp, "  Kept alive  : %d\n\n", current->session->kept_alive);
722 
723 			count++;
724 		}
725 
726 		pthread_mutex_unlock(&client_mutex[i]);
727 	}
728 
729 	fprintf(fp, "  Total: %d clients\n", count);
730 }
731 
732 /* Print the list of banned IP addresses.
733  */
print_ban_list(FILE * fp)734 void print_ban_list(FILE *fp) {
735 	t_banned *ban;
736 	char ip_address[MAX_IP_STR_LEN];
737 	int count = 0;
738 	time_t now;
739 
740 	now = time(NULL);
741 
742 	pthread_mutex_lock(&ban_mutex);
743 
744 	ban = banlist;
745 	while (ban != NULL) {
746 		if (inet_ntop(ban->ip.family, &(ban->ip.value), ip_address, MAX_IP_STR_LEN) != NULL) {
747 			fprintf(fp, "  IP-address  : %s\n", ip_address);
748 		}
749 
750 		if (ban->deadline == TIMER_OFF) {
751 			fprintf(fp, "  ban has no timer\n\n");
752 		} else if (now < ban->deadline) {
753 			fprintf(fp, "  seconds left: %ld\n\n", ban->deadline - (long)now);
754 		} else {
755 			fprintf(fp, "  ban marked for removal\n\n");
756 		}
757 
758 		count++;
759 		ban = ban->next;
760 	}
761 	fprintf(fp, "  Total: %d bans\n", count);
762 
763 	pthread_mutex_unlock(&ban_mutex);
764 }
765 
number_of_bans(void)766 int number_of_bans(void) {
767 	t_banned *ban;
768 	int result = 0;
769 
770 	pthread_mutex_lock(&ban_mutex);
771 
772 	ban = banlist;
773 	while (ban != NULL) {
774 		result++;
775 		ban = ban->next;
776 	}
777 
778 	pthread_mutex_unlock(&ban_mutex);
779 
780 	return result;
781 }
782 
783 #endif
784