]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Merge pull request #1337 from SaberUK/master+merge
authorPeter Powell <petpow@saberuk.com>
Wed, 12 Jul 2017 13:25:28 +0000 (14:25 +0100)
committerGitHub <noreply@github.com>
Wed, 12 Jul 2017 13:25:28 +0000 (14:25 +0100)
Merge v2.0.23 and v2.0.24 into master.

14 files changed:
docs/conf/modules.conf.example
include/base.h
make/calcdep.pl
src/coremods/core_who.cpp
src/modules/m_cgiirc.cpp
src/modules/m_cloaking.cpp
src/modules/m_dnsbl.cpp
src/modules/m_hostcycle.cpp
src/modules/m_httpd_stats.cpp
src/modules/m_override.cpp
src/modules/m_sasl.cpp
src/socketengines/socketengine_epoll.cpp
src/users.cpp
win/CMakeLists.txt

index 33da80c56a471b75c49e7eb0213f7ae1d18aa5e0..93e26059c73d812e4a64fb5f2675c4850f954381 100644 (file)
 #           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">                                 #
 #                                                                     #
 # 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.                                                    #
 #                                                                     #
 #
 #-#-#-#-#-#-#-#-#-# 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.      #
 # 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">
 
 #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
index c378afc1c9bc5fb8eedf135145bfdd3d26838968..d8781f7969a1f21f3b8d61b6eecff846cf2204e0 100644 (file)
@@ -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
         */
index 882e75f22ea9611172aeab133a7ea8936bec182e..99355efa40f1b9843781f0290dcd1c9c450a4b96 100755 (executable)
@@ -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
index 739c675a9d43010b7c46530f452617ce06f0d2c6..677a1eb6d2c796db9f09adcdfdb3bbe72370ae5f 100644 (file)
@@ -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);
index 09d6e5fdf50f22af94c121ec4dfdf4ff383f9376..5eba5ce354367e01c95430fbc13e707737c27ee5 100644 (file)
@@ -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;
                }
index 890c799f2b2b55d2e96b4c099db9bdc1163a9f75..5cedb5774fd3dd6ba2eba1f37cd1adfb8797b201 100644 (file)
@@ -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);
index 73ecd02a6c919af8907e5a7cf12498d5d5277fd9..7b0f061912a0e764ae38a1976fef03921987a70e 100644 (file)
@@ -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);
index b33c101efb83b9eca3e4ed3f477a3adf085cb302..621f06a279e53e715feaa36c58a053603fd0e93c 100644 (file)
@@ -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);
index 11fad4b1851a0e4b21ae537b25a8d979b02208af..62ae0c204bda86de042d7bdfc95298a6f1c22644 100644 (file)
@@ -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>";
index 9cfc3aed0e877b95c31be094afbeef490d1858b9..fd09dd6ec96178fb283b56c63ac9316f6e1d3347 100644 (file)
@@ -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;
index 2b247a198a138ebc6e7cd9943db59002a58b0599..9f7e1527bc78e6c4b46775efaca6b27b2cc412ad 100644 (file)
@@ -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
index a935d786b62a16f7df4d8e881a1926d833821fea..c442e340dcd46abd7d8b6fa93c0f22d0daacfd93 100644 (file)
@@ -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.
index bdcc9edd02bc0ffe70ee79897871644f51e7d2bc..d5493164483f4a2fa4c0dde41c04844c7cc907dc 100644 (file)
@@ -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);
 }
 
index 7682706965c1b2b9bfe9ca0b4770280dd85a6165..b5812b0c2d98714419ee713f053bcd3ea45d6591 100644 (file)
@@ -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")