X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fcoremods%2Fcore_hostname_lookup.cpp;h=ec93732b124c732b7569f36454f6fdde55b3b762;hb=b7716ed57704b2b2bcc665a590aecc8f02de631d;hp=c26d3b3d32fc82e5e5f0d3f756f5436eb3d98642;hpb=c67d3103e9f7397f0ab9631bf07a5e5547deb2c3;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/coremods/core_hostname_lookup.cpp b/src/coremods/core_hostname_lookup.cpp index c26d3b3d3..ec93732b1 100644 --- a/src/coremods/core_hostname_lookup.cpp +++ b/src/coremods/core_hostname_lookup.cpp @@ -1,7 +1,7 @@ /* * InspIRCd -- Internet Relay Chat Daemon * - * Copyright (C) 2013 Adam + * 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 @@ -56,34 +56,39 @@ 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); if (!bound_user) { - ServerInstance->Logs->Log("RESOLVER", LOG_DEBUG, "Resolution finished for user '%s' who is gone", uuid.c_str()); + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Resolution finished for user '%s' who is gone", uuid.c_str()); return; } - const DNS::ResourceRecord& ans_record = r->answers[0]; + const DNS::ResourceRecord* ans_record = r->FindAnswerOfType(this->question.type); + if (ans_record == NULL) + { + OnError(r); + return; + } - ServerInstance->Logs->Log("RESOLVER", 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 result for %s: '%s' -> '%s'", uuid.c_str(), ans_record->name.c_str(), ans_record->rdata.c_str()); if (!fwd) { // first half of resolution is done. We now need to verify that the host matches. - ph->set(bound_user, ans_record.rdata); + 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); + res_forward = new UserResolver(this->manager, this->creator, bound_user, ans_record->rdata, DNS::QUERY_AAAA); } else { /* IPV4 lookup */ - res_forward = new UserResolver(this->manager, this->creator, bound_user, ans_record.rdata, DNS::QUERY_A); + res_forward = new UserResolver(this->manager, this->creator, bound_user, ans_record->rdata, DNS::QUERY_A); } try { @@ -104,10 +109,10 @@ class UserResolver : public DNS::Request 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)) + if (inet_pton(AF_INET6, ans_record->rdata.c_str(), &res_bin)) { rev_match = !memcmp(&user_ip->in6.sin6_addr, &res_bin, sizeof(res_bin)); } @@ -115,7 +120,7 @@ class UserResolver : public DNS::Request else { struct in_addr res_bin; - if (inet_pton(AF_INET, ans_record.rdata.c_str(), &res_bin)) + if (inet_pton(AF_INET, ans_record->rdata.c_str(), &res_bin)) { rev_match = !memcmp(&user_ip->in4.sin_addr, &res_bin, sizeof(res_bin)); } @@ -129,26 +134,22 @@ class UserResolver : public DNS::Request if (hostname == NULL) { - ServerInstance->Logs->Log("RESOLVER", LOG_DEFAULT, "ERROR: User has no hostname attached when doing a forward lookup"); + 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() < 65) + 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->host.assign(*hostname, 0, 64); - bound_user->dhost = bound_user->host; - - /* Invalidate cache */ - bound_user->InvalidateCache(); + bound_user->ChangeRealHost(hostname->substr(0, ServerInstance->Config->Limits.MaxHost), true); } else { - bound_user->WriteNotice("*** Your hostname is longer than the maximum of 64 characters, using your IP address (" + bound_user->GetIPString() + ") instead."); + 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); @@ -163,14 +164,13 @@ 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); 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); - ServerInstance->stats->statsDnsBad++; } } }; @@ -183,15 +183,15 @@ class ModuleHostnameLookup : public Module public: ModuleHostnameLookup() - : dnsLookup("dnsLookup", this) - , ptrHosts("ptrHosts", this) + : dnsLookup("dnsLookup", ExtensionItem::EXT_USER, this) + , ptrHosts("ptrHosts", ExtensionItem::EXT_USER, this) , DNS(this, "DNS") { dl = &dnsLookup; ph = &ptrHosts; } - void OnUserInit(LocalUser *user) + void OnSetUserIP(LocalUser* user) CXX11_OVERRIDE { if (!DNS || !user->MyClass->resolvehostnames) { @@ -199,6 +199,13 @@ class ModuleHostnameLookup : public Module 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) + { + user->WriteNotice("*** Skipping host resolution (connected via a non-IP socket)"); + return; + } + user->WriteNotice("*** Looking up your hostname..."); UserResolver* res_reverse = new UserResolver(*this->DNS, this, user, user->GetIPString(), DNS::QUERY_PTR); @@ -215,16 +222,15 @@ class ModuleHostnameLookup : public Module this->dnsLookup.set(user, 0); delete res_reverse; ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Error in resolver: " + e.GetReason()); - ServerInstance->stats->statsDnsBad++; } } - ModResult OnCheckReady(LocalUser* user) + ModResult OnCheckReady(LocalUser* user) CXX11_OVERRIDE { return this->dnsLookup.get(user) ? MOD_RES_DENY : MOD_RES_PASSTHRU; } - Version GetVersion() + Version GetVersion() CXX11_OVERRIDE { return Version("Provides support for DNS lookups on connecting clients", VF_CORE|VF_VENDOR); }