X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/cbeab4bc340b7b3f4fbf424ff327758defb9598a..8efff56fdf9f4ce4a3968c74162fed9d8d45c51a:/ircd/reject.c diff --git a/ircd/reject.c b/ircd/reject.c index 90f4f1e8..db90d388 100644 --- a/ircd/reject.c +++ b/ircd/reject.c @@ -45,6 +45,8 @@ static void throttle_expires(void *unused); typedef struct _reject_data { rb_dlink_node rnode; + struct ConfItem *aconf; + const char *reason; time_t time; unsigned int count; uint32_t mask_hashv; @@ -54,6 +56,8 @@ typedef struct _delay_data { rb_dlink_node node; rb_fde_t *F; + struct ConfItem *aconf; + const char *reason; } delay_t; typedef struct _throttle @@ -69,9 +73,21 @@ delay_exit_length(void) return rb_dlink_list_length(&delay_exit); } +static void +reject_free(reject_t *rdata) +{ + struct ConfItem *aconf = rdata->aconf; + + if (aconf) + deref_conf(aconf); + + rb_free(rdata); +} + static void reject_exit(void *unused) { + static char dynamic_reason[BUFSIZE]; rb_dlink_node *ptr, *ptr_next; delay_t *ddata; static const char *errbuf = "ERROR :Closing Link: (*** Banned (cache))\r\n"; @@ -80,6 +96,23 @@ reject_exit(void *unused) { ddata = ptr->data; + *dynamic_reason = '\0'; + + if (ddata->aconf) + { + snprintf(dynamic_reason, BUFSIZE, form_str(ERR_YOUREBANNEDCREEP) "\r\n", + me.name, "*", get_user_ban_reason(ddata->aconf)); + rb_write(ddata->F, dynamic_reason, strlen(dynamic_reason)); + + deref_conf(ddata->aconf); + } + else if (ddata->reason) + { + snprintf(dynamic_reason, BUFSIZE, ":%s 465 %s :%s\r\n", + me.name, "*", ddata->reason); + rb_write(ddata->F, dynamic_reason, strlen(dynamic_reason)); + } + rb_write(ddata->F, errbuf, strlen(errbuf)); rb_close(ddata->F); rb_free(ddata); @@ -105,7 +138,7 @@ reject_expires(void *unused) continue; rb_dlinkDelete(ptr, &reject_list); - rb_free(rdata); + reject_free(rdata); rb_patricia_remove(reject_tree, pnode); } } @@ -141,7 +174,7 @@ throttle_size(void) } void -add_reject(struct Client *client_p, const char *mask1, const char *mask2) +add_reject(struct Client *client_p, const char *mask1, const char *mask2, struct ConfItem *aconf, const char *reason) { rb_patricia_node_t *pnode; reject_t *rdata; @@ -166,17 +199,32 @@ add_reject(struct Client *client_p, const char *mask1, const char *mask2) else { int bitlen = 32; -#ifdef RB_IPV6 if(GET_SS_FAMILY(&client_p->localClient->ip) == AF_INET6) bitlen = 128; -#endif pnode = make_and_lookup_ip(reject_tree, (struct sockaddr *)&client_p->localClient->ip, bitlen); pnode->data = rdata = rb_malloc(sizeof(reject_t)); rb_dlinkAddTail(pnode, &rdata->rnode, &reject_list); rdata->time = rb_current_time(); rdata->count = 1; + rdata->aconf = NULL; + rdata->reason = NULL; } rdata->mask_hashv = hashv; + + if (aconf != NULL && aconf != rdata->aconf && (aconf->status & CONF_KILL) && aconf->passwd) + { + if (rdata->aconf != NULL) + deref_conf(rdata->aconf); + aconf->clients++; + rdata->aconf = aconf; + } + else if (reason != NULL) + { + if (rdata->aconf != NULL) + deref_conf(rdata->aconf); + rdata->aconf = NULL; + rdata->reason = reason; + } } int @@ -185,28 +233,51 @@ check_reject(rb_fde_t *F, struct sockaddr *addr) rb_patricia_node_t *pnode; reject_t *rdata; delay_t *ddata; + /* Reject is disabled */ - if(ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_duration == 0) + if (ConfigFileEntry.reject_after_count == 0 || ConfigFileEntry.reject_duration == 0) return 0; pnode = rb_match_ip(reject_tree, addr); - if(pnode != NULL) + if (pnode == NULL) + return 0; + + rdata = pnode->data; + rdata->time = rb_current_time(); + + if (rdata->count <= (unsigned long)ConfigFileEntry.reject_after_count) + return 0; + + if (rdata->aconf != NULL && rdata->aconf->status & CONF_ILLEGAL) { - rdata = pnode->data; + rb_dlinkDelete(&rdata->rnode, &reject_list); + reject_free(rdata); + rb_patricia_remove(reject_tree, pnode); + return 0; + } - rdata->time = rb_current_time(); - if(rdata->count > (unsigned long)ConfigFileEntry.reject_after_count) - { - ddata = rb_malloc(sizeof(delay_t)); - ServerStats.is_rej++; - rb_setselect(F, RB_SELECT_WRITE | RB_SELECT_READ, NULL, NULL); - ddata->F = F; - rb_dlinkAdd(ddata, &ddata->node, &delay_exit); - return 1; - } + ddata = rb_malloc(sizeof(delay_t)); + ServerStats.is_rej++; + rb_setselect(F, RB_SELECT_WRITE | RB_SELECT_READ, NULL, NULL); + if (rdata->aconf) + { + ddata->aconf = rdata->aconf; + ddata->aconf->clients++; + ddata->reason = NULL; } - /* Caller does what it wants */ - return 0; + else if (rdata->reason) + { + ddata->reason = rdata->reason; + ddata->aconf = NULL; + } + else + { + ddata->aconf = NULL; + ddata->reason = NULL; + } + ddata->F = F; + rb_dlinkAdd(ddata, &ddata->node, &delay_exit); + return 1; } int @@ -246,7 +317,7 @@ flush_reject(void) pnode = ptr->data; rdata = pnode->data; rb_dlinkDelete(ptr, &reject_list); - rb_free(rdata); + reject_free(rdata); rb_patricia_remove(reject_tree, pnode); } } @@ -264,7 +335,7 @@ remove_reject_ip(const char *ip) { reject_t *rdata = pnode->data; rb_dlinkDelete(&rdata->rnode, &reject_list); - rb_free(rdata); + reject_free(rdata); rb_patricia_remove(reject_tree, pnode); return 1; } @@ -292,7 +363,7 @@ remove_reject_mask(const char *mask1, const char *mask2) if (rdata->mask_hashv == hashv) { rb_dlinkDelete(ptr, &reject_list); - rb_free(rdata); + reject_free(rdata); rb_patricia_remove(reject_tree, pnode); n++; } @@ -321,10 +392,8 @@ throttle_add(struct sockaddr *addr) } else { int bitlen = 32; -#ifdef RB_IPV6 if(GET_SS_FAMILY(addr) == AF_INET6) bitlen = 128; -#endif t = rb_malloc(sizeof(throttle_t)); t->last = rb_current_time(); t->count = 1;