From 7d7250484c352c13830e63ae41ee8faae40a9bd5 Mon Sep 17 00:00:00 2001 From: brain Date: Sun, 25 May 2008 17:30:43 +0000 Subject: [PATCH] First phase of conversion to dynamic limits on all the lengths, configured via the tag (the tag isnt there yet, these all just run on defaults in the class constructor) git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@9802 e03df62e-2008-0410-955e-edbf42e46eb7 --- configure | 104 +----------------------- include/configreader.h | 29 +++++-- include/hashcomp.h | 3 +- include/inspircd.h | 8 +- make/configure.pm | 22 +---- src/channels.cpp | 6 +- src/commands/cmd_away.cpp | 2 +- src/commands/cmd_join.cpp | 4 +- src/commands/cmd_kick.cpp | 8 +- src/commands/cmd_kill.cpp | 6 +- src/commands/cmd_nick.cpp | 20 ++--- src/commands/cmd_notice.cpp | 5 +- src/commands/cmd_oper.cpp | 2 +- src/commands/cmd_privmsg.cpp | 5 +- src/commands/cmd_stats.cpp | 10 +-- src/commands/cmd_topic.cpp | 8 +- src/commands/cmd_user.cpp | 6 +- src/configreader.cpp | 4 +- src/cull_list.cpp | 4 +- src/hashcomp.cpp | 4 +- src/helperfuncs.cpp | 20 ++--- src/mode.cpp | 2 +- src/modules/m_banredirect.cpp | 2 +- src/modules/m_chanprotect.cpp | 2 +- src/modules/m_chgident.cpp | 2 +- src/modules/m_chgname.cpp | 2 +- src/modules/m_conn_join.cpp | 2 +- src/modules/m_denychans.cpp | 4 +- src/modules/m_ident.cpp | 20 ++--- src/modules/m_nicklock.cpp | 10 ++- src/modules/m_operjoin.cpp | 4 +- src/modules/m_redirect.cpp | 4 +- src/modules/m_sajoin.cpp | 4 +- src/modules/m_sanick.cpp | 10 +-- src/modules/m_setident.cpp | 2 +- src/modules/m_setname.cpp | 2 +- src/modules/m_spanningtree/capab.cpp | 40 +++------ src/modules/m_spanningtree/fjoin.cpp | 2 +- src/modules/m_spanningtree/ftopic.cpp | 2 +- src/modules/m_spanningtree/netburst.cpp | 24 +++--- src/modules/m_spanningtree/opertype.cpp | 4 +- src/modules/m_spanningtree/svsjoin.cpp | 3 - src/modules/m_spanningtree/svspart.cpp | 3 - src/modules/m_spanningtree/uid.cpp | 19 +---- src/modules/m_svshold.cpp | 6 +- src/modules/m_watch.cpp | 4 +- src/server.cpp | 6 +- src/usermanager.cpp | 2 +- src/users.cpp | 6 +- 49 files changed, 172 insertions(+), 301 deletions(-) diff --git a/configure b/configure index d0c7d5356..64f80824d 100755 --- a/configure +++ b/configure @@ -97,12 +97,10 @@ our %extraobjects = (); our %extrasources = (); -our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_nick_length, - $opt_chan_length, $opt_ports, $opt_epoll, $opt_kqueue, $opt_noports, - $opt_noepoll, $opt_nokqueue, $opt_disablerpath, $opt_ipv6, $opt_ipv6links, - $opt_noipv6links, $opt_ident, $opt_quit, $opt_topic, $opt_maxbuf, $opt_kick, - $opt_gecos, $opt_away, $opt_modes, $opt_disable_debug, $opt_maxchans, - $opt_opermaxchans, $opt_freebsd_port); +our ($opt_use_gnutls, $opt_rebuild, $opt_use_openssl, $opt_nointeractive, $opt_ports, + $opt_epoll, $opt_kqueue, $opt_noports, $opt_noepoll, $opt_nokqueue, $opt_disablerpath, + $opt_ipv6, $opt_ipv6links, $opt_noipv6links, $opt_maxbuf, $opt_disable_debug, + $opt_freebsd_port); our ($opt_cc, $opt_base_dir, $opt_config_dir, $opt_module_dir, $opt_binary_dir, $opt_library_dir); @@ -121,8 +119,6 @@ GetOptions ( 'rebuild' => \$opt_rebuild, 'enable-openssl' => \$opt_use_openssl, 'disable-interactive' => \$opt_nointeractive, - 'with-nick-length=i' => \$opt_nick_length, - 'with-channel-length=i' => \$opt_chan_length, 'enable-ports' => \$opt_ports, 'enable-epoll' => \$opt_epoll, 'enable-kqueue' => \$opt_kqueue, @@ -134,14 +130,7 @@ GetOptions ( 'enable-remote-ipv6' => \$opt_ipv6links, 'disable-remote-ipv6' => \$opt_noipv6links, 'with-cc=s' => \$opt_cc, - 'with-ident-length=i' => \$opt_ident, - 'with-quit-length=i' => \$opt_quit, - 'with-topic-length=i' => \$opt_topic, 'with-maxbuf=i' => \$opt_maxbuf, - 'with-kick-length=i' => \$opt_kick, - 'with-gecos-length=i' => \$opt_gecos, - 'with-away-length=i' => \$opt_away, - 'with-max-modes=i' => \$opt_modes, 'enable-freebsd-ports-openssl' => \$opt_freebsd_port, 'prefix=s' => \$opt_base_dir, 'config-dir=s' => \$opt_config_dir, @@ -178,13 +167,6 @@ our $non_interactive = ( (defined $opt_base_dir) || (defined $opt_binary_dir) || (defined $opt_nointeractive) || - (defined $opt_away) || - (defined $opt_gecos) || - (defined $opt_kick) || - (defined $opt_modes) || - (defined $opt_topic) || - (defined $opt_quit) || - (defined $opt_ident) || (defined $opt_cc) || (defined $opt_ipv6) || (defined $opt_ipv6links) || @@ -192,10 +174,6 @@ our $non_interactive = ( (defined $opt_kqueue) || (defined $opt_epoll) || (defined $opt_ports) || - (defined $opt_maxchans) || - (defined $opt_opermaxchans) || - (defined $opt_chan_length) || - (defined $opt_nick_length) || (defined $opt_use_openssl) || (defined $opt_nokqueue) || (defined $opt_noepoll) || @@ -287,21 +265,6 @@ else $config{OPTIMISATI} = "-O2"; # DEBUGGING OFF! } -$config{NICK_LENGT} = "31"; # Default Nick Length -if (defined $opt_nick_length) -{ - $config{NICK_LENGT} = $opt_nick_length; -} -$config{CHAN_LENGT} = "64"; # Default Channel Name Length -if (defined $opt_chan_length) -{ - $config{CHAN_LENGT} = $opt_chan_length; -} -$config{MAXI_MODES} = "20"; # Default Max. Number of Modes set at once. -if (defined $opt_modes) -{ - $config{MAXI_MODES} = $opt_modes; -} $config{HAS_STRLCPY} = "false"; # strlcpy Check. $config{HAS_STDINT} = "false"; # stdint.h check $config{USE_KQUEUE} = "y"; # kqueue enabled @@ -367,37 +330,7 @@ if (defined $opt_cc) our $exec = $config{CC} . " -dumpversion | cut -c 1"; chomp($config{GCCVER} = `$exec`); # Major GCC Version $config{MAKEORDER} = "ircd mods"; # build order -$config{MAX_IDENT} = "12"; # max ident size -$config{MAX_QUIT} = "255"; # max quit message size -$config{MAX_TOPIC} = "307"; # max topic size -$config{MAX_KICK} = "255"; # max kick message size -$config{MAX_GECOS} = "128"; # max GECOS size -$config{MAX_AWAY} = "200"; # max AWAY size $config{MAXBUF} = "512"; # Max buffer size -if (defined $opt_ident) -{ - $config{MAX_IDENT} = $opt_ident; -} -if (defined $opt_quit) -{ - $config{MAX_QUIT} = $opt_quit; -} -if (defined $opt_topic) -{ - $config{MAX_TOPIC} = $opt_topic; -} -if (defined $opt_kick) -{ - $config{MAX_KICK} = $opt_kick; -} -if (defined $opt_gecos) -{ - $config{MAX_GECOS} = $opt_gecos; -} -if (defined $opt_away) -{ - $config{MAX_AWAY} = $opt_away; -} if ($config{HAS_OPENSSL} =~ /^([-[:digit:].]+)([a-z])?(\-[a-z][0-9])?$/) { $config{HAS_OPENSSL} = $1; @@ -929,24 +862,6 @@ should NOT be used. You should probably specify a newer compiler.\n\n"; else { print "\nCould not detect OpenSSL or GnuTLS. Make sure pkg-config is installed if\nyou intend to use OpenSSL, or that GnuTLS is in your path if you intend\nto use GnuTLS.\n\n"; } - - print "\nThe following questions will ask you for various figures relating\n"; - print "To your IRCd install. Please note that these should usually be left\n"; - print "as defaults unless you have a real reason to change them. If they\n"; - print "changed, then the values must be identical on all servers on your\n"; - print "network, or malfunctions and/or crashes may occur, with the exception\n"; - print "of the 'maximum number of clients' setting which may be different on\n"; - print "different servers on the network.\n\n"; - - promptnumeric("length of nicknames", "NICK_LENGT"); - promptnumeric("length of channel names", "CHAN_LENGT"); - promptnumeric("number of mode changes in one line", "MAXI_MODES"); - promptnumeric("length of an ident (username)", "MAX_IDENT"); - promptnumeric("length of a quit message", "MAX_QUIT"); - promptnumeric("length of a channel topic", "MAX_TOPIC"); - promptnumeric("length of a kick message", "MAX_KICK"); - promptnumeric("length of a GECOS (real name)", "MAX_GECOS"); - promptnumeric("length of an away message", "MAX_AWAY"); } dumphash(); @@ -1223,8 +1138,6 @@ sub writefiles { { print "Writing \e[1;32minspircd_config.h\e[0m\n"; open(FILEHANDLE, ">include/inspircd_config.h"); - my $NL = $config{NICK_LENGT}+1; - my $CL = $config{CHAN_LENGT}+1; print FILEHANDLE < operclass_t; +class ServerLimits : public Extensible +{ + public: + size_t NickMax; + size_t ChanMax; + size_t MaxModes; + size_t IdentMax; + size_t MaxQuit; + size_t MaxTopic; + size_t MaxKick; + size_t MaxGecos; + size_t MaxAway; + + /* Creating the class initialises it to the defaults + * as in 1.1's ./configure script. Reading other values + * from the config will change these values. + */ + ServerLimits() : NickMax(31), ChanMax(64), MaxModes(20), IdentMax(12), MaxQuit(255), MaxTopic(307), MaxKick(255), MaxGecos(128), MaxAway(200) + { + } +}; + /** This class holds the bulk of the runtime configuration for the ircd. * It allows for reading new config values, accessing configuration files, * and storage of the configuration data needed to run the ircd, such as @@ -275,11 +297,6 @@ class CoreExport ServerConfig : public Extensible std::map IncludedFiles; - std::map CompletedFiles; - - size_t TotalDownloaded; - size_t FileErrors; - /** Used to indicate who we announce invites to on a channel */ enum InviteAnnounceState { INVITE_ANNOUNCE_NONE, INVITE_ANNOUNCE_ALL, INVITE_ANNOUNCE_OPS, INVITE_ANNOUNCE_DYNAMIC }; @@ -295,6 +312,8 @@ class CoreExport ServerConfig : public Extensible */ ConfigDataHash config_data; + ServerLimits Limits; + /** Max number of WhoWas entries per user. */ int WhoWasGroupSize; diff --git a/include/hashcomp.h b/include/hashcomp.h index 4eb65823d..928abe809 100644 --- a/include/hashcomp.h +++ b/include/hashcomp.h @@ -174,6 +174,7 @@ namespace irc class CoreExport modestacker : public classbase { private: + InspIRCd* ServerInstance; /** The mode sequence and its parameters */ std::deque sequence; @@ -187,7 +188,7 @@ namespace irc * @param add True if the stack is adding modes, * false if it is removing them */ - modestacker(bool add); + modestacker(InspIRCd* Instance, bool add); /** Push a modeletter and its parameter onto the stack. * No checking is performed as to if this mode actually * requires a parameter. If you stack invalid mode diff --git a/include/inspircd.h b/include/inspircd.h index e729a0b2a..9d7c8e6e1 100644 --- a/include/inspircd.h +++ b/include/inspircd.h @@ -230,11 +230,11 @@ typedef std::vector > FailedPortList; class InspIRCd; DEFINE_HANDLER1(ProcessUserHandler, void, User*); -DEFINE_HANDLER1(IsNickHandler, bool, const char*); +DEFINE_HANDLER2(IsNickHandler, bool, const char*, size_t); DEFINE_HANDLER1(IsIdentHandler, bool, const char*); DEFINE_HANDLER1(FindDescriptorHandler, User*, int); DEFINE_HANDLER1(FloodQuitUserHandler, void, User*); -DEFINE_HANDLER1(IsChannelHandler, bool, const char*); +DEFINE_HANDLER2(IsChannelHandler, bool, const char*, size_t); DEFINE_HANDLER1(IsSIDHandler, bool, const std::string&); DEFINE_HANDLER1(RehashHandler, void, const std::string&); @@ -585,7 +585,7 @@ class CoreExport InspIRCd : public classbase * @param chname A channel name to verify * @return True if the name is valid */ - caller1 IsChannel; + caller2 IsChannel; /** Return true if str looks like a server ID * @param string to check against @@ -633,7 +633,7 @@ class CoreExport InspIRCd : public classbase * @param n A nickname to verify * @return True if the nick is valid */ - caller1 IsNick; + caller2 IsNick; /** Return true if an ident is valid * @param An ident to verify diff --git a/make/configure.pm b/make/configure.pm index 4f176324c..ab440f07f 100644 --- a/make/configure.pm +++ b/make/configure.pm @@ -193,21 +193,15 @@ sub dumphash() print "\e[0mConfig path:\e[1;32m\t\t\t$main::config{CONFIG_DIR}\e[0m\n"; print "\e[0mModule path:\e[1;32m\t\t\t$main::config{MODULE_DIR}\e[0m\n"; print "\e[0mLibrary path:\e[1;32m\t\t\t$main::config{LIBRARY_DIR}\e[0m\n"; - print "\e[0mMax nickname length:\e[1;32m\t\t$main::config{NICK_LENGT}\e[0m\n"; - print "\e[0mMax channel length:\e[1;32m\t\t$main::config{CHAN_LENGT}\e[0m\n"; - print "\e[0mMax mode length:\e[1;32m\t\t$main::config{MAXI_MODES}\e[0m\n"; - print "\e[0mMax ident length:\e[1;32m\t\t$main::config{MAX_IDENT}\e[0m\n"; - print "\e[0mMax quit length:\e[1;32m\t\t$main::config{MAX_QUIT}\e[0m\n"; - print "\e[0mMax topic length:\e[1;32m\t\t$main::config{MAX_TOPIC}\e[0m\n"; - print "\e[0mMax kick length:\e[1;32m\t\t$main::config{MAX_KICK}\e[0m\n"; - print "\e[0mMax name length:\e[1;32m\t\t$main::config{MAX_GECOS}\e[0m\n"; - print "\e[0mMax away length:\e[1;32m\t\t$main::config{MAX_AWAY}\e[0m\n"; print "\e[0mGCC Version Found:\e[1;32m\t\t$main::config{GCCVER}.x\e[0m\n"; print "\e[0mCompiler program:\e[1;32m\t\t$main::config{CC}\e[0m\n"; print "\e[0mIPv6 Support:\e[1;32m\t\t\t$main::config{IPV6}\e[0m\n"; print "\e[0mIPv6 to IPv4 Links:\e[1;32m\t\t$main::config{SUPPORT_IP6LINKS}\e[0m\n"; print "\e[0mGnuTLS Support:\e[1;32m\t\t\t$main::config{USE_GNUTLS}\e[0m\n"; print "\e[0mOpenSSL Support:\e[1;32m\t\t$main::config{USE_OPENSSL}\e[0m\n\n"; + print "\e[1;32mImportant note: The maximum length values are now configured in the\e[0m\n"; + print "\e[1;32m configuration file, not in ./configure! See the \e[0m\n"; + print "\e[1;32m tag in the configuration file for more information.\e[0m\n\n"; } sub is_dir @@ -258,8 +252,6 @@ InspIRCd 1.0.x, are also allowed. --clean Remove .config.cache file and go interactive --enable-gnutls Enable GnuTLS module [no] --enable-openssl Enable OpenSSL module [no] - --with-nick-length=[n] Specify max. nick length [32] - --with-channel-length=[n] Specify max. channel length [64] --enable-optimization=[n] Optimize using -O[n] gcc flag --enable-epoll Enable epoll() where supported [set] --enable-kqueue Enable kqueue() where supported [set] @@ -273,14 +265,6 @@ InspIRCd 1.0.x, are also allowed. --disable-remote-ipv6 Do not allow remote ipv6 servers [not set] --with-cc=[filename] Use an alternative g++ binary to build InspIRCd [g++] - --with-ident-length=[n] Specify max length of ident [12] - --with-quit-length=[n] Specify max length of quit [200] - --with-topic-length=[n] Specify max length of topic [350] - --with-kick-length=[n] Specify max length of kick [200] - --with-gecos-length=[n] Specify max length of gecos [150] - --with-away-length=[n] Specify max length of away [150] - --with-max-modes=[n] Specify max modes per line which - have parameters [20] --with-maxbuf=[n] Change the per message buffer size [512] DO NOT ALTER THIS OPTION WITHOUT GOOD REASON AS IT *WILL* BREAK CLIENTS!!! diff --git a/src/channels.cpp b/src/channels.cpp index f0cd66dbf..d03f80f64 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -25,7 +25,7 @@ Channel::Channel(InspIRCd* Instance, const std::string &cname, time_t ts) : Serv throw CoreException("Cannot create duplicate channel " + cname); (*(ServerInstance->chanlist))[cname.c_str()] = this; - this->name.assign(cname, 0, CHANMAX); + this->name.assign(cname, 0, ServerInstance->Config->Limits.ChanMax); this->created = ts ? ts : ServerInstance->Time(); this->age = this->created; @@ -254,7 +254,7 @@ Channel* Channel::JoinUser(InspIRCd* Instance, User *user, const char* cn, bool } } - strlcpy(cname, cn, CHANMAX); + strlcpy(cname, cn, Instance->Config->Limits.ChanMax); Ptr = Instance->FindChan(cname); if (!Ptr) @@ -917,7 +917,7 @@ void Channel::UserList(User *user, CUList *ulist) size_t ptrlen = 0; - if (curlen > (480-NICKMAX)) + if (curlen + prefixlist.length() + nick.length() + 1 > 480) { /* list overflowed into multiple numerics */ user->WriteServ(std::string(list)); diff --git a/src/commands/cmd_away.cpp b/src/commands/cmd_away.cpp index 7fac7ae6d..6dccf9759 100644 --- a/src/commands/cmd_away.cpp +++ b/src/commands/cmd_away.cpp @@ -33,7 +33,7 @@ CmdResult CommandAway::Handle (const std::vector& parameters, User return CMD_FAILURE; user->awaytime = ServerInstance->Time(); - user->awaymsg.assign(parameters[0], 0, MAXAWAY); + user->awaymsg.assign(parameters[0], 0, ServerInstance->Config->Limits.MaxAway); user->WriteNumeric(306, "%s :You have been marked as being away",user->nick.c_str()); } diff --git a/src/commands/cmd_join.cpp b/src/commands/cmd_join.cpp index b27007507..c19e7c015 100644 --- a/src/commands/cmd_join.cpp +++ b/src/commands/cmd_join.cpp @@ -28,7 +28,7 @@ CmdResult CommandJoin::Handle (const std::vector& parameters, User if (ServerInstance->Parser->LoopCall(user, this, parameters, 0, 1)) return CMD_SUCCESS; - if (ServerInstance->IsChannel(parameters[0].c_str())) + if (ServerInstance->IsChannel(parameters[0].c_str(), ServerInstance->Config->Limits.ChanMax)) { Channel::JoinUser(ServerInstance, user, parameters[0].c_str(), false, parameters[1].c_str(), false); return CMD_SUCCESS; @@ -39,7 +39,7 @@ CmdResult CommandJoin::Handle (const std::vector& parameters, User if (ServerInstance->Parser->LoopCall(user, this, parameters, 0)) return CMD_SUCCESS; - if (ServerInstance->IsChannel(parameters[0].c_str())) + if (ServerInstance->IsChannel(parameters[0].c_str(), ServerInstance->Config->Limits.ChanMax)) { Channel::JoinUser(ServerInstance, user, parameters[0].c_str(), false, "", false); return CMD_SUCCESS; diff --git a/src/commands/cmd_kick.cpp b/src/commands/cmd_kick.cpp index 174800cf5..a0ff5d1c3 100644 --- a/src/commands/cmd_kick.cpp +++ b/src/commands/cmd_kick.cpp @@ -23,7 +23,7 @@ extern "C" DllExport Command* init_command(InspIRCd* Instance) */ CmdResult CommandKick::Handle (const std::vector& parameters, User *user) { - char reason[MAXKICK]; + std::string reason; Channel* c = ServerInstance->FindChan(parameters[0]); User* u = ServerInstance->FindNick(parameters[1]); @@ -44,14 +44,14 @@ CmdResult CommandKick::Handle (const std::vector& parameters, User if (parameters.size() > 2) { - strlcpy(reason, parameters[2].c_str(), MAXKICK - 1); + reason.assign(parameters[2], 0, ServerInstance->Config->Limits.MaxKick); } else { - strlcpy(reason, user->nick.c_str(), MAXKICK - 1); + reason.assign(user->nick, 0, ServerInstance->Config->Limits.MaxKick); } - if (!c->KickUser(user, u, reason)) + if (!c->KickUser(user, u, reason.c_str())) /* Nobody left here, delete the Channel */ delete c; diff --git a/src/commands/cmd_kill.cpp b/src/commands/cmd_kill.cpp index f656c5701..02e80b4f2 100644 --- a/src/commands/cmd_kill.cpp +++ b/src/commands/cmd_kill.cpp @@ -54,18 +54,18 @@ CmdResult CommandKill::Handle (const std::vector& parameters, User if (*ServerInstance->Config->HideKillsServer) { // hidekills is on, use it - snprintf(killreason, MAXQUIT, "Killed (%s (%s))", ServerInstance->Config->HideKillsServer, parameters[1].c_str()); + snprintf(killreason, ServerInstance->Config->Limits.MaxQuit, "Killed (%s (%s))", ServerInstance->Config->HideKillsServer, parameters[1].c_str()); } else { // hidekills is off, do nothing - snprintf(killreason, MAXQUIT, "Killed (%s (%s))", user->nick.c_str(), parameters[1].c_str()); + snprintf(killreason, ServerInstance->Config->Limits.MaxQuit, "Killed (%s (%s))", user->nick.c_str(), parameters[1].c_str()); } } else { /* Leave it alone, remote server has already formatted it */ - strlcpy(killreason, parameters[1].c_str(), MAXQUIT); + strlcpy(killreason, parameters[1].c_str(), ServerInstance->Config->Limits.MaxQuit); } /* diff --git a/src/commands/cmd_nick.cpp b/src/commands/cmd_nick.cpp index 0391323dc..0eb55ccfe 100644 --- a/src/commands/cmd_nick.cpp +++ b/src/commands/cmd_nick.cpp @@ -27,7 +27,7 @@ extern "C" DllExport Command* init_command(InspIRCd* Instance) */ CmdResult CommandNick::Handle (const std::vector& parameters, User *user) { - char oldnick[NICKMAX]; + std::string oldnick; if (parameters[0].empty()) { @@ -36,7 +36,7 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User return CMD_FAILURE; } - if (((!ServerInstance->IsNick(parameters[0].c_str()))) && (IS_LOCAL(user))) + if (((!ServerInstance->IsNick(parameters[0].c_str(), ServerInstance->Config->Limits.NickMax))) && (IS_LOCAL(user))) { if (!allowinvalid) { @@ -59,11 +59,9 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User if (assign(user->nick) == parameters[0]) { - ServerInstance->Logs->Log("nick", DEBUG, "Change to same nick '%s' %d '%s' '%d'", user->nick.c_str(), user->nick.length(), parameters[0].c_str(), parameters[0].length()); /* If its exactly the same, even case, dont do anything. */ if (parameters[0] == user->nick) { - ServerInstance->Logs->Log("nick", DEBUG, "Not even a case change"); return CMD_SUCCESS; } @@ -71,14 +69,14 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User * able to do silly things like this even though the RFC says * the nick AAA is the same as the nick aaa. */ - strlcpy(oldnick, user->nick.c_str(), NICKMAX - 1); + oldnick.assign(user->nick, 0, ServerInstance->Config->Limits.NickMax); int MOD_RESULT = 0; - FOREACH_RESULT(I_OnUserPreNick,OnUserPreNick(user,parameters[0].c_str())); + FOREACH_RESULT(I_OnUserPreNick,OnUserPreNick(user,parameters[0])); if (MOD_RESULT) return CMD_FAILURE; if (user->registered == REG_ALL) user->WriteCommon("NICK %s",parameters[0].c_str()); - user->nick.assign(parameters[0], 0, NICKMAX - 1); + user->nick.assign(parameters[0], 0, ServerInstance->Config->Limits.NickMax); user->InvalidateCache(); FOREACH_MOD(I_OnUserPostNick,OnUserPostNick(user,oldnick)); return CMD_SUCCESS; @@ -122,7 +120,7 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User InUse->WriteTo(InUse, "NICK %s", InUse->uuid.c_str()); InUse->WriteNumeric(433, "%s %s :Nickname overruled.", InUse->nick.c_str(), InUse->nick.c_str()); InUse->UpdateNickHash(InUse->uuid.c_str()); - InUse->nick.assign(InUse->uuid, 0, NICKMAX - 1); + InUse->nick.assign(InUse->uuid, 0, ServerInstance->Config->Limits.NickMax); InUse->InvalidateCache(); InUse->registered &= ~REG_NICK; } @@ -145,7 +143,7 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User if (user->registered == REG_ALL) user->WriteCommon("NICK %s", parameters[0].c_str()); - strlcpy(oldnick, user->nick.c_str(), NICKMAX - 1); + oldnick.assign(user->nick, 0, ServerInstance->Config->Limits.NickMax); /* change the nick of the user in the users_hash */ user = user->UpdateNickHash(parameters[0].c_str()); @@ -154,7 +152,7 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User if (!user) return CMD_FAILURE; - user->nick.assign(parameters[0], 0, NICKMAX - 1); + user->nick.assign(parameters[0], 0, ServerInstance->Config->Limits.NickMax); user->InvalidateCache(); /* Update display nicks */ @@ -181,7 +179,7 @@ CmdResult CommandNick::Handle (const std::vector& parameters, User if (user->registered == REG_ALL) { user->IncreasePenalty(10); - FOREACH_MOD(I_OnUserPostNick,OnUserPostNick(user,oldnick)); + FOREACH_MOD(I_OnUserPostNick,OnUserPostNick(user, oldnick)); } return CMD_SUCCESS; diff --git a/src/commands/cmd_notice.cpp b/src/commands/cmd_notice.cpp index 5086f3f4f..9cf4800a4 100644 --- a/src/commands/cmd_notice.cpp +++ b/src/commands/cmd_notice.cpp @@ -130,8 +130,9 @@ CmdResult CommandNotice::Handle (const std::vector& parameters, Use if (targetserver) { - char nickonly[NICKMAX+1]; - strlcpy(nickonly, destnick, targetserver - destnick + 1); + std::string nickonly; + + nickonly.assign(destnick, 0, targetserver - destnick + 1); dest = ServerInstance->FindNickOnly(nickonly); if (dest && strcasecmp(dest->server, targetserver + 1)) { diff --git a/src/commands/cmd_oper.cpp b/src/commands/cmd_oper.cpp index 1ce7dc49d..97134f038 100644 --- a/src/commands/cmd_oper.cpp +++ b/src/commands/cmd_oper.cpp @@ -80,7 +80,7 @@ CmdResult CommandOper::Handle (const std::vector& parameters, User if (!strcmp(TypeName,OperType)) { /* found this oper's opertype */ - if (!ServerInstance->IsNick(TypeName)) + if (!ServerInstance->IsNick(TypeName, ServerInstance->Config->Limits.NickMax)) { user->WriteNumeric(491, "%s :Invalid oper type (oper types must follow the same syntax as nicknames)",user->nick.c_str()); ServerInstance->SNO->WriteToSnoMask('o',"CONFIGURATION ERROR! Oper type '%s' contains invalid characters",OperType); diff --git a/src/commands/cmd_privmsg.cpp b/src/commands/cmd_privmsg.cpp index 842635ae2..0086bb72d 100644 --- a/src/commands/cmd_privmsg.cpp +++ b/src/commands/cmd_privmsg.cpp @@ -132,8 +132,9 @@ CmdResult CommandPrivmsg::Handle (const std::vector& parameters, Us if (targetserver) { - char nickonly[NICKMAX+1]; - strlcpy(nickonly, destnick, targetserver - destnick + 1); + std::string nickonly; + + nickonly.assign(destnick, 0, targetserver - destnick + 1); dest = ServerInstance->FindNickOnly(nickonly); if (dest && strcasecmp(dest->server, targetserver + 1)) { diff --git a/src/commands/cmd_stats.cpp b/src/commands/cmd_stats.cpp index 9da5f1aeb..fafa97581 100644 --- a/src/commands/cmd_stats.cpp +++ b/src/commands/cmd_stats.cpp @@ -264,10 +264,7 @@ DllExport void DoStats(InspIRCd* ServerInstance, char statschar, User* user, str for (std::vector::iterator n = ServerInstance->Users->local_users.begin(); n != ServerInstance->Users->local_users.end(); n++) { User* i = *n; - if (ServerInstance->IsNick(i->nick.c_str())) - { - results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->sendq.length())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age)); - } + results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->dhost+"] "+ConvToStr(i->sendq.length())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age)); } break; @@ -277,10 +274,7 @@ DllExport void DoStats(InspIRCd* ServerInstance, char statschar, User* user, str for (std::vector::iterator n = ServerInstance->Users->local_users.begin(); n != ServerInstance->Users->local_users.end(); n++) { User* i = *n; - if (ServerInstance->IsNick(i->nick.c_str())) - { - results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->sendq.length())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age)); - } + results.push_back(sn+" 211 "+user->nick+" "+i->nick+"["+i->ident+"@"+i->GetIPString()+"] "+ConvToStr(i->sendq.length())+" "+ConvToStr(i->cmds_out)+" "+ConvToStr(i->bytes_out)+" "+ConvToStr(i->cmds_in)+" "+ConvToStr(i->bytes_in)+" "+ConvToStr(ServerInstance->Time() - i->age)); } break; diff --git a/src/commands/cmd_topic.cpp b/src/commands/cmd_topic.cpp index e723a50c9..0e1a115da 100644 --- a/src/commands/cmd_topic.cpp +++ b/src/commands/cmd_topic.cpp @@ -70,7 +70,7 @@ CmdResult CommandTopic::Handle (const std::vector& parameters, User } } - char topic[MAXTOPIC]; + std::string topic; if (IS_LOCAL(user)) { @@ -79,17 +79,17 @@ CmdResult CommandTopic::Handle (const std::vector& parameters, User */ int MOD_RESULT = 0; - strlcpy(topic, parameters[1].c_str(), MAXTOPIC); + topic.assign(parameters[1], 0, ServerInstance->Config->Limits.MaxTopic); FOREACH_RESULT(I_OnLocalTopicChange,OnLocalTopicChange(user,Ptr,topic)); if (MOD_RESULT) return CMD_FAILURE; - Ptr->topic.assign(topic, 0, MAXTOPIC); + Ptr->topic.assign(topic, 0, ServerInstance->Config->Limits.MaxTopic); } else { /* Sneaky shortcut, one string copy for a remote topic */ - Ptr->topic.assign(parameters[1], 0, MAXTOPIC); + Ptr->topic.assign(parameters[1], 0, ServerInstance->Config->Limits.MaxTopic); } Ptr->setby.assign(ServerInstance->Config->FullHostInTopic ? diff --git a/src/commands/cmd_user.cpp b/src/commands/cmd_user.cpp index 1acd901f9..7bc9307f6 100644 --- a/src/commands/cmd_user.cpp +++ b/src/commands/cmd_user.cpp @@ -40,14 +40,14 @@ CmdResult CommandUser::Handle (const std::vector& parameters, User * ~ character, and +1 for null termination, therefore we can safely use up to * IDENTMAX here. */ - user->ident.assign(parameters[0], 0, IDENTMAX); - user->fullname.assign(parameters[3].empty() ? std::string("No info") : parameters[3], 0, MAXGECOS); + user->ident.assign(parameters[0], 0, ServerInstance->Config->Limits.IdentMax); + user->fullname.assign(parameters[3].empty() ? std::string("No info") : parameters[3], 0, ServerInstance->Config->Limits.MaxGecos); user->registered = (user->registered | REG_USER); } } else { - user->WriteNumeric(462, "%s :You may not reregister",user->nick.c_str()); + user->WriteNumeric(462, "%s :You may not reregister", user->nick.c_str()); return CMD_FAILURE; } diff --git a/src/configreader.cpp b/src/configreader.cpp index e18435316..76aae190b 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -1009,7 +1009,7 @@ void ServerConfig::Read(bool bail, User* user) case DT_CHANNEL: { ValueContainerChar* vcc = (ValueContainerChar*)Values[Index].val; - if (*(vi.GetString()) && !ServerInstance->IsChannel(vi.GetString())) + if (*(vi.GetString()) && !ServerInstance->IsChannel(vi.GetString(), MAXBUF)) { ServerInstance->Threads->Mutex(false); throw CoreException("The value of <"+std::string(Values[Index].tag)+":"+Values[Index].value+"> is not a valid channel name"); @@ -1114,7 +1114,7 @@ void ServerConfig::Read(bool bail, User* user) vl.push_back(ValueItem(item)); else vl.push_back(ValueItem("")); - if (!ServerInstance->IsChannel(vl[vl.size()-1].GetString())) + if (!ServerInstance->IsChannel(vl[vl.size()-1].GetString(), MAXBUF)) throw CoreException("The value of <"+std::string(MultiValues[Index].tag)+":"+MultiValues[Index].items[valuenum]+"> number "+ConvToStr(tagnum + 1)+" is not a valid channel name"); } break; diff --git a/src/cull_list.cpp b/src/cull_list.cpp index ddbf6acae..a7f8d3316 100644 --- a/src/cull_list.cpp +++ b/src/cull_list.cpp @@ -54,8 +54,8 @@ int CullList::Apply() std::string reason; std::string oper_reason; - reason.assign(u->quitmsg, 0, MAXQUIT - 1); - oper_reason.assign(preset_reason.empty() ? preset_reason : u->operquitmsg, 0, MAXQUIT - 1); + reason.assign(u->quitmsg, 0, ServerInstance->Config->Limits.MaxQuit); + oper_reason.assign(preset_reason.empty() ? preset_reason : u->operquitmsg, 0, ServerInstance->Config->Limits.MaxQuit); if (u->registered != REG_ALL) if (ServerInstance->Users->unregistered_count) diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index a27a83f64..19f2d601c 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -318,7 +318,7 @@ CoreExport const char* irc::Spacify(const char* n) } -irc::modestacker::modestacker(bool add) : adding(add) +irc::modestacker::modestacker(InspIRCd* Instance, bool add) : ServerInstance(Instance), adding(add) { sequence.clear(); sequence.push_back(""); @@ -362,7 +362,7 @@ int irc::modestacker::GetStackedLine(std::deque &result, int max_li if (sequence.size() > 1) nextsize = sequence[1].length() + 2; - while (!sequence[0].empty() && (sequence.size() > 1) && (result.size() < MAXMODES) && ((size + nextsize) < max_line_size)) + while (!sequence[0].empty() && (sequence.size() > 1) && (result.size() < ServerInstance->Config->Limits.MaxModes) && ((size + nextsize) < max_line_size)) { result[0] += *(sequence[0].begin()); if (!sequence[1].empty()) diff --git a/src/helperfuncs.cpp b/src/helperfuncs.cpp index 8b93be245..d46f53ec7 100644 --- a/src/helperfuncs.cpp +++ b/src/helperfuncs.cpp @@ -182,9 +182,9 @@ bool InspIRCd::IsValidMask(const std::string &mask) } /* true for valid channel name, false else */ -bool IsChannelHandler::Call(const char *chname) +bool IsChannelHandler::Call(const char *chname, size_t max) { - char *c; + const char *c = chname + 1; /* check for no name - don't check for !*chname, as if it is empty, it won't be '#'! */ if (!chname || *chname != '#') @@ -192,7 +192,6 @@ bool IsChannelHandler::Call(const char *chname) return false; } - c = (char *)chname + 1; while (*c) { switch (*c) @@ -205,9 +204,10 @@ bool IsChannelHandler::Call(const char *chname) c++; } - + + size_t len = c - chname; /* too long a name - note funky pointer arithmetic here. */ - if ((c - chname) > CHANMAX) + if (len > max) { return false; } @@ -216,13 +216,13 @@ bool IsChannelHandler::Call(const char *chname) } /* true for valid nickname, false else */ -bool IsNickHandler::Call(const char* n) +bool IsNickHandler::Call(const char* n, size_t max) { if (!n || !*n) return false; - int p = 0; - for (char* i = (char*)n; *i; i++, p++) + unsigned int p = 0; + for (const char* i = n; *i; i++, p++) { if ((*i >= 'A') && (*i <= '}')) { @@ -241,7 +241,7 @@ bool IsNickHandler::Call(const char* n) } /* too long? or not -- pointer arithmetic rocks */ - return (p < NICKMAX - 1); + return (p < max); } /* return true for good ident, false else */ @@ -250,7 +250,7 @@ bool IsIdentHandler::Call(const char* n) if (!n || !*n) return false; - for (char* i = (char*)n; *i; i++) + for (const char* i = n; *i; i++) { if ((*i >= 'A') && (*i <= '}')) { diff --git a/src/mode.cpp b/src/mode.cpp index ed4b4b6b6..b778d1d5c 100644 --- a/src/mode.cpp +++ b/src/mode.cpp @@ -711,7 +711,7 @@ void ModeParser::Process(const std::vector& parameters, User *user, state_change = false; if ((output_sequence.length() + parameter_list.str().length() > 450) || (output_sequence.length() > 100) - || (parameter_count > MAXMODES)) + || (parameter_count > ServerInstance->Config->Limits.MaxModes)) { /* We cant have a mode sequence this long */ letter = mode_sequence.end() - 1; diff --git a/src/modules/m_banredirect.cpp b/src/modules/m_banredirect.cpp index a8add0c72..f786d48ee 100644 --- a/src/modules/m_banredirect.cpp +++ b/src/modules/m_banredirect.cpp @@ -114,7 +114,7 @@ class BanRedirect : public ModeWatcher if(mask[CHAN].length()) { - if(Srv->IsChannel(mask[CHAN].c_str())) + if(!IS_LOCAL(source) || Srv->IsChannel(mask[CHAN].c_str(), ServerInstance->Config->Limits.ChanMax)) { if (assign(channel->name) == mask[CHAN]) { diff --git a/src/modules/m_chanprotect.cpp b/src/modules/m_chanprotect.cpp index e44e496f8..a79eda993 100644 --- a/src/modules/m_chanprotect.cpp +++ b/src/modules/m_chanprotect.cpp @@ -68,7 +68,7 @@ class FounderProtectBase std::string item = extend + std::string(channel->name); std::vector mode_junk; mode_junk.push_back(channel->name); - irc::modestacker modestack(false); + irc::modestacker modestack(ServerInstance, false); std::deque stackresult; for (CUList::iterator i = cl->begin(); i != cl->end(); i++) diff --git a/src/modules/m_chgident.cpp b/src/modules/m_chgident.cpp index d0d77f193..3ab558b57 100644 --- a/src/modules/m_chgident.cpp +++ b/src/modules/m_chgident.cpp @@ -43,7 +43,7 @@ class CommandChgident : public Command return CMD_FAILURE; } - if (parameters[1].length() > IDENTMAX - 1) + if (parameters[1].length() > ServerInstance->Config->Limits.IdentMax) { user->WriteServ("NOTICE %s :*** CHGIDENT: Ident is too long", user->nick.c_str()); return CMD_FAILURE; diff --git a/src/modules/m_chgname.cpp b/src/modules/m_chgname.cpp index 233bb15b6..936cd72ac 100644 --- a/src/modules/m_chgname.cpp +++ b/src/modules/m_chgname.cpp @@ -43,7 +43,7 @@ class CommandChgname : public Command return CMD_FAILURE; } - if (parameters[1].length() > MAXGECOS) + if (parameters[1].length() > ServerInstance->Config->Limits.MaxGecos) { user->WriteServ("NOTICE %s :*** GECOS too long", user->nick.c_str()); return CMD_FAILURE; diff --git a/src/modules/m_conn_join.cpp b/src/modules/m_conn_join.cpp index 139414155..046176b0c 100644 --- a/src/modules/m_conn_join.cpp +++ b/src/modules/m_conn_join.cpp @@ -81,7 +81,7 @@ class ModuleConnJoin : public Module return; for(std::vector::iterator it = Joinchans.begin(); it != Joinchans.end(); it++) - if (ServerInstance->IsChannel(it->c_str())) + if (ServerInstance->IsChannel(it->c_str(), ServerInstance->Config->Limits.ChanMax)) Channel::JoinUser(ServerInstance, user, it->c_str(), false, "", false, ServerInstance->Time()); } diff --git a/src/modules/m_denychans.cpp b/src/modules/m_denychans.cpp index f28547679..e847f8c7c 100644 --- a/src/modules/m_denychans.cpp +++ b/src/modules/m_denychans.cpp @@ -45,7 +45,7 @@ class ModuleDenyChannels : public Module if (!redirect.empty()) { - if (!ServerInstance->IsChannel(redirect.c_str())) + if (!ServerInstance->IsChannel(redirect.c_str(), ServerInstance->Config->Limits.ChanMax)) { if (user) user->WriteServ("Notice %s :Invalid badchan redirect '%s'", user->nick.c_str(), redirect.c_str()); @@ -110,7 +110,7 @@ class ModuleDenyChannels : public Module } } - if (ServerInstance->IsChannel(redirect.c_str())) + if (ServerInstance->IsChannel(redirect.c_str(), ServerInstance->Config->Limits.ChanMax)) { /* simple way to avoid potential loops: don't redirect to +L channels */ Channel *newchan = ServerInstance->FindChan(redirect); diff --git a/src/modules/m_ident.cpp b/src/modules/m_ident.cpp index e7d8728d6..197a6e5e2 100644 --- a/src/modules/m_ident.cpp +++ b/src/modules/m_ident.cpp @@ -296,11 +296,11 @@ class IdentRequestSocket : public EventHandler if (i < 3) continue; - char ident[IDENTMAX + 2]; + std::string ident; /* Truncate the ident at any characters we don't like, skip leading spaces */ - int k = 0; - for (const char *j = token.c_str(); *j && (k < IDENTMAX + 1); j++) + size_t k = 0; + for (const char *j = token.c_str(); *j && (k < ServerInstance->Config->Limits.IdentMax + 1); j++) { if (*j == ' ') continue; @@ -308,17 +308,15 @@ class IdentRequestSocket : public EventHandler /* Rules taken from InspIRCd::IsIdent */ if (((*j >= 'A') && (*j <= '}')) || ((*j >= '0') && (*j <= '9')) || (*j == '-') || (*j == '.')) { - ident[k++] = *j; + ident += *j; continue; } break; } - ident[k] = '\0'; - /* Re-check with IsIdent, in case that changes and this doesn't (paranoia!) */ - if (*ident && ServerInstance->IsIdent(ident)) + if (!ident.empty() && ServerInstance->IsIdent(ident.c_str())) { result = ident; } @@ -366,9 +364,9 @@ class ModuleIdent : public Module virtual int OnUserRegister(User *user) { /* User::ident is currently the username field from USER; with m_ident loaded, that - * should be preceded by a ~. The field is actually IDENTMAX+2 characters wide. */ - if (user->ident.length() > IDENTMAX + 1) - user->ident.assign(user->ident, 0, IDENTMAX); + * should be preceded by a ~. The field is actually IdentMax+2 characters wide. */ + if (user->ident.length() > ServerInstance->Config->Limits.IdentMax + 1) + user->ident.assign(user->ident, 0, ServerInstance->Config->Limits.IdentMax); user->ident.insert(0, "~"); user->WriteServ("NOTICE Auth :*** Looking up your ident..."); @@ -457,7 +455,7 @@ class ModuleIdent : public Module user->WriteServ("NOTICE Auth :*** Could not find your ident, using %s instead.", isock->GetResult()); /* Copy the ident string to the user */ - user->ident.assign(isock->GetResult(), 0, IDENTMAX+1); + user->ident.assign(isock->GetResult(), 0, ServerInstance->Config->Limits.IdentMax + 1); /* The user isnt actually disconnecting, we call this to clean up the user */ OnUserDisconnect(user); diff --git a/src/modules/m_nicklock.cpp b/src/modules/m_nicklock.cpp index adeab2691..86054ab3e 100644 --- a/src/modules/m_nicklock.cpp +++ b/src/modules/m_nicklock.cpp @@ -48,7 +48,7 @@ class CommandNicklock : public Command } // check nick is valid - if (!ServerInstance->IsNick(parameters[1].c_str())) + if (IS_LOCAL(user) && !ServerInstance->IsNick(parameters[1].c_str(), ServerInstance->Config->Limits.NickMax)) { return CMD_FAILURE; } @@ -58,8 +58,12 @@ class CommandNicklock : public Command if (!target->ForceNickChange(parameters[1].c_str())) { - // ugh, nickchange failed for some reason -- possibly existing nick? XXX change to UID here - ServerInstance->Users->QuitUser(target, "Nickname collision"); + // ugh, nickchange failed for some reason -- possibly existing nick? + if (!target->ForceNickChange(target->uuid.c_str())) + { + // Well shit, we cant even change them to their UID (this should not happen!) + ServerInstance->Users->QuitUser(target, "Nickname collision"); + } } // give them a lock flag diff --git a/src/modules/m_operjoin.cpp b/src/modules/m_operjoin.cpp index 42415faa2..b0976b1cc 100644 --- a/src/modules/m_operjoin.cpp +++ b/src/modules/m_operjoin.cpp @@ -91,7 +91,7 @@ class ModuleOperjoin : public Module return; for(std::vector::iterator it = operChans.begin(); it != operChans.end(); it++) - if (ServerInstance->IsChannel(it->c_str())) + if (ServerInstance->IsChannel(it->c_str(), ServerInstance->Config->Limits.ChanMax)) Channel::JoinUser(ServerInstance, user, it->c_str(), override, "", false, ServerInstance->Time()); std::map >::iterator i = operTypeChans.find(user->oper); @@ -101,7 +101,7 @@ class ModuleOperjoin : public Module const std::vector& list = i->second; for (std::vector::const_iterator it = list.begin(); it != list.end(); ++it) { - if (ServerInstance->IsChannel(it->c_str())) + if (ServerInstance->IsChannel(it->c_str(), ServerInstance->Config->Limits.ChanMax)) { Channel::JoinUser(ServerInstance, user, it->c_str(), override, "", false, ServerInstance->Time()); } diff --git a/src/modules/m_redirect.cpp b/src/modules/m_redirect.cpp index 289a73dca..9c529a37d 100644 --- a/src/modules/m_redirect.cpp +++ b/src/modules/m_redirect.cpp @@ -42,9 +42,9 @@ class Redirect : public ModeHandler { Channel* c = NULL; - if (!ServerInstance->IsChannel(parameter.c_str())) + if (IS_LOCAL(source) && !ServerInstance->IsChannel(parameter.c_str(), ServerInstance->Config->Limits.ChanMax)) { - source->WriteNumeric(403, "%s %s :Invalid channel name",source->nick.c_str(), parameter.c_str()); + source->WriteNumeric(403, "%s %s :Invalid channel name", source->nick.c_str(), parameter.c_str()); parameter.clear(); return MODEACTION_DENY; } diff --git a/src/modules/m_sajoin.cpp b/src/modules/m_sajoin.cpp index 8b237674b..5be61fbf6 100644 --- a/src/modules/m_sajoin.cpp +++ b/src/modules/m_sajoin.cpp @@ -37,10 +37,10 @@ class CommandSajoin : public Command user->WriteNumeric(990, "%s :Cannot use an SA command on a u-lined client",user->nick.c_str()); return CMD_FAILURE; } - if (!ServerInstance->IsChannel(parameters[1].c_str())) + if (IS_LOCAL(source) && !ServerInstance->IsChannel(parameters[1].c_str(), ServerInstance->Config->Limits.ChanMax)) { /* we didn't need to check this for each character ;) */ - user->WriteServ("NOTICE "+std::string(user->nick)+" :*** Invalid characters in channel name"); + user->WriteServ("NOTICE "+std::string(user->nick)+" :*** Invalid characters in channel name or name too long"); return CMD_FAILURE; } diff --git a/src/modules/m_sanick.cpp b/src/modules/m_sanick.cpp index cd93377c8..83d7fabd4 100644 --- a/src/modules/m_sanick.cpp +++ b/src/modules/m_sanick.cpp @@ -38,7 +38,11 @@ class CommandSanick : public Command return CMD_FAILURE; } std::string oldnick = user->nick; - if (ServerInstance->IsNick(parameters[1].c_str())) + if (IS_LOCAL(user) && !ServerInstance->IsNick(parameters[1].c_str(), ServerInstance->Config->Limits.NickMax)) + { + user->WriteServ("NOTICE %s :*** Invalid nickname '%s'", user->nick.c_str(), parameters[1].c_str()); + } + else { if (target->ForceNickChange(parameters[1].c_str())) { @@ -52,10 +56,6 @@ class CommandSanick : public Command return CMD_FAILURE; } } - else - { - user->WriteServ("NOTICE %s :*** Invalid nickname '%s'", user->nick.c_str(), parameters[1].c_str()); - } return CMD_FAILURE; } diff --git a/src/modules/m_setident.cpp b/src/modules/m_setident.cpp index 13f5d0c92..6577ebbb3 100644 --- a/src/modules/m_setident.cpp +++ b/src/modules/m_setident.cpp @@ -35,7 +35,7 @@ class CommandSetident : public Command return CMD_FAILURE; } - if (parameters[0].size() > IDENTMAX) + if (parameters[0].size() > ServerInstance->Config->Limits.IdentMax) { user->WriteServ("NOTICE %s :*** SETIDENT: Ident is too long", user->nick.c_str()); return CMD_FAILURE; diff --git a/src/modules/m_setname.cpp b/src/modules/m_setname.cpp index eab376cab..8c35c2be2 100644 --- a/src/modules/m_setname.cpp +++ b/src/modules/m_setname.cpp @@ -35,7 +35,7 @@ class CommandSetname : public Command return CMD_FAILURE; } - if (parameters[0].size() > MAXGECOS) + if (parameters[0].size() > ServerInstance->Config->Limits.MaxGecos) { user->WriteServ("NOTICE %s :*** SETNAME: GECOS too long", user->nick.c_str()); return CMD_FAILURE; diff --git a/src/modules/m_spanningtree/capab.cpp b/src/modules/m_spanningtree/capab.cpp index 5919c65bb..9a45b8131 100644 --- a/src/modules/m_spanningtree/capab.cpp +++ b/src/modules/m_spanningtree/capab.cpp @@ -81,16 +81,16 @@ void TreeSocket::SendCapabilities() } this->WriteLine("CAPAB CAPABILITIES " /* Preprocessor does this one. */ - ":NICKMAX="+ConvToStr(NICKMAX)+ - " HALFOP="+ConvToStr(this->Instance->Config->AllowHalfop)+ - " CHANMAX="+ConvToStr(CHANMAX)+ - " MAXMODES="+ConvToStr(MAXMODES)+ - " IDENTMAX="+ConvToStr(IDENTMAX)+ - " MAXQUIT="+ConvToStr(MAXQUIT)+ - " MAXTOPIC="+ConvToStr(MAXTOPIC)+ - " MAXKICK="+ConvToStr(MAXKICK)+ - " MAXGECOS="+ConvToStr(MAXGECOS)+ - " MAXAWAY="+ConvToStr(MAXAWAY)+ + ":NICKMAX="+ConvToStr(Instance->Config->Limits.NickMax)+ + " HALFOP="+ConvToStr(Instance->Config->AllowHalfop)+ + " CHANMAX="+ConvToStr(Instance->Config->Limits.ChanMax)+ + " MAXMODES="+ConvToStr(Instance->Config->Limits.MaxModes)+ + " IDENTMAX="+ConvToStr(Instance->Config->Limits.IdentMax)+ + " MAXQUIT="+ConvToStr(Instance->Config->Limits.MaxQuit)+ + " MAXTOPIC="+ConvToStr(Instance->Config->Limits.MaxTopic)+ + " MAXKICK="+ConvToStr(Instance->Config->Limits.MaxKick)+ + " MAXGECOS="+ConvToStr(Instance->Config->Limits.MaxGecos)+ + " MAXAWAY="+ConvToStr(Instance->Config->Limits.MaxAway)+ " IP6NATIVE="+ConvToStr(ip6)+ " IP6SUPPORT="+ConvToStr(ip6support)+ " PROTOCOL="+ConvToStr(ProtocolVersion)+extra+ @@ -171,19 +171,6 @@ bool TreeSocket::Capab(const std::deque ¶ms) reason = "Modules loaded on these servers are not correctly matched, these modules are not loaded on " + diff; } - cap_validation valid_capab[] = { - {"Maximum nickname lengths differ or remote nickname length not specified", "NICKMAX", NICKMAX}, - {"Maximum ident lengths differ or remote ident length not specified", "IDENTMAX", IDENTMAX}, - {"Maximum channel lengths differ or remote channel length not specified", "CHANMAX", CHANMAX}, - {"Maximum modes per line differ or remote modes per line not specified", "MAXMODES", MAXMODES}, - {"Maximum quit lengths differ or remote quit length not specified", "MAXQUIT", MAXQUIT}, - {"Maximum topic lengths differ or remote topic length not specified", "MAXTOPIC", MAXTOPIC}, - {"Maximum kick lengths differ or remote kick length not specified", "MAXKICK", MAXKICK}, - {"Maximum GECOS (fullname) lengths differ or remote GECOS length not specified", "MAXGECOS", MAXGECOS}, - {"Maximum awaymessage lengths differ or remote awaymessage length not specified", "MAXAWAY", MAXAWAY}, - {"", "", 0} - }; - if (((this->CapKeys.find("IP6SUPPORT") == this->CapKeys.end()) && (ip6support)) || ((this->CapKeys.find("IP6SUPPORT") != this->CapKeys.end()) && (this->CapKeys.find("IP6SUPPORT")->second != ConvToStr(ip6support)))) reason = "We don't both support linking to IPV6 servers"; if (((this->CapKeys.find("IP6NATIVE") != this->CapKeys.end()) && (this->CapKeys.find("IP6NATIVE")->second == "1")) && (!ip6support)) @@ -201,13 +188,6 @@ bool TreeSocket::Capab(const std::deque ¶ms) if (((this->CapKeys.find("HALFOP") == this->CapKeys.end()) && (Instance->Config->AllowHalfop)) || ((this->CapKeys.find("HALFOP") != this->CapKeys.end()) && (this->CapKeys.find("HALFOP")->second != ConvToStr(Instance->Config->AllowHalfop)))) reason = "We don't both have halfop support enabled/disabled identically"; - - for (int x = 0; valid_capab[x].size; ++x) - { - if (((this->CapKeys.find(valid_capab[x].key) == this->CapKeys.end()) || ((this->CapKeys.find(valid_capab[x].key) != this->CapKeys.end()) && - (this->CapKeys.find(valid_capab[x].key)->second != ConvToStr(valid_capab[x].size))))) - reason = valid_capab[x].reason; - } /* Challenge response, store their challenge for our password */ std::map::iterator n = this->CapKeys.find("CHALLENGE"); diff --git a/src/modules/m_spanningtree/fjoin.cpp b/src/modules/m_spanningtree/fjoin.cpp index 985c86143..4ef8d2d4f 100644 --- a/src/modules/m_spanningtree/fjoin.cpp +++ b/src/modules/m_spanningtree/fjoin.cpp @@ -60,7 +60,7 @@ bool TreeSocket::ForceJoin(const std::string &source, std::deque &p if (params.size() < 3) return true; - irc::modestacker modestack(true); /* Modes to apply from the users in the user list */ + irc::modestacker modestack(Instance, true); /* Modes to apply from the users in the user list */ User* who = NULL; /* User we are currently checking */ std::string channel = params[0]; /* Channel name, as a string */ time_t TS = atoi(params[1].c_str()); /* Timestamp given to us for remote side */ diff --git a/src/modules/m_spanningtree/ftopic.cpp b/src/modules/m_spanningtree/ftopic.cpp index 3ea775112..e18187087 100644 --- a/src/modules/m_spanningtree/ftopic.cpp +++ b/src/modules/m_spanningtree/ftopic.cpp @@ -34,7 +34,7 @@ bool TreeSocket::ForceTopic(const std::string &source, std::deque & if ((ts >= c->topicset) || (c->topic.empty())) { std::string oldtopic = c->topic; - c->topic.assign(params[3], 0, MAXTOPIC); + c->topic.assign(params[3], 0, Instance->Config->Limits.MaxTopic); c->setby.assign(params[2], 0, 127); c->topicset = ts; /* if the topic text is the same as the current topic, diff --git a/src/modules/m_spanningtree/netburst.cpp b/src/modules/m_spanningtree/netburst.cpp index 8444bbec6..793a3cf9a 100644 --- a/src/modules/m_spanningtree/netburst.cpp +++ b/src/modules/m_spanningtree/netburst.cpp @@ -96,8 +96,19 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c) for (CUList::iterator i = ulist->begin(); i != ulist->end(); i++) { + size_t ptrlen = 0; + std::string modestr = this->Instance->Modes->ModeString(i->first, c, false); + + if ((curlen + modestr.length() + i->first->uuid.length() + 4) > 480) + { + buffer.append(list).append("\r\n"); + dlen = curlen = snprintf(list, MAXBUF, ":%s FJOIN %s %lu +%s", this->Instance->Config->GetSID().c_str(), c->name.c_str(), (unsigned long)c->age, c->ChanModes(true)); + ptr = list + dlen; + numusers = 0; + } + // The first parameter gets a : before it - size_t ptrlen = snprintf(ptr, MAXBUF, " %s%s,%s", !numusers ? ":" : "", this->Instance->Modes->ModeString(i->first, c, false).c_str(), i->first->uuid.c_str()); + ptrlen = snprintf(ptr, MAXBUF, " %s%s,%s", !numusers ? ":" : "", modestr.c_str(), i->first->uuid.c_str()); looped_once = true; @@ -105,15 +116,6 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c) ptr += ptrlen; numusers++; - - if (curlen > (480-NICKMAX)) - { - buffer.append(list).append("\r\n"); - dlen = curlen = snprintf(list,MAXBUF,":%s FJOIN %s %lu +%s", this->Instance->Config->GetSID().c_str(), c->name.c_str(), (unsigned long)c->age, c->ChanModes(true)); - ptr = list + dlen; - ptrlen = 0; - numusers = 0; - } } // Okay, permanent channels will (of course) need this \r\n anyway, numusers check is if there @@ -132,7 +134,7 @@ void TreeSocket::SendFJoins(TreeServer* Current, Channel* c) params.append(" ").append(b->data); linesize += size; } - if ((params.length() >= MAXMODES) || (currsize > 350)) + if ((params.length() >= Instance->Config->Limits.MaxModes) || (currsize > 350)) { /* Wrap at MAXMODES */ buffer.append(":").append(this->Instance->Config->GetSID()).append(" FMODE ").append(c->name).append(" ").append(ConvToStr(c->age)).append(" +").append(modes).append(params).append("\r\n"); diff --git a/src/modules/m_spanningtree/opertype.cpp b/src/modules/m_spanningtree/opertype.cpp index a2aff74f9..01638f9ac 100644 --- a/src/modules/m_spanningtree/opertype.cpp +++ b/src/modules/m_spanningtree/opertype.cpp @@ -35,8 +35,8 @@ bool TreeSocket::OperType(const std::string &prefix, std::deque &pa if (!u->IsModeSet('o')) this->Instance->Users->all_opers.push_back(u); u->modes[UM_OPERATOR] = 1; - u->oper.assign(opertype, 0, NICKMAX - 1); - Utils->DoOneToAllButSender(u->uuid,"OPERTYPE",params,u->server); + u->oper.assign(opertype, 0, Instance->Config->Limits.NickMax); + Utils->DoOneToAllButSender(u->uuid, "OPERTYPE", params, u->server); TreeServer* remoteserver = Utils->FindServer(u->server); bool dosend = true; diff --git a/src/modules/m_spanningtree/svsjoin.cpp b/src/modules/m_spanningtree/svsjoin.cpp index ee4addb74..5f9f94e95 100644 --- a/src/modules/m_spanningtree/svsjoin.cpp +++ b/src/modules/m_spanningtree/svsjoin.cpp @@ -35,9 +35,6 @@ bool TreeSocket::ServiceJoin(const std::string &prefix, std::deque if (params.size() < 2) return true; - if (!this->Instance->IsChannel(params[1].c_str())) - return true; - User* u = this->Instance->FindNick(params[0]); if (u) diff --git a/src/modules/m_spanningtree/svspart.cpp b/src/modules/m_spanningtree/svspart.cpp index 00fd9eb3a..639792be9 100644 --- a/src/modules/m_spanningtree/svspart.cpp +++ b/src/modules/m_spanningtree/svspart.cpp @@ -35,9 +35,6 @@ bool TreeSocket::ServicePart(const std::string &prefix, std::deque if (params.size() < 2) return true; - if (!this->Instance->IsChannel(params[1].c_str())) - return true; - User* u = this->Instance->FindNick(params[0]); Channel* c = this->Instance->FindChan(params[1]); diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp index 70f7b874c..d84ee2a04 100644 --- a/src/modules/m_spanningtree/uid.cpp +++ b/src/modules/m_spanningtree/uid.cpp @@ -48,9 +48,6 @@ bool TreeSocket::ParseUID(const std::string &source, std::deque &pa time_t signon = ConvToInt(params[8]); std::string empty; - /* XXX probably validate UID length too -- w00t */ - cmd_validation valid[] = { {"Nickname", 2, NICKMAX}, {"Hostname", 3, 64}, {"Displayed hostname", 4, 64}, {"Ident", 5, IDENTMAX + 1}, {"GECOS", 9, MAXGECOS}, {"", 0, 0} }; - TreeServer* remoteserver = Utils->FindServer(source); if (!remoteserver) @@ -66,16 +63,6 @@ bool TreeSocket::ParseUID(const std::string &source, std::deque &pa return true; } - for (size_t x = 0; valid[x].length; ++x) - { - if (params[valid[x].param].length() > valid[x].length) - { - this->WriteLine(std::string(":")+this->Instance->Config->GetSID()+" KILL "+params[0]+" :Invalid client introduction (" + valid[x].item + " > " + ConvToStr(valid[x].length) + ")"); - return true; - } - } - - /* check for collision */ user_hash::iterator iter = this->Instance->Users->clientlist->find(params[2]); @@ -109,12 +96,12 @@ bool TreeSocket::ParseUID(const std::string &source, std::deque &pa } (*(this->Instance->Users->clientlist))[params[2]] = _new; _new->SetFd(FD_MAGIC_NUMBER); - _new->nick.assign(params[2], 0, NICKMAX - 1); + _new->nick.assign(params[2], 0, MAXBUF); _new->host.assign(params[3], 0, 64); _new->dhost.assign(params[4], 0, 64); _new->server = this->Instance->FindServerNamePtr(remoteserver->GetName().c_str()); - _new->ident.assign(params[5], 0, IDENTMAX + 1); - _new->fullname.assign(params[9], 0, MAXGECOS); + _new->ident.assign(params[5], 0, MAXBUF); + _new->fullname.assign(params[9], 0, MAXBUF); _new->registered = REG_ALL; _new->signon = signon; _new->age = age_t; diff --git a/src/modules/m_svshold.cpp b/src/modules/m_svshold.cpp index ce19a67a3..c1c7e8421 100644 --- a/src/modules/m_svshold.cpp +++ b/src/modules/m_svshold.cpp @@ -100,7 +100,11 @@ class CommandSvshold : public Command else if (parameters.size() >= 2) { /* full form to add a SVSHold */ - if (ServerInstance->IsNick(parameters[0].c_str())) + + /* NOTE: We check nicks up to 512 in length here, as a hax to allow + * remote nicks that are longer than our configuration to be held + */ + if (ServerInstance->IsNick(parameters[0].c_str(), 512)) { // parameters[0] = w00t // parameters[1] = 1h3m2s diff --git a/src/modules/m_watch.cpp b/src/modules/m_watch.cpp index 3ae856b5e..62949e48a 100644 --- a/src/modules/m_watch.cpp +++ b/src/modules/m_watch.cpp @@ -137,7 +137,7 @@ class CommandWatch : public Command CmdResult remove_watch(User* user, const char* nick) { // removing an item from the list - if (!ServerInstance->IsNick(nick)) + if (!ServerInstance->IsNick(nick, ServerInstance->Config->Limits.NickMax)) { user->WriteNumeric(942, "%s %s :Invalid nickname", user->nick.c_str(), nick); return CMD_FAILURE; @@ -191,7 +191,7 @@ class CommandWatch : public Command CmdResult add_watch(User* user, const char* nick) { - if (!ServerInstance->IsNick(nick)) + if (!ServerInstance->IsNick(nick, ServerInstance->Config->Limits.NickMax)) { user->WriteNumeric(942, "%s %s :Invalid nickname",user->nick.c_str(),nick); return CMD_FAILURE; diff --git a/src/server.cpp b/src/server.cpp index ae1d106b8..d583d87c3 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -83,9 +83,9 @@ void InspIRCd::BuildISupport() { // the neatest way to construct the initial 005 numeric, considering the number of configure constants to go in it... std::stringstream v; - v << "WALLCHOPS WALLVOICES MODES=" << MAXMODES << " CHANTYPES=# PREFIX=" << this->Modes->BuildPrefixes() << " MAP MAXCHANNELS=" << Config->MaxChans << " MAXBANS=60 VBANLIST NICKLEN=" << NICKMAX-1; - v << " CASEMAPPING=rfc1459 STATUSMSG=@" << (this->Config->AllowHalfop ? "%" : "") << "+ CHARSET=ascii TOPICLEN=" << MAXTOPIC << " KICKLEN=" << MAXKICK << " MAXTARGETS=" << Config->MaxTargets; - v << " AWAYLEN=" << MAXAWAY << " CHANMODES=" << this->Modes->ChanModes() << " FNC NETWORK=" << Config->Network << " MAXPARA=32 ELIST=MU"; + v << "WALLCHOPS WALLVOICES MODES=" << Config->Limits.MaxModes << " CHANTYPES=# PREFIX=" << this->Modes->BuildPrefixes() << " MAP MAXCHANNELS=" << Config->MaxChans << " MAXBANS=60 VBANLIST NICKLEN=" << Config->Limits.NickMax; + v << " CASEMAPPING=rfc1459 STATUSMSG=@" << (this->Config->AllowHalfop ? "%" : "") << "+ CHARSET=ascii TOPICLEN=" << Config->Limits.MaxTopic << " KICKLEN=" << Config->Limits.MaxKick << " MAXTARGETS=" << Config->MaxTargets; + v << " AWAYLEN=" << Config->Limits.MaxAway << " CHANMODES=" << this->Modes->ChanModes() << " FNC NETWORK=" << Config->Network << " MAXPARA=32 ELIST=MU"; Config->data005 = v.str(); FOREACH_MOD_I(this,I_On005Numeric,On005Numeric(Config->data005)); Config->Update005(); diff --git a/src/usermanager.cpp b/src/usermanager.cpp index a171c32d2..73096d4a8 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -68,7 +68,7 @@ void UserManager::AddUser(InspIRCd* Instance, int socket, int port, bool iscache (*(this->clientlist))[New->uuid] = New; /* The users default nick is their UUID */ - New->nick.assign(New->uuid, 0, NICKMAX - 1); + New->nick.assign(New->uuid, 0, ServerInstance->Config->Limits.NickMax); New->server = Instance->FindServerNamePtr(Instance->Config->ServerName); New->ident.assign("unknown"); diff --git a/src/users.cpp b/src/users.cpp index 4ffdeb678..c892c51f5 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -721,7 +721,7 @@ void User::Oper(const std::string &opertype, const std::string &opername) this->WriteServ("MODE %s :+o", this->nick.c_str()); FOREACH_MOD(I_OnOper, OnOper(this, opertype)); ServerInstance->Logs->Log("OPER", DEFAULT, "%s!%s@%s opered as type: %s", this->nick.c_str(), this->ident.c_str(), this->host.c_str(), opertype.c_str()); - this->oper.assign(opertype, 0, NICKMAX - 1); + this->oper.assign(opertype, 0, ServerInstance->Config->Limits.NickMax); ServerInstance->Users->all_opers.push_back(this); opertype_t::iterator iter_opertype = ServerInstance->Config->opertypes.find(this->oper.c_str()); @@ -1521,7 +1521,7 @@ bool User::ChangeName(const char* gecos) return false; FOREACH_MOD(I_OnChangeName,OnChangeName(this,gecos)); } - this->fullname.assign(gecos, 0, MAXGECOS+1); + this->fullname.assign(gecos, 0, ServerInstance->Config->Limits.MaxGecos); return true; } @@ -1573,7 +1573,7 @@ bool User::ChangeIdent(const char* newident) if (this->ServerInstance->Config->CycleHosts) this->WriteCommonExcept("%s","QUIT :Changing ident"); - this->ident.assign(newident, 0, IDENTMAX + 1); + this->ident.assign(newident, 0, ServerInstance->Config->Limits.IdentMax + 1); this->InvalidateCache(); -- 2.39.5