@ -31,6 +31,7 @@
# include <signal.h>
# include <ftw.h>
# include <tqdir.h>
# include <tqstring.h>
# include <tqstringlist.h>
@ -46,7 +47,9 @@
// Some internal constants
# define CREATE_LIFE_CYCLE "01"
# define tqarg arg
# define KDM_CONTROL_FIFO_DIR " / tmp / ksocket-global / kdm"
# define KDM_CONTROL_FIFO_FILE " / tmp / ksocket-global / kdm / kdmctl-%1"
# define KDM_CONTROL_FIFO_SAK_FILE " / tmp / ksocket-global / kdm / kdmctl-sak-%1"
// In ckpass.o
extern " C " {
@ -69,6 +72,17 @@ static TQString darray[MAXIMUM_VTS];
static FILE * opensc_explorer_file ;
struct sigaction usr_action ;
sigset_t block_mask ;
void handle_sigpipe ( int sig )
{
int uidnum ;
if ( sig = = SIGPIPE ) {
printf ( " Got SIGPIPE! \n \r " ) ; fflush ( stdout ) ;
}
}
TQString readfile ( const char * filename ) {
FILE * fp ;
long len ;
@ -90,6 +104,20 @@ TQString readfile(const char * filename) {
return contents ;
}
int writefile ( const char * filename , TQString contents ) {
int fp ;
long len ;
char * buf ;
fp = open ( filename , O_WRONLY | O_NONBLOCK ) ;
if ( fp < 0 ) {
printf ( " [WARNING] Unable to open file %s for writing \n \r " , filename ) ; fflush ( stdout ) ;
return - 1 ;
}
int retcode = write ( fp , contents . ascii ( ) , contents . length ( ) ) ;
close ( fp ) ;
return retcode ;
}
TQString exec ( const char * cmd ) {
TQString bashcommand = cmd ;
bashcommand = bashcommand . replace ( " \" " , " \\ \" " ) ;
@ -278,6 +306,13 @@ int main (int argc, char *argv[])
printf ( " [DEBUG 390.0] Starting up \n \r " ) ; fflush ( stdout ) ;
// Initialize signal handlers
sigfillset ( & block_mask ) ;
usr_action . sa_handler = handle_sigpipe ;
usr_action . sa_mask = block_mask ;
usr_action . sa_flags = 0 ;
sigaction ( SIGPIPE , & usr_action , NULL ) ;
// Create the secure directory and lock it down
secure_directory = SECURE_DIRECTORY_PATH ;
rmrf ( secure_directory . ascii ( ) ) ;
@ -565,68 +600,104 @@ int main (int argc, char *argv[])
if ( foundsession = = 0 ) {
printf ( " [DEBUG 400.c] Existing session not found, starting new... \n \r " ) ; fflush ( stdout ) ;
// Make sure that this is not display :0 (default login screen).
// If it is, execute login. If not, create new session, then execute login
int usebasedisplay = 0 ;
if ( noactivesessions = = 1 ) {
newdisplay = exec ( " ls /var/run/xdmctl/ | grep 'xdmctl-:0' " ) ;
printf ( " [DEBUG 400.d] %s \n \r " , newdisplay . ascii ( ) ) ; fflush ( stdout ) ;
if ( newdisplay ! = " " ) {
usebasedisplay = 1 ;
// Get directory listing of kdm control socket directory
// Also start new X server if needed
bool have_valid_display = false ;
bool display_has_sak = false ;
bool writeerror = false ;
newdisplayint = MAXIMUM_VTS + 1 ;
while ( have_valid_display = = false ) {
display_has_sak = false ;
writeerror = false ;
TQDir dr ( KDM_CONTROL_FIFO_DIR ) ;
dr . setFilter ( TQDir : : System ) ;
dr . setSorting ( TQDir : : Name ) ;
const TQFileInfoList * list = dr . entryInfoList ( ) ;
if ( list ) {
TQFileInfoListIterator it ( * list ) ;
TQFileInfo * fi ;
while ( ( fi = it . current ( ) ) ! = NULL ) {
bool isint ;
int tempdisplayint ;
TQString tempdisplaystr ;
tempdisplaystr = fi - > fileName ( ) ;
printf ( " %s \n " , fi - > fileName ( ) . latin1 ( ) ) ; fflush ( stdout ) ;
if ( fi - > fileName ( ) . tqcontains ( " kdmctl-sak- " ) ) {
tempdisplaystr = tempdisplaystr . replace ( " kdmctl-sak- " , " " ) ;
tempdisplayint = tempdisplaystr . toInt ( & isint ) ;
if ( isint ) {
if ( tempdisplayint < newdisplayint ) {
newdisplayint = tempdisplayint ;
display_has_sak = true ;
}
}
}
else if ( fi - > fileName ( ) . tqcontains ( " kdmctl- " ) ) {
tempdisplaystr = tempdisplaystr . replace ( " kdmctl- " , " " ) ;
tempdisplayint = tempdisplaystr . toInt ( & isint ) ;
if ( isint ) {
if ( tempdisplayint < newdisplayint ) {
newdisplayint = tempdisplayint ;
display_has_sak = false ;
}
}
}
+ + it ;
}
if ( display_has_sak ) {
if ( writefile ( TQString ( KDM_CONTROL_FIFO_SAK_FILE ) . tqarg ( newdisplayint ) , " CLOSE \n " ) < 0 ) {
// Uh oh, something failed...
printf ( " Unable to write to KDM control socket %s \n \r " , ( TQString ( KDM_CONTROL_FIFO_SAK_FILE ) . tqarg ( newdisplayint ) ) . ascii ( ) ) ; fflush ( stdout ) ;
unlink ( ( TQString ( KDM_CONTROL_FIFO_SAK_FILE ) . tqarg ( newdisplayint ) ) . ascii ( ) ) ;
writeerror = true ;
}
else {
struct stat buffer ;
int status = - 1 ;
int timeout_counter = 0 ;
while ( ( status ! = 0 ) & & ( timeout_counter < 30 ) ) {
status = stat ( ( TQString ( KDM_CONTROL_FIFO_FILE ) . tqarg ( newdisplayint ) ) . ascii ( ) , & buffer ) ;
timeout_counter + + ;
usleep ( 100000 ) ;
}
}
}
else {
// Make sure the control socket is writable
if ( writefile ( TQString ( KDM_CONTROL_FIFO_FILE ) . tqarg ( newdisplayint ) , " PING \n " ) < 0 ) {
// Uh oh, something failed...
printf ( " Unable to write to KDM control socket %s \n \r " , ( TQString ( KDM_CONTROL_FIFO_FILE ) . tqarg ( newdisplayint ) ) . ascii ( ) ) ; fflush ( stdout ) ;
unlink ( ( TQString ( KDM_CONTROL_FIFO_FILE ) . tqarg ( newdisplayint ) ) . ascii ( ) ) ;
writeerror = true ;
}
}
if ( newdisplayint = = ( MAXIMUM_VTS + 1 ) ) {
writeerror = true ;
systemexec ( TRINITY_BIN_PREFIX " kdmctl -g reserve " ) ;
usleep ( 1000000 ) ;
}
if ( writeerror )
have_valid_display = false ;
else
have_valid_display = true ;
}
}
if ( ! resultbkp . contains ( " : " ) ) {
newdisplay = exec ( " ls /var/run/xdmctl/ | grep 'xdmctl-:0' " ) ;
printf ( " [DEBUG 400.d] %s \n \r " , newdisplay . ascii ( ) ) ; fflush ( stdout ) ;
if ( newdisplay ! = " " ) {
usebasedisplay = 1 ;
else
{
// Could not find any existing kdm sessions; start a new one
systemexec ( TRINITY_BIN_PREFIX " kdmctl -g reserve " ) ;
}
}
printf ( " [DEBUG 400.e] Creating new session \n \r " ) ; fflush ( stdout ) ;
if ( usebasedisplay ) {
printf ( " [DEBUG 400.e] Using base display \n \r " ) ; fflush ( stdout ) ;
}
// Attempt login
// // Find next sequential inactive display
// // FIXME
// // This assumes the original VT is on display 0 at all times,
// // which is not always true
// int minvt = 0;
// TQStringList sessionList = TQStringList::split('\t', result, false);
// for (newdisplayint = minvt; newdisplayint<MAXIMUM_VTS; newdisplayint++) {
// bool displayfound = false;
// for ( TQStringList::Iterator it = sessionList.begin(); it != sessionList.end(); ++it ) {
// TQStringList sessionInfoList = TQStringList::split(',', *it, true);
// if ((*(sessionInfoList.at(0))).startsWith(TQString(":%1").tqarg(newdisplayint))) {
// displayfound = true;
// }
// }
// if (displayfound == false) {
// break;
// }
// }
// This external bash code does not assume that the original VT is on display 0 at all times,
// but it is a bit sloppy to have to call it from here. FIXME
newdisplayint = systemexec ( " smartauth_displayfinder " ) ;
newdisplay = TQString ( " :%1 " ) . tqarg ( newdisplayint ) ;
printf ( " [DEBUG 400.f] The next display to start will be %s \n \r " , newdisplay . ascii ( ) ) ; fflush ( stdout ) ;
printf ( " [DEBUG 400.f] Logging in on display %s \n \r " , newdisplay . ascii ( ) ) ; fflush ( stdout ) ;
if ( ! usebasedisplay ) {
systemexec ( TRINITY_BIN_PREFIX " kdmctl -g reserve " ) ;
}
TQString kdmctl_command = TQString ( " login \t %1 \t now \t %2 \t %3 \n " ) . tqarg ( newdisplay ) . tqarg ( smartcard_username ) . tqarg ( smartcard_password ) ;
FILE * kdmctlpipe = popen ( TRINITY_BIN_PREFIX " kdmctl -g - " , " w " ) ;
if ( pipe ) {
fputs ( kdmctl_command . ascii ( ) , kdmctlpipe ) ;
fflush ( kdmctlpipe ) ;
pclose ( kdmctlpipe ) ;
// Construct login string
TQString logincommand = TQString ( " LOGIN \t %1 \t %2 \n " ) . tqarg ( smartcard_username ) . tqarg ( smartcard_password ) ;
if ( writefile ( TQString ( KDM_CONTROL_FIFO_FILE ) . tqarg ( newdisplayint ) , logincommand ) < 0 ) {
// Uh oh, something failed...
printf ( " Unable to write to KDM control socket %s \n \r " , ( TQString ( KDM_CONTROL_FIFO_FILE ) . tqarg ( newdisplayint ) ) . ascii ( ) ) ; fflush ( stdout ) ;
}
sleep ( 2 ) ;
systemexec ( ( TQString ( TRINITY_BIN_PREFIX " kdmctl -g activate %1 " ) . tqarg ( newdisplay ) ) . ascii ( ) ) ;
udisplay = newdisplay ;
}