summaryrefslogtreecommitdiffstats
path: root/lib/libtdekrb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libtdekrb')
-rw-r--r--lib/libtdekrb/src/tdekrbclientsocket.cpp60
-rw-r--r--lib/libtdekrb/src/tdekrbclientsocket.h8
-rw-r--r--lib/libtdekrb/src/tdekrbserversocket.cpp330
-rw-r--r--lib/libtdekrb/src/tdekrbserversocket.h26
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