Branch: master

74d8f852 2014-12-23 19:50:34 Timothy Pearson
Add ability to set client socket SASL mechanism
Fix a couple of build warnings
M lib/libtdekrb/src/tdekrbclientsocket.cpp
M lib/libtdekrb/src/tdekrbclientsocket.h
M lib/libtdekrb/src/tdekrbserversocket.cpp
diff --git a/lib/libtdekrb/src/tdekrbclientsocket.cpp b/lib/libtdekrb/src/tdekrbclientsocket.cpp
index 3663e7a..167fdda 100644
--- a/lib/libtdekrb/src/tdekrbclientsocket.cpp
+++ b/lib/libtdekrb/src/tdekrbclientsocket.cpp
@@ -546,6 +546,18 @@
 	}
 }
 
+void TDEKerberosClientSocket::setAllowedMechanisms(TQStringList mechanisms) {
+	m_allowedMechanisms = mechanisms;
+}
+
+void TDEKerberosClientSocket::setDisallowedMechanisms(TQStringList mechanisms) {
+	m_disallowedMechanisms = mechanisms;
+}
+
+void TDEKerberosClientSocket::setMechanismOverrideList(TQStringList mechanisms) {
+	m_overrideMechanisms = mechanisms;
+}
+
 void TDEKerberosClientSocket::freeKerberosConnection(void) {
 	if (saslData->m_krbConnection) {
 		sasl_dispose(&saslData->m_krbConnection);
@@ -666,7 +678,7 @@
 	remnant_position = 0;
 	while ((data_remaining > 0) && (dataTimeoutTimer.isActive() || (m_dataTimeout < 0))) {
 		int data_to_write_len;
-		if (data_remaining > (m_negotiatedMaxBufferSize/2)) {
+		if ((unsigned long)data_remaining > (m_negotiatedMaxBufferSize/2)) {
 			data_to_write_len = m_negotiatedMaxBufferSize/2;
 		}
 		else {
@@ -815,9 +827,50 @@
 						}
 						len = slen;
 
-						printf("Choosing best mechanism from: %s\n", buf);
+						printf("[DEBUG] Server and client support mechanisms: %s\n", buf);
 
-						m_krbInitResult = sasl_client_start(saslData->m_krbConnection, buf, NULL, &data, &len, &chosenmech);
+						TQStringList krbMechList = TQStringList::split(" ", buf, false);
+
+						// If mechanism override is set then use it1
+						if (m_overrideMechanisms.count() > 0) {
+							printf("[DEBUG] Overriding mechanisms list: %s\n", m_overrideMechanisms.join(" ").ascii());
+
+							TQStringList supportedMechanisms = krbMechList;
+							krbMechList = m_overrideMechanisms;
+							// Remove all mechanisms not supported by the client and server
+							for (TQStringList::Iterator it = krbMechList.begin(); it != krbMechList.end(); ++it ) {
+								if (supportedMechanisms.find(*it) == supportedMechanisms.end()) {
+									krbMechList.remove(*it);
+									it = krbMechList.begin();
+								}
+							}
+						}
+						else {
+							// Remove all mechanisms not listed in the allowed list
+							if (m_allowedMechanisms.count() > 0) {
+								for (TQStringList::Iterator it = krbMechList.begin(); it != krbMechList.end(); ++it ) {
+									if (m_allowedMechanisms.find(*it) == m_allowedMechanisms.end()) {
+										printf("[DEBUG] Removing implicitly disallowed mechanism %s from list\n", (*it).ascii());
+										krbMechList.remove(*it);
+										it = krbMechList.begin();
+									}
+								}
+							}
+	
+							// Remove all mechanisms listed in the disallowed list
+							if (m_disallowedMechanisms.count() > 0) {
+								for (TQStringList::Iterator it = m_disallowedMechanisms.begin(); it != m_disallowedMechanisms.end(); ++it ) {
+									printf("[DEBUG] Removing explicitly disallowed mechanism %s from list\n", (*it).ascii());
+									krbMechList.remove(*it);
+								}
+							}
+						}
+
+						TQString krbMechListString = krbMechList.join(" ");
+
+						printf("Choosing best mechanism from: %s\n", krbMechListString.ascii());
+
+						m_krbInitResult = sasl_client_start(saslData->m_krbConnection, krbMechListString.ascii(), NULL, &data, &len, &chosenmech);
 						if (m_krbInitResult != SASL_OK && m_krbInitResult != SASL_CONTINUE) {
 							printf("[ERROR] Starting SASL negotiation returned %s (%d)\n\r", sasl_errstring(m_krbInitResult, NULL, NULL), m_krbInitResult);
 							freeKerberosConnection();
diff --git a/lib/libtdekrb/src/tdekrbclientsocket.h b/lib/libtdekrb/src/tdekrbclientsocket.h
index 93e0dc3..b941eb0 100644
--- a/lib/libtdekrb/src/tdekrbclientsocket.h
+++ b/lib/libtdekrb/src/tdekrbclientsocket.h
@@ -22,6 +22,7 @@
 #define TDEKRBCLIENTSOCKET_H
 
 #include <tqsocket.h>
+#include <tqstringlist.h>
 
 #define N_CALLBACKS 3
 
@@ -78,6 +79,10 @@
 		void clearFrameTail();
 		void writeBufferedData();
 
+		void setAllowedMechanisms(TQStringList mechanisms);
+		void setDisallowedMechanisms(TQStringList mechanisms);
+		void setMechanismOverrideList(TQStringList mechanisms);
+
 	public slots:
 		int processPendingData();
 
@@ -112,6 +117,9 @@
 		TQString m_prevStatusMessage;
 		int m_dataTimeout;
 		TQTimer* kerberosInitLoopTimer;
+		TQStringList m_allowedMechanisms;
+		TQStringList m_disallowedMechanisms;
+		TQStringList m_overrideMechanisms;
 		bool* m_canary;
 
 	private:
diff --git a/lib/libtdekrb/src/tdekrbserversocket.cpp b/lib/libtdekrb/src/tdekrbserversocket.cpp
index 5a9f9ff..a924236 100644
--- a/lib/libtdekrb/src/tdekrbserversocket.cpp
+++ b/lib/libtdekrb/src/tdekrbserversocket.cpp
@@ -675,7 +675,7 @@
 	remnant_position = 0;
 	while ((data_remaining > 0) && (dataTimeoutTimer.isActive() || (m_dataTimeout < 0))) {
 		int data_to_write_len;
-		if (data_remaining > (m_negotiatedMaxBufferSize/2)) {
+		if ((unsigned long)data_remaining > (m_negotiatedMaxBufferSize/2)) {
 			data_to_write_len = m_negotiatedMaxBufferSize/2;
 		}
 		else {