summaryrefslogtreecommitdiffstats
path: root/lib/libtdekrb/src
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-06-23 17:23:49 -0500
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2012-06-23 17:23:49 -0500
commit8dcfe72c396a6f0c4bafd2ed23ba52a475154ef2 (patch)
treea0a77ec1d7d7cd826e1f2ba92ea4f96351bae5e3 /lib/libtdekrb/src
parentb48b26b86975d2166a4da7fc41086facefb3c4f2 (diff)
downloadulab-8dcfe72c396a6f0c4bafd2ed23ba52a475154ef2.tar.gz
ulab-8dcfe72c396a6f0c4bafd2ed23ba52a475154ef2.zip
Fix a number of crashes and generally clean up the code
Diffstat (limited to 'lib/libtdekrb/src')
-rw-r--r--lib/libtdekrb/src/Makefile.am7
-rw-r--r--lib/libtdekrb/src/tdekrbclientsocket.cpp113
-rw-r--r--lib/libtdekrb/src/tdekrbclientsocket.h3
-rw-r--r--lib/libtdekrb/src/tdekrbserversocket.cpp126
-rw-r--r--lib/libtdekrb/src/tdekrbserversocket.h3
5 files changed, 170 insertions, 82 deletions
diff --git a/lib/libtdekrb/src/Makefile.am b/lib/libtdekrb/src/Makefile.am
index b0b10cf..9cbe92e 100644
--- a/lib/libtdekrb/src/Makefile.am
+++ b/lib/libtdekrb/src/Makefile.am
@@ -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) \ No newline at end of file
+libtdekrbsocket_la_LDFLAGS = -avoid-version -module -no-undefined $(all_libraries)
diff --git a/lib/libtdekrb/src/tdekrbclientsocket.cpp b/lib/libtdekrb/src/tdekrbclientsocket.cpp
index 053dd23..ad7f0bd 100644
--- a/lib/libtdekrb/src/tdekrbclientsocket.cpp
+++ b/lib/libtdekrb/src/tdekrbclientsocket.cpp
@@ -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);
diff --git a/lib/libtdekrb/src/tdekrbclientsocket.h b/lib/libtdekrb/src/tdekrbclientsocket.h
index 1cea942..d0eb018 100644
--- a/lib/libtdekrb/src/tdekrbclientsocket.h
+++ b/lib/libtdekrb/src/tdekrbclientsocket.h
@@ -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;
diff --git a/lib/libtdekrb/src/tdekrbserversocket.cpp b/lib/libtdekrb/src/tdekrbserversocket.cpp
index 1d7cfbf..33187bc 100644
--- a/lib/libtdekrb/src/tdekrbserversocket.cpp
+++ b/lib/libtdekrb/src/tdekrbserversocket.cpp
@@ -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;
}
diff --git a/lib/libtdekrb/src/tdekrbserversocket.h b/lib/libtdekrb/src/tdekrbserversocket.h
index 04f70b9..a41d14f 100644
--- a/lib/libtdekrb/src/tdekrbserversocket.h
+++ b/lib/libtdekrb/src/tdekrbserversocket.h
@@ -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;