realhost("cgiirc_realhost", Creator), realip("cgiirc_realip", Creator),
webirc_hostname("cgiirc_webirc_hostname", Creator), webirc_ip("cgiirc_webirc_ip", Creator)
{
+ allow_empty_last_param = false;
works_before_reg = true;
this->syntax = "password client hostname ip";
}
if(user->registered == REG_ALL)
return CMD_FAILURE;
+ irc::sockets::sockaddrs ipaddr;
+ if (!irc::sockets::aptosa(parameters[3], 0, ipaddr))
+ {
+ IS_LOCAL(user)->CommandFloodPenalty += 5000;
+ ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s tried to use WEBIRC but gave an invalid IP address.", user->GetFullRealHost().c_str());
+ return CMD_FAILURE;
+ }
+
for(CGIHostlist::iterator iter = Hosts.begin(); iter != Hosts.end(); iter++)
{
if(InspIRCd::Match(user->host, iter->hostmask, ascii_case_insensitive_map) || InspIRCd::MatchCIDR(user->GetIPString(), iter->hostmask, ascii_case_insensitive_map))
{
realhost.set(user, user->host);
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());
- // 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);
+ // Check if we're happy with the provided hostname. If it's problematic then use the IP instead.
+ bool host_ok = (parameters[2].length() < 64) && (parameters[2].find_first_not_of("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.:-") == std::string::npos);
+ 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(), newhost.c_str(), user->host.c_str());
+
+ webirc_hostname.set(user, newhost);
webirc_ip.set(user, parameters[3]);
return CMD_SUCCESS;
}
}
}
+ IS_LOCAL(user)->CommandFloodPenalty += 5000;
ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s tried to use WEBIRC, but didn't match any configured webirc blocks.", user->GetFullRealHost().c_str());
return CMD_FAILURE;
}
{
/* 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 RecheckElineAndClass(LocalUser* user)
+ static void RecheckClass(LocalUser* user)
{
- user->exempt = (ServerInstance->XLines->MatchesLine("E", user) != NULL);
+ user->MyClass = NULL;
user->SetClass();
user->CheckClass();
}
{
cmd.realhost.set(user, user->host);
cmd.realip.set(user, user->GetIPString());
- ChangeIP(user, newip);
user->host = user->dhost = user->GetIPString();
+ ChangeIP(user, newip);
user->InvalidateCache();
- RecheckElineAndClass(user);
- // Don't create the resolver if the core couldn't put the user in a connect class
- if (user->quitting)
+ 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);
- ServerInstance->AddResolver(r, cached);
waiting.set(user, waiting.get(user) + 1);
+ ServerInstance->AddResolver(r, cached);
}
catch (...)
{
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;
- ChangeIP(user, *webirc_ip);
-
std::string* webirc_hostname = cmd.webirc_hostname.get(user);
user->host = user->dhost = (webirc_hostname ? *webirc_hostname : user->GetIPString());
- RecheckElineAndClass(user);
+ ChangeIP(user, *webirc_ip);
+ user->InvalidateCache();
+
+ RecheckClass(user);
if (user->quitting)
return MOD_RES_DENY;