Skip to content

Commit

Permalink
Remove possible references to deleted User objects due to DNS lookups
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12445 e03df62e-2008-0410-955e-edbf42e46eb7
  • Loading branch information
danieldg committed Feb 12, 2010
1 parent 39cf323 commit 69e28c6
Show file tree
Hide file tree
Showing 8 changed files with 79 additions and 114 deletions.
15 changes: 7 additions & 8 deletions include/users.h
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,8 @@ class CoreExport UserIOHandler : public StreamSocket
void AddWriteBuf(const std::string &data);
};

typedef unsigned int already_sent_t;

class CoreExport LocalUser : public User
{
/** A list of channels the user has a pending invite to.
Expand Down Expand Up @@ -776,6 +778,9 @@ class CoreExport LocalUser : public User
*/
unsigned int CommandFloodPenalty;

static already_sent_t already_sent_id;
already_sent_t already_sent;

/** Stored reverse lookup from res_forward. Should not be used after resolution.
*/
std::string stored_host;
Expand Down Expand Up @@ -851,8 +856,6 @@ class CoreExport LocalUser : public User
* @return True if the user can set or unset this mode.
*/
bool HasModePermission(unsigned char mode, ModeType type);

inline int GetFd() { return eh.GetFd(); }
};

class CoreExport RemoteUser : public User
Expand Down Expand Up @@ -904,12 +907,8 @@ inline FakeUser* IS_SERVER(User* u)
class CoreExport UserResolver : public Resolver
{
private:
/** User this class is 'attached' to.
*/
LocalUser* bound_user;
/** File descriptor teh lookup is bound to
*/
int bound_fd;
/** UUID we are looking up */
std::string uuid;
/** True if the lookup is forward, false if is a reverse lookup
*/
bool fwd;
Expand Down
10 changes: 5 additions & 5 deletions src/modules/extra/m_ssl_gnutls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,13 +572,13 @@ class ModuleSSLGnuTLS : public Module
{
if (user->eh.GetIOHook() == this)
{
if (sessions[user->GetFd()].sess)
if (sessions[user->eh.GetFd()].sess)
{
ssl_cert* cert = sessions[user->GetFd()].cert;
ssl_cert* cert = sessions[user->eh.GetFd()].cert;
SSLCertSubmission(user, this, ServerInstance->Modules->Find("m_sslinfo.so"), cert);
std::string cipher = gnutls_kx_get_name(gnutls_kx_get(sessions[user->GetFd()].sess));
cipher.append("-").append(gnutls_cipher_get_name(gnutls_cipher_get(sessions[user->GetFd()].sess))).append("-");
cipher.append(gnutls_mac_get_name(gnutls_mac_get(sessions[user->GetFd()].sess)));
std::string cipher = gnutls_kx_get_name(gnutls_kx_get(sessions[user->eh.GetFd()].sess));
cipher.append("-").append(gnutls_cipher_get_name(gnutls_cipher_get(sessions[user->eh.GetFd()].sess))).append("-");
cipher.append(gnutls_mac_get_name(gnutls_mac_get(sessions[user->eh.GetFd()].sess)));
if (cert->fingerprint.empty())
user->WriteServ("NOTICE %s :*** You are connected using SSL cipher \"%s\"", user->nick.c_str(), cipher.c_str());
else
Expand Down
8 changes: 4 additions & 4 deletions src/modules/extra/m_ssl_openssl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,13 @@ class ModuleSSLOpenSSL : public Module
{
if (user->eh.GetIOHook() == this)
{
if (sessions[user->GetFd()].sess)
if (sessions[user->eh.GetFd()].sess)
{
SSLCertSubmission(user, this, ServerInstance->Modules->Find("m_sslinfo.so"), sessions[user->GetFd()].cert);
SSLCertSubmission(user, this, ServerInstance->Modules->Find("m_sslinfo.so"), sessions[user->eh.GetFd()].cert);

if (!sessions[user->GetFd()].cert->fingerprint.empty())
if (!sessions[user->eh.GetFd()].cert->fingerprint.empty())
user->WriteServ("NOTICE %s :*** You are connected using SSL fingerprint %s",
user->nick.c_str(), sessions[user->GetFd()].cert->fingerprint.c_str());
user->nick.c_str(), sessions[user->eh.GetFd()].cert->fingerprint.c_str());
}
}
}
Expand Down
18 changes: 10 additions & 8 deletions src/modules/m_cgiirc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,17 @@ class CommandWebirc : public Command
class CGIResolver : public Resolver
{
std::string typ;
int theirfd;
LocalUser* them;
std::string theiruid;
bool notify;
public:
CGIResolver(Module* me, bool NotifyOpers, const std::string &source, bool forward, LocalUser* u, int userfd, const std::string &type, bool &cached)
: Resolver(source, forward ? DNS_QUERY_A : DNS_QUERY_PTR4, cached, me), typ(type), theirfd(userfd), them(u), notify(NotifyOpers) { }
CGIResolver(Module* me, bool NotifyOpers, const std::string &source, bool forward, LocalUser* u, const std::string &type, bool &cached)
: Resolver(source, forward ? DNS_QUERY_A : DNS_QUERY_PTR4, cached, me), typ(type), theiruid(u->uuid), notify(NotifyOpers) { }

virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
{
/* Check the user still exists */
if ((them) && (&them->eh == ServerInstance->SE->GetRef(theirfd)))
User* them = ServerInstance->FindUUID(theiruid);
if (them)
{
if (notify)
ServerInstance->SNO->WriteGlobalSno('a', "Connecting user %s detected as using CGI:IRC (%s), changing real host to %s from %s", them->nick.c_str(), them->host.c_str(), result.c_str(), typ.c_str());
Expand All @@ -128,7 +128,9 @@ class CGIResolver : public Resolver

virtual void OnError(ResolverError e, const std::string &errormessage)
{
if ((them) && (&them->eh == ServerInstance->SE->GetRef(theirfd)))
User* them = ServerInstance->FindUUID(theiruid);
if (them)
if (them)
{
if (notify)
ServerInstance->SNO->WriteToSnoMask('a', "Connecting user %s detected as using CGI:IRC (%s), but their host can't be resolved from their %s!", them->nick.c_str(), them->host.c_str(), typ.c_str());
Expand Down Expand Up @@ -298,7 +300,7 @@ class ModuleCgiIRC : public Module
{

bool cached;
CGIResolver* r = new CGIResolver(this, NotifyOpers, user->password, false, user, user->GetFd(), "PASS", cached);
CGIResolver* r = new CGIResolver(this, NotifyOpers, user->password, false, user, "PASS", cached);
ServerInstance->AddResolver(r, cached);
}
catch (...)
Expand Down Expand Up @@ -349,7 +351,7 @@ class ModuleCgiIRC : public Module
{

bool cached;
CGIResolver* r = new CGIResolver(this, NotifyOpers, newipstr, false, user, user->GetFd(), "IDENT", cached);
CGIResolver* r = new CGIResolver(this, NotifyOpers, newipstr, false, user, "IDENT", cached);
ServerInstance->AddResolver(r, cached);
}
catch (...)
Expand Down
13 changes: 6 additions & 7 deletions src/modules/m_dnsbl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,25 +45,24 @@ class DNSBLConfEntry
*/
class DNSBLResolver : public Resolver
{
int theirfd;
LocalUser* them;
std::string theiruid;
DNSBLConfEntry *ConfEntry;

public:

DNSBLResolver(Module *me, const std::string &hostname, LocalUser* u, int userfd, DNSBLConfEntry *conf, bool &cached)
DNSBLResolver(Module *me, const std::string &hostname, LocalUser* u, DNSBLConfEntry *conf, bool &cached)
: Resolver(hostname, DNS_QUERY_A, cached, me)
{
theirfd = userfd;
them = u;
theiruid = u->uuid;
ConfEntry = conf;
}

/* Note: This may be called multiple times for multiple A record results */
virtual void OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
{
/* Check the user still exists */
if ((them) && (&them->eh == ServerInstance->SE->GetRef(theirfd)))
User* them = ServerInstance->FindUUID(theiruid);
if (them)
{
// Now we calculate the bitmask: 256*(256*(256*a+b)+c)+d
if(result.length())
Expand Down Expand Up @@ -352,7 +351,7 @@ class ModuleDNSBL : public Module

/* now we'd need to fire off lookups for `hostname'. */
bool cached;
DNSBLResolver *r = new DNSBLResolver(this, hostname, user, user->GetFd(), *i, cached);
DNSBLResolver *r = new DNSBLResolver(this, hostname, user, *i, cached);
ServerInstance->AddResolver(r, cached);
}

Expand Down
5 changes: 0 additions & 5 deletions src/modules/m_testnet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,6 @@ class CommandTest : public Command
{
IS_LOCAL(user)->CommandFloodPenalty += atoi(parameters[1].c_str());
}
else if (parameters[0] == "shutdown" && IS_LOCAL(user))
{
int i = parameters.size() > 1 ? atoi(parameters[1].c_str()) : 2;
ServerInstance->SE->Shutdown(IS_LOCAL(user)->GetFd(), i);
}
else if (parameters[0] == "check")
{
checkall(creator);
Expand Down
53 changes: 27 additions & 26 deletions src/user_resolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,26 @@

#include "inspircd.h"
UserResolver::UserResolver(LocalUser* user, std::string to_resolve, QueryType qt, bool &cache) :
Resolver(to_resolve, qt, cache, NULL), bound_user(user)
Resolver(to_resolve, qt, cache, NULL), uuid(user->uuid)
{
this->fwd = (qt == DNS_QUERY_A || qt == DNS_QUERY_AAAA);
this->bound_fd = user->GetFd();
}

void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl, bool cached)
{
UserResolver *res_forward; // for forward-resolution
LocalUser* bound_user = (LocalUser*)ServerInstance->FindUUID(uuid);

if ((!this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == &bound_user->eh))
if ((!this->fwd) && bound_user)
{
this->bound_user->stored_host = result;
bound_user->stored_host = result;
try
{
/* Check we didnt time out */
if (this->bound_user->registered != REG_ALL)
if (bound_user->registered != REG_ALL)
{
bool lcached = false;
if (this->bound_user->client_sa.sa.sa_family == AF_INET6)
if (bound_user->client_sa.sa.sa_family == AF_INET6)
{
/* IPV6 forward lookup */
res_forward = new UserResolver(bound_user, result, DNS_QUERY_AAAA, lcached);
Expand All @@ -50,11 +50,11 @@ void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl,
ServerInstance->Logs->Log("RESOLVER", DEBUG,"Error in resolver: %s",e.GetReason());
}
}
else if ((this->fwd) && (ServerInstance->SE->GetRef(this->bound_fd) == &bound_user->eh))
else if ((this->fwd) && bound_user)
{
/* Both lookups completed */

irc::sockets::sockaddrs* user_ip = &this->bound_user->client_sa;
irc::sockets::sockaddrs* user_ip = &bound_user->client_sa;
bool rev_match = false;
if (user_ip->sa.sa_family == AF_INET6)
{
Expand All @@ -75,54 +75,55 @@ void UserResolver::OnLookupComplete(const std::string &result, unsigned int ttl,

if (rev_match)
{
std::string hostname = this->bound_user->stored_host;
std::string hostname = bound_user->stored_host;
if (hostname.length() < 65)
{
/* Check we didnt time out */
if ((this->bound_user->registered != REG_ALL) && (!this->bound_user->dns_done))
if ((bound_user->registered != REG_ALL) && (!bound_user->dns_done))
{
/* Hostnames starting with : are not a good thing (tm) */
if (hostname[0] == ':')
hostname.insert(0, "0");

this->bound_user->WriteServ("NOTICE Auth :*** Found your hostname (%s)%s", hostname.c_str(), (cached ? " -- cached" : ""));
this->bound_user->dns_done = true;
this->bound_user->dhost.assign(hostname, 0, 64);
this->bound_user->host.assign(hostname, 0, 64);
bound_user->WriteServ("NOTICE Auth :*** Found your hostname (%s)%s", hostname.c_str(), (cached ? " -- cached" : ""));
bound_user->dns_done = true;
bound_user->dhost.assign(hostname, 0, 64);
bound_user->host.assign(hostname, 0, 64);
/* Invalidate cache */
this->bound_user->InvalidateCache();
bound_user->InvalidateCache();
}
}
else
{
if (!this->bound_user->dns_done)
if (!bound_user->dns_done)
{
this->bound_user->WriteServ("NOTICE Auth :*** Your hostname is longer than the maximum of 64 characters, using your IP address (%s) instead.", this->bound_user->GetIPString());
this->bound_user->dns_done = true;
bound_user->WriteServ("NOTICE Auth :*** Your hostname is longer than the maximum of 64 characters, using your IP address (%s) instead.", bound_user->GetIPString());
bound_user->dns_done = true;
}
}
}
else
{
if (!this->bound_user->dns_done)
if (!bound_user->dns_done)
{
this->bound_user->WriteServ("NOTICE Auth :*** Your hostname does not match up with your IP address. Sorry, using your IP address (%s) instead.", this->bound_user->GetIPString());
this->bound_user->dns_done = true;
bound_user->WriteServ("NOTICE Auth :*** Your hostname does not match up with your IP address. Sorry, using your IP address (%s) instead.", bound_user->GetIPString());
bound_user->dns_done = true;
}
}

// Save some memory by freeing this up; it's never used again in the user's lifetime.
this->bound_user->stored_host.resize(0);
bound_user->stored_host.resize(0);
}
}

void UserResolver::OnError(ResolverError e, const std::string &errormessage)
{
if (ServerInstance->SE->GetRef(this->bound_fd) == &bound_user->eh)
LocalUser* bound_user = (LocalUser*)ServerInstance->FindUUID(uuid);
if (bound_user)
{
this->bound_user->WriteServ("NOTICE Auth :*** Could not resolve your hostname: %s; using your IP address (%s) instead.", errormessage.c_str(), this->bound_user->GetIPString());
this->bound_user->dns_done = true;
this->bound_user->stored_host.resize(0);
bound_user->WriteServ("NOTICE Auth :*** Could not resolve your hostname: %s; using your IP address (%s) instead.", errormessage.c_str(), bound_user->GetIPString());
bound_user->dns_done = true;
bound_user->stored_host.resize(0);
ServerInstance->stats->statsDnsBad++;
}
}
Loading

0 comments on commit 69e28c6

Please sign in to comment.