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 | |
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')
-rw-r--r-- | lib/libtdekrb/src/Makefile.am | 7 | ||||
-rw-r--r-- | lib/libtdekrb/src/tdekrbclientsocket.cpp | 113 | ||||
-rw-r--r-- | lib/libtdekrb/src/tdekrbclientsocket.h | 3 | ||||
-rw-r--r-- | lib/libtdekrb/src/tdekrbserversocket.cpp | 126 | ||||
-rw-r--r-- | lib/libtdekrb/src/tdekrbserversocket.h | 3 |
5 files changed, 170 insertions, 82 deletions
diff --git a/lib/libtdekrb/src/Makefile.am b/lib/libtdekrb/src/Makefile.am index b0b10cf..9cbe92e 100644 --- a/lib/libtdekrb/src/Makefile.am +++ b/lib/libtdekrb/src/Makefile.am @@ -1,5 +1,6 @@ -INCLUDES = $(all_includes) -I/usr/include/sasl -METASOURCES = AUTO +INCLUDES = $(all_includes) -I/usr/include/sasl +KDE_CXXFLAGS = $(USE_EXCEPTIONS) +METASOURCES = AUTO # Create a shared library file lib_LTLIBRARIES = libtdekrbsocket.la @@ -8,4 +9,4 @@ include_HEADERS = tdekrbclientsocket.h tdekrbserversocket.h libtdekrbsocket_la_SOURCES = tdekrbclientsocket.cpp tdekrbserversocket.cpp libtdekrbsocket_la_LIBADD = -lkio $(LIB_TDEUI) -lsasl2 -libtdekrbsocket_la_LDFLAGS = -avoid-version -module -no-undefined $(all_libraries)
\ No newline at end of file +libtdekrbsocket_la_LDFLAGS = -avoid-version -module -no-undefined $(all_libraries) 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); diff --git a/lib/libtdekrb/src/tdekrbclientsocket.h b/lib/libtdekrb/src/tdekrbclientsocket.h index 1cea942..d0eb018 100644 --- a/lib/libtdekrb/src/tdekrbclientsocket.h +++ b/lib/libtdekrb/src/tdekrbclientsocket.h @@ -51,7 +51,7 @@ class TDEKerberosClientSocket : public TQSocket int initializeKerberosInterface(); void freeKerberosConnection(); void sendSASLDataToNetwork(const char *buffer, unsigned length, int netfd); - unsigned int getSASLDataFromNetwork(char *buf, int trunclen); + int getSASLDataFromNetwork(char *buf, int trunclen); int transmitEncryptedData(int fd, const char* readbuf, int cc); int receiveEncryptedData(char *buf, int trunclen); @@ -59,6 +59,7 @@ class TDEKerberosClientSocket : public TQSocket bool m_kerberosRequested; TQString m_serviceName; TQString m_serverFQDN; + int m_criticalSection; private: SASLDataPrivate *saslData; diff --git a/lib/libtdekrb/src/tdekrbserversocket.cpp b/lib/libtdekrb/src/tdekrbserversocket.cpp index 1d7cfbf..33187bc 100644 --- a/lib/libtdekrb/src/tdekrbserversocket.cpp +++ b/lib/libtdekrb/src/tdekrbserversocket.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; } -TDEKerberosServerSocket::TDEKerberosServerSocket(TQObject *parent, const char *name) : TQSocket(parent, name), m_kerberosRequested(false), m_negotiatedMaxBufferSize(NET_SEC_BUF_SIZE) { +TDEKerberosServerSocket::TDEKerberosServerSocket(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 TDEKerberosServerSocket::open(int mode) { void TDEKerberosServerSocket::close() { TQSocket::close(); + if (m_criticalSection > 0) { + throw exit_exception(-1); + } } int TDEKerberosServerSocket::setUsingKerberos(bool krbactive) { @@ -213,41 +232,54 @@ void TDEKerberosServerSocket::sendSASLDataToNetwork(const char *buffer, unsigned free(buf); } -unsigned int TDEKerberosServerSocket::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 TDEKerberosServerSocket::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 (TQSocket::readBlock(ba.data()+len, 1) > 0) { + if (ba.data()[len] == '\n') { + ba.data()[len] = 0; + break; + } + if (ba.data()[len] != '\r') { + len++; + } } - 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 TDEKerberosServerSocket::transmitEncryptedData(int fd, const char* readbuf, int cc) { @@ -257,7 +289,7 @@ int TDEKerberosServerSocket::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 TDEKerberosServerSocket::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 TDEKerberosServerSocket::receiveEncryptedData(char *buf, int trunclen) { } free(encbuf); - return 0; + return recv_len; } int TDEKerberosServerSocket::initializeKerberosInterface() { @@ -303,6 +338,7 @@ int TDEKerberosServerSocket::initializeKerberosInterface() { sasl_security_properties_t secprops; const char *ext_authid = NULL; unsigned int len; + int slen; int count; const char *data; char user_authorized = 0; @@ -336,20 +372,20 @@ int TDEKerberosServerSocket::initializeKerberosInterface() { result = sasl_server_init(saslData->m_callbacks, m_serviceName.ascii()); if (result != SASL_OK) { - printf("[ERROR] Initializing libsasl returned %s (%d)\n\r", sasl_errdetail(saslData->m_krbConnection), result); + printf("[ERROR] Initializing libsasl returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), result); return -1; } result = sasl_server_new(m_serviceName.ascii(), localdomain, userdomain, iplocal, ipremote, NULL, serverlast, &saslData->m_krbConnection); if (result != SASL_OK) { - printf("[ERROR] Allocating sasl connection state returned %s (%d)\n\r", sasl_errdetail(saslData->m_krbConnection), result); + printf("[ERROR] Allocating sasl connection state returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), result); return -1; } result = sasl_setprop(saslData->m_krbConnection, SASL_SEC_PROPS, &secprops); if (result != SASL_OK) { - printf("[ERROR] Setting security properties returned %s (%d)\n\r", sasl_errdetail(saslData->m_krbConnection), result); + printf("[ERROR] Setting security properties returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), result); freeKerberosConnection(); return -1; } @@ -357,7 +393,7 @@ int TDEKerberosServerSocket::initializeKerberosInterface() { puts("[DEBUG] Generating client mechanism list..."); result = sasl_listmech(saslData->m_krbConnection, ext_authid, NULL, " ", NULL, &data, &len, &count); if (result != SASL_OK) { - printf("[ERROR] Generating client mechanism list returned %s (%d)\n\r", sasl_errdetail(saslData->m_krbConnection), result); + printf("[ERROR] Generating client mechanism list returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), result); freeKerberosConnection(); return -1; } @@ -366,9 +402,13 @@ int TDEKerberosServerSocket::initializeKerberosInterface() { sendSASLDataToNetwork(data, len, socket()); printf("[DEBUG] Waiting for client mechanism...\n\r"); - len = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); + slen = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); + if (slen < 0) { + return -2; + } + len = slen; if (strlen(buf) < len) { - printf("[DEBUG] Initial response received (%d < %d) [%s]\n\r", strlen(buf), len, buf); + printf("[DEBUG] Initial response received\n\r"); // An initial response is present data = buf + strlen(buf) + 1; len = len - (unsigned) strlen(buf) - 1; @@ -379,7 +419,7 @@ int TDEKerberosServerSocket::initializeKerberosInterface() { } result = sasl_server_start(saslData->m_krbConnection, buf, data, len, &data, &len); if (result != SASL_OK && result != SASL_CONTINUE) { - printf("[ERROR] Starting SASL negotiation returned %s (%d)\n\r", sasl_errdetail(saslData->m_krbConnection), result); + printf("[ERROR] Starting SASL negotiation returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), result); freeKerberosConnection(); return -1; } @@ -395,11 +435,15 @@ int TDEKerberosServerSocket::initializeKerberosInterface() { return -1; } printf("[DEBUG] Waiting for client reply...\n\r"); - len = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); + slen = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); + if (slen < 0) { + return -2; + } + len = slen; data = NULL; result = sasl_server_step(saslData->m_krbConnection, buf, len, &data, &len); if (result != SASL_OK && result != SASL_CONTINUE) { - printf("[ERROR] Performing SASL negotiation returned %s (%d)\n\r", sasl_errdetail(saslData->m_krbConnection), result); + printf("[ERROR] Performing SASL negotiation returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), result); freeKerberosConnection(); return -1; } diff --git a/lib/libtdekrb/src/tdekrbserversocket.h b/lib/libtdekrb/src/tdekrbserversocket.h index 04f70b9..a41d14f 100644 --- a/lib/libtdekrb/src/tdekrbserversocket.h +++ b/lib/libtdekrb/src/tdekrbserversocket.h @@ -51,7 +51,7 @@ class TDEKerberosServerSocket : public TQSocket int initializeKerberosInterface(); void freeKerberosConnection(); void sendSASLDataToNetwork(const char *buffer, unsigned length, int netfd); - unsigned int getSASLDataFromNetwork(char *buf, int trunclen); + int getSASLDataFromNetwork(char *buf, int trunclen); int transmitEncryptedData(int fd, const char* readbuf, int cc); int receiveEncryptedData(char *buf, int trunclen); @@ -59,6 +59,7 @@ class TDEKerberosServerSocket : public TQSocket bool m_kerberosRequested; TQString m_serviceName; TQString m_serverFQDN; + int m_criticalSection; private: SASLDataPrivate *saslData; |