diff --git a/doc/ircd.conf.example b/doc/ircd.conf.example index 928cbc44..dbe97c2b 100644 --- a/doc/ircd.conf.example +++ b/doc/ircd.conf.example @@ -609,6 +609,7 @@ general { no_oper_flood = yes; max_targets = 4; client_flood_max_lines = 20; + post_registration_delay = 0 seconds; use_whois_actually = no; oper_only_umodes = operwall, locops, servnotice; oper_umodes = locops, servnotice, operwall, wallop; diff --git a/doc/reference.conf b/doc/reference.conf index 98f20931..72af5182 100644 --- a/doc/reference.conf +++ b/doc/reference.conf @@ -1312,6 +1312,12 @@ general { */ max_targets = 4; + /* post-registration delay: wait this long before processing commands from a newly + * registered user. Used to allow network utility bots to perform any actions + * (such as host changes or proxy scanning) before the user can join channels. + */ + post_registration_delay = 2 seconds; + /* use_whois_actually: send clients requesting a whois a numeric * giving the real IP of non-spoofed clients to prevent DNS abuse. */ diff --git a/include/s_conf.h b/include/s_conf.h index 703f4eac..fec5c8a8 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -215,6 +215,7 @@ struct config_file_entry int tkline_expire_notices; int use_whois_actually; int disable_auth; + int post_registration_delay; int connect_timeout; int burst_away; int reject_ban_time; diff --git a/ircd/newconf.c b/ircd/newconf.c index 6a81208d..7a540606 100644 --- a/ircd/newconf.c +++ b/ircd/newconf.c @@ -2748,6 +2748,7 @@ static struct ConfEntry conf_general_table[] = { "client_exit", CF_YESNO, NULL, 0, &ConfigFileEntry.client_exit }, { "collision_fnc", CF_YESNO, NULL, 0, &ConfigFileEntry.collision_fnc }, { "resv_fnc", CF_YESNO, NULL, 0, &ConfigFileEntry.resv_fnc }, + { "post_registration_delay", CF_TIME, NULL, 0, &ConfigFileEntry.post_registration_delay }, { "connect_timeout", CF_TIME, NULL, 0, &ConfigFileEntry.connect_timeout }, { "default_floodcount", CF_INT, NULL, 0, &ConfigFileEntry.default_floodcount }, { "default_ident_timeout", CF_INT, NULL, 0, &ConfigFileEntry.default_ident_timeout }, diff --git a/ircd/packet.c b/ircd/packet.c index 3eb038ad..502d5344 100644 --- a/ircd/packet.c +++ b/ircd/packet.c @@ -133,6 +133,12 @@ parse_client_queued(struct Client *client_p) if(client_p->localClient->sent_parsed >= allow_read) break; + /* post_registration_delay hack. Don't process any messages from a new client for $n seconds, + * to allow network bots to do their thing before channels can be joined. + */ + if (rb_current_time() < client_p->localClient->firsttime + ConfigFileEntry.post_registration_delay) + break; + dolen = rb_linebuf_get(&client_p->localClient-> buf_recvq, readBuf, READBUF_SIZE, LINEBUF_COMPLETE, LINEBUF_PARSED); diff --git a/ircd/s_user.c b/ircd/s_user.c index daba26ec..06d3b6cb 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -386,7 +386,9 @@ register_local_user(struct Client *client_p, struct Client *source_p) if(source_p->preClient->auth.cid) return -1; - client_p->localClient->last = rb_current_time(); + /* Set firsttime here so that post_registration_delay works from registration, + * rather than initial connection. */ + source_p->localClient->firsttime = client_p->localClient->last = rb_current_time(); /* XXX - fixme. we shouldnt have to build a users buffer twice.. */ if(!IsGotId(source_p) && (strchr(source_p->username, '[') != NULL)) diff --git a/modules/m_info.c b/modules/m_info.c index 0f08d04d..d3c8e8c0 100644 --- a/modules/m_info.c +++ b/modules/m_info.c @@ -151,6 +151,12 @@ static struct InfoStruct info_table[] = { &ConfigFileEntry.client_flood_message_time, "Time to allow per client_flood_message_num outside of burst", }, + { + "post_registration_delay", + OUTPUT_DECIMAL, + &ConfigFileEntry.post_registration_delay, + "Time to wait before processing commands from a new client", + }, { "connect_timeout", OUTPUT_DECIMAL,