summaryrefslogtreecommitdiffstats
path: root/lib/libtdekrb/src/tdekrbclientsocket.cpp
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/tdekrbclientsocket.cpp
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/tdekrbclientsocket.cpp')
-rw-r--r--lib/libtdekrb/src/tdekrbclientsocket.cpp113
1 files changed, 77 insertions, 36 deletions
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);