diff options
author | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2008-05-25 17:30:43 +0000 |
---|---|---|
committer | brain <brain@e03df62e-2008-0410-955e-edbf42e46eb7> | 2008-05-25 17:30:43 +0000 |
commit | 7d7250484c352c13830e63ae41ee8faae40a9bd5 (patch) | |
tree | 0fdf4941b4d72469a18eec97506f06f6e94e86e9 | |
parent | e7b837ec5f120f928a0dc321fa918bdd01ab0c02 (diff) |
First phase of conversion to dynamic limits on all the lengths, configured via the <limits> 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
49 files changed, 172 insertions, 301 deletions
@@ -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 <<EOF; /* Auto generated by configure, do not modify! */ #ifndef __CONFIGURATION_AUTO__ @@ -1239,15 +1152,6 @@ sub writefiles { #define VERSION "$version" #define REVISION "$revision2" #define SOMAXCONN_S "$config{_SOMAXCONN}" -#define NICKMAX $NL -#define CHANMAX $CL -#define MAXMODES $config{MAXI_MODES} -#define IDENTMAX $config{MAX_IDENT} -#define MAXQUIT $config{MAX_QUIT} -#define MAXTOPIC $config{MAX_TOPIC} -#define MAXKICK $config{MAX_KICK} -#define MAXGECOS $config{MAX_GECOS} -#define MAXAWAY $config{MAX_AWAY} #define OPTIMISATION $config{OPTIMITEMP} #define LIBRARYDIR "$config{LIBRARY_DIR}" #define SYSTEM "$incos" diff --git a/include/configreader.h b/include/configreader.h index 7fc60203d..56a2ee698 100644 --- a/include/configreader.h +++ b/include/configreader.h @@ -226,6 +226,28 @@ struct operclass_data : public Extensible typedef std::map<irc::string, operclass_data> 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<std::string, std::istream*> IncludedFiles; - std::map<std::string, bool> 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<std::string> 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<std::pair<std::string, long> > 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<bool, const char*> IsChannel; + caller2<bool, const char*, size_t> 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<bool, const char*> IsNick; + caller2<bool, const char*, size_t> 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 <limits>\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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& parameters, User *user) { - char oldnick[NICKMAX]; + std::string oldnick; if (parameters[0].empty()) { @@ -36,7 +36,7 @@ CmdResult CommandNick::Handle (const std::vector<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<User*>::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<User*>::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<std::string>& parameters, User } } - char topic[MAXTOPIC]; + std::string topic; if (IS_LOCAL(user)) { @@ -79,17 +79,17 @@ CmdResult CommandTopic::Handle (const std::vector<std::string>& 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<std::string>& 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<std::string> &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<std::string>& 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<std::string> mode_junk; mode_junk.push_back(channel->name); - irc::modestacker modestack(false); + irc::modestacker modestack(ServerInstance, false); std::deque<std::string> 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<std::string>::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<std::string>::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<std::string, std::vector<std::string> >::iterator i = operTypeChans.find(user->oper); @@ -101,7 +101,7 @@ class ModuleOperjoin : public Module const std::vector<std::string>& list = i->second; for (std::vector<std::string>::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<std::string> ¶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<std::string> ¶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<std::string,std::string>::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<std::string> &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<std::string> & 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<std::string> &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<std::string> 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<std::string> 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<std::string> &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<std::string> &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<std::string> &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(); |