issl_io_status wstat;
unsigned int inbufoffset;
- char* inbuf; // Buffer OpenSSL reads into.
+ char* inbuf; // Buffer OpenSSL reads into.
std::string outbuf; // Buffer for outgoing data that OpenSSL will not take.
int fd;
bool outbound;
class ModuleSSLOpenSSL : public Module
{
-
- ConfigReader* Conf;
-
std::vector<int> listenports;
int inbufsize;
InspIRCd* PublicInstance;
ModuleSSLOpenSSL(InspIRCd* Me)
- : Module(Me), PublicInstance(Me)
+ : Module(Me), PublicInstance(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;
if (param != "ssl")
return;
- Conf = new ConfigReader(ServerInstance);
+ ConfigReader Conf(ServerInstance);
for (unsigned int i = 0; i < listenports.size(); i++)
{
clientactive = 0;
sslports.clear();
- for (int i = 0; i < Conf->Enumerate("bind"); i++)
+ 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")) && (Conf->ReadValue("bind", "ssl", i) == "openssl"))
+ std::string x = Conf.ReadValue("bind", "type", i);
+ if (((x.empty()) || (x == "clients")) && (Conf.ReadValue("bind", "ssl", i) == "openssl"))
{
// Get the port we're meant to be listening on with SSL
- std::string port = Conf->ReadValue("bind", "port", i);
+ std::string port = Conf.ReadValue("bind", "port", i);
irc::portparser portrange(port, false);
long portno = -1;
while ((portno = portrange.GetToken()))
// +1 so we the path ends with a /
confdir = confdir.substr(0, confdir.find_last_of('/') + 1);
- cafile = Conf->ReadValue("openssl", "cafile", 0);
- certfile = Conf->ReadValue("openssl", "certfile", 0);
- keyfile = Conf->ReadValue("openssl", "keyfile", 0);
- dhfile = Conf->ReadValue("openssl", "dhfile", 0);
+ cafile = Conf.ReadValue("openssl", "cafile", 0);
+ certfile = Conf.ReadValue("openssl", "certfile", 0);
+ keyfile = Conf.ReadValue("openssl", "keyfile", 0);
+ dhfile = Conf.ReadValue("openssl", "dhfile", 0);
// Set all the default values needed.
if (cafile.empty())
}
fclose(dhpfile);
-
- DELETE(Conf);
}
virtual void On005Numeric(std::string &output)
void Implements(char* List)
{
List[I_OnRawSocketConnect] = List[I_OnRawSocketAccept] = List[I_OnRawSocketClose] = List[I_OnRawSocketRead] = List[I_OnRawSocketWrite] = List[I_OnCleanup] = List[I_On005Numeric] = 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_OnBufferFlushed] = List[I_OnRequest] = List[I_OnSyncUserMetaData] = List[I_OnDecodeMetaData] = List[I_OnUnloadModule] = List[I_OnRehash] = List[I_OnWhois] = List[I_OnPostConnect] = 1;
}
virtual char* OnRequest(Request* request)
virtual void OnRawSocketConnect(int fd)
{
- ServerInstance->Log(DEBUG,"OnRawSocketConnect connecting");
issl_session* session = &sessions[fd];
session->fd = fd;
}
Handshake(session);
- ServerInstance->Log(DEBUG,"Exiting OnRawSocketConnect");
}
virtual void OnRawSocketClose(int fd)
{
issl_session* session = &sessions[fd];
- ServerInstance->Log(DEBUG,"OnRawSocketRead");
-
if (!session->sess)
{
- ServerInstance->Log(DEBUG,"OnRawSocketRead has no session");
readresult = 0;
CloseSession(session);
return 1;
{
if (session->rstat == ISSL_READ || session->wstat == ISSL_READ)
{
- ServerInstance->Log(DEBUG,"Resume handshake in read");
// The handshake isn't finished and it wants to read, try to finish it.
if (!Handshake(session))
{
- ServerInstance->Log(DEBUG,"Cant resume handshake in read");
// Couldn't resume handshake.
return -1;
}
{
int ret = DoRead(session);
+ ServerInstance->Log(DEBUG, "<***> DoRead count: " + ConvToStr(count));
+ ServerInstance->Log(DEBUG, "<***> DoRead ret: " + ConvToStr(ret));
+ ServerInstance->Log(DEBUG, "<***> DoRead session->inbufoffset: " + ConvToStr(session->inbufoffset));
+
if (ret > 0)
{
if (count <= session->inbufoffset)
if (!session->sess)
{
- ServerInstance->Log(DEBUG,"Close session missing sess");
CloseSession(session);
return -1;
}
session->outbuf.append(buffer, count);
+ MakePollWrite(session);
if (session->status == ISSL_HANDSHAKING)
{
// The handshake isn't finished, try to finish it.
if (session->rstat == ISSL_WRITE || session->wstat == ISSL_WRITE)
{
- ServerInstance->Log(DEBUG,"Handshake resume");
Handshake(session);
}
}
{
if (session->rstat == ISSL_WRITE)
{
- ServerInstance->Log(DEBUG,"DoRead");
DoRead(session);
}
if (session->wstat == ISSL_WRITE)
{
- ServerInstance->Log(DEBUG,"DoWrite");
return DoWrite(session);
}
}
if (ret == 0)
{
- ServerInstance->Log(DEBUG,"Oops, got 0 from SSL_write");
CloseSession(session);
return 0;
}
if (err == SSL_ERROR_WANT_WRITE)
{
session->wstat = ISSL_WRITE;
- MakePollWrite(session);
return -1;
}
else if (err == SSL_ERROR_WANT_READ)
}
else
{
- ServerInstance->Log(DEBUG,"Close due to returned -1 in SSL_Write");
CloseSession(session);
return 0;
}
// Is this right? Not sure if the unencrypted data is garaunteed to be the same length.
// Read into the inbuffer, offset from the beginning by the amount of data we have that insp hasn't taken yet.
- ServerInstance->Log(DEBUG,"DoRead");
-
int ret = SSL_read(session->sess, session->inbuf + session->inbufoffset, inbufsize - session->inbufoffset);
if (ret == 0)
{
// Client closed connection.
- ServerInstance->Log(DEBUG,"Oops, got 0 from SSL_read");
CloseSession(session);
return 0;
}
if (err == SSL_ERROR_WANT_READ)
{
session->rstat = ISSL_READ;
- ServerInstance->Log(DEBUG,"Setting want_read");
return -1;
}
else if (err == SSL_ERROR_WANT_WRITE)
{
session->rstat = ISSL_WRITE;
MakePollWrite(session);
- ServerInstance->Log(DEBUG,"Setting want_write");
return -1;
}
else
{
- ServerInstance->Log(DEBUG,"Closed due to returned -1 in SSL_Read");
CloseSession(session);
return 0;
}
bool Handshake(issl_session* session)
{
- ServerInstance->Log(DEBUG,"Handshake");
int ret;
if (session->outbound)
{
- ServerInstance->Log(DEBUG,"SSL_connect");
ret = SSL_connect(session->sess);
}
else
if (err == SSL_ERROR_WANT_READ)
{
- ServerInstance->Log(DEBUG,"Want read, handshaking");
session->rstat = ISSL_READ;
session->status = ISSL_HANDSHAKING;
return true;
}
else if (err == SSL_ERROR_WANT_WRITE)
{
- ServerInstance->Log(DEBUG,"Want write, handshaking");
session->wstat = ISSL_WRITE;
session->status = ISSL_HANDSHAKING;
MakePollWrite(session);
}
else
{
- ServerInstance->Log(DEBUG,"Handshake failed");
CloseSession(session);
}
ServerInstance->SE->WantWrite(eh);
}
+ virtual void OnBufferFlushed(userrec* user)
+ {
+ if (user->GetExt("ssl"))
+ {
+ ServerInstance->Log(DEBUG,"OnBufferFlushed for ssl user");
+ issl_session* session = &sessions[user->GetFd()];
+ if (session && session->outbuf.size())
+ OnRawSocketWrite(user->GetFd(), NULL, 0);
+ }
+ }
+
void CloseSession(issl_session* session)
{
if (session->sess)
}
MODULE_INIT(ModuleSSLOpenSSL);
-