@ -31,6 +31,12 @@
# define NET_SEC_BUF_SIZE (2048)
# define NET_SEC_BUF_SIZE (2048)
/* exception handling */
struct exit_exception {
int c ;
exit_exception ( int c ) : c ( c ) { }
} ;
class SASLDataPrivate
class SASLDataPrivate
{
{
public :
public :
@ -38,6 +44,16 @@ class SASLDataPrivate
sasl_conn_t * m_krbConnection ;
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 ) {
static int logSASLMessages ( void * context __attribute__ ( ( unused ) ) , int priority , const char * message ) {
const char * label ;
const char * label ;
@ -62,7 +78,7 @@ static int logSASLMessages(void *context __attribute__((unused)), int priority,
return SASL_OK ;
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 = new SASLDataPrivate ;
saslData - > m_krbConnection = NULL ;
saslData - > m_krbConnection = NULL ;
}
}
@ -81,6 +97,9 @@ bool TDEKerberosServerSocket::open(int mode) {
void TDEKerberosServerSocket : : close ( ) {
void TDEKerberosServerSocket : : close ( ) {
TQSocket : : close ( ) ;
TQSocket : : close ( ) ;
if ( m_criticalSection > 0 ) {
throw exit_exception ( - 1 ) ;
}
}
}
int TDEKerberosServerSocket : : setUsingKerberos ( bool krbactive ) {
int TDEKerberosServerSocket : : setUsingKerberos ( bool krbactive ) {
@ -213,7 +232,9 @@ void TDEKerberosServerSocket::sendSASLDataToNetwork(const char *buffer, unsigned
free ( buf ) ;
free ( buf ) ;
}
}
unsigned int TDEKerberosServerSocket : : getSASLDataFromNetwork ( char * buf , int trunclen ) {
int TDEKerberosServerSocket : : getSASLDataFromNetwork ( char * buf , int trunclen ) {
m_criticalSection + + ;
try {
unsigned int len ;
unsigned int len ;
int result ;
int result ;
@ -223,6 +244,7 @@ unsigned int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trun
while ( 1 ) {
while ( 1 ) {
tqApp - > processEvents ( ) ;
tqApp - > processEvents ( ) ;
if ( state ( ) ! = TQSocket : : Connected ) {
if ( state ( ) ! = TQSocket : : Connected ) {
m_criticalSection - - ;
return - 1 ;
return - 1 ;
}
}
if ( TQSocket : : readBlock ( ba . data ( ) + len , 1 ) > 0 ) {
if ( TQSocket : : readBlock ( ba . data ( ) + len , 1 ) > 0 ) {
@ -234,6 +256,9 @@ unsigned int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trun
len + + ;
len + + ;
}
}
}
}
else {
usleep ( 1000 ) ;
}
if ( len > = ( ba . size ( ) - 1 ) ) {
if ( len > = ( ba . size ( ) - 1 ) ) {
ba . resize ( ba . size ( ) + 2048 ) ;
ba . resize ( ba . size ( ) + 2048 ) ;
}
}
@ -243,12 +268,19 @@ unsigned int TDEKerberosServerSocket::getSASLDataFromNetwork(char *buf, int trun
result = sasl_decode64 ( ba . data ( ) , strlen ( ba . data ( ) ) , buf , trunclen , & len ) ;
result = sasl_decode64 ( ba . data ( ) , strlen ( ba . data ( ) ) , buf , trunclen , & len ) ;
if ( result ! = SASL_OK ) {
if ( result ! = SASL_OK ) {
printf ( " [ERROR] Decoding data from base64 returned %s (%d) \n \r " , sasl_errstring ( result , NULL , NULL ) , result ) ;
printf ( " [ERROR] Decoding data from base64 returned %s (%d) \n \r " , sasl_errstring ( result , NULL , NULL ) , result ) ;
m_criticalSection - - ;
return - 1 ;
return - 1 ;
}
}
buf [ len ] = ' \0 ' ;
buf [ len ] = ' \0 ' ;
m_criticalSection - - ;
return len ;
return len ;
}
}
catch ( exit_exception & e ) {
m_criticalSection - - ;
return - 1 ;
}
}
int TDEKerberosServerSocket : : transmitEncryptedData ( int fd , const char * readbuf , int cc ) {
int TDEKerberosServerSocket : : transmitEncryptedData ( int fd , const char * readbuf , int cc ) {
int result = 0 ;
int result = 0 ;
@ -257,7 +289,7 @@ int TDEKerberosServerSocket::transmitEncryptedData(int fd, const char* readbuf,
result = sasl_encode ( saslData - > m_krbConnection , readbuf , cc , & data , & len ) ;
result = sasl_encode ( saslData - > m_krbConnection , readbuf , cc , & data , & len ) ;
if ( result ! = SASL_OK ) {
if ( result ! = SASL_OK ) {
printf ( " [ERROR] Encrypting data returned %s (%d) \n \r " , sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
printf ( " [ERROR] Encrypting data returned %s (%d) \n \r " , sa fe_sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
return - 1 ;
return - 1 ;
}
}
sendSASLDataToNetwork ( data , len , fd ) ;
sendSASLDataToNetwork ( data , len , fd ) ;
@ -273,11 +305,14 @@ int TDEKerberosServerSocket::receiveEncryptedData(char *buf, int trunclen) {
char * encbuf = ( char * ) malloc ( m_negotiatedMaxBufferSize ) ;
char * encbuf = ( char * ) malloc ( m_negotiatedMaxBufferSize ) ;
len = getSASLDataFromNetwork ( encbuf , m_negotiatedMaxBufferSize ) ;
len = getSASLDataFromNetwork ( encbuf , m_negotiatedMaxBufferSize ) ;
if ( len < 0 ) {
return - 1 ;
}
if ( len > = 0 ) {
if ( len > = 0 ) {
result = sasl_decode ( saslData - > m_krbConnection , encbuf , len , & recv_data , & recv_len ) ;
result = sasl_decode ( saslData - > m_krbConnection , encbuf , len , & recv_data , & recv_len ) ;
if ( result ! = SASL_OK ) {
if ( result ! = SASL_OK ) {
free ( encbuf ) ;
free ( encbuf ) ;
printf ( " [ERROR] Decrypting data returned %s (%d) \n \r " , sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
printf ( " [ERROR] Decrypting data returned %s (%d) \n \r " , sa fe_sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
return - 1 ;
return - 1 ;
}
}
if ( recv_len > trunclen ) {
if ( recv_len > trunclen ) {
@ -287,7 +322,7 @@ int TDEKerberosServerSocket::receiveEncryptedData(char *buf, int trunclen) {
}
}
free ( encbuf ) ;
free ( encbuf ) ;
return 0 ;
return recv_len ;
}
}
int TDEKerberosServerSocket : : initializeKerberosInterface ( ) {
int TDEKerberosServerSocket : : initializeKerberosInterface ( ) {
@ -303,6 +338,7 @@ int TDEKerberosServerSocket::initializeKerberosInterface() {
sasl_security_properties_t secprops ;
sasl_security_properties_t secprops ;
const char * ext_authid = NULL ;
const char * ext_authid = NULL ;
unsigned int len ;
unsigned int len ;
int slen ;
int count ;
int count ;
const char * data ;
const char * data ;
char user_authorized = 0 ;
char user_authorized = 0 ;
@ -336,20 +372,20 @@ int TDEKerberosServerSocket::initializeKerberosInterface() {
result = sasl_server_init ( saslData - > m_callbacks , m_serviceName . ascii ( ) ) ;
result = sasl_server_init ( saslData - > m_callbacks , m_serviceName . ascii ( ) ) ;
if ( result ! = SASL_OK ) {
if ( result ! = SASL_OK ) {
printf ( " [ERROR] Initializing libsasl returned %s (%d) \n \r " , sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
printf ( " [ERROR] Initializing libsasl returned %s (%d) \n \r " , sa fe_sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
return - 1 ;
return - 1 ;
}
}
result = sasl_server_new ( m_serviceName . ascii ( ) , localdomain , userdomain , iplocal , ipremote , NULL , serverlast , & saslData - > m_krbConnection ) ;
result = sasl_server_new ( m_serviceName . ascii ( ) , localdomain , userdomain , iplocal , ipremote , NULL , serverlast , & saslData - > m_krbConnection ) ;
if ( result ! = SASL_OK ) {
if ( result ! = SASL_OK ) {
printf ( " [ERROR] Allocating sasl connection state returned %s (%d) \n \r " , sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
printf ( " [ERROR] Allocating sasl connection state returned %s (%d) \n \r " , sa fe_sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
return - 1 ;
return - 1 ;
}
}
result = sasl_setprop ( saslData - > m_krbConnection , SASL_SEC_PROPS , & secprops ) ;
result = sasl_setprop ( saslData - > m_krbConnection , SASL_SEC_PROPS , & secprops ) ;
if ( result ! = SASL_OK ) {
if ( result ! = SASL_OK ) {
printf ( " [ERROR] Setting security properties returned %s (%d) \n \r " , sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
printf ( " [ERROR] Setting security properties returned %s (%d) \n \r " , sa fe_sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
freeKerberosConnection ( ) ;
freeKerberosConnection ( ) ;
return - 1 ;
return - 1 ;
}
}
@ -357,7 +393,7 @@ int TDEKerberosServerSocket::initializeKerberosInterface() {
puts ( " [DEBUG] Generating client mechanism list... " ) ;
puts ( " [DEBUG] Generating client mechanism list... " ) ;
result = sasl_listmech ( saslData - > m_krbConnection , ext_authid , NULL , " " , NULL , & data , & len , & count ) ;
result = sasl_listmech ( saslData - > m_krbConnection , ext_authid , NULL , " " , NULL , & data , & len , & count ) ;
if ( result ! = SASL_OK ) {
if ( result ! = SASL_OK ) {
printf ( " [ERROR] Generating client mechanism list returned %s (%d) \n \r " , sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
printf ( " [ERROR] Generating client mechanism list returned %s (%d) \n \r " , sa fe_sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
freeKerberosConnection ( ) ;
freeKerberosConnection ( ) ;
return - 1 ;
return - 1 ;
}
}
@ -366,9 +402,13 @@ int TDEKerberosServerSocket::initializeKerberosInterface() {
sendSASLDataToNetwork ( data , len , socket ( ) ) ;
sendSASLDataToNetwork ( data , len , socket ( ) ) ;
printf ( " [DEBUG] Waiting for client mechanism... \n \r " ) ;
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 ) {
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
// An initial response is present
data = buf + strlen ( buf ) + 1 ;
data = buf + strlen ( buf ) + 1 ;
len = len - ( unsigned ) 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 ) ;
result = sasl_server_start ( saslData - > m_krbConnection , buf , data , len , & data , & len ) ;
if ( result ! = SASL_OK & & result ! = SASL_CONTINUE ) {
if ( result ! = SASL_OK & & result ! = SASL_CONTINUE ) {
printf ( " [ERROR] Starting SASL negotiation returned %s (%d) \n \r " , sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
printf ( " [ERROR] Starting SASL negotiation returned %s (%d) \n \r " , sa fe_sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
freeKerberosConnection ( ) ;
freeKerberosConnection ( ) ;
return - 1 ;
return - 1 ;
}
}
@ -395,11 +435,15 @@ int TDEKerberosServerSocket::initializeKerberosInterface() {
return - 1 ;
return - 1 ;
}
}
printf ( " [DEBUG] Waiting for client reply... \n \r " ) ;
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 ;
data = NULL ;
result = sasl_server_step ( saslData - > m_krbConnection , buf , len , & data , & len ) ;
result = sasl_server_step ( saslData - > m_krbConnection , buf , len , & data , & len ) ;
if ( result ! = SASL_OK & & result ! = SASL_CONTINUE ) {
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 " , sa fe_sa sl_errdetail( saslData - > m_krbConnection ) , result ) ;
freeKerberosConnection ( ) ;
freeKerberosConnection ( ) ;
return - 1 ;
return - 1 ;
}
}