diff options
-rw-r--r-- | .travis.yml | 15 | ||||
-rwxr-xr-x | configure | 28 | ||||
-rw-r--r-- | docs/conf/modules.conf.example | 29 | ||||
-rw-r--r-- | include/base.h | 2 | ||||
-rwxr-xr-x | make/calcdep.pl | 2 | ||||
-rwxr-xr-x | modulemanager | 1 | ||||
-rw-r--r-- | src/commands/cmd_who.cpp | 8 | ||||
-rw-r--r-- | src/modules/extra/m_ldapauth.cpp | 47 | ||||
-rw-r--r-- | src/modules/m_cgiirc.cpp | 10 | ||||
-rw-r--r-- | src/modules/m_cloaking.cpp | 7 | ||||
-rw-r--r-- | src/modules/m_dnsbl.cpp | 9 | ||||
-rw-r--r-- | src/modules/m_httpd_stats.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_spanningtree/protocolinterface.cpp | 15 | ||||
-rw-r--r-- | src/socketengines/socketengine_epoll.cpp | 9 | ||||
-rw-r--r-- | src/users.cpp | 2 | ||||
-rwxr-xr-x | tools/travis-ci.sh | 5 | ||||
-rw-r--r-- | win/CMakeLists.txt | 1 |
17 files changed, 113 insertions, 79 deletions
diff --git a/.travis.yml b/.travis.yml index 631802526..bb82add9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,12 +1,13 @@ compiler: - - "clang" - - "gcc" -language: "cpp" + - clang + - gcc +dist: trusty +env: + - PURE_STATIC=1 + - +language: cpp notifications: email: false -os: - - "linux" - - "osx" script: - - "sh ./tools/travis-ci.sh" + - sh ./tools/travis-ci.sh sudo: required @@ -28,6 +28,7 @@ BEGIN { require 5.8.0; + push @INC, '.'; } use strict; @@ -268,10 +269,9 @@ if (defined $opt_cc) { $config{CC} = $opt_cc; } -our $exec = $config{CC} . " -dumpversion | cut -c 1"; -chomp($config{GCCVER} = `$exec`); # Major GCC Version -$exec = $config{CC} . " -dumpversion | cut -c 3"; -chomp($config{GCCMINOR} = `$exec`); +`$config{CC} -dumpversion` =~ /^(\d+)(?:\.(\d+))?/; +$config{GCCVER} = defined $1 ? $1 : ''; +$config{GCCMINOR} = defined $2 ? $2 : '0'; $config{MAXBUF} = "512"; # Max buffer size if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)(?:[a-z])?(?:\-[a-z][0-9])?/) { @@ -347,10 +347,9 @@ print ($cache_loaded ? "found\n" : "not found\n"); $config{SYSTEM} = lc $^O; print "Checking operating system version... $config{SYSTEM}\n"; -$exec = $config{CC} . " -dumpversion | cut -c 1"; -chomp($config{GCCVER} = `$exec`); # Major GCC Version -$exec = $config{CC} . " -dumpversion | cut -c 3"; -chomp($config{GCCMINOR} = `$exec`); +`$config{CC} -dumpversion` =~ /^(\d+)(?:\.(\d+))?/; +$config{GCCVER} = defined $1 ? $1 : ''; +$config{GCCMINOR} = defined $2 ? $2 : '0'; printf "Checking if stdint.h exists... "; $config{HAS_STDINT} = test_compile('stdint'); @@ -488,8 +487,9 @@ should NOT be used. You should probably specify a newer compiler.\n\n"; } chomp(my $foo = `$config{CC} -dumpversion | cut -c 1`); if ($foo ne "") { - chomp($config{GCCVER} = `$config{CC} -dumpversion | cut -c 1`); # we must redo these if we change compilers - chomp($config{GCCMINOR} = `$config{CC} -dumpversion | cut -c 3`); + `$config{CC} -dumpversion` =~ /^(\d+)(?:\.(\d+))?/; + $config{GCCVER} = defined $1 ? $1 : ''; + $config{GCCMINOR} = defined $2 ? $2 : '0'; print "Queried compiler: \e[1;32m$config{CC}\e[0m (version \e[1;32m$config{GCCVER}.$config{GCCMINOR}\e[0m)\n"; if ($config{GCCVER} < 3) { print "\e[1;32mGCC 2.x WILL NOT WORK!\e[0m. Let's try that again, shall we?\n"; @@ -839,8 +839,8 @@ sub writefiles { open(FILEHANDLE, ">include/inspircd_config.h.tmp"); print FILEHANDLE <<EOF; /* Auto generated by configure, do not modify! */ -#ifndef __CONFIGURATION_AUTO__ -#define __CONFIGURATION_AUTO__ +#ifndef INSPIRCD_CONFIG_H +#define INSPIRCD_CONFIG_H /* this is for windows support. */ #define CoreExport /**/ @@ -876,6 +876,10 @@ print FILEHANDLE "#define MAXBUF " . ($config{MAXBUF}+2) . "\n"; } if ($config{OSNAME} !~ /DARWIN/i) { print FILEHANDLE "#define HAS_CLOCK_GETTIME\n"; + } else { + print FILEHANDLE "#ifdef MAC_OS_X_VERSION_10_12\n"; + print FILEHANDLE "# define HAS_CLOCK_GETTIME\n"; + print FILEHANDLE "#endif\n"; } my $use_hiperf = 0; if (($has_kqueue) && ($config{USE_KQUEUE} eq "y")) { diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index 97d69da90..003b4d04b 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -421,6 +421,9 @@ #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Chanprotect module: Gives +q and +a channel modes. +# +# IMPORTANT: This module has been removed in the next major version of +# InspIRCd. You should use m_customprefix instead. #<module name="m_chanprotect.so"> <chanprotect @@ -519,6 +522,10 @@ # key3, key4; the values must be less than 0x80000000 and should be # # picked at random. Prefix is mandatory, will default to network name # # if not specified, and will always have a "-" appended. # +# # +# IMPORTANT: The compat-host and compat-ip modes have been removed in # +# the next major version of InspIRCd. You should ONLY use them if you # +# need backwards compatibility with InspIRCd 1.2. # # #<cloak mode="half" # key="secret" @@ -824,6 +831,9 @@ #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Halfop module: Provides the +h (halfops) channel status mode. +# +# IMPORTANT: This module has been removed in the next major version of +# InspIRCd. You should use m_customprefix instead. #<module name="m_halfop.so"> #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# @@ -999,7 +1009,8 @@ # binddn="cn=Manager,dc=brainbox,dc=cc" # # bindauth="mysecretpass" # # verbose="yes" # -# host="$uid.$ou.inspircd.org"> # +# host="$uid.$ou.inspircd.org" # +# useusername="no"> # # # # <ldapwhitelist cidr="10.42.0.0/16"> # # # @@ -1011,6 +1022,10 @@ # The attribute value indicates the attribute which is used to locate # # a user account by name. On POSIX systems this is usually 'uid'. # # # +# 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. # +# # # The server parameter indicates the LDAP server to connect to. The # # ldap:// style scheme before the hostname proper is MANDATORY. # # # @@ -1584,13 +1599,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. # @@ -1687,7 +1701,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 +# m_sslinfo module (see below). #<module name="m_sslmodes.so"> #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# diff --git a/include/base.h b/include/base.h index 0a4456f3a..19222a6f5 100644 --- a/include/base.h +++ b/include/base.h @@ -201,7 +201,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. * The module should probably put something informative here as the user will see this upon failure. */ diff --git a/make/calcdep.pl b/make/calcdep.pl index 4a759a24a..49506dd3b 100755 --- a/make/calcdep.pl +++ b/make/calcdep.pl @@ -160,7 +160,7 @@ END obj/ld-extra.cmd: $core_src \@\$(SOURCEPATH)/make/unit-cc.pl gen-ld\$(VERBOSE) \$\@ \$^ \$> -bin/inspircd: obj/ld-extra.cmd $core_mk +bin/inspircd: $core_mk obj/ld-extra.cmd \@\$(SOURCEPATH)/make/unit-cc.pl static-ld\$(VERBOSE) \$\@ \$^ \$> inspircd: bin/inspircd diff --git a/modulemanager b/modulemanager index af5bf113c..b107f2c1f 100755 --- a/modulemanager +++ b/modulemanager @@ -25,6 +25,7 @@ use warnings FATAL => qw(all); use make::configure; BEGIN { + push @INC, '.'; unless (module_installed("LWP::Simple")) { die "Your system is missing the LWP::Simple Perl module!"; } diff --git a/src/commands/cmd_who.cpp b/src/commands/cmd_who.cpp index 90c26a974..8438f8cdd 100644 --- a/src/commands/cmd_who.cpp +++ b/src/commands/cmd_who.cpp @@ -58,13 +58,15 @@ class CommandWho : public Command }; -static Channel* get_first_visible_channel(User *u) +static Channel* get_first_visible_channel(User *source, User *u) { UCListIter i = u->chans.begin(); while (i != u->chans.end()) { Channel* c = *i++; - if (!c->IsModeSet('s')) + + /* XXX move the +I check into m_hidechans */ + if (source == u || !(c->IsModeSet('s') || c->IsModeSet('p') || u->IsModeSet('I')) || c->HasUser(source)) return c; } return NULL; @@ -189,7 +191,7 @@ bool CommandWho::CanView(Channel* chan, User* user) void CommandWho::SendWhoLine(User* user, const std::vector<std::string>& parms, const std::string &initial, Channel* ch, User* u, std::vector<std::string> &whoresults) { if (!ch) - ch = get_first_visible_channel(u); + ch = get_first_visible_channel(user, u); std::string wholine = initial + (ch ? ch->name : "*") + " " + u->ident + " " + (opt_showrealhost ? u->host : u->dhost) + " "; diff --git a/src/modules/extra/m_ldapauth.cpp b/src/modules/extra/m_ldapauth.cpp index 6c765fb2e..405bab082 100644 --- a/src/modules/extra/m_ldapauth.cpp +++ b/src/modules/extra/m_ldapauth.cpp @@ -310,36 +310,25 @@ public: } RAIILDAPMessage msg; - std::string what = (attribute + "=" + (useusername ? user->ident : user->nick)); - if ((res = ldap_search_ext_s(conn, base.c_str(), searchscope, what.c_str(), NULL, 0, NULL, NULL, NULL, 0, &msg)) != LDAP_SUCCESS) + std::string what; + std::string::size_type pos = user->password.find(':'); + // If a username is provided in PASS, use it, othewrise user their nick or ident + if (pos != std::string::npos) { - // Do a second search, based on password, if it contains a : - // That is, PASS <user>:<password> will work. - size_t pos = user->password.find(":"); - if (pos != std::string::npos) - { - // manpage says we must deallocate regardless of success or failure - // since we're about to do another query (and reset msg), first - // free the old one. - msg.dealloc(); - - std::string cutpassword = user->password.substr(0, pos); - res = ldap_search_ext_s(conn, base.c_str(), searchscope, cutpassword.c_str(), NULL, 0, NULL, NULL, NULL, 0, &msg); - - if (res == LDAP_SUCCESS) - { - // Trim the user: prefix, leaving just 'pass' for later password check - user->password = user->password.substr(pos + 1); - } - } + what = (attribute + "=" + user->password.substr(0, pos)); - // It may have found based on user:pass check above. - if (res != LDAP_SUCCESS) - { - if (verbose) - ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (LDAP search failed: %s)", user->GetFullRealHost().c_str(), ldap_err2string(res)); - return false; - } + // Trim the user: prefix, leaving just 'pass' for later password check + user->password = user->password.substr(pos + 1); + } + else + { + what = (attribute + "=" + (useusername ? user->ident : user->nick)); + } + if ((res = ldap_search_ext_s(conn, base.c_str(), searchscope, what.c_str(), NULL, 0, NULL, NULL, NULL, 0, &msg)) != LDAP_SUCCESS) + { + if (verbose) + ServerInstance->SNO->WriteToSnoMask('c', "Forbidden connection from %s (LDAP search failed: %s)", user->GetFullRealHost().c_str(), ldap_err2string(res)); + return false; } if (ldap_count_entries(conn, msg) > 1) { @@ -404,7 +393,7 @@ public: std::string dnPart; while (stream.GetToken(dnPart)) { - std::string::size_type pos = dnPart.find('='); + pos = dnPart.find('='); if (pos == std::string::npos) // malformed continue; diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp index cce2e7855..09f6a4659 100644 --- a/src/modules/m_cgiirc.cpp +++ b/src/modules/m_cgiirc.cpp @@ -73,6 +73,7 @@ class CommandWebirc : public Command realhost("cgiirc_realhost", Creator), realip("cgiirc_realip", Creator), webirc_hostname("cgiirc_webirc_hostname", Creator), webirc_ip("cgiirc_webirc_ip", Creator) { + allow_empty_last_param = false; works_before_reg = true; this->syntax = "password client hostname ip"; } @@ -81,6 +82,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)) @@ -108,6 +117,7 @@ class CommandWebirc : public Command } } + IS_LOCAL(user)->CommandFloodPenalty += 5000; ServerInstance->SNO->WriteGlobalSno('a', "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 105d68833..1bf99f919 100644 --- a/src/modules/m_cloaking.cpp +++ b/src/modules/m_cloaking.cpp @@ -493,11 +493,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_COMPAT_HOST: { - if (ipstr != host) + if (!host_is_ip) { std::string tail = LastTwoDomainParts(host); @@ -520,7 +523,7 @@ class ModuleCloaking : public Module break; 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 d4101686a..3dea080ce 100644 --- a/src/modules/m_dnsbl.cpp +++ b/src/modules/m_dnsbl.cpp @@ -70,8 +70,8 @@ class DNSBLResolver : public Resolver int i = countExt.get(them); if (i) countExt.set(them, i - 1); - // Now we calculate the bitmask: 256*(256*(256*a+b)+c)+d - if(result.length()) + // All replies should be in 127.0.0.0/8 + if (result.compare(0, 4, "127.") == 0) { unsigned int bitmask = 0, record = 0; bool match = false; @@ -82,6 +82,7 @@ class DNSBLResolver : public Resolver switch (ConfEntry->type) { case DNSBLConfEntry::A_BITMASK: + // Now we calculate the bitmask: 256*(256*(256*a+b)+c)+d bitmask = resultip.s_addr >> 24; /* Last octet (network byte order) */ bitmask &= ConfEntry->bitmask; match = (bitmask != 0); @@ -196,7 +197,11 @@ class DNSBLResolver : public Resolver ConfEntry->stats_misses++; } else + { + if (!result.empty()) + ServerInstance->SNO->WriteGlobalSno('a', "DNSBL: %s returned address outside of acceptable subnet 127.0.0.0/8: %s", ConfEntry->domain.c_str(), result.c_str()); ConfEntry->stats_misses++; + } } } diff --git a/src/modules/m_httpd_stats.cpp b/src/modules/m_httpd_stats.cpp index 2fc7ca7de..e17bf514f 100644 --- a/src/modules/m_httpd_stats.cpp +++ b/src/modules/m_httpd_stats.cpp @@ -213,7 +213,7 @@ class ModuleHttpStats : public Module 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_spanningtree/protocolinterface.cpp b/src/modules/m_spanningtree/protocolinterface.cpp index 3ab5dae9d..ca4147fea 100644 --- a/src/modules/m_spanningtree/protocolinterface.cpp +++ b/src/modules/m_spanningtree/protocolinterface.cpp @@ -137,9 +137,6 @@ void SpanningTreeProtocolInterface::PushToClient(User* target, const std::string void SpanningTreeProtocolInterface::SendChannel(Channel* target, char status, const std::string &text) { - std::string cname = target->name; - if (status) - cname = status + cname; TreeServerList list; CUList exempt_list; Utils->GetListOfServersForChannel(target,list,status,exempt_list); @@ -154,12 +151,20 @@ void SpanningTreeProtocolInterface::SendChannel(Channel* target, char status, co void SpanningTreeProtocolInterface::SendChannelPrivmsg(Channel* target, char status, const std::string &text) { - SendChannel(target, status, ":" + ServerInstance->Config->GetSID()+" PRIVMSG "+target->name+" :"+text); + std::string cname = target->name; + if (status) + cname.insert(0, 1, status); + + SendChannel(target, status, ":" + ServerInstance->Config->GetSID()+" PRIVMSG "+cname+" :"+text); } void SpanningTreeProtocolInterface::SendChannelNotice(Channel* target, char status, const std::string &text) { - SendChannel(target, status, ":" + ServerInstance->Config->GetSID()+" NOTICE "+target->name+" :"+text); + std::string cname = target->name; + if (status) + cname.insert(0, 1, status); + + SendChannel(target, status, ":" + ServerInstance->Config->GetSID()+" NOTICE "+cname+" :"+text); } void SpanningTreeProtocolInterface::SendUserPrivmsg(User* target, const std::string &text) diff --git a/src/socketengines/socketengine_epoll.cpp b/src/socketengines/socketengine_epoll.cpp index f2837777a..d5f017347 100644 --- a/src/socketengines/socketengine_epoll.cpp +++ b/src/socketengines/socketengine_epoll.cpp @@ -25,7 +25,7 @@ #include "exitcodes.h" #include "socketengine.h" #include <sys/epoll.h> -#include <ulimit.h> +#include <sys/resource.h> #include <iostream> #define EP_DELAY 5 @@ -55,10 +55,11 @@ public: EPollEngine::EPollEngine() { CurrentSetSize = 0; - int max = ulimit(4, 0); - if (max > 0) + + struct rlimit limit; + if (!getrlimit(RLIMIT_NOFILE, &limit)) { - MAX_DESCRIPTORS = max; + MAX_DESCRIPTORS = limit.rlim_cur; } else { diff --git a/src/users.cpp b/src/users.cpp index 685ef9743..4dbb73a1f 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -1398,6 +1398,8 @@ void User::DoHostCycle(const std::string &quitline) FOREACH_MOD(I_OnBuildNeighborList,OnBuildNeighborList(this, include_c, exceptions)); + // Users shouldn't see themselves quitting when host cycling + exceptions.erase(this); for (std::map<User*,bool>::iterator i = exceptions.begin(); i != exceptions.end(); ++i) { LocalUser* u = IS_LOCAL(i->first); diff --git a/tools/travis-ci.sh b/tools/travis-ci.sh index 6dbc82300..42b07fa25 100755 --- a/tools/travis-ci.sh +++ b/tools/travis-ci.sh @@ -4,11 +4,6 @@ if [ "$TRAVIS_OS_NAME" = "linux" ] then sudo apt-get update --assume-yes sudo apt-get install --assume-yes libgeoip-dev libgnutls-dev libldap2-dev libmysqlclient-dev libpcre3-dev libpq-dev libsqlite3-dev libssl-dev libtre-dev -elif [ "$TRAVIS_OS_NAME" = "osx" ] -then - brew update - brew install geoip gnutls mysql-connector-c openssl pcre postgresql sqlite3 tre - brew link sqlite3 --force else >&2 echo "'$TRAVIS_OS_NAME' is an unknown Travis CI environment!" exit 1 diff --git a/win/CMakeLists.txt b/win/CMakeLists.txt index 10653cf74..7be08a3fc 100644 --- a/win/CMakeLists.txt +++ b/win/CMakeLists.txt @@ -85,6 +85,7 @@ file(MAKE_DIRECTORY ${LOG_PATH}) install(DIRECTORY ${LOG_PATH} 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") |