# SQLite3 module: Allows other SQL modules to access SQLite3 #
# databases through a unified API. #
# This module is in extras. Re-run configure with: #
- # ./configure --enable-extras=m_sqlite.cpp
+ # ./configure --enable-extras=m_sqlite3.cpp
# and run make install, then uncomment this module to enable it. #
#
-#<module name="m_sqlite3.so">
+#<module name="sqlite3">
#
#-#-#-#-#-#-#-#-#-#-#-#- SQL CONFIGURATION -#-#-#-#-#-#-#-#-#-#-#-#-#
# #
--- /dev/null
- return InspIRCd::Match(user->GetIPString(), ip, ascii_case_insensitive_map);
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
+ * Copyright (C) 2009 Matt Smith <dz@inspircd.org>
+ * Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+#include "xline.h"
+#include "core_xline.h"
+
+CommandZline::CommandZline(Module* parent)
+ : Command(parent, "ZLINE", 1, 3)
+{
+ flags_needed = 'o';
+ syntax = "<ipmask> [<duration> :<reason>]";
+}
+
+CmdResult CommandZline::Handle (const std::vector<std::string>& parameters, User *user)
+{
+ std::string target = parameters[0];
+
+ if (parameters.size() >= 3)
+ {
+ if (target.find('!') != std::string::npos)
+ {
+ user->WriteNotice("*** You cannot include a nickname in a zline, a zline must ban only an IP mask");
+ return CMD_FAILURE;
+ }
+
+ User *u = ServerInstance->FindNick(target);
+
+ if ((u) && (u->registered == REG_ALL))
+ {
+ target = u->GetIPString();
+ }
+
+ const char* ipaddr = target.c_str();
+
+ if (strchr(ipaddr,'@'))
+ {
+ while (*ipaddr != '@')
+ ipaddr++;
+ ipaddr++;
+ }
+
+ IPMatcher matcher;
+ if (InsaneBan::MatchesEveryone(ipaddr, matcher, user, "Z", "ipmasks"))
+ return CMD_FAILURE;
+
+ unsigned long duration = InspIRCd::Duration(parameters[1]);
+ ZLine* zl = new ZLine(ServerInstance->Time(), duration, user->nick.c_str(), parameters[2].c_str(), ipaddr);
+ if (ServerInstance->XLines->AddLine(zl,user))
+ {
+ if (!duration)
+ {
+ ServerInstance->SNO->WriteToSnoMask('x',"%s added permanent Z-line for %s: %s", user->nick.c_str(), ipaddr, parameters[2].c_str());
+ }
+ else
+ {
+ time_t c_requires_crap = duration + ServerInstance->Time();
+ std::string timestr = InspIRCd::TimeString(c_requires_crap);
+ ServerInstance->SNO->WriteToSnoMask('x',"%s added timed Z-line for %s, expires on %s: %s",user->nick.c_str(),ipaddr,
+ timestr.c_str(), parameters[2].c_str());
+ }
+ ServerInstance->XLines->ApplyLines();
+ }
+ else
+ {
+ delete zl;
+ user->WriteNotice("*** Z-Line for " + std::string(ipaddr) + " already exists");
+ }
+ }
+ else
+ {
+ if (ServerInstance->XLines->DelLine(target.c_str(),"Z",user))
+ {
+ ServerInstance->SNO->WriteToSnoMask('x',"%s removed Z-line on %s",user->nick.c_str(),target.c_str());
+ }
+ else
+ {
+ user->WriteNotice("*** Z-Line " + target + " not found in list, try /stats Z.");
+ return CMD_FAILURE;
+ }
+ }
+
+ return CMD_SUCCESS;
+}
+
+bool CommandZline::IPMatcher::Check(User* user, const std::string& ip) const
+{
++ return InspIRCd::MatchCIDR(user->GetIPString(), ip, ascii_case_insensitive_map);
+}
--- /dev/null
- return ((InspIRCd::Match(user->MakeHost(), mask, ascii_case_insensitive_map)) ||
- (InspIRCd::Match(user->MakeHostIP(), mask, ascii_case_insensitive_map)));
+/*
+ * InspIRCd -- Internet Relay Chat Daemon
+ *
+ * Copyright (C) 2014 Attila Molnar <attilamolnar@hush.com>
+ *
+ * This file is part of InspIRCd. InspIRCd is free software: you can
+ * redistribute it and/or modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation, version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "inspircd.h"
+#include "xline.h"
+#include "core_xline.h"
+
+bool InsaneBan::MatchesEveryone(const std::string& mask, MatcherBase& test, User* user, const char* bantype, const char* confkey)
+{
+ ConfigTag* insane = ServerInstance->Config->ConfValue("insane");
+
+ if (insane->getBool(confkey))
+ return false;
+
+ float itrigger = insane->getFloat("trigger", 95.5);
+
+ long matches = test.Run(mask);
+
+ if (!matches)
+ return false;
+
+ float percent = ((float)matches / (float)ServerInstance->Users->GetUsers().size()) * 100;
+ if (percent > itrigger)
+ {
+ ServerInstance->SNO->WriteToSnoMask('a', "\2WARNING\2: %s tried to set a %s-line mask of %s, which covers %.2f%% of the network!", user->nick.c_str(), bantype, mask.c_str(), percent);
+ return true;
+ }
+ return false;
+}
+
+bool InsaneBan::IPHostMatcher::Check(User* user, const std::string& mask) const
+{
++ return ((InspIRCd::MatchCIDR(user->MakeHost(), mask, ascii_case_insensitive_map)) ||
++ (InspIRCd::MatchCIDR(user->MakeHostIP(), mask, ascii_case_insensitive_map)));
+}
+
+class CoreModXLine : public Module
+{
+ CommandEline cmdeline;
+ CommandGline cmdgline;
+ CommandKline cmdkline;
+ CommandQline cmdqline;
+ CommandZline cmdzline;
+
+ public:
+ CoreModXLine()
+ : cmdeline(this), cmdgline(this), cmdkline(this), cmdqline(this), cmdzline(this)
+ {
+ }
+
+ ModResult OnUserPreNick(LocalUser* user, const std::string& newnick) CXX11_OVERRIDE
+ {
+ // Check Q-Lines (for local nick changes only, remote servers have our Q-Lines to enforce themselves)
+
+ XLine* xline = ServerInstance->XLines->MatchesLine("Q", newnick);
+ if (!xline)
+ return MOD_RES_PASSTHRU; // No match
+
+ // A Q-Line matched the new nick, tell opers if the user is registered
+ if (user->registered == REG_ALL)
+ {
+ ServerInstance->SNO->WriteGlobalSno('a', "Q-Lined nickname %s from %s: %s",
+ newnick.c_str(), user->GetFullRealHost().c_str(), xline->reason.c_str());
+ }
+
+ // Send a numeric because if we deny then the core doesn't reply anything
+ user->WriteNumeric(ERR_ERRONEUSNICKNAME, newnick, InspIRCd::Format("Invalid nickname: %s", xline->reason.c_str()));
+ return MOD_RES_DENY;
+ }
+
+ Version GetVersion() CXX11_OVERRIDE
+ {
+ return Version("Provides the ELINE, GLINE, KLINE, QLINE, and ZLINE commands", VF_VENDOR|VF_CORE);
+ }
+};
+
+MODULE_INIT(CoreModXLine)
const char* srcver = (char*)dlsym(h, "inspircd_src_version");
if (srcver)
return srcver;
- return "Unversioned module";
+ return "";
}
- #ifdef _WIN32
void DLLManager::RetrieveLastError()
{
+ #if defined _WIN32
char errmsg[500];
DWORD dwErrorCode = GetLastError();
if (FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, dwErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)errmsg, _countof(errmsg), NULL) == 0)
OLDTIME = TIME.tv_sec;
if ((TIME.tv_sec % 3600) == 0)
- this->RehashUsersAndChans();
- FOREACH_MOD(I_OnGarbageCollect, OnGarbageCollect());
+ {
- Timers->TickTimers(TIME.tv_sec);
- this->DoBackgroundUserStuff();
+ FOREACH_MOD(OnGarbageCollect, ());
+
++ // HACK: ELines are not expired properly at the moment but it can't be fixed as
++ // the 2.0 XLine system is a spaghetti nightmare. Instead we skip over expired
++ // ELines in XLineManager::CheckELines() and expire them here instead.
++ XLines->GetAll("E");
+ }
+
+ Timers.TickTimers(TIME.tv_sec);
+ Users->DoBackgroundUserStuff();
if ((TIME.tv_sec % 5) == 0)
{
realhost.set(user, user->host);
realip.set(user, user->GetIPString());
- bool host_ok = (parameters[2].length() < 64) && (parameters[2].find_first_not_of("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-") == std::string::npos);
+ // Check if we're happy with the provided hostname. If it's problematic then make sure we won't set a host later, just the IP
- bool host_ok = (parameters[2].length() <= ServerInstance->Config->Limits.MaxHost);
++ bool host_ok = (parameters[2].length() <= ServerInstance->Config->Limits.MaxHost) && (parameters[2].find_first_not_of("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-") == std::string::npos);
const std::string& newhost = (host_ok ? parameters[2] : parameters[3]);
if (notify)
if ((target_type == TYPE_CHANNEL) && (IS_LOCAL(user)))
{
Channel* c = (Channel*)dest;
- if ((text.empty()) || (text[0] != '\001') || (!strncmp(text.c_str(),"\1ACTION ",8)))
+ if ((text.empty()) || (text[0] != '\001') || (!strncmp(text.c_str(),"\1ACTION ", 8)) || (text == "\1ACTION\1") || (text == "\1ACTION"))
return MOD_RES_PASSTHRU;
- ModResult res = ServerInstance->OnCheckExemption(user,c,"noctcp");
+ ModResult res;
+ FIRST_MOD_RESULT_CUSTOM(exemptionprov, CheckExemption::EventListener, OnCheckExemption, res, (user, c, "noctcp"));
if (res == MOD_RES_ALLOW)
return MOD_RES_PASSTHRU;
SaslResult result;
bool state_announced;
- /* taken from m_services_account */
- static bool ReadCGIIRCExt(const char* extname, User* user, std::string& out)
- {
- ExtensionItem* wiext = ServerInstance->Extensions.GetItem(extname);
- if (!wiext)
- return false;
-
- if (wiext->creator->ModuleSourceFile != "m_cgiirc.so")
- return false;
-
- StringExtItem* stringext = static_cast<StringExtItem*>(wiext);
- std::string* addr = stringext->get(user);
- if (!addr)
- return false;
-
- out = *addr;
- return true;
- }
-
-
void SendHostIP()
{
- std::string host, ip;
-
- if (!ReadCGIIRCExt("cgiirc_webirc_hostname", user, host))
- {
- host = user->host;
- }
- if (!ReadCGIIRCExt("cgiirc_webirc_ip", user, ip))
- {
- ip = user->GetIPString();
- }
- else
- {
- /* IP addresses starting with a : on irc are a Bad Thing (tm) */
- if (ip.c_str()[0] == ':')
- ip.insert(ip.begin(),1,'0');
- }
-
parameterlist params;
- params.push_back(sasl_target);
- params.push_back("SASL");
- params.push_back(user->uuid);
- params.push_back("*");
- params.push_back("H");
- params.push_back(host);
- params.push_back(ip);
-
- LocalUser* lu = IS_LOCAL(user);
- if (lu)
- {
- // NOTE: SaslAuthenticator instances are only created for local
- // users so this parameter will always be appended.
- SocketCertificateRequest req(&lu->eh, ServerInstance->Modules->Find("m_sasl.so"));
- params.push_back(req.cert ? "S" : "P");
- }
+ params.push_back(user->host);
+ params.push_back(user->GetIPString());
++ params.push_back(SSLIOHook::IsSSL(&user->eh) ? "S" : "P");
- SendSASL(params);
+ SendSASL(user, "*", 'H', params);
}
public:
TimedBanList.push_back(T);
// If halfop is loaded, send notice to halfops and above, otherwise send to ops and above
-- ModeHandler* mh = ServerInstance->Modes->FindMode('h', MODETYPE_CHANNEL);
- char pfxchar = (mh && mh->name == "halfop") ? '%' : '@';
++ PrefixMode* mh = ServerInstance->Modes->FindPrefixMode('h');
+ char pfxchar = (mh && mh->name == "halfop") ? mh->GetPrefix() : '@';
channel->WriteAllExcept(ServerInstance->FakeClient, true, pfxchar, tmp, "NOTICE %s :%s added a timed ban on %s lasting for %ld seconds.", channel->name.c_str(), user->nick.c_str(), mask.c_str(), duration);
return CMD_SUCCESS;
if (ELines.empty())
return;
- for (LocalUserList::const_iterator u2 = ServerInstance->Users->local_users.begin(); u2 != ServerInstance->Users->local_users.end(); u2++)
+ const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers();
+ for (UserManager::LocalList::const_iterator u2 = list.begin(); u2 != list.end(); u2++)
{
- User* u = (User*)(*u2);
+ LocalUser* u = *u2;
+ u->exempt = false;
/* This uses safe iteration to ensure that if a line expires here, it doenst trash the iterator */
LookupIter safei;