summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/channels.h7
-rw-r--r--src/channels.cpp32
-rw-r--r--src/mode.cpp6
-rw-r--r--src/modules/m_foobar.cpp11
4 files changed, 51 insertions, 5 deletions
diff --git a/include/channels.h b/include/channels.h
index 693f429f4..bf025ec56 100644
--- a/include/channels.h
+++ b/include/channels.h
@@ -528,6 +528,13 @@ class CoreExport Channel : public Extensible
*/
bool IsBanned(User* user);
+ /** Check whether an extban of a given type matches
+ * a given user for this channel.
+ * @param u The user to match bans against
+ * @param type The type of extban to check
+ */
+ bool IsExtBanned(User *u, char type);
+
/** Clears the cached max bans value
*/
void ResetMaxBans();
diff --git a/src/channels.cpp b/src/channels.cpp
index c03a69ace..5dde87117 100644
--- a/src/channels.cpp
+++ b/src/channels.cpp
@@ -450,6 +450,38 @@ bool Channel::IsBanned(User* user)
return false;
}
+bool Channel::IsExtBanned(User *user, char type)
+{
+ // XXX. do we need events?
+ char mask[MAXBUF];
+ char *maskptr;
+
+ snprintf(mask, MAXBUF, "%s!%s@%s", user->nick, user->ident, user->GetIPString());
+
+ for (BanList::iterator i = this->bans.begin(); i != this->bans.end(); i++)
+ {
+ if (i->data[0] != type || i->data[1] != ':')
+ continue;
+
+ // Iterate past char and : to get to the mask without doing a data copy(!)
+ maskptr = i->data;
+ maskptr++; // past the char
+ maskptr++; // past the :
+printf("realmask: %s\n", maskptr);
+
+ /* This allows CIDR ban matching
+ *
+ * Full masked host Full unmasked host IP with/without CIDR
+ */
+ if ((match(user->GetFullHost(), maskptr)) || (match(user->GetFullRealHost(), maskptr)) || (match(mask, maskptr, true)))
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
/* Channel::PartUser
* remove a channel from a users record, and return the number of users left.
* Therefore, if this function returns 0 the caller should delete the Channel.
diff --git a/src/mode.cpp b/src/mode.cpp
index 83aff70cf..6805c348c 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -705,12 +705,12 @@ void ModeParser::CleanMask(std::string &mask)
std::string::size_type pos_of_pling = mask.find_first_of('!');
std::string::size_type pos_of_at = mask.find_first_of('@');
std::string::size_type pos_of_dot = mask.find_first_of('.');
- std::string::size_type pos_of_colon = mask.find_first_of(':'); /* Because ipv6 addresses are colon delimited */
+ std::string::size_type pos_of_colons = mask.find("::"); /* Because ipv6 addresses are colon delimited -- double so it treats extban as nick */
if ((pos_of_pling == std::string::npos) && (pos_of_at == std::string::npos))
{
- /* Just a nick, or just a host */
- if ((pos_of_dot == std::string::npos) && (pos_of_colon == std::string::npos))
+ /* Just a nick, or just a host - or clearly ipv6 (starting with :) */
+ if ((pos_of_dot == std::string::npos) && (pos_of_colons == std::string::npos) && mask[0] != ':')
{
/* It has no '.' in it, it must be a nick. */
mask.append("!*@*");
diff --git a/src/modules/m_foobar.cpp b/src/modules/m_foobar.cpp
index 4917dd501..d9254c435 100644
--- a/src/modules/m_foobar.cpp
+++ b/src/modules/m_foobar.cpp
@@ -35,8 +35,8 @@ class ModuleFoobar : public Module
// The constructor just makes a copy of the server class
- Implementation eventlist[] = { I_OnUserConnect, I_OnUserQuit, I_OnUserJoin, I_OnUserPart };
- ServerInstance->Modules->Attach(eventlist, this, 4);
+ Implementation eventlist[] = { I_OnUserConnect, I_OnUserQuit, I_OnUserJoin, I_OnUserPart, I_OnUserPreJoin };
+ ServerInstance->Modules->Attach(eventlist, this, 5);
}
virtual ~ModuleFoobar()
@@ -86,6 +86,13 @@ class ModuleFoobar : public Module
ServerInstance->Logs->Log("m_foobar",DEBUG,"Foobar: User "+b+" parted "+c);
}
+ virtual int OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs)
+ {
+ if (chan->IsExtBanned(user, 'n'))
+ return 1;
+
+ return 0;
+ }
};