diff options
-rw-r--r-- | docs/conf/modules.conf.example | 19 | ||||
-rw-r--r-- | include/base.h | 2 | ||||
-rwxr-xr-x | make/calcdep.pl | 2 | ||||
-rw-r--r-- | src/coremods/core_who.cpp | 11 | ||||
-rw-r--r-- | src/modules/m_cgiirc.cpp | 10 | ||||
-rw-r--r-- | src/modules/m_cloaking.cpp | 9 | ||||
-rw-r--r-- | src/modules/m_dnsbl.cpp | 8 | ||||
-rw-r--r-- | src/modules/m_hostcycle.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_httpd_stats.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_override.cpp | 3 | ||||
-rw-r--r-- | src/modules/m_sasl.cpp | 61 | ||||
-rw-r--r-- | src/socketengines/socketengine_epoll.cpp | 10 | ||||
-rw-r--r-- | src/users.cpp | 4 | ||||
-rw-r--r-- | win/CMakeLists.txt | 1 |
14 files changed, 121 insertions, 23 deletions
diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index 33da80c56..93e26059c 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -1059,7 +1059,8 @@ # allowpattern="Guest* Bot*" # # killreason="Access denied" # # verbose="yes" # -# host="$uid.$ou.inspircd.org"> # +# host="$uid.$ou.inspircd.org" # +# useusername="no"> # # # # <ldapwhitelist cidr="10.42.0.0/16"> # # # @@ -1076,6 +1077,10 @@ # regardless of if they have an account, for example guest and bot # # users. # # # +# The useusername setting chooses whether the user's username or # +# nickname is used when locating a user account, if a username isn't # +# provided in PASS. # +# # # Killreason indicates the QUIT reason to give to users if they fail # # to authenticate. # # # @@ -1682,13 +1687,12 @@ # #-#-#-#-#-#-#-#-#-# SECURELIST CONFIGURATION -#-#-#-#-#-#-#-#-#-#-#-#-# # # -# Securelist can be harmful to some IRC search engines such as # -# netsplit.de and searchirc.com. To prevent securelist blocking these # -# sites from listing, define exception tags as shown below: # -#<securehost exception="*@*.searchirc.org"> +# Securelist can be harmful to some IRC search engines. To prevent # +# securelist blocking these sites from listing, define exception tags # +# as shown below: # #<securehost exception="*@*.netsplit.de"> -#<securehost exception="*@echo940.server4you.de"> #<securehost exception="*@*.ircdriven.com"> +#<securehost exception="*@*.irc-source.com"> # # # Define the following variable to change how long a user must wait # # before issuing a LIST. If not defined, defaults to 60 seconds. # @@ -1826,7 +1830,8 @@ # SSL channel mode module: Adds support for SSL-only channels via # channel mode +z and the 'z' extban which matches SSL client # certificate fingerprints. -# Does not do anything useful without a working SSL module (see below). +# Does not do anything useful without a working SSL module and the +# sslinfo module (see below). #<module name="sslmodes"> #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# diff --git a/include/base.h b/include/base.h index c378afc1c..d8781f796 100644 --- a/include/base.h +++ b/include/base.h @@ -202,7 +202,7 @@ class CoreExport CoreException : public std::exception * Actually no, it does nothing. Never mind. * @throws Nothing! */ - virtual ~CoreException() throw() {}; + virtual ~CoreException() throw() {} /** Returns the reason for the exception. * @return Human readable description of the error */ diff --git a/make/calcdep.pl b/make/calcdep.pl index 882e75f22..99355efa4 100755 --- a/make/calcdep.pl +++ b/make/calcdep.pl @@ -166,7 +166,7 @@ END obj/ld-extra.cmd: $core_src \@\$(SOURCEPATH)/make/unit-cc.pl gen-ld \$\@ \$^ \$> -bin/inspircd: obj/ld-extra.cmd $core_mk +bin/inspircd: $core_mk obj/ld-extra.cmd \@\$(SOURCEPATH)/make/unit-cc.pl static-ld \$\@ \$^ \$> inspircd: bin/inspircd diff --git a/src/coremods/core_who.cpp b/src/coremods/core_who.cpp index 739c675a9..677a1eb6d 100644 --- a/src/coremods/core_who.cpp +++ b/src/coremods/core_who.cpp @@ -38,14 +38,18 @@ class CommandWho : public Command bool opt_time; ChanModeReference secretmode; ChanModeReference privatemode; + UserModeReference hidechansmode; UserModeReference invisiblemode; - Membership* get_first_visible_channel(User* u) + Membership* get_first_visible_channel(User* source, User* u) { for (User::ChanList::iterator i = u->chans.begin(); i != u->chans.end(); ++i) { Membership* memb = *i; - if (!memb->chan->IsModeSet(secretmode)) + + /* XXX move the +I check into m_hidechans */ + bool has_modes = memb->chan->IsModeSet(secretmode) || memb->chan->IsModeSet(privatemode) || u->IsModeSet(hidechansmode); + if (source == u || !has_modes || memb->chan->HasUser(source)) return memb; } return NULL; @@ -58,6 +62,7 @@ class CommandWho : public Command : Command(parent, "WHO", 1) , secretmode(parent, "secret") , privatemode(parent, "private") + , hidechansmode(parent, "hidechans") , invisiblemode(parent, "invisible") { syntax = "<server>|<nickname>|<channel>|<realname>|<host>|0 [ohurmMiaplf]"; @@ -189,7 +194,7 @@ bool CommandWho::CanView(Channel* chan, User* user) void CommandWho::SendWhoLine(User* user, const std::vector<std::string>& parms, Membership* memb, User* u, std::vector<Numeric::Numeric>& whoresults) { if (!memb) - memb = get_first_visible_channel(u); + memb = get_first_visible_channel(user, u); Numeric::Numeric wholine(RPL_WHOREPLY); wholine.push(memb ? memb->chan->name : "*").push(u->ident); diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp index 09d6e5fdf..5eba5ce35 100644 --- a/src/modules/m_cgiirc.cpp +++ b/src/modules/m_cgiirc.cpp @@ -77,6 +77,7 @@ class CommandWebirc : public Command realhost("cgiirc_realhost", ExtensionItem::EXT_USER, Creator) , realip("cgiirc_realip", ExtensionItem::EXT_USER, Creator) { + allow_empty_last_param = false; works_before_reg = true; this->syntax = "password client hostname ip"; } @@ -85,6 +86,14 @@ class CommandWebirc : public Command if(user->registered == REG_ALL) return CMD_FAILURE; + irc::sockets::sockaddrs ipaddr; + if (!irc::sockets::aptosa(parameters[3], 0, ipaddr)) + { + IS_LOCAL(user)->CommandFloodPenalty += 5000; + ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s tried to use WEBIRC but gave an invalid IP address.", user->GetFullRealHost().c_str()); + return CMD_FAILURE; + } + for(CGIHostlist::iterator iter = Hosts.begin(); iter != Hosts.end(); iter++) { if(InspIRCd::Match(user->host, iter->hostmask, ascii_case_insensitive_map) || InspIRCd::MatchCIDR(user->GetIPString(), iter->hostmask, ascii_case_insensitive_map)) @@ -112,6 +121,7 @@ class CommandWebirc : public Command } } + IS_LOCAL(user)->CommandFloodPenalty += 5000; ServerInstance->SNO->WriteGlobalSno('w', "Connecting user %s tried to use WEBIRC, but didn't match any configured webirc blocks.", user->GetFullRealHost().c_str()); return CMD_FAILURE; } diff --git a/src/modules/m_cloaking.cpp b/src/modules/m_cloaking.cpp index 890c799f2..5cedb5774 100644 --- a/src/modules/m_cloaking.cpp +++ b/src/modules/m_cloaking.cpp @@ -89,6 +89,10 @@ class CloakUser : public ModeHandler if (adding) { + // assume this is more correct + if (user->registered != REG_ALL && user->host != user->dhost) + return MODEACTION_DENY; + std::string* cloak = ext.get(user); if (!cloak) @@ -343,11 +347,14 @@ class ModuleCloaking : public Module { std::string chost; + irc::sockets::sockaddrs hostip; + bool host_is_ip = irc::sockets::aptosa(host, ip.port(), hostip) && hostip == ip; + switch (mode) { case MODE_HALF_CLOAK: { - if (ipstr != host) + if (!host_is_ip) chost = prefix + SegmentCloak(host, 1, 6) + LastTwoDomainParts(host); if (chost.empty() || chost.length() > 50) chost = SegmentIP(ip, false); diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp index 73ecd02a6..7b0f06191 100644 --- a/src/modules/m_dnsbl.cpp +++ b/src/modules/m_dnsbl.cpp @@ -70,6 +70,14 @@ class DNSBLResolver : public DNS::Request if (!ans_record) return; + // All replies should be in 127.0.0.0/8 + if (ans_record->rdata.compare(0, 4, "127.") != 0) + { + ServerInstance->SNO->WriteGlobalSno('a', "DNSBL: %s returned address outside of acceptable subnet 127.0.0.0/8: %s", ConfEntry->domain.c_str(), ans_record->rdata.c_str()); + ConfEntry->stats_misses++; + return; + } + int i = countExt.get(them); if (i) countExt.set(them, i - 1); diff --git a/src/modules/m_hostcycle.cpp b/src/modules/m_hostcycle.cpp index b33c101ef..621f06a27 100644 --- a/src/modules/m_hostcycle.cpp +++ b/src/modules/m_hostcycle.cpp @@ -40,6 +40,8 @@ class ModuleHostCycle : public Module FOREACH_MOD(OnBuildNeighborList, (user, include_chans, exceptions)); + // Users shouldn't see themselves quitting when host cycling + exceptions.erase(user); for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i) { LocalUser* u = IS_LOCAL(i->first); diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp index 11fad4b18..62ae0c204 100644 --- a/src/modules/m_httpd_stats.cpp +++ b/src/modules/m_httpd_stats.cpp @@ -211,7 +211,7 @@ class ModuleHttpStats : public Module, public HTTPRequestEventListener data << "<server>"; data << "<servername>" << b->servername << "</servername>"; data << "<parentname>" << b->parentname << "</parentname>"; - data << "<gecos>" << b->gecos << "</gecos>"; + data << "<gecos>" << Sanitize(b->gecos) << "</gecos>"; data << "<usercount>" << b->usercount << "</usercount>"; // This is currently not implemented, so, commented out. // data << "<opercount>" << b->opercount << "</opercount>"; diff --git a/src/modules/m_override.cpp b/src/modules/m_override.cpp index 9cfc3aed0..fd09dd6ec 100644 --- a/src/modules/m_override.cpp +++ b/src/modules/m_override.cpp @@ -121,7 +121,8 @@ class ModuleOverride : public Module if (source->IsOper() && CanOverride(source,"KICK")) { // If the kicker's status is less than the target's, or the kicker's status is less than or equal to voice - if ((memb->chan->GetPrefixValue(source) < memb->getRank()) || (memb->chan->GetPrefixValue(source) <= VOICE_VALUE)) + if ((memb->chan->GetPrefixValue(source) < memb->getRank()) || (memb->chan->GetPrefixValue(source) <= VOICE_VALUE) || + (memb->chan->GetPrefixValue(source) == HALFOP_VALUE && memb->getRank() == HALFOP_VALUE)) { ServerInstance->SNO->WriteGlobalSno('v',source->nick+" used oper override to kick "+memb->user->nick+" on "+memb->chan->name+" ("+reason+")"); return MOD_RES_ALLOW; diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp index 2b247a198..9f7e1527b 100644 --- a/src/modules/m_sasl.cpp +++ b/src/modules/m_sasl.cpp @@ -153,10 +153,63 @@ class SaslAuthenticator 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); + + SendSASL(params); + } + public: SaslAuthenticator(User* user_, const std::string& method) : user(user_), state(SASL_INIT), state_announced(false) { + SendHostIP(); + parameterlist params; params.push_back(user->uuid); params.push_back("*"); @@ -287,6 +340,7 @@ class CommandAuthenticate : public Command : Command(Creator, "AUTHENTICATE", 1), authExt(ext), cap(Cap) { works_before_reg = true; + allow_empty_last_param = false; } CmdResult Handle (const std::vector<std::string>& parameters, User *user) @@ -295,6 +349,9 @@ class CommandAuthenticate : public Command if (!cap.get(user)) return CMD_FAILURE; + if (parameters[0].find(' ') != std::string::npos || parameters[0][0] == ':') + return CMD_FAILURE; + SaslAuthenticator *sasl = authExt.get(user); if (!sasl) authExt.set(user, new SaslAuthenticator(user, parameters[0])); @@ -378,7 +435,7 @@ class ModuleSASL : public Module servertracker.Reset(); } - ModResult OnUserRegister(LocalUser *user) CXX11_OVERRIDE + void OnUserConnect(LocalUser *user) CXX11_OVERRIDE { SaslAuthenticator *sasl_ = authExt.get(user); if (sasl_) @@ -386,8 +443,6 @@ class ModuleSASL : public Module sasl_->Abort(); authExt.unset(user); } - - return MOD_RES_PASSTHRU; } void OnDecodeMetaData(Extensible* target, const std::string& extname, const std::string& extdata) CXX11_OVERRIDE diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp index a935d786b..c442e340d 100644 --- a/src/socketengines/socketengine_epoll.cpp +++ b/src/socketengines/socketengine_epoll.cpp @@ -22,7 +22,7 @@ #include "exitcodes.h" #include <sys/epoll.h> -#include <ulimit.h> +#include <sys/resource.h> #include <iostream> /** A specialisation of the SocketEngine class, designed to use linux 2.6 epoll(). @@ -38,8 +38,12 @@ namespace void SocketEngine::Init() { - // MAX_DESCRIPTORS is mainly used for display purposes, no problem if ulimit() fails and returns a negative number - MAX_DESCRIPTORS = ulimit(4, 0); + // MAX_DESCRIPTORS is mainly used for display purposes, no problem if getrlimit() fails + struct rlimit limit; + if (!getrlimit(RLIMIT_NOFILE, &limit)) + { + MAX_DESCRIPTORS = limit.rlim_cur; + } // 128 is not a maximum, just a hint at the eventual number of sockets that may be polled, // and it is completely ignored by 2.6.8 and later kernels, except it must be larger than zero. diff --git a/src/users.cpp b/src/users.cpp index bdcc9edd0..d54931644 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -588,6 +588,7 @@ void LocalUser::FullConnect() void User::InvalidateCache() { /* Invalidate cache */ + cachedip.clear(); cached_fullhost.clear(); cached_hostip.clear(); cached_makehost.clear(); @@ -709,8 +710,7 @@ irc::sockets::cidr_mask User::GetCIDRMask() bool User::SetClientIP(const char* sip, bool recheck_eline) { - cachedip.clear(); - cached_hostip.clear(); + this->InvalidateCache(); return irc::sockets::aptosa(sip, 0, client_sa); } diff --git a/win/CMakeLists.txt b/win/CMakeLists.txt index 768270696..b5812b0c2 100644 --- a/win/CMakeLists.txt +++ b/win/CMakeLists.txt @@ -89,6 +89,7 @@ file(MAKE_DIRECTORY ${LOG_DIR}) install(DIRECTORY ${LOG_DIR} DESTINATION .) if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") + set(CMAKE_INSTALL_SYSTEM_RUNTIME_DESTINATION ".") # place runtime libraries next to InspIRCd binary include(InstallRequiredSystemLibraries) set(CPACK_PACKAGE_NAME "InspIRCd IRC Daemon") |