summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/helpop.conf.example5
-rw-r--r--docs/inspircd.conf.example19
-rw-r--r--include/commands.h1
-rw-r--r--include/xline.h15
-rw-r--r--src/commands.cpp33
-rw-r--r--src/inspircd.cpp42
-rw-r--r--src/xline.cpp79
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);
+ }
+}