@ -23,6 +23,8 @@
# include <tqapplication.h>
# include <tqapplication.h>
# include <tqbuffer.h>
# include <tqbuffer.h>
# include <tqeventloop.h>
# include <tqtimer.h>
# include <sasl.h>
# include <sasl.h>
# include <saslplug.h>
# include <saslplug.h>
@ -38,7 +40,7 @@
* m_canary = false ; \
* m_canary = false ; \
} \
} \
bool * canary = m_canary ; \
bool * canary = m_canary ; \
tqApp - > processEvents( ) ; \
tqApp - > eventLoop( ) - > processEvents( TQEventLoop : : ExcludeUserInput ) ; \
if ( * canary = = true ) { \
if ( * canary = = true ) { \
delete canary ; \
delete canary ; \
return - 1 ; \
return - 1 ; \
@ -93,7 +95,7 @@ static int logSASLMessages(void *context __attribute__((unused)), int priority,
return SASL_OK ;
return SASL_OK ;
}
}
TDEKerberosClientSocket : : TDEKerberosClientSocket ( TQObject * parent , const char * name ) : TQSocket ( parent , name ) , m_kerberosRequested ( false ) , m_criticalSection ( 0 ) , m_bufferLength ( 0 ) , m_ canary( NULL ) , m_negotiatedMaxBufferSize ( NET_SEC_BUF_SIZE ) {
TDEKerberosClientSocket : : TDEKerberosClientSocket ( TQObject * parent , const char * name ) : TQSocket ( parent , name ) , m_kerberosRequested ( false ) , m_criticalSection ( 0 ) , m_bufferLength ( 0 ) , m_ krbInitRunning( false ) , m_krbInitState ( - 1 ) , m_ canary( NULL ) , m_negotiatedMaxBufferSize ( NET_SEC_BUF_SIZE ) {
saslData = new SASLDataPrivate ;
saslData = new SASLDataPrivate ;
saslData - > m_krbConnection = NULL ;
saslData - > m_krbConnection = NULL ;
m_buffer = new TQBuffer ( ) ;
m_buffer = new TQBuffer ( ) ;
@ -122,7 +124,7 @@ void TDEKerberosClientSocket::close() {
}
}
void TDEKerberosClientSocket : : flush ( ) {
void TDEKerberosClientSocket : : flush ( ) {
if ( m_kerberosRequested ) {
if ( kerberosStatus( ) = = KerberosInUse ) {
// FIXME
// FIXME
// If a write buffer is implemented, it will need to be flushed before the following call is made
// If a write buffer is implemented, it will need to be flushed before the following call is made
TQSocket : : flush ( ) ;
TQSocket : : flush ( ) ;
@ -135,7 +137,7 @@ void TDEKerberosClientSocket::flush() {
TQIODevice : : Offset TDEKerberosClientSocket : : size ( ) const {
TQIODevice : : Offset TDEKerberosClientSocket : : size ( ) const {
TQIODevice : : Offset ret ;
TQIODevice : : Offset ret ;
if ( m_kerberosRequested ) {
if ( kerberosStatus( ) = = KerberosInUse ) {
ret = m_bufferLength ;
ret = m_bufferLength ;
}
}
else {
else {
@ -153,7 +155,7 @@ bool TDEKerberosClientSocket::at(TQIODevice::Offset off) {
long i ;
long i ;
bool ret ;
bool ret ;
if ( m_kerberosRequested ) {
if ( kerberosStatus( ) = = KerberosInUse ) {
if ( off > 0 ) {
if ( off > 0 ) {
// Prevent overflow
// Prevent overflow
if ( off > ( unsigned long ) m_bufferLength ) {
if ( off > ( unsigned long ) m_bufferLength ) {
@ -184,7 +186,7 @@ bool TDEKerberosClientSocket::at(TQIODevice::Offset off) {
bool TDEKerberosClientSocket : : atEnd ( ) const {
bool TDEKerberosClientSocket : : atEnd ( ) const {
bool ret ;
bool ret ;
if ( m_kerberosRequested ) {
if ( kerberosStatus( ) = = KerberosInUse ) {
ret = TQSocket : : atEnd ( ) ;
ret = TQSocket : : atEnd ( ) ;
}
}
else {
else {
@ -205,7 +207,7 @@ int TDEKerberosClientSocket::setUsingKerberos(bool krbactive) {
if ( krbactive ) {
if ( krbactive ) {
m_kerberosRequested = true ;
m_kerberosRequested = true ;
if ( ( ! saslData - > m_krbConnection ) & & ( state ( ) = = TQSocket : : Connected ) ) {
if ( ( ! saslData - > m_krbConnection ) & & ( state ( ) = = TQSocket : : Connected ) ) {
ret = initializeKerberosInterface( ) ;
initializeKerberosInterface( ) ;
}
}
}
}
else {
else {
@ -230,7 +232,7 @@ TQ_LONG TDEKerberosClientSocket::readBlock(char *data, TQ_ULONG maxlen) {
long i ;
long i ;
TQ_LONG ret ;
TQ_LONG ret ;
if ( m_kerberosRequested ) {
if ( kerberosStatus( ) = = KerberosInUse ) {
int reclen ;
int reclen ;
int wrlen ;
int wrlen ;
char * buf = ( char * ) malloc ( m_negotiatedMaxBufferSize ) ;
char * buf = ( char * ) malloc ( m_negotiatedMaxBufferSize ) ;
@ -277,7 +279,7 @@ TQ_LONG TDEKerberosClientSocket::readBlock(char *data, TQ_ULONG maxlen) {
TQ_LONG TDEKerberosClientSocket : : writeBlock ( const char * data , TQ_ULONG len ) {
TQ_LONG TDEKerberosClientSocket : : writeBlock ( const char * data , TQ_ULONG len ) {
TQ_LONG ret ;
TQ_LONG ret ;
if ( m_kerberosRequested ) {
if ( kerberosStatus( ) = = KerberosInUse ) {
ret = transmitEncryptedData ( socket ( ) , data , len ) ;
ret = transmitEncryptedData ( socket ( ) , data , len ) ;
}
}
else {
else {
@ -291,7 +293,7 @@ TQ_LONG TDEKerberosClientSocket::readLine(char *data, TQ_ULONG maxlen) {
long i ;
long i ;
TQ_LONG ret ;
TQ_LONG ret ;
if ( m_kerberosRequested ) {
if ( kerberosStatus( ) = = KerberosInUse ) {
int reclen ;
int reclen ;
int wrlen ;
int wrlen ;
char * buf = ( char * ) malloc ( m_negotiatedMaxBufferSize ) ;
char * buf = ( char * ) malloc ( m_negotiatedMaxBufferSize ) ;
@ -340,7 +342,7 @@ TQString TDEKerberosClientSocket::readLine() {
TQString ret ;
TQString ret ;
long maxlen ;
long maxlen ;
if ( m_kerberosRequested ) {
if ( kerberosStatus( ) = = KerberosInUse ) {
int reclen ;
int reclen ;
int wrlen ;
int wrlen ;
int readlen ;
int readlen ;
@ -393,7 +395,7 @@ TQString TDEKerberosClientSocket::readLine() {
}
}
void TDEKerberosClientSocket : : writeLine ( TQString str ) {
void TDEKerberosClientSocket : : writeLine ( TQString str ) {
if ( m_kerberosRequested ) {
if ( kerberosStatus( ) = = KerberosInUse ) {
transmitEncryptedData ( socket ( ) , str . ascii ( ) , str . length ( ) ) ;
transmitEncryptedData ( socket ( ) , str . ascii ( ) , str . length ( ) ) ;
}
}
else {
else {
@ -561,79 +563,50 @@ int TDEKerberosClientSocket::receiveEncryptedData(char *buf, unsigned int truncl
return recv_len ;
return recv_len ;
}
}
int TDEKerberosClientSocket : : initializeKerberosInterface ( ) {
TDEKerberosClientSocket : : KerberosStatus TDEKerberosClientSocket : : kerberosStatus ( ) const {
if ( state ( ) ! = TQSocket : : Connected ) {
if ( ! m_kerberosRequested ) {
saslData - > m_krbConnection = false ;
return KerberosNotRequested ;
return - 1 ;
}
if ( m_krbInitRunning ) {
return KerberosInitializing ;
}
if ( m_krbInitState < 0 ) {
return KerberosFailure ;
}
return KerberosInUse ;
}
}
sasl_callback_t * callback ;
void TDEKerberosClientSocket : : continueKerberosInitialization ( ) {
int slen ;
char buf [ NET_SEC_BUF_SIZE ] ;
char buf [ NET_SEC_BUF_SIZE ] ;
int result = 0 ;
int serverlast = 0 ;
sasl_security_properties_t secprops ;
const char * chosenmech ;
unsigned int len ;
unsigned int len ;
int slen ;
const char * data ;
const char * data ;
const char * chosenmech ;
sasl_ssf_t * ssf ;
sasl_ssf_t * ssf ;
char * iplocal = NULL ;
char * ipremote = NULL ;
const char * service = m_serviceName . ascii ( ) ;
const char * fqdn = m_serverFQDN . ascii ( ) ;
callback = saslData - > m_callbacks ;
// log
callback - > id = SASL_CB_LOG ;
callback - > proc = ( sasl_callback_ft ) & logSASLMessages ;
callback - > context = NULL ;
+ + callback ;
// end of callback list
callback - > id = SASL_CB_LIST_END ;
callback - > proc = NULL ;
callback - > context = NULL ;
+ + callback ;
// Initialize default data structures
memset ( & secprops , 0L , sizeof ( secprops ) ) ;
secprops . maxbufsize = NET_SEC_BUF_SIZE ;
secprops . max_ssf = UINT_MAX ;
result = sasl_client_init ( saslData - > m_callbacks ) ;
if ( result ! = SASL_OK ) {
printf ( " [ERROR] Initializing libsasl returned %s (%d) \n \r " , sasl_errstring ( result , NULL , NULL ) , result ) ;
return - 1 ;
}
result = sasl_client_new ( service , fqdn , iplocal , ipremote , NULL , serverlast , & saslData - > m_krbConnection ) ;
if ( result ! = SASL_OK ) {
printf ( " [ERROR] Allocating sasl connection state returned %s (%d) \n \r " , sasl_errstring ( result , NULL , NULL ) , 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_errstring ( result , NULL , NULL ) , result ) ;
freeKerberosConnection ( ) ;
return - 1 ;
}
if ( m_krbInitRunning ) {
switch ( m_krbInitState ) {
case 0 :
if ( state ( ) = = TQSocket : : Connected ) {
if ( canReadLine ( ) ) {
printf ( " [DEBUG] Waiting for mechanism list from server... \n \r " ) ;
printf ( " [DEBUG] Waiting for mechanism list from server... \n \r " ) ;
slen = getSASLDataFromNetwork ( buf , NET_SEC_BUF_SIZE ) ;
slen = getSASLDataFromNetwork ( buf , NET_SEC_BUF_SIZE ) ;
if ( slen < 0 ) {
if ( slen < 0 ) {
return - 2 ;
m_krbInitState = - 2 ;
m_krbInitRunning = false ;
return ;
}
}
len = slen ;
len = slen ;
printf ( " Choosing best mechanism from: %s \n " , buf ) ;
printf ( " Choosing best mechanism from: %s \n " , buf ) ;
result = sasl_client_start ( saslData - > m_krbConnection , buf , NULL , & data , & len , & chosenmech ) ;
m_krbInitResult = sasl_client_start ( saslData - > m_krbConnection , buf , NULL , & data , & len , & chosenmech ) ;
if ( result ! = SASL_OK & & result ! = SASL_CONTINUE ) {
if ( m_krbInitResult ! = SASL_OK & & m_krbInitResult ! = SASL_CONTINUE ) {
printf ( " [ERROR] Starting SASL negotiation returned %s (%d) \n \r " , sasl_errstring ( result, NULL , NULL ) , result) ;
printf ( " [ERROR] Starting SASL negotiation returned %s (%d) \n \r " , sasl_errstring ( m_krbInitResult , NULL , NULL ) , m_krbInitResult ) ;
freeKerberosConnection ( ) ;
freeKerberosConnection ( ) ;
return - 1 ;
m_krbInitState = - 1 ;
m_krbInitRunning = false ;
return ;
}
}
printf ( " [DEBUG] Using mechanism %s \n \r " , chosenmech ) ;
printf ( " [DEBUG] Using mechanism %s \n \r " , chosenmech ) ;
@ -642,7 +615,9 @@ int TDEKerberosClientSocket::initializeKerberosInterface() {
if ( NET_SEC_BUF_SIZE - strlen ( buf ) - 1 < len ) {
if ( NET_SEC_BUF_SIZE - strlen ( buf ) - 1 < len ) {
printf ( " [ERROR] Insufficient buffer space to construct initial response! \n \r " ) ;
printf ( " [ERROR] Insufficient buffer space to construct initial response! \n \r " ) ;
freeKerberosConnection ( ) ;
freeKerberosConnection ( ) ;
return - 1 ;
m_krbInitState = - 1 ;
m_krbInitRunning = false ;
return ;
}
}
printf ( " [DEBUG] Preparing initial response... \n \r " ) ;
printf ( " [DEBUG] Preparing initial response... \n \r " ) ;
memcpy ( buf + strlen ( buf ) + 1 , data , len ) ;
memcpy ( buf + strlen ( buf ) + 1 , data , len ) ;
@ -656,61 +631,156 @@ int TDEKerberosClientSocket::initializeKerberosInterface() {
printf ( " [DEBUG] Sending initial response... \n \r " ) ;
printf ( " [DEBUG] Sending initial response... \n \r " ) ;
sendSASLDataToNetwork ( buf , len , socket ( ) ) ;
sendSASLDataToNetwork ( buf , len , socket ( ) ) ;
while ( result = = SASL_CONTINUE ) {
m_krbInitState = 1 ;
}
}
else {
m_krbInitState = - 3 ;
m_krbInitRunning = false ;
}
break ;
case 1 :
if ( state ( ) = = TQSocket : : Connected ) {
if ( m_krbInitResult = = SASL_CONTINUE ) {
if ( canReadLine ( ) ) {
printf ( " [DEBUG] Waiting for server reply... \n \r " ) ;
printf ( " [DEBUG] Waiting for server reply... \n \r " ) ;
slen = getSASLDataFromNetwork ( buf , NET_SEC_BUF_SIZE ) ;
slen = getSASLDataFromNetwork ( buf , NET_SEC_BUF_SIZE ) ;
if ( slen < 0 ) {
if ( slen < 0 ) {
return - 2 ;
m_krbInitState = - 2 ;
m_krbInitRunning = false ;
return ;
}
}
len = slen ;
len = slen ;
result = sasl_client_step ( saslData - > m_krbConnection , buf , len , NULL , & data , & len ) ;
m_k rbInitR esult = sasl_client_step ( saslData - > m_krbConnection , buf , len , NULL , & data , & len ) ;
if ( result ! = SASL_OK & & result ! = SASL_CONTINUE ) {
if ( m_k rbInitR esult ! = SASL_OK & & m_k rbInitR esult ! = SASL_CONTINUE ) {
printf ( " [ERROR] Performing SASL negotiation returned %s (%d) \n \r " , sasl_errstring ( result , NULL , NULL ) , result ) ;
printf ( " [ERROR] Performing SASL negotiation returned %s (%d) \n \r " , sasl_errstring ( m_k rbInitR esult, NULL , NULL ) , m_k rbInitR esult) ;
freeKerberosConnection ( ) ;
freeKerberosConnection ( ) ;
return - 1 ;
m_krbInitState = - 1 ;
m_krbInitRunning = false ;
return ;
}
}
if ( data & & len ) {
if ( data & & len ) {
printf ( " [DEBUG] Sending response... \n \r " ) ;
printf ( " [DEBUG] Sending response... \n \r " ) ;
sendSASLDataToNetwork ( data , len , socket ( ) ) ;
sendSASLDataToNetwork ( data , len , socket ( ) ) ;
}
}
else if ( result ! = SASL_OK | | ! serverl ast) {
else if ( m_k rbInitR esult ! = SASL_OK | | ! m_krbInitServerL ast) {
sendSASLDataToNetwork ( " " , 0 , socket ( ) ) ;
sendSASLDataToNetwork ( " " , 0 , socket ( ) ) ;
}
}
}
}
}
else {
printf ( " [DEBUG] Negotiation complete! \n \r " ) ;
printf ( " [DEBUG] Negotiation complete! \n \r " ) ;
m_krbInitState = 2 ;
result = sasl_getprop ( saslData - > m_krbConnection , SASL_USERNAME , ( const void * * ) & data ) ;
}
if ( result ! = SASL_OK ) {
}
else {
m_krbInitState = - 3 ;
m_krbInitRunning = false ;
}
break ;
case 2 :
if ( state ( ) = = TQSocket : : Connected ) {
m_krbInitResult = sasl_getprop ( saslData - > m_krbConnection , SASL_USERNAME , ( const void * * ) & data ) ;
if ( m_krbInitResult ! = SASL_OK ) {
printf ( " [WARNING] Unable to determine authenticated username! \n \r " ) ;
printf ( " [WARNING] Unable to determine authenticated username! \n \r " ) ;
}
}
else {
else {
printf ( " [DEBUG] Authenticated username: %s \n \r " , data ? data : " (NULL) " ) ;
printf ( " [DEBUG] Authenticated username: %s \n \r " , data ? data : " (NULL) " ) ;
}
}
result = sasl_getprop ( saslData - > m_krbConnection , SASL_DEFUSERREALM , ( const void * * ) & data ) ;
m_k rbInitR esult = sasl_getprop ( saslData - > m_krbConnection , SASL_DEFUSERREALM , ( const void * * ) & data ) ;
if ( result ! = SASL_OK ) {
if ( m_k rbInitR esult ! = SASL_OK ) {
printf ( " [WARNING] Unable to determine authenticated realm! \n \r " ) ;
printf ( " [WARNING] Unable to determine authenticated realm! \n \r " ) ;
}
}
else {
else {
printf ( " [DEBUG] Authenticated realm: %s \n \r " , data ? data : " (NULL) " ) ;
printf ( " [DEBUG] Authenticated realm: %s \n \r " , data ? data : " (NULL) " ) ;
}
}
result = sasl_getprop ( saslData - > m_krbConnection , SASL_SSF , ( const void * * ) & ssf ) ;
m_k rbInitR esult = sasl_getprop ( saslData - > m_krbConnection , SASL_SSF , ( const void * * ) & ssf ) ;
if ( result ! = SASL_OK ) {
if ( m_k rbInitR esult ! = SASL_OK ) {
printf ( " [WARNING] Unable to determine SSF! \n \r " ) ;
printf ( " [WARNING] Unable to determine SSF! \n \r " ) ;
}
}
else {
else {
printf ( " [DEBUG] Authenticated SSF: %d \n " , * ssf ) ;
printf ( " [DEBUG] Authenticated SSF: %d \n " , * ssf ) ;
}
}
result = sasl_getprop ( saslData - > m_krbConnection , SASL_MAXOUTBUF , ( const void * * ) & m_negotiatedMaxBufferSize ) ;
m_k rbInitR esult = sasl_getprop ( saslData - > m_krbConnection , SASL_MAXOUTBUF , ( const void * * ) & m_negotiatedMaxBufferSize ) ;
if ( result ! = SASL_OK ) {
if ( m_k rbInitR esult ! = SASL_OK ) {
printf ( " [WARNING] Unable to determine maximum buffer size! \n \r " ) ;
printf ( " [WARNING] Unable to determine maximum buffer size! \n \r " ) ;
m_negotiatedMaxBufferSize = NET_SEC_BUF_SIZE ;
m_negotiatedMaxBufferSize = NET_SEC_BUF_SIZE ;
}
}
else {
else {
printf ( " [DEBUG] Maximum buffer size: %d \n " , m_negotiatedMaxBufferSize ) ;
printf ( " [DEBUG] Maximum buffer size: %d \n " , m_negotiatedMaxBufferSize ) ;
}
}
m_krbInitState = 3 ;
m_krbInitRunning = false ;
}
else {
m_krbInitState = - 3 ;
m_krbInitRunning = false ;
}
break ;
}
TQTimer : : singleShot ( 0 , this , SLOT ( continueKerberosInitialization ( ) ) ) ;
}
}
int TDEKerberosClientSocket : : initializeKerberosInterface ( ) {
if ( state ( ) ! = TQSocket : : Connected ) {
saslData - > m_krbConnection = false ;
return - 1 ;
}
sasl_callback_t * callback ;
m_krbInitResult = 0 ;
m_krbInitServerLast = 0 ;
sasl_security_properties_t secprops ;
char * iplocal = NULL ;
char * ipremote = NULL ;
const char * service = m_serviceName . ascii ( ) ;
const char * fqdn = m_serverFQDN . ascii ( ) ;
callback = saslData - > m_callbacks ;
// log
callback - > id = SASL_CB_LOG ;
callback - > proc = ( sasl_callback_ft ) & logSASLMessages ;
callback - > context = NULL ;
+ + callback ;
// end of callback list
callback - > id = SASL_CB_LIST_END ;
callback - > proc = NULL ;
callback - > context = NULL ;
+ + callback ;
// Initialize default data structures
memset ( & secprops , 0L , sizeof ( secprops ) ) ;
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 ;
}
m_krbInitResult = sasl_client_new ( service , fqdn , iplocal , ipremote , NULL , m_krbInitServerLast , & saslData - > m_krbConnection ) ;
if ( m_krbInitResult ! = SASL_OK ) {
printf ( " [ERROR] Allocating sasl connection state returned %s (%d) \n \r " , sasl_errstring ( m_krbInitResult , NULL , NULL ) , m_krbInitResult ) ;
return - 1 ;
}
m_krbInitResult = sasl_setprop ( saslData - > m_krbConnection , SASL_SEC_PROPS , & secprops ) ;
if ( m_krbInitResult ! = SASL_OK ) {
printf ( " [ERROR] Setting security properties returned %s (%d) \n \r " , sasl_errstring ( m_krbInitResult , NULL , NULL ) , m_krbInitResult ) ;
freeKerberosConnection ( ) ;
return - 1 ;
}
m_krbInitRunning = true ;
m_krbInitState = 0 ;
TQTimer : : singleShot ( 0 , this , SLOT ( continueKerberosInitialization ( ) ) ) ;
return 0 ;
return 0 ;
}
}