summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorattilamolnar <attilamolnar@hush.com>2012-11-21 01:53:41 +0100
committerattilamolnar <attilamolnar@hush.com>2012-11-29 20:26:17 +0100
commit6e55cd2003750a7f69866128cfd44409676c9a1e (patch)
treebc7bec680f3ef67996da27bdd4bea7f92b5df1bc /src
parent9eb655dbdd49cd7afb44ca972512f0fdf7cfa46f (diff)
m_cgiirc De-duplicate code, recheck elines after ip/host changes
Fixes #350 reported by @MistrX New functions: - RecheckElineAndClass() - ChangeIP() - decreases clone counts for a user, calls SetUserIP, increases clone counts after the new ip is applied - HandleIdentOrPass() - common code extracted from CheckIdent() and CheckPass()
Diffstat (limited to 'src')
-rw-r--r--src/modules/m_cgiirc.cpp133
1 files changed, 64 insertions, 69 deletions
diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp
index e4d967667..8e46a5d4d 100644
--- a/src/modules/m_cgiirc.cpp
+++ b/src/modules/m_cgiirc.cpp
@@ -24,6 +24,7 @@
#include "inspircd.h"
+#include "xline.h"
/* $ModDesc: Change user's hosts connecting from known CGI:IRC hosts */
@@ -90,7 +91,13 @@ class CommandWebirc : public Command
realip.set(user, user->GetIPString());
if (notify)
ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s detected as using CGI:IRC (%s), changing real host to %s from %s", user->nick.c_str(), user->host.c_str(), parameters[2].c_str(), user->host.c_str());
- webirc_hostname.set(user, parameters[2]);
+
+ // Check if we're happy with the provided hostname. If it's problematic then make sure we won't set a host later, just the IP
+ if (parameters[2].length() < 64)
+ webirc_hostname.set(user, parameters[2]);
+ else
+ webirc_hostname.unset(user);
+
webirc_ip.set(user, parameters[3]);
return CMD_SUCCESS;
}
@@ -162,6 +169,48 @@ class ModuleCgiIRC : public Module
{
CommandWebirc cmd;
LocalIntExt waiting;
+
+ static void RecheckElineAndClass(LocalUser* user)
+ {
+ user->exempt = (ServerInstance->XLines->MatchesLine("E", user) != NULL);
+ user->SetClass();
+ user->CheckClass();
+ }
+
+ static void ChangeIP(LocalUser* user, const std::string& newip)
+ {
+ ServerInstance->Users->RemoveCloneCounts(user);
+ user->SetClientIP(newip.c_str());
+ ServerInstance->Users->AddLocalClone(user);
+ ServerInstance->Users->AddGlobalClone(user);
+ }
+
+ void HandleIdentOrPass(LocalUser* user, const std::string& newip, bool was_pass)
+ {
+ cmd.realhost.set(user, user->host);
+ cmd.realip.set(user, user->GetIPString());
+ ChangeIP(user, newip);
+ user->host = user->dhost = user->GetIPString();
+ user->InvalidateCache();
+ RecheckElineAndClass(user);
+ // Don't create the resolver if the core couldn't put the user in a connect class
+ if (user->quitting)
+ return;
+
+ try
+ {
+ bool cached;
+ CGIResolver* r = new CGIResolver(this, cmd.notify, newip, user, (was_pass ? "PASS" : "IDENT"), cached, waiting);
+ ServerInstance->AddResolver(r, cached);
+ waiting.set(user, waiting.get(user) + 1);
+ }
+ catch (...)
+ {
+ if (cmd.notify)
+ ServerInstance->SNO->WriteToSnoMask('a', "Connecting user %s detected as using CGI:IRC (%s), but I could not resolve their hostname!", user->nick.c_str(), user->host.c_str());
+ }
+ }
+
public:
ModuleCgiIRC() : cmd(this), waiting("cgiirc-delay", this)
{
@@ -239,27 +288,22 @@ public:
if (!webirc_ip)
return MOD_RES_PASSTHRU;
- ServerInstance->Users->RemoveCloneCounts(user);
- user->SetClientIP(webirc_ip->c_str());
- cmd.webirc_ip.unset(user);
+ ChangeIP(user, *webirc_ip);
std::string* webirc_hostname = cmd.webirc_hostname.get(user);
- if (webirc_hostname && webirc_hostname->length() < 64)
- user->host = user->dhost = *webirc_hostname;
- else
- user->host = user->dhost = user->GetIPString();
+ user->host = user->dhost = (webirc_hostname ? *webirc_hostname : user->GetIPString());
- user->InvalidateCache();
- cmd.webirc_hostname.unset(user);
+ RecheckElineAndClass(user);
+ if (user->quitting)
+ return MOD_RES_DENY;
- ServerInstance->Users->AddLocalClone(user);
- ServerInstance->Users->AddGlobalClone(user);
- user->SetClass();
- user->CheckClass();
user->CheckLines(true);
if (user->quitting)
return MOD_RES_DENY;
+ cmd.webirc_hostname.unset(user);
+ cmd.webirc_ip.unset(user);
+
return MOD_RES_PASSTHRU;
}
@@ -306,32 +350,7 @@ public:
{
if(IsValidHost(user->password))
{
- cmd.realhost.set(user, user->host);
- cmd.realip.set(user, user->GetIPString());
- user->host = user->password;
- user->dhost = user->password;
- user->InvalidateCache();
-
- ServerInstance->Users->RemoveCloneCounts(user);
- user->SetClientIP(user->password.c_str());
- ServerInstance->Users->AddLocalClone(user);
- ServerInstance->Users->AddGlobalClone(user);
- user->SetClass();
- user->CheckClass();
-
- try
- {
- bool cached;
- CGIResolver* r = new CGIResolver(this, cmd.notify, user->password, user, "PASS", cached, waiting);
- ServerInstance->AddResolver(r, cached);
- waiting.set(user, waiting.get(user) + 1);
- }
- catch (...)
- {
- if (cmd.notify)
- ServerInstance->SNO->WriteToSnoMask('a', "Connecting user %s detected as using CGI:IRC (%s), but I could not resolve their hostname!", user->nick.c_str(), user->host.c_str());
- }
-
+ HandleIdentOrPass(user, user->password, true);
user->password.clear();
return true;
}
@@ -342,12 +361,11 @@ public:
bool CheckIdent(LocalUser* user)
{
const char* ident;
- int len = user->ident.length();
in_addr newip;
- if(len == 8)
+ if (user->ident.length() == 8)
ident = user->ident.c_str();
- else if(len == 9 && user->ident[0] == '~')
+ else if (user->ident.length() == 9 && user->ident[0] == '~')
ident = user->ident.c_str() + 1;
else
return false;
@@ -357,33 +375,10 @@ public:
if (errno)
return false;
newip.s_addr = htonl(ipaddr);
- char* newipstr = inet_ntoa(newip);
+ std::string newipstr(inet_ntoa(newip));
- cmd.realhost.set(user, user->host);
- cmd.realip.set(user, user->GetIPString());
- ServerInstance->Users->RemoveCloneCounts(user);
- user->SetClientIP(newipstr);
- ServerInstance->Users->AddLocalClone(user);
- ServerInstance->Users->AddGlobalClone(user);
- user->SetClass();
- user->CheckClass();
- user->host = newipstr;
- user->dhost = newipstr;
- user->ident.assign("~cgiirc", 0, 8);
- try
- {
- bool cached;
- CGIResolver* r = new CGIResolver(this, cmd.notify, newipstr, user, "IDENT", cached, waiting);
- ServerInstance->AddResolver(r, cached);
- waiting.set(user, waiting.get(user) + 1);
- }
- catch (...)
- {
- user->InvalidateCache();
-
- if(cmd.notify)
- ServerInstance->SNO->WriteToSnoMask('a', "Connecting user %s detected as using CGI:IRC (%s), but I could not resolve their hostname!", user->nick.c_str(), user->host.c_str());
- }
+ user->ident = "~cgiirc";
+ HandleIdentOrPass(user, newipstr, false);
return true;
}