Implement support for configurable casemapping & default to ASCII.

This commit is contained in:
Peter Powell 2017-07-30 17:34:05 +01:00
parent 5a3f8af9f9
commit 51a47e7d75
6 changed files with 48 additions and 8 deletions

View File

@ -563,6 +563,14 @@
# the correct parameters are.
syntaxhints="no"
# casemapping: This sets the case mapping method to be used by the
# server. This MUST be the same on all servers. Possible values are:
# "ascii" (recommended)
# "rfc1459" (default, required for linking to 2.0 servers)
# NOTE: if you are using the nationalchars module this setting will be
# ignored. You should use <nationalchars:casemapping> instead.
casemapping="ascii"
# cyclehostsfromuser: If enabled, the source of the mode change for
# cyclehosts will be the user who cycled. This can look nicer, but
# triggers anti-takeover mechanisms of some obsolete bots.

View File

@ -424,6 +424,10 @@ class CoreExport ServerConfig
*/
bool SyntaxHints;
/** The name of the casemapping method used by this server.
*/
std::string CaseMapping;
/** If set to true, the CycleHosts mode change will be sourced from the user,
* rather than the server
*/

View File

@ -400,6 +400,14 @@ void ServerConfig::Fill()
sid = server->getString("id");
if (!sid.empty() && !InspIRCd::IsSID(sid))
throw CoreException(sid + " is not a valid server ID. A server ID must be 3 characters long, with the first character a digit and the next two characters a digit or letter.");
CaseMapping = options->getString("casemapping", "rfc1459");
if (CaseMapping == "ascii")
national_case_insensitive_map = ascii_case_insensitive_map;
else if (CaseMapping == "rfc1459")
national_case_insensitive_map = rfc_case_insensitive_map;
else
throw CoreException("<options:casemapping> must be set to 'ascii', or 'rfc1459'");
}
else
{
@ -410,6 +418,11 @@ void ServerConfig::Fill()
std::string nsid = server->getString("id");
if (!nsid.empty() && nsid != sid)
throw CoreException("You must restart to change the server id");
std::string casemapping = options->getString("casemapping");
if (!casemapping.empty() && casemapping != CaseMapping)
throw CoreException("You must restart to change the server casemapping");
}
SoftLimit = ConfValue("performance")->getInt("softlimit", (SocketEngine::GetMaxFds() > 0 ? SocketEngine::GetMaxFds() : LONG_MAX), 10);
CCOnConnect = ConfValue("performance")->getBool("clonesonconnect", true);

View File

@ -218,7 +218,7 @@ bool lwbNickHandler::Call(const std::string& nick)
class ModuleNationalChars : public Module
{
lwbNickHandler myhandler;
std::string charset, casemapping;
std::string charset;
unsigned char m_additional[256], m_additionalUp[256], m_lower[256], m_upper[256];
caller1<bool, const std::string&> rememberer;
bool forcequit;
@ -262,18 +262,14 @@ class ModuleNationalChars : public Module
ServerInstance->IsNick = &myhandler;
}
void On005Numeric(std::map<std::string, std::string>& tokens) CXX11_OVERRIDE
{
tokens["CASEMAPPING"] = casemapping;
}
void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
{
ConfigTag* tag = ServerInstance->Config->ConfValue("nationalchars");
charset = tag->getString("file");
casemapping = tag->getString("casemapping", FileSystem::GetFileName(charset));
std::string casemapping = tag->getString("casemapping", FileSystem::GetFileName(charset));
if (casemapping.find(' ') != std::string::npos)
throw ModuleException("<nationalchars:casemapping> must not contain any spaces!");
ServerInstance->Config->CaseMapping = casemapping;
#if defined _WIN32
if (!FileSystem::StartsWithWindowsDriveLetter(charset))
charset.insert(0, "./locales/");

View File

@ -182,6 +182,7 @@ void TreeSocket::SendCapabilities(int phase)
" PREFIX="+ServerInstance->Modes->BuildPrefixes()+
" CHANMODES="+ServerInstance->Modes->GiveModeList(MODETYPE_CHANNEL)+
" USERMODES="+ServerInstance->Modes->GiveModeList(MODETYPE_USER)+
" CASEMAPPING="+ServerInstance->Config->CaseMapping+
// XXX: Advertise the presence or absence of m_globops in CAPAB CAPABILITIES.
// Services want to know about it, and since m_globops was not marked as VF_(OPT)COMMON
// in 2.0, we advertise it here to not break linking to previous versions.
@ -343,6 +344,24 @@ bool TreeSocket::Capab(const parameterlist &params)
if (this->capab->CapKeys.find("USERMODES")->second != ServerInstance->Modes->GiveModeList(MODETYPE_USER))
reason = "One or more of the user modes on the remote server are invalid on this server.";
}
else
{
// We default to rfc1459 here because if this key is not sent then
// the remote server is running the 2.0 protocol which uses rfc1459
// by default.
std::string casemapping = "rfc1459";
std::map<std::string, std::string>::iterator citer = this->capab->CapKeys.find("CASEMAPPING");
if (citer != this->capab->CapKeys.end())
casemapping = citer->second;
if (casemapping != ServerInstance->Config->CaseMapping)
{
reason = "The casemapping of the remote server differs to that of the local server."
" Local casemapping: " + ServerInstance->Config->CaseMapping +
" Remote casemapping: " + casemapping;
}
}
/* Challenge response, store their challenge for our password */
std::map<std::string,std::string>::iterator n = this->capab->CapKeys.find("CHALLENGE");

View File

@ -164,7 +164,7 @@ void ISupportManager::Build()
std::map<std::string, std::string> tokens;
tokens["AWAYLEN"] = ConvToStr(ServerInstance->Config->Limits.MaxAway);
tokens["CASEMAPPING"] = "rfc1459";
tokens["CASEMAPPING"] = ServerInstance->Config->CaseMapping;
tokens["CHANLIMIT"] = InspIRCd::Format("#:%u", ServerInstance->Config->MaxChans);
tokens["CHANMODES"] = ServerInstance->Modes->GiveModeList(MODETYPE_CHANNEL);
tokens["CHANNELLEN"] = ConvToStr(ServerInstance->Config->Limits.ChanMax);