summaryrefslogtreecommitdiffstats
path: root/lib/libtdekrb/src/tdekrbserversocket.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libtdekrb/src/tdekrbserversocket.cpp')
-rw-r--r--lib/libtdekrb/src/tdekrbserversocket.cpp60
1 files changed, 50 insertions, 10 deletions
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;
}