std::string certfile;
std::string cafile;
std::string crlfile;
+ std::string sslports;
int dh_bits;
int clientactive;
ModuleSSLGnuTLS(InspIRCd* Me)
: Module(Me)
{
- ServerInstance->PublishInterface("InspSocketHook", this);
+ ServerInstance->Modules->PublishInterface("InspSocketHook", this);
// Not rehashable...because I cba to reduce all the sizes of existing buffers.
inbufsize = ServerInstance->Config->NetBufferSize;
listenports.clear();
clientactive = 0;
+ sslports.clear();
for(int i = 0; i < Conf->Enumerate("bind"); i++)
{
// For each <bind> tag
std::string x = Conf->ReadValue("bind", "type", i);
- if(((x.empty()) || (x == "clients")) && (x == "gnutls"))
+ if(((x.empty()) || (x == "clients")) && (Conf->ReadValue("bind", "ssl", i) == "gnutls"))
{
// Get the port we're meant to be listening on with SSL
std::string port = Conf->ReadValue("bind", "port", i);
if (ServerInstance->Config->ports[i]->GetPort() == portno)
ServerInstance->Config->ports[i]->SetDescription("ssl");
ServerInstance->Log(DEFAULT, "m_ssl_gnutls.so: Enabling SSL for port %d", portno);
+ sslports.append("*:").append(ConvToStr(portno)).append(";");
}
else
{
if((ret = gnutls_certificate_set_x509_crl_file (x509_cred, crlfile.c_str(), GNUTLS_X509_FMT_PEM)) < 0)
ServerInstance->Log(DEFAULT, "m_ssl_gnutls.so: Failed to set X.509 CRL file '%s': %s", crlfile.c_str(), gnutls_strerror(ret));
- // Guessing on the return value of this, manual doesn't say :|
if((ret = gnutls_certificate_set_x509_key_file (x509_cred, certfile.c_str(), keyfile.c_str(), GNUTLS_X509_FMT_PEM)) < 0)
- ServerInstance->Log(DEFAULT, "m_ssl_gnutls.so: Failed to set X.509 certificate and key files '%s' and '%s': %s", certfile.c_str(), keyfile.c_str(), gnutls_strerror(ret));
+ {
+ // 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)));
+ }
// This may be on a large (once a day or week) timer eventually.
GenerateDHParams();
{
// 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->GlobalCulls.AddItem(user, "SSL module unloading");
+ userrec::QuitUser(ServerInstance, user, "SSL module unloading");
}
if (user->GetExt("ssl_cert", dummy) && isin(user->GetPort(), listenports))
{
void Implements(char* List)
{
- List[I_OnRawSocketConnect] = List[I_OnRawSocketAccept] = List[I_OnRawSocketClose] = List[I_OnRawSocketRead] = List[I_OnRawSocketWrite] = List[I_OnCleanup] = 1;
- List[I_OnRequest] = List[I_OnSyncUserMetaData] = List[I_OnDecodeMetaData] = List[I_OnUnloadModule] = List[I_OnRehash] = List[I_OnWhois] = List[I_OnPostConnect] = 1;
+ List[I_On005Numeric] = List[I_OnRawSocketConnect] = List[I_OnRawSocketAccept] = List[I_OnRawSocketClose] = List[I_OnRawSocketRead] = List[I_OnRawSocketWrite] = List[I_OnCleanup] = 1;
+ List[I_OnBufferFlushed] = List[I_OnRequest] = List[I_OnSyncUserMetaData] = List[I_OnDecodeMetaData] = List[I_OnUnloadModule] = List[I_OnRehash] = List[I_OnWhois] = List[I_OnPostConnect] = 1;
+ }
+
+ virtual void On005Numeric(std::string &output)
+ {
+ output.append(" SSL=" + sslports);
}
virtual char* OnRequest(Request* request)
virtual void OnRawSocketAccept(int fd, const std::string &ip, int localport)
{
+ /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
+ if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ return;
+
issl_session* session = &sessions[fd];
session->fd = fd;
virtual void OnRawSocketConnect(int fd)
{
+ /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
+ if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ return;
+
issl_session* session = &sessions[fd];
session->fd = fd;
virtual void OnRawSocketClose(int fd)
{
+ /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
+ if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ return;
+
CloseSession(&sessions[fd]);
EventHandler* user = ServerInstance->SE->GetRef(fd);
virtual int OnRawSocketRead(int fd, char* buffer, unsigned int count, int &readresult)
{
+ /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
+ if ((fd < 0) || (fd > MAX_DESCRIPTORS))
+ return 0;
+
issl_session* session = &sessions[fd];
if (!session->sess)
else if (session->status == ISSL_HANDSHAKING_WRITE)
{
errno = EAGAIN;
+ MakePollWrite(session);
return -1;
}
virtual int OnRawSocketWrite(int fd, const char* buffer, int count)
{
- if (!count)
+ /* Are there any possibilities of an out of range fd? Hope not, but lets be paranoid */
+ if ((fd < 0) || (fd > MAX_DESCRIPTORS))
return 0;
issl_session* session = &sessions[fd];
sendbuffer = session->outbuf.c_str();
count = session->outbuf.size();
- if(session->status == ISSL_HANDSHAKING_WRITE)
+ if (session->status == ISSL_HANDSHAKING_WRITE)
{
// The handshake isn't finished, try to finish it.
Handshake(session);
int ret = 0;
- if(session->status == ISSL_HANDSHAKEN)
+ if (session->status == ISSL_HANDSHAKEN)
{
ret = gnutls_record_send(session->sess, sendbuffer, count);
- if(ret == 0)
+ if (ret == 0)
{
CloseSession(session);
}
else
{
errno = EAGAIN;
- return -1;
}
}
else
}
}
+ MakePollWrite(session);
+
/* Who's smart idea was it to return 1 when we havent written anything?
* This fucks the buffer up in InspSocket :p
*/
virtual void OnPostConnect(userrec* user)
{
// This occurs AFTER OnUserConnect so we can be sure the
- // protocol module has propogated the NICK message.
+ // protocol module has propagated the NICK message.
if ((user->GetExt("ssl", dummy)) && (IS_LOCAL(user)))
{
// Tell whatever protocol module we're using that we need to inform other servers of this metadata NOW.
void MakePollWrite(issl_session* session)
{
- OnRawSocketWrite(session->fd, NULL, 0);
+ //OnRawSocketWrite(session->fd, NULL, 0);
+ EventHandler* eh = ServerInstance->FindDescriptor(session->fd);
+ if (eh)
+ ServerInstance->SE->WantWrite(eh);
+ }
+
+ virtual void OnBufferFlushed(userrec* user)
+ {
+ if (user->GetExt("ssl"))
+ {
+ issl_session* session = &sessions[user->GetFd()];
+ if (session && session->outbuf.size())
+ OnRawSocketWrite(user->GetFd(), NULL, 0);
+ }
}
void CloseSession(issl_session* session)
};
-class ModuleSSLGnuTLSFactory : public ModuleFactory
-{
- public:
- ModuleSSLGnuTLSFactory()
- {
- }
-
- ~ModuleSSLGnuTLSFactory()
- {
- }
-
- virtual Module * CreateModule(InspIRCd* Me)
- {
- return new ModuleSSLGnuTLS(Me);
- }
-};
-
-
-extern "C" DllExport void * init_module( void )
-{
- return new ModuleSSLGnuTLSFactory;
-}
+MODULE_INIT(ModuleSSLGnuTLS);