diff --git a/Changes b/Changes
index dd7b8ce44..3f2bf3087 100644
--- a/Changes
+++ b/Changes
@@ -3172,3 +3172,7 @@ This is the 3.2 fixes branch.
- Imported TRE 0.6.7 for *nix and made use of tre_version to report the version of TRE
in use at startup
- Fixed a Win32 module bug
+- Added set::spamfilter::virus-help-channel-deny. This allows you to block any
+ normal joins to the virus-help-channel. This way you could prevent users into
+ accidental (or tricked) joining of the virus-help-channel and becomming infected.
+ This feature is disabled by default. Requested by bleepy (#0001811).
diff --git a/doc/unreal32docs.html b/doc/unreal32docs.html
index 7a2b6e369..c7ef170b3 100644
--- a/doc/unreal32docs.html
+++ b/doc/unreal32docs.html
@@ -502,6 +502,7 @@ into spaces at runtime. And double underscore ('__') gets an underscore ('_'). A
@@ -2170,6 +2171,10 @@ set {
Reason to be used for *lines added by spamfilter
set::spamfilter::virus-help-channel <channel>
The channel to use for the 'viruschan' action in spamfilter
+
set::spamfilter::virus-help-channel-deny <yes|no>
+ If set to yes (or '1') it replies 'invite only' to any normal users that try to join
+ the virus-help-channel. Only opers, people that match spamfilters and people that
+ are /invite'd can join.
set::spamfilter::except <target(s)>
These targets are exempt from spam filtering (no action will be taken),
can be single target or comma seperated list.. Ex: except "#help,#spamreport"
diff --git a/include/dynconf.h b/include/dynconf.h
index e61d2b8ba..835588144 100644
--- a/include/dynconf.h
+++ b/include/dynconf.h
@@ -134,6 +134,7 @@ struct zConfiguration {
long spamfilter_ban_time;
char *spamfilter_ban_reason;
char *spamfilter_virus_help_channel;
+ char spamfilter_vchan_deny;
SpamExcept *spamexcept;
char *spamexcept_line;
aNetwork network;
@@ -230,4 +231,5 @@ extern MODVAR aConfiguration iConf;
#define SPAMFILTER_BAN_TIME iConf.spamfilter_ban_time
#define SPAMFILTER_BAN_REASON iConf.spamfilter_ban_reason
#define SPAMFILTER_VIRUSCHAN iConf.spamfilter_virus_help_channel
+#define SPAMFILTER_VIRUSCHANDENY iConf.spamfilter_vchan_deny
#define SPAMFILTER_EXCEPT iConf.spamexcept_line
diff --git a/src/channel.c b/src/channel.c
index 3b684ef05..1b20f2842 100644
--- a/src/channel.c
+++ b/src/channel.c
@@ -65,6 +65,7 @@ long opermode = 0;
aChannel *channel = NullChn;
extern char backupbuf[];
extern ircstats IRCstats;
+extern int spamf_ugly_vchanoverride;
#ifndef NO_FDLIST
extern int lifesux;
@@ -3351,7 +3352,6 @@ Ban *banned;
#endif
#endif
-
return 0;
}
@@ -3912,6 +3912,28 @@ CMD_FUNC(do_join)
}
}
}
+ /* ugly set::spamfilter::virus-help-channel-deny hack.. */
+ if (SPAMFILTER_VIRUSCHANDENY && SPAMFILTER_VIRUSCHAN &&
+ !strcasecmp(name, SPAMFILTER_VIRUSCHAN) &&
+ !IsAnOper(sptr) && !spamf_ugly_vchanoverride)
+ {
+ int invited = 0;
+ Link *lp;
+ aChannel *chptr = find_channel(name, NULL);
+
+ if (chptr)
+ {
+ for (lp = sptr->user->invited; lp; lp = lp->next)
+ if (lp->value.chptr == chptr)
+ invited = 1;
+ }
+ if (!invited)
+ {
+ sendnotice(sptr, "*** Cannot join '%s' because it's the virus-help-channel which is "
+ "reserved for infected users only", name);
+ continue;
+ }
+ }
}
chptr = get_channel(sptr, name, CREATE);
diff --git a/src/modules/m_invite.c b/src/modules/m_invite.c
index bdc4eaefe..9cab198b2 100644
--- a/src/modules/m_invite.c
+++ b/src/modules/m_invite.c
@@ -193,6 +193,15 @@ DLLFUNC CMD_FUNC(m_invite)
}
}
+ if (MyClient(sptr) && SPAMFILTER_VIRUSCHANDENY && SPAMFILTER_VIRUSCHAN &&
+ !strcasecmp(chptr->chname, SPAMFILTER_VIRUSCHAN) &&
+ !is_chan_op(sptr, chptr) && !IsAnOper(sptr) && !IsULine(sptr))
+ {
+ sendto_one(sptr, err_str(ERR_CHANOPRIVSNEEDED),
+ me.name, parv[0], chptr->chname);
+ return -1;
+ }
+
if (MyConnect(sptr))
{
if (check_for_target_limit(sptr, acptr, acptr->name))
diff --git a/src/s_conf.c b/src/s_conf.c
index 604524f2b..e47e747aa 100644
--- a/src/s_conf.c
+++ b/src/s_conf.c
@@ -5824,6 +5824,8 @@ int _conf_set(ConfigFile *conf, ConfigEntry *ce)
ircstrdup(tempiConf.spamfilter_ban_reason, cepp->ce_vardata);
if (!strcmp(cepp->ce_varname, "virus-help-channel"))
ircstrdup(tempiConf.spamfilter_virus_help_channel, cepp->ce_vardata);
+ if (!strcmp(cepp->ce_varname, "virus-help-channel-deny"))
+ tempiConf.spamfilter_vchan_deny = config_checkval(cepp->ce_vardata,CFG_YESNO);
if (!strcmp(cepp->ce_varname, "except"))
{
char *name, *p;
@@ -6442,6 +6444,8 @@ int _test_set(ConfigFile *conf, ConfigEntry *ce)
continue;
}
} else
+ if (!strcmp(cepp->ce_varname, "virus-help-channel-deny"))
+ { } else
if (!strcmp(cepp->ce_varname, "except"))
{ } else
{
diff --git a/src/s_kline.c b/src/s_kline.c
index f86e15308..9ea664ab9 100644
--- a/src/s_kline.c
+++ b/src/s_kline.c
@@ -43,6 +43,7 @@
aTKline *tklines[TKLISTLEN];
extern MODVAR char zlinebuf[BUFSIZE];
+int spamf_ugly_vchanoverride = 0;
/** tkl hash method.
* NOTE1: the input value 'c' is assumed to be in range a-z or A-Z!
@@ -1434,6 +1435,7 @@ char *str = (char *)StripControlCodes(str_in);
{
char *xparv[3], chbuf[CHANNELLEN + 16];
aChannel *chptr;
+ int ret;
if (IsVirus(sptr)) /* Already tagged */
return 0;
@@ -1442,7 +1444,10 @@ char *str = (char *)StripControlCodes(str_in);
xparv[1] = buf;
xparv[2] = NULL;
/* RECURSIVE CAUTION in case we ever add blacklisted chans */
- if (m_join(sptr, sptr, 2, xparv) == FLUSH_BUFFER)
+ spamf_ugly_vchanoverride = 1;
+ ret = m_join(sptr, sptr, 2, xparv);
+ spamf_ugly_vchanoverride = 0;
+ if (ret == FLUSH_BUFFER)
return FLUSH_BUFFER; /* don't ask me how we could have died... */
sendnotice(sptr, "You are now restricted to talking in %s: %s",
SPAMFILTER_VIRUSCHAN, unreal_decodespace(tk->spamf->tkl_reason));