]> git.netwichtig.de Git - user/henk/code/inspircd.git/blobdiff - src/modules/extra/m_ssl_gnutls.cpp
MetaData rework
[user/henk/code/inspircd.git] / src / modules / extra / m_ssl_gnutls.cpp
index c81be9f7bb16f476f4f9399dac0947ccf5f7252a..a769bd12bfae55aadb200b1b2ce5775974e7c3ab 100644 (file)
@@ -81,7 +81,7 @@ class CommandStartTLS : public Command
                        {
                                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());
+                               Caller->OnRawSocketAccept(user->GetFd(), NULL, NULL);
                        }
                        else
                                user->WriteNumeric(691, "%s :STARTTLS failure", user->nick.c_str());
@@ -110,12 +110,12 @@ class ModuleSSLGnuTLS : public Module
        int clientactive;
        bool cred_alloc;
 
-       CommandStartTLS* starttls;
+       CommandStartTLS starttls;
 
  public:
 
        ModuleSSLGnuTLS(InspIRCd* Me)
-               : Module(Me)
+               : Module(Me), starttls(Me, this)
        {
                ServerInstance->Modules->PublishInterface("BufferedSocketHook", this);
 
@@ -135,8 +135,7 @@ class ModuleSSLGnuTLS : public Module
                        I_OnPostConnect, I_OnEvent, I_OnHookUserIO };
                ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
 
-               starttls = new CommandStartTLS(ServerInstance, this);
-               ServerInstance->AddCommand(starttls);
+               ServerInstance->AddCommand(&starttls);
        }
 
        virtual void OnRehash(User* user)
@@ -255,16 +254,16 @@ class ModuleSSLGnuTLS : public Module
                        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));
+                       ServerInstance->Logs->Log("m_ssl_gnutls",DEBUG, "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));
+                       ServerInstance->Logs->Log("m_ssl_gnutls",DEBUG, "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));
+                       ServerInstance->Logs->Log("m_ssl_gnutls",DEBUG, "m_ssl_gnutls.so: Failed to set X.509 trust file '%s': %s", cafile.c_str(), gnutls_strerror(ret));
 
                if((ret = gnutls_certificate_set_x509_crl_file (x509_cred, crlfile.c_str(), GNUTLS_X509_FMT_PEM)) < 0)
-                       ServerInstance->Logs->Log("m_ssl_gnutls",DEFAULT, "m_ssl_gnutls.so: Failed to set X.509 CRL file '%s': %s", crlfile.c_str(), gnutls_strerror(ret));
+                       ServerInstance->Logs->Log("m_ssl_gnutls",DEBUG, "m_ssl_gnutls.so: Failed to set X.509 CRL file '%s': %s", crlfile.c_str(), gnutls_strerror(ret));
 
                if((ret = gnutls_certificate_set_x509_key_file (x509_cred, certfile.c_str(), keyfile.c_str(), GNUTLS_X509_FMT_PEM)) < 0)
                {
@@ -302,7 +301,7 @@ class ModuleSSLGnuTLS : public Module
        {
                if(target_type == TYPE_USER)
                {
-                       User* user = (User*)item;
+                       User* user = static_cast<User*>(item);
 
                        if (user->GetIOHook() == this)
                        {
@@ -347,9 +346,9 @@ class ModuleSSLGnuTLS : public Module
                output.append(" STARTTLS");
        }
 
-       virtual void OnHookUserIO(User* user, const std::string &targetip)
+       virtual void OnHookUserIO(User* user)
        {
-               if (!user->GetIOHook() && isin(targetip,user->GetPort(),listenports))
+               if (!user->GetIOHook() && isin(user->GetServerIP(),user->GetServerPort(),listenports))
                {
                        /* Hook the user with our module */
                        user->AddIOHook(this);
@@ -358,7 +357,7 @@ class ModuleSSLGnuTLS : public Module
 
        virtual const char* OnRequest(Request* request)
        {
-               ISHRequest* ISR = (ISHRequest*)request;
+               ISHRequest* ISR = static_cast<ISHRequest*>(request);
                if (strcmp("IS_NAME", request->GetId()) == 0)
                {
                        return "gnutls";
@@ -368,7 +367,7 @@ class ModuleSSLGnuTLS : public Module
                        const char* ret = "OK";
                        try
                        {
-                               ret = ISR->Sock->AddIOHook((Module*)this) ? "OK" : NULL;
+                               ret = ISR->Sock->AddIOHook(this) ? "OK" : NULL;
                        }
                        catch (ModuleException &e)
                        {
@@ -395,9 +394,9 @@ class ModuleSSLGnuTLS : public Module
                                issl_session* session = &sessions[ISR->Sock->GetFd()];
                                if (session->sess)
                                {
-                                       if ((Extensible*)ServerInstance->SE->GetRef(ISR->Sock->GetFd()) == (Extensible*)(ISR->Sock))
+                                       if (static_cast<Extensible*>(ServerInstance->SE->GetRef(ISR->Sock->GetFd())) == static_cast<Extensible*>(ISR->Sock))
                                        {
-                                               VerifyCertificate(session, (BufferedSocket*)ISR->Sock);
+                                               VerifyCertificate(session, ISR->Sock);
                                                return "OK";
                                        }
                                }
@@ -421,7 +420,7 @@ class ModuleSSLGnuTLS : public Module
        }
 
 
-       virtual void OnRawSocketAccept(int fd, const std::string &ip, int localport)
+       virtual void OnRawSocketAccept(int fd, irc::sockets::sockaddrs* client, irc::sockets::sockaddrs* server)
        {
                /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
                if ((fd < 0) || (fd > ServerInstance->SE->GetMaxFds() - 1))
@@ -439,7 +438,7 @@ class ModuleSSLGnuTLS : public Module
                gnutls_credentials_set(session->sess, GNUTLS_CRD_CERTIFICATE, x509_cred);
                gnutls_dh_set_prime_bits(session->sess, dh_bits);
 
-               gnutls_transport_set_ptr(session->sess, (gnutls_transport_ptr_t) fd); // Give gnutls the fd for the socket.
+               gnutls_transport_set_ptr(session->sess, reinterpret_cast<gnutls_transport_ptr_t>(fd)); // Give gnutls the fd for the socket.
 
                gnutls_certificate_server_set_request(session->sess, GNUTLS_CERT_REQUEST); // Request client certificate if any.
 
@@ -459,7 +458,7 @@ class ModuleSSLGnuTLS : public Module
                gnutls_set_default_priority(session->sess); // Avoid calling all the priority functions, defaults are adequate.
                gnutls_credentials_set(session->sess, GNUTLS_CRD_CERTIFICATE, x509_cred);
                gnutls_dh_set_prime_bits(session->sess, dh_bits);
-               gnutls_transport_set_ptr(session->sess, (gnutls_transport_ptr_t) fd); // Give gnutls the fd for the socket.
+               gnutls_transport_set_ptr(session->sess, reinterpret_cast<gnutls_transport_ptr_t>(fd)); // Give gnutls the fd for the socket.
 
                Handshake(session, fd);
        }
@@ -520,34 +519,43 @@ class ModuleSSLGnuTLS : public Module
 
                if (session->status == ISSL_HANDSHAKEN)
                {
-                       int ret = gnutls_record_recv(session->sess, buffer, count);
-
-                       if (ret > 0)
+                       unsigned int len = 0;
+                       while (len < count)
                        {
-                               readresult = ret;
+                               int ret = gnutls_record_recv(session->sess, buffer + len, count - len);
+                               if (ret > 0)
+                               {
+                                       len += ret;
+                               }
+                               else if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
+                               {
+                                       break;
+                               }
+                               else
+                               {
+                                       if (ret != 0)
+                                               ServerInstance->Logs->Log("m_ssl_gnutls", DEFAULT,
+                                                       "m_ssl_gnutls.so: Error while reading on fd %d: %s",
+                                                       fd, gnutls_strerror(ret));
+
+                                       // if ret == 0, client closed connection.
+                                       readresult = 0;
+                                       CloseSession(session);
+                                       return 1;
+                               }
                        }
-                       else if (ret == 0)
+                       readresult = len;
+                       if (len)
                        {
-                               // Client closed connection.
-                               readresult = 0;
-                               CloseSession(session);
                                return 1;
                        }
-                       else if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED)
+                       else
                        {
                                errno = EAGAIN;
                                return -1;
                        }
-                       else
-                       {
-                               ServerInstance->Logs->Log("m_ssl_gnutls", DEFAULT,
-                                               "m_ssl_gnutls.so: Error while reading on fd %d: %s",
-                                               fd, gnutls_strerror(ret));
-                               readresult = 0;
-                               CloseSession(session);
-                       }
                }
-               else if(session->status == ISSL_CLOSING)
+               else if (session->status == ISSL_CLOSING)
                        readresult = 0;
 
                return 1;
@@ -610,7 +618,8 @@ class ModuleSSLGnuTLS : public Module
                        }
                }
 
-               MakePollWrite(fd);
+               if (!session->outbuf.empty())
+                       MakePollWrite(fd);
 
                /* Who's smart idea was it to return 1 when we havent written anything?
                 * This fucks the buffer up in BufferedSocket :p
@@ -688,9 +697,9 @@ class ModuleSSLGnuTLS : public Module
                                user->WriteServ("NOTICE %s :*** You are connected using SSL cipher \"%s\"", user->nick.c_str(), cipher.c_str());
                        }
 
-                       ServerInstance->PI->SendMetaData(user, TYPE_USER, "ssl", "ON");
+                       ServerInstance->PI->SendMetaData(user, "ssl", "ON");
                        if (certdata)
-                               ServerInstance->PI->SendMetaData(user, TYPE_USER, "ssl_cert", certdata->GetMetaLine().c_str());
+                               ServerInstance->PI->SendMetaData(user, "ssl_cert", certdata->GetMetaLine().c_str());
                }
        }