X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fcoremods%2Fcore_hostname_lookup.cpp;h=91d817765a17cafb44629b7a11e46d6bdf490c57;hb=e0dc7691c4cff3a38bc12adf10b3709d8c4901ba;hp=2a8426be9c133523bacf1edd0d2d99218ad4e30e;hpb=d865b434865907bfad0a187dd403d4ca8144e469;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/coremods/core_hostname_lookup.cpp b/src/coremods/core_hostname_lookup.cpp index 2a8426be9..91d817765 100644 --- a/src/coremods/core_hostname_lookup.cpp +++ b/src/coremods/core_hostname_lookup.cpp @@ -1,7 +1,10 @@ /* * InspIRCd -- Internet Relay Chat Daemon * - * Copyright (C) 2013-2016 Adam + * Copyright (C) 2020 Matt Schatz + * Copyright (C) 2013-2015 Attila Molnar + * Copyright (C) 2013, 2017-2020 Sadie Powell + * Copyright (C) 2013, 2016 Adam * * This file is part of InspIRCd. InspIRCd is free software: you can * redistribute it and/or modify it under the terms of the GNU General Public @@ -23,19 +26,26 @@ namespace { LocalIntExt* dl; - LocalStringExt* ph; } /** Derived from Resolver, and performs user forward/reverse lookups. */ class UserResolver : public DNS::Request { + private: /** UUID we are looking up */ const std::string uuid; - /** True if the lookup is forward, false if is a reverse lookup - */ - const bool fwd; + /** Handles errors which happen during DNS resolution. */ + static void HandleError(LocalUser* user, const std::string& message) + { + user->WriteNotice("*** " + message + "; using your IP address (" + user->GetIPString() + ") instead."); + + bool display_is_real = user->GetDisplayedHost() == user->GetRealHost(); + user->ChangeRealHost(user->GetIPString(), display_is_real); + + dl->unset(user); + } public: /** Create a resolver. @@ -48,7 +58,6 @@ class UserResolver : public DNS::Request UserResolver(DNS::Manager* mgr, Module* me, LocalUser* user, const std::string& to_resolve, DNS::QueryType qt) : DNS::Request(mgr, me, to_resolve, qt) , uuid(user->uuid) - , fwd(qt == DNS::QUERY_A || qt == DNS::QUERY_AAAA) { } @@ -56,9 +65,9 @@ class UserResolver : public DNS::Request * if a previous result has already come back. * @param r The finished query */ - void OnLookupComplete(const DNS::Query* r) + void OnLookupComplete(const DNS::Query* r) CXX11_OVERRIDE { - LocalUser* bound_user = (LocalUser*)ServerInstance->FindUUID(uuid); + LocalUser* bound_user = IS_LOCAL(ServerInstance->FindUUID(uuid)); if (!bound_user) { ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Resolution finished for user '%s' who is gone", uuid.c_str()); @@ -68,19 +77,19 @@ class UserResolver : public DNS::Request const DNS::ResourceRecord* ans_record = r->FindAnswerOfType(this->question.type); if (ans_record == NULL) { - OnError(r); + HandleError(bound_user, "Could not resolve your hostname: No " + this->manager->GetTypeStr(this->question.type) + " records found"); return; } - ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "DNS result for %s: '%s' -> '%s'", uuid.c_str(), ans_record->name.c_str(), ans_record->rdata.c_str()); + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "DNS %s result for %s: '%s' -> '%s'%s", + this->manager->GetTypeStr(question.type).c_str(), uuid.c_str(), + ans_record->name.c_str(), ans_record->rdata.c_str(), + r->cached ? " (cached)" : ""); - if (!fwd) + if (this->question.type == DNS::QUERY_PTR) { - // first half of resolution is done. We now need to verify that the host matches. - ph->set(bound_user, ans_record->rdata); - UserResolver* res_forward; - if (bound_user->client_sa.sa.sa_family == AF_INET6) + if (bound_user->client_sa.family() == AF_INET6) { /* IPV6 forward lookup */ res_forward = new UserResolver(this->manager, this->creator, bound_user, ans_record->rdata, DNS::QUERY_AAAA); @@ -99,17 +108,16 @@ class UserResolver : public DNS::Request delete res_forward; ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Error in resolver: " + e.GetReason()); - bound_user->WriteNotice("*** There was an internal error resolving your host, using your IP address (" + bound_user->GetIPString() + ") instead."); - dl->set(bound_user, 0); + HandleError(bound_user, "There was an internal error resolving your host"); } } - else + else if (this->question.type == DNS::QUERY_A || this->question.type == DNS::QUERY_AAAA) { /* Both lookups completed */ irc::sockets::sockaddrs* user_ip = &bound_user->client_sa; bool rev_match = false; - if (user_ip->sa.sa_family == AF_INET6) + if (user_ip->family() == AF_INET6) { struct in6_addr res_bin; if (inet_pton(AF_INET6, ans_record->rdata.c_str(), &res_bin)) @@ -126,37 +134,16 @@ class UserResolver : public DNS::Request } } - dl->set(bound_user, 0); - if (rev_match) { - std::string* hostname = ph->get(bound_user); - - if (hostname == NULL) - { - ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "ERROR: User has no hostname attached when doing a forward lookup"); - bound_user->WriteNotice("*** There was an internal error resolving your host, using your IP address (" + bound_user->GetIPString() + ") instead."); - return; - } - else if (hostname->length() <= ServerInstance->Config->Limits.MaxHost) - { - /* Hostnames starting with : are not a good thing (tm) */ - if ((*hostname)[0] == ':') - hostname->insert(0, "0"); - - bound_user->WriteNotice("*** Found your hostname (" + *hostname + (r->cached ? ") -- cached" : ")")); - bound_user->ChangeRealHost(hostname->substr(ServerInstance->Config->Limits.MaxHost), true); - } - else - { - bound_user->WriteNotice("*** Your hostname is longer than the maximum of " + ConvToStr(ServerInstance->Config->Limits.MaxHost) + " characters, using your IP address (" + bound_user->GetIPString() + ") instead."); - } - - ph->unset(bound_user); + bound_user->WriteNotice("*** Found your hostname (" + this->question.name + (r->cached ? ") -- cached" : ")")); + bool display_is_real = bound_user->GetDisplayedHost() == bound_user->GetRealHost(); + bound_user->ChangeRealHost(this->question.name, display_is_real); + dl->unset(bound_user); } else { - bound_user->WriteNotice("*** Your hostname does not match up with your IP address. Sorry, using your IP address (" + bound_user->GetIPString() + ") instead."); + HandleError(bound_user, "Your hostname does not match up with your IP address"); } } } @@ -164,40 +151,38 @@ class UserResolver : public DNS::Request /** Called on failed lookup * @param query The errored query */ - void OnError(const DNS::Query* query) + void OnError(const DNS::Query* query) CXX11_OVERRIDE { - LocalUser* bound_user = (LocalUser*)ServerInstance->FindUUID(uuid); + LocalUser* bound_user = IS_LOCAL(ServerInstance->FindUUID(uuid)); if (bound_user) - { - bound_user->WriteNotice("*** Could not resolve your hostname: " + this->manager->GetErrorStr(query->error) + "; using your IP address (" + bound_user->GetIPString() + ") instead."); - dl->set(bound_user, 0); - } + HandleError(bound_user, "Could not resolve your hostname: " + this->manager->GetErrorStr(query->error)); } }; class ModuleHostnameLookup : public Module { + private: LocalIntExt dnsLookup; - LocalStringExt ptrHosts; dynamic_reference DNS; public: ModuleHostnameLookup() : dnsLookup("dnsLookup", ExtensionItem::EXT_USER, this) - , ptrHosts("ptrHosts", ExtensionItem::EXT_USER, this) , DNS(this, "DNS") { dl = &dnsLookup; - ph = &ptrHosts; } - void OnUserInit(LocalUser *user) CXX11_OVERRIDE + void OnSetUserIP(LocalUser* user) CXX11_OVERRIDE { - if (!DNS || !user->MyClass->resolvehostnames) - { - user->WriteNotice("*** Skipping host resolution (disabled by server administrator)"); + // If core_dns is not loaded or hostname resolution is disabled for the user's + // connect class then the logic in this function does not apply. + if (!DNS || user->quitting || !user->MyClass->resolvehostnames) + return; + + // Clients can't have a DNS hostname if they aren't connected via IPv4 or IPv6. + if (user->client_sa.family() != AF_INET && user->client_sa.family() != AF_INET6) return; - } user->WriteNotice("*** Looking up your hostname...");