From 3a11a742ba35155e1b2e14dc4ef1a4f7f659ea13 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Mon, 8 Aug 2016 14:28:02 +0200 Subject: Pass sendq to OnStreamSocketWrite --- src/modules/extra/m_ssl_gnutls.cpp | 3 +-- src/modules/extra/m_ssl_mbedtls.cpp | 3 +-- src/modules/extra/m_ssl_openssl.cpp | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) (limited to 'src/modules/extra') diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index a1c989163..44a49d895 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -1086,7 +1086,7 @@ info_done_dealloc: } } - int OnStreamSocketWrite(StreamSocket* user) CXX11_OVERRIDE + int OnStreamSocketWrite(StreamSocket* user, StreamSocket::SendQueue& sendq) CXX11_OVERRIDE { // Finish handshake if needed int prepret = PrepareIO(user); @@ -1094,7 +1094,6 @@ info_done_dealloc: return prepret; // Session is ready for transferring application data - StreamSocket::SendQueue& sendq = user->GetSendQ(); #ifdef INSPIRCD_GNUTLS_HAS_CORK while (true) diff --git a/src/modules/extra/m_ssl_mbedtls.cpp b/src/modules/extra/m_ssl_mbedtls.cpp index 8578b8196..7efcce72d 100644 --- a/src/modules/extra/m_ssl_mbedtls.cpp +++ b/src/modules/extra/m_ssl_mbedtls.cpp @@ -698,7 +698,7 @@ class mbedTLSIOHook : public SSLIOHook } } - int OnStreamSocketWrite(StreamSocket* sock) CXX11_OVERRIDE + int OnStreamSocketWrite(StreamSocket* sock, StreamSocket::SendQueue& sendq) CXX11_OVERRIDE { // Finish handshake if needed int prepret = PrepareIO(sock); @@ -706,7 +706,6 @@ class mbedTLSIOHook : public SSLIOHook return prepret; // Session is ready for transferring application data - StreamSocket::SendQueue& sendq = sock->GetSendQ(); while (!sendq.empty()) { FlattenSendQueue(sendq, profile->GetOutgoingRecordSize()); diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 80c9d9395..5587f323a 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -656,7 +656,7 @@ class OpenSSLIOHook : public SSLIOHook } } - int OnStreamSocketWrite(StreamSocket* user) CXX11_OVERRIDE + int OnStreamSocketWrite(StreamSocket* user, StreamSocket::SendQueue& sendq) CXX11_OVERRIDE { // Finish handshake if needed int prepret = PrepareIO(user); @@ -666,7 +666,6 @@ class OpenSSLIOHook : public SSLIOHook data_to_write = true; // Session is ready for transferring application data - StreamSocket::SendQueue& sendq = user->GetSendQ(); while (!sendq.empty()) { ERR_clear_error(); -- cgit v1.3.1-10-gc9f91 From eef55acb1dbb2ae6c0202fec54e12506c064f892 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Mon, 8 Aug 2016 14:31:49 +0200 Subject: Add StreamSocket::GetModHook() for obtaining the IOHook belonging to a given module Use it to simplify logic in all modules using or providing IOHooks --- include/inspsocket.h | 6 ++++++ src/inspsocket.cpp | 10 ++++++++++ src/modules/extra/m_ssl_gnutls.cpp | 23 +++++++++++------------ src/modules/extra/m_ssl_mbedtls.cpp | 12 ++++-------- src/modules/extra/m_ssl_openssl.cpp | 12 ++++-------- src/modules/m_httpd.cpp | 2 +- src/modules/m_spanningtree/main.cpp | 4 ++-- 7 files changed, 38 insertions(+), 31 deletions(-) (limited to 'src/modules/extra') diff --git a/include/inspsocket.h b/include/inspsocket.h index 53eca2e91..72fb03d58 100644 --- a/include/inspsocket.h +++ b/include/inspsocket.h @@ -284,6 +284,12 @@ class CoreExport StreamSocket : public EventHandler virtual void Close(); /** This ensures that close is called prior to destructor */ virtual CullResult cull(); + + /** Get the IOHook of a module attached to this socket + * @param mod Module whose IOHook to return + * @return IOHook belonging to the module or NULL if the module haven't attached an IOHook to this socket + */ + IOHook* GetModHook(Module* mod) const; }; /** * BufferedSocket is an extendable socket class which modules diff --git a/src/inspsocket.cpp b/src/inspsocket.cpp index dcc455482..0b0507f7c 100644 --- a/src/inspsocket.cpp +++ b/src/inspsocket.cpp @@ -434,3 +434,13 @@ void StreamSocket::CheckError(BufferedSocketError errcode) OnError(errcode); } } + +IOHook* StreamSocket::GetModHook(Module* mod) const +{ + if (iohook) + { + if (iohook->prov->creator == mod) + return iohook; + } + return NULL; +} diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 44a49d895..dfd3b47dd 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -101,6 +101,8 @@ typedef gnutls_connection_end_t inspircd_gnutls_session_init_flags_t; #define INSPIRCD_GNUTLS_HAS_CORK #endif +static Module* thismod; + class RandGen : public HandlerBase2 { public: @@ -917,7 +919,7 @@ info_done_dealloc: { StreamSocket* sock = reinterpret_cast(session_wrap); #ifdef _WIN32 - GnuTLSIOHook* session = static_cast(sock->GetIOHook()); + GnuTLSIOHook* session = static_cast(sock->GetModHook(thismod)); #endif if (sock->GetEventMask() & FD_READ_WILL_BLOCK) @@ -954,7 +956,7 @@ info_done_dealloc: { StreamSocket* sock = reinterpret_cast(transportptr); #ifdef _WIN32 - GnuTLSIOHook* session = static_cast(sock->GetIOHook()); + GnuTLSIOHook* session = static_cast(sock->GetModHook(thismod)); #endif if (sock->GetEventMask() & FD_WRITE_WILL_BLOCK) @@ -989,7 +991,7 @@ info_done_dealloc: { StreamSocket* sock = reinterpret_cast(session_wrap); #ifdef _WIN32 - GnuTLSIOHook* session = static_cast(sock->GetIOHook()); + GnuTLSIOHook* session = static_cast(sock->GetModHook(thismod)); #endif if (sock->GetEventMask() & FD_WRITE_WILL_BLOCK) @@ -1172,7 +1174,7 @@ int GnuTLS::X509Credentials::cert_callback(gnutls_session_t sess, const gnutls_d st->key_type = GNUTLS_PRIVKEY_X509; #endif StreamSocket* sock = reinterpret_cast(gnutls_transport_get_ptr(sess)); - GnuTLS::X509Credentials& cred = static_cast(sock->GetIOHook())->GetProfile()->GetX509Credentials(); + GnuTLS::X509Credentials& cred = static_cast(sock->GetModHook(thismod))->GetProfile()->GetX509Credentials(); st->ncerts = cred.certs.size(); st->cert.x509 = cred.certs.raw(); @@ -1282,6 +1284,7 @@ class ModuleSSLGnuTLS : public Module #ifndef GNUTLS_HAS_RND gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); #endif + thismod = this; } void init() CXX11_OVERRIDE @@ -1317,7 +1320,7 @@ class ModuleSSLGnuTLS : public Module { LocalUser* user = IS_LOCAL(static_cast(item)); - if (user && user->eh.GetIOHook() && user->eh.GetIOHook()->prov->creator == this) + if ((user) && (user->eh.GetModHook(this))) { // User is using SSL, they're a local user, and they're using one of *our* SSL ports. // Potentially there could be multiple SSL modules loaded at once on different ports. @@ -1333,13 +1336,9 @@ class ModuleSSLGnuTLS : public Module ModResult OnCheckReady(LocalUser* user) CXX11_OVERRIDE { - if ((user->eh.GetIOHook()) && (user->eh.GetIOHook()->prov->creator == this)) - { - GnuTLSIOHook* iohook = static_cast(user->eh.GetIOHook()); - if (!iohook->IsHandshakeDone()) - return MOD_RES_DENY; - } - + const GnuTLSIOHook* const iohook = static_cast(user->eh.GetModHook(this)); + if ((iohook) && (!iohook->IsHandshakeDone())) + return MOD_RES_DENY; return MOD_RES_PASSTHRU; } }; diff --git a/src/modules/extra/m_ssl_mbedtls.cpp b/src/modules/extra/m_ssl_mbedtls.cpp index 7efcce72d..845d02aa3 100644 --- a/src/modules/extra/m_ssl_mbedtls.cpp +++ b/src/modules/extra/m_ssl_mbedtls.cpp @@ -894,7 +894,7 @@ class ModuleSSLmbedTLS : public Module return; LocalUser* user = IS_LOCAL(static_cast(item)); - if ((user) && (user->eh.GetIOHook()) && (user->eh.GetIOHook()->prov->creator == this)) + if ((user) && (user->eh.GetModHook(this))) { // User is using SSL, they're a local user, and they're using our IOHook. // Potentially there could be multiple SSL modules loaded at once on different ports. @@ -904,13 +904,9 @@ class ModuleSSLmbedTLS : public Module ModResult OnCheckReady(LocalUser* user) CXX11_OVERRIDE { - if ((user->eh.GetIOHook()) && (user->eh.GetIOHook()->prov->creator == this)) - { - mbedTLSIOHook* iohook = static_cast(user->eh.GetIOHook()); - if (!iohook->IsHandshakeDone()) - return MOD_RES_DENY; - } - + const mbedTLSIOHook* const iohook = static_cast(user->eh.GetModHook(this)); + if ((iohook) && (!iohook->IsHandshakeDone())) + return MOD_RES_DENY; return MOD_RES_PASSTHRU; } diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 5587f323a..4ad556438 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -909,7 +909,7 @@ class ModuleSSLOpenSSL : public Module { LocalUser* user = IS_LOCAL((User*)item); - if (user && user->eh.GetIOHook() && user->eh.GetIOHook()->prov->creator == this) + if ((user) && (user->eh.GetModHook(this))) { // User is using SSL, they're a local user, and they're using one of *our* SSL ports. // Potentially there could be multiple SSL modules loaded at once on different ports. @@ -920,13 +920,9 @@ class ModuleSSLOpenSSL : public Module ModResult OnCheckReady(LocalUser* user) CXX11_OVERRIDE { - if ((user->eh.GetIOHook()) && (user->eh.GetIOHook()->prov->creator == this)) - { - OpenSSLIOHook* iohook = static_cast(user->eh.GetIOHook()); - if (!iohook->IsHandshakeDone()) - return MOD_RES_DENY; - } - + const OpenSSLIOHook* const iohook = static_cast(user->eh.GetModHook(this)); + if ((iohook) && (!iohook->IsHandshakeDone())) + return MOD_RES_DENY; return MOD_RES_PASSTHRU; } diff --git a/src/modules/m_httpd.cpp b/src/modules/m_httpd.cpp index 760647d47..0b6b2e32b 100644 --- a/src/modules/m_httpd.cpp +++ b/src/modules/m_httpd.cpp @@ -413,7 +413,7 @@ class ModuleHttpServer : public Module { HttpServerSocket* sock = *i; ++i; - if (sock->GetIOHook() && sock->GetIOHook()->prov->creator == mod) + if (sock->GetModHook(mod)) { sock->cull(); delete sock; diff --git a/src/modules/m_spanningtree/main.cpp b/src/modules/m_spanningtree/main.cpp index 0b9bb65df..81543b0da 100644 --- a/src/modules/m_spanningtree/main.cpp +++ b/src/modules/m_spanningtree/main.cpp @@ -635,7 +635,7 @@ restart: for (TreeServer::ChildServers::const_iterator i = list.begin(); i != list.end(); ++i) { TreeSocket* sock = (*i)->GetSocket(); - if (sock->GetIOHook() && sock->GetIOHook()->prov->creator == mod) + if (sock->GetModHook(mod)) { sock->SendError("SSL module unloaded"); sock->Close(); @@ -647,7 +647,7 @@ restart: for (SpanningTreeUtilities::TimeoutList::const_iterator i = Utils->timeoutlist.begin(); i != Utils->timeoutlist.end(); ++i) { TreeSocket* sock = i->first; - if (sock->GetIOHook() && sock->GetIOHook()->prov->creator == mod) + if (sock->GetModHook(mod)) sock->Close(); } } -- cgit v1.3.1-10-gc9f91 From a86e320ac19fbbd6034d0447f048beb8b4a0ad1d Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Mon, 8 Aug 2016 16:42:54 +0200 Subject: m_ssl_* Add option to sslprofile controlling whether to request client certificates --- src/modules/extra/m_ssl_gnutls.cpp | 17 +++++++++++++---- src/modules/extra/m_ssl_mbedtls.cpp | 20 ++++++++++++++++---- src/modules/extra/m_ssl_openssl.cpp | 11 ++++++++++- 3 files changed, 39 insertions(+), 9 deletions(-) (limited to 'src/modules/extra') diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index dfd3b47dd..bda4e6a48 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -583,16 +583,21 @@ namespace GnuTLS */ const unsigned int outrecsize; + /** True to request a client certificate as a server + */ + const bool requestclientcert; + Profile(const std::string& profilename, const std::string& certstr, const std::string& keystr, std::auto_ptr& DH, unsigned int mindh, const std::string& hashstr, const std::string& priostr, std::auto_ptr& CA, std::auto_ptr& CRL, - unsigned int recsize) + unsigned int recsize, bool Requestclientcert) : name(profilename) , x509cred(certstr, keystr) , min_dh_bits(mindh) , hash(hashstr) , priority(priostr) , outrecsize(recsize) + , requestclientcert(Requestclientcert) { x509cred.SetDH(DH); x509cred.SetCA(CA, CRL); @@ -663,7 +668,10 @@ namespace GnuTLS #else unsigned int outrecsize = tag->getInt("outrecsize", 2048, 512, 16384); #endif - return new Profile(profilename, certstr, keystr, dh, mindh, hashstr, priostr, ca, crl, outrecsize); + + const bool requestclientcert = tag->getBool("requestclientcert", true); + + return new Profile(profilename, certstr, keystr, dh, mindh, hashstr, priostr, ca, crl, outrecsize, requestclientcert); } /** Set up the given session with the settings in this profile @@ -674,8 +682,9 @@ namespace GnuTLS x509cred.SetupSession(sess); gnutls_dh_set_prime_bits(sess, min_dh_bits); - // Request client certificate if we are a server, no-op if we're a client - gnutls_certificate_server_set_request(sess, GNUTLS_CERT_REQUEST); + // Request client certificate if enabled and we are a server, no-op if we're a client + if (requestclientcert) + gnutls_certificate_server_set_request(sess, GNUTLS_CERT_REQUEST); } const std::string& GetName() const { return name; } diff --git a/src/modules/extra/m_ssl_mbedtls.cpp b/src/modules/extra/m_ssl_mbedtls.cpp index 845d02aa3..a465d06ee 100644 --- a/src/modules/extra/m_ssl_mbedtls.cpp +++ b/src/modules/extra/m_ssl_mbedtls.cpp @@ -257,7 +257,6 @@ namespace mbedTLS mbedtls_debug_set_threshold(INT_MAX); mbedtls_ssl_conf_dbg(&conf, DebugLogFunc, NULL); #endif - mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); // TODO: check ret of mbedtls_ssl_config_defaults mbedtls_ssl_config_defaults(&conf, endpoint, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); @@ -308,6 +307,11 @@ namespace mbedTLS mbedtls_ssl_conf_ca_chain(&conf, certs.get(), crl.get()); } + void SetOptionalVerifyCert() + { + mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); + } + const mbedtls_ssl_config* GetConf() const { return &conf; } }; @@ -376,7 +380,8 @@ namespace mbedTLS const std::string& castr, const std::string& crlstr, unsigned int recsize, CTRDRBG& ctrdrbg, - int minver, int maxver + int minver, int maxver, + bool requestclientcert ) : name(profilename) , x509cred(certstr, keystr) @@ -414,7 +419,13 @@ namespace mbedTLS serverctx.SetDHParams(dhparams); } - serverctx.SetCA(cacerts, crl); + clientctx.SetOptionalVerifyCert(); + // The default for servers is to not request a client certificate from the peer + if (requestclientcert) + { + serverctx.SetOptionalVerifyCert(); + serverctx.SetCA(cacerts, crl); + } } static std::string ReadFile(const std::string& filename) @@ -451,7 +462,8 @@ namespace mbedTLS int minver = tag->getInt("minver"); int maxver = tag->getInt("maxver"); unsigned int outrecsize = tag->getInt("outrecsize", 2048, 512, 16384); - return new Profile(profilename, certstr, keystr, dhstr, mindh, hashstr, ciphersuitestr, curvestr, castr, crlstr, outrecsize, ctr_drbg, minver, maxver); + const bool requestclientcert = tag->getBool("requestclientcert", true); + return new Profile(profilename, certstr, keystr, dhstr, mindh, hashstr, ciphersuitestr, curvestr, castr, crlstr, outrecsize, ctr_drbg, minver, maxver, requestclientcert); } /** Set up the given session with the settings in this profile diff --git a/src/modules/extra/m_ssl_openssl.cpp b/src/modules/extra/m_ssl_openssl.cpp index 4ad556438..4df0d8962 100644 --- a/src/modules/extra/m_ssl_openssl.cpp +++ b/src/modules/extra/m_ssl_openssl.cpp @@ -132,7 +132,7 @@ namespace OpenSSL mode |= SSL_MODE_RELEASE_BUFFERS; #endif SSL_CTX_set_mode(ctx, mode); - SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, OnVerify); + SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); SSL_CTX_set_info_callback(ctx, StaticSSLInfoCallback); } @@ -206,6 +206,11 @@ namespace OpenSSL return SSL_CTX_clear_options(ctx, clearoptions); } + void SetVerifyCert() + { + SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, OnVerify); + } + SSL* CreateServerSession() { SSL* sess = SSL_new(ctx); @@ -345,6 +350,10 @@ namespace OpenSSL ERR_print_errors_cb(error_callback, this); ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "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", filename.c_str(), lasterr.c_str()); } + + clictx.SetVerifyCert(); + if (tag->getBool("requestclientcert", true)) + ctx.SetVerifyCert(); } const std::string& GetName() const { return name; } -- cgit v1.3.1-10-gc9f91