#include "inspircd.h"
+#include "xline.h"
/* $ModDesc: Change user's hosts connecting from known CGI:IRC hosts */
{
realhost.set(user, user->host);
realip.set(user, user->GetIPString());
+
+ bool host_ok = (parameters[2].length() < 64);
+ const std::string& newhost = (host_ok ? parameters[2] : parameters[3]);
+
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]);
+ 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(), newhost.c_str(), user->host.c_str());
+
+ // 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 (host_ok)
+ webirc_hostname.set(user, parameters[2]);
+ else
+ webirc_hostname.unset(user);
+
webirc_ip.set(user, parameters[3]);
return CMD_SUCCESS;
}
{
/* Check the user still exists */
User* them = ServerInstance->FindUUID(theiruid);
- if (them)
+ if ((them) && (!them->quitting))
{
if (notify)
ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s detected as using CGI:IRC (%s), changing real host to %s from %s", them->nick.c_str(), them->host.c_str(), result.c_str(), typ.c_str());
virtual void OnError(ResolverError e, const std::string &errormessage)
{
+ if (!notify)
+ return;
+
User* them = ServerInstance->FindUUID(theiruid);
- if (them)
+ if ((them) && (!them->quitting))
{
- if (notify)
- ServerInstance->SNO->WriteToSnoMask('a', "Connecting user %s detected as using CGI:IRC (%s), but their host can't be resolved from their %s!", them->nick.c_str(), them->host.c_str(), typ.c_str());
+ ServerInstance->SNO->WriteToSnoMask('a', "Connecting user %s detected as using CGI:IRC (%s), but their host can't be resolved from their %s!", them->nick.c_str(), them->host.c_str(), typ.c_str());
}
}
{
CommandWebirc cmd;
LocalIntExt waiting;
+
+ static void RecheckClass(LocalUser* user)
+ {
+ user->MyClass = 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();
+ RecheckClass(user);
+ // Don't create the resolver if the core couldn't put the user in a connect class or when dns is disabled
+ if (user->quitting || ServerInstance->Config->NoUserDns)
+ return;
+
+ try
+ {
+ bool cached;
+ CGIResolver* r = new CGIResolver(this, cmd.notify, newip, user, (was_pass ? "PASS" : "IDENT"), cached, waiting);
+ waiting.set(user, waiting.get(user) + 1);
+ ServerInstance->AddResolver(r, cached);
+ }
+ 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)
{
void init()
{
OnRehash(NULL);
- ServerInstance->AddCommand(&cmd);
- ServerInstance->Extensions.Register(&cmd.realhost);
- ServerInstance->Extensions.Register(&cmd.realip);
- ServerInstance->Extensions.Register(&cmd.webirc_hostname);
- ServerInstance->Extensions.Register(&cmd.webirc_ip);
- ServerInstance->Extensions.Register(&waiting);
+ ServiceProvider* providerlist[] = { &cmd, &cmd.realhost, &cmd.realip, &cmd.webirc_hostname, &cmd.webirc_ip, &waiting };
+ ServerInstance->Modules->AddServices(providerlist, sizeof(providerlist)/sizeof(ServiceProvider*));
Implementation eventlist[] = { I_OnRehash, I_OnUserRegister, I_OnCheckReady };
- ServerInstance->Modules->Attach(eventlist, this, 3);
+ ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
}
void OnRehash(User* user)
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);
- ServerInstance->Users->AddLocalClone(user);
- ServerInstance->Users->AddGlobalClone(user);
- user->SetClass();
- user->CheckClass();
+ RecheckClass(user);
+ if (user->quitting)
+ return MOD_RES_DENY;
+
user->CheckLines(true);
if (user->quitting)
return MOD_RES_DENY;
+ cmd.webirc_hostname.unset(user);
+ cmd.webirc_ip.unset(user);
+
return MOD_RES_PASSTHRU;
}
{
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;
}
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;
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;
}