Convert krb server socket to stateful operation

Do the same to the server daemons and the MDI frame client
master
Timothy Pearson 12 years ago
parent e89735d72a
commit 1f8f9ca943

@ -30,7 +30,7 @@ using namespace std;
#include "dialogs/selectserverdlg.h"
RemoteMDI::RemoteMDI()
: KMdiMainFrm(0, "RemoteMDI", KMdi::ChildframeMode), m_children(0), m_rsvSvrSocket(NULL)
: KMdiMainFrm(0, "RemoteMDI", KMdi::ChildframeMode), m_children(0), m_rsvSvrSocket(NULL), connToServerConnecting(false), connToServerState(-1), connToServerTimeoutTimer(NULL)
{
setXMLFile("remotelabui.rc");
@ -75,10 +75,10 @@ RemoteMDI::~RemoteMDI()
}
if (m_rsvSvrSocket) {
m_rsvSvrSocket->clearPendingData();
m_rsvSvrSocket->close();
while (m_rsvSvrSocket->state() == TQSocket::Closing) {
tqApp->processEvents();
}
delete m_rsvSvrSocket;
m_rsvSvrSocket = NULL;
}
}
@ -137,46 +137,54 @@ void RemoteMDI::startModule() {
}
}
void RemoteMDI::connectToServer() {
if (m_rsvSvrSocket) {
if (m_rsvSvrSocket->state() != TQSocket::Idle) {
printf("[DEBUG] Not connecting because the socket is still in state %d\n\r", m_rsvSvrSocket->state()); fflush(stdout);
return;
}
}
connect_action->setEnabled(false);
disconnect_action->setEnabled(true);
// Connect to the central reservation/control server
if (!m_rsvSvrSocket) {
m_rsvSvrSocket = new TDEKerberosClientSocket(this);
connect(m_rsvSvrSocket, SIGNAL(connectionClosed()), this, SLOT(connectionClosedHandler()));
}
m_rsvSvrSocket->setServiceName("remotefpga");
if (m_serverHost != "") {
m_rsvSvrSocket->setServerFQDN(m_serverHost);
m_rsvSvrSocket->connectToHost(m_serverHost, 4004);
TQTimer connectionTimeout;
connectionTimeout.start(5000, TRUE);
while ((m_rsvSvrSocket->state() == TQSocket::Connecting) || (m_rsvSvrSocket->state() == TQSocket::HostLookup)) {
tqApp->processEvents();
if (!connectionTimeout.isActive()) {
void RemoteMDI::finishConnectingToServer() {
if (connToServerConnecting) {
switch(connToServerState) {
case 0:
if (!connToServerTimeoutTimer) {
connToServerTimeoutTimer = new TQTimer;
connToServerTimeoutTimer->start(5000, TRUE);
}
if ((m_rsvSvrSocket->state() == TQSocket::Connecting) || (m_rsvSvrSocket->state() == TQSocket::HostLookup)) {
if (!connToServerTimeoutTimer->isActive()) {
connToServerState = -3;
connToServerConnecting = false;
disconnectFromServer();
KMessageBox::error(this, i18n("<qt>Unable to establish connection to remote server</qt>"), i18n("Connection Failed"));
}
}
else {
if (m_rsvSvrSocket->state() == TQSocket::Connected) {
printf("[DEBUG] Initial connection established...\n\r"); fflush(stdout);
m_rsvSvrSocket->setDataTimeout(5000);
m_rsvSvrSocket->setUsingKerberos(true);
connToServerState = 1;
}
else {
connToServerState = -1;
connToServerConnecting = false;
disconnectFromServer();
KMessageBox::error(this, i18n("<qt>Unable to establish connection to remote server</qt>"), i18n("Connection Failed"));
}
}
break;
}
}
connectionTimeout.stop();
if (m_rsvSvrSocket->state() == TQSocket::Connected) {
printf("[DEBUG] Initial connection established...\n\r"); fflush(stdout);
m_rsvSvrSocket->setUsingKerberos(true);
while (m_rsvSvrSocket->kerberosStatus() == TDEKerberosClientSocket::KerberosInitializing) {
tqApp->processEvents();
}
if (m_rsvSvrSocket->kerberosStatus() != TDEKerberosClientSocket::KerberosInUse) {
disconnectFromServer();
KMessageBox::error(this, i18n("<qt>Unable to establish Kerberos protocol with remote server<p>Please verify that you currently hold a valid Kerberos ticket</qt>"), i18n("Connection Failed"));
}
else {
case 1:
if (m_rsvSvrSocket->kerberosStatus() == TDEKerberosClientSocket::KerberosInitializing) {
// Do nothing
}
else {
if (m_rsvSvrSocket->kerberosStatus() != TDEKerberosClientSocket::KerberosInUse) {
connToServerState = -1;
connToServerConnecting = false;
disconnectFromServer();
KMessageBox::error(this, i18n("<qt>Unable to establish Kerberos protocol with remote server<p>Please verify that you currently hold a valid Kerberos ticket</qt>"), i18n("Connection Failed"));
}
else {
connToServerState = 2;
}
}
break;
case 2:
// Connection established!
// Read magic number and proto version from server
TQDataStream* ds = new TQDataStream(m_rsvSvrSocket);
@ -194,19 +202,43 @@ void RemoteMDI::connectToServer() {
disconnectFromServer();
KMessageBox::error(this, i18n("<qt>The remote server is not compatible with this client</qt>"), i18n("Connection Failed"));
}
}
connToServerState = 3;
connToServerConnecting = false;
processLockouts();
break;
}
else {
disconnectFromServer();
KMessageBox::error(this, i18n("<qt>Unable to establish connection to remote server</qt>"), i18n("Connection Failed"));
TQTimer::singleShot(0, this, SLOT(finishConnectingToServer()));
}
}
void RemoteMDI::connectToServer() {
if (m_rsvSvrSocket) {
if (m_rsvSvrSocket->state() != TQSocket::Idle) {
printf("[DEBUG] Not connecting because the socket is still in state %d\n\r", m_rsvSvrSocket->state()); fflush(stdout);
return;
}
}
else {
disconnectFromServer();
KMessageBox::error(this, i18n("<qt>The address of the remote server has not been specified</qt>"), i18n("Connection Failed"));
connect_action->setEnabled(false);
disconnect_action->setEnabled(true);
// Connect to the central reservation/control server
if (!m_rsvSvrSocket) {
m_rsvSvrSocket = new TDEKerberosClientSocket(this);
connect(m_rsvSvrSocket, SIGNAL(connectionClosed()), this, SLOT(connectionClosedHandler()));
connect(m_rsvSvrSocket, TQT_SIGNAL(statusMessageUpdated(const TQString&)), statusBar(), TQT_SLOT(message(const TQString&) ));
}
m_rsvSvrSocket->setServiceName("remotefpga");
if (m_serverHost != "") {
m_rsvSvrSocket->setServerFQDN(m_serverHost);
m_rsvSvrSocket->connectToHost(m_serverHost, 4004);
processLockouts();
// Finish connecting when appropriate
connToServerState = 0;
connToServerConnecting = true;
TQTimer::singleShot(0, this, SLOT(finishConnectingToServer()));
}
}
void RemoteMDI::promptForStationType() {
@ -290,7 +322,7 @@ void RemoteMDI::connectionClosedHandler() {
void RemoteMDI::processLockouts() {
bool connected = false;
if (m_rsvSvrSocket) {
connected = (m_rsvSvrSocket->state() == TQSocket::Connected);
connected = ((m_rsvSvrSocket->state() == TQSocket::Connected) && (connToServerConnecting == false) && (connToServerState > 0));
}
printf("[RAJA DEBUG 600.0] connected: %d\n\r", connected); fflush(stdout);

@ -59,6 +59,7 @@ class RemoteMDI : public KMdiMainFrm
void configToolbars();
void configKeys();
void connectToServer();
void finishConnectingToServer();
void disconnectFromServer();
void promptForStationType();
void connectionClosedHandler();
@ -74,6 +75,10 @@ class RemoteMDI : public KMdiMainFrm
TDEKerberosClientSocket* m_rsvSvrSocket;
bool connToServerConnecting;
int connToServerState;
TQTimer *connToServerTimeoutTimer;
private:
KAction *connect_action;
KAction *disconnect_action;

@ -158,6 +158,7 @@ printf("[RAJA DEBUG 200.1] In FPGAViewPart::connectToServer TRIED TO CONNECT TWI
if (m_socket->state() != TQSocket::Connected) {
return -1;
}
m_socket->setDataTimeout(5000);
m_socket->setUsingKerberos(true);
while (m_socket->kerberosStatus() == TDEKerberosClientSocket::KerberosInitializing) {
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);

@ -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;
}

@ -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:

@ -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;
}

@ -32,6 +32,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

@ -106,7 +106,12 @@ void AuthSocket::connectionClosedHandler() {
}
int AuthSocket::initiateKerberosHandshake() {
if (setUsingKerberos(true) == 0) {
// RAJA FIXME
setUsingKerberos(true);
while (kerberosStatus() == TDEKerberosServerSocket::KerberosInitializing) {
tqApp->processEvents();
}
if (kerberosStatus() == TDEKerberosServerSocket::KerberosInUse) {
TQ_UINT32 magicnum = MAGIC_NUMBER;
TQ_UINT32 protover = PROTOCOL_VERSION;

@ -88,7 +88,12 @@ void FPGASocket::connectionClosedHandler() {
}
int FPGASocket::initiateKerberosHandshake() {
if (setUsingKerberos(true) == 0) {
// RAJA FIXME
setUsingKerberos(true);
while (kerberosStatus() == TDEKerberosServerSocket::KerberosInitializing) {
tqApp->processEvents();
}
if (kerberosStatus() == TDEKerberosServerSocket::KerberosInUse) {
TQDataStream ds(this);
ds << TQString("OK");

Loading…
Cancel
Save