diff options
author | Attila Molnar <attilamolnar@hush.com> | 2015-11-11 10:49:12 +0100 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2015-11-11 10:49:12 +0100 |
commit | 689bb28120da0b54a8c5fe71508d3b3c9cf35064 (patch) | |
tree | 2ba0c3f13463ca409f1c64612dd1ba0c943f972d /src/modules | |
parent | 40a299772ca1ade0c356f4f91941d95fbac09237 (diff) |
m_ssl_gnutls Strip unrecognized tokens from the priority string if configured to do so or when using the default
Diffstat (limited to 'src/modules')
-rw-r--r-- | src/modules/extra/m_ssl_gnutls.cpp | 63 |
1 files changed, 61 insertions, 2 deletions
diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index cc61ababc..112ec8ef9 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -350,6 +350,35 @@ namespace GnuTLS { return "NORMAL"; } + + 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 @@ -373,6 +402,12 @@ namespace GnuTLS { return "NORMAL"; } + + static std::string RemoveUnknownTokens(const std::string& prio) + { + // We don't do anything here because only NORMAL is accepted + return prio; + } }; #endif @@ -566,6 +601,31 @@ 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) { @@ -574,8 +634,7 @@ namespace GnuTLS 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", GnuTLS::Priority::GetDefault()); + std::string priostr = GetPrioStr(profilename, tag); unsigned int mindh = tag->getInt("mindhbits", 1024); std::string hashstr = tag->getString("hash", "md5"); |