]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/extra/m_ssl_gnutls.cpp
Update wiki links to use HTTPS and point to the correct pages.
[user/henk/code/inspircd.git] / src / modules / extra / m_ssl_gnutls.cpp
index 4135194c58780a68b632ac57a479682d3780ed9a..2f4acf3f05edbb14454642940bf70fa37ae2759a 100644 (file)
 
 
 #include "inspircd.h"
-#ifndef _WIN32
-#include <gcrypt.h>
-#endif
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
 #include "ssl.h"
 #include "m_cap.h"
 
 #ifdef _WIN32
-# pragma comment(lib, "libgnutls-28.lib")
+# pragma comment(lib, "libgnutls-30.lib")
 #endif
 
 /* $ModDesc: Provides SSL support for clients */
-/* $CompileFlags: pkgconfincludes("gnutls","/gnutls/gnutls.h","") exec("libgcrypt-config --cflags") */
-/* $LinkerFlags: rpath("pkg-config --libs gnutls") pkgconflibs("gnutls","/libgnutls.so","-lgnutls") exec("libgcrypt-config --libs") */
+/* $CompileFlags: pkgconfincludes("gnutls","/gnutls/gnutls.h","") iflt("pkg-config --modversion gnutls","2.12") exec("libgcrypt-config --cflags") */
+/* $LinkerFlags: rpath("pkg-config --libs gnutls") pkgconflibs("gnutls","/libgnutls.so","-lgnutls") iflt("pkg-config --modversion gnutls","2.12") exec("libgcrypt-config --libs") */
 /* $NoPedantic */
 
 #ifndef GNUTLS_VERSION_MAJOR
@@ -55,7 +52,7 @@ typedef gnutls_certificate_credentials_t gnutls_certificate_credentials;
 typedef gnutls_dh_params_t gnutls_dh_params;
 #endif
 
-#if (defined(_WIN32) && (GNUTLS_VERSION_MAJOR > 2 || (GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR >= 12)))
+#if (GNUTLS_VERSION_MAJOR > 2 || (GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR >= 12))
 # define GNUTLS_HAS_RND
 # include <gnutls/crypto.h>
 #else
@@ -157,7 +154,7 @@ public:
        reference<ssl_cert> cert;
        reference<SSLConfig> config;
 
-       issl_session() : socket(NULL), sess(NULL) {}
+       issl_session() : socket(NULL), sess(NULL), status(ISSL_NONE) {}
 };
 
 static SSLConfig* GetSessionConfig(gnutls_session_t sess)
@@ -319,7 +316,7 @@ class ModuleSSLGnuTLS : public Module
                ServerInstance->GenRandom = &randhandler;
 
                Implementation eventlist[] = { I_On005Numeric, I_OnRehash, I_OnModuleRehash, I_OnUserConnect,
-                       I_OnEvent, I_OnHookIO };
+                       I_OnEvent, I_OnHookIO, I_OnCheckReady };
                ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
 
                ServerInstance->Modules->AddService(iohook);
@@ -419,6 +416,10 @@ class ModuleSSLGnuTLS : public Module
                        hash = GNUTLS_DIG_MD5;
                else if (hashname == "sha1")
                        hash = GNUTLS_DIG_SHA1;
+#ifdef INSPIRCD_GNUTLS_ENABLE_SHA256_FINGERPRINT
+               else if (hashname == "sha256")
+                       hash = GNUTLS_DIG_SHA256;
+#endif
                else
                        throw ModuleException("Unknown hash type " + hashname);
 
@@ -615,6 +616,12 @@ class ModuleSSLGnuTLS : public Module
 
                        req.cert = session->cert;
                }
+               else if (!strcmp("GET_RAW_SSL_SESSION", request.id))
+               {
+                       SSLRawSessionRequest& req = static_cast<SSLRawSessionRequest&>(request);
+                       if ((req.fd >= 0) && (req.fd < ServerInstance->SE->GetMaxFds()))
+                               req.data = reinterpret_cast<void*>(sessions[req.fd].sess);
+               }
        }
 
        void InitSession(StreamSocket* user, bool me_server)
@@ -696,6 +703,9 @@ class ModuleSSLGnuTLS : public Module
                        if (ret > 0)
                        {
                                recvq.append(buffer, ret);
+                               // Schedule a read if there is still data in the GnuTLS buffer
+                               if (gnutls_record_check_pending(session->sess) > 0)
+                                       ServerInstance->SE->ChangeEventMask(user, FD_ADD_TRIAL_READ);
                                return 1;
                        }
                        else if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
@@ -967,6 +977,13 @@ info_done_dealloc:
                if (starttls.enabled)
                        capHandler.HandleEvent(ev);
        }
+
+       ModResult OnCheckReady(LocalUser* user)
+       {
+               if ((user->eh.GetIOHook() == this) && (sessions[user->eh.GetFd()].status != ISSL_HANDSHAKEN))
+                       return MOD_RES_DENY;
+               return MOD_RES_PASSTHRU;
+       }
 };
 
 MODULE_INIT(ModuleSSLGnuTLS)