diff options
Diffstat (limited to 'lib/libtdekrb/src/tdekrbclientsocket.cpp')
-rw-r--r-- | lib/libtdekrb/src/tdekrbclientsocket.cpp | 64 |
1 files changed, 52 insertions, 12 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; } |