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