+ // If we don't match the host then skip to the next host.
+ if (!iter->Matches(user, parameters[0], sslapi))
+ continue;
+
+ irc::sockets::sockaddrs ipaddr;
+ if (!irc::sockets::aptosa(parameters[3], user->client_sa.port(), ipaddr))
+ {
+ WriteLog("Connecting user %s (%s) tried to use WEBIRC but gave an invalid IP address.",
+ user->uuid.c_str(), user->GetIPString().c_str());
+ ServerInstance->Users->QuitUser(user, "WEBIRC: IP address is invalid: " + parameters[3]);
+ return CMD_FAILURE;
+ }
+
+ // The user matched a WebIRC block!
+ gateway.set(user, parameters[1]);
+ realhost.set(user, user->GetRealHost());
+ realip.set(user, user->GetIPString());
+
+ WriteLog("Connecting user %s is using the %s WebIRC gateway; changing their IP from %s to %s.",
+ user->uuid.c_str(), parameters[1].c_str(),
+ user->GetIPString().c_str(), parameters[3].c_str());
+
+ // If we have custom flags then deal with them.
+ WebIRC::FlagMap flags;
+ const bool hasflags = (parameters.size() > 4);
+ if (hasflags)
+ {
+ // Parse the flags.
+ irc::spacesepstream flagstream(parameters[4]);
+ for (std::string flag; flagstream.GetToken(flag); )
+ {
+ // Does this flag have a value?
+ const size_t separator = flag.find('=');
+ if (separator == std::string::npos)
+ {
+ flags[flag];
+ continue;
+ }
+
+ // The flag has a value!
+ const std::string key = flag.substr(0, separator);
+ const std::string value = flag.substr(separator + 1);
+ flags[key] = value;
+ }
+ }
+
+ // Inform modules about the WebIRC attempt.
+ FOREACH_MOD_CUSTOM(webircevprov, WebIRC::EventListener, OnWebIRCAuth, (user, (hasflags ? &flags : NULL)));
+
+ // Set the IP address sent via WEBIRC. We ignore the hostname and lookup
+ // instead do our own DNS lookups because of unreliable gateways.
+ user->SetClientIP(ipaddr);
+ return CMD_SUCCESS;