From 1382b1f0c8d40386827dc49cb8fd7eb869e755aa Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Fri, 6 Jul 2012 11:43:35 -0500 Subject: [PATCH] Fix crash caused by improper SASL initialization --- clients/tde/src/app/remotemdi.cpp | 10 +-- clients/tde/src/part/fpgaprogram/part.cpp | 83 ++++++++++------- clients/tde/src/part/fpgaprogram/part.h | 1 + clients/tde/src/part/fpgaview/part.cpp | 88 +++++++++++-------- clients/tde/src/part/fpgaview/part.h | 1 + lib/libtdekrb/src/tdekrbclientsocket.cpp | 26 ++++-- lib/libtdekrb/src/tdekrbserversocket.cpp | 33 +++++-- servers/auth_server_lin/src/auth_conn.cpp | 1 + .../src/fpga_conn.cpp | 1 + servers/fpga_server_lin/src/fpga_conn.cpp | 1 + 10 files changed, 149 insertions(+), 96 deletions(-) diff --git a/clients/tde/src/app/remotemdi.cpp b/clients/tde/src/app/remotemdi.cpp index 8a566e2..eec5144 100644 --- a/clients/tde/src/app/remotemdi.cpp +++ b/clients/tde/src/app/remotemdi.cpp @@ -333,15 +333,7 @@ void RemoteMDI::disconnectFromServer() { unplugActionList("instrumentToolBar_actionlist"); // Close all windows - KMdiIterator *it = createIterator(); - while (it->currentItem()) { - KMdiChildView *c = dynamic_cast(it->currentItem()); - if (c) { - closeSpecifiedWindow(c); - } - it->next(); - } - deleteIterator(it); + closeAllViews(); if (m_rsvSvrSocket) { m_rsvSvrSocket->clearPendingData(); diff --git a/clients/tde/src/part/fpgaprogram/part.cpp b/clients/tde/src/part/fpgaprogram/part.cpp index b51c39a..0464c8b 100644 --- a/clients/tde/src/part/fpgaprogram/part.cpp +++ b/clients/tde/src/part/fpgaprogram/part.cpp @@ -79,6 +79,8 @@ FPGAProgramPart::FPGAProgramPart(TQWidget *parentWidget, const char *widgetName, // Create timers m_updateTimer = new TQTimer(this); + m_connectionTimer = new TQTimer(this); + connect(m_connectionTimer, SIGNAL(timeout()), this, SLOT(finishConnectingToServer())); // Create widgets m_base = new FPGAProgramBase(widget()); @@ -154,6 +156,8 @@ bool FPGAProgramPart::closeURL() { } void FPGAProgramPart::disconnectFromServer() { + m_connectionTimer->stop(); + m_updateTimer->stop(); if (m_socket) { m_socket->clearPendingData(); m_socket->close(); @@ -220,45 +224,56 @@ void FPGAProgramPart::finishConnectingToServer() { case 2: // Connection established! // Read magic number and proto version from server - TQDataStream ds(m_socket); - TQ_UINT32 magicnum; - TQ_UINT32 protover; - ds >> magicnum; - ds >> protover; - printf("[DEBUG] Got magic number %d and protocol version %d\n\r", magicnum, protover); fflush(stdout); - - // Request connection to backend server - TQString response; - ds << TQString("SERV"); - ds << TQString(CLIENT_LIBRARY); - ds >> response; -printf("[RAJA DEBUG 400.0] Got '%s' from the server\n\r", response.ascii()); fflush(stdout); - if (response == "OK") { + m_socket->processPendingData(); + if (m_socket->bytesAvailable() > 0) { + TQDataStream ds(m_socket); + TQ_UINT32 magicnum; + TQ_UINT32 protover; + ds >> magicnum; + ds >> protover; + printf("[DEBUG] Got magic number %d and protocol version %d\n\r", magicnum, protover); fflush(stdout); + + // Request connection to backend server + ds << TQString("SERV"); + ds << TQString(CLIENT_LIBRARY); connToServerState = 3; - connToServerConnecting = false; - connect(m_socket, SIGNAL(readyRead()), m_socket, SLOT(processPendingData())); - connect(m_socket, SIGNAL(newDataReceived()), this, SLOT(mainEventLoop())); - m_tickerState = 0; - m_commHandlerState = 0; - m_commHandlerMode = 0; - m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE); - processLockouts(); - mainEventLoop(); - return; } - else { - TQStringList errorStrings = textForServerError(response); - connToServerState = -1; - connToServerConnecting = false; - disconnectFromServer(); - KMessageBox::error(0, errorStrings[0], errorStrings[1]); - close(); - return; + break; + case 3: + // Read response from server + m_socket->processPendingData(); + if (m_socket->bytesAvailable() > 0) { + TQDataStream ds(m_socket); + TQString response; + ds >> response; +printf("[RAJA DEBUG 400.0] Got '%s' from the server\n\r", response.ascii()); fflush(stdout); + if (response == "OK") { + connToServerState = 4; + connToServerConnecting = false; + connect(m_socket, SIGNAL(readyRead()), m_socket, SLOT(processPendingData())); + connect(m_socket, SIGNAL(newDataReceived()), this, SLOT(mainEventLoop())); + m_tickerState = 0; + m_commHandlerState = 0; + m_commHandlerMode = 0; + m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE); + processLockouts(); + mainEventLoop(); + return; + } + else { + TQStringList errorStrings = textForServerError(response); + connToServerState = -1; + connToServerConnecting = false; + disconnectFromServer(); + KMessageBox::error(0, errorStrings[0], errorStrings[1]); + close(); + return; + } } break; } - TQTimer::singleShot(0, this, SLOT(finishConnectingToServer())); + m_connectionTimer->start(100, TRUE); } } @@ -277,7 +292,7 @@ int FPGAProgramPart::connectToServer(TQString server) { // Finish connecting when appropriate connToServerState = 0; connToServerConnecting = true; - TQTimer::singleShot(0, this, SLOT(finishConnectingToServer())); + m_connectionTimer->start(100, TRUE); return 0; } diff --git a/clients/tde/src/part/fpgaprogram/part.h b/clients/tde/src/part/fpgaprogram/part.h index f254cbc..5becdde 100644 --- a/clients/tde/src/part/fpgaprogram/part.h +++ b/clients/tde/src/part/fpgaprogram/part.h @@ -79,6 +79,7 @@ namespace RemoteLab TDEKerberosClientSocket* m_socket; FPGAProgramBase* m_base; TQMutex* m_connectionMutex; + TQTimer* m_connectionTimer; TQTimer* m_updateTimer; bool connToServerConnecting; diff --git a/clients/tde/src/part/fpgaview/part.cpp b/clients/tde/src/part/fpgaview/part.cpp index 755f25c..01c23b4 100644 --- a/clients/tde/src/part/fpgaview/part.cpp +++ b/clients/tde/src/part/fpgaview/part.cpp @@ -564,8 +564,9 @@ K_EXPORT_COMPONENT_FACTORY(libremotelab_fpgaviewer, RemoteLab::Factory) FPGAViewPart::FPGAViewPart(TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const TQStringList&) : RemoteInstrumentPart( parent, name ), m_socket(0), m_base(0), connToServerConnecting(false), connToServerState(-1), connToServerTimeoutTimer(NULL), m_interfaceMode(BasicInterfaceMode), - m_commHandlerState(0), m_connectionActiveAndValid(false), m_tickerState(0), m_remoteInputModeEnabled(false), m_4bitInputValue(0), m_4bitOutputValue(0), m_8bitInputValue(0), m_8bitOutputValue(0), - m_16bitInputValue(0), m_16bitOutputValue(0), m_7segDigit3OutputValue(0xffffffff), m_7segDigit2OutputValue(0xffffffff), m_7segDigit1OutputValue(0xffffffff), m_7segDigit0OutputValue(0xffffffff), + m_commHandlerState(0), m_commHandlerMode(0), m_connectionActiveAndValid(false), m_tickerState(0), m_remoteInputModeEnabled(false), m_4bitInputValue(0), m_4bitOutputValue(0), + m_8bitInputValue(0), m_8bitOutputValue(0), m_16bitInputValue(0), m_16bitOutputValue(0), m_7segDigit3OutputValue(0xffffffff), + m_7segDigit2OutputValue(0xffffffff), m_7segDigit1OutputValue(0xffffffff), m_7segDigit0OutputValue(0xffffffff), m_batchOutputFile(NULL), m_dataOutputFile(NULL) { // Initialize mutex @@ -577,6 +578,8 @@ FPGAViewPart::FPGAViewPart(TQWidget *parentWidget, const char *widgetName, TQObj // Create timers m_updateTimer = new TQTimer(this); + m_connectionTimer = new TQTimer(this); + connect(m_connectionTimer, SIGNAL(timeout()), this, SLOT(finishConnectingToServer())); // Create widgets m_base = new FPGAViewBase(widget()); @@ -984,6 +987,8 @@ bool FPGAViewPart::closeURL() { } void FPGAViewPart::disconnectFromServer() { + m_connectionTimer->stop(); + m_updateTimer->stop(); if (m_socket) { m_socket->clearPendingData(); m_socket->close(); @@ -1050,45 +1055,56 @@ void FPGAViewPart::finishConnectingToServer() { case 2: // Connection established! // Read magic number and proto version from server - TQDataStream ds(m_socket); - TQ_UINT32 magicnum; - TQ_UINT32 protover; - ds >> magicnum; - ds >> protover; - printf("[DEBUG] Got magic number %d and protocol version %d\n\r", magicnum, protover); fflush(stdout); - - // Request connection to backend server - TQString response; - ds << TQString("SERV"); - ds << TQString(CLIENT_LIBRARY); - ds >> response; -printf("[RAJA DEBUG 400.0] Got '%s' from the server\n\r", response.ascii()); fflush(stdout); - if (response == "OK") { + m_socket->processPendingData(); + if (m_socket->bytesAvailable() > 0) { + TQDataStream ds(m_socket); + TQ_UINT32 magicnum; + TQ_UINT32 protover; + ds >> magicnum; + ds >> protover; + printf("[DEBUG] Got magic number %d and protocol version %d\n\r", magicnum, protover); fflush(stdout); + + // Request connection to backend server + ds << TQString("SERV"); + ds << TQString(CLIENT_LIBRARY); connToServerState = 3; - connToServerConnecting = false; - connect(m_socket, SIGNAL(readyRead()), m_socket, SLOT(processPendingData())); - connect(m_socket, SIGNAL(newDataReceived()), this, SLOT(updateDisplay())); - m_tickerState = 0; - m_commHandlerState = 0; - m_commHandlerMode = 0; - m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE); - processLockouts(); - updateDisplay(); - return; } - else { - TQStringList errorStrings = textForServerError(response); - connToServerState = -1; - connToServerConnecting = false; - disconnectFromServer(); - KMessageBox::error(0, errorStrings[0], errorStrings[1]); - close(); - return; + break; + case 3: + // Read response from server + m_socket->processPendingData(); + if (m_socket->bytesAvailable() > 0) { + TQDataStream ds(m_socket); + TQString response; + ds >> response; +printf("[RAJA DEBUG 400.0] Got '%s' from the server\n\r", response.ascii()); fflush(stdout); + if (response == "OK") { + connToServerState = 4; + connToServerConnecting = false; + connect(m_socket, SIGNAL(readyRead()), m_socket, SLOT(processPendingData())); + connect(m_socket, SIGNAL(newDataReceived()), this, SLOT(updateDisplay())); + m_tickerState = 0; + m_commHandlerState = 0; + m_commHandlerMode = 0; + m_updateTimer->start(FPGA_COMM_TIMEOUT_MS, FALSE); + processLockouts(); + updateDisplay(); + return; + } + else { + TQStringList errorStrings = textForServerError(response); + connToServerState = -1; + connToServerConnecting = false; + disconnectFromServer(); + KMessageBox::error(0, errorStrings[0], errorStrings[1]); + close(); + return; + } } break; } - TQTimer::singleShot(0, this, SLOT(finishConnectingToServer())); + m_connectionTimer->start(100, TRUE); } } @@ -1107,7 +1123,7 @@ int FPGAViewPart::connectToServer(TQString server) { // Finish connecting when appropriate connToServerState = 0; connToServerConnecting = true; - TQTimer::singleShot(0, this, SLOT(finishConnectingToServer())); + m_connectionTimer->start(100, TRUE); return 0; } diff --git a/clients/tde/src/part/fpgaview/part.h b/clients/tde/src/part/fpgaview/part.h index 02d2773..a0b0463 100644 --- a/clients/tde/src/part/fpgaview/part.h +++ b/clients/tde/src/part/fpgaview/part.h @@ -186,6 +186,7 @@ namespace RemoteLab TDEKerberosClientSocket* m_socket; FPGAViewBase* m_base; TQMutex* m_connectionMutex; + TQTimer* m_connectionTimer; TQTimer* m_updateTimer; bool connToServerConnecting; diff --git a/lib/libtdekrb/src/tdekrbclientsocket.cpp b/lib/libtdekrb/src/tdekrbclientsocket.cpp index a286ff6..c1cade8 100644 --- a/lib/libtdekrb/src/tdekrbclientsocket.cpp +++ b/lib/libtdekrb/src/tdekrbclientsocket.cpp @@ -50,6 +50,9 @@ delete m_canary; \ m_canary = NULL; +static bool tde_krb_sasl_client_initialized = false; +static sasl_callback_t tde_krb_sasl_client_callbacks[N_CALLBACKS]; + /* exception handling */ struct exit_exception { int c; @@ -59,7 +62,6 @@ struct exit_exception { class SASLDataPrivate { public: - sasl_callback_t m_callbacks[N_CALLBACKS]; sasl_conn_t *m_krbConnection; }; @@ -113,6 +115,7 @@ TDEKerberosClientSocket::~TDEKerberosClientSocket() { delete kerberosInitLoopTimer; kerberosInitLoopTimer = NULL; } + setUsingKerberos(false); m_buffer->close(); delete m_buffer; delete saslData; @@ -533,7 +536,7 @@ void TDEKerberosClientSocket::sendSASLDataToNetwork(const char *buffer, unsigned unsigned len, alloclen; int result; - alloclen = ((length / 3) + 1) * 4 + 1; + alloclen = (((length / 3) + 1) * 4) + 1; buf = (char*)malloc(alloclen+1); if (!buf) { printf("[ERROR] Unable to malloc()!\n\r"); @@ -834,7 +837,8 @@ void TDEKerberosClientSocket::continueKerberosInitialization() { else { printf("[DEBUG] Authenticated username: %s\n\r", data ? data : "(NULL)"); } - + +#if 0 m_krbInitResult = sasl_getprop(saslData->m_krbConnection, SASL_DEFUSERREALM, (const void **)&data); if (m_krbInitResult != SASL_OK) { printf("[WARNING] Unable to determine authenticated realm!\n\r"); @@ -842,6 +846,7 @@ void TDEKerberosClientSocket::continueKerberosInitialization() { else { printf("[DEBUG] Authenticated realm: %s\n\r", data ? data : "(NULL)"); } +#endif m_krbInitResult = sasl_getprop(saslData->m_krbConnection, SASL_SSF, (const void **)&ssf); if (m_krbInitResult != SASL_OK) { @@ -850,7 +855,7 @@ void TDEKerberosClientSocket::continueKerberosInitialization() { else { printf("[DEBUG] Authenticated SSF: %d\n", *ssf); } - + m_krbInitResult = sasl_getprop(saslData->m_krbConnection, SASL_MAXOUTBUF, (const void **)&m_negotiatedMaxBufferSize); if (m_krbInitResult != SASL_OK) { printf("[WARNING] Unable to determine maximum buffer size!\n\r"); @@ -896,7 +901,7 @@ int TDEKerberosClientSocket::initializeKerberosInterface() { const char *service = m_serviceName.ascii(); const char *fqdn = m_serverFQDN.ascii(); - callback = saslData->m_callbacks; + callback = tde_krb_sasl_client_callbacks; // log callback->id = SASL_CB_LOG; @@ -915,10 +920,13 @@ int TDEKerberosClientSocket::initializeKerberosInterface() { secprops.maxbufsize = NET_SEC_BUF_SIZE; secprops.max_ssf = UINT_MAX; - m_krbInitResult = sasl_client_init(saslData->m_callbacks); - if (m_krbInitResult != SASL_OK) { - printf("[ERROR] Initializing libsasl returned %s (%d)\n\r", sasl_errstring(m_krbInitResult, NULL, NULL), m_krbInitResult); - return -1; + if (!tde_krb_sasl_client_initialized) { + m_krbInitResult = sasl_client_init(tde_krb_sasl_client_callbacks); + if (m_krbInitResult != SASL_OK) { + printf("[ERROR] Initializing libsasl returned %s (%d)\n\r", sasl_errstring(m_krbInitResult, NULL, NULL), m_krbInitResult); + return -1; + } + tde_krb_sasl_client_initialized = true; } m_krbInitResult = sasl_client_new(service, fqdn, iplocal, ipremote, NULL, m_krbInitServerLast, &saslData->m_krbConnection); diff --git a/lib/libtdekrb/src/tdekrbserversocket.cpp b/lib/libtdekrb/src/tdekrbserversocket.cpp index aa281cc..1303e64 100644 --- a/lib/libtdekrb/src/tdekrbserversocket.cpp +++ b/lib/libtdekrb/src/tdekrbserversocket.cpp @@ -50,6 +50,10 @@ delete m_canary; \ m_canary = NULL; +static bool tde_krb_sasl_server_initialized = false; +static TQString tde_krb_sasl_server_appname; +static sasl_callback_t tde_krb_sasl_server_callbacks[N_CALLBACKS]; + /* exception handling */ struct exit_exception { int c; @@ -59,7 +63,6 @@ struct exit_exception { class SASLDataPrivate { public: - sasl_callback_t m_callbacks[N_CALLBACKS]; sasl_conn_t *m_krbConnection; }; @@ -113,6 +116,7 @@ TDEKerberosServerSocket::~TDEKerberosServerSocket() { delete kerberosInitLoopTimer; kerberosInitLoopTimer = NULL; } + setUsingKerberos(false); m_buffer->close(); delete m_buffer; delete saslData; @@ -307,7 +311,7 @@ int TDEKerberosServerSocket::processPendingData() { int TDEKerberosServerSocket::setUsingKerberos(bool krbactive) { int ret = 0; - if (m_serviceName == "") { + if ((m_serviceName == "") || (tde_krb_sasl_server_appname == "")) { printf("[ERROR] No service name set!\n\r"); fflush(stdout); return -1; } @@ -330,6 +334,12 @@ int TDEKerberosServerSocket::setUsingKerberos(bool krbactive) { void TDEKerberosServerSocket::setServiceName(TQString name) { m_serviceName = name; + if (!tde_krb_sasl_server_initialized) { + tde_krb_sasl_server_appname = name; + } + else { + printf("[WARNING] Attempt was made to change application name after initial Kerberos connection was tried. Application name was NOT changed!\n\r"); fflush(stdout); + } } void TDEKerberosServerSocket::setServerFQDN(TQString name) { @@ -533,7 +543,7 @@ void TDEKerberosServerSocket::sendSASLDataToNetwork(const char *buffer, unsigned unsigned len, alloclen; int result; - alloclen = ((length / 3) + 1) * 4 + 1; + alloclen = (((length / 3) + 1) * 4) + 1; buf = (char*)malloc(alloclen+1); if (!buf) { printf("[ERROR] Unable to malloc()!\n\r"); @@ -839,6 +849,7 @@ void TDEKerberosServerSocket::continueKerberosInitialization() { printf("[DEBUG] Authenticated username: %s\n\r", m_authenticatedUserName.ascii()); } +#if 0 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"); @@ -847,6 +858,9 @@ void TDEKerberosServerSocket::continueKerberosInitialization() { m_authenticatedRealmName = m_krbInitData ? m_krbInitData : "(NULL)"; printf("[DEBUG] Authenticated realm: %s\n\r", m_authenticatedRealmName.ascii()); } +#else + m_authenticatedRealmName = "(NULL)"; +#endif m_krbInitResult = sasl_getprop(saslData->m_krbConnection, SASL_SSF, (const void **)&ssf); if (m_krbInitResult != SASL_OK) { @@ -906,7 +920,7 @@ int TDEKerberosServerSocket::initializeKerberosInterface() { char *localdomain = NULL; char *userdomain = NULL; - callback = saslData->m_callbacks; + callback = tde_krb_sasl_server_callbacks; // log callback->id = SASL_CB_LOG; @@ -925,10 +939,13 @@ int TDEKerberosServerSocket::initializeKerberosInterface() { secprops.maxbufsize = NET_SEC_BUF_SIZE; secprops.max_ssf = UINT_MAX; - 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; + if (!tde_krb_sasl_server_initialized) { + m_krbInitResult = sasl_server_init(tde_krb_sasl_server_callbacks, tde_krb_sasl_server_appname.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; + } + tde_krb_sasl_server_initialized = true; } m_krbInitResult = sasl_server_new(m_serviceName.ascii(), localdomain, userdomain, iplocal, ipremote, NULL, m_krbInitServerLast, &saslData->m_krbConnection); diff --git a/servers/auth_server_lin/src/auth_conn.cpp b/servers/auth_server_lin/src/auth_conn.cpp index 51dcef0..0f0912b 100644 --- a/servers/auth_server_lin/src/auth_conn.cpp +++ b/servers/auth_server_lin/src/auth_conn.cpp @@ -113,6 +113,7 @@ void AuthSocket::connectionClosedHandler() { int AuthSocket::initiateKerberosHandshake() { setUsingKerberos(true); while (kerberosStatus() == TDEKerberosServerSocket::KerberosInitializing) { + // RAJA FIXME tqApp->processEvents(); } if (kerberosStatus() == TDEKerberosServerSocket::KerberosInUse) { diff --git a/servers/fpga_programming_server_lin/src/fpga_conn.cpp b/servers/fpga_programming_server_lin/src/fpga_conn.cpp index 1ed0e09..08c5d38 100644 --- a/servers/fpga_programming_server_lin/src/fpga_conn.cpp +++ b/servers/fpga_programming_server_lin/src/fpga_conn.cpp @@ -94,6 +94,7 @@ void FPGASocket::connectionClosedHandler() { int FPGASocket::initiateKerberosHandshake() { setUsingKerberos(true); while (kerberosStatus() == TDEKerberosServerSocket::KerberosInitializing) { + // RAJA FIXME tqApp->processEvents(); } if (kerberosStatus() == TDEKerberosServerSocket::KerberosInUse) { diff --git a/servers/fpga_server_lin/src/fpga_conn.cpp b/servers/fpga_server_lin/src/fpga_conn.cpp index 0225cea..15c34c7 100644 --- a/servers/fpga_server_lin/src/fpga_conn.cpp +++ b/servers/fpga_server_lin/src/fpga_conn.cpp @@ -94,6 +94,7 @@ void FPGASocket::connectionClosedHandler() { int FPGASocket::initiateKerberosHandshake() { setUsingKerberos(true); while (kerberosStatus() == TDEKerberosServerSocket::KerberosInitializing) { + // RAJA FIXME tqApp->processEvents(); } if (kerberosStatus() == TDEKerberosServerSocket::KerberosInUse) {