]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Merge insp20
authorAttila Molnar <attilamolnar@hush.com>
Tue, 21 Jan 2014 17:44:08 +0000 (18:44 +0100)
committerAttila Molnar <attilamolnar@hush.com>
Tue, 21 Jan 2014 17:44:08 +0000 (18:44 +0100)
48 files changed:
docs/conf/helpop-full.conf.example
docs/conf/helpop.conf.example
docs/conf/inspircd.conf.example
docs/conf/links.conf.example
docs/conf/modules.conf.example
docs/conf/opers.conf.example
include/configreader.h
include/inspircd.h
modulemanager
src/channels.cpp
src/commands/cmd_admin.cpp
src/commands/cmd_commands.cpp
src/commands/cmd_info.cpp
src/commands/cmd_modules.cpp
src/commands/cmd_whois.cpp
src/configparser.cpp
src/inspircd.cpp
src/mode.cpp
src/modules.cpp
src/modules/m_alias.cpp
src/modules/m_callerid.cpp
src/modules/m_channames.cpp
src/modules/m_dccallow.cpp
src/modules/m_dnsbl.cpp
src/modules/m_helpop.cpp
src/modules/m_httpd.cpp
src/modules/m_httpd_stats.cpp
src/modules/m_ident.cpp
src/modules/m_joinflood.cpp
src/modules/m_mlock.cpp
src/modules/m_override.cpp
src/modules/m_permchannels.cpp
src/modules/m_remove.cpp
src/modules/m_ripemd160.cpp
src/modules/m_sajoin.cpp
src/modules/m_sasl.cpp
src/modules/m_services_account.cpp
src/modules/m_showwhois.cpp
src/modules/m_silence.cpp
src/modules/m_spanningtree/main.cpp
src/modules/m_spanningtree/main.h
src/modules/m_spanningtree/svsnick.cpp
src/modules/m_spanningtree/utils.cpp
src/modules/m_svshold.cpp
src/modules/m_uninvite.cpp
src/modules/m_userip.cpp
src/socket.cpp
src/users.cpp

index a6d3c7cd1c50b1623bc8e4aca9d0bcb01d6e8e9c..6268ba9ca2e72274d65d639e2a619b12d0146c2a 100644 (file)
@@ -361,8 +361,8 @@ Sets your name to the specified name.">
 <helpop key="coper" value="Oper Commands
 -------------
 
-OPERMOTD  CHECK     CLONES      USERIP   LINE
-ALLTIME   MODULES   WALLOPS     GLOBOPS
+OPERMOTD  CHECK     CLONES      USERIP   TLINE
+ALLTIME   WALLOPS   GLOBOPS
 
 SETHOST   SETIDENT  CHGHOST     CHGIDENT CHGNAME
 SETIDLE   SWHOIS
index 5f33b6d88e71d8a4a8b2ca18a1dc52b5fdddeba0..6d6a8171977cdde7a184065c4ea0009172e49797 100644 (file)
@@ -34,7 +34,7 @@ PRIVMSG   NOTICE   NICK      JOIN      PART
 CYCLE     KNOCK    MODE      DEVOICE   TOPIC
 KICK      FPART    REMOVE    TBAN      INVITE
 UNINVITE  AWAY     DCCALLOW  SILENCE   ACCEPT
-MKPASSWD  VHOST    TITLE
+MKPASSWD  VHOST    TITLE     SETNAME
 
 WHOIS     WHOWAS   ISON      USERHOST  WATCH
 LIST      NAMES    WHO       MOTD
@@ -49,11 +49,11 @@ OPER">
 <helpop key="coper" value="Oper Commands
 -------------
 
-OPERMOTD  CHECK     TAXONOMY    CLONES   USERIP
-TLINE     ALLTIME   MODULES     WALLOPS  GLOBOPS
+OPERMOTD  CHECK     CLONES      USERIP   TLINE
+ALLTIME   WALLOPS   GLOBOPS
 
-SETHOST   SETIDENT  SETNAME     CHGHOST  CHGIDENT
-CHGNAME   SETIDLE   SWHOIS
+SETHOST   SETIDENT  CHGHOST     CHGIDENT CHGNAME
+SETIDLE   SWHOIS
 
 SANICK    NICKLOCK  NICKUNLOCK
 
index fd7973f39d28511f963bb6d016369a01ca44939d..737e05e5aab2dfbff4a6b32f8648f5fdee6a6182 100644 (file)
 
 <connect
          # deny: Will not let people connect if they have specified host/IP.
-         deny="69.254.*">
+         deny="192.0.2.*">
 
 # connect:reason is the message that users will see if they match a deny block
 <connect deny="3ffe::0/32" reason="The 6bone address space is deprecated">
          parent="main"
 
          # allow: What IP addresses/hosts to allow for this block.
-         allow="196.12.*"
+         allow="203.0.113.*"
 
          # hash: what hash this password is hashed with. requires the module
          # for selected hash (m_md5.so, m_sha256.so or m_ripemd160.so) be
           #  no        Do not show
           operspywhois="no"
 
-          # runasuser: If this is set, InspIRCd will attempt to setuid
-          # to run as this user- allows binding of ports under 1024.
+          # runasuser: If this is set, InspIRCd will attempt to switch
+          # to run as this user, which allows binding of ports under 1024.
+          # You should NOT set this unless you are starting as root.
           # NOT SUPPORTED/NEEDED UNDER WINDOWS.
           #runasuser=""
 
-          # runasgroup: If this is set, InspIRCd will attempt to set group
-          # to run under this group, which allows binding of ports under 1024
+          # runasgroup: If this is set, InspIRCd will attempt to switch
+          # to run as this group, which allows binding of ports under 1024.
+          # You should NOT set this unless you are starting as root.
           # NOT SUPPORTED/NEEDED UNDER WINDOWS.
           #runasgroup=""
 
 
 <badip
        # ipmask: IP range to ban. Wildcards and CIDR can be used.
-       ipmask="69.69.69.69"
+       ipmask="192.0.2.69"
 
        # reason: Reason to display when user is disconnected.
        reason="No porn here thanks.">
 <badhost
          # host: ident@hostname to ban.
          # Wildcards and CIDR (if you specify an IP) can be used.
-         host="*@hundredz.n.hundredz.o.1337.kiddies.com"
+         host="*@hundredz.n.hundredz.o.1337.kiddies.example.net"
 
          # reason: Reason to display when user is disconnected
          reason="Too many 1337 kiddiots">
 
-<badhost host="root@*" reason="Don't irc as root!">
-<badhost host="*@172.32.0.0/16" reason="This subnet is bad.">
+<badhost host="root@*" reason="Don't IRC as root!">
+<badhost host="*@198.51.100.0/24" reason="This subnet is bad.">
 
 # exception: Hosts that are exempt from [kgz]lines.
 <exception
            # host: ident@hostname to exempt.
            # Wildcards and CIDR (if you specify an IP) can be used.
-           host="*@ircop.host.com"
+           host="*@ircop.example.com"
 
            # reason: Reason for exception. Only shown in /stats e
-           reason="Opers hostname">
+           reason="Oper's hostname">
 
 #-#-#-#-#-#-#-#-#-#-#- INSANE BAN OPTIONS  -#-#-#-#-#-#-#-#-#-#-#-#-#-#
 #                                                                     #
index b196c5621002b76a6daab6371c6a28132e3e8a60..5e36689f022205379c5039b5c9b4c1058e16364b 100644 (file)
@@ -29,7 +29,7 @@
 
       # allowmask: Range of IP addresses to allow for this link.
       # Can be a CIDR (see example).
-      allowmask="69.58.44.0/24 127.0.0.0/8"
+      allowmask="203.0.113.0/24 127.0.0.0/8 2001:db8::/32"
 
       # timeout: If defined, this option defines how long the server
       # will wait to consider the connect attempt failed and try the
@@ -74,7 +74,7 @@
 <link name="hub.penguin.org"
       ipaddr="penguin.box.com"
       port="7000"
-      allowmask="69.58.44.0/24"
+      allowmask="203.0.113.0/24"
       timeout="300"
       ssl="gnutls"
       bind="1.2.3.4"
index 2ab1adebfde9b73c63966512e82758c2f6650d27..672bcb9d0f080a0ac5cc3f2e9b834279759988aa 100644 (file)
 # a <bind> tag with type "httpd", and load at least one of the other
 # m_httpd_* modules to provide pages to display.
 #
+# You can adjust the timeout for HTTP connections below. All HTTP
+# connections will be closed after (roughly) this many seconds.
+#<httpd timeout="20">
 
 #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
 # http ACL module: Provides access control lists for m_httpd dependent
 
 #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
 # SASL authentication module: Provides support for IRC Authentication 
-# Layer (aka: atheme SASL) via AUTHENTICATE.
+# Layer via AUTHENTICATE. Note: You also need to have m_cap.so loaded
+# for SASL to work.
 #<module name="m_sasl.so">
 
 #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
 # SVSHold module: Implements SVSHOLD. Like Q:Lines, but can only be   #
 # added/removed by Services.                                          #
 #<module name="m_svshold.so">
+# If silent is true no snotices will be generated by SVSHOLD.
+#<svshold silent="false">
 
 #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
 # SWHOIS module: Allows you to add arbitary lines to user WHOIS.
index b39c73e43af024115aa6d72e7e8d5729ac96aa13..a759622a446ec82fe6d9718468ac749b01b5e609 100644 (file)
@@ -90,7 +90,7 @@
       # Multiple options can be separated by spaces and CIDR's are allowed.
       # You CAN use just * or *@* for this section, but it is not recommended
       # for security reasons.
-      host="ident@dialup15.isp.com *@localhost *@server.com *@3ffe::0/16"
+      host="yourident@dialup15.isp.com *@localhost *@example.com *@2001:db8::/32"
 
       # ** ADVANCED ** This option is disabled by default.
       # fingerprint: When using the m_sslinfo module, you may specify
 <oper
       name="Brain"
       password="s3cret"
-      host="ident@dialup15.isp.com *@localhost *@server.com *@3ffe::0/16"
+      host="yourident@dialup15.isp.com *@localhost *@example.com *@2001:db8::/32"
       #fingerprint="67cb9dc013248a829bb2171ed11becd4"
       type="NetAdmin">
 
       # Multiple options can be separated by spaces and CIDR's are allowed.
       # You CAN use just * or *@* for this section, but it is not recommended
       # for security reasons.
-      host="ident@dialup15.isp.com *@localhost *@server.com *@3ffe::0/16"
+      host="yourident@dialup15.isp.com *@localhost *@example.com *@2001:db8::/32"
 
       # type: What oper type this oline is. See the block above for list
       # of types. NOTE: This is case-sensitive as well.
index e8c439933cef7fc7bf926b61b2b1038800303c74..7bc6c1bcb017a661afee9436c52240a30adb952d 100644 (file)
@@ -83,8 +83,7 @@ class CoreExport ConfigTag : public refcountbase
        inline const std::vector<KeyVal>& getItems() const { return items; }
 
        /** Create a new ConfigTag, giving access to the private KeyVal item list */
-       static ConfigTag* create(const std::string& Tag, const std::string& file, int line,
-               std::vector<KeyVal>*&items);
+       static ConfigTag* create(const std::string& Tag, const std::string& file, int line, std::vector<KeyVal>*& Items);
  private:
        ConfigTag(const std::string& Tag, const std::string& file, int line);
 };
index d69d1b46b53657348961a3212af5114ea1728c72..7a8c1fb748e3f7a8ccb418cd36232d917c954090 100644 (file)
@@ -132,7 +132,7 @@ inline std::string ConvToStr(const bool in)
  */
 inline std::string ConvToStr(char in)
 {
-       return std::string(in,1);
+       return std::string(1, in);
 }
 
 /** Template function to convert any input type to std::string
index 9e4670de87d216c549408fc2131bb69394eed61c..86f9ca0c476405eb3e6f5b10ab731c0b8be3d2b1 100755 (executable)
@@ -24,14 +24,14 @@ use warnings FATAL => qw(all);
 
 use make::utilities;
 
-if (!module_installed("LWP::Simple"))
-{
-       die "Your system is missing the LWP::Simple Perl module!";
-}
+BEGIN {
+       unless (module_installed("LWP::Simple")) {
+               die "Your system is missing the LWP::Simple Perl module!";
+       }
+       unless (module_installed("Crypt::SSLeay") || module_installed("IO::Socket::SSL")) {
+               die "Your system is missing the Crypt::SSLeay or IO::Socket::SSL Perl modules!";
+       }
 
-if (!module_installed("Crypt::SSLeay") && !module_installed("IO::Socket::SSL"))
-{
-       die "Your system is missing the Crypt::SSLeay or IO::Socket::SSL Perl modules!";
 }
 
 use File::Basename;
@@ -56,15 +56,20 @@ sub parse_url;
 
 # retrieve and parse entries from sources.list
 sub parse_url {
-       my $src = shift;
+       chomp(my $src = shift);
        return if $url_seen{$src};
        $url_seen{$src}++;
 
-       my $doc = get($src);
-       die "Could not retrieve $_" unless defined $doc;
+       my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => 0 });
+       my $response = $ua->get($src);
+
+       unless ($response->is_success) {
+               my $err = $response->message;
+               die "Could not retrieve $src: $err";
+       }
 
        my $mod;
-       for (split /\n+/, $doc) {
+       for (split /\n+/, $response->decoded_content) {
                s/^\s+//; # ignore whitespace at start
                next if /^#/;
                if (/^module (\S+) (\S+) (\S+)/) {
@@ -257,7 +262,7 @@ sub resolve_deps {
        }
 }
 
-my $action = $#ARGV > 0 ? lc shift @ARGV : 'help';
+my $action = $#ARGV >= 0 ? lc shift @ARGV : 'help';
 
 if ($action eq 'install') {
        for my $mod (@ARGV) {
index 563bc27044c204618735dc0cf1bf506a1d95b325..5865f67245d21a0bbcaa8d17bb355a099a2b23d1 100644 (file)
@@ -654,7 +654,8 @@ const char* Channel::ChanModes(bool showkey)
  */
 void Channel::UserList(User *user)
 {
-       if (this->IsModeSet(secretmode) && !this->HasUser(user) && !user->HasPrivPermission("channels/auspex"))
+       bool has_privs = user->HasPrivPermission("channels/auspex");
+       if (this->IsModeSet(secretmode) && !this->HasUser(user) && !has_privs)
        {
                user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", this->name.c_str());
                return;
@@ -679,7 +680,7 @@ void Channel::UserList(User *user)
        {
                if (i->first->quitting)
                        continue;
-               if ((!has_user) && (i->first->IsModeSet(invisiblemode)))
+               if ((!has_user) && (i->first->IsModeSet(invisiblemode)) && (!has_privs))
                {
                        /*
                         * user is +i, and source not on the channel, does not show
index 3a3eed3465734115857a8dd8fd1528c8a82094e3..0d6c235f09a27297c67819a36d096093bf063809 100644 (file)
@@ -30,7 +30,12 @@ class CommandAdmin : public Command
  public:
        /** Constructor for admin.
         */
-       CommandAdmin(Module* parent) : Command(parent,"ADMIN",0,0) { syntax = "[<servername>]"; }
+       CommandAdmin(Module* parent) : Command(parent,"ADMIN",0,0)
+       {
+               Penalty = 2;
+               syntax = "[<servername>]";
+       }
+
        /** Handle command.
         * @param parameters The parameters to the comamnd
         * @param pcnt The number of parameters passed to teh command
index 190c883bda56a1c904cef871bf197e663dae06fd..c456160612a57a5f70bc9ec73bd025a8ec91b91b 100644 (file)
@@ -30,7 +30,11 @@ class CommandCommands : public Command
  public:
        /** Constructor for commands.
         */
-       CommandCommands ( Module* parent) : Command(parent,"COMMANDS",0,0) { }
+       CommandCommands(Module* parent) : Command(parent,"COMMANDS",0,0)
+       {
+               Penalty = 3;
+       }
+
        /** Handle command.
         * @param parameters The parameters to the comamnd
         * @param pcnt The number of parameters passed to teh command
index b3f146c307d79f5ec3da251ab8e45b686bc823d6..7ee1c4d3b8d48cd74b2a3c743757177a244e1222 100644 (file)
@@ -32,7 +32,12 @@ class CommandInfo : public Command
  public:
        /** Constructor for info.
         */
-       CommandInfo ( Module* parent) : Command(parent,"INFO") { syntax = "[<servermask>]"; }
+       CommandInfo(Module* parent) : Command(parent,"INFO")
+       {
+               Penalty = 4;
+               syntax = "[<servername>]";
+       }
+
        /** Handle command.
         * @param parameters The parameters to the comamnd
         * @param pcnt The number of parameters passed to teh command
index fe199e7a433259dba318da4bc4e74ccda0a38e09..d9fa7d5d5642f60779e3388513b91679e7fdd390 100644 (file)
@@ -31,7 +31,12 @@ class CommandModules : public Command
  public:
        /** Constructor for modules.
         */
-       CommandModules ( Module* parent) : Command(parent,"MODULES",0,0) { syntax = "[server]"; }
+       CommandModules(Module* parent) : Command(parent,"MODULES",0,0)
+       {
+               Penalty = 4;
+               syntax = "[<servername>]";
+       }
+
        /** Handle command.
         * @param parameters The parameters to the comamnd
         * @param pcnt The number of parameters passed to teh command
@@ -74,7 +79,7 @@ CmdResult CommandModules::Handle (const std::vector<std::string>& parameters, Us
                Module* m = i->second;
                Version V = m->GetVersion();
 
-               if (user->HasPrivPermission("servers/auspex"))
+               if (IS_LOCAL(user) && user->HasPrivPermission("servers/auspex"))
                {
                        std::string flags("SvcC");
                        int pos = 0;
index 7e67676edab33b5fab33bf5de64b9db6fc6c6b24..e8a751fa036dc6ade92b4e63feb1b60eb31572a9 100644 (file)
@@ -80,7 +80,7 @@ void CommandWhois::SplitChanList(User* source, User* dest, const std::string& cl
 {
        std::string line;
        std::ostringstream prefix;
-       std::string::size_type start, pos, length;
+       std::string::size_type start, pos;
 
        prefix << dest->nick << " :";
        line = prefix.str();
@@ -88,23 +88,13 @@ void CommandWhois::SplitChanList(User* source, User* dest, const std::string& cl
 
        for (start = 0; (pos = cl.find(' ', start)) != std::string::npos; start = pos+1)
        {
-               length = (pos == std::string::npos) ? cl.length() : pos;
-
-               if (line.length() + namelen + length - start > 510)
+               if (line.length() + namelen + pos - start > 510)
                {
                        ServerInstance->SendWhoisLine(source, dest, 319, line);
                        line = prefix.str();
                }
 
-               if(pos == std::string::npos)
-               {
-                       line.append(cl.substr(start, length - start));
-                       break;
-               }
-               else
-               {
-                       line.append(cl.substr(start, length - start + 1));
-               }
+               line.append(cl.substr(start, pos - start + 1));
        }
 
        if (line.length() != prefix.str().length())
index e23d6ec435d44f5c6d30be96a79d3734b3ee3b55..92f05edd40d33fbf630e769d7bc43dc688bfa61c 100644 (file)
@@ -499,10 +499,10 @@ std::string ConfigTag::getTagLocation()
        return src_name + ":" + ConvToStr(src_line);
 }
 
-ConfigTag* ConfigTag::create(const std::string& Tag, const std::string& file, int line, std::vector<KeyVal>*&items)
+ConfigTag* ConfigTag::create(const std::string& Tag, const std::string& file, int line, std::vector<KeyVal>*& Items)
 {
        ConfigTag* rv = new ConfigTag(Tag, file, line);
-       items = &rv->items;
+       Items = &rv->items;
        return rv;
 }
 
index 75e9f3699d0966a84aff310ffdafeeae0229c7b9..fb33f1937cb7f6ff6de11bace05aa239b79fa99e 100644 (file)
@@ -161,13 +161,20 @@ void InspIRCd::QuickExit(int status)
        exit(status);
 }
 
+// Required for returning the proper value of EXIT_SUCCESS for the parent process
+static void VoidSignalHandler(int signalreceived)
+{
+       exit(0);
+}
+
 bool InspIRCd::DaemonSeed()
 {
 #ifdef _WIN32
        std::cout << "InspIRCd Process ID: " << con_green << GetCurrentProcessId() << con_reset << std::endl;
        return true;
 #else
-       signal(SIGTERM, InspIRCd::QuickExit);
+       // Do not use QuickExit here: It will exit with status SIGTERM which would break e.g. daemon scripts
+       signal(SIGTERM, VoidSignalHandler);
 
        int childpid = fork();
        if (childpid < 0)
@@ -570,7 +577,7 @@ InspIRCd::InspIRCd(int argc, char** argv) :
 
                if (!g)
                {
-                       this->Logs->Log("STARTUP", LOG_DEFAULT, "getgrnam() failed (bad user?): %s", strerror(errno));
+                       this->Logs->Log("STARTUP", LOG_DEFAULT, "getgrnam(%s) failed (wrong group?): %s", SetGroup.c_str(), strerror(errno));
                        this->QuickExit(0);
                }
 
@@ -578,7 +585,7 @@ InspIRCd::InspIRCd(int argc, char** argv) :
 
                if (ret == -1)
                {
-                       this->Logs->Log("STARTUP", LOG_DEFAULT, "setgid() failed (bad user?): %s", strerror(errno));
+                       this->Logs->Log("STARTUP", LOG_DEFAULT, "setgid() failed (wrong group?): %s", strerror(errno));
                        this->QuickExit(0);
                }
        }
@@ -593,7 +600,7 @@ InspIRCd::InspIRCd(int argc, char** argv) :
 
                if (!u)
                {
-                       this->Logs->Log("STARTUP", LOG_DEFAULT, "getpwnam() failed (bad user?): %s", strerror(errno));
+                       this->Logs->Log("STARTUP", LOG_DEFAULT, "getpwnam(%s) failed (wrong user?): %s", SetUser.c_str(), strerror(errno));
                        this->QuickExit(0);
                }
 
@@ -601,7 +608,7 @@ InspIRCd::InspIRCd(int argc, char** argv) :
 
                if (ret == -1)
                {
-                       this->Logs->Log("STARTUP", LOG_DEFAULT, "setuid() failed (bad user?): %s", strerror(errno));
+                       this->Logs->Log("STARTUP", LOG_DEFAULT, "setuid() failed (wrong user?): %s", strerror(errno));
                        this->QuickExit(0);
                }
        }
index e0381b6830dcd57f2d66630ef5a0fc965fe1260b..ad46e602de1e39390dd3304b785be9266e289c8b 100644 (file)
@@ -207,7 +207,12 @@ PrefixMode::PrefixMode(Module* Creator, const std::string& Name, char ModeLetter
 
 ModeAction PrefixMode::OnModeChange(User* source, User*, Channel* chan, std::string& parameter, bool adding)
 {
-       User* target = ServerInstance->FindNick(parameter);
+       User* target;
+       if (IS_LOCAL(source))
+               target = ServerInstance->FindNickOnly(parameter);
+       else
+               target = ServerInstance->FindNick(parameter);
+
        if (!target)
        {
                source->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", parameter.c_str());
@@ -347,9 +352,16 @@ ModeAction ModeParser::TryMode(User* user, User* targetuser, Channel* chan, bool
 
 void ModeParser::Process(const std::vector<std::string>& parameters, User* user, ModeProcessFlag flags)
 {
-       std::string target = parameters[0];
+       const std::string& target = parameters[0];
        Channel* targetchannel = ServerInstance->FindChan(target);
-       User* targetuser  = ServerInstance->FindNick(target);
+       User* targetuser = NULL;
+       if (!targetchannel)
+       {
+               if (IS_LOCAL(user))
+                       targetuser = ServerInstance->FindNickOnly(target);
+               else
+                       targetuser = ServerInstance->FindNick(target);
+       }
        ModeType type = targetchannel ? MODETYPE_CHANNEL : MODETYPE_USER;
 
        LastParse.clear();
index 5c5e4febc6ce04d2a224fbc403a7d211d3cf3e13..23aceb3e11e442c524e5eb8f15ce44e2ef619eba 100644 (file)
@@ -388,18 +388,23 @@ void ModuleManager::DoSafeUnload(Module* mod)
        std::vector<reference<ExtensionItem> > items;
        ServerInstance->Extensions.BeginUnregister(modfind->second, items);
        /* Give the module a chance to tidy out all its metadata */
-       for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); c++)
+       for (chan_hash::iterator c = ServerInstance->chanlist->begin(); c != ServerInstance->chanlist->end(); )
        {
-               mod->OnCleanup(TYPE_CHANNEL,c->second);
-               c->second->doUnhookExtensions(items);
-               const UserMembList* users = c->second->GetUsers();
+               Channel* chan = c->second;
+               ++c;
+               mod->OnCleanup(TYPE_CHANNEL, chan);
+               chan->doUnhookExtensions(items);
+               const UserMembList* users = chan->GetUsers();
                for(UserMembCIter mi = users->begin(); mi != users->end(); mi++)
                        mi->second->doUnhookExtensions(items);
        }
-       for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); u++)
+       for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); )
        {
-               mod->OnCleanup(TYPE_USER,u->second);
-               u->second->doUnhookExtensions(items);
+               User* user = u->second;
+               // The module may quit the user (e.g. SSL mod unloading) and that will remove it from the container
+               ++u;
+               mod->OnCleanup(TYPE_USER, user);
+               user->doUnhookExtensions(items);
        }
        for(char m='A'; m <= 'z'; m++)
        {
index 065b9184e0c9ddde45fdbb55a77de25cf98d3f5b..b3b5f2c7619e1eef2cf958f89b84f71535d5c480 100644 (file)
@@ -310,11 +310,11 @@ class ModuleAlias : public Module
                for (unsigned int i = 0; i < newline.length(); i++)
                {
                        char c = newline[i];
-                       if (c == '$')
+                       if ((c == '$') && (i + 1 < newline.length()))
                        {
                                if (isdigit(newline[i+1]))
                                {
-                                       int len = (newline[i+2] == '-') ? 3 : 2;
+                                       int len = ((i + 2 < newline.length()) && (newline[i+2] == '-')) ? 3 : 2;
                                        std::string var = newline.substr(i, len);
                                        result.append(GetVar(var, original_line));
                                        i += len - 1;
index 3dc932958a97df15f3e8e62c7a6671fc89597e85..6f2c6730085560a8715ffc53fdfa09993c76970f 100644 (file)
@@ -158,13 +158,18 @@ class CommandAccept : public Command
         */
        typedef std::pair<User*, bool> ACCEPTAction;
 
-       static ACCEPTAction GetTargetAndAction(std::string& tok)
+       static ACCEPTAction GetTargetAndAction(std::string& tok, User* cmdfrom = NULL)
        {
                bool remove = (tok[0] == '-');
                if ((remove) || (tok[0] == '+'))
                        tok.erase(tok.begin());
 
-               User* target = ServerInstance->FindNick(tok);
+               User* target;
+               if (!cmdfrom || !IS_LOCAL(cmdfrom))
+                       target = ServerInstance->FindNick(tok);
+               else
+                       target = ServerInstance->FindNickOnly(tok);
+
                if ((!target) || (target->registered != REG_ALL) || (target->quitting) || (IS_SERVER(target)))
                        target = NULL;
 
@@ -216,7 +221,7 @@ public:
                }
 
                std::string tok = parameters[0];
-               ACCEPTAction action = GetTargetAndAction(tok);
+               ACCEPTAction action = GetTargetAndAction(tok, user);
                if (!action.first)
                {
                        user->WriteNumeric(ERR_NOSUCHNICK, "%s :No such nick/channel", tok.c_str());
@@ -248,7 +253,7 @@ public:
 
                // Find the target
                std::string targetstring = parameters[0];
-               ACCEPTAction action = GetTargetAndAction(targetstring);
+               ACCEPTAction action = GetTargetAndAction(targetstring, user);
                if (!action.first)
                        // Target is a "*" or source is local and the target is a list of nicks
                        return ROUTE_LOCALONLY;
index 8b050df2b964193ef8bc3efcb799cf60b1551eb3..f6d78037d660f7ef1abd4e084f40fe895eb00183 100644 (file)
@@ -106,6 +106,12 @@ class ModuleChannelNames : public Module
                ConfigTag* tag = ServerInstance->Config->ConfValue("channames");
                std::string denyToken = tag->getString("denyrange");
                std::string allowToken = tag->getString("allowrange");
+
+               if (!denyToken.compare(0, 2, "0-"))
+                       denyToken[0] = '1';
+               if (!allowToken.compare(0, 2, "0-"))
+                       allowToken[0] = '1';
+
                allowedmap.set();
 
                irc::portparser denyrange(denyToken, false);
index 487e4a7ed23fca65038e1d6a473ebe9de56f18ba..7332402bafa1e7566f354b27c1509f3476f65892 100644 (file)
@@ -225,6 +225,10 @@ class CommandDccallow : public Command
                user->WriteNumeric(998, ":  they will be removed from your DCCALLOW list.");
                user->WriteNumeric(998, ":  your DCCALLOW list will be deleted when you leave IRC.");
                user->WriteNumeric(999, ":End of DCCALLOW HELP");
+
+               LocalUser* localuser = IS_LOCAL(user);
+               if (localuser)
+                       localuser->CommandFloodPenalty += 4000;
        }
 
        void DisplayDCCAllowList(User* user)
index 10419de5157e59c674adb9afd2543a8c6096e5d2..6ee1c317ba6155e28e3627203c0589837fd8c880 100644 (file)
@@ -142,7 +142,10 @@ class DNSBLResolver : public DNS::Request
                                                ServerInstance->XLines->ApplyLines();
                                        }
                                        else
+                                       {
                                                delete kl;
+                                               return;
+                                       }
                                        break;
                                }
                                case DNSBLConfEntry::I_GLINE:
@@ -157,7 +160,10 @@ class DNSBLResolver : public DNS::Request
                                                ServerInstance->XLines->ApplyLines();
                                        }
                                        else
+                                       {
                                                delete gl;
+                                               return;
+                                       }
                                        break;
                                }
                                case DNSBLConfEntry::I_ZLINE:
@@ -172,7 +178,10 @@ class DNSBLResolver : public DNS::Request
                                                ServerInstance->XLines->ApplyLines();
                                        }
                                        else
+                                       {
                                                delete zl;
+                                               return;
+                                       }
                                        break;
                                }
                                case DNSBLConfEntry::I_UNKNOWN:
index 64bdc2400c6410a99d665c24d545c7b1de5f9cb6..2fe958a71c2c96fa4c7bc71be7e0741a4c667c48 100644 (file)
@@ -96,7 +96,6 @@ class CommandHelpop : public Command
 
 class ModuleHelpop : public Module
 {
-               std::string  h_file;
                CommandHelpop cmd;
                Helpop ho;
 
@@ -108,7 +107,7 @@ class ModuleHelpop : public Module
 
                void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
                {
-                       helpop_map.clear();
+                       HelpopMap help;
 
                        ConfigTagList tags = ServerInstance->Config->ConfTags("helpop");
                        for(ConfigIter i = tags.first; i != tags.second; ++i)
@@ -123,20 +122,21 @@ class ModuleHelpop : public Module
                                        throw ModuleException("m_helpop: The key 'index' is reserved for internal purposes. Please remove it.");
                                }
 
-                               helpop_map[key] = value;
+                               help[key] = value;
                        }
 
-                       if (helpop_map.find("start") == helpop_map.end())
+                       if (help.find("start") == help.end())
                        {
                                // error!
                                throw ModuleException("m_helpop: Helpop file is missing important entry 'start'. Please check the example conf.");
                        }
-                       else if (helpop_map.find("nohelp") == helpop_map.end())
+                       else if (help.find("nohelp") == help.end())
                        {
                                // error!
                                throw ModuleException("m_helpop: Helpop file is missing important entry 'nohelp'. Please check the example conf.");
                        }
 
+                       helpop_map.swap(help);
                }
 
                void OnWhois(User* src, User* dst) CXX11_OVERRIDE
index 5a71f8018e3b6cb82bcde7f6f7812499f5840ce6..735551dffa3ba6dd184a014fa72200b99560d961 100644 (file)
@@ -30,6 +30,7 @@ class ModuleHttpServer;
 
 static ModuleHttpServer* HttpModule;
 static bool claimed;
+static std::set<HttpServerSocket*> sockets;
 
 /** HTTP socket states
  */
@@ -56,8 +57,11 @@ class HttpServerSocket : public BufferedSocket
        std::string http_version;
 
  public:
+       const time_t createtime;
+
        HttpServerSocket(int newfd, const std::string& IP, ListenSocket* via, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server)
                : BufferedSocket(newfd), ip(IP), postsize(0)
+               , createtime(ServerInstance->Time())
        {
                InternalState = HTTP_SERVE_WAIT_REQUEST;
 
@@ -66,6 +70,11 @@ class HttpServerSocket : public BufferedSocket
                        GetIOHook()->OnStreamSocketAccept(this, client, server);
        }
 
+       ~HttpServerSocket()
+       {
+               sockets.erase(this);
+       }
+
        void OnError(BufferedSocketError) CXX11_OVERRIDE
        {
                ServerInstance->GlobalCulls.AddItem(this);
@@ -347,6 +356,7 @@ class ModuleHttpServer : public Module
 {
        std::vector<HttpServerSocket *> httpsocks;
        HTTPdAPIImpl APIImpl;
+       unsigned int timeoutsec;
 
  public:
        ModuleHttpServer()
@@ -359,6 +369,12 @@ class ModuleHttpServer : public Module
                HttpModule = this;
        }
 
+       void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
+       {
+               ConfigTag* tag = ServerInstance->Config->ConfValue("httpd");
+               timeoutsec = tag->getInt("timeout");
+       }
+
        ModResult OnAcceptConnection(int nfd, ListenSocket* from, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) CXX11_OVERRIDE
        {
                if (from->bind_tag->getString("type") != "httpd")
@@ -366,17 +382,39 @@ class ModuleHttpServer : public Module
                int port;
                std::string incomingip;
                irc::sockets::satoap(*client, incomingip, port);
-               new HttpServerSocket(nfd, incomingip, from, client, server);
+               sockets.insert(new HttpServerSocket(nfd, incomingip, from, client, server));
                return MOD_RES_ALLOW;
        }
 
-       ~ModuleHttpServer()
+       void OnBackgroundTimer(time_t curtime) CXX11_OVERRIDE
+       {
+               if (!timeoutsec)
+                       return;
+
+               time_t oldest_allowed = curtime - timeoutsec;
+               for (std::set<HttpServerSocket*>::const_iterator i = sockets.begin(); i != sockets.end(); )
+               {
+                       HttpServerSocket* sock = *i;
+                       ++i;
+                       if (sock->createtime < oldest_allowed)
+                       {
+                               sock->cull();
+                               delete sock;
+                       }
+               }
+       }
+
+       CullResult cull() CXX11_OVERRIDE
        {
-               for (size_t i = 0; i < httpsocks.size(); i++)
+               std::set<HttpServerSocket*> local;
+               local.swap(sockets);
+               for (std::set<HttpServerSocket*>::const_iterator i = local.begin(); i != local.end(); ++i)
                {
-                       httpsocks[i]->cull();
-                       delete httpsocks[i];
+                       HttpServerSocket* sock = *i;
+                       sock->cull();
+                       delete sock;
                }
+               return Module::cull();
        }
 
        Version GetVersion() CXX11_OVERRIDE
index 346fe41f51cce2a2f011f9ba2665cc78ef1618a0..11809e8931f073e1c3901ef9418a44e7d61da65a 100644 (file)
@@ -52,7 +52,7 @@ class ModuleHttpStats : public Module
                                ret += it->second;
                                ret += ';';
                        }
-                       else if (*x == 0x9 ||  *x == 0xA || *x == 0xD || *x >= 0x20)
+                       else if (*x == 0x09 ||  *x == 0x0A || *x == 0x0D || ((*x >= 0x20) && (*x <= 0x7e)))
                        {
                                // The XML specification defines the following characters as valid inside an XML document:
                                // Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]
index c73e26b16f0fb211451067a19a12e13923d29343..1f57fc3e1a8009262309abeba041a9706ca4203a 100644 (file)
@@ -336,7 +336,7 @@ class ModuleIdent : public Module
                /* wooo, got a result (it will be good, or bad) */
                if (isock->result.empty())
                {
-                       user->ident.insert(0, 1, '~');
+                       user->ident.insert(user->ident.begin(), 1, '~');
                        user->WriteNotice("*** Could not find your ident, using " + user->ident + " instead.");
                }
                else
index 81ad7e1692de7560c2abe8f225debe3f9be107a7..edce2b22cb6310236f5fcddb1911a0113f00c761 100644 (file)
@@ -124,12 +124,8 @@ class JoinFlood : public ModeHandler
                        if (!channel->IsModeSet(this))
                                return MODEACTION_DENY;
 
-                       joinfloodsettings* f = ext.get(channel);
-                       if (f)
-                       {
-                               ext.unset(channel);
-                               return MODEACTION_ALLOW;
-                       }
+                       ext.unset(channel);
+                       return MODEACTION_ALLOW;
                }
                return MODEACTION_DENY;
        }
@@ -168,7 +164,7 @@ class ModuleJoinFlood : public Module
                joinfloodsettings *f = jf.ext.get(memb->chan);
 
                /* But all others are OK */
-               if (f)
+               if ((f) && (!f->islocked()))
                {
                        f->addjoin();
                        if (f->shouldlock())
index 43eadf63ee5d4222764c90ecdf3d5013e2928bda..22faa2119b22eed6f5f1e176449e63dd90a5d331 100644 (file)
@@ -31,12 +31,7 @@ public:
                return Version("Implements the ability to have server-side MLOCK enforcement.", VF_VENDOR);
        }
 
-       void Prioritize()
-       {
-               ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_FIRST);
-       }
-
-       ModResult OnPreMode(User* source, User* dest, Channel* channel, const std::vector<std::string>& parameters) CXX11_OVERRIDE
+       ModResult OnRawMode(User* source, Channel* channel, const char mode, const std::string& parameter, bool adding, int pcnt)
        {
                if (!channel)
                        return MOD_RES_PASSTHRU;
@@ -48,11 +43,11 @@ public:
                if (!mlock_str)
                        return MOD_RES_PASSTHRU;
 
-               std::string::size_type p = parameters[1].find_first_of(*mlock_str);
+               std::string::size_type p = mlock_str->find(mode);
                if (p != std::string::npos)
                {
                        source->WriteNumeric(742, "%s %c %s :MODE cannot be set due to channel having an active MLOCK restriction policy",
-                                            channel->name.c_str(), parameters[1][p], mlock_str->c_str());
+                                            channel->name.c_str(), mode, mlock_str->c_str());
                        return MOD_RES_DENY;
                }
 
index ce9ea17e273ef9fca24455d3c75641174765ac2f..346d38b9f32b68518898689746f223e67a148a55 100644 (file)
@@ -35,6 +35,20 @@ class ModuleOverride : public Module
        ChanModeReference key;
        ChanModeReference limit;
 
+       static bool IsOverride(unsigned int userlevel, const std::string& modeline)
+       {
+               for (std::string::const_iterator i = modeline.begin(); i != modeline.end(); ++i)
+               {
+                       ModeHandler* mh = ServerInstance->Modes->FindMode(*i, MODETYPE_CHANNEL);
+                       if (!mh)
+                               continue;
+
+                       if (mh->GetLevelRequired() > userlevel)
+                               return true;
+               }
+               return false;
+       }
+
  public:
        ModuleOverride()
                : topiclock(this, "topiclock")
@@ -110,7 +124,10 @@ class ModuleOverride : public Module
 
                unsigned int mode = channel->GetPrefixValue(source);
 
-               if (mode < HALFOP_VALUE && CanOverride(source, "MODE"))
+               if (!IsOverride(mode, parameters[1]))
+                       return MOD_RES_PASSTHRU;
+
+               if (CanOverride(source, "MODE"))
                {
                        std::string msg = source->nick+" overriding modes:";
                        for(unsigned int i=0; i < parameters.size(); i++)
index a0b3284e3acd49354cdbf3ce950594811f1049e9..61080b2dd9622a7c48e25d5f8b07805223da3aa9 100644 (file)
@@ -165,10 +165,12 @@ class ModulePermanentChannels : public Module
 {
        PermChannel p;
        bool dirty;
+       bool loaded;
        bool save_listmodes;
 public:
 
-       ModulePermanentChannels() : p(this), dirty(false)
+       ModulePermanentChannels()
+               : p(this), dirty(false), loaded(false)
        {
        }
 
@@ -301,8 +303,6 @@ public:
                // to be able to set the modes they provide (e.g.: m_stripcolor is inited after us)
                // Prioritize() is called after all module initialization is complete, consequently
                // all modes are available now
-
-               static bool loaded = false;
                if (loaded)
                        return;
 
index 4dcd5aaa1868fce8fa67983c45de2cc809bc9dc3..ed9b6ce253876f7e3ebb8969431cda6b613288a3 100644 (file)
@@ -60,7 +60,10 @@ class RemoveBase : public Command
                const std::string& username = parameters[neworder ? 1 : 0];
 
                /* Look up the user we're meant to be removing from the channel */
-               target = ServerInstance->FindNick(username);
+               if (IS_LOCAL(user))
+                       target = ServerInstance->FindNickOnly(username);
+               else
+                       target = ServerInstance->FindNick(username);
 
                /* And the channel we're meant to be removing them from */
                channel = ServerInstance->FindChan(channame);
index 41331543acee35a5a4962c6ca78c90039ad6a7d1..261cd1e27ede6925ac7dd3e77cdc54eb6ec4ed60 100644 (file)
@@ -149,6 +149,9 @@ typedef uint32_t dword;
 
 class RIProv : public HashProvider
 {
+       /** Final hash value
+        */
+       byte hashcode[RMDsize/8];
 
        void MDinit(dword *MDbuf, unsigned int* key)
        {
@@ -403,7 +406,6 @@ class RIProv : public HashProvider
        byte *RMD(byte *message, dword length, unsigned int* key)
        {
                dword         MDbuf[RMDsize/32];   /* contains (A, B, C, D(E))   */
-               static byte   hashcode[RMDsize/8]; /* for final hash-value         */
                dword         X[16];               /* current 16-word chunk        */
                unsigned int  i;                   /* counter                      */
                dword         nbytes;              /* # of bytes not yet processed */
index eda58ef96e1db9548cc825f7941430045386cbae..0748c013b96344c698f60f42203b9cf101cb32ee 100644 (file)
@@ -60,7 +60,7 @@ class CommandSajoin : public Command
                                Channel* n = Channel::JoinUser(localuser, parameters[1], true);
                                if (n && n->HasUser(dest))
                                {
-                                       ServerInstance->SNO->WriteToSnoMask('a', user->nick+" used SAJOIN to make "+dest->nick+" join "+parameters[1]);
+                                       ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used SAJOIN to make "+dest->nick+" join "+parameters[1]);
                                        return CMD_SUCCESS;
                                }
                                else
@@ -71,7 +71,6 @@ class CommandSajoin : public Command
                        }
                        else
                        {
-                               ServerInstance->SNO->WriteToSnoMask('a', user->nick+" sent remote SAJOIN to make "+dest->nick+" join "+parameters[1]);
                                return CMD_SUCCESS;
                        }
                }
index 1d67f0c025040bd428a39244759c4b5e5e9c2a44..796d343ea6fa9fe1b5e69adff540e6d18c142a4d 100644 (file)
@@ -91,20 +91,23 @@ class SaslAuthenticator
                {
                 case SASL_INIT:
                        this->agent = msg[0];
-                       this->user->Write("AUTHENTICATE %s", msg[3].c_str());
                        this->state = SASL_COMM;
-                       break;
+                       /* fall through */
                 case SASL_COMM:
                        if (msg[0] != this->agent)
                                return this->state;
 
-                       if (msg[2] != "D")
+                       if (msg[2] == "C")
                                this->user->Write("AUTHENTICATE %s", msg[3].c_str());
-                       else
+                       else if (msg[2] == "D")
                        {
                                this->state = SASL_DONE;
                                this->result = this->GetSaslResult(msg[3]);
                        }
+                       else if (msg[2] == "M")
+                               this->user->WriteNumeric(908, "%s %s :are available SASL mechanisms", this->user->nick.c_str(), msg[3].c_str());
+                       else
+                               ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Services sent an unknown SASL message \"%s\" \"%s\"", msg[2].c_str(), msg[3].c_str());
 
                        break;
                 case SASL_DONE:
index 5f288424ca685bc0c008452b404b0f695ce694f1..8ab9c9a3ba37a79e7933e7e5e4b235672013ad85 100644 (file)
@@ -102,6 +102,24 @@ class AChannel_M : public SimpleChannelModeHandler
        AChannel_M(Module* Creator) : SimpleChannelModeHandler(Creator, "regmoderated", 'M') { }
 };
 
+static bool ReadCGIIRCExt(const char* extname, User* user, const 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;
+}
+
 class AccountExtItemImpl : public AccountExtItem
 {
  public:
@@ -121,8 +139,19 @@ class AccountExtItemImpl : public AccountExtItem
                {
                        // Logged in
                        if (IS_LOCAL(user))
-                               user->WriteNumeric(900, "%s %s :You are now logged in as %s",
-                                       user->GetFullHost().c_str(), value.c_str(), value.c_str());
+                       {
+                               const std::string* host = &user->dhost;
+                               if (user->registered != REG_ALL)
+                               {
+                                       if (!ReadCGIIRCExt("cgiirc_webirc_hostname", user, host))
+                                       {
+                                               ReadCGIIRCExt("cgiirc_webirc_ip", user, host);
+                                       }
+                               }
+
+                               user->WriteNumeric(900, "%s!%s@%s %s :You are now logged in as %s",
+                                       user->nick.c_str(), user->ident.c_str(), host->c_str(), value.c_str(), value.c_str());
+                       }
 
                        AccountEvent(creator, user, value).Send();
                }
@@ -142,6 +171,7 @@ class ModuleServicesAccount : public Module
        Channel_r m4;
        User_r m5;
        AccountExtItemImpl accountname;
+       bool checking_ban;
  public:
        ModuleServicesAccount() : m1(this), m2(this), m3(this), m4(this), m5(this),
                accountname(this)
@@ -219,8 +249,7 @@ class ModuleServicesAccount : public Module
 
        ModResult OnCheckBan(User* user, Channel* chan, const std::string& mask) CXX11_OVERRIDE
        {
-               static bool checking = false;
-               if (checking)
+               if (checking_ban)
                        return MOD_RES_PASSTHRU;
 
                if ((mask.length() > 2) && (mask[1] == ':'))
@@ -240,9 +269,9 @@ class ModuleServicesAccount : public Module
 
                                /* If we made it this far we know the user isn't registered
                                        so just deny if it matches */
-                               checking = true;
+                               checking_ban = true;
                                bool result = chan->CheckBan(user, mask.substr(2));
-                               checking = false;
+                               checking_ban = false;
 
                                if (result)
                                        return MOD_RES_DENY;
index 7a3b2d352099105b645e9bc3f9b09ea773fc0bcb..783f7d3feafc1b16e3336ea8699cb575e160f770 100644 (file)
@@ -42,7 +42,7 @@ class SeeWhois : public SimpleUserModeHandler
 class WhoisNoticeCmd : public Command
 {
  public:
-       WhoisNoticeCmd(Module* Creator) : Command(Creator,"WHOISNOTICE", 1)
+       WhoisNoticeCmd(Module* Creator) : Command(Creator,"WHOISNOTICE", 2)
        {
                flags_needed = FLAG_SERVERONLY;
        }
index fe741862131f4d90c75e853e63975917c6966023..3a213c6e7c2e0b2c43d8526a75f3137d04736767 100644 (file)
@@ -85,7 +85,7 @@ class CommandSVSSilence : public Command
 
                if (IS_LOCAL(u))
                {
-                       ServerInstance->Parser->CallHandler("SILENCE", std::vector<std::string>(++parameters.begin(), parameters.end()), u);
+                       ServerInstance->Parser->CallHandler("SILENCE", std::vector<std::string>(parameters.begin() + 1, parameters.end()), u);
                }
 
                return CMD_SUCCESS;
@@ -301,7 +301,7 @@ class ModuleSilence : public Module
 
        void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
        {
-               maxsilence = ServerInstance->Config->ConfValue("showwhois")->getInt("maxentries", 32);
+               maxsilence = ServerInstance->Config->ConfValue("silence")->getInt("maxentries", 32);
                if (!maxsilence)
                        maxsilence = 32;
        }
index 9a7cddec3ce6e395ef48625641ac23dd77d67ea6..671e102691af8a0bd7a3f3762cd135a4acf7fad7 100644 (file)
@@ -38,6 +38,7 @@
 ModuleSpanningTree::ModuleSpanningTree()
        : rconnect(this), rsquit(this), map(this)
        , commands(NULL), DNS(this, "DNS")
+       , KeepNickTS(false)
 {
 }
 
@@ -246,7 +247,7 @@ void ModuleSpanningTree::ConnectServer(Link* x, Autoconnect* y)
 {
        bool ipvalid = true;
 
-       if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name)))
+       if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name), rfc_case_insensitive_map))
        {
                ServerInstance->SNO->WriteToSnoMask('l', "CONNECT: Not connecting to myself.");
                return;
@@ -377,9 +378,9 @@ ModResult ModuleSpanningTree::HandleConnect(const std::vector<std::string>& para
        for (std::vector<reference<Link> >::iterator i = Utils->LinkBlocks.begin(); i < Utils->LinkBlocks.end(); i++)
        {
                Link* x = *i;
-               if (InspIRCd::Match(x->Name.c_str(),parameters[0]))
+               if (InspIRCd::Match(x->Name.c_str(),parameters[0], rfc_case_insensitive_map))
                {
-                       if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name)))
+                       if (InspIRCd::Match(ServerInstance->Config->ServerName, assign(x->Name), rfc_case_insensitive_map))
                        {
                                RemoteMessage(user, "*** CONNECT: Server \002%s\002 is ME, not connecting.",x->Name.c_str());
                                return MOD_RES_DENY;
@@ -529,7 +530,7 @@ void ModuleSpanningTree::OnChangeName(User* user, const std::string &gecos)
        if (user->registered != REG_ALL || !IS_LOCAL(user))
                return;
 
-       CmdBuilder(user, "FNAME").push(gecos).Broadcast();
+       CmdBuilder(user, "FNAME").push_last(gecos).Broadcast();
 }
 
 void ModuleSpanningTree::OnChangeIdent(User* user, const std::string &ident)
@@ -587,11 +588,12 @@ void ModuleSpanningTree::OnUserPostNick(User* user, const std::string &oldnick)
 
                /** IMPORTANT: We don't update the TS if the oldnick is just a case change of the newnick!
                 */
-               if (irc::string(user->nick.c_str()) != assign(oldnick))
+               if ((irc::string(user->nick.c_str()) != assign(oldnick)) && (!this->KeepNickTS))
                        user->age = ServerInstance->Time();
 
                params.push_back(ConvToStr(user->age));
                params.Broadcast();
+               this->KeepNickTS = false;
        }
        else if (!loopCall && user->nick == user->uuid)
        {
index 513e86a2f2b97967a5f4cc9657b61ad3a0083c71..12667aebf0b4d494508eb0e618766168ac583937 100644 (file)
@@ -77,6 +77,11 @@ class ModuleSpanningTree : public Module
         */
        bool SplitInProgress;
 
+       /** If true OnUserPostNick() won't update the nick TS before sending the NICK,
+        * used when handling SVSNICK.
+        */
+       bool KeepNickTS;
+
        /** Constructor
         */
        ModuleSpanningTree();
index a504afbd7b25faacf61c9c49fda3f071c0dbca4e..b3480eb55404bcc726c3187ce81f18bab7f9eeb0 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "inspircd.h"
 
+#include "main.h"
 #include "commands.h"
 
 CmdResult CommandSVSNick::Handle(User* user, std::vector<std::string>& parameters)
@@ -32,17 +33,28 @@ CmdResult CommandSVSNick::Handle(User* user, std::vector<std::string>& parameter
                if (isdigit(nick[0]))
                        nick = u->uuid;
 
+               // Don't update the TS if the nick is exactly the same
+               if (u->nick == nick)
+                       return CMD_FAILURE;
+
+               time_t NickTS = ConvToInt(parameters[2]);
+               if (NickTS <= 0)
+                       return CMD_FAILURE;
+
+               ModuleSpanningTree* st = (ModuleSpanningTree*)(Module*)creator;
+               st->KeepNickTS = true;
+               u->age = NickTS;
+
                if (!u->ForceNickChange(nick))
                {
                        /* buh. UID them */
                        if (!u->ForceNickChange(u->uuid))
                        {
                                ServerInstance->Users->QuitUser(u, "Nickname collision");
-                               return CMD_SUCCESS;
                        }
                }
 
-               u->age = ConvToInt(parameters[2]);
+               st->KeepNickTS = false;
        }
 
        return CMD_SUCCESS;
index fd51fb6b4c9d88802b9f340846e9836937f7ce7e..de96b073d65450959183212fcdc21c1c9dfb5570 100644 (file)
@@ -363,7 +363,7 @@ Link* SpanningTreeUtilities::FindLink(const std::string& name)
        for (std::vector<reference<Link> >::iterator i = LinkBlocks.begin(); i != LinkBlocks.end(); ++i)
        {
                Link* x = *i;
-               if (InspIRCd::Match(x->Name.c_str(), name.c_str()))
+               if (InspIRCd::Match(x->Name.c_str(), name.c_str(), rfc_case_insensitive_map))
                {
                        return x;
                }
index b1b454e63d99547004daec9ffd1d67b205bd79a4..c821f63bb3e744e3d5cf5de24da0e46a484dff31 100644 (file)
 #include "inspircd.h"
 #include "xline.h"
 
+namespace
+{
+       bool silent;
+}
+
 /** Holds a SVSHold item
  */
 class SVSHold : public XLine
@@ -48,6 +53,15 @@ public:
                return InspIRCd::Match(s, nickname);
        }
 
+       void DisplayExpiry()
+       {
+               if (!silent)
+               {
+                       ServerInstance->SNO->WriteToSnoMask('x', "Removing expired SVSHOLD %s (set by %s %ld seconds ago)",
+                               nickname.c_str(), source.c_str(), (long)(ServerInstance->Time() - set_time));
+               }
+       }
+
        const std::string& Displayable()
        {
                return nickname;
@@ -99,7 +113,8 @@ class CommandSvshold : public Command
                {
                        if (ServerInstance->XLines->DelLine(parameters[0].c_str(), "SVSHOLD", user))
                        {
-                               ServerInstance->SNO->WriteToSnoMask('x',"%s removed SVSHOLD on %s",user->nick.c_str(),parameters[0].c_str());
+                               if (!silent)
+                                       ServerInstance->SNO->WriteToSnoMask('x',"%s removed SVSHOLD on %s",user->nick.c_str(),parameters[0].c_str());
                        }
                        else
                        {
@@ -116,6 +131,9 @@ class CommandSvshold : public Command
 
                        if (ServerInstance->XLines->AddLine(r, user))
                        {
+                               if (silent)
+                                       return CMD_SUCCESS;
+
                                if (!duration)
                                {
                                        ServerInstance->SNO->WriteGlobalSno('x', "%s added permanent SVSHOLD for %s: %s", user->nick.c_str(), parameters[0].c_str(), parameters[2].c_str());
@@ -159,6 +177,12 @@ class ModuleSVSHold : public Module
                ServerInstance->XLines->RegisterFactory(&s);
        }
 
+       void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
+       {
+               ConfigTag* tag = ServerInstance->Config->ConfValue("svshold");
+               silent = tag->getBool("silent");
+       }
+
        ModResult OnStats(char symbol, User* user, string_list &out) CXX11_OVERRIDE
        {
                if(symbol != 'S')
index 6eaeb285f66c83eee3d07a719a96736c95929725..97ad841f12e37e09f4c2ae6619f5adb5387ed527 100644 (file)
@@ -35,7 +35,12 @@ class CommandUninvite : public Command
 
        CmdResult Handle (const std::vector<std::string> &parameters, User *user)
        {
-               User* u = ServerInstance->FindNick(parameters[0]);
+               User* u;
+               if (IS_LOCAL(user))
+                       u = ServerInstance->FindNickOnly(parameters[0]);
+               else
+                       u = ServerInstance->FindNick(parameters[0]);
+
                Channel* c = ServerInstance->FindChan(parameters[1]);
 
                if ((!c) || (!u) || (u->registered != REG_ALL))
index f4e67d6bf7eba29264d538cd4c5107925c89536e..96505a047d09ea8bcdada6479a421bf90af901ab 100644 (file)
@@ -40,7 +40,7 @@ class CommandUserip : public Command
 
                for (int i = 0; i < (int)parameters.size(); i++)
                {
-                       User *u = ServerInstance->FindNick(parameters[i]);
+                       User *u = ServerInstance->FindNickOnly(parameters[i]);
                        if ((u) && (u->registered == REG_ALL))
                        {
                                // Anyone may query their own IP
index 9ec7544f24f67ae440c295d72804b0589da12cf0..4ebed1ccd7117684f61c747729c790ae6899d2a7 100644 (file)
@@ -262,35 +262,41 @@ bool irc::sockets::sockaddrs::operator==(const irc::sockets::sockaddrs& other) c
 static void sa2cidr(irc::sockets::cidr_mask& cidr, const irc::sockets::sockaddrs& sa, int range)
 {
        const unsigned char* base;
+       unsigned char target_byte;
        cidr.type = sa.sa.sa_family;
+
+       memset(cidr.bits, 0, sizeof(cidr.bits));
+
        if (cidr.type == AF_INET)
        {
+               target_byte = sizeof(sa.in4.sin_addr);
                base = (unsigned char*)&sa.in4.sin_addr;
                if (range > 32)
                        range = 32;
        }
        else if (cidr.type == AF_INET6)
        {
+               target_byte = sizeof(sa.in6.sin6_addr);
                base = (unsigned char*)&sa.in6.sin6_addr;
                if (range > 128)
                        range = 128;
        }
        else
        {
-               base = (unsigned char*)"";
-               range = 0;
+               cidr.length = 0;
+               return;
        }
        cidr.length = range;
        unsigned int border = range / 8;
        unsigned int bitmask = (0xFF00 >> (range & 7)) & 0xFF;
-       for(unsigned int i=0; i < 16; i++)
+       for(unsigned int i=0; i < target_byte; i++)
        {
                if (i < border)
                        cidr.bits[i] = base[i];
                else if (i == border)
                        cidr.bits[i] = base[i] & bitmask;
                else
-                       cidr.bits[i] = 0;
+                       return;
        }
 }
 
index eff72033d021e9c2af29920748c7ce512630734d..dab3aad6c402f5993e397c2e462905935f5031b5 100644 (file)
@@ -761,7 +761,7 @@ const std::string& User::GetIPString()
                irc::sockets::satoap(client_sa, cachedip, port);
                /* IP addresses starting with a : on irc are a Bad Thing (tm) */
                if (cachedip[0] == ':')
-                       cachedip.insert(0,1,'0');
+                       cachedip.insert(cachedip.begin(),1,'0');
        }
 
        return cachedip;