diff options
Diffstat (limited to 'src/modules/m_spanningtree')
-rw-r--r-- | src/modules/m_spanningtree/main.cpp | 16 | ||||
-rw-r--r-- | src/modules/m_spanningtree/resolvers.cpp | 30 | ||||
-rw-r--r-- | src/modules/m_spanningtree/resolvers.h | 25 | ||||
-rw-r--r-- | src/modules/m_spanningtree/server.cpp | 8 | ||||
-rw-r--r-- | src/modules/m_spanningtree/treesocket1.cpp | 12 | ||||
-rw-r--r-- | src/modules/m_spanningtree/treesocket2.cpp | 13 | ||||
-rw-r--r-- | src/modules/m_spanningtree/uid.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_spanningtree/utils.cpp | 79 |
8 files changed, 95 insertions, 90 deletions
diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index 1067852d1..f639a748d 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -765,7 +765,21 @@ void ModuleSpanningTree::OnPreRehash(User* user, const std::string ¶meter) void ModuleSpanningTree::OnRehash(User* user) { // Re-read config stuff - Utils->ReadConfiguration(); + try + { + Utils->ReadConfiguration(); + } + catch (ModuleException& e) + { + // Refresh the IP cache anyway, so servers read before the error will be allowed to connect + Utils->RefreshIPCache(); + // Always warn local opers with snomask +l, also warn globally (snomask +L) if the rehash was issued by a remote user + std::string msg = "Error in configuration: "; + msg.append(e.GetReason()); + ServerInstance->SNO->WriteToSnoMask('l', msg); + if (!IS_LOCAL(user)) + ServerInstance->PI->SendSNONotice("L", msg); + } } void ModuleSpanningTree::OnLoadModule(Module* mod) diff --git a/src/modules/m_spanningtree/resolvers.cpp b/src/modules/m_spanningtree/resolvers.cpp index ae951bd38..b69c5c29e 100644 --- a/src/modules/m_spanningtree/resolvers.cpp +++ b/src/modules/m_spanningtree/resolvers.cpp @@ -80,3 +80,33 @@ void ServernameResolver::OnError(ResolverError e, const std::string &errormessag Utils->Creator->ConnectServer(myautoconnect, false); } +SecurityIPResolver::SecurityIPResolver(Module* me, SpanningTreeUtilities* U, const std::string &hostname, Link* x, bool &cached, QueryType qt) + : Resolver(hostname, qt, cached, me), MyLink(x), Utils(U), mine(me), host(hostname), query(qt) +{ +} + +void SecurityIPResolver::OnLookupComplete(const std::string &result, unsigned int ttl, bool cached) +{ + for (std::vector<reference<Link> >::iterator i = Utils->LinkBlocks.begin(); i != Utils->LinkBlocks.end(); ++i) + { + Link* L = *i; + if (L->IPAddr == host) + { + Utils->ValidIPs.push_back(result); + break; + } + } +} + +void SecurityIPResolver::OnError(ResolverError e, const std::string &errormessage) +{ + if (query == DNS_QUERY_AAAA) + { + bool cached; + SecurityIPResolver* res = new SecurityIPResolver(mine, Utils, host, MyLink, cached, DNS_QUERY_A); + ServerInstance->AddResolver(res, cached); + return; + } + ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Could not resolve IP associated with Link '%s': %s", + MyLink->Name.c_str(),errormessage.c_str()); +} diff --git a/src/modules/m_spanningtree/resolvers.h b/src/modules/m_spanningtree/resolvers.h index cb3b38516..65b9e7249 100644 --- a/src/modules/m_spanningtree/resolvers.h +++ b/src/modules/m_spanningtree/resolvers.h @@ -39,28 +39,9 @@ class SecurityIPResolver : public Resolver std::string host; QueryType query; public: - SecurityIPResolver(Module* me, SpanningTreeUtilities* U, const std::string &hostname, Link* x, bool &cached, QueryType qt) - : Resolver(hostname, qt, cached, me), MyLink(x), Utils(U), mine(me), host(hostname), query(qt) - { - } - - void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached) - { - Utils->ValidIPs.push_back(result); - } - - void OnError(ResolverError e, const std::string &errormessage) - { - if (query == DNS_QUERY_AAAA) - { - bool cached; - SecurityIPResolver* res = new SecurityIPResolver(mine, Utils, host, MyLink, cached, DNS_QUERY_A); - ServerInstance->AddResolver(res, cached); - return; - } - ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Could not resolve IP associated with Link '%s': %s", - MyLink->Name.c_str(),errormessage.c_str()); - } + SecurityIPResolver(Module* me, SpanningTreeUtilities* U, const std::string &hostname, Link* x, bool &cached, QueryType qt); + void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached); + void OnError(ResolverError e, const std::string &errormessage); }; /** This class is used to resolve server hostnames during /connect and autoconnect. diff --git a/src/modules/m_spanningtree/server.cpp b/src/modules/m_spanningtree/server.cpp index 1b13fb2da..64c32e8fb 100644 --- a/src/modules/m_spanningtree/server.cpp +++ b/src/modules/m_spanningtree/server.cpp @@ -163,15 +163,15 @@ bool TreeSocket::Outbound_Reply_Server(parameterlist ¶ms) linkID = sname; MyRoot = new TreeServer(Utils, sname, description, sid, Utils->TreeRoot, this, x->Hidden); - Utils->TreeRoot->AddChild(MyRoot); + this->DoBurst(MyRoot); + params[4] = ":" + params[4]; /* IMPORTANT: Take password/hmac hash OUT of here before we broadcast the introduction! */ params[1] = "*"; Utils->DoOneToAllButSender(ServerInstance->Config->GetSID(),"SERVER",params,sname); - this->DoBurst(MyRoot); return true; } @@ -259,10 +259,6 @@ bool TreeSocket::Inbound_Server(parameterlist ¶ms) MyRoot = new TreeServer(Utils, sname, description, sid, Utils->TreeRoot, this, x->Hidden); Utils->TreeRoot->AddChild(MyRoot); - params[1] = "*"; - params[4] = ":" + params[4]; - Utils->DoOneToAllButSender(ServerInstance->Config->GetSID(),"SERVER",params,sname); - this->LinkState = WAIT_AUTH_2; return true; } diff --git a/src/modules/m_spanningtree/treesocket1.cpp b/src/modules/m_spanningtree/treesocket1.cpp index 673b05c55..dcb35af31 100644 --- a/src/modules/m_spanningtree/treesocket1.cpp +++ b/src/modules/m_spanningtree/treesocket1.cpp @@ -183,10 +183,14 @@ void TreeSocket::Squit(TreeServer* Current, const std::string &reason) { DelServerEvent(Utils->Creator, Current->GetName()); - parameterlist params; - params.push_back(Current->GetName()); - params.push_back(":"+reason); - Utils->DoOneToAllButSender(Current->GetParent()->GetName(),"SQUIT",params,Current->GetName()); + if (!Current->GetSocket() || Current->GetSocket()->GetLinkState() == CONNECTED) + { + parameterlist params; + params.push_back(Current->GetName()); + params.push_back(":"+reason); + Utils->DoOneToAllButSender(Current->GetParent()->GetName(),"SQUIT",params,Current->GetName()); + } + if (Current->GetParent() == Utils->TreeRoot) { ServerInstance->SNO->WriteGlobalSno('l', "Server \002"+Current->GetName()+"\002 split: "+reason); diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp index 4582eb4c5..cb49d92c9 100644 --- a/src/modules/m_spanningtree/treesocket2.cpp +++ b/src/modules/m_spanningtree/treesocket2.cpp @@ -165,12 +165,19 @@ void TreeSocket::ProcessLine(std::string &line) } } this->LinkState = CONNECTED; - Utils->timeoutlist.erase(this); - parameterlist sparams; - Utils->DoOneToAllButSender(MyRoot->GetID(), "BURST", params, MyRoot->GetName()); + MyRoot->bursting = true; this->DoBurst(MyRoot); + + parameterlist sparams; + sparams.push_back(MyRoot->GetName()); + sparams.push_back("*"); + sparams.push_back("0"); + sparams.push_back(MyRoot->GetID()); + sparams.push_back(":" + MyRoot->GetDesc()); + Utils->DoOneToAllButSender(ServerInstance->Config->GetSID(), "SERVER", sparams, MyRoot->GetName()); + Utils->DoOneToAllButSender(MyRoot->GetID(), "BURST", params, MyRoot->GetName()); } else if (command == "ERROR") { diff --git a/src/modules/m_spanningtree/uid.cpp b/src/modules/m_spanningtree/uid.cpp index 67a21a484..0a8f4dbfc 100644 --- a/src/modules/m_spanningtree/uid.cpp +++ b/src/modules/m_spanningtree/uid.cpp @@ -154,7 +154,7 @@ CmdResult CommandUID::Handle(const parameterlist ¶ms, User* serversrc) dosend = false; if (dosend) - ServerInstance->SNO->WriteToSnoMask('C',"Client connecting at %s: %s!%s@%s [%s] [%s]", _new->server.c_str(), _new->nick.c_str(), _new->ident.c_str(), _new->host.c_str(), _new->GetIPString(), _new->fullname.c_str()); + ServerInstance->SNO->WriteToSnoMask('C',"Client connecting at %s: %s!%s@%s (%s) [%s]", _new->server.c_str(), _new->nick.c_str(), _new->ident.c_str(), _new->host.c_str(), _new->GetIPString(), _new->fullname.c_str()); FOREACH_MOD(I_OnPostConnect,OnPostConnect(_new)); diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp index ec9d5aacc..75d4eaca3 100644 --- a/src/modules/m_spanningtree/utils.cpp +++ b/src/modules/m_spanningtree/utils.cpp @@ -319,17 +319,9 @@ void SpanningTreeUtilities::RefreshIPCache() for (std::vector<reference<Link> >::iterator i = LinkBlocks.begin(); i != LinkBlocks.end(); ++i) { Link* L = *i; - if (L->IPAddr.empty() || L->RecvPass.empty() || L->SendPass.empty() || L->Name.empty() || !L->Port) + if (!L->Port) { - if (L->Name.empty()) - { - ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"m_spanningtree: Ignoring a malformed link block (all link blocks require a name!)"); - } - else - { - ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"m_spanningtree: Ignoring a link block missing recvpass, sendpass, port or ipaddr."); - } - + ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"m_spanningtree: Ignoring a link block without a port."); /* Invalid link block */ continue; } @@ -339,7 +331,7 @@ void SpanningTreeUtilities::RefreshIPCache() irc::sockets::sockaddrs dummy; bool ipvalid = irc::sockets::aptosa(L->IPAddr, L->Port, dummy); - if (ipvalid) + if ((L->IPAddr == "*") || (ipvalid)) ValidIPs.push_back(L->IPAddr); else { @@ -377,7 +369,6 @@ void SpanningTreeUtilities::ReadConfiguration() AutoconnectBlocks.clear(); LinkBlocks.clear(); - ValidIPs.clear(); ConfigTagList tags = ServerInstance->Config->ConfTags("link"); for(ConfigIter i = tags.first; i != tags.second; ++i) { @@ -396,55 +387,37 @@ void SpanningTreeUtilities::ReadConfiguration() L->Bind = tag->getString("bind"); L->Hidden = tag->getBool("hidden"); + if (L->Name.empty()) + throw ModuleException("Invalid configuration, found a link tag without a name!" + (!L->IPAddr.empty() ? " IP address: "+L->IPAddr : "")); + if (L->Name.find('.') == std::string::npos) - throw CoreException("The link name '"+assign(L->Name)+"' is invalid and must contain at least one '.' character"); + throw ModuleException("The link name '"+assign(L->Name)+"' is invalid as it must contain at least one '.' character"); if (L->Name.length() > 64) - throw CoreException("The link name '"+assign(L->Name)+"' is longer than 64 characters!"); + throw ModuleException("The link name '"+assign(L->Name)+"' is invalid as it is longer than 64 characters"); - if (L->Fingerprint.find(':') != std::string::npos) - { - std::string tmp = L->Fingerprint; - L->Fingerprint.clear(); - for(unsigned int j=0; j < tmp.length(); j++) - if (tmp[j] != ':') - L->Fingerprint.push_back(tmp[j]); - } + if (L->RecvPass.empty()) + throw ModuleException("Invalid configuration for server '"+assign(L->Name)+"', recvpass not defined"); - if ((!L->IPAddr.empty()) && (!L->RecvPass.empty()) && (!L->SendPass.empty()) && (!L->Name.empty()) && (L->Port)) - { - ValidIPs.push_back(L->IPAddr); - } - else - { - if (L->IPAddr.empty()) - { - L->IPAddr = "*"; - ValidIPs.push_back("*"); - ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Configuration warning: Link block " + assign(L->Name) + " has no IP defined! This will allow any IP to connect as this server, and MAY not be what you want."); - } + if (L->SendPass.empty()) + throw ModuleException("Invalid configuration for server '"+assign(L->Name)+"', sendpass not defined"); - if (L->RecvPass.empty()) - { - throw CoreException("Invalid configuration for server '"+assign(L->Name)+"', recvpass not defined!"); - } + if ((L->SendPass.find(' ') != std::string::npos) || (L->RecvPass.find(' ') != std::string::npos)) + throw ModuleException("Link block '" + assign(L->Name) + "' has a password set that contains a space character which is invalid"); - if (L->SendPass.empty()) - { - throw CoreException("Invalid configuration for server '"+assign(L->Name)+"', sendpass not defined!"); - } + if ((L->SendPass[0] == ':') || (L->RecvPass[0] == ':')) + throw ModuleException("Link block '" + assign(L->Name) + "' has a password set that begins with a colon (:) which is invalid"); - if (L->Name.empty()) - { - throw CoreException("Invalid configuration, link tag without a name! IP address: "+L->IPAddr); - } - - if (!L->Port) - { - ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Configuration warning: Link block " + assign(L->Name) + " has no port defined, you will not be able to /connect it."); - } + if (L->IPAddr.empty()) + { + L->IPAddr = "*"; + ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Configuration warning: Link block '" + assign(L->Name) + "' has no IP defined! This will allow any IP to connect as this server, and MAY not be what you want."); } + if (!L->Port) + ServerInstance->Logs->Log("m_spanningtree",DEFAULT,"Configuration warning: Link block '" + assign(L->Name) + "' has no port defined, you will not be able to /connect it."); + + L->Fingerprint.erase(std::remove(L->Fingerprint.begin(), L->Fingerprint.end(), ':'), L->Fingerprint.end()); LinkBlocks.push_back(L); } @@ -465,12 +438,12 @@ void SpanningTreeUtilities::ReadConfiguration() if (A->Period <= 0) { - throw CoreException("Invalid configuration for autoconnect, period not a positive integer!"); + throw ModuleException("Invalid configuration for autoconnect, period not a positive integer!"); } if (A->servers.empty()) { - throw CoreException("Invalid configuration for autoconnect, server cannot be empty!"); + throw ModuleException("Invalid configuration for autoconnect, server cannot be empty!"); } AutoconnectBlocks.push_back(A); |