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"
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");
@ -42,9 +42,9 @@ RemoteMDI::RemoteMDI()
KStdAction::quit(TQT_TQOBJECT(this), TQT_SLOT(close()), ac);
KStdAction::configureToolbars(TQT_TQOBJECT(this), TQT_SLOT(configToolbars()), 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");
disconnect_action = new KAction(i18n("Disconnect from Server"), "connect_no", NULL, 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");
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", KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(disconnectFromServer()), ac, "disconnect_server");
inst_sa_menu = new KAction(i18n("Launch Spectrum Analyzer"), "remote", KShortcut(), TQT_TQOBJECT(this), TQT_SLOT(startSpectrumAnalyzer()), ac, "spectrum_analyzer");
// Add Window menu
if ( !isFakingSDIApplication() ) {
@ -85,21 +85,24 @@ RemoteMDI::~RemoteMDI()
while (m_rsvSvrSocket->state() == TQSocket::Closing) {
tqApp->processEvents();
}
delete m_rsvSvrSocket;
}
}
void RemoteMDI::connectToServer() {
if (m_rsvSvrSocket) {
return;
if (m_rsvSvrSocket->state() != TQSocket::Idle) {
return;
}
}
connect_action->setEnabled(false);
disconnect_action->setEnabled(false);
// Connect to the central reservation/control server
m_rsvSvrSocket = new TDEKerberosClientSocket(this);
connect(m_rsvSvrSocket, SIGNAL(connectionClosed()), this, SLOT(connectionClosedHandler()));
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);
@ -116,18 +119,16 @@ void RemoteMDI::connectToServer() {
else {
// Connection established!
// Read magic number and proto version from server
TQDataStream ds(m_rsvSvrSocket);
TQDataStream* ds = new TQDataStream(m_rsvSvrSocket);
TQ_UINT32 magicnum;
TQ_UINT32 protover;
ds >> magicnum;
ds >> protover;
printf("[RAJA DEBUG 200.0] Got magic %d and proto %d\n\r", magicnum, protover); fflush(stdout);
*ds >> magicnum;
*ds >> protover;
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)) {
disconnect_action->setEnabled(true);
// 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);
promptForStationType();
}
else {
disconnectFromServer();
@ -148,6 +149,24 @@ void RemoteMDI::connectToServer() {
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() {
connect_action->setEnabled(false);
disconnect_action->setEnabled(false);
@ -157,8 +176,6 @@ void RemoteMDI::disconnectFromServer() {
while (m_rsvSvrSocket->state() == TQSocket::Closing) {
tqApp->processEvents();
}
delete m_rsvSvrSocket;
m_rsvSvrSocket = 0;
}
connect_action->setEnabled(true);
@ -239,20 +256,10 @@ void RemoteMDI::openNewWindow(KMdiChildView *view)
void RemoteMDI::childWindowCloseRequest(KMdiChildView *pWnd) {
RemoteLab::InstrumentView* iview = dynamic_cast<RemoteLab::InstrumentView*>(pWnd);
if (iview) {
// Give the child a chance to finish what it was doing and exit cleanly (i.e. without crashing!)
iview->closeConnections();
iview->hide();
// Give the child a chance to finish what it was doing
// 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());
KMdiMainFrm::childWindowCloseRequest(pWnd);
}
}

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

@ -1,5 +1,6 @@
INCLUDES = $(all_includes) -I$(top_srcdir)/src -I$(top_srcdir)/src/widgets
METASOURCES = AUTO
INCLUDES = $(all_includes) -I$(top_srcdir)/src -I$(top_srcdir)/src/widgets
KDE_CXXFLAGS = $(USE_EXCEPTIONS)
METASOURCES = AUTO
#Part
kde_module_LTLIBRARIES = libremotelab_commanalyzer.la

@ -26,6 +26,12 @@
#include "floatspinbox.h"
#include "layout.h"
/* exception handling */
struct exit_exception {
int c;
exit_exception(int c):c(c) { }
};
namespace RemoteLab {
typedef KParts::GenericFactory<RemoteLab::CommAnalyzerPart> Factory;
@ -88,7 +94,11 @@ bool CommAnalyzerPart::closeURL() {
}
m_url = KURL();
if (m_instrumentMutex->locked()) {
throw exit_exception(-1);
}
return true;
}
@ -97,24 +107,30 @@ 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);
return TQString::null;
}
m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command);
cmd.append('\r');
m_socket->writeBlock(cmd.latin1(), cmd.length());
// Read from the server
TQString serverRet;
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
try {
m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command);
cmd.append('\r');
m_socket->writeBlock(cmd.latin1(), cmd.length());
// Read from the server
TQString serverRet;
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
m_instrumentMutex->unlock();
return serverRet;
}
else {
m_instrumentMutex->unlock();
return TQString::null;
}
m_instrumentMutex->unlock();
return serverRet;
}
else {
catch (exit_exception& e) {
m_instrumentMutex->unlock();
return TQString::null;
}
@ -125,33 +141,39 @@ int16_t CommAnalyzerPart::callServerMethodInt16(int command) {
printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
return 0;
}
m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command);
cmd.append('\r');
m_socket->writeBlock(cmd.latin1(), cmd.length());
// Read from the server
int bytesread = 0;
int16_t data[1];
while ((bytesread < 2) && (m_socket->state() == TQSocket::Connected)) {
int ret = m_socket->readBlock(((char*)data)+bytesread, 1);
if (ret > 0) {
bytesread += ret;
try {
m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command);
cmd.append('\r');
m_socket->writeBlock(cmd.latin1(), cmd.length());
// Read from the server
int bytesread = 0;
int16_t data[1];
while ((bytesread < 2) && (m_socket->state() == TQSocket::Connected)) {
int ret = m_socket->readBlock(((char*)data)+bytesread, 1);
if (ret > 0) {
bytesread += ret;
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
TQString serverRet;
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
TQString serverRet;
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
m_instrumentMutex->unlock();
return data[0];
}
else {
m_instrumentMutex->unlock();
return 0;
}
m_instrumentMutex->unlock();
return data[0];
}
else {
catch (exit_exception& e) {
m_instrumentMutex->unlock();
return 0;
}
@ -162,33 +184,39 @@ double CommAnalyzerPart::callServerMethodDouble(int command) {
printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
return 0;
}
m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command);
cmd.append('\r');
m_socket->writeBlock(cmd.latin1(), cmd.length());
// Read from the server
unsigned int bytesread = 0;
double data[1];
while ((bytesread < sizeof(double)) && (m_socket->state() == TQSocket::Connected)) {
int ret = m_socket->readBlock(((char*)data)+bytesread, 1);
if (ret > 0) {
bytesread += ret;
try {
m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command);
cmd.append('\r');
m_socket->writeBlock(cmd.latin1(), cmd.length());
// Read from the server
unsigned int bytesread = 0;
double data[1];
while ((bytesread < sizeof(double)) && (m_socket->state() == TQSocket::Connected)) {
int ret = m_socket->readBlock(((char*)data)+bytesread, 1);
if (ret > 0) {
bytesread += ret;
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
TQString serverRet;
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
TQString serverRet;
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
m_instrumentMutex->unlock();
return data[0];
}
else {
m_instrumentMutex->unlock();
return 0;
}
m_instrumentMutex->unlock();
return data[0];
}
else {
catch (exit_exception& e) {
m_instrumentMutex->unlock();
return 0;
}
@ -199,23 +227,30 @@ void CommAnalyzerPart::sendServerCommandWithParameter(int command, TQString para
printf("[WARN] An attempt was made to access the instrument asynchronously, and was rejected to prevent a lockup\n\r"); fflush(stdout);
return;
}
m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command);
param = TQString("%1%2%3").arg(param).arg(TQChar('°')).arg(TQChar('\r'));
cmd += param;
m_socket->writeBlock(cmd.ascii(), cmd.length());
// Read from the server
TQString serverRet;
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
try {
m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command);
param = TQString("%1%2%3").arg(param).arg(TQChar('°')).arg(TQChar('\r'));
cmd += param;
m_socket->writeBlock(cmd.ascii(), cmd.length());
// Read from the server
TQString serverRet;
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
m_instrumentMutex->unlock();
return;
}
catch (exit_exception& e) {
m_instrumentMutex->unlock();
return;
}
m_instrumentMutex->unlock();
}
void CommAnalyzerPart::sendServerCommand(int command) {
@ -223,22 +258,29 @@ 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);
return;
}
m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command);
cmd.append('\r');
m_socket->writeBlock(cmd.latin1(), cmd.length());
// Read from the server
TQString serverRet;
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
try {
m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command);
cmd.append('\r');
m_socket->writeBlock(cmd.latin1(), cmd.length());
// Read from the server
TQString serverRet;
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
m_instrumentMutex->unlock();
return;
}
catch (exit_exception& e) {
m_instrumentMutex->unlock();
return;
}
m_instrumentMutex->unlock();
}
void CommAnalyzerPart::callServerMethodDoubleArray(int command, double * array, int arrayLen) {
@ -246,62 +288,65 @@ 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);
return;
}
m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command);
cmd.append('\r');
m_socket->writeBlock(cmd.latin1(), cmd.length());
// Read from the server
TQString serverRet;
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
try {
m_instrumentMutex->lock();
if (m_socket->state() == TQSocket::Connected) {
TQString cmd = TQChar(command);
cmd.append('\r');
m_socket->writeBlock(cmd.latin1(), cmd.length());
// Read from the server
TQString serverRet;
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
unsigned int bytesread = 0;
int16_t data[1];
while ((bytesread < 2) && (m_socket->state() == TQSocket::Connected)) {
int ret = m_socket->readBlock(((char*)data)+bytesread, 1);
if (ret > 0) {
bytesread += ret;
unsigned int bytesread = 0;
int16_t data[1];
while ((bytesread < 2) && (m_socket->state() == TQSocket::Connected)) {
int ret = m_socket->readBlock(((char*)data)+bytesread, 1);
if (ret > 0) {
bytesread += ret;
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
serverRet = "";
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
serverRet = "";
while ((!serverRet.contains('\r')) && (m_socket->state() == TQSocket::Connected)) {
char data[1];
if( m_socket->readBlock(data, 1) > 0) {
serverRet.append(data[0]);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
bytesread = 0;
int elementsread = 0;
for (elementsread=0;elementsread<arrayLen;elementsread++) {
bytesread = 0;
while ((bytesread < sizeof(double)) && (m_socket->state() == TQSocket::Connected)) {
if (m_socket->size() < 1) {
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
int ret = m_socket->readBlock(((char*)array)+bytesread+(elementsread*sizeof(double)), 1);
if (ret > 0) {
bytesread += ret;
int elementsread = 0;
for (elementsread=0;elementsread<arrayLen;elementsread++) {
bytesread = 0;
while ((bytesread < sizeof(double)) && (m_socket->state() == TQSocket::Connected)) {
if (m_socket->size() < 1) {
tqApp->eventLoop()->processEvents(TQEventLoop::AllEvents);
}
int ret = m_socket->readBlock(((char*)array)+bytesread+(elementsread*sizeof(double)), 1);
if (ret > 0) {
bytesread += ret;
}
}
}
}
m_instrumentMutex->unlock();
return;
}
catch (exit_exception& e) {
m_instrumentMutex->unlock();
return;
}
m_instrumentMutex->unlock();
}
int CommAnalyzerPart::connectToServer(TQString server) {
if (!m_socket) {
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);
while ((m_socket->state() != TQSocket::Connected) && (m_socket->state() != TQSocket::Idle)) {

@ -1,5 +1,6 @@
INCLUDES = $(all_includes) -I/usr/include/sasl
METASOURCES = AUTO
INCLUDES = $(all_includes) -I/usr/include/sasl
KDE_CXXFLAGS = $(USE_EXCEPTIONS)
METASOURCES = AUTO
# Create a shared library file
lib_LTLIBRARIES = libtdekrbsocket.la
@ -8,4 +9,4 @@ include_HEADERS = tdekrbclientsocket.h tdekrbserversocket.h
libtdekrbsocket_la_SOURCES = tdekrbclientsocket.cpp tdekrbserversocket.cpp
libtdekrbsocket_la_LIBADD = -lkio $(LIB_TDEUI) -lsasl2
libtdekrbsocket_la_LDFLAGS = -avoid-version -module -no-undefined $(all_libraries)
libtdekrbsocket_la_LDFLAGS = -avoid-version -module -no-undefined $(all_libraries)

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

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

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

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

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

@ -24,18 +24,23 @@
#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.
For every client that connects to the server, the server creates a new
instance of this class.
*/
AuthSocket::AuthSocket(int sock, TQObject *parent, const char *name) :
TDEKerberosServerSocket( parent, name ) {
TDEKerberosServerSocket( parent, name ), m_criticalSection(0) {
setServiceName("remotefpga");
line = 0;
connect(this, SIGNAL(connectionClosed()), SLOT(deleteLater()));
connect(this, SIGNAL(connectionClosed()), SLOT(connectionClosedHandler()));
setSocket( sock );
}
@ -45,17 +50,18 @@ AuthSocket::~AuthSocket() {
}
void AuthSocket::close() {
TQSocket::close();
TDEKerberosServerSocket::close();
connectionClosedHandler();
}
void AuthSocket::connectionClosedHandler() {
printf("[DEBUG] Connection from %s closed\n\r", m_remoteHost.ascii());
if (m_criticalSection > 0) {
throw exit_exception(-1);
}
}
int AuthSocket::initiateKerberosHandshake() {
bool user_authorized = false;
if (setUsingKerberos(true) == 0) {
TQ_UINT32 magicnum = MAGIC_NUMBER;
TQ_UINT32 protover = PROTOCOL_VERSION;
@ -64,14 +70,6 @@ int AuthSocket::initiateKerberosHandshake() {
ds << magicnum;
ds << protover;
// RAJA FIXME
if (user_authorized == 1) {
// Send list of available servers...
writeBlock("OK<EFBFBD>", strlen("OK<EFBFBD>"));
}
writeBlock("TESTING", strlen("TESTING"));
return 0;
}
else {
@ -79,6 +77,37 @@ int AuthSocket::initiateKerberosHandshake() {
}
}
int AuthSocket::enterCommandLoop() {
m_criticalSection++;
try {
TQString command;
TQDataStream ds(this);
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 {
ds << "ERRINVCMD";
}
tqApp->processEvents();
}
m_criticalSection--;
return 0;
}
catch (...) {
m_criticalSection--;
return -1;
}
}
/*
The AuthServer class handles new connections to the server. For every
client that connects, it creates a new AuthSocket -- that instance is now
@ -103,8 +132,12 @@ void AuthServer::newConnection(int socket) {
printf("[DEBUG] New connection from %s\n\r", s->m_remoteHost.ascii());
if (s->initiateKerberosHandshake() != 0) {
s->close();
delete s;
s = NULL;
}
else {
connect(s, SIGNAL(connectionClosed()), s, SLOT(deleteLater()));
emit newConnect(s);
s->enterCommandLoop();
}
}

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

Loading…
Cancel
Save