diff options
39 files changed, 243 insertions, 163 deletions
@@ -178,7 +178,7 @@ if (defined $opt_data_dir) { if (defined $opt_log_dir) { $config{LOG_DIR} = $opt_log_dir; } -chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null | cut -c 1,2,3`); # GNUTLS Version. +chomp($config{HAS_GNUTLS} = `pkg-config --modversion gnutls 2>/dev/null`); # GNUTLS Version. if (defined $opt_freebsd_port) { diff --git a/include/command_parse.h b/include/command_parse.h index a49fc0b6e..4a88a8ec8 100644 --- a/include/command_parse.h +++ b/include/command_parse.h @@ -22,10 +22,6 @@ #pragma once -/** A list of dll/so files containing the command handlers for the core - */ -typedef std::map<std::string, void*> SharedObjectList; - /** This class handles command management and parsing. * It allows you to add and remove commands from the map, * call command handlers by name, and chop up comma seperated @@ -34,10 +30,6 @@ typedef std::map<std::string, void*> SharedObjectList; class CoreExport CommandParser { private: - /** Parameter buffer - */ - std::vector<std::string> para; - /** Process a parameter string into a list of items * @param command_p The output list of items * @param parameters The input string @@ -51,8 +43,6 @@ class CoreExport CommandParser */ void ProcessCommand(LocalUser* user, std::string& cmd); - - public: /** Command list, a hash_map of command names to Command* */ diff --git a/include/usermanager.h b/include/usermanager.h index 1ab48925d..f5df25f00 100644 --- a/include/usermanager.h +++ b/include/usermanager.h @@ -31,6 +31,8 @@ class CoreExport UserManager */ clonemap local_clones; public: + UserManager(); + ~UserManager() { for (user_hash::iterator i = clientlist->begin();i != clientlist->end();i++) @@ -62,7 +64,11 @@ class CoreExport UserManager /** Number of unregistered users online right now. * (Unregistered means before USER/NICK/dns) */ - int unregistered_count; + unsigned int unregistered_count; + + /** Number of elements in local_users + */ + unsigned int local_count; /** Map of global ip addresses for clone counting * XXX - this should be private, but m_clones depends on it currently. diff --git a/make/template/main.mk b/make/template/main.mk index 4930fa7e3..032fff5e2 100644 --- a/make/template/main.mk +++ b/make/template/main.mk @@ -281,8 +281,8 @@ configureclean: -rm -f org.inspircd.plist distclean: clean configureclean - rm -rf $(BASE) - find src/modules/ -type l | xargs rm -f + -rm -rf $(SOURCEPATH)/run + find $(SOURCEPATH)/src/modules -type l | xargs rm -f help: @echo 'InspIRCd Makefile' @@ -308,8 +308,7 @@ help: @echo ' Multiple targets may be separated by a space' @echo '' @echo ' clean Cleans object files produced by the compile' - @echo ' distclean Cleans all files produced by compile and ./configure' - @echo ' Note: this includes the Makefile' + @echo ' distclean Cleans all generated files (build, configure, run, etc)' @echo ' deinstall Removes the files created by "make install"' @echo diff --git a/src/command_parse.cpp b/src/command_parse.cpp index bb86219d7..7bedcd71e 100644 --- a/src/command_parse.cpp +++ b/src/command_parse.cpp @@ -378,7 +378,6 @@ bool CommandParser::AddCommand(Command *f) CommandParser::CommandParser() { - para.resize(128); } int CommandParser::TranslateUIDs(const std::vector<TranslateType> to, const std::vector<std::string> &source, std::string &dest, bool prefix_final, Command* custom_translator) @@ -440,7 +439,6 @@ int CommandParser::TranslateUIDs(const std::vector<TranslateType> to, const std: int CommandParser::TranslateUIDs(TranslateType to, const std::string &source, std::string &dest) { User* user = NULL; - std::string item; int translations = 0; dest.clear(); diff --git a/src/commands/cmd_info.cpp b/src/commands/cmd_info.cpp index 63debd3fe..6e5f2a909 100644 --- a/src/commands/cmd_info.cpp +++ b/src/commands/cmd_info.cpp @@ -64,26 +64,27 @@ static const char* const lines[] = { " Matt Smith, dz, <dz@inspircd.org>", " Daniel De Graaf, danieldg, <danieldg@inspircd.org>", " jackmcbarn, <jackmcbarn@inspircd.org>", + " Attila Molnar, Attila, <attilamolnar@hush.com>", " ", "\2Regular Contributors\2:", - " Majic MacGyver Namegduf Ankit", - " Phoenix Taros", + " Adam SaberUK", " ", "\2Other Contributors\2:", + " ChrisTX Shawn Shutter", + " ", + "\2Former Contributors\2:", " dmb Zaba skenmy GreenReaper", " Dan Jason satmd owine", " Adremelech John2 jilles HiroP", " eggy Bricker AnMaster djGrrr", " nenolod Quension praetorian pippijn", - " Adam", - " ", - "\2Former Contributors\2:", " CC jamie typobox43 Burlex (win32)", " Stskeeps ThaPrince BuildSmart Thunderhacker", - " Skip LeaChim", + " Skip LeaChim Majic MacGyver", + " Namegduf Ankit Phoenix Taros", " ", "\2Thanks To\2:", - " searchirc.com irc-junkie.org Brik", + " searchirc.com irc-junkie.org Brik fraggeln", " ", " Best experienced with: \2An IRC client\2", NULL diff --git a/src/commands/cmd_loadmodule.cpp b/src/commands/cmd_loadmodule.cpp index 9d60613a2..379e597e4 100644 --- a/src/commands/cmd_loadmodule.cpp +++ b/src/commands/cmd_loadmodule.cpp @@ -44,7 +44,7 @@ class CommandLoadmodule : public Command */ CmdResult CommandLoadmodule::Handle (const std::vector<std::string>& parameters, User *user) { - if (ServerInstance->Modules->Load(parameters[0].c_str())) + if (ServerInstance->Modules->Load(parameters[0])) { ServerInstance->SNO->WriteGlobalSno('a', "NEW MODULE: %s loaded %s",user->nick.c_str(), parameters[0].c_str()); user->WriteNumeric(975, "%s %s :Module successfully loaded.",user->nick.c_str(), parameters[0].c_str()); diff --git a/src/commands/cmd_who.cpp b/src/commands/cmd_who.cpp index c865cf67b..82d541a2a 100644 --- a/src/commands/cmd_who.cpp +++ b/src/commands/cmd_who.cpp @@ -256,7 +256,7 @@ CmdResult CommandWho::Handle (const std::vector<std::string>& parameters, User * std::string matchtext = ((parameters[0] == "0") ? "*" : parameters[0]); // WHO flags count as a wildcard - bool usingwildcards = ((parameters.size() > 1) || (matchtext.find_first_of("*?") != std::string::npos)); + bool usingwildcards = ((parameters.size() > 1) || (matchtext.find_first_of("*?.") != std::string::npos)); if (parameters.size() > 1) { diff --git a/src/inspircd.cpp b/src/inspircd.cpp index fe3304569..0e4a6646f 100644 --- a/src/inspircd.cpp +++ b/src/inspircd.cpp @@ -322,8 +322,6 @@ InspIRCd::InspIRCd(int argc, char** argv) : // Create base manager classes early, so nothing breaks this->Users = new UserManager; - this->Users->unregistered_count = 0; - this->Users->clientlist = new user_hash(); this->Users->uuidlist = new user_hash(); this->chanlist = new chan_hash(); @@ -449,7 +447,8 @@ InspIRCd::InspIRCd(int argc, char** argv) : std::cout << con_green << "(C) InspIRCd Development Team." << con_reset << std::endl << std::endl; std::cout << "Developers:" << std::endl; std::cout << con_green << "\tBrain, FrostyCoolSlug, w00t, Om, Special, peavey" << std::endl; - std::cout << "\taquanight, psychon, dz, danieldg, jackmcbarn" << con_reset << std::endl << std::endl; + std::cout << "\taquanight, psychon, dz, danieldg, jackmcbarn" << std::endl; + std::cout << "\tAttila" << con_reset << std::endl << std::endl; std::cout << "Others:\t\t\t" << con_green << "See /INFO Output" << con_reset << std::endl; this->Modes = new ModeParser; diff --git a/src/listensocket.cpp b/src/listensocket.cpp index f875bc646..20cbe51ac 100644 --- a/src/listensocket.cpp +++ b/src/listensocket.cpp @@ -37,6 +37,24 @@ ListenSocket::ListenSocket(ConfigTag* tag, const irc::sockets::sockaddrs& bind_t if (this->fd == -1) return; +#ifdef IPV6_V6ONLY + /* This OS supports IPv6 sockets that can also listen for IPv4 + * connections. If our address is "*" or empty, enable both v4 and v6 to + * allow for simpler configuration on dual-stack hosts. Otherwise, if it + * is "::" or an IPv6 address, disable support so that an IPv4 bind will + * work on the port (by us or another application). + */ + if (bind_to.sa.sa_family == AF_INET6) + { + std::string addr = tag->getString("address"); + /* This must be >= sizeof(DWORD) on Windows */ + const int enable = (addr.empty() || addr == "*") ? 0 : 1; + /* This must be before bind() */ + setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, reinterpret_cast<const char *>(&enable), sizeof(enable)); + // errors ignored intentionally + } +#endif + ServerInstance->SE->SetReuse(fd); int rv = ServerInstance->SE->Bind(this->fd, bind_to); if (rv >= 0) @@ -55,22 +73,6 @@ ListenSocket::ListenSocket(ConfigTag* tag, const irc::sockets::sockaddrs& bind_t #endif } -#ifdef IPV6_V6ONLY - /* This OS supports IPv6 sockets that can also listen for IPv4 - * connections. If our address is "*" or empty, enable both v4 and v6 to - * allow for simpler configuration on dual-stack hosts. Otherwise, if it - * is "::" or an IPv6 address, disable support so that an IPv4 bind will - * work on the port (by us or another application). - */ - if (bind_to.sa.sa_family == AF_INET6) - { - std::string addr = tag->getString("address"); - const char enable = (addr.empty() || addr == "*") ? 0 : 1; - setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &enable, sizeof(enable)); - // errors ignored intentionally - } -#endif - if (rv < 0) { int errstore = errno; diff --git a/src/modes/umode_o.cpp b/src/modes/umode_o.cpp index de00d7f73..45b99b1d6 100644 --- a/src/modes/umode_o.cpp +++ b/src/modes/umode_o.cpp @@ -32,7 +32,7 @@ ModeUserOperator::ModeUserOperator() : ModeHandler(NULL, "oper", 'o', PARAM_NONE ModeAction ModeUserOperator::OnModeChange(User* source, User* dest, Channel*, std::string&, bool adding) { /* Only opers can execute this class at all */ - if (!ServerInstance->ULine(source->nick.c_str()) && !ServerInstance->ULine(source->server) && !source->IsOper()) + if (!ServerInstance->ULine(source->server) && !source->IsOper()) return MODEACTION_DENY; /* Not even opers can GIVE the +o mode, only take it away */ diff --git a/src/modules/extra/m_geoip.cpp b/src/modules/extra/m_geoip.cpp index 7696146e8..ddc4e9a38 100644 --- a/src/modules/extra/m_geoip.cpp +++ b/src/modules/extra/m_geoip.cpp @@ -35,7 +35,7 @@ class ModuleGeoIP : public Module LocalStringExt ext; GeoIP* gi; - void SetExt(LocalUser* user) + std::string* SetExt(LocalUser* user) { const char* c = GeoIP_country_code_by_addr(gi, user->GetIPString().c_str()); if (!c) @@ -43,6 +43,7 @@ class ModuleGeoIP : public Module std::string* cc = new std::string(c); ext.set(user, cc); + return cc; } public: @@ -85,7 +86,7 @@ class ModuleGeoIP : public Module { std::string* cc = ext.get(user); if (!cc) - SetExt(user); + cc = SetExt(user); std::string geoip = myclass->config->getString("geoip"); if (geoip.empty()) diff --git a/src/modules/extra/m_mysql.cpp b/src/modules/extra/m_mysql.cpp index e5d8d379c..bb8f1b573 100644 --- a/src/modules/extra/m_mysql.cpp +++ b/src/modules/extra/m_mysql.cpp @@ -180,7 +180,6 @@ class MySQLresult : public SQLResult rows++; } mysql_free_result(res); - res = NULL; } } @@ -329,10 +328,15 @@ class SQLConnection : public SQLProvider if (param < p.size()) { std::string parm = p[param++]; - char buffer[MAXBUF]; - mysql_escape_string(buffer, parm.c_str(), parm.length()); + // In the worst case, each character may need to be encoded as using two bytes, + // and one byte is the terminating null + std::vector<char> buffer(parm.length() * 2 + 1); + + // The return value of mysql_escape_string() is the length of the encoded string, + // not including the terminating null + unsigned long escapedsize = mysql_escape_string(&buffer[0], parm.c_str(), parm.length()); // mysql_real_escape_string(connection, queryend, paramscopy[paramnum].c_str(), paramscopy[paramnum].length()); - res.append(buffer); + res.append(&buffer[0], escapedsize); } } } @@ -358,9 +362,10 @@ class SQLConnection : public SQLProvider if (it != p.end()) { std::string parm = it->second; - char buffer[MAXBUF]; - mysql_escape_string(buffer, parm.c_str(), parm.length()); - res.append(buffer); + // NOTE: See above + std::vector<char> buffer(parm.length() * 2 + 1); + unsigned long escapedsize = mysql_escape_string(&buffer[0], parm.c_str(), parm.length()); + res.append(&buffer[0], escapedsize); } } } @@ -431,13 +436,14 @@ void ModuleSQL::OnRehash(User* user) i->second->lock.Lock(); i->second->lock.Unlock(); // now remove all active queries to this DB - for(unsigned int j = qq.size() - 1; j >= 0; j--) + for (size_t j = qq.size(); j > 0; j--) { - if (qq[j].c == i->second) + size_t k = j - 1; + if (qq[k].c == i->second) { - qq[j].q->OnError(err); - delete qq[j].q; - qq.erase(qq.begin() + j); + qq[k].q->OnError(err); + delete qq[k].q; + qq.erase(qq.begin() + k); } } // finally, nuke the connection diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp index 3df6b91bd..61e8d5bbb 100644 --- a/src/modules/extra/m_pgsql.cpp +++ b/src/modules/extra/m_pgsql.cpp @@ -412,16 +412,16 @@ restart: if (param < p.size()) { std::string parm = p[param++]; - char buffer[MAXBUF]; + std::vector<char> buffer(parm.length() * 2 + 1); #ifdef PGSQL_HAS_ESCAPECONN int error; - PQescapeStringConn(sql, buffer, parm.c_str(), parm.length(), &error); + size_t escapedsize = PQescapeStringConn(sql, &buffer[0], parm.data(), parm.length(), &error); if (error) ServerInstance->Logs->Log("m_pgsql", LOG_DEBUG, "BUG: Apparently PQescapeStringConn() failed"); #else - PQescapeString (buffer, parm.c_str(), parm.length()); + size_t escapedsize = PQescapeString(&buffer[0], parm.data(), parm.length()); #endif - res.append(buffer); + res.append(&buffer[0], escapedsize); } } } @@ -447,16 +447,16 @@ restart: if (it != p.end()) { std::string parm = it->second; - char buffer[MAXBUF]; + std::vector<char> buffer(parm.length() * 2 + 1); #ifdef PGSQL_HAS_ESCAPECONN int error; - PQescapeStringConn(sql, buffer, parm.c_str(), parm.length(), &error); + size_t escapedsize = PQescapeStringConn(sql, &buffer[0], parm.data(), parm.length(), &error); if (error) ServerInstance->Logs->Log("m_pgsql", LOG_DEBUG, "BUG: Apparently PQescapeStringConn() failed"); #else - PQescapeString (buffer, parm.c_str(), parm.length()); + size_t escapedsize = PQescapeString(&buffer[0], parm.data(), parm.length()); #endif - res.append(buffer); + res.append(&buffer[0], escapedsize); } } } diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 0659f631c..8faee2da7 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -77,46 +77,6 @@ static int cert_callback (gnutls_session_t session, const gnutls_datum_t * req_c return 0; } -static ssize_t gnutls_pull_wrapper(gnutls_transport_ptr_t user_wrap, void* buffer, size_t size) -{ - StreamSocket* user = reinterpret_cast<StreamSocket*>(user_wrap); - if (user->GetEventMask() & FD_READ_WILL_BLOCK) - { - errno = EAGAIN; - return -1; - } - int rv = ServerInstance->SE->Recv(user, reinterpret_cast<char *>(buffer), size, 0); - if (rv < 0) - { - /* On Windows we need to set errno for gnutls */ - if (SocketEngine::IgnoreError()) - errno = EAGAIN; - } - if (rv < (int)size) - ServerInstance->SE->ChangeEventMask(user, FD_READ_WILL_BLOCK); - return rv; -} - -static ssize_t gnutls_push_wrapper(gnutls_transport_ptr_t user_wrap, const void* buffer, size_t size) -{ - StreamSocket* user = reinterpret_cast<StreamSocket*>(user_wrap); - if (user->GetEventMask() & FD_WRITE_WILL_BLOCK) - { - errno = EAGAIN; - return -1; - } - int rv = ServerInstance->SE->Send(user, reinterpret_cast<const char *>(buffer), size, 0); - if (rv < 0) - { - /* On Windows we need to set errno for gnutls */ - if (SocketEngine::IgnoreError()) - errno = EAGAIN; - } - if (rv < (int)size) - ServerInstance->SE->ChangeEventMask(user, FD_WRITE_WILL_BLOCK); - return rv; -} - class RandGen : public HandlerBase2<void, char*, size_t> { public: @@ -132,10 +92,12 @@ class RandGen : public HandlerBase2<void, char*, size_t> class issl_session { public: + StreamSocket* socket; gnutls_session_t sess; issl_status status; reference<ssl_cert> cert; - issl_session() : sess(NULL) {} + + issl_session() : socket(NULL), sess(NULL) {} }; class CommandStartTLS : public SplitCommand @@ -213,6 +175,70 @@ class ModuleSSLGnuTLS : public Module return str ? str : "UNKNOWN"; } + static ssize_t gnutls_pull_wrapper(gnutls_transport_ptr_t session_wrap, void* buffer, size_t size) + { + issl_session* session = reinterpret_cast<issl_session*>(session_wrap); + if (session->socket->GetEventMask() & FD_READ_WILL_BLOCK) + { +#ifdef _WIN32 + gnutls_transport_set_errno(session->sess, EAGAIN); +#else + errno = EAGAIN; +#endif + return -1; + } + + int rv = ServerInstance->SE->Recv(session->socket, reinterpret_cast<char *>(buffer), size, 0); + +#ifdef _WIN32 + if (rv < 0) + { + /* Windows doesn't use errno, but gnutls does, so check SocketEngine::IgnoreError() + * and then set errno appropriately. + * The gnutls library may also have a different errno variable than us, see + * gnutls_transport_set_errno(3). + */ + gnutls_transport_set_errno(session->sess, SocketEngine::IgnoreError() ? EAGAIN : errno); + } +#endif + + if (rv < (int)size) + ServerInstance->SE->ChangeEventMask(session->socket, FD_READ_WILL_BLOCK); + return rv; + } + + static ssize_t gnutls_push_wrapper(gnutls_transport_ptr_t session_wrap, const void* buffer, size_t size) + { + issl_session* session = reinterpret_cast<issl_session*>(session_wrap); + if (session->socket->GetEventMask() & FD_WRITE_WILL_BLOCK) + { +#ifdef _WIN32 + gnutls_transport_set_errno(session->sess, EAGAIN); +#else + errno = EAGAIN; +#endif + return -1; + } + + int rv = ServerInstance->SE->Send(session->socket, reinterpret_cast<const char *>(buffer), size, 0); + +#ifdef _WIN32 + if (rv < 0) + { + /* Windows doesn't use errno, but gnutls does, so check SocketEngine::IgnoreError() + * and then set errno appropriately. + * The gnutls library may also have a different errno variable than us, see + * gnutls_transport_set_errno(3). + */ + gnutls_transport_set_errno(session->sess, SocketEngine::IgnoreError() ? EAGAIN : errno); + } +#endif + + if (rv < (int)size) + ServerInstance->SE->ChangeEventMask(session->socket, FD_WRITE_WILL_BLOCK); + return rv; + } + public: ModuleSSLGnuTLS() : starttls(this), capHandler(this, "tls"), iohook(this, "ssl/gnutls", SERVICE_IOHOOK) @@ -538,13 +564,14 @@ class ModuleSSLGnuTLS : public Module issl_session* session = &sessions[user->GetFd()]; gnutls_init(&session->sess, me_server ? GNUTLS_SERVER : GNUTLS_CLIENT); + session->socket = user; #ifdef GNUTLS_NEW_PRIO_API gnutls_priority_set(session->sess, priority); #endif gnutls_credentials_set(session->sess, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_dh_set_prime_bits(session->sess, dh_bits); - gnutls_transport_set_ptr(session->sess, reinterpret_cast<gnutls_transport_ptr_t>(user)); + gnutls_transport_set_ptr(session->sess, reinterpret_cast<gnutls_transport_ptr_t>(session)); gnutls_transport_set_push_function(session->sess, gnutls_push_wrapper); gnutls_transport_set_pull_function(session->sess, gnutls_pull_wrapper); @@ -760,6 +787,7 @@ class ModuleSSLGnuTLS : public Module gnutls_bye(session->sess, GNUTLS_SHUT_WR); gnutls_deinit(session->sess); } + session->socket = NULL; session->sess = NULL; session->cert = NULL; session->status = ISSL_NONE; diff --git a/src/modules/m_alias.cpp b/src/modules/m_alias.cpp index 34f4c4f64..118cedeea 100644 --- a/src/modules/m_alias.cpp +++ b/src/modules/m_alias.cpp @@ -244,7 +244,7 @@ class ModuleAlias : public Module } - int DoAlias(User *user, Channel *c, Alias *a, const std::string compare, const std::string safe) + int DoAlias(User *user, Channel *c, Alias *a, const std::string& compare, const std::string& safe) { User *u = NULL; diff --git a/src/modules/m_cban.cpp b/src/modules/m_cban.cpp index 5e629ed42..7dedb7441 100644 --- a/src/modules/m_cban.cpp +++ b/src/modules/m_cban.cpp @@ -34,7 +34,7 @@ private: irc::string matchtext; public: - CBan(time_t s_time, long d, std::string src, std::string re, std::string ch) + CBan(time_t s_time, long d, const std::string& src, const std::string& re, const std::string& ch) : XLine(s_time, d, src, re, "CBAN") { this->displaytext = ch; diff --git a/src/modules/m_channames.cpp b/src/modules/m_channames.cpp index 9b43649a8..52f781ae1 100644 --- a/src/modules/m_channames.cpp +++ b/src/modules/m_channames.cpp @@ -87,9 +87,17 @@ class ModuleChannelNames : public Module ServerInstance->SendGlobalMode(modes, ServerInstance->FakeClient); } const UserMembList* users = c->GetUsers(); - for(UserMembCIter j = users->begin(); j != users->end(); ++j) + for(UserMembCIter j = users->begin(); j != users->end(); ) + { if (IS_LOCAL(j->first)) - c->KickUser(ServerInstance->FakeClient, j->first, "Channel name no longer valid"); + { + // KickUser invalidates the iterator + UserMembCIter it = j++; + c->KickUser(ServerInstance->FakeClient, it->first, "Channel name no longer valid"); + } + else + ++j; + } } badchan = false; } diff --git a/src/modules/m_connectban.cpp b/src/modules/m_connectban.cpp index d741dfb36..eca9352e8 100644 --- a/src/modules/m_connectban.cpp +++ b/src/modules/m_connectban.cpp @@ -93,11 +93,12 @@ class ModuleConnectBan : public Module { // Create zline for set duration. ZLine* zl = new ZLine(ServerInstance->Time(), banduration, ServerInstance->Config->ServerName, "Your IP range has been attempting to connect too many times in too short a duration. Wait a while, and you will be able to connect.", mask.str()); - if (ServerInstance->XLines->AddLine(zl,NULL)) - ServerInstance->XLines->ApplyLines(); - else + if (!ServerInstance->XLines->AddLine(zl, NULL)) + { delete zl; - + return; + } + ServerInstance->XLines->ApplyLines(); std::string maskstr = mask.str(); std::string timestr = ServerInstance->TimeString(zl->expiry); ServerInstance->SNO->WriteGlobalSno('x',"Module m_connectban added Z:line on *@%s to expire on %s: Connect flooding", diff --git a/src/modules/m_dccallow.cpp b/src/modules/m_dccallow.cpp index 5061cf250..1024c4ab2 100644 --- a/src/modules/m_dccallow.cpp +++ b/src/modules/m_dccallow.cpp @@ -166,7 +166,7 @@ class CommandDccallow : public Command length = InspIRCd::Duration(parameters[1]); } - if (!ServerInstance->IsValidMask(mask.c_str())) + if (!ServerInstance->IsValidMask(mask)) { return CMD_FAILURE; } diff --git a/src/modules/m_filter.cpp b/src/modules/m_filter.cpp index d138c44cd..bdf849f32 100644 --- a/src/modules/m_filter.cpp +++ b/src/modules/m_filter.cpp @@ -60,7 +60,7 @@ class FilterResult bool flag_notice; bool flag_strip_color; - FilterResult(const std::string free, const std::string &rea, FilterAction act, long gt, const std::string &fla) : + FilterResult(const std::string& free, const std::string& rea, FilterAction act, long gt, const std::string& fla) : freeform(free), reason(rea), action(act), gline_time(gt) { this->FillFlags(fla); diff --git a/src/modules/m_httpd_acl.cpp b/src/modules/m_httpd_acl.cpp index 982e514ad..061d56f25 100644 --- a/src/modules/m_httpd_acl.cpp +++ b/src/modules/m_httpd_acl.cpp @@ -45,7 +45,7 @@ class ModuleHTTPAccessList : public Module std::vector<HTTPACL> acl_list; public: - void ReadConfig() + void OnRehash(User* user) { acl_list.clear(); ConfigTagList acls = ServerInstance->Config->ConfTags("httpdacl"); @@ -91,8 +91,8 @@ class ModuleHTTPAccessList : public Module void init() CXX11_OVERRIDE { - ReadConfig(); - Implementation eventlist[] = { I_OnEvent }; + OnRehash(NULL); + Implementation eventlist[] = { I_OnEvent, I_OnRehash }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); } diff --git a/src/modules/m_kicknorejoin.cpp b/src/modules/m_kicknorejoin.cpp index 8d2d88e99..3406f4f99 100644 --- a/src/modules/m_kicknorejoin.cpp +++ b/src/modules/m_kicknorejoin.cpp @@ -115,7 +115,7 @@ public: } } - if (!dl->size()) + if (dl->empty()) kr.ext.unset(chan); } } diff --git a/src/modules/m_nicklock.cpp b/src/modules/m_nicklock.cpp index 9da40ce78..7bd2c43b2 100644 --- a/src/modules/m_nicklock.cpp +++ b/src/modules/m_nicklock.cpp @@ -179,7 +179,7 @@ class ModuleNickLock : public Module void Prioritize() { Module *nflood = ServerInstance->Modules->Find("m_nickflood.so"); - ServerInstance->Modules->SetPriority(this, I_OnUserPreJoin, PRIORITY_BEFORE, &nflood); + ServerInstance->Modules->SetPriority(this, I_OnUserPreNick, PRIORITY_BEFORE, &nflood); } }; diff --git a/src/modules/m_operprefix.cpp b/src/modules/m_operprefix.cpp index fbb7e8b50..d061a5eab 100644 --- a/src/modules/m_operprefix.cpp +++ b/src/modules/m_operprefix.cpp @@ -51,7 +51,7 @@ class OperPrefixMode : public ModeHandler return MODEACTION_ALLOW; else { - if (source && channel) + if (channel) source->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :Only servers are permitted to change channel mode '%c'", source->nick.c_str(), channel->name.c_str(), 'y'); return MODEACTION_DENY; } diff --git a/src/modules/m_passforward.cpp b/src/modules/m_passforward.cpp index 6e29f272b..64c7df519 100644 --- a/src/modules/m_passforward.cpp +++ b/src/modules/m_passforward.cpp @@ -90,7 +90,7 @@ class ModulePassForward : public Module if (!nickrequired.empty()) { /* Check if nick exists and its server is ulined */ - User* u = ServerInstance->FindNick(nickrequired.c_str()); + User* u = ServerInstance->FindNick(nickrequired); if (!u || !ServerInstance->ULine(u->server)) return; } diff --git a/src/modules/m_rline.cpp b/src/modules/m_rline.cpp index aa96d4951..ca123cc11 100644 --- a/src/modules/m_rline.cpp +++ b/src/modules/m_rline.cpp @@ -41,11 +41,10 @@ class RLine : public XLine * @param regex Pattern to match with * @ */ - RLine(time_t s_time, long d, std::string src, std::string re, std::string regexs, dynamic_reference<RegexFactory>& rxfactory) + RLine(time_t s_time, long d, const std::string& src, const std::string& re, const std::string& regexs, dynamic_reference<RegexFactory>& rxfactory) : XLine(s_time, d, src, re, "R") + , matchtext(regexs) { - matchtext = regexs; - /* This can throw on failure, but if it does we DONT catch it here, we catch it and display it * where the object is created, we might not ALWAYS want it to output stuff to snomask x all the time */ diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp index 8cae025e2..322a726ce 100644 --- a/src/modules/m_sasl.cpp +++ b/src/modules/m_sasl.cpp @@ -52,7 +52,7 @@ class SaslAuthenticator bool state_announced; public: - SaslAuthenticator(User *user_, std::string method, Module *ctor) + SaslAuthenticator(User* user_, const std::string& method) : user(user_), state(SASL_INIT), state_announced(false) { parameterlist params; @@ -195,7 +195,7 @@ class CommandAuthenticate : public Command SaslAuthenticator *sasl = authExt.get(user); if (!sasl) - authExt.set(user, new SaslAuthenticator(user, parameters[0], creator)); + authExt.set(user, new SaslAuthenticator(user, parameters[0])); else if (sasl->SendClientMessage(parameters) == false) // IAL abort extension --nenolod { sasl->AnnounceState(); diff --git a/src/modules/m_shun.cpp b/src/modules/m_shun.cpp index 6da24208a..a06149b62 100644 --- a/src/modules/m_shun.cpp +++ b/src/modules/m_shun.cpp @@ -30,10 +30,10 @@ class Shun : public XLine public: std::string matchtext; - Shun(time_t s_time, long d, std::string src, std::string re, std::string shunmask) + Shun(time_t s_time, long d, const std::string& src, const std::string& re, const std::string& shunmask) : XLine(s_time, d, src, re, "SHUN") + , matchtext(shunmask) { - this->matchtext = shunmask; } bool Matches(User *u) diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index 764c8b8ec..aafda7eea 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -582,8 +582,7 @@ void ModuleSpanningTree::OnChangeName(User* user, const std::string &gecos) void ModuleSpanningTree::OnChangeIdent(User* user, const std::string &ident) { - // only occurs for local clients - if (user->registered != REG_ALL) + if ((user->registered != REG_ALL) || (!IS_LOCAL(user))) return; parameterlist params; diff --git a/src/modules/m_spanningtree/netburst.cpp b/src/modules/m_spanningtree/netburst.cpp index 639a397c6..8daaefd8a 100644 --- a/src/modules/m_spanningtree/netburst.cpp +++ b/src/modules/m_spanningtree/netburst.cpp @@ -183,7 +183,6 @@ void TreeSocket::SyncChannel(Channel* chan) void TreeSocket::SendUsers() { char data[MAXBUF]; - std::string dataline; for (user_hash::iterator u = ServerInstance->Users->clientlist->begin(); u != ServerInstance->Users->clientlist->end(); u++) { if (u->second->registered == REG_ALL) diff --git a/src/modules/m_spanningtree/utils.h b/src/modules/m_spanningtree/utils.h index a2566c0c8..e97df3839 100644 --- a/src/modules/m_spanningtree/utils.h +++ b/src/modules/m_spanningtree/utils.h @@ -90,9 +90,6 @@ class SpanningTreeUtilities : public classbase /** Hash of currently known server ids */ server_hash sidlist; - /** Hash of servers currently bursting but not initialized as connected - */ - std::map<irc::string,TreeSocket*> burstingserverlist; /** List of all outgoing sockets and their timeouts */ std::map<TreeSocket*, std::pair<std::string, int> > timeoutlist; diff --git a/src/modules/m_svshold.cpp b/src/modules/m_svshold.cpp index d35d5f3ba..a53298126 100644 --- a/src/modules/m_svshold.cpp +++ b/src/modules/m_svshold.cpp @@ -32,7 +32,7 @@ class SVSHold : public XLine public: std::string nickname; - SVSHold(time_t s_time, long d, std::string src, std::string re, std::string nick) + SVSHold(time_t s_time, long d, const std::string& src, const std::string& re, const std::string& nick) : XLine(s_time, d, src, re, "SVSHOLD") { this->nickname = nick; diff --git a/src/modules/m_userip.cpp b/src/modules/m_userip.cpp index 7cc2fa04d..670e9a9d7 100644 --- a/src/modules/m_userip.cpp +++ b/src/modules/m_userip.cpp @@ -30,19 +30,37 @@ class CommandUserip : public Command public: CommandUserip(Module* Creator) : Command(Creator,"USERIP", 1) { - flags_needed = 'o'; syntax = "<nick>{,<nick>}"; + syntax = "<nick>{,<nick>}"; } CmdResult Handle (const std::vector<std::string> ¶meters, User *user) { std::string retbuf = "340 " + user->nick + " :"; int nicks = 0; + bool checked_privs = false; + bool has_privs; for (int i = 0; i < (int)parameters.size(); i++) { User *u = ServerInstance->FindNick(parameters[i]); if ((u) && (u->registered == REG_ALL)) { + // Anyone may query their own IP + if (u != user) + { + if (!checked_privs) + { + // Do not trigger the insufficient priviliges message more than once + checked_privs = true; + has_privs = user->HasPrivPermission("users/auspex"); + if (!has_privs) + user->WriteNumeric(ERR_NOPRIVILEGES, "%s :Permission Denied - You do not have the required operator privileges",user->nick.c_str()); + } + + if (!has_privs) + continue; + } + retbuf = retbuf + u->nick + (u->IsOper() ? "*" : "") + "="; if (u->IsAway()) retbuf += "-"; @@ -56,7 +74,6 @@ class CommandUserip : public Command if (nicks != 0) user->WriteServ(retbuf); - /* Dont send to the network */ return CMD_SUCCESS; } }; diff --git a/src/threadengines/threadengine_win32.cpp b/src/threadengines/threadengine_win32.cpp index 637a3e010..529e24a29 100644 --- a/src/threadengines/threadengine_win32.cpp +++ b/src/threadengines/threadengine_win32.cpp @@ -65,6 +65,7 @@ void ThreadData::FreeThread(Thread* thread) { thread->SetExitFlag(); WaitForSingleObject(handle,INFINITE); + CloseHandle(handle); } class ThreadSignalSocket : public BufferedSocket diff --git a/src/usermanager.cpp b/src/usermanager.cpp index cdc594387..d6c61d2e3 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -24,6 +24,11 @@ #include "xline.h" #include "bancache.h" +UserManager::UserManager() + : unregistered_count(0), local_count(0) +{ +} + /* add a client connection to the sockets list */ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) { @@ -74,6 +79,7 @@ void UserManager::AddUser(int socket, ListenSocket* via, irc::sockets::sockaddrs ServerInstance->Users->AddGlobalClone(New); New->localuseriter = this->local_users.insert(local_users.end(), New); + local_count++; if ((this->local_users.size() > ServerInstance->Config->SoftLimit) || (this->local_users.size() >= (unsigned int)ServerInstance->SE->GetMaxFds())) { @@ -317,7 +323,7 @@ unsigned int UserManager::UnregisteredUserCount() unsigned int UserManager::LocalUserCount() { /* Doesnt count unregistered clients */ - return (this->local_users.size() - this->UnregisteredUserCount()); + return (this->local_count - this->UnregisteredUserCount()); } void UserManager::ServerNoticeAll(const char* text, ...) diff --git a/src/users.cpp b/src/users.cpp index 49c5c5e42..44834330b 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -506,7 +506,10 @@ CullResult LocalUser::cull() // overwritten in UserManager::AddUser() with the real iterator so this check // is only a precaution currently. if (localuseriter != ServerInstance->Users->local_users.end()) + { + ServerInstance->Users->local_count--; ServerInstance->Users->local_users.erase(localuseriter); + } else ServerInstance->Logs->Log("USERS", LOG_DEFAULT, "ERROR: LocalUserIter does not point to a valid entry for " + this->nick); diff --git a/win/CMakeLists.txt b/win/CMakeLists.txt index 827ef1c90..ca7e9eb18 100644 --- a/win/CMakeLists.txt +++ b/win/CMakeLists.txt @@ -5,7 +5,7 @@ project(InspIRCd CXX) set(CONF_PATH "conf" CACHE PATH "Configuration file path") set(MODULE_PATH "modules" CACHE PATH "Module path") set(DATA_PATH "data" CACHE PATH "Data path") -set(LOG_PATH "log" CACHE PATH "Log file path") +set(LOG_PATH "logs" CACHE PATH "Log file path") set(EXTRA_INCLUDES "" CACHE PATH "Extra include paths") set(EXTRA_LIBS "" CACHE PATH "Extra library paths") @@ -74,10 +74,10 @@ file(GLOB_RECURSE EXAMPLE_CONFIGS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "${INSPIR install(FILES ${EXAMPLE_CONFIGS} DESTINATION conf) # Create an empty data and logs directory and install them -file(MAKE_DIRECTORY data) -install(DIRECTORY "data" DESTINATION .) -file(MAKE_DIRECTORY logs) -install(DIRECTORY "logs" DESTINATION .) +file(MAKE_DIRECTORY ${DATA_PATH}) +install(DIRECTORY ${DATA_PATH} DESTINATION .) +file(MAKE_DIRECTORY ${LOG_PATH}) +install(DIRECTORY ${LOG_PATH} DESTINATION .) if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") include(InstallRequiredSystemLibraries) diff --git a/win/inspircd_win32wrapper.cpp b/win/inspircd_win32wrapper.cpp index 7a07868f9..2836674bb 100644 --- a/win/inspircd_win32wrapper.cpp +++ b/win/inspircd_win32wrapper.cpp @@ -56,18 +56,38 @@ CoreExport const char *insp_inet_ntop(int af, const void *src, char *dst, sockle CoreExport int insp_inet_pton(int af, const char *src, void *dst) { - sockaddr_in sa; - int len = sizeof(SOCKADDR); - int rv = WSAStringToAddressA((LPSTR)src, af, NULL, (LPSOCKADDR)&sa, &len); - if(rv >= 0) + int address_length; + sockaddr_storage sa; + sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(&sa); + sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(&sa); + + switch (af) { - if(WSAGetLastError() == WSAEINVAL) - rv = 0; - else - rv = 1; + case AF_INET: + address_length = sizeof(sockaddr_in); + break; + case AF_INET6: + address_length = sizeof(sockaddr_in6); + break; + default: + return -1; } - memcpy(dst, &sa.sin_addr, sizeof(struct in_addr)); - return rv; + + if (!WSAStringToAddress(static_cast<LPSTR>(const_cast<char *>(src)), af, NULL, reinterpret_cast<LPSOCKADDR>(&sa), &address_length)) + { + switch (af) + { + case AF_INET: + memcpy(dst, &sin->sin_addr, sizeof(in_addr)); + break; + case AF_INET6: + memcpy(dst, &sin6->sin6_addr, sizeof(in6_addr)); + break; + } + return 1; + } + + return 0; } CoreExport DIR * opendir(const char * path) @@ -144,7 +164,7 @@ int getopt_long(int ___argc, char *const *___argv, const char *__shortopts, cons // optind++; // Trash this next argument, we won't be needing it. par = ___argv[optind-1]; } - } + } // increment the argument for next time // optind++; @@ -170,9 +190,9 @@ int getopt_long(int ___argc, char *const *___argv, const char *__shortopts, cons { if (__longopts[i].val == -1 || par == 0) return 1; - + return __longopts[i].val; - } + } break; } } |