diff options
author | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2010-02-12 22:30:27 +0000 |
---|---|---|
committer | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2010-02-12 22:30:27 +0000 |
commit | 69e28c67dddd8b74ee4c321667d286111e09e5da (patch) | |
tree | b5de7bc4ab8abfc93b1adc0721f62ba5d54e5760 | |
parent | 39cf323606a311b3b7f59a9c9f39a21d42520c24 (diff) |
Remove possible references to deleted User objects due to DNS lookups
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12445 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r-- | include/users.h | 15 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_gnutls.cpp | 10 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_openssl.cpp | 8 | ||||
-rw-r--r-- | src/modules/m_cgiirc.cpp | 18 | ||||
-rw-r--r-- | src/modules/m_dnsbl.cpp | 13 | ||||
-rw-r--r-- | src/modules/m_testnet.cpp | 5 | ||||
-rw-r--r-- | src/user_resolver.cpp | 53 | ||||
-rw-r--r-- | src/users.cpp | 71 |
8 files changed, 79 insertions, 114 deletions
diff --git a/include/users.h b/include/users.h index 6b891d7da..ed7b6bf5e 100644 --- a/include/users.h +++ b/include/users.h @@ -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. @@ -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; @@ -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 @@ -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; diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index c2dc4c878..243c8e28e 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -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 diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 018d7351e..7d46cf66a 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -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()); } } } diff --git a/src/modules/m_cgiirc.cpp b/src/modules/m_cgiirc.cpp index 27309e677..618eec9f5 100644 --- a/src/modules/m_cgiirc.cpp +++ b/src/modules/m_cgiirc.cpp @@ -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()); @@ -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()); @@ -298,7 +300,7 @@ public: { 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 (...) @@ -349,7 +351,7 @@ public: { 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 (...) diff --git a/src/modules/m_dnsbl.cpp b/src/modules/m_dnsbl.cpp index 8fa627ab8..818450b79 100644 --- a/src/modules/m_dnsbl.cpp +++ b/src/modules/m_dnsbl.cpp @@ -45,17 +45,15 @@ 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; } @@ -63,7 +61,8 @@ class DNSBLResolver : public Resolver 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()) @@ -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); } diff --git a/src/modules/m_testnet.cpp b/src/modules/m_testnet.cpp index 43c06978b..cd57cb52b 100644 --- a/src/modules/m_testnet.cpp +++ b/src/modules/m_testnet.cpp @@ -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); diff --git a/src/user_resolver.cpp b/src/user_resolver.cpp index 5180d670a..156bb9828 100644 --- a/src/user_resolver.cpp +++ b/src/user_resolver.cpp @@ -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); @@ -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) { @@ -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++; } } diff --git a/src/users.cpp b/src/users.cpp index 1a9c2da18..89a064b1f 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -18,37 +18,7 @@ #include "bancache.h" #include "commands/cmd_whowas.h" -typedef unsigned int uniq_id_t; -class sent -{ - uniq_id_t uniq_id; - uniq_id_t* array; - void init() - { - if (!array) - array = new uniq_id_t[ServerInstance->SE->GetMaxFds()]; - memset(array, 0, ServerInstance->SE->GetMaxFds() * sizeof(uniq_id_t)); - uniq_id++; - } - public: - sent() : uniq_id(static_cast<uniq_id_t>(-1)), array(NULL) {} - inline uniq_id_t operator++() - { - if (++uniq_id == 0) - init(); - return uniq_id; - } - inline uniq_id_t& operator[](int i) - { - return array[i]; - } - ~sent() - { - delete[] array; - } -}; - -static sent already_sent; +already_sent_t LocalUser::already_sent_id = 0; std::string User::ProcessNoticeMasks(const char *sm) { @@ -222,12 +192,11 @@ User::User(const std::string &uid, const std::string& sid, int type) } LocalUser::LocalUser(int myfd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* servaddr) - : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL), eh(this) + : User(ServerInstance->GetUID(), ServerInstance->Config->ServerName, USERTYPE_LOCAL), eh(this), + bytes_in(0), bytes_out(0), cmds_in(0), cmds_out(0), nping(0), CommandFloodPenalty(0), + already_sent(0) { - bytes_in = bytes_out = cmds_in = cmds_out = 0; - server_sa.sa.sa_family = AF_UNSPEC; - CommandFloodPenalty = 0; - lastping = nping = 0; + lastping = 0; eh.SetFd(myfd); memcpy(&client_sa, client, sizeof(irc::sockets::sockaddrs)); memcpy(&server_sa, servaddr, sizeof(irc::sockets::sockaddrs)); @@ -1193,7 +1162,7 @@ void User::WriteCommonRaw(const std::string &line, bool include_self) if (this->registered != REG_ALL || quitting) return; - uniq_id_t uniq_id = ++already_sent; + LocalUser::already_sent_id++; UserChanList include_c(chans); std::map<User*,bool> exceptions; @@ -1207,7 +1176,7 @@ void User::WriteCommonRaw(const std::string &line, bool include_self) LocalUser* u = IS_LOCAL(i->first); if (u && !u->quitting) { - already_sent[u->GetFd()] = uniq_id; + u->already_sent = LocalUser::already_sent_id; if (i->second) u->Write(line); } @@ -1219,9 +1188,9 @@ void User::WriteCommonRaw(const std::string &line, bool include_self) for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { LocalUser* u = IS_LOCAL(i->first); - if (u && !u->quitting && already_sent[u->GetFd()] != uniq_id) + if (u && !u->quitting && u->already_sent != LocalUser::already_sent_id) { - already_sent[u->GetFd()] = uniq_id; + u->already_sent = LocalUser::already_sent_id; u->Write(line); } } @@ -1236,7 +1205,7 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op if (this->registered != REG_ALL) return; - uniq_id_t uniq_id = ++already_sent; + already_sent_t uniq_id = ++LocalUser::already_sent_id; snprintf(tb1,MAXBUF,":%s QUIT :%s",this->GetFullHost().c_str(),normal_text.c_str()); snprintf(tb2,MAXBUF,":%s QUIT :%s",this->GetFullHost().c_str(),oper_text.c_str()); @@ -1253,7 +1222,7 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op LocalUser* u = IS_LOCAL(i->first); if (u && !u->quitting) { - already_sent[u->GetFd()] = uniq_id; + u->already_sent = uniq_id; if (i->second) u->Write(IS_OPER(u) ? out2 : out1); } @@ -1264,9 +1233,9 @@ void User::WriteCommonQuit(const std::string &normal_text, const std::string &op for (UserMembList::const_iterator i = ulist->begin(); i != ulist->end(); i++) { LocalUser* u = IS_LOCAL(i->first); - if (u && !u->quitting && (already_sent[u->GetFd()] != uniq_id)) + if (u && !u->quitting && (u->already_sent != uniq_id)) { - already_sent[u->GetFd()] = uniq_id; + u->already_sent = uniq_id; u->Write(IS_OPER(u) ? out2 : out1); } } @@ -1377,8 +1346,8 @@ void User::DoHostCycle(const std::string &quitline) if (!ServerInstance->Config->CycleHosts) return; - uniq_id_t silent_id = ++already_sent; - uniq_id_t seen_id = ++already_sent; + already_sent_t silent_id = ++LocalUser::already_sent_id; + already_sent_t seen_id = ++LocalUser::already_sent_id; UserChanList include_c(chans); std::map<User*,bool> exceptions; @@ -1392,12 +1361,12 @@ void User::DoHostCycle(const std::string &quitline) { if (i->second) { - already_sent[u->GetFd()] = seen_id; + u->already_sent = seen_id; u->Write(quitline); } else { - already_sent[u->GetFd()] = silent_id; + u->already_sent = silent_id; } } } @@ -1422,13 +1391,13 @@ void User::DoHostCycle(const std::string &quitline) LocalUser* u = IS_LOCAL(i->first); if (u == NULL || u == this) continue; - if (already_sent[u->GetFd()] == silent_id) + if (u->already_sent == silent_id) continue; - if (already_sent[u->GetFd()] != seen_id) + if (u->already_sent != seen_id) { u->Write(quitline); - already_sent[u->GetFd()] = seen_id; + u->already_sent = seen_id; } u->Write(joinline); if (modeline.length() > 0) |