Fix a number of crashes and generally clean up the code

master
Timothy Pearson 12 years ago
parent b48b26b869
commit 8dcfe72c39

@ -29,7 +29,7 @@ using namespace std;
#include "views/instrumentview.h" #include "views/instrumentview.h"
RemoteMDI::RemoteMDI() RemoteMDI::RemoteMDI()
: KMdiMainFrm(0, "RemoteMDI", KMdi::ChildframeMode), m_children(NULL), m_rsvSvrSocket(NULL) : KMdiMainFrm(0, "RemoteMDI", KMdi::ChildframeMode), m_children(0), m_rsvSvrSocket(NULL)
{ {
setXMLFile("remotelabui.rc"); setXMLFile("remotelabui.rc");
@ -42,9 +42,9 @@ RemoteMDI::RemoteMDI()
KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT(close()), ac); KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT(close()), ac);
KStdAction::configureToolbars(TQT_TQOBJECT(this), TQT_SLOT(configToolbars()), ac); KStdAction::configureToolbars(TQT_TQOBJECT(this), TQT_SLOT(configToolbars()), ac);
KStdAction::keyBindings(TQT_TQOBJECT(this), TQT_SLOT(configKeys()), ac); KStdAction::keyBindings(TQT_TQOBJECT(this), TQT_SLOT(configKeys()), ac);
connect_action = new KAction(i18n("Connect to Server"), "connect_creating", NULL, TQT_TQOBJECT(this), TQT_SLOT(connectToServer()), ac, "connect_server"); connect_action = new KAction(i18n("Connect to Server"), "connect_creating", KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(connectToServer()), ac, "connect_server");
disconnect_action = new KAction(i18n("Disconnect from Server"), "connect_no", NULL, TQT_TQOBJECT(this), TQT_SLOT(disconnectFromServer()), ac, "disconnect_server"); disconnect_action = new KAction(i18n("Disconnect from Server"), "connect_no", KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(disconnectFromServer()), ac, "disconnect_server");
inst_sa_menu = new KAction(i18n("Launch Spectrum Analyzer"), "remote", NULL, TQT_TQOBJECT(this), TQT_SLOT(startSpectrumAnalyzer()), ac, "spectrum_analyzer"); inst_sa_menu = new KAction(i18n("Launch Spectrum Analyzer"), "remote", KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(startSpectrumAnalyzer()), ac, "spectrum_analyzer");
// Add Window menu // Add Window menu
if ( !isFakingSDIApplication() ) { if ( !isFakingSDIApplication() ) {
@ -85,21 +85,24 @@ RemoteMDI::~RemoteMDI()
while (m_rsvSvrSocket->state() == TQSocket::Closing) { while (m_rsvSvrSocket->state() == TQSocket::Closing) {
tqApp->processEvents(); tqApp->processEvents();
} }
delete m_rsvSvrSocket;
} }
} }
void RemoteMDI::connectToServer() { void RemoteMDI::connectToServer() {
if (m_rsvSvrSocket) { if (m_rsvSvrSocket) {
if (m_rsvSvrSocket->state() != TQSocket::Idle) {
return; return;
} }
}
connect_action->setEnabled(false); connect_action->setEnabled(false);
disconnect_action->setEnabled(false); disconnect_action->setEnabled(false);
// Connect to the central reservation/control server // Connect to the central reservation/control server
if (!m_rsvSvrSocket) {
m_rsvSvrSocket = new TDEKerberosClientSocket(this); m_rsvSvrSocket = new TDEKerberosClientSocket(this);
connect(m_rsvSvrSocket, SIGNAL(connectionClosed()), this, SLOT(connectionClosedHandler())); connect(m_rsvSvrSocket, SIGNAL(connectionClosed()), this, SLOT(connectionClosedHandler()));
}
m_rsvSvrSocket->setServiceName("remotefpga"); m_rsvSvrSocket->setServiceName("remotefpga");
if (m_serverHost != "") { if (m_serverHost != "") {
m_rsvSvrSocket->setServerFQDN(m_serverHost); m_rsvSvrSocket->setServerFQDN(m_serverHost);
@ -116,18 +119,16 @@ void RemoteMDI::connectToServer() {
else { else {
// Connection established! // Connection established!
// Read magic number and proto version from server // Read magic number and proto version from server
TQDataStream ds(m_rsvSvrSocket); TQDataStream* ds = new TQDataStream(m_rsvSvrSocket);
TQ_UINT32 magicnum; TQ_UINT32 magicnum;
TQ_UINT32 protover; TQ_UINT32 protover;
ds >> magicnum; *ds >> magicnum;
ds >> protover; *ds >> protover;
printf("[RAJA DEBUG 200.0] Got magic %d and proto %d\n\r", magicnum, protover); fflush(stdout); printf("[DEBUG] Got magic number %d and protocol version %d\n\r", magicnum, protover); fflush(stdout);
delete ds;
if ((magicnum == MAGIC_NUMBER) && (protover == PROTOCOL_VERSION)) { if ((magicnum == MAGIC_NUMBER) && (protover == PROTOCOL_VERSION)) {
disconnect_action->setEnabled(true); disconnect_action->setEnabled(true);
promptForStationType();
// Read the next line from the server
TQString str = m_rsvSvrSocket->readLine();
printf("[RAJA DEBUG 200.1] Got %s\n\r", str.ascii()); fflush(stdout);
} }
else { else {
disconnectFromServer(); disconnectFromServer();
@ -148,6 +149,24 @@ void RemoteMDI::connectToServer() {
processLockouts(); processLockouts();
} }
void RemoteMDI::promptForStationType() {
if (!m_rsvSvrSocket) {
return;
}
if (m_rsvSvrSocket->state() != TQSocket::Connected) {
return;
}
TQDataStream ds(m_rsvSvrSocket);
// Request list of laboratory stations
StationList slist;
ds << TQString("LIST");
ds >> slist;
printf("[RAJA DEBUG 200.2] Got list of stations, count is %d\n\r", slist.count()); fflush(stdout);
}
void RemoteMDI::disconnectFromServer() { void RemoteMDI::disconnectFromServer() {
connect_action->setEnabled(false); connect_action->setEnabled(false);
disconnect_action->setEnabled(false); disconnect_action->setEnabled(false);
@ -157,8 +176,6 @@ void RemoteMDI::disconnectFromServer() {
while (m_rsvSvrSocket->state() == TQSocket::Closing) { while (m_rsvSvrSocket->state() == TQSocket::Closing) {
tqApp->processEvents(); tqApp->processEvents();
} }
delete m_rsvSvrSocket;
m_rsvSvrSocket = 0;
} }
connect_action->setEnabled(true); connect_action->setEnabled(true);
@ -239,20 +256,10 @@ void RemoteMDI::openNewWindow(KMdiChildView *view)
void RemoteMDI::childWindowCloseRequest(KMdiChildView *pWnd) { void RemoteMDI::childWindowCloseRequest(KMdiChildView *pWnd) {
RemoteLab::InstrumentView* iview = dynamic_cast<RemoteLab::InstrumentView*>(pWnd); RemoteLab::InstrumentView* iview = dynamic_cast<RemoteLab::InstrumentView*>(pWnd);
if (iview) { if (iview) {
// Give the child a chance to finish what it was doing and exit cleanly (i.e. without crashing!)
iview->closeConnections(); iview->closeConnections();
iview->hide(); iview->hide();
// Give the child a chance to finish what it was doing KMdiMainFrm::childWindowCloseRequest(pWnd);
// FIXME HACK
// There is no nice way to shut down the instrument parts it seems...
// Debug why they crash when this delay is set to zero!
m_closelist.append(pWnd);
TQTimer::singleShot(100, this, SLOT(processCloseList()));
}
}
void RemoteMDI::processCloseList() {
if (m_closelist.begin() != m_closelist.end()) {
KMdiMainFrm::childWindowCloseRequest(*m_closelist.begin());
} }
} }

@ -47,7 +47,6 @@ class RemoteMDI : public KMdiMainFrm
public slots: public slots:
virtual void childWindowCloseRequest(KMdiChildView *pWnd); virtual void childWindowCloseRequest(KMdiChildView *pWnd);
void processCloseList();
protected slots: protected slots:
void openNewWindow(KMdiChildView *view=0); void openNewWindow(KMdiChildView *view=0);
@ -62,6 +61,7 @@ class RemoteMDI : public KMdiMainFrm
void configKeys(); void configKeys();
void connectToServer(); void connectToServer();
void disconnectFromServer(); void disconnectFromServer();
void promptForStationType();
void connectionClosedHandler(); void connectionClosedHandler();
void processLockouts(); void processLockouts();
void startSpectrumAnalyzer(); void startSpectrumAnalyzer();
@ -73,7 +73,6 @@ class RemoteMDI : public KMdiMainFrm
TQString m_serverHost; TQString m_serverHost;
TQValueList<KMdiChildView*> m_window; TQValueList<KMdiChildView*> m_window;
TQValueList<KMdiChildView*> m_closelist;
KListBox *m_listBox; KListBox *m_listBox;
TDEKerberosClientSocket* m_rsvSvrSocket; TDEKerberosClientSocket* m_rsvSvrSocket;

@ -1,4 +1,5 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/src -I$(top_srcdir)/src/widgets INCLUDES = $(all_includes) -I$(top_srcdir)/src -I$(top_srcdir)/src/widgets
KDE_CXXFLAGS = $(USE_EXCEPTIONS)
METASOURCES = AUTO METASOURCES = AUTO
#Part #Part

@ -26,6 +26,12 @@
#include "floatspinbox.h" #include "floatspinbox.h"
#include "layout.h" #include "layout.h"
/* exception handling */
struct exit_exception {
int c;
exit_exception(int c):c(c) { }
};
namespace RemoteLab { namespace RemoteLab {
typedef KParts::GenericFactory<RemoteLab::CommAnalyzerPart> Factory; typedef KParts::GenericFactory<RemoteLab::CommAnalyzerPart> Factory;
@ -89,6 +95,10 @@ bool CommAnalyzerPart::closeURL() {
m_url = KURL(); m_url = KURL();
if (m_instrumentMutex->locked()) {
throw exit_exception(-1);
}
return true; return true;
} }
@ -97,6 +107,7 @@ TQString CommAnalyzerPart::callServerMethod(int command) {
printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout); printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
return TQString::null; return TQString::null;
} }
try {
m_instrumentMutex->lock(); m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) { if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command); TQString cmd = TQChar(command);
@ -119,12 +130,18 @@ TQString CommAnalyzerPart::callServerMethod(int command) {
return TQString::null; return TQString::null;
} }
} }
catch (exit_exception& e) {
m_instrumentMutex->unlock();
return TQString::null;
}
}
int16_t CommAnalyzerPart::callServerMethodInt16(int command) { int16_t CommAnalyzerPart::callServerMethodInt16(int command) {
if (m_instrumentMutex->locked() == true) { if (m_instrumentMutex->locked() == true) {
printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout); printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
return 0; return 0;
} }
try {
m_instrumentMutex->lock(); m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) { if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command); TQString cmd = TQChar(command);
@ -156,12 +173,18 @@ int16_t CommAnalyzerPart::callServerMethodInt16(int command) {
return 0; return 0;
} }
} }
catch (exit_exception& e) {
m_instrumentMutex->unlock();
return 0;
}
}
double CommAnalyzerPart::callServerMethodDouble(int command) { double CommAnalyzerPart::callServerMethodDouble(int command) {
if (m_instrumentMutex->locked() == true) { if (m_instrumentMutex->locked() == true) {
printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout); printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
return 0; return 0;
} }
try {
m_instrumentMutex->lock(); m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) { if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command); TQString cmd = TQChar(command);
@ -193,12 +216,18 @@ double CommAnalyzerPart::callServerMethodDouble(int command) {
return 0; return 0;
} }
} }
catch (exit_exception& e) {
m_instrumentMutex->unlock();
return 0;
}
}
void CommAnalyzerPart::sendServerCommandWithParameter(int command, TQString param) { void CommAnalyzerPart::sendServerCommandWithParameter(int command, TQString param) {
if (m_instrumentMutex->locked() == true) { if (m_instrumentMutex->locked() == true) {
printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout); printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
return; return;
} }
try {
m_instrumentMutex->lock(); m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) { if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command); TQString cmd = TQChar(command);
@ -216,6 +245,12 @@ void CommAnalyzerPart::sendServerCommandWithParameter(int command, TQString para
} }
} }
m_instrumentMutex->unlock(); m_instrumentMutex->unlock();
return;
}
catch (exit_exception& e) {
m_instrumentMutex->unlock();
return;
}
} }
void CommAnalyzerPart::sendServerCommand(int command) { void CommAnalyzerPart::sendServerCommand(int command) {
@ -223,6 +258,7 @@ void CommAnalyzerPart::sendServerCommand(int command) {
printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout); printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
return; return;
} }
try {
m_instrumentMutex->lock(); m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) { if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command); TQString cmd = TQChar(command);
@ -239,6 +275,12 @@ void CommAnalyzerPart::sendServerCommand(int command) {
} }
} }
m_instrumentMutex->unlock(); m_instrumentMutex->unlock();
return;
}
catch (exit_exception& e) {
m_instrumentMutex->unlock();
return;
}
} }
void CommAnalyzerPart::callServerMethodDoubleArray(int command, double * array, int arrayLen) { void CommAnalyzerPart::callServerMethodDoubleArray(int command, double * array, int arrayLen) {
@ -246,6 +288,7 @@ void CommAnalyzerPart::callServerMethodDoubleArray(int command, double * array,
printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout); printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
return; return;
} }
try {
m_instrumentMutex->lock(); m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) { if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command); TQString cmd = TQChar(command);
@ -293,15 +336,17 @@ void CommAnalyzerPart::callServerMethodDoubleArray(int command, double * array,
} }
} }
m_instrumentMutex->unlock(); m_instrumentMutex->unlock();
return;
}
catch (exit_exception& e) {
m_instrumentMutex->unlock();
return;
}
} }
int CommAnalyzerPart::connectToServer(TQString server) { int CommAnalyzerPart::connectToServer(TQString server) {
if (!m_socket) { if (!m_socket) {
m_socket = new TQSocket(this); m_socket = new TQSocket(this);
// connect(m_socket, SIGNAL(connected()), SLOT(socketConnected()));
// connect(m_socket, SIGNAL(connectionClosed()), SLOT(socketConnectionClosed()));
// connect(m_socket, SIGNAL(readyRead()), SLOT(socketReadyRead()));
// connect(m_socket, SIGNAL(error(int)), SLOT(socketError(int)));
} }
m_socket->connectToHost(server, 4002); m_socket->connectToHost(server, 4002);
while ((m_socket->state() != TQSocket::Connected) && (m_socket->state() != TQSocket::Idle)) { while ((m_socket->state() != TQSocket::Connected) && (m_socket->state() != TQSocket::Idle)) {

@ -1,4 +1,5 @@
INCLUDES = $(all_includes) -I/usr/include/sasl INCLUDES = $(all_includes) -I/usr/include/sasl
KDE_CXXFLAGS = $(USE_EXCEPTIONS)
METASOURCES = AUTO METASOURCES = AUTO
# Create a shared library file # Create a shared library file

@ -31,6 +31,12 @@
#define NET_SEC_BUF_SIZE (2048) #define NET_SEC_BUF_SIZE (2048)
/* exception handling */
struct exit_exception {
int c;
exit_exception(int c):c(c) { }
};
class SASLDataPrivate class SASLDataPrivate
{ {
public: public:
@ -38,6 +44,16 @@ class SASLDataPrivate
sasl_conn_t *m_krbConnection; 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) { static int logSASLMessages(void *context __attribute__((unused)), int priority, const char *message) {
const char *label; const char *label;
@ -62,7 +78,7 @@ static int logSASLMessages(void *context __attribute__((unused)), int priority,
return SASL_OK; 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 = new SASLDataPrivate;
saslData->m_krbConnection = NULL; saslData->m_krbConnection = NULL;
} }
@ -81,6 +97,9 @@ bool TDEKerberosClientSocket::open(int mode) {
void TDEKerberosClientSocket::close() { void TDEKerberosClientSocket::close() {
TQSocket::close(); TQSocket::close();
if (m_criticalSection > 0) {
throw exit_exception(-1);
}
} }
int TDEKerberosClientSocket::setUsingKerberos(bool krbactive) { int TDEKerberosClientSocket::setUsingKerberos(bool krbactive) {
@ -213,7 +232,9 @@ void TDEKerberosClientSocket::sendSASLDataToNetwork(const char *buffer, unsigned
free(buf); free(buf);
} }
unsigned int TDEKerberosClientSocket::getSASLDataFromNetwork(char *buf, int trunclen) { int TDEKerberosClientSocket::getSASLDataFromNetwork(char *buf, int trunclen) {
m_criticalSection++;
try {
unsigned int len; unsigned int len;
int result; int result;
@ -223,6 +244,7 @@ unsigned int TDEKerberosClientSocket::getSASLDataFromNetwork(char *buf, int trun
while (1) { while (1) {
tqApp->processEvents(); tqApp->processEvents();
if (state() != TQSocket::Connected) { if (state() != TQSocket::Connected) {
m_criticalSection--;
return -1; return -1;
} }
if (TQSocket::readBlock(ba.data()+len, 1) > 0) { if (TQSocket::readBlock(ba.data()+len, 1) > 0) {
@ -234,6 +256,9 @@ unsigned int TDEKerberosClientSocket::getSASLDataFromNetwork(char *buf, int trun
len++; len++;
} }
} }
else {
usleep(1000);
}
if (len >= (ba.size()-1)) { if (len >= (ba.size()-1)) {
ba.resize(ba.size()+2048); ba.resize(ba.size()+2048);
} }
@ -243,12 +268,19 @@ unsigned int TDEKerberosClientSocket::getSASLDataFromNetwork(char *buf, int trun
result = sasl_decode64(ba.data(), strlen(ba.data()), buf, trunclen, &len); result = sasl_decode64(ba.data(), strlen(ba.data()), buf, trunclen, &len);
if (result != SASL_OK) { if (result != SASL_OK) {
printf("[ERROR] Decoding data from base64 returned %s (%d)\n\r", sasl_errstring(result, NULL, NULL), result); printf("[ERROR] Decoding data from base64 returned %s (%d)\n\r", sasl_errstring(result, NULL, NULL), result);
m_criticalSection--;
return -1; return -1;
} }
buf[len] = '\0'; buf[len] = '\0';
m_criticalSection--;
return len; return len;
} }
catch(exit_exception& e) {
m_criticalSection--;
return -1;
}
}
int TDEKerberosClientSocket::transmitEncryptedData(int fd, const char* readbuf, int cc) { int TDEKerberosClientSocket::transmitEncryptedData(int fd, const char* readbuf, int cc) {
int result = 0; int result = 0;
@ -257,7 +289,7 @@ int TDEKerberosClientSocket::transmitEncryptedData(int fd, const char* readbuf,
result=sasl_encode(saslData->m_krbConnection, readbuf, cc, &data, &len); result=sasl_encode(saslData->m_krbConnection, readbuf, cc, &data, &len);
if (result != SASL_OK) { 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; return -1;
} }
sendSASLDataToNetwork(data, len, fd); sendSASLDataToNetwork(data, len, fd);
@ -273,11 +305,14 @@ int TDEKerberosClientSocket::receiveEncryptedData(char *buf, int trunclen) {
char *encbuf = (char*)malloc(m_negotiatedMaxBufferSize); char *encbuf = (char*)malloc(m_negotiatedMaxBufferSize);
len = getSASLDataFromNetwork(encbuf, m_negotiatedMaxBufferSize); len = getSASLDataFromNetwork(encbuf, m_negotiatedMaxBufferSize);
if (len < 0) {
return -1;
}
if (len >= 0) { if (len >= 0) {
result=sasl_decode(saslData->m_krbConnection, encbuf, len, &recv_data, &recv_len); result=sasl_decode(saslData->m_krbConnection, encbuf, len, &recv_data, &recv_len);
if (result != SASL_OK) { if (result != SASL_OK) {
free(encbuf); 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; return -1;
} }
if (recv_len > trunclen) { if (recv_len > trunclen) {
@ -287,7 +322,7 @@ int TDEKerberosClientSocket::receiveEncryptedData(char *buf, int trunclen) {
} }
free(encbuf); free(encbuf);
return 0; return recv_len;
} }
int TDEKerberosClientSocket::initializeKerberosInterface() { int TDEKerberosClientSocket::initializeKerberosInterface() {
@ -303,6 +338,7 @@ int TDEKerberosClientSocket::initializeKerberosInterface() {
sasl_security_properties_t secprops; sasl_security_properties_t secprops;
const char *chosenmech; const char *chosenmech;
unsigned int len; unsigned int len;
int slen;
const char *data; const char *data;
char user_authorized = 0; char user_authorized = 0;
sasl_ssf_t *ssf; sasl_ssf_t *ssf;
@ -350,7 +386,11 @@ int TDEKerberosClientSocket::initializeKerberosInterface() {
} }
printf("[DEBUG] Waiting for mechanism list from server...\n\r"); 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); printf("Choosing best mechanism from: %s\n", buf);
@ -383,10 +423,11 @@ int TDEKerberosClientSocket::initializeKerberosInterface() {
while (result == SASL_CONTINUE) { while (result == SASL_CONTINUE) {
printf("[DEBUG] Waiting for server reply...\n\r"); printf("[DEBUG] Waiting for server reply...\n\r");
len = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE); slen = getSASLDataFromNetwork(buf, NET_SEC_BUF_SIZE);
if (state() != TQSocket::Connected) { if (slen < 0) {
return -1; return -2;
} }
len = slen;
result = sasl_client_step(saslData->m_krbConnection, buf, len, NULL, &data, &len); result = sasl_client_step(saslData->m_krbConnection, buf, len, NULL, &data, &len);
if (result != SASL_OK && result != SASL_CONTINUE) { if (result != SASL_OK && result != SASL_CONTINUE) {
printf("[ERROR] Performing SASL negotiation returned %s (%d)\n\r", sasl_errstring(result, NULL, NULL), result); printf("[ERROR] Performing SASL negotiation returned %s (%d)\n\r", sasl_errstring(result, NULL, NULL), result);

@ -51,7 +51,7 @@ class TDEKerberosClientSocket : public TQSocket
int initializeKerberosInterface(); int initializeKerberosInterface();
void freeKerberosConnection(); void freeKerberosConnection();
void sendSASLDataToNetwork(const char *buffer, unsigned length, int netfd); 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 transmitEncryptedData(int fd, const char* readbuf, int cc);
int receiveEncryptedData(char *buf, int trunclen); int receiveEncryptedData(char *buf, int trunclen);
@ -59,6 +59,7 @@ class TDEKerberosClientSocket : public TQSocket
bool m_kerberosRequested; bool m_kerberosRequested;
TQString m_serviceName; TQString m_serviceName;
TQString m_serverFQDN; TQString m_serverFQDN;
int m_criticalSection;
private: private:
SASLDataPrivate *saslData; SASLDataPrivate *saslData;

@ -31,6 +31,12 @@
#define NET_SEC_BUF_SIZE (2048) #define NET_SEC_BUF_SIZE (2048)
/* exception handling */
struct exit_exception {
int c;
exit_exception(int c):c(c) { }
};
class SASLDataPrivate class SASLDataPrivate
{ {
public: public:
@ -38,6 +44,16 @@ class SASLDataPrivate
sasl_conn_t *m_krbConnection; 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) { static int logSASLMessages(void *context __attribute__((unused)), int priority, const char *message) {
const char *label; const char *label;
@ -62,7 +78,7 @@ static int logSASLMessages(void *context __attribute__((unused)), int priority,
return SASL_OK; 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 = new SASLDataPrivate;
saslData->m_krbConnection = NULL; saslData->m_krbConnection = NULL;
} }
@ -81,6 +97,9 @@ bool TDEKerberosServerSocket::open(int mode) {
void TDEKerberosServerSocket::close() { void TDEKerberosServerSocket::close() {
TQSocket::close(); TQSocket::close();
if (m_criticalSection > 0) {
throw exit_exception(-1);
}
} }
int TDEKerberosServerSocket::setUsingKerberos(bool krbactive) { int TDEKerberosServerSocket::setUsingKerberos(bool krbactive) {
@ -213,7 +232,9 @@ void TDEKerberosServerSocket::sendSASLDataToNetwork(const char *buffer, unsigned
free(buf); free(buf);
} }
unsigned int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trunclen) { int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trunclen) {
m_criticalSection++;
try {
unsigned int len; unsigned int len;
int result; int result;
@ -223,6 +244,7 @@ unsigned int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trun
while (1) { while (1) {
tqApp->processEvents(); tqApp->processEvents();
if (state() != TQSocket::Connected) { if (state() != TQSocket::Connected) {
m_criticalSection--;
return -1; return -1;
} }
if (TQSocket::readBlock(ba.data()+len, 1) > 0) { if (TQSocket::readBlock(ba.data()+len, 1) > 0) {
@ -234,6 +256,9 @@ unsigned int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trun
len++; len++;
} }
} }
else {
usleep(1000);
}
if (len >= (ba.size()-1)) { if (len >= (ba.size()-1)) {
ba.resize(ba.size()+2048); ba.resize(ba.size()+2048);
} }
@ -243,12 +268,19 @@ unsigned int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trun
result = sasl_decode64(ba.data(), strlen(ba.data()), buf, trunclen, &len); result = sasl_decode64(ba.data(), strlen(ba.data()), buf, trunclen, &len);
if (result != SASL_OK) { if (result != SASL_OK) {
printf("[ERROR] Decoding data from base64 returned %s (%d)\n\r", sasl_errstring(result, NULL, NULL), result); printf("[ERROR] Decoding data from base64 returned %s (%d)\n\r", sasl_errstring(result, NULL, NULL), result);
m_criticalSection--;
return -1; return -1;
} }
buf[len] = '\0'; buf[len] = '\0';
m_criticalSection--;
return len; return len;
} }
catch(exit_exception& e) {
m_criticalSection--;
return -1;
}
}
int TDEKerberosServerSocket::transmitEncryptedData(int fd, const char* readbuf, int cc) { int TDEKerberosServerSocket::transmitEncryptedData(int fd, const char* readbuf, int cc) {
int result = 0; int result = 0;
@ -257,7 +289,7 @@ int TDEKerberosServerSocket::transmitEncryptedData(int fd, const char* readbuf,
result=sasl_encode(saslData->m_krbConnection, readbuf, cc, &data, &len); result=sasl_encode(saslData->m_krbConnection, readbuf, cc, &data, &len);
if (result != SASL_OK) { 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; return -1;
} }
sendSASLDataToNetwork(data, len, fd); sendSASLDataToNetwork(data, len, fd);
@ -273,11 +305,14 @@ int TDEKerberosServerSocket::receiveEncryptedData(char *buf, int trunclen) {
char *encbuf = (char*)malloc(m_negotiatedMaxBufferSize); char *encbuf = (char*)malloc(m_negotiatedMaxBufferSize);
len = getSASLDataFromNetwork(encbuf, m_negotiatedMaxBufferSize); len = getSASLDataFromNetwork(encbuf, m_negotiatedMaxBufferSize);
if (len < 0) {
return -1;
}
if (len >= 0) { if (len >= 0) {
result=sasl_decode(saslData->m_krbConnection, encbuf, len, &recv_data, &recv_len); result=sasl_decode(saslData->m_krbConnection, encbuf, len, &recv_data, &recv_len);
if (result != SASL_OK) { if (result != SASL_OK) {
free(encbuf); 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; return -1;
} }
if (recv_len > trunclen) { if (recv_len > trunclen) {
@ -287,7 +322,7 @@ int TDEKerberosServerSocket::receiveEncryptedData(char *buf, int trunclen) {
} }
free(encbuf); free(encbuf);
return 0; return recv_len;
} }
int TDEKerberosServerSocket::initializeKerberosInterface() { int TDEKerberosServerSocket::initializeKerberosInterface() {
@ -303,6 +338,7 @@ int TDEKerberosServerSocket::initializeKerberosInterface() {
sasl_security_properties_t secprops; sasl_security_properties_t secprops;
const char *ext_authid = NULL; const char *ext_authid = NULL;
unsigned int len; unsigned int len;
int slen;
int count; int count;
const char *data; const char *data;
char user_authorized = 0; char user_authorized = 0;
@ -336,20 +372,20 @@ int TDEKerberosServerSocket::initializeKerberosInterface() {
result = sasl_server_init(saslData->m_callbacks, m_serviceName.ascii()); result = sasl_server_init(saslData->m_callbacks, m_serviceName.ascii());
if (result != SASL_OK) { 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; return -1;
} }
result = sasl_server_new(m_serviceName.ascii(), localdomain, userdomain, iplocal, ipremote, NULL, serverlast, &saslData->m_krbConnection); result = sasl_server_new(m_serviceName.ascii(), localdomain, userdomain, iplocal, ipremote, NULL, serverlast, &saslData->m_krbConnection);
if (result != SASL_OK) { 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; return -1;
} }
result = sasl_setprop(saslData->m_krbConnection, SASL_SEC_PROPS, &secprops); result = sasl_setprop(saslData->m_krbConnection, SASL_SEC_PROPS, &secprops);
if (result != SASL_OK) { 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(); freeKerberosConnection();
return -1; return -1;
} }
@ -357,7 +393,7 @@ int TDEKerberosServerSocket::initializeKerberosInterface() {
puts("[DEBUG] Generating client mechanism list..."); puts("[DEBUG] Generating client mechanism list...");
result = sasl_listmech(saslData->m_krbConnection, ext_authid, NULL, " ", NULL, &data, &len, &count); result = sasl_listmech(saslData->m_krbConnection, ext_authid, NULL, " ", NULL, &data, &len, &count);
if (result != SASL_OK) { 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(); freeKerberosConnection();
return -1; return -1;
} }
@ -366,9 +402,13 @@ int TDEKerberosServerSocket::initializeKerberosInterface() {
sendSASLDataToNetwork(data, len, socket()); sendSASLDataToNetwork(data, len, socket());
printf("[DEBUG] Waiting for client mechanism...\n\r"); 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) { 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 // An initial response is present
data = buf + strlen(buf) + 1; data = buf + strlen(buf) + 1;
len = len - (unsigned) 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); result = sasl_server_start(saslData->m_krbConnection, buf, data, len, &data, &len);
if (result != SASL_OK && result != SASL_CONTINUE) { 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(); freeKerberosConnection();
return -1; return -1;
} }
@ -395,11 +435,15 @@ int TDEKerberosServerSocket::initializeKerberosInterface() {
return -1; return -1;
} }
printf("[DEBUG] Waiting for client reply...\n\r"); 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; data = NULL;
result = sasl_server_step(saslData->m_krbConnection, buf, len, &data, &len); result = sasl_server_step(saslData->m_krbConnection, buf, len, &data, &len);
if (result != SASL_OK && result != SASL_CONTINUE) { 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(); freeKerberosConnection();
return -1; return -1;
} }

@ -51,7 +51,7 @@ class TDEKerberosServerSocket : public TQSocket
int initializeKerberosInterface(); int initializeKerberosInterface();
void freeKerberosConnection(); void freeKerberosConnection();
void sendSASLDataToNetwork(const char *buffer, unsigned length, int netfd); 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 transmitEncryptedData(int fd, const char* readbuf, int cc);
int receiveEncryptedData(char *buf, int trunclen); int receiveEncryptedData(char *buf, int trunclen);
@ -59,6 +59,7 @@ class TDEKerberosServerSocket : public TQSocket
bool m_kerberosRequested; bool m_kerberosRequested;
TQString m_serviceName; TQString m_serviceName;
TQString m_serverFQDN; TQString m_serverFQDN;
int m_criticalSection;
private: private:
SASLDataPrivate *saslData; SASLDataPrivate *saslData;

@ -23,10 +23,8 @@
#include <tqobject.h> #include <tqobject.h>
class StationType : TQObject class StationType
{ {
Q_OBJECT
public: public:
TQ_UINT32 type; TQ_UINT32 type;
TQValueList<TQ_UINT32> services; TQValueList<TQ_UINT32> services;
@ -40,4 +38,6 @@ Q_EXPORT TQDataStream &operator<<(TQDataStream &, const StationType &);
Q_EXPORT TQDataStream &operator>>(TQDataStream &, StationType &); Q_EXPORT TQDataStream &operator>>(TQDataStream &, StationType &);
#endif #endif
typedef TQValueList<StationType> StationList;
#endif // TQTRLA_H #endif // TQTRLA_H

@ -1,4 +1,5 @@
INCLUDES= $(all_includes) $(KDE_INCLUDES)/tde -I/usr/include/sasl INCLUDES= $(all_includes) $(KDE_INCLUDES)/tde -I/usr/include/sasl
KDE_CXXFLAGS = $(USE_EXCEPTIONS)
bin_PROGRAMS = remotefpga_authserver bin_PROGRAMS = remotefpga_authserver

@ -24,18 +24,23 @@
#include "auth_conn.h" #include "auth_conn.h"
/* exception handling */
struct exit_exception {
int c;
exit_exception(int c):c(c) { }
};
/* /*
The AuthSocket class provides a socket that is connected with a client. The AuthSocket class provides a socket that is connected with a client.
For every client that connects to the server, the server creates a new For every client that connects to the server, the server creates a new
instance of this class. instance of this class.
*/ */
AuthSocket::AuthSocket(int sock, TQObject *parent, const char *name) : AuthSocket::AuthSocket(int sock, TQObject *parent, const char *name) :
TDEKerberosServerSocket( parent, name ) { TDEKerberosServerSocket( parent, name ), m_criticalSection(0) {
setServiceName("remotefpga"); setServiceName("remotefpga");
line = 0; line = 0;
connect(this, SIGNAL(connectionClosed()), SLOT(deleteLater()));
connect(this, SIGNAL(connectionClosed()), SLOT(connectionClosedHandler())); connect(this, SIGNAL(connectionClosed()), SLOT(connectionClosedHandler()));
setSocket( sock ); setSocket( sock );
} }
@ -45,17 +50,18 @@ AuthSocket::~AuthSocket() {
} }
void AuthSocket::close() { void AuthSocket::close() {
TQSocket::close(); TDEKerberosServerSocket::close();
connectionClosedHandler(); connectionClosedHandler();
} }
void AuthSocket::connectionClosedHandler() { void AuthSocket::connectionClosedHandler() {
printf("[DEBUG] Connection from %s closed\n\r", m_remoteHost.ascii()); printf("[DEBUG] Connection from %s closed\n\r", m_remoteHost.ascii());
if (m_criticalSection > 0) {
throw exit_exception(-1);
}
} }
int AuthSocket::initiateKerberosHandshake() { int AuthSocket::initiateKerberosHandshake() {
bool user_authorized = false;
if (setUsingKerberos(true) == 0) { if (setUsingKerberos(true) == 0) {
TQ_UINT32 magicnum = MAGIC_NUMBER; TQ_UINT32 magicnum = MAGIC_NUMBER;
TQ_UINT32 protover = PROTOCOL_VERSION; TQ_UINT32 protover = PROTOCOL_VERSION;
@ -64,19 +70,42 @@ int AuthSocket::initiateKerberosHandshake() {
ds << magicnum; ds << magicnum;
ds << protover; ds << protover;
// RAJA FIXME return 0;
if (user_authorized == 1) { }
// Send list of available servers... else {
writeBlock("OK<EFBFBD>", strlen("OK<EFBFBD>")); return -1;
}
} }
writeBlock("TESTING", strlen("TESTING")); int AuthSocket::enterCommandLoop() {
m_criticalSection++;
try {
TQString command;
TQDataStream ds(this);
return 0; while (state() == TQSocket::Connected) {
ds >> command;
printf("[RAJA DEBUG 500.0] Got command %s\n\r", command.ascii()); fflush(stdout);
if (command == "LIST") {
// Send list of available servers...
// RAJA FIXME
StationList slist;
ds << slist;
} }
else { else {
ds << "ERRINVCMD";
}
tqApp->processEvents();
}
m_criticalSection--;
return 0;
}
catch (...) {
m_criticalSection--;
return -1; return -1;
} }
} }
/* /*
@ -103,8 +132,12 @@ void AuthServer::newConnection(int socket) {
printf("[DEBUG] New connection from %s\n\r", s->m_remoteHost.ascii()); printf("[DEBUG] New connection from %s\n\r", s->m_remoteHost.ascii());
if (s->initiateKerberosHandshake() != 0) { if (s->initiateKerberosHandshake() != 0) {
s->close(); s->close();
delete s;
s = NULL;
} }
else { else {
connect(s, SIGNAL(connectionClosed()), s, SLOT(deleteLater()));
emit newConnect(s); emit newConnect(s);
s->enterCommandLoop();
} }
} }

@ -47,12 +47,14 @@ class AuthSocket : public TDEKerberosServerSocket
public: public:
void close(); void close();
int initiateKerberosHandshake(); int initiateKerberosHandshake();
int enterCommandLoop();
private slots: private slots:
void connectionClosedHandler(); void connectionClosedHandler();
private: private:
int line; int line;
int m_criticalSection;
TQString m_remoteHost; TQString m_remoteHost;
friend class AuthServer; friend class AuthServer;

Loading…
Cancel
Save