📄 ipban.c
字号:
for (; text[i]==' '; i++); switch (identify_ipban_function(subcommand)) { case IPBAN_FUNC_ADD: ipbanlist_add(c,ipstr,ipbanlist_str_to_time_t(c,&text[i])); ipbanlist_save(prefs_get_ipbanfile()); break; case IPBAN_FUNC_DEL: ipban_func_del(c,ipstr); ipbanlist_save(prefs_get_ipbanfile()); break; case IPBAN_FUNC_LIST: ipban_func_list(c); break; case IPBAN_FUNC_CHECK: ipban_func_check(c,ipstr); break; case IPBAN_FUNC_HELP: message_send_text(c,message_type_info,c,"The ipban command supports the following patterns."); ipban_usage(c); break; default: message_send_text(c,message_type_info,c,"The command is incorect. Use one of the following patterns."); ipban_usage(c); } return 0;}static int identify_ipban_function(const char * funcstr){ if (strcasecmp(funcstr,"add")==0 || strcasecmp(funcstr,"a")==0) return IPBAN_FUNC_ADD; if (strcasecmp(funcstr,"del")==0 || strcasecmp(funcstr,"d")==0) return IPBAN_FUNC_DEL; if (strcasecmp(funcstr,"list")==0 || strcasecmp(funcstr,"l")==0 || strcmp(funcstr,"")==0) return IPBAN_FUNC_LIST; if (strcasecmp(funcstr,"check")==0 || strcasecmp(funcstr,"c")==0) return IPBAN_FUNC_CHECK; if (strcasecmp(funcstr,"help")==0 || strcasecmp(funcstr,"h")==0) return IPBAN_FUNC_HELP; return IPBAN_FUNC_UNKNOWN;}static int ipban_func_del(t_connection * c, char const * cp){ t_ipban_entry * to_delete; unsigned int to_delete_nmbr; t_ipban_entry * entry; t_elem * curr; unsigned int counter; char tstr[MAX_MESSAGE_LEN]; counter = 0; if (strchr(cp,'.') || strchr(cp,'/') || strchr(cp,'*')) { if (!(to_delete = ipban_str_to_ipban_entry(cp))) { message_send_text(c,message_type_error,c,"Illegal IP entry."); return -1; } LIST_TRAVERSE(ipbanlist_head,curr) { entry = elem_get_data(curr); if (!entry) { eventlog(eventlog_level_error,__FUNCTION__,"ipbanlist contains NULL item"); return -1; } if (ipban_identical_entry(to_delete,entry)) { counter++; if (list_remove_elem(ipbanlist_head,&curr)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not remove item"); else ipban_unload_entry(entry); } } ipban_unload_entry(to_delete); if (counter == 0) { message_send_text(c,message_type_error,c,"No matching entry."); return -1; } else { if (counter == 1) sprintf(tstr,"Entry deleted."); else sprintf(tstr,"Deleted %u entries.",counter); message_send_text(c,message_type_info,c,tstr); return 0; } } to_delete_nmbr = atoi(cp); if (to_delete_nmbr <= 0) { message_send_text(c,message_type_error,c,"Wrong entry number."); return -1; } LIST_TRAVERSE(ipbanlist_head,curr) { if (to_delete_nmbr == ++counter) { entry = elem_get_data(curr); if (!entry) { eventlog(eventlog_level_error,__FUNCTION__,"ipbanlist contains NULL item"); return -1; } if (list_remove_elem(ipbanlist_head,&curr)<0) eventlog(eventlog_level_error,__FUNCTION__,"could not remove item"); else { ipban_unload_entry(entry); message_send_text(c,message_type_info,c,"Entry deleted."); } } } if (to_delete_nmbr > counter) { sprintf(tstr,"There are only %u entries.",counter); message_send_text(c,message_type_error,c,tstr); return -1; } return 0;}static int ipban_func_list(t_connection * c){ t_elem const * curr; t_ipban_entry * entry; char tstr[MAX_MESSAGE_LEN]; unsigned int counter; char timestr[50]; char * ipstr; counter = 0; message_send_text(c,message_type_info,c,"Banned IPs:"); LIST_TRAVERSE_CONST(ipbanlist_head,curr) { entry = elem_get_data(curr); if (!entry) { eventlog(eventlog_level_error,__FUNCTION__,"ipbanlist contains NULL item"); return -1; } counter++; if (entry->endtime == 0) sprintf(timestr,"(perm)"); else sprintf(timestr,"(%.48s)",seconds_to_timestr(entry->endtime - now)); if (!(ipstr = ipban_entry_to_str(entry))) { eventlog(eventlog_level_error,__FUNCTION__,"could not convert entry to string"); continue; } sprintf(tstr,"%u: %s %s",counter,ipstr,timestr); message_send_text(c,message_type_info,c,tstr); xfree(ipstr); } if (counter == 0) message_send_text(c,message_type_info,c,"none"); return 0;}static int ipban_func_check(t_connection * c, char const * cp){ int res; char entry[MAX_MESSAGE_LEN]; res = ipbanlist_check(cp); switch (res) { case 0: message_send_text(c,message_type_info,c,"IP not banned."); break; case -1: message_send_text(c,message_type_error,c,"Error occured."); break; default: sprintf(entry,"IP banned by rule #%i.",res); message_send_text(c,message_type_info,c,entry); } return 0;}static int ipban_identical_entry(t_ipban_entry * e1, t_ipban_entry * e2){ switch (e2->type) { case ipban_type_exact: if (strcmp(e1->info1,e2->info1)==0) return 1; break; case ipban_type_range: if (strcmp(e1->info1,e2->info1)==0 && strcmp(e1->info2,e2->info2)==0) return 1; break; case ipban_type_wildcard: if (strcmp(e1->info1,e2->info1)==0 && strcmp(e1->info2,e2->info2)==0 && strcmp(e1->info3,e2->info3)==0 && strcmp(e1->info4,e2->info4)==0) return 1; break; case ipban_type_netmask: if (strcmp(e1->info1,e2->info1)==0 && strcmp(e1->info2,e2->info2)==0) return 1; break; case ipban_type_prefix: if (strcmp(e1->info1,e2->info1)==0 && strcmp(e1->info2,e2->info2)==0) return 1; break; default: /* unknown type */ eventlog(eventlog_level_warn,__FUNCTION__,"found bad ban type %d",(int)e2->type); } return 0;}static int ipban_unload_entry(t_ipban_entry * e){ switch (e->type) { case ipban_type_exact: case ipban_type_wildcard: if (e->info1) xfree(e->info1); break; case ipban_type_range: case ipban_type_netmask: case ipban_type_prefix: if (e->info1) xfree(e->info1); if (e->info2) xfree(e->info2); break; default: /* unknown type */ eventlog(eventlog_level_warn,__FUNCTION__,"found bad ban type %d",(int)e->type); return -1; } xfree(e); return 0;}static t_ipban_entry * ipban_str_to_ipban_entry(char const * ipstr){ char * matched; char * whole; char * cp; t_ipban_entry * entry; entry = xmalloc(sizeof(t_ipban_entry)); if (!ipstr) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL IP"); xfree(entry); return NULL; } if (ipstr[0] == '\0') { eventlog(eventlog_level_warn,__FUNCTION__,"got empty IP string"); xfree(entry); return NULL; } cp = xstrdup(ipstr); if (ipban_could_be_ip_str(cp)==0) { eventlog(eventlog_level_debug,__FUNCTION__,"string: \"%.32s\" can not be valid IP",cp); xfree(entry); return NULL; } if ((matched = strchr(cp,'-'))) /* range */ { entry->type = ipban_type_range; eventlog(eventlog_level_debug,__FUNCTION__,"entry: %s matched as ipban_type_range",cp); matched[0] = '\0'; entry->info1 = xstrdup(cp); /* start of range */ entry->info2 = xstrdup(&matched[1]); /* end of range */ entry->info3 = NULL; /* clear unused elements so debugging is nicer */ entry->info4 = NULL; } else if (strchr(cp,'*')) /* wildcard */ { entry->type = ipban_type_wildcard; eventlog(eventlog_level_debug,__FUNCTION__,"entry: %s matched as ipban_type_wildcard",cp); /* only xfree() info1! */ whole = xstrdup(cp); entry->info1 = strtok(whole,"."); entry->info2 = strtok(NULL,"."); entry->info3 = strtok(NULL,"."); entry->info4 = strtok(NULL,"."); if (!entry->info4) /* not enough dots */ { eventlog(eventlog_level_error,__FUNCTION__,"wildcard entry \"%s\" does not contain all four octets",cp); xfree(entry->info1); xfree(entry); xfree(cp); return NULL; } } else if ((matched = strchr(cp,'/'))) /* netmask or prefix */ { if (strchr(&matched[1],'.')) { entry->type = ipban_type_netmask; eventlog(eventlog_level_debug,__FUNCTION__,"entry: %s matched as ipban_type_netmask",cp); } else { entry->type = ipban_type_prefix; eventlog(eventlog_level_debug,__FUNCTION__,"entry: %s matched as ipban_type_prefix",cp); } matched[0] = '\0'; entry->info1 = xstrdup(cp); entry->info2 = xstrdup(&matched[1]); entry->info3 = NULL; /* clear unused elements so debugging is nicer */ entry->info4 = NULL; } else /* exact */ { entry->type = ipban_type_exact; eventlog(eventlog_level_debug,__FUNCTION__,"entry: %s matched as ipban_type_exact",cp); entry->info1 = xstrdup(cp); entry->info2 = NULL; /* clear unused elements so debugging is nicer */ entry->info3 = NULL; entry->info4 = NULL; } xfree(cp); return entry;}static char * ipban_entry_to_str(t_ipban_entry const * entry){ char tstr[MAX_MESSAGE_LEN]; char * str; switch (entry->type) { case ipban_type_exact: sprintf(tstr,"%s",entry->info1); break; case ipban_type_wildcard: sprintf(tstr,"%s.%s.%s.%s",entry->info1,entry->info2,entry->info3,entry->info4); break; case ipban_type_range: sprintf(tstr,"%s-%s",entry->info1,entry->info2); break; case ipban_type_netmask: case ipban_type_prefix: sprintf(tstr,"%s/%s",entry->info1,entry->info2); break; default: /* unknown type */ eventlog(eventlog_level_warn,__FUNCTION__,"found bad ban type %d",(int)entry->type); return NULL; } str = xstrdup(tstr); return str;}static unsigned long ipban_str_to_ulong(char const * ipaddr){ unsigned long lip; char * ip1; char * ip2; char * ip3; char * ip4; char * tipaddr; tipaddr = xstrdup(ipaddr); ip1 = strtok(tipaddr,"."); ip2 = strtok(NULL,"."); ip3 = strtok(NULL,"."); ip4 = strtok(NULL,"."); lip = (atoi(ip1) << 24) + (atoi(ip2) << 16) + (atoi(ip3) << 8) + (atoi(ip4)); xfree(tipaddr); return lip;}static int ipban_could_be_exact_ip_str(char const * str){ char * ipstr; char * s; char * ttok; int i; ipstr = xstrdup(str); s = ipstr; for (i=0; i<4; i++) { ttok = (char *)strsep(&ipstr, "."); if (!ttok || strlen(ttok)<1 || strlen(ttok)>3) { xfree(s); return 0; } } xfree(s); return 1;}static int ipban_could_be_ip_str(char const * str){ char * matched; char * ipstr; unsigned int i; if (strlen(str)<7) { eventlog(eventlog_level_error,__FUNCTION__,"string too short"); return 0; } for (i=0; i<strlen(str); i++) if (!isdigit((int)str[i]) && str[i]!='.' && str[i]!='*' && str[i]!='/' && str[i]!='-') { eventlog(eventlog_level_debug,__FUNCTION__,"illegal character on position %i",i); return 0; } ipstr = xstrdup(str); if ((matched = strchr(ipstr,'-'))) { matched[0] = '\0'; if ((ipban_could_be_exact_ip_str(ipstr)==0) || (ipban_could_be_exact_ip_str(&matched[1])==0)) { xfree(ipstr); return 0; } } else if ((matched = strchr(ipstr,'*'))) { if (ipban_could_be_exact_ip_str(ipstr)==0) /* FIXME: 123.123.1*.123 allowed */ { xfree(ipstr); return 0; } } else if ((matched = strchr(ipstr,'/'))) { matched[0] = '\0'; if (strchr(&matched[1],'.')) { if ((ipban_could_be_exact_ip_str(ipstr)==0) || (ipban_could_be_exact_ip_str(&matched[1])==0)) { xfree(ipstr); return 0; } } else { if (ipban_could_be_exact_ip_str(ipstr)==0) { xfree(ipstr); return 0; } for (i=1; i<strlen(&matched[1]); i++) if (!isdigit((int)matched[i])) { xfree(ipstr); return 0; } if (atoi(&matched[1])>32) /* can not be less than 0 because IP/-24 is matched as range */ { xfree(ipstr); return 0; } } } else { if (ipban_could_be_exact_ip_str(ipstr)==0) { xfree(ipstr); return 0; } } xfree(ipstr); return 1; }static void ipban_usage(t_connection * c){ message_send_text(c,message_type_info,c,"to print this information:"); message_send_text(c,message_type_info,c," /ipban h[elp]"); message_send_text(c,message_type_info,c,"to print all baned IPs"); message_send_text(c,message_type_info,c," /ipban [l[ist]]"); message_send_text(c,message_type_info,c,"to erase ban:"); message_send_text(c,message_type_info,c," /ipban d[el] <IP|index num>"); message_send_text(c,message_type_info,c," (IP have to be entry accepted in bnban)"); message_send_text(c,message_type_info,c,"to add ban:"); message_send_text(c,message_type_info,c," /ipban a[dd] IP"); message_send_text(c,message_type_info,c," (IP have to be entry accepted in bnban)"); message_send_text(c,message_type_info,c,"to check is specified IP banned:"); message_send_text(c,message_type_info,c," /ipban c[heck] IP");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -