diff options
author | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-06-23 17:23:49 -0500 |
---|---|---|
committer | Timothy Pearson <kb9vqf@pearsoncomputing.net> | 2012-06-23 17:23:49 -0500 |
commit | 8dcfe72c396a6f0c4bafd2ed23ba52a475154ef2 (patch) | |
tree | a0a77ec1d7d7cd826e1f2ba92ea4f96351bae5e3 /lib/libtdekrb/src/tdekrbclientsocket.cpp | |
parent | b48b26b86975d2166a4da7fc41086facefb3c4f2 (diff) | |
download | ulab-8dcfe72c396a6f0c4bafd2ed23ba52a475154ef2.tar.gz ulab-8dcfe72c396a6f0c4bafd2ed23ba52a475154ef2.zip |
Fix a number of crashes and generally clean up the code
Diffstat (limited to 'lib/libtdekrb/src/tdekrbclientsocket.cpp')
-rw-r--r-- | lib/libtdekrb/src/tdekrbclientsocket.cpp | 113 |
1 files changed, 77 insertions, 36 deletions
diff --git a/lib/libtdekrb/src/tdekrbclientsocket.cpp b/lib/libtdekrb/src/tdekrbclientsocket.cpp index 053dd23..ad7f0bd 100644 --- a/lib/libtdekrb/src/tdekrbclientsocket.cpp +++ b/lib/libtdekrb/src/tdekrbclientsocket.cpp @@ -31,6 +31,12 @@ #define NET_SEC_BUF_SIZE (2048) +/* exception handling */ +struct exit_exception { + int c; + exit_exception(int c):c(c) { } +}; + class SASLDataPrivate { public: @@ -38,6 +44,16 @@ class SASLDataPrivate sasl_conn_t *m_krbConnection; }; +static const char * safe_sasl_errdetail(sasl_conn_t *conn) { + const char * str = sasl_errdetail(conn); + if (str) { + return str; + } + else { + return "unknown error"; + } +} + static int logSASLMessages(void *context __attribute__((unused)), int priority, const char *message) { const char *label; @@ -62,7 +78,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_negotiatedMaxBufferSize(NET_SEC_BUF_SIZE) { +TDEKerberosClientSocket::TDEKerberosClientSocket(TQObject *parent, const char *name) : TQSocket(parent, name), m_kerberosRequested(false), m_negotiatedMaxBufferSize(NET_SEC_BUF_SIZE), m_criticalSection(0) { saslData = new SASLDataPrivate; saslData->m_krbConnection = NULL; } @@ -81,6 +97,9 @@ bool TDEKerberosClientSocket::open(int mode) { void TDEKerberosClientSocket::close() { TQSocket::close(); + if (m_criticalSection > 0) { + throw exit_exception(-1); + } } int TDEKerberosClientSocket::setUsingKerberos(bool krbactive) { @@ -213,41 +232,54 @@ void TDEKerberosClientSocket::sendSASLDataToNetwork(const char *buffer, unsigned free(buf); } -unsigned int TDEKerberosClientSocket::getSASLDataFromNetwork(char *buf, int trunclen) { - unsigned int len; - int result; - - TQByteArray ba(2048); - - len = 0; - while (1) { - tqApp->processEvents(); - if (state() != TQSocket::Connected) { - return -1; - } - if (TQSocket::readBlock(ba.data()+len, 1) > 0) { - if (ba.data()[len] == '\n') { - ba.data()[len] = 0; - break; +int TDEKerberosClientSocket::getSASLDataFromNetwork(char *buf, int trunclen) { + m_criticalSection++; + try { + unsigned int len; + int result; + + TQByteArray ba(2048); + + len = 0; + while (1) { + tqApp->processEvents(); + if (state() != TQSocket::Connected) { + m_criticalSection--; + return -1; } - if (ba.data()[len] != '\r') { - len++; + if (TQSocket::readBlock(ba.data()+len, 1) > 0) { + if (ba.data()[len] == '\n') { + ba.data()[len] = 0; + break; + } + if (ba.data()[len] != '\r') { + len++; + } + } + else { + usleep(1000); + } + if (len >= (ba.size()-1)) { + ba.resize(ba.size()+2048); } } - if (len >= (ba.size()-1)) { - ba.resize(ba.size()+2048); + + len = strlen(ba.data()); + result = sasl_decode64(ba.data(), strlen(ba.data()), buf, trunclen, &len); + if (result != SASL_OK) { + printf("[ERROR] Decoding data from base64 returned %s (%d)\n\r", sasl_errstring(result, NULL, NULL), result); + m_criticalSection--; + return -1; } - } + buf[len] = '\0'; - len = strlen(ba.data()); - result = sasl_decode64(ba.data(), strlen(ba.data()), buf, trunclen, &len); - if (result != SASL_OK) { - printf("[ERROR] Decoding data from base64 returned %s (%d)\n\r", sasl_errstring(result, NULL, NULL), result); + m_criticalSection--; + return len; + } + catch(exit_exception& e) { + m_criticalSection--; return -1; } - buf[len] = '\0'; - - return len; } int TDEKerberosClientSocket::transmitEncryptedData(int fd, const char* readbuf, int cc) { @@ -257,7 +289,7 @@ int TDEKerberosClientSocket::transmitEncryptedData(int fd, const char* readbuf, result=sasl_encode(saslData->m_krbConnection, readbuf, cc, &data, &len); if (result != SASL_OK) { - printf("[ERROR] Encrypting data returned %s (%d)\n\r", sasl_errdetail(saslData->m_krbConnection), result); + printf("[ERROR] Encrypting data returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), result); return -1; } sendSASLDataToNetwork(data, len, fd); @@ -273,11 +305,14 @@ int TDEKerberosClientSocket::receiveEncryptedData(char *buf, int trunclen) { char *encbuf = (char*)malloc(m_negotiatedMaxBufferSize); len = getSASLDataFromNetwork(encbuf, m_negotiatedMaxBufferSize); + if (len < 0) { + return -1; + } if (len >= 0) { result=sasl_decode(saslData->m_krbConnection, encbuf, len, &recv_data, &recv_len); if (result != SASL_OK) { free(encbuf); - printf("[ERROR] Decrypting data returned %s (%d)\n\r", sasl_errdetail(saslData->m_krbConnection), result); + printf("[ERROR] Decrypting data returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), result); return -1; } if (recv_len > trunclen) { @@ -287,7 +322,7 @@ int TDEKerberosClientSocket::receiveEncryptedData(char *buf, int trunclen) { } free(encbuf); - return 0; + return recv_len; } int TDEKerberosClientSocket::initializeKerberosInterface() { @@ -303,6 +338,7 @@ int TDEKerberosClientSocket::initializeKerberosInterface() { sasl_security_properties_t secprops; const char *chosenmech; unsigned int len; + int slen; const char *data; char user_authorized = 0; sasl_ssf_t *ssf; @@ -350,7 +386,11 @@ int TDEKerberosClientSocket::initializeKerberosInterface() { } printf("[DEBUG] Waiting for mechanism list from server...\n\r"); - len = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); + slen = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); + if (slen < 0) { + return -2; + } + len = slen; printf("Choosing best mechanism from: %s\n", buf); @@ -383,10 +423,11 @@ int TDEKerberosClientSocket::initializeKerberosInterface() { while (result == SASL_CONTINUE) { printf("[DEBUG] Waiting for server reply...\n\r"); - len = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); - if (state() != TQSocket::Connected) { - return -1; + slen = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); + if (slen < 0) { + return -2; } + len = slen; result = sasl_client_step(saslData->m_krbConnection, buf, len, NULL, &data, &len); if (result != SASL_OK && result != SASL_CONTINUE) { printf("[ERROR] Performing SASL negotiation returned %s (%d)\n\r", sasl_errstring(result, NULL, NULL), result); |