From 42105f07dd1ac0e04e28077754b6245a80d55597 Mon Sep 17 00:00:00 2001 From: brain Date: Sun, 15 Jul 2007 13:18:28 +0000 Subject: [PATCH] Fix for bug #349: NOTE there is important caveat about this in the example config, MAKE SURE TO READ IT. When you connect a cgi:irc client two different connect classes are checked at two different times (first the one that the website they are cgi'ing from, then later one for the user's real ip). READ THIS AND UNDERSTAND IT! git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@7440 e03df62e-2008-0410-955e-edbf42e46eb7 --- docs/inspircd.conf.example | 14 +++++++++++++ include/users.h | 6 ++++++ src/modules/m_cgiirc.cpp | 14 ++++++++++++- src/users.cpp | 43 +++++++++++++++++++++----------------- 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/docs/inspircd.conf.example b/docs/inspircd.conf.example index 823998b30..1fef8f707 100644 --- a/docs/inspircd.conf.example +++ b/docs/inspircd.conf.example @@ -1251,6 +1251,20 @@ # # Get IP from WEBIRC # # Get IP from ident # # See the docs +# +# IMPORTANT NOTE: +# --------------- +# +# When you connect CGI:IRC clients, there are two connect classes which +# apply to these clients. When the client initially connects, the connect +# class which matches the cgi:irc site's host is checked. Therefore you +# must raise the maximum local/global clients for this ip as high as you +# want to allow cgi clients. After the client has connected and is +# determined to be a cgi:irc client, the class which matches the client's +# real IP is then checked. You may set this class to a lower value, so that +# the real IP of the client can still be restricted to, for example, 3 +# sessions maximum. +# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# diff --git a/include/users.h b/include/users.h index b710c9993..0443b24d2 100644 --- a/include/users.h +++ b/include/users.h @@ -830,6 +830,12 @@ class CoreExport userrec : public connection */ unsigned long LocalCloneCount(); + /** Remove all clone counts from the user, you should + * use this if you change the user's IP address in + * userrec::ip after they have registered. + */ + void RemoveCloneCounts(); + /** Write text to this user, appending CR/LF. * @param text A std::string to send to the user */ diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp index ec6d5d398..290f55d22 100644 --- a/src/modules/m_cgiirc.cpp +++ b/src/modules/m_cgiirc.cpp @@ -289,6 +289,7 @@ public: if(user->GetExt("cgiirc_webirc_ip", webirc_ip)) { bool valid=false; + user->RemoveCloneCounts(); #ifdef IPV6 valid = (inet_pton(AF_INET6, webirc_ip->c_str(), &((sockaddr_in6*)user->ip)->sin6_addr) > 0); @@ -302,6 +303,9 @@ public: delete webirc_ip; user->InvalidateCache(); user->Shrink("cgiirc_webirc_ip"); + ServerInstance->AddLocalClone(user); + ServerInstance->AddGlobalClone(user); + user->CheckClass(); } } @@ -316,6 +320,7 @@ public: user->InvalidateCache(); bool valid = false; + user->RemoveCloneCounts(); #ifdef IPV6 if (user->GetProtocolFamily() == AF_INET6) valid = (inet_pton(AF_INET6, user->password, &((sockaddr_in6*)user->ip)->sin6_addr) > 0); @@ -325,6 +330,10 @@ public: if (inet_aton(user->password, &((sockaddr_in*)user->ip)->sin_addr)) valid = true; #endif + ServerInstance->AddLocalClone(user); + ServerInstance->AddGlobalClone(user); + user->CheckClass(); + if (valid) { /* We were given a IP in the password, we don't do DNS so they get this is as their host as well. */ @@ -381,13 +390,16 @@ public: user->Extend("cgiirc_realhost", new std::string(user->host)); user->Extend("cgiirc_realip", new std::string(user->GetIPString())); + user->RemoveCloneCounts(); #ifdef IPV6 if (user->GetProtocolFamily() == AF_INET6) inet_pton(AF_INET6, newip, &((sockaddr_in6*)user->ip)->sin6_addr); else #endif inet_aton(newip, &((sockaddr_in*)user->ip)->sin_addr); - + ServerInstance->AddLocalClone(user); + ServerInstance->AddGlobalClone(user); + user->CheckClass(); try { strlcpy(user->host, newip, 16); diff --git a/src/users.cpp b/src/users.cpp index d83788566..7da7d6b09 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -344,6 +344,29 @@ userrec::userrec(InspIRCd* Instance) : ServerInstance(Instance) operquit = cached_fullhost = cached_hostip = cached_makehost = cached_fullrealhost = NULL; } +void userrec::RemoveCloneCounts() +{ + clonemap::iterator x = ServerInstance->local_clones.find(this->GetIPString()); + if (x != ServerInstance->local_clones.end()) + { + x->second--; + if (!x->second) + { + ServerInstance->local_clones.erase(x); + } + } + + clonemap::iterator y = ServerInstance->global_clones.find(this->GetIPString()); + if (y != ServerInstance->global_clones.end()) + { + y->second--; + if (!y->second) + { + ServerInstance->global_clones.erase(y); + } + } +} + userrec::~userrec() { this->InvalidateCache(); @@ -352,25 +375,7 @@ userrec::~userrec() free(operquit); if (ip) { - clonemap::iterator x = ServerInstance->local_clones.find(this->GetIPString()); - if (x != ServerInstance->local_clones.end()) - { - x->second--; - if (!x->second) - { - ServerInstance->local_clones.erase(x); - } - } - - clonemap::iterator y = ServerInstance->global_clones.find(this->GetIPString()); - if (y != ServerInstance->global_clones.end()) - { - y->second--; - if (!y->second) - { - ServerInstance->global_clones.erase(y); - } - } + this->RemoveCloneCounts(); if (this->GetProtocolFamily() == AF_INET) { -- 2.39.5