diff options
Diffstat (limited to 'src/modules')
-rw-r--r-- | src/modules/extra/m_ssl_gnutls.cpp | 93 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_openssl.cpp | 14 | ||||
-rw-r--r-- | src/modules/m_hostcycle.cpp | 4 |
3 files changed, 86 insertions, 25 deletions
diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 962e80d28..716a736f8 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -209,14 +209,6 @@ namespace GnuTLS return dh; } - /** Generate */ - static std::auto_ptr<DHParams> Generate(unsigned int bits) - { - std::auto_ptr<DHParams> dh(new DHParams); - ThrowOnError(gnutls_dh_params_generate2(dh->dh_params, bits), "Unable to generate DH params"); - return dh; - } - ~DHParams() { gnutls_dh_params_deinit(dh_params); @@ -353,6 +345,40 @@ namespace GnuTLS { gnutls_priority_set(sess, priority); } + + static const char* GetDefault() + { + return "NORMAL:%SERVER_PRECEDENCE:-VERS-SSL3.0"; + } + + static std::string RemoveUnknownTokens(const std::string& prio) + { + std::string ret; + irc::sepstream ss(prio, ':'); + for (std::string token; ss.GetToken(token); ) + { + // Save current position so we can revert later if needed + const std::string::size_type prevpos = ret.length(); + // Append next token + if (!ret.empty()) + ret.push_back(':'); + ret.append(token); + + gnutls_priority_t test; + if (gnutls_priority_init(&test, ret.c_str(), NULL) < 0) + { + // The new token broke the priority string, revert to the previously working one + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Priority string token not recognized: \"%s\"", token.c_str()); + ret.erase(prevpos); + } + else + { + // Worked + gnutls_priority_deinit(test); + } + } + return ret; + } }; #else /** Dummy class, used when gnutls_priority_set() is not available @@ -362,7 +388,7 @@ namespace GnuTLS public: Priority(const std::string& priorities) { - if (priorities != "NORMAL") + if (priorities != GetDefault()) throw Exception("You've set a non-default priority string, but GnuTLS lacks support for it"); } @@ -371,6 +397,17 @@ namespace GnuTLS // Always set the default priorities gnutls_set_default_priority(sess); } + + static const char* GetDefault() + { + return "NORMAL"; + } + + static std::string RemoveUnknownTokens(const std::string& prio) + { + // We don't do anything here because only NORMAL is accepted + return prio; + } }; #endif @@ -564,24 +601,40 @@ namespace GnuTLS return ret; } + static std::string GetPrioStr(const std::string& profilename, ConfigTag* tag) + { + // Use default priority string if this tag does not specify one + std::string priostr = GnuTLS::Priority::GetDefault(); + bool found = tag->readString("priority", priostr); + // If the prio string isn't set in the config don't be strict about the default one because it doesn't work on all versions of GnuTLS + if (!tag->getBool("strictpriority", found)) + { + std::string stripped = GnuTLS::Priority::RemoveUnknownTokens(priostr); + if (stripped.empty()) + { + // Stripping failed, act as if a prio string wasn't set + stripped = GnuTLS::Priority::RemoveUnknownTokens(GnuTLS::Priority::GetDefault()); + ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Priority string for profile \"%s\" contains unknown tokens and stripping it didn't yield a working one either, falling back to \"%s\"", profilename.c_str(), stripped.c_str()); + } + else if ((found) && (stripped != priostr)) + { + // Prio string was set in the config and we ended up with something that works but different + ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Priority string for profile \"%s\" contains unknown tokens, stripped to \"%s\"", profilename.c_str(), stripped.c_str()); + } + priostr.swap(stripped); + } + return priostr; + } + public: static reference<Profile> Create(const std::string& profilename, ConfigTag* tag) { std::string certstr = ReadFile(tag->getString("certfile", "cert.pem")); std::string keystr = ReadFile(tag->getString("keyfile", "key.pem")); - std::auto_ptr<DHParams> dh; - int gendh = tag->getInt("gendh"); - if (gendh) - { - gendh = (gendh < 1024 ? 1024 : gendh); - dh = DHParams::Generate(gendh); - } - else - dh = DHParams::Import(ReadFile(tag->getString("dhfile", "dhparams.pem"))); + std::auto_ptr<DHParams> dh = DHParams::Import(ReadFile(tag->getString("dhfile", "dhparams.pem"))); - // Use default priority string if this tag does not specify one - std::string priostr = tag->getString("priority", "NORMAL"); + std::string priostr = GetPrioStr(profilename, tag); unsigned int mindh = tag->getInt("mindhbits", 1024); std::string hashstr = tag->getString("hash", "md5"); diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 7dd834e13..c9ae14e11 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -269,10 +269,10 @@ namespace OpenSSL long setoptions = tag->getInt(ctxname + "setoptions"); long clearoptions = tag->getInt(ctxname + "clearoptions"); #ifdef SSL_OP_NO_COMPRESSION - if (!tag->getBool("compression", true)) + if (!tag->getBool("compression", false)) // Disable compression by default setoptions |= SSL_OP_NO_COMPRESSION; #endif - if (!tag->getBool("sslv3", true)) + if (!tag->getBool("sslv3", false)) // Disable SSLv3 by default setoptions |= SSL_OP_NO_SSLv3; if (!tag->getBool("tlsv1", true)) setoptions |= SSL_OP_NO_TLSv1; @@ -363,6 +363,14 @@ namespace OpenSSL return 1; } + static int destroy(BIO* bio) + { + // XXX: Dummy function to avoid a memory leak in OpenSSL. + // The memory leak happens in BIO_free() (bio_lib.c) when the destroy func of the BIO is NULL. + // This is fixed in OpenSSL but some distros still ship the unpatched version hence we provide this workaround. + return 1; + } + static long ctrl(BIO* bio, int cmd, long num, void* ptr) { if (cmd == BIO_CTRL_FLUSH) @@ -385,7 +393,7 @@ static BIO_METHOD biomethods = NULL, // gets OpenSSL::BIOMethod::ctrl, OpenSSL::BIOMethod::create, - NULL, // destroy, NULL causes older OpenSSL to leak memory in BIO_free() (bio_lib.c) + OpenSSL::BIOMethod::destroy, // destroy, does nothing, see function body for more info NULL // callback_ctrl }; diff --git a/src/modules/m_hostcycle.cpp b/src/modules/m_hostcycle.cpp index e8a0abbf1..d4def6473 100644 --- a/src/modules/m_hostcycle.cpp +++ b/src/modules/m_hostcycle.cpp @@ -29,8 +29,8 @@ class ModuleHostCycle : public Module // GetFullHost() returns the original data at the time this function is called const std::string quitline = ":" + user->GetFullHost() + " QUIT :" + quitmsg; - already_sent_t silent_id = ++LocalUser::already_sent_id; - already_sent_t seen_id = ++LocalUser::already_sent_id; + already_sent_t silent_id = ServerInstance->Users.NextAlreadySentId(); + already_sent_t seen_id = ServerInstance->Users.NextAlreadySentId(); IncludeChanList include_chans(user->chans.begin(), user->chans.end()); std::map<User*,bool> exceptions; |