X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fmodules%2Fextra%2Fm_ssl_gnutls.cpp;h=adbd48fb64dcf44ebb74c8a63dde347d7a3ce6bc;hb=dd9ba46a3c4daa650ae080a73a650521b1f5fcf4;hp=91f29189e0c788e49254295d7db6f7984a76d0b0;hpb=e7b837ec5f120f928a0dc321fa918bdd01ab0c02;p=user%2Fhenk%2Fcode%2Finspircd.git diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 91f29189e..adbd48fb6 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -12,17 +12,8 @@ */ #include "inspircd.h" - #include #include - -#include "inspircd_config.h" -#include "configreader.h" -#include "users.h" -#include "channels.h" -#include "modules.h" -#include "socket.h" -#include "hashcomp.h" #include "transport.h" #include "m_cap.h" @@ -55,6 +46,11 @@ bool isin(const std::string &host, int port, const std::vector &por class issl_session : public classbase { public: + issl_session() + { + sess = NULL; + } + gnutls_session_t sess; issl_status status; std::string outbuf; @@ -81,8 +77,14 @@ class CommandStartTLS : public Command } else { - user->io = Caller; - Caller->OnRawSocketAccept(user->GetFd(), user->GetIPString(), user->GetPort()); + if (!user->GetIOHook()) + { + user->WriteNumeric(670, "%s :STARTTLS successful, go ahead with TLS handshake", user->nick.c_str()); + user->AddIOHook(Caller); + Caller->OnRawSocketAccept(user->GetFd(), user->GetIPString(), user->GetPort()); + } + else + user->WriteNumeric(671, "%s :STARTTLS failure", user->nick.c_str()); } return CMD_FAILURE; @@ -112,6 +114,7 @@ class ModuleSSLGnuTLS : public Module int dh_bits; int clientactive; + bool cred_alloc; CommandStartTLS* starttls; @@ -129,13 +132,7 @@ class ModuleSSLGnuTLS : public Module gnutls_global_init(); // This must be called once in the program - if(gnutls_certificate_allocate_credentials(&x509_cred) != 0) - ServerInstance->Logs->Log("m_ssl_gnutls",DEFAULT, "m_ssl_gnutls.so: Failed to allocate certificate credentials"); - - // Guessing return meaning - if(gnutls_dh_params_init(&dh_params) < 0) - ServerInstance->Logs->Log("m_ssl_gnutls",DEFAULT, "m_ssl_gnutls.so: Failed to initialise DH parameters"); - + cred_alloc = false; // Needs the flag as it ignores a plain /rehash OnRehash(NULL,"ssl"); @@ -240,7 +237,22 @@ class ModuleSSLGnuTLS : public Module keyfile = confdir + keyfile; int ret; - + + if (cred_alloc) + { + // Deallocate the old credentials + gnutls_dh_params_deinit(dh_params); + gnutls_certificate_free_credentials(x509_cred); + } + else + cred_alloc = true; + + if((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) + ServerInstance->Logs->Log("m_ssl_gnutls",DEFAULT, "m_ssl_gnutls.so: Failed to allocate certificate credentials: %s", gnutls_strerror(ret)); + + if((ret = gnutls_dh_params_init(&dh_params)) < 0) + ServerInstance->Logs->Log("m_ssl_gnutls",DEFAULT, "m_ssl_gnutls.so: Failed to initialise DH parameters: %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",DEFAULT, "m_ssl_gnutls.so: Failed to set X.509 trust file '%s': %s", cafile.c_str(), gnutls_strerror(ret)); @@ -250,7 +262,7 @@ class ModuleSSLGnuTLS : public Module if((ret = gnutls_certificate_set_x509_key_file (x509_cred, certfile.c_str(), keyfile.c_str(), GNUTLS_X509_FMT_PEM)) < 0) { // If this fails, no SSL port will work. At all. So, do the smart thing - throw a ModuleException - throw ModuleException("Unable to load GnuTLS server certificate: " + std::string(gnutls_strerror(ret))); + throw ModuleException("Unable to load GnuTLS server certificate (" + std::string(certfile) + ", key: " + keyfile + "): " + std::string(gnutls_strerror(ret))); } // This may be on a large (once a day or week) timer eventually. @@ -287,11 +299,12 @@ class ModuleSSLGnuTLS : public Module { User* user = (User*)item; - if(user->io) + if (user->GetIOHook() == 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. ServerInstance->Users->QuitUser(user, "SSL module unloading"); + user->DelIOHook(); } if (user->GetExt("ssl_cert", dummy)) { @@ -300,8 +313,6 @@ class ModuleSSLGnuTLS : public Module delete tofree; user->Shrink("ssl_cert"); } - - user->io = NULL; } } @@ -320,7 +331,7 @@ class ModuleSSLGnuTLS : public Module virtual Version GetVersion() { - return Version(1, 2, 0, 0, VF_VENDOR, API_VERSION); + return Version("$Id$", VF_VENDOR, API_VERSION); } @@ -331,10 +342,10 @@ class ModuleSSLGnuTLS : public Module virtual void OnHookUserIO(User* user, const std::string &targetip) { - if (!user->io && isin(targetip,user->GetPort(),listenports)) + if (!user->GetIOHook() && isin(targetip,user->GetPort(),listenports)) { /* Hook the user with our module */ - user->io = this; + user->AddIOHook(this); } } @@ -350,7 +361,7 @@ class ModuleSSLGnuTLS : public Module const char* ret = "OK"; try { - ret = ServerInstance->Config->AddIOHook((Module*)this, (BufferedSocket*)ISR->Sock) ? "OK" : NULL; + ret = ISR->Sock->AddIOHook((Module*)this) ? "OK" : NULL; } catch (ModuleException &e) { @@ -360,7 +371,7 @@ class ModuleSSLGnuTLS : public Module } else if (strcmp("IS_UNHOOK", request->GetId()) == 0) { - return ServerInstance->Config->DelIOHook((BufferedSocket*)ISR->Sock) ? "OK" : NULL; + return ISR->Sock->DelIOHook() ? "OK" : NULL; } else if (strcmp("IS_HSDONE", request->GetId()) == 0) { @@ -539,7 +550,7 @@ class ModuleSSLGnuTLS : public Module { memcpy(buffer, session->inbuf, count); // Move the stuff left in inbuf to the beginning of it - memcpy(session->inbuf, session->inbuf + count, (length - count)); + memmove(session->inbuf, session->inbuf + count, (length - count)); // Now we need to set session->inbufoffset to the amount of data still waiting to be handed to insp. session->inbufoffset = length - count; // Insp uses readresult as the count of how much data there is in buffer, so: @@ -631,7 +642,7 @@ class ModuleSSLGnuTLS : public Module return; // Bugfix, only send this numeric for *our* SSL users - if (dest->GetExt("ssl", dummy) || ((IS_LOCAL(dest) && (dest->io == this)))) + if (dest->GetExt("ssl", dummy) || ((IS_LOCAL(dest) && (dest->GetIOHook() == this)))) { ServerInstance->SendWhoisLine(source, dest, 320, "%s %s :is using a secure connection", source->nick.c_str(), dest->nick.c_str()); } @@ -907,7 +918,7 @@ class ModuleSSLGnuTLS : public Module GenericCapHandler(ev, "tls", "tls"); } - void Prioritize() + void Prioritize() { Module* server = ServerInstance->Modules->Find("m_spanningtree.so"); ServerInstance->Modules->SetPriority(this, I_OnPostConnect, PRIO_AFTER, &server);