From 234be2f3cb00735ec07c9df749a0d53effce5f65 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Sun, 3 Aug 2014 10:35:31 +0100 Subject: Fix listmodes when the config does not specify a wildcard size entry. --- src/modules/u_listmode.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/modules') diff --git a/src/modules/u_listmode.h b/src/modules/u_listmode.h index 0f5903e53..30bf6a48f 100644 --- a/src/modules/u_listmode.h +++ b/src/modules/u_listmode.h @@ -201,13 +201,13 @@ class ListModeBase : public ModeHandler if (limit.mask.size() && limit.limit > 0) chanlimits.push_back(limit); } - if (chanlimits.empty()) - { - ListLimit limit; - limit.mask = "*"; - limit.limit = 64; - chanlimits.push_back(limit); - } + + // Add the default entry. This is inserted last so if the user specifies a + // wildcard record in the config it will take precedence over this entry. + ListLimit limit; + limit.mask = "*"; + limit.limit = 64; + chanlimits.push_back(limit); } /** Populate the Implements list with the correct events for a List Mode -- cgit v1.2.3 From 8125a187b17f41a199cc4ebaa99f4d616e930049 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Tue, 2 Sep 2014 00:15:59 +0200 Subject: m_sqlite3 Fix cleanup of unsuccessful database connections --- src/modules/extra/m_sqlite3.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_sqlite3.cpp b/src/modules/extra/m_sqlite3.cpp index 7f6a53359..1e3a65a18 100644 --- a/src/modules/extra/m_sqlite3.cpp +++ b/src/modules/extra/m_sqlite3.cpp @@ -97,8 +97,11 @@ class SQLConn : public SQLProvider ~SQLConn() { - sqlite3_interrupt(conn); - sqlite3_close(conn); + if (conn) + { + sqlite3_interrupt(conn); + sqlite3_close(conn); + } } void Query(SQLQuery* query, const std::string& q) -- cgit v1.2.3 From af5e651cc73d0a0d599c03bc95955f8f9c314680 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Fri, 3 Oct 2014 23:50:54 +0200 Subject: m_ssl_gnutls Re-set DH params when the gnutls_certificate_credentials_t struct is reallocated --- src/modules/extra/m_ssl_gnutls.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 6a6a7923a..7934c23ab 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -281,8 +281,6 @@ class ModuleSSLGnuTLS : public Module ServerInstance->GenRandom = &randhandler; - // Void return, guess we assume success - gnutls_certificate_set_dh_params(x509_cred, dh_params); Implementation eventlist[] = { I_On005Numeric, I_OnRehash, I_OnModuleRehash, I_OnUserConnect, I_OnEvent, I_OnHookIO }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); @@ -487,6 +485,8 @@ class ModuleSSLGnuTLS : public Module { GenerateDHParams(); } + + gnutls_certificate_set_dh_params(x509_cred, dh_params); } void GenerateDHParams() -- cgit v1.2.3 From 21f99f133e635d19b3a719467bd700a494111cc4 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 8 Oct 2014 02:36:00 +0200 Subject: m_ssl_openssl Clear the error queue before every SSL_* call --- src/modules/extra/m_ssl_openssl.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 33f848798..0398a33c7 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -215,6 +215,7 @@ class ModuleSSLOpenSSL : public Module if (!ciphers.empty()) { + ERR_clear_error(); if ((!SSL_CTX_set_cipher_list(ctx, ciphers.c_str())) || (!SSL_CTX_set_cipher_list(clictx, ciphers.c_str()))) { ServerInstance->Logs->Log("m_ssl_openssl",DEFAULT, "m_ssl_openssl.so: Can't set cipher list to %s.", ciphers.c_str()); @@ -225,12 +226,14 @@ class ModuleSSLOpenSSL : public Module /* Load our keys and certificates * NOTE: OpenSSL's error logging API sucks, don't blame us for this clusterfuck. */ + ERR_clear_error(); if ((!SSL_CTX_use_certificate_chain_file(ctx, certfile.c_str())) || (!SSL_CTX_use_certificate_chain_file(clictx, certfile.c_str()))) { ServerInstance->Logs->Log("m_ssl_openssl",DEFAULT, "m_ssl_openssl.so: Can't read certificate file %s. %s", certfile.c_str(), strerror(errno)); ERR_print_errors_cb(error_callback, this); } + ERR_clear_error(); if (((!SSL_CTX_use_PrivateKey_file(ctx, keyfile.c_str(), SSL_FILETYPE_PEM))) || (!SSL_CTX_use_PrivateKey_file(clictx, keyfile.c_str(), SSL_FILETYPE_PEM))) { ServerInstance->Logs->Log("m_ssl_openssl",DEFAULT, "m_ssl_openssl.so: Can't read key file %s. %s", keyfile.c_str(), strerror(errno)); @@ -238,6 +241,7 @@ class ModuleSSLOpenSSL : public Module } /* Load the CAs we trust*/ + ERR_clear_error(); if (((!SSL_CTX_load_verify_locations(ctx, cafile.c_str(), 0))) || (!SSL_CTX_load_verify_locations(clictx, cafile.c_str(), 0))) { ServerInstance->Logs->Log("m_ssl_openssl",DEFAULT, "m_ssl_openssl.so: Can't read CA list from %s. This is only a problem if you want to verify client certificates, otherwise it's safe to ignore this message. Error: %s", cafile.c_str(), strerror(errno)); @@ -264,6 +268,8 @@ class ModuleSSLOpenSSL : public Module #else ret = PEM_read_DHparams(dhpfile, NULL, NULL, NULL); #endif + + ERR_clear_error(); if ((SSL_CTX_set_tmp_dh(ctx, ret) < 0) || (SSL_CTX_set_tmp_dh(clictx, ret) < 0)) { ServerInstance->Logs->Log("m_ssl_openssl",DEFAULT, "m_ssl_openssl.so: Couldn't set DH parameters %s. SSL errors follow:", dhfile.c_str()); @@ -426,6 +432,7 @@ class ModuleSSLOpenSSL : public Module if (session->status == ISSL_OPEN) { + ERR_clear_error(); char* buffer = ServerInstance->GetReadBuffer(); size_t bufsiz = ServerInstance->Config->NetBufferSize; int ret = SSL_read(session->sess, buffer, bufsiz); @@ -496,6 +503,7 @@ class ModuleSSLOpenSSL : public Module if (session->status == ISSL_OPEN) { + ERR_clear_error(); int ret = SSL_write(session->sess, buffer.data(), buffer.size()); if (ret == (int)buffer.length()) { @@ -542,6 +550,7 @@ class ModuleSSLOpenSSL : public Module { int ret; + ERR_clear_error(); if (session->outbound) ret = SSL_connect(session->sess); else -- cgit v1.2.3 From 9179e51e513587cddd4c4171f0ad74c8f5bf052e Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Fri, 10 Oct 2014 14:10:24 +0200 Subject: m_ssl_openssl Enable single (EC)DH use and disable SSL v2 Options enabled: - SSL_OP_NO_SSLv2 - SSL_OP_SINGLE_DH_USE - SSL_OP_SINGLE_ECDH_USE (if it exists) Partial backport of #856 by @jvehent --- src/modules/extra/m_ssl_openssl.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 0398a33c7..081b0153e 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -130,6 +130,15 @@ class ModuleSSLOpenSSL : public Module const unsigned char session_id[] = "inspircd"; SSL_CTX_set_session_id_context(ctx, session_id, sizeof(session_id) - 1); + + long opts = SSL_OP_NO_SSLv2 | SSL_OP_SINGLE_DH_USE; + // Only turn options on if they exist +#ifdef SSL_OP_SINGLE_ECDH_USE + opts |= SSL_OP_SINGLE_ECDH_USE; +#endif + + SSL_CTX_set_options(ctx, opts); + SSL_CTX_set_options(clictx, opts); } void init() -- cgit v1.2.3 From b4dc9d871cd8c7817c6dff17c76b66e989712ffc Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Fri, 10 Oct 2014 14:15:37 +0200 Subject: m_ssl_openssl Disable session caching and session tickets --- src/modules/extra/m_ssl_openssl.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 081b0153e..37d2a9cdf 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -128,14 +128,17 @@ class ModuleSSLOpenSSL : public Module SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, OnVerify); SSL_CTX_set_verify(clictx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, OnVerify); - const unsigned char session_id[] = "inspircd"; - SSL_CTX_set_session_id_context(ctx, session_id, sizeof(session_id) - 1); + SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); + SSL_CTX_set_session_cache_mode(clictx, SSL_SESS_CACHE_OFF); long opts = SSL_OP_NO_SSLv2 | SSL_OP_SINGLE_DH_USE; // Only turn options on if they exist #ifdef SSL_OP_SINGLE_ECDH_USE opts |= SSL_OP_SINGLE_ECDH_USE; #endif +#ifdef SSL_OP_NO_TICKET + opts |= SSL_OP_NO_TICKET; +#endif SSL_CTX_set_options(ctx, opts); SSL_CTX_set_options(clictx, opts); -- cgit v1.2.3 From 44542c1f1acabbf00f8f468f3bb837c5a8b2736e Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Fri, 10 Oct 2014 14:26:09 +0200 Subject: m_ssl_openssl Allow configuring raw OpenSSL context options --- src/modules/extra/m_ssl_openssl.cpp | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 37d2a9cdf..518712c00 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -102,10 +102,29 @@ class ModuleSSLOpenSSL : public Module SSL_CTX* ctx; SSL_CTX* clictx; + long ctx_options; + long clictx_options; + std::string sslports; bool use_sha; ServiceProvider iohook; + + static void SetContextOptions(SSL_CTX* ctx, long defoptions, const std::string& ctxname, ConfigTag* tag) + { + long setoptions = tag->getInt(ctxname + "setoptions"); + long clearoptions = tag->getInt(ctxname + "clearoptions"); + ServerInstance->Logs->Log("m_ssl_openssl", DEBUG, "Setting OpenSSL %s context options, default: %ld set: %ld clear: %ld", ctxname.c_str(), defoptions, clearoptions, setoptions); + + // Clear everything + SSL_CTX_clear_options(ctx, SSL_CTX_get_options(ctx)); + + // Set the default options and what is in the conf + SSL_CTX_set_options(ctx, defoptions | setoptions); + long final = SSL_CTX_clear_options(ctx, clearoptions); + ServerInstance->Logs->Log("m_ssl_openssl", DEFAULT, "OpenSSL %s context options: %ld", ctxname.c_str(), final); + } + public: ModuleSSLOpenSSL() : iohook(this, "ssl/openssl", SERVICE_IOHOOK) @@ -140,8 +159,8 @@ class ModuleSSLOpenSSL : public Module opts |= SSL_OP_NO_TICKET; #endif - SSL_CTX_set_options(ctx, opts); - SSL_CTX_set_options(clictx, opts); + ctx_options = SSL_CTX_set_options(ctx, opts); + clictx_options = SSL_CTX_set_options(clictx, opts); } void init() @@ -223,6 +242,12 @@ class ModuleSSLOpenSSL : public Module throw ModuleException("Unknown hash type " + hash); use_sha = (hash == "sha1"); + if (conf->getBool("customcontextoptions")) + { + SetContextOptions(ctx, ctx_options, "server", conf); + SetContextOptions(clictx, clictx_options, "client", conf); + } + std::string ciphers = conf->getString("ciphers", ""); if (!ciphers.empty()) -- cgit v1.2.3 From 402a1bb010522a35600325c1a3084e092b40ca22 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Mon, 6 Oct 2014 13:30:31 +0100 Subject: Fix various warnings when building with LLVM 3.5. - warning: absolute value function 'abs' given an argument of type 'long' but has parameter of type 'int' which may cause truncation of value [-Wabsolute-value] - warning: 'this' pointer cannot be null in well-defined C++ code; pointer may be assumed to always convert to true [-Wundefined-bool-conversion] --- src/commands/cmd_whois.cpp | 2 +- src/configparser.cpp | 9 +++++++++ src/modules/m_spanningtree/idle.cpp | 2 +- src/modules/m_spanningtree/treesocket2.cpp | 6 +++--- src/server.cpp | 11 ++++------- 5 files changed, 18 insertions(+), 12 deletions(-) (limited to 'src/modules') diff --git a/src/commands/cmd_whois.cpp b/src/commands/cmd_whois.cpp index ba2ad9c15..ab0b82fff 100644 --- a/src/commands/cmd_whois.cpp +++ b/src/commands/cmd_whois.cpp @@ -76,7 +76,7 @@ CmdResult CommandWhois::Handle (const std::vector& parameters, User */ if (IS_LOCAL(dest) && (ServerInstance->Config->HideWhoisServer.empty() || parameters.size() > 1)) { - idle = abs((long)((dest->idle_lastmsg)-ServerInstance->Time())); + idle = labs((long)((dest->idle_lastmsg)-ServerInstance->Time())); signon = dest->signon; } diff --git a/src/configparser.cpp b/src/configparser.cpp index 825dfc966..94192a71b 100644 --- a/src/configparser.cpp +++ b/src/configparser.cpp @@ -390,8 +390,17 @@ bool ParseStack::ParseExec(const std::string& name, int flags, const std::string bool ConfigTag::readString(const std::string& key, std::string& value, bool allow_lf) { +#ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wunknown-pragmas" +# pragma clang diagnostic ignored "-Wundefined-bool-conversion" +#endif + // TODO: this is undefined behaviour but changing the API is too risky for 2.0. if (!this) return false; +#ifdef __clang__ +# pragma clang diagnostic pop +#endif for(std::vector::iterator j = items.begin(); j != items.end(); ++j) { if(j->first != key) diff --git a/src/modules/m_spanningtree/idle.cpp b/src/modules/m_spanningtree/idle.cpp index 0ea06a3cc..18aeb0ad5 100644 --- a/src/modules/m_spanningtree/idle.cpp +++ b/src/modules/m_spanningtree/idle.cpp @@ -40,7 +40,7 @@ bool TreeSocket::Whois(const std::string &prefix, parameterlist ¶ms) User* x = ServerInstance->FindNick(params[0]); if ((x) && (IS_LOCAL(x))) { - long idle = abs((long)((x->idle_lastmsg) - ServerInstance->Time())); + long idle = labs((long)((x->idle_lastmsg) - ServerInstance->Time())); parameterlist par; par.push_back(prefix); par.push_back(ConvToStr(x->signon)); diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp index fb658c9c7..acb822fbf 100644 --- a/src/modules/m_spanningtree/treesocket2.cpp +++ b/src/modules/m_spanningtree/treesocket2.cpp @@ -155,13 +155,13 @@ void TreeSocket::ProcessLine(std::string &line) time_t delta = them - ServerInstance->Time(); if ((delta < -600) || (delta > 600)) { - ServerInstance->SNO->WriteGlobalSno('l',"\2ERROR\2: Your clocks are out by %d seconds (this is more than five minutes). Link aborted, \2PLEASE SYNC YOUR CLOCKS!\2",abs((long)delta)); - SendError("Your clocks are out by "+ConvToStr(abs((long)delta))+" seconds (this is more than five minutes). Link aborted, PLEASE SYNC YOUR CLOCKS!"); + ServerInstance->SNO->WriteGlobalSno('l',"\2ERROR\2: Your clocks are out by %ld seconds (this is more than five minutes). Link aborted, \2PLEASE SYNC YOUR CLOCKS!\2",labs((long)delta)); + SendError("Your clocks are out by "+ConvToStr(labs((long)delta))+" seconds (this is more than five minutes). Link aborted, PLEASE SYNC YOUR CLOCKS!"); return; } else if ((delta < -30) || (delta > 30)) { - ServerInstance->SNO->WriteGlobalSno('l',"\2WARNING\2: Your clocks are out by %d seconds. Please consider synching your clocks.", abs((long)delta)); + ServerInstance->SNO->WriteGlobalSno('l',"\2WARNING\2: Your clocks are out by %ld seconds. Please consider synching your clocks.", labs((long)delta)); } } diff --git a/src/server.cpp b/src/server.cpp index 4741f942d..d05ece8a4 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -46,13 +46,10 @@ void InspIRCd::Exit(int status) #ifdef _WIN32 SetServiceStopped(status); #endif - if (this) - { - this->SendError("Exiting with status " + ConvToStr(status) + " (" + std::string(ExitCodes[status]) + ")"); - this->Cleanup(); - delete this; - ServerInstance = NULL; - } + this->SendError("Exiting with status " + ConvToStr(status) + " (" + std::string(ExitCodes[status]) + ")"); + this->Cleanup(); + delete this; + ServerInstance = NULL; exit (status); } -- cgit v1.2.3 From d8fe6df7a7bc385a80ae3fde0e9e4a2ac12d4af3 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Sun, 12 Oct 2014 18:38:23 +0100 Subject: Kill some logically dead code detected by Coverity. - m_watch: wl has already been confirmed to not be NULL on L161. --- src/modules/m_watch.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/modules') diff --git a/src/modules/m_watch.cpp b/src/modules/m_watch.cpp index be05d7d2d..074ce37ad 100644 --- a/src/modules/m_watch.cpp +++ b/src/modules/m_watch.cpp @@ -163,9 +163,6 @@ class CommandWatch : public Command /* Yup, is on my list */ watchlist::iterator n = wl->find(nick); - if (!wl) - return CMD_FAILURE; - if (n != wl->end()) { if (!n->second.empty()) -- cgit v1.2.3 From 1377fabfee72994531df274248ed0ce6de483dd2 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Mon, 13 Oct 2014 21:11:14 +0200 Subject: m_nationalchars Rebuild core hashmaps when the national_case_insensitive_map changes Issue #923 --- src/modules/m_nationalchars.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/modules') diff --git a/src/modules/m_nationalchars.cpp b/src/modules/m_nationalchars.cpp index b43b6e2b6..20e4eaa9e 100644 --- a/src/modules/m_nationalchars.cpp +++ b/src/modules/m_nationalchars.cpp @@ -228,11 +228,24 @@ class ModuleNationalChars : public Module caller2 rememberer; bool forcequit; const unsigned char * lowermap_rememberer; + unsigned char prev_map[256]; + + void CheckRehash() + { + // See if anything changed + if (!memcmp(prev_map, national_case_insensitive_map, sizeof(prev_map))) + return; + + memcpy(prev_map, national_case_insensitive_map, sizeof(prev_map)); + + ServerInstance->RehashUsersAndChans(); + } public: ModuleNationalChars() : rememberer(ServerInstance->IsNick), lowermap_rememberer(national_case_insensitive_map) { + memcpy(prev_map, national_case_insensitive_map, sizeof(prev_map)); } void init() @@ -265,6 +278,7 @@ class ModuleNationalChars : public Module loadtables(charset, tables, 8, 5); forcequit = tag->getBool("forcequit"); CheckForceQuit("National character set changed"); + CheckRehash(); } void CheckForceQuit(const char * message) @@ -286,6 +300,7 @@ class ModuleNationalChars : public Module ServerInstance->IsNick = rememberer; national_case_insensitive_map = lowermap_rememberer; CheckForceQuit("National characters module unloaded"); + CheckRehash(); } virtual Version GetVersion() -- cgit v1.2.3 From 156c35c91f5c69a77a76f6b60db1ea61581bc13f Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Mon, 13 Oct 2014 21:12:55 +0200 Subject: m_nationalchars Rebuild the hash map in m_watch when the national_case_insensitive_map changes Issue #923 --- src/modules/m_nationalchars.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/modules') diff --git a/src/modules/m_nationalchars.cpp b/src/modules/m_nationalchars.cpp index 20e4eaa9e..e02a946f1 100644 --- a/src/modules/m_nationalchars.cpp +++ b/src/modules/m_nationalchars.cpp @@ -239,6 +239,11 @@ class ModuleNationalChars : public Module memcpy(prev_map, national_case_insensitive_map, sizeof(prev_map)); ServerInstance->RehashUsersAndChans(); + + // The OnGarbageCollect() method in m_watch rebuilds the hashmap used by it + Module* mod = ServerInstance->Modules->Find("m_watch.so"); + if (mod) + mod->OnGarbageCollect(); } public: -- cgit v1.2.3 From 48253b1103dcdcd8252808bd021519772b223143 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Mon, 13 Oct 2014 21:16:51 +0200 Subject: m_spanningtree Rebuild serverlist and sidlist when receiving a specific Request Issue #923 --- src/modules/m_spanningtree/main.cpp | 6 ++++++ src/modules/m_spanningtree/main.h | 1 + src/modules/m_spanningtree/utils.cpp | 13 +++++++++++++ src/modules/m_spanningtree/utils.h | 5 +++++ 4 files changed, 25 insertions(+) (limited to 'src/modules') diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index e7ff3789b..5f06cad58 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -930,6 +930,12 @@ ModResult ModuleSpanningTree::OnSetAway(User* user, const std::string &awaymsg) return MOD_RES_PASSTHRU; } +void ModuleSpanningTree::OnRequest(Request& request) +{ + if (!strcmp(request.id, "rehash")) + Utils->Rehash(); +} + void ModuleSpanningTree::ProtoSendMode(void* opaque, TargetTypeFlags target_type, void* target, const parameterlist &modeline, const std::vector &translate) { TreeSocket* s = (TreeSocket*)opaque; diff --git a/src/modules/m_spanningtree/main.h b/src/modules/m_spanningtree/main.h index eb17c4195..17adc9287 100644 --- a/src/modules/m_spanningtree/main.h +++ b/src/modules/m_spanningtree/main.h @@ -178,6 +178,7 @@ class ModuleSpanningTree : public Module void OnLoadModule(Module* mod); void OnUnloadModule(Module* mod); ModResult OnAcceptConnection(int newsock, ListenSocket* from, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server); + void OnRequest(Request& request); CullResult cull(); ~ModuleSpanningTree(); Version GetVersion(); diff --git a/src/modules/m_spanningtree/utils.cpp b/src/modules/m_spanningtree/utils.cpp index 3bd0aa2c7..367a3b921 100644 --- a/src/modules/m_spanningtree/utils.cpp +++ b/src/modules/m_spanningtree/utils.cpp @@ -428,3 +428,16 @@ Link* SpanningTreeUtilities::FindLink(const std::string& name) } return NULL; } + +void SpanningTreeUtilities::Rehash() +{ + server_hash temp; + for (server_hash::const_iterator i = serverlist.begin(); i != serverlist.end(); ++i) + temp.insert(std::make_pair(i->first, i->second)); + serverlist.swap(temp); + temp.clear(); + + for (server_hash::const_iterator i = sidlist.begin(); i != sidlist.end(); ++i) + temp.insert(std::make_pair(i->first, i->second)); + sidlist.swap(temp); +} diff --git a/src/modules/m_spanningtree/utils.h b/src/modules/m_spanningtree/utils.h index a0543b6bd..5559b3459 100644 --- a/src/modules/m_spanningtree/utils.h +++ b/src/modules/m_spanningtree/utils.h @@ -173,6 +173,11 @@ class SpanningTreeUtilities : public classbase /** Refresh the IP cache used for allowing inbound connections */ void RefreshIPCache(); + + /** Recreate serverlist and sidlist, this is needed because of m_nationalchars changing + * national_case_insensitive_map which is used by the hash function + */ + void Rehash(); }; #endif -- cgit v1.2.3 From 856d1b422b286dd569a48dd538d3e720ee29fd5d Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Mon, 13 Oct 2014 21:18:12 +0200 Subject: m_nationalchars Ask m_spanningtree to rebuild its hashmaps when the national_case_insensitive_map changes Issue #923 --- src/modules/m_nationalchars.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/modules') diff --git a/src/modules/m_nationalchars.cpp b/src/modules/m_nationalchars.cpp index e02a946f1..bf95f0f9f 100644 --- a/src/modules/m_nationalchars.cpp +++ b/src/modules/m_nationalchars.cpp @@ -244,6 +244,14 @@ class ModuleNationalChars : public Module Module* mod = ServerInstance->Modules->Find("m_watch.so"); if (mod) mod->OnGarbageCollect(); + + // Send a Request to m_spanningtree asking it to rebuild its hashmaps + mod = ServerInstance->Modules->Find("m_spanningtree.so"); + if (mod) + { + Request req(this, mod, "rehash"); + req.Send(); + } } public: -- cgit v1.2.3 From 566904ece4aa15cfc90a4452375b54b5daf3baf2 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Tue, 14 Oct 2014 17:40:13 +0200 Subject: m_ssl_openssl Add user-friendly config options for setting a few OpenSSL context options --- src/modules/extra/m_ssl_openssl.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 518712c00..8a575466e 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -113,6 +113,20 @@ class ModuleSSLOpenSSL : public Module static void SetContextOptions(SSL_CTX* ctx, long defoptions, const std::string& ctxname, ConfigTag* tag) { long setoptions = tag->getInt(ctxname + "setoptions"); + // User-friendly config options for setting context options +#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE + if (tag->getBool("cipherserverpref")) + setoptions |= SSL_OP_CIPHER_SERVER_PREFERENCE; +#endif +#ifdef SSL_OP_NO_COMPRESSION + if (!tag->getBool("compression", true)) + setoptions |= SSL_OP_NO_COMPRESSION; +#endif + if (!tag->getBool("sslv3", true)) + setoptions |= SSL_OP_NO_SSLv3; + if (!tag->getBool("tlsv1", true)) + setoptions |= SSL_OP_NO_TLSv1; + long clearoptions = tag->getInt(ctxname + "clearoptions"); ServerInstance->Logs->Log("m_ssl_openssl", DEBUG, "Setting OpenSSL %s context options, default: %ld set: %ld clear: %ld", ctxname.c_str(), defoptions, clearoptions, setoptions); -- cgit v1.2.3 From 6a8e8dae95b9fd74471bd3cef0b6d352426a2973 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Tue, 14 Oct 2014 17:52:41 +0200 Subject: m_ssl_openssl Return an error from the IOHook read and write functions if the handshake returns 0 The meaning of a 0 return value quoted from the manual: The TLS/SSL handshake was not successful but was shut down controlled and by the specifications of the TLS/SSL protocol. --- src/modules/extra/m_ssl_openssl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 8a575466e..e9b5c4052 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -644,7 +644,7 @@ class ModuleSSLOpenSSL : public Module else if (ret == 0) { CloseSession(session); - return true; + return false; } return true; -- cgit v1.2.3 From fba9bbe4cd29744fe30753f63a37102f664e36bc Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 15 Oct 2014 20:07:55 +0200 Subject: m_ssl_openssl Remove bogus errno assignment from CloseSession() --- src/modules/extra/m_ssl_openssl.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index e9b5c4052..663926c4f 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -660,7 +660,6 @@ class ModuleSSLOpenSSL : public Module session->sess = NULL; session->status = ISSL_NONE; - errno = EIO; } void VerifyCertificate(issl_session* session, StreamSocket* user) -- cgit v1.2.3 From 8e3cc7d5d45e598d5c41ac5ae7597cafbfaac888 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 15 Oct 2014 20:10:04 +0200 Subject: m_ssl_openssl Free the ssl_cert object as soon as the session is closed instead of waiting for the next VerifyCertificate() or new connection --- src/modules/extra/m_ssl_openssl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 663926c4f..2c7c67cf1 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -403,7 +403,6 @@ class ModuleSSLOpenSSL : public Module session->sess = SSL_new(ctx); session->status = ISSL_NONE; session->outbound = false; - session->cert = NULL; if (session->sess == NULL) return; @@ -660,6 +659,7 @@ class ModuleSSLOpenSSL : public Module session->sess = NULL; session->status = ISSL_NONE; + session->cert = NULL; } void VerifyCertificate(issl_session* session, StreamSocket* user) -- cgit v1.2.3 From 177304d63763e94d38e15de98d791ab12ef17a75 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 15 Oct 2014 20:13:00 +0200 Subject: m_ssl_openssl Reset data_to_write for new sessions --- src/modules/extra/m_ssl_openssl.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 2c7c67cf1..d9dc47569 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -403,6 +403,7 @@ class ModuleSSLOpenSSL : public Module session->sess = SSL_new(ctx); session->status = ISSL_NONE; session->outbound = false; + session->data_to_write = false; if (session->sess == NULL) return; @@ -428,6 +429,7 @@ class ModuleSSLOpenSSL : public Module session->sess = SSL_new(clictx); session->status = ISSL_NONE; session->outbound = true; + session->data_to_write = false; if (session->sess == NULL) return; -- cgit v1.2.3 From 7b5703b9a22e176ef6a47b405f2b0d5ce122df0a Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 15 Oct 2014 20:16:05 +0200 Subject: m_ssl_openssl Fix debug message --- src/modules/extra/m_ssl_openssl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index d9dc47569..27cd3a2ae 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -128,7 +128,7 @@ class ModuleSSLOpenSSL : public Module setoptions |= SSL_OP_NO_TLSv1; long clearoptions = tag->getInt(ctxname + "clearoptions"); - ServerInstance->Logs->Log("m_ssl_openssl", DEBUG, "Setting OpenSSL %s context options, default: %ld set: %ld clear: %ld", ctxname.c_str(), defoptions, clearoptions, setoptions); + ServerInstance->Logs->Log("m_ssl_openssl", DEBUG, "Setting OpenSSL %s context options, default: %ld set: %ld clear: %ld", ctxname.c_str(), defoptions, setoptions, clearoptions); // Clear everything SSL_CTX_clear_options(ctx, SSL_CTX_get_options(ctx)); -- cgit v1.2.3 From e04ece9061f3b454876a09da9cac018d6aabef9a Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Thu, 16 Oct 2014 21:07:25 +0200 Subject: m_ssl_gnutls Refcount GnuTLS objects, free them when they are no longer in use instead of at /rehash ssl time --- src/modules/extra/m_ssl_gnutls.cpp | 176 +++++++++++++++++++++++-------------- 1 file changed, 110 insertions(+), 66 deletions(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 7934c23ab..4135194c5 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -64,8 +64,53 @@ typedef gnutls_dh_params_t gnutls_dh_params; enum issl_status { ISSL_NONE, ISSL_HANDSHAKING_READ, ISSL_HANDSHAKING_WRITE, ISSL_HANDSHAKEN, ISSL_CLOSING, ISSL_CLOSED }; -static std::vector x509_certs; -static gnutls_x509_privkey_t x509_key; +struct SSLConfig : public refcountbase +{ + gnutls_certificate_credentials_t x509_cred; + std::vector x509_certs; + gnutls_x509_privkey_t x509_key; + gnutls_dh_params_t dh_params; +#ifdef GNUTLS_NEW_PRIO_API + gnutls_priority_t priority; +#endif + + SSLConfig() + : x509_cred(NULL) + , x509_key(NULL) + , dh_params(NULL) +#ifdef GNUTLS_NEW_PRIO_API + , priority(NULL) +#endif + { + } + + ~SSLConfig() + { + ServerInstance->Logs->Log("m_ssl_gnutls", DEBUG, "Destroying SSLConfig %p", (void*)this); + + if (x509_cred) + gnutls_certificate_free_credentials(x509_cred); + + for (unsigned int i = 0; i < x509_certs.size(); i++) + gnutls_x509_crt_deinit(x509_certs[i]); + + if (x509_key) + gnutls_x509_privkey_deinit(x509_key); + + if (dh_params) + gnutls_dh_params_deinit(dh_params); + +#ifdef GNUTLS_NEW_PRIO_API + if (priority) + gnutls_priority_deinit(priority); +#endif + } +}; + +static reference currconf; + +static SSLConfig* GetSessionConfig(gnutls_session_t session); + #if(GNUTLS_VERSION_MAJOR < 2 || ( GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR < 12 ) ) static int cert_callback (gnutls_session_t session, const gnutls_datum_t * req_ca_rdn, int nreqs, const gnutls_pk_algorithm_t * sign_algos, int sign_algos_length, gnutls_retr_st * st) { @@ -77,9 +122,11 @@ static int cert_callback (gnutls_session_t session, const gnutls_datum_t * req_c st->cert_type = GNUTLS_CRT_X509; st->key_type = GNUTLS_PRIVKEY_X509; #endif + SSLConfig* conf = GetSessionConfig(session); + std::vector& x509_certs = conf->x509_certs; st->ncerts = x509_certs.size(); st->cert.x509 = &x509_certs[0]; - st->key.x509 = x509_key; + st->key.x509 = conf->x509_key; st->deinit_all = 0; return 0; @@ -108,10 +155,17 @@ public: gnutls_session_t sess; issl_status status; reference cert; + reference config; issl_session() : socket(NULL), sess(NULL) {} }; +static SSLConfig* GetSessionConfig(gnutls_session_t sess) +{ + issl_session* session = reinterpret_cast(gnutls_transport_get_ptr(sess)); + return session->config; +} + class CommandStartTLS : public SplitCommand { public: @@ -163,19 +217,11 @@ class ModuleSSLGnuTLS : public Module { issl_session* sessions; - gnutls_certificate_credentials_t x509_cred; - gnutls_dh_params_t dh_params; gnutls_digest_algorithm_t hash; - #ifdef GNUTLS_NEW_PRIO_API - gnutls_priority_t priority; - #endif std::string sslports; int dh_bits; - bool cred_alloc; - bool dh_alloc; - RandGen randhandler; CommandStartTLS starttls; @@ -263,21 +309,12 @@ class ModuleSSLGnuTLS : public Module sessions = new issl_session[ServerInstance->SE->GetMaxFds()]; gnutls_global_init(); // This must be called once in the program - gnutls_x509_privkey_init(&x509_key); - - #ifdef GNUTLS_NEW_PRIO_API - // Init this here so it's always initialized, avoids an extra boolean - gnutls_priority_init(&priority, "NORMAL", NULL); - #endif - - cred_alloc = false; - dh_alloc = false; } void init() { - // Needs the flag as it ignores a plain /rehash - OnModuleRehash(NULL,"ssl"); + currconf = new SSLConfig; + InitSSLConfig(currconf); ServerInstance->GenRandom = &randhandler; @@ -334,11 +371,30 @@ class ModuleSSLGnuTLS : public Module if(param != "ssl") return; + reference newconf = new SSLConfig; + try + { + InitSSLConfig(newconf); + } + catch (ModuleException& ex) + { + ServerInstance->Logs->Log("m_ssl_gnutls", DEFAULT, "m_ssl_gnutls: Not applying new config. %s", ex.GetReason()); + return; + } + + ServerInstance->Logs->Log("m_ssl_gnutls", DEFAULT, "m_ssl_gnutls: Applying new config, old config is in use by %d connection(s)", currconf->GetReferenceCount()-1); + currconf = newconf; + } + + void InitSSLConfig(SSLConfig* config) + { + ServerInstance->Logs->Log("m_ssl_gnutls", DEBUG, "Initializing new SSLConfig %p", (void*)config); + std::string keyfile; std::string certfile; std::string cafile; std::string crlfile; - OnRehash(user); + OnRehash(NULL); ConfigTag* Conf = ServerInstance->Config->ConfValue("gnutls"); @@ -369,28 +425,17 @@ class ModuleSSLGnuTLS : public Module int ret; - if (dh_alloc) - { - gnutls_dh_params_deinit(dh_params); - dh_alloc = false; - dh_params = NULL; - } + gnutls_certificate_credentials_t& x509_cred = config->x509_cred; - if (cred_alloc) + ret = gnutls_certificate_allocate_credentials(&x509_cred); + if (ret < 0) { - // Deallocate the old credentials - gnutls_certificate_free_credentials(x509_cred); - - for(unsigned int i=0; i < x509_certs.size(); i++) - gnutls_x509_crt_deinit(x509_certs[i]); - x509_certs.clear(); + // Set to NULL because we can't be sure what value is in it and we must not try to + // deallocate it in case of an error + x509_cred = NULL; + throw ModuleException("Failed to allocate certificate credentials: " + std::string(gnutls_strerror(ret))); } - ret = gnutls_certificate_allocate_credentials(&x509_cred); - cred_alloc = (ret >= 0); - if (!cred_alloc) - ServerInstance->Logs->Log("m_ssl_gnutls",DEBUG, "m_ssl_gnutls.so: Failed to allocate certificate credentials: %s", gnutls_strerror(ret)); - if((ret =gnutls_certificate_set_x509_trust_file(x509_cred, cafile.c_str(), GNUTLS_X509_FMT_PEM)) < 0) ServerInstance->Logs->Log("m_ssl_gnutls",DEBUG, "m_ssl_gnutls.so: Failed to set X.509 trust file '%s': %s", cafile.c_str(), gnutls_strerror(ret)); @@ -407,6 +452,8 @@ class ModuleSSLGnuTLS : public Module std::string key_string = reader.Contents(); gnutls_datum_t key_datum = { (unsigned char*)key_string.data(), static_cast(key_string.length()) }; + std::vector& x509_certs = config->x509_certs; + // If this fails, no SSL port will work. At all. So, do the smart thing - throw a ModuleException unsigned int certcount = 3; x509_certs.resize(certcount); @@ -426,6 +473,14 @@ class ModuleSSLGnuTLS : public Module } x509_certs.resize(ret); + gnutls_x509_privkey_t& x509_key = config->x509_key; + if (gnutls_x509_privkey_init(&x509_key) < 0) + { + // Make sure the destructor does not try to deallocate this, see above + x509_key = NULL; + throw ModuleException("Unable to initialize private key"); + } + if((ret = gnutls_x509_privkey_import(x509_key, &key_datum, GNUTLS_X509_FMT_PEM)) < 0) throw ModuleException("Unable to load GnuTLS server private key (" + keyfile + "): " + std::string(gnutls_strerror(ret))); @@ -433,14 +488,12 @@ class ModuleSSLGnuTLS : public Module throw ModuleException("Unable to set GnuTLS cert/key pair: " + std::string(gnutls_strerror(ret))); #ifdef GNUTLS_NEW_PRIO_API - // It's safe to call this every time as we cannot have this uninitialized, see constructor and below. - gnutls_priority_deinit(priority); - // Try to set the priorities for ciphers, kex methods etc. to the user supplied string // If the user did not supply anything then the string is already set to "NORMAL" const char* priocstr = priorities.c_str(); const char* prioerror; + gnutls_priority_t& priority = config->priority; if ((ret = gnutls_priority_init(&priority, priocstr, &prioerror)) < 0) { // gnutls did not understand the user supplied string, log and fall back to the default priorities @@ -458,10 +511,13 @@ class ModuleSSLGnuTLS : public Module #else gnutls_certificate_set_retrieve_function (x509_cred, cert_callback); #endif + + gnutls_dh_params_t& dh_params = config->dh_params; ret = gnutls_dh_params_init(&dh_params); - dh_alloc = (ret >= 0); - if (!dh_alloc) + if (ret < 0) { + // Make sure the destructor does not try to deallocate this, see above + dh_params = NULL; ServerInstance->Logs->Log("m_ssl_gnutls",DEFAULT, "m_ssl_gnutls.so: Failed to initialise DH parameters: %s", gnutls_strerror(ret)); return; } @@ -478,27 +534,24 @@ class ModuleSSLGnuTLS : public Module { // File unreadable or GnuTLS was unhappy with the contents, generate the DH primes now ServerInstance->Logs->Log("m_ssl_gnutls", DEFAULT, "m_ssl_gnutls.so: Generating DH parameters because I failed to load them from file '%s': %s", dhfile.c_str(), gnutls_strerror(ret)); - GenerateDHParams(); + GenerateDHParams(dh_params); } } else { - GenerateDHParams(); + GenerateDHParams(dh_params); } gnutls_certificate_set_dh_params(x509_cred, dh_params); } - void GenerateDHParams() + void GenerateDHParams(gnutls_dh_params_t dh_params) { // Generate Diffie Hellman parameters - for use with DHE // kx algorithms. These should be discarded and regenerated // once a day, once a week or once a month. Depending on the // security requirements. - if (!dh_alloc) - return; - int ret; if((ret = gnutls_dh_params_generate2(dh_params, dh_bits)) < 0) @@ -507,18 +560,7 @@ class ModuleSSLGnuTLS : public Module ~ModuleSSLGnuTLS() { - for(unsigned int i=0; i < x509_certs.size(); i++) - gnutls_x509_crt_deinit(x509_certs[i]); - - gnutls_x509_privkey_deinit(x509_key); - #ifdef GNUTLS_NEW_PRIO_API - gnutls_priority_deinit(priority); - #endif - - if (dh_alloc) - gnutls_dh_params_deinit(dh_params); - if (cred_alloc) - gnutls_certificate_free_credentials(x509_cred); + currconf = NULL; gnutls_global_deinit(); delete[] sessions; @@ -581,13 +623,14 @@ class ModuleSSLGnuTLS : public Module gnutls_init(&session->sess, me_server ? GNUTLS_SERVER : GNUTLS_CLIENT); session->socket = user; + session->config = currconf; #ifdef GNUTLS_NEW_PRIO_API - gnutls_priority_set(session->sess, priority); + gnutls_priority_set(session->sess, currconf->priority); #else gnutls_set_default_priority(session->sess); #endif - gnutls_credentials_set(session->sess, GNUTLS_CRD_CERTIFICATE, x509_cred); + gnutls_credentials_set(session->sess, GNUTLS_CRD_CERTIFICATE, currconf->x509_cred); gnutls_dh_set_prime_bits(session->sess, dh_bits); gnutls_transport_set_ptr(session->sess, reinterpret_cast(session)); gnutls_transport_set_push_function(session->sess, gnutls_push_wrapper); @@ -809,6 +852,7 @@ class ModuleSSLGnuTLS : public Module session->sess = NULL; session->cert = NULL; session->status = ISSL_NONE; + session->config = NULL; } void VerifyCertificate(issl_session* session, StreamSocket* user) -- cgit v1.2.3 From 3e20f7bd2959fb1f267ba03b0387443b1c30cba1 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Thu, 16 Oct 2014 21:15:31 +0200 Subject: Add interface to SSL modules that allows other modules to obtain the raw SSL session of a socket --- src/modules/extra/m_ssl_gnutls.cpp | 6 ++++++ src/modules/extra/m_ssl_openssl.cpp | 6 ++++++ src/modules/ssl.h | 15 +++++++++++++++ 3 files changed, 27 insertions(+) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 4135194c5..cdfe00b9c 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -615,6 +615,12 @@ class ModuleSSLGnuTLS : public Module req.cert = session->cert; } + else if (!strcmp("GET_RAW_SSL_SESSION", request.id)) + { + SSLRawSessionRequest& req = static_cast(request); + if ((req.fd >= 0) && (req.fd < ServerInstance->SE->GetMaxFds())) + req.data = reinterpret_cast(sessions[req.fd].sess); + } } void InitSession(StreamSocket* user, bool me_server) diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 27cd3a2ae..9ca92fe52 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -392,6 +392,12 @@ class ModuleSSLOpenSSL : public Module req.cert = session->cert; } + else if (!strcmp("GET_RAW_SSL_SESSION", request.id)) + { + SSLRawSessionRequest& req = static_cast(request); + if ((req.fd >= 0) && (req.fd < ServerInstance->SE->GetMaxFds())) + req.data = reinterpret_cast(sessions[req.fd].sess); + } } void OnStreamSocketAccept(StreamSocket* user, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server) diff --git a/src/modules/ssl.h b/src/modules/ssl.h index 9deafb830..4c877551d 100644 --- a/src/modules/ssl.h +++ b/src/modules/ssl.h @@ -172,4 +172,19 @@ struct UserCertificateRequest : public Request } }; +class SSLRawSessionRequest : public Request +{ + public: + const int fd; + void* data; + + SSLRawSessionRequest(int FD, Module* srcmod, Module* destmod) + : Request(srcmod, destmod, "GET_RAW_SSL_SESSION") + , fd(FD) + , data(NULL) + { + Send(); + } +}; + #endif -- cgit v1.2.3 From 8cd84786d0b710a60d25e4c9c58fdde2fb0b8211 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Thu, 16 Oct 2014 21:18:29 +0200 Subject: Initialize all fields of issl_session on module load in SSL modules --- src/modules/extra/m_ssl_gnutls.cpp | 2 +- src/modules/extra/m_ssl_openssl.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index cdfe00b9c..21b58f280 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -157,7 +157,7 @@ public: reference cert; reference config; - issl_session() : socket(NULL), sess(NULL) {} + issl_session() : socket(NULL), sess(NULL), status(ISSL_NONE) {} }; static SSLConfig* GetSessionConfig(gnutls_session_t sess) diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 9ca92fe52..01bf11678 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -75,6 +75,8 @@ public: bool data_to_write; issl_session() + : sess(NULL) + , status(ISSL_NONE) { outbound = false; data_to_write = false; -- cgit v1.2.3 From a681248b3c989667c2d025758722d2c90b444abe Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Fri, 17 Oct 2014 15:40:01 +0200 Subject: m_delayjoin Only send JOIN on mode change if the mode being changed is a prefix mode --- src/modules/m_delayjoin.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/modules') diff --git a/src/modules/m_delayjoin.cpp b/src/modules/m_delayjoin.cpp index a9a92e67a..20d4c8e8f 100644 --- a/src/modules/m_delayjoin.cpp +++ b/src/modules/m_delayjoin.cpp @@ -182,6 +182,11 @@ ModResult ModuleDelayJoin::OnRawMode(User* user, Channel* channel, const char mo if (!user || !channel || param.empty()) return MOD_RES_PASSTHRU; + ModeHandler* mh = ServerInstance->Modes->FindMode(mode, MODETYPE_CHANNEL); + // If not a prefix mode then we got nothing to do here + if (!mh || !mh->GetPrefixRank()) + return MOD_RES_PASSTHRU; + User* dest; if (IS_LOCAL(user)) dest = ServerInstance->FindNickOnly(param); -- cgit v1.2.3 From 4e9006c9676f31d0845b1a5062cd36bdd1b8796c Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 18 Oct 2014 14:28:50 -0400 Subject: Fix watch away numerics, #937 --- src/modules/m_watch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/m_watch.cpp b/src/modules/m_watch.cpp index 074ce37ad..a86483291 100644 --- a/src/modules/m_watch.cpp +++ b/src/modules/m_watch.cpp @@ -417,7 +417,7 @@ class Modulewatch : public Module { for (std::deque::iterator n = x->second.begin(); n != x->second.end(); n++) { - (*n)->WriteNumeric(inum, numeric); + (*n)->WriteNumeric(inum, (*n)->nick + " " + numeric); } } -- cgit v1.2.3 From 5fe0592bbc049c2e7801ddb59182fa7219427d45 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Mon, 20 Oct 2014 20:48:23 +0200 Subject: m_ssl_gnutls Add compile time option for allowing sha256 certificate fingerprints --- src/modules/extra/m_ssl_gnutls.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 21b58f280..228ceb994 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -419,6 +419,10 @@ class ModuleSSLGnuTLS : public Module hash = GNUTLS_DIG_MD5; else if (hashname == "sha1") hash = GNUTLS_DIG_SHA1; +#ifdef INSPIRCD_GNUTLS_ENABLE_SHA256_FINGERPRINT + else if (hashname == "sha256") + hash = GNUTLS_DIG_SHA256; +#endif else throw ModuleException("Unknown hash type " + hashname); -- cgit v1.2.3 From f9a3f7e080ce62eefeb03f7926777e687c169f3b Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Wed, 15 Oct 2014 18:27:20 +0200 Subject: m_ssl_openssl Add compile time option to enable ECDH --- src/modules/extra/m_ssl_openssl.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 01bf11678..737dab914 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -141,6 +141,38 @@ class ModuleSSLOpenSSL : public Module ServerInstance->Logs->Log("m_ssl_openssl", DEFAULT, "OpenSSL %s context options: %ld", ctxname.c_str(), final); } +#ifdef INSPIRCD_OPENSSL_ENABLE_ECDH + void SetupECDH(ConfigTag* tag) + { + std::string curvename = tag->getString("ecdhcurve", "prime256v1"); + if (curvename.empty()) + return; + + int nid = OBJ_sn2nid(curvename.c_str()); + if (nid == 0) + { + ServerInstance->Logs->Log("m_ssl_openssl", DEFAULT, "m_ssl_openssl.so: Unknown curve: \"%s\"", curvename.c_str()); + return; + } + + EC_KEY* eckey = EC_KEY_new_by_curve_name(nid); + if (!eckey) + { + ServerInstance->Logs->Log("m_ssl_openssl", DEFAULT, "m_ssl_openssl.so: Unable to create EC key object"); + return; + } + + ERR_clear_error(); + if (SSL_CTX_set_tmp_ecdh(ctx, eckey) < 0) + { + ServerInstance->Logs->Log("m_ssl_openssl", DEFAULT, "m_ssl_openssl.so: Couldn't set ECDH parameters"); + ERR_print_errors_cb(error_callback, this); + } + + EC_KEY_free(eckey); + } +#endif + public: ModuleSSLOpenSSL() : iohook(this, "ssl/openssl", SERVICE_IOHOOK) @@ -334,6 +366,10 @@ class ModuleSSLOpenSSL : public Module #ifndef _WIN32 fclose(dhpfile); #endif + +#ifdef INSPIRCD_OPENSSL_ENABLE_ECDH + SetupECDH(conf); +#endif } void On005Numeric(std::string &output) -- cgit v1.2.3 From cbb699a705d3f3d61fbb223d41e2a1c313c3609b Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Fri, 17 Oct 2014 18:46:47 +0200 Subject: m_ssl_openssl Add compile time option that allows disabling renegotiations --- src/modules/extra/m_ssl_openssl.cpp | 61 +++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 737dab914..02f44f2f1 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -51,10 +51,16 @@ /* $NoPedantic */ +class ModuleSSLOpenSSL; + enum issl_status { ISSL_NONE, ISSL_HANDSHAKING, ISSL_OPEN }; static bool SelfSigned = false; +#ifdef INSPIRCD_OPENSSL_ENABLE_RENEGO_DETECTION +static ModuleSSLOpenSSL* opensslmod = NULL; +#endif + char* get_error() { return ERR_error_string(ERR_get_error(), NULL); @@ -173,10 +179,40 @@ class ModuleSSLOpenSSL : public Module } #endif +#ifdef INSPIRCD_OPENSSL_ENABLE_RENEGO_DETECTION + static void SSLInfoCallback(const SSL* ssl, int where, int rc) + { + int fd = SSL_get_fd(const_cast(ssl)); + issl_session& session = opensslmod->sessions[fd]; + + if ((where & SSL_CB_HANDSHAKE_START) && (session.status == ISSL_OPEN)) + { + // The other side is trying to renegotiate, kill the connection and change status + // to ISSL_NONE so CheckRenego() closes the session + session.status = ISSL_NONE; + ServerInstance->SE->Shutdown(fd, 2); + } + } + + bool CheckRenego(StreamSocket* sock, issl_session* session) + { + if (session->status != ISSL_NONE) + return true; + + ServerInstance->Logs->Log("m_ssl_openssl", DEBUG, "Session %p killed, attempted to renegotiate", (void*)session->sess); + CloseSession(session); + sock->SetError("Renegotiation is not allowed"); + return false; + } +#endif + public: ModuleSSLOpenSSL() : iohook(this, "ssl/openssl", SERVICE_IOHOOK) { +#ifdef INSPIRCD_OPENSSL_ENABLE_RENEGO_DETECTION + opensslmod = this; +#endif sessions = new issl_session[ServerInstance->SE->GetMaxFds()]; /* Global SSL library initialization*/ @@ -235,6 +271,20 @@ class ModuleSSLOpenSSL : public Module ConfigTag* Conf = ServerInstance->Config->ConfValue("openssl"); +#ifdef INSPIRCD_OPENSSL_ENABLE_RENEGO_DETECTION + // Set the callback if we are not allowing renegotiations, unset it if we do + if (Conf->getBool("renegotiation", true)) + { + SSL_CTX_set_info_callback(ctx, NULL); + SSL_CTX_set_info_callback(clictx, NULL); + } + else + { + SSL_CTX_set_info_callback(ctx, SSLInfoCallback); + SSL_CTX_set_info_callback(clictx, SSLInfoCallback); + } +#endif + if (Conf->getBool("showports", true)) { sslports = Conf->getString("advertisedports"); @@ -533,6 +583,11 @@ class ModuleSSLOpenSSL : public Module size_t bufsiz = ServerInstance->Config->NetBufferSize; int ret = SSL_read(session->sess, buffer, bufsiz); +#ifdef INSPIRCD_OPENSSL_ENABLE_RENEGO_DETECTION + if (!CheckRenego(user, session)) + return -1; +#endif + if (ret > 0) { recvq.append(buffer, ret); @@ -601,6 +656,12 @@ class ModuleSSLOpenSSL : public Module { ERR_clear_error(); int ret = SSL_write(session->sess, buffer.data(), buffer.size()); + +#ifdef INSPIRCD_OPENSSL_ENABLE_RENEGO_DETECTION + if (!CheckRenego(user, session)) + return -1; +#endif + if (ret == (int)buffer.length()) { session->data_to_write = false; -- cgit v1.2.3 From 9e42a8e8f77b3c9fa65d7d2384b3d145f46e1376 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 20 Oct 2014 15:14:54 -0400 Subject: Fix m_banredirect causing bans added for hosts being rewritten as nicks --- src/modules/m_banredirect.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/modules') diff --git a/src/modules/m_banredirect.cpp b/src/modules/m_banredirect.cpp index 2e2592541..1b9e361bf 100644 --- a/src/modules/m_banredirect.cpp +++ b/src/modules/m_banredirect.cpp @@ -75,6 +75,9 @@ class BanRedirect : public ModeWatcher if (param.length() >= 2 && param[1] == ':') return true; + if (param.find('#') == std::string::npos) + return true; + if(adding && (channel->bans.size() > static_cast(maxbans))) { source->WriteNumeric(478, "%s %s :Channel ban list for %s is full (maximum entries for this channel is %ld)", source->nick.c_str(), channel->name.c_str(), channel->name.c_str(), maxbans); @@ -119,6 +122,14 @@ class BanRedirect : public ModeWatcher mask[NICK].swap(mask[IDENT]); } + if (!mask[NICK].empty() && mask[IDENT].empty() && mask[HOST].empty()) + { + if (mask[NICK].find('.') != std::string::npos || mask[NICK].find(':') != std::string::npos) + { + mask[NICK].swap(mask[HOST]); + } + } + for(int i = 0; i < 3; i++) { if(mask[i].empty()) -- cgit v1.2.3 From 6cc3e6be818f8d15c41e32787ba6885d501e8ed4 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Thu, 23 Oct 2014 17:59:44 +0200 Subject: m_delaymsg Add option to disallow NOTICEs too --- docs/conf/modules.conf.example | 2 ++ src/modules/m_delaymsg.cpp | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'src/modules') diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index 2af84c83b..30b8181ac 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -695,6 +695,8 @@ # from talking in the channel unless they've been joined for X seconds. # Settable using /MODE #chan +d 30 # +# Set allownotice to no to disallow NOTICEs too. Defaults to yes. +# #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Deny channels module: Deny channels from being used by users. diff --git a/src/modules/m_delaymsg.cpp b/src/modules/m_delaymsg.cpp index cfc06866a..978ab55d2 100644 --- a/src/modules/m_delaymsg.cpp +++ b/src/modules/m_delaymsg.cpp @@ -52,12 +52,15 @@ class ModuleDelayMsg : public Module { ServerInstance->Modules->AddService(djm); ServerInstance->Modules->AddService(djm.jointime); - Implementation eventlist[] = { I_OnUserJoin, I_OnUserPreMessage}; + Implementation eventlist[] = { I_OnUserJoin, I_OnUserPreMessage, I_OnRehash }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); + OnRehash(NULL); } Version GetVersion(); void OnUserJoin(Membership* memb, bool sync, bool created, CUList&); ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string &text, char status, CUList &exempt_list); + ModResult OnUserPreNotice(User* user, void* dest, int target_type, std::string& text, char status, CUList& exempt_list); + void OnRehash(User* user); }; ModeAction DelayMsgMode::OnModeChange(User* source, User* dest, Channel* channel, std::string ¶meter, bool adding) @@ -144,5 +147,19 @@ ModResult ModuleDelayMsg::OnUserPreMessage(User* user, void* dest, int target_ty return MOD_RES_PASSTHRU; } +ModResult ModuleDelayMsg::OnUserPreNotice(User* user, void* dest, int target_type, std::string& text, char status, CUList& exempt_list) +{ + return OnUserPreMessage(user, dest, target_type, text, status, exempt_list); +} + +void ModuleDelayMsg::OnRehash(User* user) +{ + ConfigTag* tag = ServerInstance->Config->ConfValue("delaymsg"); + if (tag->getBool("allownotice", true)) + ServerInstance->Modules->Detach(I_OnUserPreNotice, this); + else + ServerInstance->Modules->Attach(I_OnUserPreNotice, this); +} + MODULE_INIT(ModuleDelayMsg) -- cgit v1.2.3 From a49fd4cba6a44334eb5a39c6fbe8f6cebd55d0c7 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Mon, 25 Aug 2014 13:04:17 +0100 Subject: Use gnutls_rnd instead of gcry_randomize on newer GnuTLS versions. This is a modified version of 690c372. Fixes #905. --- make/utilities.pm | 9 +++++++++ src/modules/extra/m_ssl_gnutls.cpp | 9 +++------ 2 files changed, 12 insertions(+), 6 deletions(-) (limited to 'src/modules') diff --git a/make/utilities.pm b/make/utilities.pm index 42dd6b547..ae16ce3dc 100644 --- a/make/utilities.pm +++ b/make/utilities.pm @@ -319,6 +319,15 @@ sub translate_functions($$) die "Developers should no longer use backticks in configuration macros. Please use exec() and eval() macros instead. Offending line: $line (In module: $module)"; } + if ($line =~ /if(gt|lt)\("(.+?)","(.+?)"\)/) { + chomp(my $result = `$2 2>/dev/null`); + if (($1 eq 'gt' && $result le $3) || ($1 eq 'lt' && $result ge $3)) { + $line = substr $line, 0, $-[0]; + } else { + $line =~ s/if$1\("$2","$3"\)//; + } + } + if ($line =~ /ifuname\(\!"(\w+)"\)/) { my $uname = $1; diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 228ceb994..3b67a6180 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -22,9 +22,6 @@ #include "inspircd.h" -#ifndef _WIN32 -#include -#endif #include #include #include "ssl.h" @@ -35,8 +32,8 @@ #endif /* $ModDesc: Provides SSL support for clients */ -/* $CompileFlags: pkgconfincludes("gnutls","/gnutls/gnutls.h","") exec("libgcrypt-config --cflags") */ -/* $LinkerFlags: rpath("pkg-config --libs gnutls") pkgconflibs("gnutls","/libgnutls.so","-lgnutls") exec("libgcrypt-config --libs") */ +/* $CompileFlags: pkgconfincludes("gnutls","/gnutls/gnutls.h","") iflt("pkg-config --modversion gnutls","2.12") exec("libgcrypt-config --cflags") */ +/* $LinkerFlags: rpath("pkg-config --libs gnutls") pkgconflibs("gnutls","/libgnutls.so","-lgnutls") iflt("pkg-config --modversion gnutls","2.12") exec("libgcrypt-config --libs") */ /* $NoPedantic */ #ifndef GNUTLS_VERSION_MAJOR @@ -55,7 +52,7 @@ typedef gnutls_certificate_credentials_t gnutls_certificate_credentials; typedef gnutls_dh_params_t gnutls_dh_params; #endif -#if (defined(_WIN32) && (GNUTLS_VERSION_MAJOR > 2 || (GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR >= 12))) +#if (GNUTLS_VERSION_MAJOR > 2 || (GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR >= 12)) # define GNUTLS_HAS_RND # include #else -- cgit v1.2.3 From 382662a8a4ae5c501b096643cb8f09d2d9d084d0 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Sun, 26 Oct 2014 18:01:24 +0100 Subject: Remove some dead code found by Coverity --- src/modules/extra/m_ssl_openssl.cpp | 4 +--- src/modules/m_spanningtree/treesocket.h | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 02f44f2f1..b21091d3f 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -750,10 +750,8 @@ class ModuleSSLOpenSSL : public Module else if (ret == 0) { CloseSession(session); - return false; } - - return true; + return false; } void CloseSession(issl_session* session) diff --git a/src/modules/m_spanningtree/treesocket.h b/src/modules/m_spanningtree/treesocket.h index d8445572b..abda28335 100644 --- a/src/modules/m_spanningtree/treesocket.h +++ b/src/modules/m_spanningtree/treesocket.h @@ -97,8 +97,6 @@ class TreeSocket : public BufferedSocket ServerState LinkState; /* Link state */ CapabData* capab; /* Link setup data (held until burst is sent) */ TreeServer* MyRoot; /* The server we are talking to */ - time_t NextPing; /* Time when we are due to ping this server */ - bool LastPingWasGood; /* Responded to last ping we sent? */ int proto_version; /* Remote protocol version */ bool ConnectionFailureShown; /* Set to true if a connection failure message was shown */ -- cgit v1.2.3