diff options
author | Adam <Adam@anope.org> | 2014-01-15 23:31:28 -0500 |
---|---|---|
committer | Attila Molnar <attilamolnar@hush.com> | 2014-01-21 18:04:08 +0100 |
commit | ec1e85cb3dbe7c733faa7dbd850459a41b7e5144 (patch) | |
tree | 2d204c9706a4a76a313f084c54ce3bd2e64583d8 | |
parent | 1cf73c8f32ef8c9cd2a3a1447f9c346e8c2fdacd (diff) |
Add m_starttls and remove it from m_ssl_gnutls, which allows it to work with both openssl and gnutls
-rw-r--r-- | docs/conf/modules.conf.example | 6 | ||||
-rw-r--r-- | src/configreader.cpp | 1 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_gnutls.cpp | 66 | ||||
-rw-r--r-- | src/modules/m_starttls.cpp | 122 |
4 files changed, 130 insertions, 65 deletions
diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index ff7210001..2ab1adebf 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -1807,6 +1807,12 @@ #<sqloper dbid="1" hash="md5"> #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# +# StartTLS module: Implements STARTTLS, which allows clients # +# connected to non SSL enabled ports to enable SSL, if a proper SSL # +# module is loaded (either m_ssl_gnutls or m_ssl_openssl). # +#<module name="m_starttls.so"> + +#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # SVSHold module: Implements SVSHOLD. Like Q:Lines, but can only be # # added/removed by Services. # #<module name="m_svshold.so"> diff --git a/src/configreader.cpp b/src/configreader.cpp index 2320a44b1..0f6d414dd 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -335,6 +335,7 @@ struct DeprecatedConfig static const DeprecatedConfig ChangedConfig[] = { { "bind", "transport", "", "has been moved to <bind:ssl> as of 2.0" }, { "die", "value", "", "you need to reread your config" }, + { "gnutls", "starttls", "", "has been replaced with m_starttls as of 2.2" }, { "link", "autoconnect", "", "2.0+ does not use this attribute - define <autoconnect> tags instead" }, { "link", "transport", "", "has been moved to <link:ssl> as of 2.0" }, { "module", "name", "m_chanprotect.so", "has been replaced with m_customprefix as of 2.2" }, diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index f894043b7..0e0dc64b4 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -548,57 +548,6 @@ info_done_dealloc: } }; -class CommandStartTLS : public SplitCommand -{ - IOHook& hook; - - public: - bool enabled; - CommandStartTLS(Module* mod, IOHook& Hook) - : SplitCommand(mod, "STARTTLS") - , hook(Hook) - { - enabled = true; - works_before_reg = true; - } - - CmdResult HandleLocal(const std::vector<std::string> ¶meters, LocalUser *user) - { - if (!enabled) - { - user->WriteNumeric(691, ":STARTTLS is not enabled"); - return CMD_FAILURE; - } - - if (user->registered == REG_ALL) - { - user->WriteNumeric(691, ":STARTTLS is not permitted after client registration is complete"); - } - else - { - if (!user->eh.GetIOHook()) - { - user->WriteNumeric(670, ":STARTTLS successful, go ahead with TLS handshake"); - /* We need to flush the write buffer prior to adding the IOHook, - * otherwise we'll be sending this line inside the SSL session - which - * won't start its handshake until the client gets this line. Currently, - * we assume the write will not block here; this is usually safe, as - * STARTTLS is sent very early on in the registration phase, where the - * user hasn't built up much sendq. Handling a blocked write here would - * be very annoying. - */ - user->eh.DoWrite(); - user->eh.AddIOHook(&hook); - hook.OnStreamSocketAccept(&user->eh, NULL, NULL); - } - else - user->WriteNumeric(691, ":STARTTLS failure"); - } - - return CMD_FAILURE; - } -}; - class ModuleSSLGnuTLS : public Module { GnuTLSIOHook iohook; @@ -611,13 +560,9 @@ class ModuleSSLGnuTLS : public Module bool dh_alloc; RandGen randhandler; - CommandStartTLS starttls; - - GenericCap capHandler; public: - ModuleSSLGnuTLS() - : iohook(this), starttls(this, iohook), capHandler(this, "tls") + ModuleSSLGnuTLS() : iohook(this) { #ifndef GNUTLS_HAS_RND gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); @@ -651,7 +596,6 @@ class ModuleSSLGnuTLS : public Module sslports.clear(); ConfigTag* Conf = ServerInstance->Config->ConfValue("gnutls"); - starttls.enabled = Conf->getBool("starttls", true); if (Conf->getBool("showports", true)) { @@ -919,8 +863,6 @@ class ModuleSSLGnuTLS : public Module { if (!sslports.empty()) tokens["SSL"] = sslports; - if (starttls.enabled) - tokens["STARTTLS"]; } void OnHookIO(StreamSocket* user, ListenSocket* lsb) CXX11_OVERRIDE @@ -937,12 +879,6 @@ class ModuleSSLGnuTLS : public Module if (user->eh.GetIOHook() == &iohook) iohook.TellCiphersAndFingerprint(user); } - - void OnEvent(Event& ev) CXX11_OVERRIDE - { - if (starttls.enabled) - capHandler.HandleEvent(ev); - } }; MODULE_INIT(ModuleSSLGnuTLS) diff --git a/src/modules/m_starttls.cpp b/src/modules/m_starttls.cpp new file mode 100644 index 000000000..09c9b4f0f --- /dev/null +++ b/src/modules/m_starttls.cpp @@ -0,0 +1,122 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2014 Adam <Adam@anope.org> + * + * This file is part of InspIRCd. InspIRCd is free software: you can + * redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + + +#include "inspircd.h" +#include "modules/ssl.h" +#include "modules/cap.h" + +// From IRCv3 tls-3.1 +enum +{ + RPL_STARTTLS = 670, + ERR_STARTTLS = 691 +}; + +class CommandStartTLS : public SplitCommand +{ + dynamic_reference_nocheck<IOHook>& ssl; + + public: + CommandStartTLS(Module* mod, dynamic_reference_nocheck<IOHook>& s) + : SplitCommand(mod, "STARTTLS") + , ssl(s) + { + works_before_reg = true; + } + + CmdResult HandleLocal(const std::vector<std::string>& parameters, LocalUser* user) + { + if (!ssl) + { + user->WriteNumeric(ERR_STARTTLS, ":STARTTLS is not enabled"); + return CMD_FAILURE; + } + + if (user->registered == REG_ALL) + { + user->WriteNumeric(ERR_STARTTLS, ":STARTTLS is not permitted after client registration is complete"); + return CMD_FAILURE; + } + + if (user->eh.GetIOHook()) + { + user->WriteNumeric(ERR_STARTTLS, ":STARTTLS failure"); + return CMD_FAILURE; + } + + user->WriteNumeric(RPL_STARTTLS, ":STARTTLS successful, go ahead with TLS handshake"); + /* We need to flush the write buffer prior to adding the IOHook, + * otherwise we'll be sending this line inside the SSL session - which + * won't start its handshake until the client gets this line. Currently, + * we assume the write will not block here; this is usually safe, as + * STARTTLS is sent very early on in the registration phase, where the + * user hasn't built up much sendq. Handling a blocked write here would + * be very annoying. + */ + user->eh.DoWrite(); + + user->eh.AddIOHook(*ssl); + ssl->OnStreamSocketAccept(&user->eh, NULL, NULL); + + return CMD_SUCCESS; + } +}; + +class ModuleStartTLS : public Module +{ + CommandStartTLS starttls; + GenericCap tls; + dynamic_reference_nocheck<IOHook> ssl; + + public: + ModuleStartTLS() + : starttls(this, ssl) + , tls(this, "tls") + , ssl(this, "ssl") + { + } + + void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE + { + ConfigTag* conf = ServerInstance->Config->ConfValue("starttls"); + + std::string newprovider = conf->getString("provider"); + if (newprovider.empty()) + ssl.SetProvider("ssl"); + else + ssl.SetProvider("ssl/" + newprovider); + } + + void OnEvent(Event& ev) CXX11_OVERRIDE + { + tls.HandleEvent(ev); + } + + void On005Numeric(std::map<std::string, std::string>& tokens) CXX11_OVERRIDE + { + tokens["STARTTLS"]; + } + + Version GetVersion() CXX11_OVERRIDE + { + return Version("Provides support for the STARTTLS command", VF_VENDOR); + } +}; + +MODULE_INIT(ModuleStartTLS) |