diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libtdekrb/src/tdekrbclientsocket.cpp | 64 | ||||
-rw-r--r-- | lib/libtdekrb/src/tdekrbclientsocket.h | 5 | ||||
-rw-r--r-- | lib/libtdekrb/src/tdekrbserversocket.cpp | 60 | ||||
-rw-r--r-- | lib/libtdekrb/src/tdekrbserversocket.h | 5 |
4 files changed, 108 insertions, 26 deletions
diff --git a/lib/libtdekrb/src/tdekrbclientsocket.cpp b/lib/libtdekrb/src/tdekrbclientsocket.cpp index 9ea30fa..2736f5a 100644 --- a/lib/libtdekrb/src/tdekrbclientsocket.cpp +++ b/lib/libtdekrb/src/tdekrbclientsocket.cpp @@ -32,6 +32,20 @@ #define NET_SEC_BUF_SIZE (2048) +// When control comes back from processEvents() my object may be completely gone! This attempts to mitigate the risk +#define SAFELY_PROCESS_EVENTS if (!m_canary) { \ + m_canary = new bool; \ + *m_canary = false; \ + } \ + bool* canary = m_canary; \ + tqApp->processEvents(); \ + if (*canary == true) { \ + delete canary; \ + return -1; \ + } \ + delete m_canary; \ + m_canary = NULL; + /* exception handling */ struct exit_exception { int c; @@ -79,7 +93,7 @@ static int logSASLMessages(void *context __attribute__((unused)), int priority, return SASL_OK; } -TDEKerberosClientSocket::TDEKerberosClientSocket(TQObject *parent, const char *name) : TQSocket(parent, name), m_kerberosRequested(false), m_criticalSection(0), m_bufferLength(0), m_negotiatedMaxBufferSize(NET_SEC_BUF_SIZE) { +TDEKerberosClientSocket::TDEKerberosClientSocket(TQObject *parent, const char *name) : TQSocket(parent, name), m_kerberosRequested(false), m_criticalSection(0), m_bufferLength(0), m_canary(NULL), m_negotiatedMaxBufferSize(NET_SEC_BUF_SIZE) { saslData = new SASLDataPrivate; saslData->m_krbConnection = NULL; m_buffer = new TQBuffer(); @@ -87,6 +101,9 @@ TDEKerberosClientSocket::TDEKerberosClientSocket(TQObject *parent, const char *n } TDEKerberosClientSocket::~TDEKerberosClientSocket() { + if (m_canary) { + *m_canary = true; + } m_buffer->close(); delete m_buffer; delete saslData; @@ -102,9 +119,6 @@ bool TDEKerberosClientSocket::open(int mode) { void TDEKerberosClientSocket::close() { TQSocket::close(); - if (m_criticalSection > 0) { - throw exit_exception(-1); - } } void TDEKerberosClientSocket::flush() { @@ -221,6 +235,10 @@ TQ_LONG TDEKerberosClientSocket::readBlock(char *data, TQ_ULONG maxlen) { int wrlen; char* buf = (char*)malloc(m_negotiatedMaxBufferSize); reclen = receiveEncryptedData(buf, m_negotiatedMaxBufferSize); + if (reclen < 0) { + free(buf); + return -1; + } if (reclen > 0) { m_buffer->at(m_bufferLength); wrlen = m_buffer->writeBlock(buf, reclen); @@ -278,6 +296,10 @@ TQ_LONG TDEKerberosClientSocket::readLine(char *data, TQ_ULONG maxlen) { int wrlen; char* buf = (char*)malloc(m_negotiatedMaxBufferSize); reclen = receiveEncryptedData(buf, m_negotiatedMaxBufferSize); + if (reclen < 0) { + free(buf); + return -1; + } if (reclen > 0) { m_buffer->at(m_bufferLength); wrlen = m_buffer->writeBlock(buf, reclen); @@ -325,6 +347,10 @@ TQString TDEKerberosClientSocket::readLine() { maxlen = m_negotiatedMaxBufferSize; char* buf = (char*)malloc(m_negotiatedMaxBufferSize); reclen = receiveEncryptedData(buf, m_negotiatedMaxBufferSize); + if (reclen < 0) { + free(buf); + return TQString::null; + } if (reclen > 0) { m_buffer->at(m_bufferLength); wrlen = m_buffer->writeBlock(buf, reclen); @@ -410,17 +436,25 @@ void TDEKerberosClientSocket::sendSASLDataToNetwork(const char *buffer, unsigned free(buf); } -int TDEKerberosClientSocket::getSASLDataFromNetwork(char *buf, int trunclen) { +int TDEKerberosClientSocket::getSASLDataFromNetwork(char *buf, int trunclen, bool shouldblock) { m_criticalSection++; try { unsigned int len; int result; - + TQByteArray ba(2048); - + + if (!shouldblock) { + if ((!TQSocket::canReadLine()) || (state() != TQSocket::Connected)) { + return 0; + } + } + len = 0; while (1) { - tqApp->processEvents(); + if (shouldblock) { + SAFELY_PROCESS_EVENTS + } if (state() != TQSocket::Connected) { m_criticalSection--; return -1; @@ -435,7 +469,13 @@ int TDEKerberosClientSocket::getSASLDataFromNetwork(char *buf, int trunclen) { } } else { - usleep(1000); + if (shouldblock) { + + usleep(1000); + } + else { + break; + } } if (len >= (ba.size()-1)) { ba.resize(ba.size()+2048); @@ -486,21 +526,21 @@ int TDEKerberosClientSocket::transmitEncryptedData(int fd, const char* readbuf, data_remaining = data_remaining - data_to_write_len; remnant_position = remnant_position + data_to_write_len; if (data_remaining > 0) { - tqApp->processEvents(); + SAFELY_PROCESS_EVENTS } } return 0; } -int TDEKerberosClientSocket::receiveEncryptedData(char *buf, unsigned int trunclen) { +int TDEKerberosClientSocket::receiveEncryptedData(char *buf, unsigned int trunclen, bool shouldblock) { unsigned int recv_len; const char *recv_data; int result; int len; char *encbuf = (char*)malloc(m_negotiatedMaxBufferSize); - len = getSASLDataFromNetwork(encbuf, m_negotiatedMaxBufferSize); + len = getSASLDataFromNetwork(encbuf, m_negotiatedMaxBufferSize, shouldblock); if (len < 0) { return -1; } diff --git a/lib/libtdekrb/src/tdekrbclientsocket.h b/lib/libtdekrb/src/tdekrbclientsocket.h index fde4eee..ddba47a 100644 --- a/lib/libtdekrb/src/tdekrbclientsocket.h +++ b/lib/libtdekrb/src/tdekrbclientsocket.h @@ -58,9 +58,9 @@ class TDEKerberosClientSocket : public TQSocket int initializeKerberosInterface(); void freeKerberosConnection(); void sendSASLDataToNetwork(const char *buffer, unsigned length, int netfd); - int getSASLDataFromNetwork(char *buf, int trunclen); + int getSASLDataFromNetwork(char *buf, int trunclen, bool shouldblock=true); int transmitEncryptedData(int fd, const char* readbuf, int cc); - int receiveEncryptedData(char *buf, unsigned int trunclen); + int receiveEncryptedData(char *buf, unsigned int trunclen, bool shouldblock=true); private: bool m_kerberosRequested; @@ -69,6 +69,7 @@ class TDEKerberosClientSocket : public TQSocket int m_criticalSection; TQBuffer* m_buffer; long m_bufferLength; + bool* m_canary; private: SASLDataPrivate *saslData; diff --git a/lib/libtdekrb/src/tdekrbserversocket.cpp b/lib/libtdekrb/src/tdekrbserversocket.cpp index 89cb05d..e1e2c02 100644 --- a/lib/libtdekrb/src/tdekrbserversocket.cpp +++ b/lib/libtdekrb/src/tdekrbserversocket.cpp @@ -32,6 +32,20 @@ #define NET_SEC_BUF_SIZE (2048) +// When control comes back from processEvents() my object may be completely gone! This attempts to mitigate the risk +#define SAFELY_PROCESS_EVENTS if (!m_canary) { \ + m_canary = new bool; \ + *m_canary = false; \ + } \ + bool* canary = m_canary; \ + tqApp->processEvents(); \ + if (*canary == true) { \ + delete canary; \ + return -1; \ + } \ + delete m_canary; \ + m_canary = NULL; + /* exception handling */ struct exit_exception { int c; @@ -79,7 +93,7 @@ static int logSASLMessages(void *context __attribute__((unused)), int priority, return SASL_OK; } -TDEKerberosServerSocket::TDEKerberosServerSocket(TQObject *parent, const char *name) : TQSocket(parent, name), m_kerberosRequested(false), m_criticalSection(0), m_bufferLength(0), m_negotiatedMaxBufferSize(NET_SEC_BUF_SIZE) { +TDEKerberosServerSocket::TDEKerberosServerSocket(TQObject *parent, const char *name) : TQSocket(parent, name), m_kerberosRequested(false), m_criticalSection(0), m_bufferLength(0), m_canary(NULL), m_negotiatedMaxBufferSize(NET_SEC_BUF_SIZE) { saslData = new SASLDataPrivate; saslData->m_krbConnection = NULL; m_buffer = new TQBuffer(); @@ -87,6 +101,9 @@ TDEKerberosServerSocket::TDEKerberosServerSocket(TQObject *parent, const char *n } TDEKerberosServerSocket::~TDEKerberosServerSocket() { + if (m_canary) { + *m_canary = true; + } m_buffer->close(); delete m_buffer; delete saslData; @@ -102,9 +119,6 @@ bool TDEKerberosServerSocket::open(int mode) { void TDEKerberosServerSocket::close() { TQSocket::close(); - if (m_criticalSection > 0) { - throw exit_exception(-1); - } } void TDEKerberosServerSocket::flush() { @@ -221,6 +235,10 @@ TQ_LONG TDEKerberosServerSocket::readBlock(char *data, TQ_ULONG maxlen) { int wrlen; char* buf = (char*)malloc(m_negotiatedMaxBufferSize); reclen = receiveEncryptedData(buf, m_negotiatedMaxBufferSize); + if (reclen < 0) { + free(buf); + return -1; + } if (reclen > 0) { m_buffer->at(m_bufferLength); wrlen = m_buffer->writeBlock(buf, reclen); @@ -278,6 +296,10 @@ TQ_LONG TDEKerberosServerSocket::readLine(char *data, TQ_ULONG maxlen) { int wrlen; char* buf = (char*)malloc(m_negotiatedMaxBufferSize); reclen = receiveEncryptedData(buf, m_negotiatedMaxBufferSize); + if (reclen < 0) { + free(buf); + return -1; + } if (reclen > 0) { m_buffer->at(m_bufferLength); wrlen = m_buffer->writeBlock(buf, reclen); @@ -325,6 +347,10 @@ TQString TDEKerberosServerSocket::readLine() { maxlen = m_negotiatedMaxBufferSize; char* buf = (char*)malloc(m_negotiatedMaxBufferSize); reclen = receiveEncryptedData(buf, m_negotiatedMaxBufferSize); + if (reclen < 0) { + free(buf); + return TQString::null; + } if (reclen > 0) { m_buffer->at(m_bufferLength); wrlen = m_buffer->writeBlock(buf, reclen); @@ -410,7 +436,7 @@ void TDEKerberosServerSocket::sendSASLDataToNetwork(const char *buffer, unsigned free(buf); } -int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trunclen) { +int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trunclen, bool shouldblock) { m_criticalSection++; try { unsigned int len; @@ -418,9 +444,17 @@ int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trunclen) { TQByteArray ba(2048); + if (!shouldblock) { + if ((!TQSocket::canReadLine()) || (state() != TQSocket::Connected)) { + return 0; + } + } + len = 0; while (1) { - tqApp->processEvents(); + if (shouldblock) { + SAFELY_PROCESS_EVENTS + } if (state() != TQSocket::Connected) { m_criticalSection--; return -1; @@ -435,7 +469,13 @@ int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trunclen) { } } else { - usleep(1000); + if (shouldblock) { + + usleep(1000); + } + else { + break; + } } if (len >= (ba.size()-1)) { ba.resize(ba.size()+2048); @@ -486,21 +526,21 @@ int TDEKerberosServerSocket::transmitEncryptedData(int fd, const char* readbuf, data_remaining = data_remaining - data_to_write_len; remnant_position = remnant_position + data_to_write_len; if (data_remaining > 0) { - tqApp->processEvents(); + SAFELY_PROCESS_EVENTS } } return 0; } -int TDEKerberosServerSocket::receiveEncryptedData(char *buf, unsigned int trunclen) { +int TDEKerberosServerSocket::receiveEncryptedData(char *buf, unsigned int trunclen, bool shouldblock) { unsigned int recv_len; const char *recv_data; int result; int len; char *encbuf = (char*)malloc(m_negotiatedMaxBufferSize); - len = getSASLDataFromNetwork(encbuf, m_negotiatedMaxBufferSize); + len = getSASLDataFromNetwork(encbuf, m_negotiatedMaxBufferSize, shouldblock); if (len < 0) { return -1; } diff --git a/lib/libtdekrb/src/tdekrbserversocket.h b/lib/libtdekrb/src/tdekrbserversocket.h index 0d71faf..80c84fd 100644 --- a/lib/libtdekrb/src/tdekrbserversocket.h +++ b/lib/libtdekrb/src/tdekrbserversocket.h @@ -58,9 +58,9 @@ class TDEKerberosServerSocket : public TQSocket int initializeKerberosInterface(); void freeKerberosConnection(); void sendSASLDataToNetwork(const char *buffer, unsigned length, int netfd); - int getSASLDataFromNetwork(char *buf, int trunclen); + int getSASLDataFromNetwork(char *buf, int trunclen, bool shouldblock=true); int transmitEncryptedData(int fd, const char* readbuf, int cc); - int receiveEncryptedData(char *buf, unsigned int trunclen); + int receiveEncryptedData(char *buf, unsigned int trunclen, bool shouldblock=true); protected: TQString m_authenticatedUserName; @@ -73,6 +73,7 @@ class TDEKerberosServerSocket : public TQSocket int m_criticalSection; TQBuffer* m_buffer; long m_bufferLength; + bool* m_canary; private: SASLDataPrivate *saslData; |