diff options
Diffstat (limited to 'lib/libtdekrb/src/tdekrbserversocket.cpp')
| -rw-r--r-- | lib/libtdekrb/src/tdekrbserversocket.cpp | 126 |
1 files changed, 85 insertions, 41 deletions
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; } |
