diff options
Diffstat (limited to 'lib/libtdekrb')
-rw-r--r-- | lib/libtdekrb/src/tdekrbclientsocket.cpp | 60 | ||||
-rw-r--r-- | lib/libtdekrb/src/tdekrbclientsocket.h | 8 | ||||
-rw-r--r-- | lib/libtdekrb/src/tdekrbserversocket.cpp | 330 | ||||
-rw-r--r-- | lib/libtdekrb/src/tdekrbserversocket.h | 26 |
4 files changed, 309 insertions, 115 deletions
diff --git a/lib/libtdekrb/src/tdekrbclientsocket.cpp b/lib/libtdekrb/src/tdekrbclientsocket.cpp index 24acb29..7e39fcf 100644 --- a/lib/libtdekrb/src/tdekrbclientsocket.cpp +++ b/lib/libtdekrb/src/tdekrbclientsocket.cpp @@ -30,6 +30,8 @@ #include <saslplug.h> #include <saslutil.h> +#include <klocale.h> + #include "tdekrbclientsocket.h" #define NET_SEC_BUF_SIZE (2048) @@ -95,7 +97,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_krbInitRunning(false), m_krbInitState(-1), m_canary(NULL), 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_krbInitRunning(false), m_krbInitState(-1), m_dataTimeout(-1), m_canary(NULL), m_negotiatedMaxBufferSize(NET_SEC_BUF_SIZE) { saslData = new SASLDataPrivate; saslData->m_krbConnection = NULL; m_buffer = new TQBuffer(); @@ -111,7 +113,12 @@ TDEKerberosClientSocket::~TDEKerberosClientSocket() { delete saslData; } +void TDEKerberosClientSocket::setDataTimeout(int timeoutms) { + m_dataTimeout = timeoutms; +} + bool TDEKerberosClientSocket::open(int mode) { + setStatusMessage(i18n("Establishing initial connection to server")); bool ret = TQSocket::open(mode); if (m_kerberosRequested) { initializeKerberosInterface(); @@ -121,6 +128,7 @@ bool TDEKerberosClientSocket::open(int mode) { void TDEKerberosClientSocket::close() { TQSocket::close(); + setStatusMessage(i18n("Disconnected")); } void TDEKerberosClientSocket::flush() { @@ -453,8 +461,12 @@ int TDEKerberosClientSocket::getSASLDataFromNetwork(char *buf, int trunclen, boo } len = 0; - while (1) { - if (shouldblock) { + TQTimer dataTimeoutTimer; + if (m_dataTimeout > 0) { + dataTimeoutTimer.start(m_dataTimeout, TRUE); + } + while (dataTimeoutTimer.isActive() || (m_dataTimeout < 0)) { + if ((shouldblock) && (dataTimeoutTimer.isActive() || (m_dataTimeout < 0))) { SAFELY_PROCESS_EVENTS } if (state() != TQSocket::Connected) { @@ -469,10 +481,13 @@ int TDEKerberosClientSocket::getSASLDataFromNetwork(char *buf, int trunclen, boo if (ba.data()[len] != '\r') { len++; } + if (m_dataTimeout > 0) { + dataTimeoutTimer.stop(); + dataTimeoutTimer.start(m_dataTimeout, TRUE); + } } else { if (shouldblock) { - usleep(1000); } else { @@ -509,9 +524,14 @@ int TDEKerberosClientSocket::transmitEncryptedData(int fd, const char* readbuf, long data_remaining; long remnant_position; + TQTimer dataTimeoutTimer; + if (m_dataTimeout > 0) { + dataTimeoutTimer.start(m_dataTimeout, TRUE); + } + data_remaining = cc; remnant_position = 0; - while (data_remaining > 0) { + while ((data_remaining > 0) && (dataTimeoutTimer.isActive() || (m_dataTimeout < 0))) { int data_to_write_len; if (data_remaining > (m_negotiatedMaxBufferSize/2)) { data_to_write_len = m_negotiatedMaxBufferSize/2; @@ -527,7 +547,7 @@ int TDEKerberosClientSocket::transmitEncryptedData(int fd, const char* readbuf, sendSASLDataToNetwork(data, len, fd); data_remaining = data_remaining - data_to_write_len; remnant_position = remnant_position + data_to_write_len; - if (data_remaining > 0) { + if ((data_remaining > 0) && (dataTimeoutTimer.isActive() || (m_dataTimeout < 0))) { SAFELY_PROCESS_EVENTS } } @@ -576,6 +596,13 @@ TDEKerberosClientSocket::KerberosStatus TDEKerberosClientSocket::kerberosStatus( return KerberosInUse; } +void TDEKerberosClientSocket::setStatusMessage(TQString message) { + if (message != m_prevStatusMessage) { + emit(statusMessageUpdated(message)); + m_prevStatusMessage = message; + } +} + void TDEKerberosClientSocket::continueKerberosInitialization() { int slen; char buf[NET_SEC_BUF_SIZE]; @@ -588,27 +615,30 @@ void TDEKerberosClientSocket::continueKerberosInitialization() { switch (m_krbInitState) { case 0: if (state() == TQSocket::Connected) { + setStatusMessage(i18n("Waiting for mechanism list from server")); if (canReadLine()) { printf("[DEBUG] Waiting for mechanism list from server...\n\r"); slen = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); if (slen < 0) { m_krbInitState = -2; m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); return; } len = slen; - + printf("Choosing best mechanism from: %s\n", buf); - + m_krbInitResult = sasl_client_start(saslData->m_krbConnection, buf, NULL, &data, &len, &chosenmech); if (m_krbInitResult != SASL_OK && m_krbInitResult != SASL_CONTINUE) { printf("[ERROR] Starting SASL negotiation returned %s (%d)\n\r", sasl_errstring(m_krbInitResult, NULL, NULL), m_krbInitResult); freeKerberosConnection(); m_krbInitState = -1; m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); return; } - + printf("[DEBUG] Using mechanism %s\n\r", chosenmech); strcpy(buf, chosenmech); if (data) { @@ -617,6 +647,7 @@ void TDEKerberosClientSocket::continueKerberosInitialization() { freeKerberosConnection(); m_krbInitState = -1; m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); return; } printf("[DEBUG] Preparing initial response...\n\r"); @@ -627,7 +658,7 @@ void TDEKerberosClientSocket::continueKerberosInitialization() { else { len = (unsigned) strlen(buf); } - + printf("[DEBUG] Sending initial response...\n\r"); sendSASLDataToNetwork(buf, len, socket()); @@ -642,12 +673,14 @@ void TDEKerberosClientSocket::continueKerberosInitialization() { case 1: if (state() == TQSocket::Connected) { if (m_krbInitResult == SASL_CONTINUE) { + setStatusMessage(i18n("Waiting for server reply")); if (canReadLine()) { printf("[DEBUG] Waiting for server reply...\n\r"); slen = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); if (slen < 0) { m_krbInitState = -2; m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); return; } len = slen; @@ -657,6 +690,7 @@ void TDEKerberosClientSocket::continueKerberosInitialization() { freeKerberosConnection(); m_krbInitState = -1; m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); return; } if (data && len) { @@ -676,6 +710,8 @@ void TDEKerberosClientSocket::continueKerberosInitialization() { else { m_krbInitState = -3; m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); + return; } break; case 2: @@ -714,10 +750,14 @@ void TDEKerberosClientSocket::continueKerberosInitialization() { } m_krbInitState = 3; m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection established")); + return; } else { m_krbInitState = -3; m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); + return; } break; } diff --git a/lib/libtdekrb/src/tdekrbclientsocket.h b/lib/libtdekrb/src/tdekrbclientsocket.h index 48ec09a..8f4a287 100644 --- a/lib/libtdekrb/src/tdekrbclientsocket.h +++ b/lib/libtdekrb/src/tdekrbclientsocket.h @@ -62,6 +62,8 @@ class TDEKerberosClientSocket : public TQSocket void setServiceName(TQString name); void setServerFQDN(TQString name); + void setDataTimeout(int timeoutms); + KerberosStatus kerberosStatus() const; private: @@ -71,10 +73,14 @@ class TDEKerberosClientSocket : public TQSocket int getSASLDataFromNetwork(char *buf, int trunclen, bool shouldblock=true); int transmitEncryptedData(int fd, const char* readbuf, int cc); int receiveEncryptedData(char *buf, unsigned int trunclen, bool shouldblock=true); + void setStatusMessage(TQString message); private slots: void continueKerberosInitialization(); + signals: + void statusMessageUpdated(const TQString&); + private: bool m_kerberosRequested; TQString m_serviceName; @@ -84,6 +90,8 @@ class TDEKerberosClientSocket : public TQSocket long m_bufferLength; bool m_krbInitRunning; int m_krbInitState; + TQString m_prevStatusMessage; + int m_dataTimeout; bool* m_canary; private: diff --git a/lib/libtdekrb/src/tdekrbserversocket.cpp b/lib/libtdekrb/src/tdekrbserversocket.cpp index 8e5c071..4840c16 100644 --- a/lib/libtdekrb/src/tdekrbserversocket.cpp +++ b/lib/libtdekrb/src/tdekrbserversocket.cpp @@ -24,11 +24,14 @@ #include <tqapplication.h> #include <tqbuffer.h> #include <tqeventloop.h> +#include <tqtimer.h> #include <sasl.h> #include <saslplug.h> #include <saslutil.h> +#include <klocale.h> + #include "tdekrbserversocket.h" #define NET_SEC_BUF_SIZE (2048) @@ -94,7 +97,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_canary(NULL), 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_krbInitRunning(false), m_krbInitState(-1), m_dataTimeout(-1), m_canary(NULL), m_negotiatedMaxBufferSize(NET_SEC_BUF_SIZE) { saslData = new SASLDataPrivate; saslData->m_krbConnection = NULL; m_buffer = new TQBuffer(); @@ -110,7 +113,12 @@ TDEKerberosServerSocket::~TDEKerberosServerSocket() { delete saslData; } +void TDEKerberosServerSocket::setDataTimeout(int timeoutms) { + m_dataTimeout = timeoutms; +} + bool TDEKerberosServerSocket::open(int mode) { + setStatusMessage(i18n("Opening socket")); bool ret = TQSocket::open(mode); if (m_kerberosRequested) { initializeKerberosInterface(); @@ -120,6 +128,7 @@ bool TDEKerberosServerSocket::open(int mode) { void TDEKerberosServerSocket::close() { TQSocket::close(); + setStatusMessage(i18n("Socket closed")); } void TDEKerberosServerSocket::flush() { @@ -452,8 +461,12 @@ int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trunclen, boo } len = 0; - while (1) { - if (shouldblock) { + TQTimer dataTimeoutTimer; + if (m_dataTimeout > 0) { + dataTimeoutTimer.start(m_dataTimeout, TRUE); + } + while (dataTimeoutTimer.isActive() || (m_dataTimeout < 0)) { + if ((shouldblock) && (dataTimeoutTimer.isActive() || (m_dataTimeout < 0))) { SAFELY_PROCESS_EVENTS } if (state() != TQSocket::Connected) { @@ -468,10 +481,13 @@ int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trunclen, boo if (ba.data()[len] != '\r') { len++; } + if (m_dataTimeout > 0) { + dataTimeoutTimer.stop(); + dataTimeoutTimer.start(m_dataTimeout, TRUE); + } } else { if (shouldblock) { - usleep(1000); } else { @@ -508,9 +524,14 @@ int TDEKerberosServerSocket::transmitEncryptedData(int fd, const char* readbuf, long data_remaining; long remnant_position; + TQTimer dataTimeoutTimer; + if (m_dataTimeout > 0) { + dataTimeoutTimer.start(m_dataTimeout, TRUE); + } + data_remaining = cc; remnant_position = 0; - while (data_remaining > 0) { + while ((data_remaining > 0) && (dataTimeoutTimer.isActive() || (m_dataTimeout < 0))) { int data_to_write_len; if (data_remaining > (m_negotiatedMaxBufferSize/2)) { data_to_write_len = m_negotiatedMaxBufferSize/2; @@ -526,7 +547,7 @@ int TDEKerberosServerSocket::transmitEncryptedData(int fd, const char* readbuf, sendSASLDataToNetwork(data, len, fd); data_remaining = data_remaining - data_to_write_len; remnant_position = remnant_position + data_to_write_len; - if (data_remaining > 0) { + if ((data_remaining > 0) && (dataTimeoutTimer.isActive() || (m_dataTimeout < 0))) { SAFELY_PROCESS_EVENTS } } @@ -562,6 +583,185 @@ int TDEKerberosServerSocket::receiveEncryptedData(char *buf, unsigned int truncl return recv_len; } +TDEKerberosServerSocket::KerberosStatus TDEKerberosServerSocket::kerberosStatus() const { + if (!m_kerberosRequested) { + return KerberosNotRequested; + } + if (m_krbInitRunning) { + return KerberosInitializing; + } + if (m_krbInitState < 0) { + return KerberosFailure; + } + return KerberosInUse; +} + +void TDEKerberosServerSocket::setStatusMessage(TQString message) { + if (message != m_prevStatusMessage) { + emit(statusMessageUpdated(message)); + m_prevStatusMessage = message; + } +} + +void TDEKerberosServerSocket::continueKerberosInitialization() { + int slen; + char buf[NET_SEC_BUF_SIZE]; + unsigned int len; + sasl_ssf_t *ssf; + + if (m_krbInitRunning) { + switch (m_krbInitState) { + case 0: + if (state() == TQSocket::Connected) { + setStatusMessage(i18n("Waiting for client mechanism")); + if (canReadLine()) { + printf("[DEBUG] Waiting for client mechanism...\n\r"); + slen = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); + if (slen < 0) { + m_krbInitState = -2; + m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); + return; + } + len = slen; + if (strlen(buf) < len) { + printf("[DEBUG] Initial response received\n\r"); + // An initial response is present + m_krbInitData = buf + strlen(buf) + 1; + len = len - (unsigned) strlen(buf) - 1; + } + else { + m_krbInitData = NULL; + len = 0; + } + m_krbInitResult = sasl_server_start(saslData->m_krbConnection, buf, m_krbInitData, len, &m_krbInitData, &len); + if (m_krbInitResult != SASL_OK && m_krbInitResult != SASL_CONTINUE) { + printf("[ERROR] Starting SASL negotiation returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), m_krbInitResult); + freeKerberosConnection(); + m_krbInitState = -1; + m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); + return; + } + m_krbInitState = 1; + } + } + else { + m_krbInitState = -3; + m_krbInitRunning = false; + } + break; + case 1: + if (state() == TQSocket::Connected) { + if (m_krbInitResult == SASL_CONTINUE) { + if (m_krbInitData) { + printf("[DEBUG] Sending response...\n\r"); + sendSASLDataToNetwork(m_krbInitData, len, socket()); + } + else { + printf("[ERROR] No data to send!\n\r"); + freeKerberosConnection(); + m_krbInitState = -1; + m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); + return; + } + m_krbInitState = 2; + } + else { + printf("[DEBUG] Negotiation complete\n\r"); + m_krbInitState = 3; + } + } + else { + m_krbInitState = -3; + m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); + return; + } + break; + case 2: + if (state() == TQSocket::Connected) { + setStatusMessage(i18n("Waiting for client reply")); + if (canReadLine()) { + printf("[DEBUG] Waiting for client reply...\n\r"); + slen = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); + if (slen < 0) { + m_krbInitState = -2; + m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); + return; + } + len = slen; + m_krbInitData = NULL; + m_krbInitResult = sasl_server_step(saslData->m_krbConnection, buf, len, &m_krbInitData, &len); + if (m_krbInitResult != SASL_OK && m_krbInitResult != SASL_CONTINUE) { + printf("[ERROR] Performing SASL negotiation returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), m_krbInitResult); + freeKerberosConnection(); + m_krbInitState = -1; + m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); + return; + } + m_krbInitState = 1; + } + } + else { + m_krbInitState = -3; + m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); + return; + } + break; + case 3: + if (state() == TQSocket::Connected) { + if(m_krbInitServerLast && m_krbInitData) { + printf("[DEBUG] Additional information needed to be sent\n\r"); + sendSASLDataToNetwork(m_krbInitData, len, socket()); + } + + m_krbInitResult = sasl_getprop(saslData->m_krbConnection, SASL_USERNAME, (const void **)&m_krbInitData); + if (m_krbInitResult != SASL_OK) { + printf("[WARNING] Unable to determine authenticated username!\n\r"); + } + else { + m_authenticatedUserName = m_krbInitData ? m_krbInitData : "(NULL)"; + printf("[DEBUG] Authenticated username: %s\n\r", m_authenticatedUserName.ascii()); + } + + m_krbInitResult = sasl_getprop(saslData->m_krbConnection, SASL_DEFUSERREALM, (const void **)&m_krbInitData); + if (m_krbInitResult != SASL_OK) { + printf("[WARNING] Unable to determine authenticated realm!\n\r"); + } + else { + m_authenticatedRealmName = m_krbInitData ? m_krbInitData : "(NULL)"; + printf("[DEBUG] Authenticated realm: %s\n\r", m_authenticatedRealmName.ascii()); + } + + m_krbInitResult = sasl_getprop(saslData->m_krbConnection, SASL_SSF, (const void **)&ssf); + if (m_krbInitResult != SASL_OK) { + printf("[WARNING] Unable to determine SSF!\n\r"); + } + else { + printf("[DEBUG] Authenticated SSF: %d\n", *ssf); + } + m_krbInitState = 4; + m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection established")); + return; + } + else { + m_krbInitState = -3; + m_krbInitRunning = false; + setStatusMessage(i18n("Kerberos connection failed")); + return; + } + break; + } + TQTimer::singleShot(0, this, SLOT(continueKerberosInitialization())); + } +} + int TDEKerberosServerSocket::initializeKerberosInterface() { if (state() != TQSocket::Connected) { saslData->m_krbConnection = false; @@ -569,16 +769,12 @@ int TDEKerberosServerSocket::initializeKerberosInterface() { } sasl_callback_t *callback; - char buf[NET_SEC_BUF_SIZE]; - int result = 0; - int serverlast = 0; + m_krbInitResult = 0; + m_krbInitServerLast = 0; sasl_security_properties_t secprops; const char *ext_authid = NULL; - unsigned int len; - int slen; int count; - const char *data; - sasl_ssf_t *ssf; + unsigned int len; // FIXME // Populate these fields! @@ -606,116 +802,40 @@ int TDEKerberosServerSocket::initializeKerberosInterface() { secprops.maxbufsize = NET_SEC_BUF_SIZE; secprops.max_ssf = UINT_MAX; - result = sasl_server_init(saslData->m_callbacks, m_serviceName.ascii()); - if (result != SASL_OK) { - printf("[ERROR] Initializing libsasl returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), result); + m_krbInitResult = sasl_server_init(saslData->m_callbacks, m_serviceName.ascii()); + if (m_krbInitResult != SASL_OK) { + printf("[ERROR] Initializing libsasl returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), m_krbInitResult); 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", safe_sasl_errdetail(saslData->m_krbConnection), result); + m_krbInitResult = sasl_server_new(m_serviceName.ascii(), localdomain, userdomain, iplocal, ipremote, NULL, m_krbInitServerLast, &saslData->m_krbConnection); + if (m_krbInitResult != SASL_OK) { + printf("[ERROR] Allocating sasl connection state returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), m_krbInitResult); return -1; } - result = sasl_setprop(saslData->m_krbConnection, SASL_SEC_PROPS, &secprops); + m_krbInitResult = sasl_setprop(saslData->m_krbConnection, SASL_SEC_PROPS, &secprops); - if (result != SASL_OK) { - printf("[ERROR] Setting security properties returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), result); + if (m_krbInitResult != SASL_OK) { + printf("[ERROR] Setting security properties returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), m_krbInitResult); freeKerberosConnection(); return -1; } 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", safe_sasl_errdetail(saslData->m_krbConnection), result); + m_krbInitResult = sasl_listmech(saslData->m_krbConnection, ext_authid, NULL, " ", NULL, &m_krbInitData, &len, &count); + if (m_krbInitResult != SASL_OK) { + printf("[ERROR] Generating client mechanism list returned %s (%d)\n\r", safe_sasl_errdetail(saslData->m_krbConnection), m_krbInitResult); freeKerberosConnection(); return -1; } printf("[DEBUG] Sending list of %d mechanism(s)\n\r", count); - sendSASLDataToNetwork(data, len, socket()); + sendSASLDataToNetwork(m_krbInitData, len, socket()); - printf("[DEBUG] Waiting for client mechanism...\n\r"); - slen = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); - if (slen < 0) { - return -2; - } - len = slen; - if (strlen(buf) < len) { - printf("[DEBUG] Initial response received\n\r"); - // An initial response is present - data = buf + strlen(buf) + 1; - len = len - (unsigned) strlen(buf) - 1; - } - else { - data = NULL; - len = 0; - } - 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", safe_sasl_errdetail(saslData->m_krbConnection), result); - freeKerberosConnection(); - return -1; - } - - while (result == SASL_CONTINUE) { - if (data) { - printf("[DEBUG] Sending response...\n\r"); - sendSASLDataToNetwork(data, len, socket()); - } - else { - printf("[ERROR] No data to send!\n\r"); - freeKerberosConnection(); - return -1; - } - printf("[DEBUG] Waiting for client reply...\n\r"); - 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", safe_sasl_errdetail(saslData->m_krbConnection), result); - freeKerberosConnection(); - return -1; - } - } - printf("[DEBUG] Negotiation complete\n\r"); - - if(serverlast && data) { - printf("[DEBUG] Additional information needed to be sent\n\r"); - sendSASLDataToNetwork(data, len, socket()); - } - - result = sasl_getprop(saslData->m_krbConnection, SASL_USERNAME, (const void **)&data); - if (result != SASL_OK) { - printf("[WARNING] Unable to determine authenticated username!\n\r"); - } - else { - m_authenticatedUserName = data ? data : "(NULL)"; - printf("[DEBUG] Authenticated username: %s\n\r", m_authenticatedUserName.ascii()); - } - - result = sasl_getprop(saslData->m_krbConnection, SASL_DEFUSERREALM, (const void **)&data); - if (result != SASL_OK) { - printf("[WARNING] Unable to determine authenticated realm!\n\r"); - } - else { - m_authenticatedRealmName = data ? data : "(NULL)"; - printf("[DEBUG] Authenticated realm: %s\n\r", m_authenticatedRealmName.ascii()); - } - - result = sasl_getprop(saslData->m_krbConnection, SASL_SSF, (const void **)&ssf); - if (result != SASL_OK) { - printf("[WARNING] Unable to determine SSF!\n\r"); - } - else { - printf("[DEBUG] Authenticated SSF: %d\n", *ssf); - } + m_krbInitRunning = true; + m_krbInitState = 0; + TQTimer::singleShot(0, this, SLOT(continueKerberosInitialization())); return 0; }
\ No newline at end of file diff --git a/lib/libtdekrb/src/tdekrbserversocket.h b/lib/libtdekrb/src/tdekrbserversocket.h index 80c84fd..4a315ca 100644 --- a/lib/libtdekrb/src/tdekrbserversocket.h +++ b/lib/libtdekrb/src/tdekrbserversocket.h @@ -33,6 +33,14 @@ class TDEKerberosServerSocket : public TQSocket Q_OBJECT public: + enum KerberosStatus { + KerberosNotRequested, + KerberosFailure, + KerberosInitializing, + KerberosInUse + }; + + public: TDEKerberosServerSocket(TQObject *parent=0, const char *name=0); virtual ~TDEKerberosServerSocket(); @@ -53,6 +61,10 @@ class TDEKerberosServerSocket : public TQSocket int setUsingKerberos(bool krbactive); void setServiceName(TQString name); void setServerFQDN(TQString name); + + void setDataTimeout(int timeoutms); + + KerberosStatus kerberosStatus() const; private: int initializeKerberosInterface(); @@ -61,6 +73,13 @@ class TDEKerberosServerSocket : public TQSocket int getSASLDataFromNetwork(char *buf, int trunclen, bool shouldblock=true); int transmitEncryptedData(int fd, const char* readbuf, int cc); int receiveEncryptedData(char *buf, unsigned int trunclen, bool shouldblock=true); + void setStatusMessage(TQString message); + + private slots: + void continueKerberosInitialization(); + + signals: + void statusMessageUpdated(const TQString&); protected: TQString m_authenticatedUserName; @@ -73,11 +92,18 @@ class TDEKerberosServerSocket : public TQSocket int m_criticalSection; TQBuffer* m_buffer; long m_bufferLength; + bool m_krbInitRunning; + int m_krbInitState; + TQString m_prevStatusMessage; + int m_dataTimeout; bool* m_canary; private: SASLDataPrivate *saslData; unsigned int m_negotiatedMaxBufferSize; + int m_krbInitResult; + int m_krbInitServerLast; + const char *m_krbInitData; }; #endif // TDEKRBSERVERSOCKET_H
\ No newline at end of file |