diff options
-rw-r--r-- | docs/helpop.conf.example | 5 | ||||
-rw-r--r-- | docs/inspircd.conf.example | 19 | ||||
-rw-r--r-- | include/commands.h | 1 | ||||
-rw-r--r-- | include/xline.h | 15 | ||||
-rw-r--r-- | src/commands.cpp | 33 | ||||
-rw-r--r-- | src/inspircd.cpp | 42 | ||||
-rw-r--r-- | src/xline.cpp | 79 |
7 files changed, 170 insertions, 24 deletions
diff --git a/docs/helpop.conf.example b/docs/helpop.conf.example index 583108b23..522250242 100644 --- a/docs/helpop.conf.example +++ b/docs/helpop.conf.example @@ -137,8 +137,9 @@ line18="U Show u-lined servers" line19="P Show online opers and their idle times" line20="I Show connect class permissions" - line21="-" - line22="Note that all /STATS use is broadcast to online IRC operators."> + line21="e Show e-lines (local ban exemptions)" + line22="-" + line23="Note that all /STATS use is broadcast to online IRC operators."> <kline line1="/KLINE [user@host] {[duration] :[reason]}" line2="Sets or removes a k-line (host based ban) on a host and ident mask." diff --git a/docs/inspircd.conf.example b/docs/inspircd.conf.example index 22031e957..39fa8fe1e 100644 --- a/docs/inspircd.conf.example +++ b/docs/inspircd.conf.example @@ -257,6 +257,18 @@ <pid file="/path/to/inspircd.pid"> +#-#-#-#-#-#-#-#-#-#-#-#-#- BANLIST LIMITS #-#-#-#-#-#-#-#-#-#-#-#-#-#-# +# # +# Use these tags to customise the ban limits on a per channel basis. # +# the tags are read from top to bottom, and any tag found which # +# matches the channels name applies the banlimit to that channel. # +# It is advisable to put an entry with the channel as '*' at the # +# bottom of the list. If none are specified or no maxbans tag is # +# matched, the banlist size defaults to 64 entries. # +# # + +<banlist chan="#morons" limit="128"> +<banlist chan="*" limit="69"> #-#-#-#-#-#-#-#-#-#-#-#-#-#-#- RTFM LINE -#-#-#-#-#-#-#-#-#-#-#-#-#-# # # @@ -353,6 +365,11 @@ # host - ident@hostname (wildcards possible) # # reason - Reason to display on disconnection # # # +# exception lines define a hostmask that is excempt from [kzg]lines # +# # +# host - ident@hostname (wildcards possible) # +# reason - Reason, shown only in /stats e # +# # <badip ipmask="69.69.69.69" reason="No porn here thanks."> @@ -364,6 +381,8 @@ <badhost host="*@hundredz.n.hundredz.o.1337.kiddies.com" reason="Too many 1337 kiddiots"> <badhost host="*@localhost" reason="No irc from localhost!"> +<exception host="*@ircop.host.com" reason="Opers hostname"> + #-#-#-#-#-#-#-#-#-#-#- ALIAS DEFINITIONS -#-#-#-#-#-#-#-#-#-#-#-#-#-# # # # If you have the m_alias.so module loaded, you may also define # diff --git a/include/commands.h b/include/commands.h index f1c383e08..1242671b3 100644 --- a/include/commands.h +++ b/include/commands.h @@ -77,6 +77,7 @@ void handle_kline(char **parameters, int pcnt, userrec *user); void handle_gline(char **parameters, int pcnt, userrec *user); void handle_zline(char **parameters, int pcnt, userrec *user); void handle_qline(char **parameters, int pcnt, userrec *user); +void handle_eline(char **parameters, int pcnt, userrec *user); void handle_server(char **parameters, int pcnt, userrec *user); /** Special functions for processing server to server traffic diff --git a/include/xline.h b/include/xline.h index 87f88518f..b5163ee58 100644 --- a/include/xline.h +++ b/include/xline.h @@ -79,6 +79,15 @@ class GLine : public XLine char hostmask[MAXBUF]; }; +class ELine : public XLine +{ + public: + /** Hostmask (ident@host) to match against + * May contain wildcards. + */ + char hostmask[MAXBUF]; +}; + /** ZLine class */ class ZLine : public XLine @@ -115,16 +124,19 @@ void add_gline(long duration, char* source, char* reason, char* hostmask); void add_qline(long duration, char* source, char* reason, char* nickname); void add_zline(long duration, char* source, char* reason, char* ipaddr); void add_kline(long duration, char* source, char* reason, char* hostmask); +void add_eline(long duration, char* source, char* reason, char* hostmask); bool del_gline(char* hostmask); bool del_qline(char* nickname); bool del_zline(char* ipaddr); bool del_kline(char* hostmask); +bool del_eline(char* hostmask); char* matches_qline(const char* nick); char* matches_gline(const char* host); char* matches_zline(const char* ipaddr); char* matches_kline(const char* host); +char* matches_exception(const char* host); void expire_lines(); void apply_lines(); @@ -133,6 +145,7 @@ void stats_k(userrec* user); void stats_g(userrec* user); void stats_q(userrec* user); void stats_z(userrec* user); +void stats_e(userrec* user); void gline_set_creation_time(char* host, time_t create_time); void qline_set_creation_time(char* nick, time_t create_time); @@ -144,5 +157,3 @@ bool qline_make_global(char* nickname); void sync_xlines(serverrec* serv, char* tcp_host); #endif - - diff --git a/src/commands.cpp b/src/commands.cpp index 75f0dd86d..2ae4e0049 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -1293,6 +1293,11 @@ void handle_stats(char **parameters, int pcnt, userrec *user) stats_z(user); } + if (!strcmp(parameters[0],"e")) + { + stats_e(user); + } + /* stats m (list number of times each command has been used, plus bytecount) */ if (!strcmp(parameters[0],"m")) { @@ -3160,6 +3165,34 @@ void handle_kline(char **parameters, int pcnt, userrec *user) apply_lines(); } +void handle_eline(char **parameters, int pcnt, userrec *user) +{ + if (pcnt >= 3) + { + add_eline(duration(parameters[1]),user->nick,parameters[2],parameters[0]); + if (!duration(parameters[1])) + { + WriteOpers("*** %s added permenant E-line for %s.",user->nick,parameters[0]); + } + else + { + WriteOpers("*** %s added timed E-line for %s, expires in %d seconds.",user->nick,parameters[0],duration(parameters[1])); + } + } + else + { + if (del_eline(parameters[0])) + { + WriteOpers("*** %s Removed E-line on %s.",user->nick,parameters[0]); + } + else + { + WriteServ(user->fd,"NOTICE %s :*** E-Line %s not found in list, try /stats e.",user->nick,parameters[0]); + } + } + // no need to apply the lines for an eline +} + void handle_gline(char **parameters, int pcnt, userrec *user) { char netdata[MAXBUF]; diff --git a/src/inspircd.cpp b/src/inspircd.cpp index d979750b5..2ef0b53bc 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -2243,8 +2243,10 @@ void AddClient(int socket, char* host, int port, bool iscached, char* ip) if (clientlist.size() == MAXCLIENTS) kill_link(clientlist[tempnick],"No more connections allowed in this class"); + char* r = matches_zline(ip); - if (r) + char* e = matches_exception(ip); + if ((r) && (!e)) { char reason[MAXBUF]; snprintf(reason,MAXBUF,"Z-Lined: %s",r); @@ -2375,23 +2377,26 @@ void FullConnectUser(userrec* user) char match_against[MAXBUF]; snprintf(match_against,MAXBUF,"%s@%s",user->ident,user->host); - char* r = matches_gline(match_against); - if (r) - { - char reason[MAXBUF]; - snprintf(reason,MAXBUF,"G-Lined: %s",r); - kill_link_silent(user,reason); - return; - } - - r = matches_kline(user->host); - if (r) - { - char reason[MAXBUF]; - snprintf(reason,MAXBUF,"K-Lined: %s",r); - kill_link_silent(user,reason); - return; - } + char* e = matches_exception(match_against); + if (!e) + { + char* r = matches_gline(match_against); + if (r) + { + char reason[MAXBUF]; + snprintf(reason,MAXBUF,"G-Lined: %s",r); + kill_link_silent(user,reason); + return; + } + r = matches_kline(user->host); + if (r) + { + char reason[MAXBUF]; + snprintf(reason,MAXBUF,"K-Lined: %s",r); + kill_link_silent(user,reason); + return; + } + } WriteServ(user->fd,"NOTICE Auth :Welcome to \002%s\002!",Network); WriteServ(user->fd,"001 %s :Welcome to the %s IRC Network %s!%s@%s",user->nick,Network,user->nick,user->ident,user->host); @@ -2967,6 +2972,7 @@ void SetupCommandTable(void) createcommand("GLINE",handle_gline,'o',1); createcommand("ZLINE",handle_zline,'o',1); createcommand("QLINE",handle_qline,'o',1); + createcommand("ELINE",handle_eline,'o',1); createcommand("SERVER",handle_server,0,0); } diff --git a/src/xline.cpp b/src/xline.cpp index 15032b32a..ce6257a66 100644 --- a/src/xline.cpp +++ b/src/xline.cpp @@ -186,6 +186,7 @@ std::vector<KLine> klines; std::vector<GLine> glines; std::vector<ZLine> zlines; std::vector<QLine> qlines; +std::vector<ELine> elines; // Reads the default bans from the config file. // only a very small number of bans are defined @@ -222,6 +223,13 @@ void read_xline_defaults() add_kline(0,"<Config>",reason,host); log(DEBUG,"Read K line (badhost tag): host=%s reason=%s",host,reason); } + for (int i = 0; i < ConfValueEnum("exception",&config_f); i++) + { + ConfValue("exception","host",i,host,&config_f); + ConfValue("exception","reason",i,reason,&config_f); + add_eline(0,"<Config>",reason,host); + log(DEBUG,"Read E line (exception tag): host=%s reason=%s",host,reason); + } } // adds a g:line @@ -239,6 +247,21 @@ void add_gline(long duration, char* source, char* reason, char* hostmask) glines.push_back(item); } +// adds an e:line (exception to bans) + +void add_eline(long duration, char* source, char* reason, char* hostmask) +{ + del_eline(hostmask); + ELine item; + item.duration = duration; + strlcpy(item.hostmask,hostmask,MAXBUF); + strlcpy(item.reason,reason,MAXBUF); + strlcpy(item.source,source,MAXBUF); + item.n_matches = 0; + item.set_time = time(NULL); + elines.push_back(item); +} + // adds a q:line void add_qline(long duration, char* source, char* reason, char* nickname) @@ -301,6 +324,21 @@ bool del_gline(char* hostmask) return false; } +// deletes a e:line, returns true if the line existed and was removed + +bool del_eline(char* hostmask) +{ + for (std::vector<ELine>::iterator i = elines.begin(); i != elines.end(); i++) + { + if (!strcasecmp(hostmask,i->hostmask)) + { + elines.erase(i); + return true; + } + } + return false; +} + // deletes a q:line, returns true if the line existed and was removed bool del_qline(char* nickname) @@ -430,6 +468,21 @@ char* matches_gline(const char* host) return NULL; } +char* matches_exception(const char* host) +{ + char host2[MAXBUF]; + snprintf(host2,MAXBUF,"*@%s",host); + for (std::vector<ELine>::iterator i = elines.begin(); i != elines.end(); i++) + { + if ((match(host,i->hostmask)) || (match(host2,i->hostmask))) + { + return i->reason; + } + } + return NULL; +} + + void gline_set_creation_time(char* host, time_t create_time) { for (std::vector<GLine>::iterator i = glines.begin(); i != glines.end(); i++) @@ -521,6 +574,17 @@ void expire_lines() } } + for (std::vector<ELine>::iterator i = elines.begin(); i != elines.end(); i++) + { + if ((current > (i->duration + i->set_time)) && (i->duration > 0)) + { + WriteOpers("Expiring timed E-Line %s (set by %s %d seconds ago)",i->hostmask,i->source,i->duration); + elines.erase(i); + go_again = true; + break; + } + } + for (std::vector<GLine>::iterator i = glines.begin(); i != glines.end(); i++) { if ((current > (i->duration + i->set_time)) && (i->duration > 0)) @@ -575,6 +639,12 @@ void apply_lines() if (!strcasecmp(u->second->server,ServerName)) { snprintf(host,MAXBUF,"%s@%s",u->second->ident,u->second->host); + if (elines.size()) + { + // ignore people matching exempts + if (matches_exception(host)) + continue; + } if (glines.size()) { char* check = matches_gline(host); @@ -660,5 +730,10 @@ void stats_z(userrec* user) } } - - +void stats_e(userrec* user) +{ + for (std::vector<ELine>::iterator i = elines.begin(); i != elines.end(); i++) + { + WriteServ(user->fd,"223 %s :%s %d %d %s %s",user->nick,i->hostmask,i->set_time,i->duration,i->source,i->reason); + } +} |