/* Smart Card TDE Authentication Script (c) 2010-2011 Timothy Pearson
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# define _XOPEN_SOURCE 500
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <unistd.h>
# include <errno.h>
# include <fcntl.h>
# include <limits.h>
# include <dirent.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/select.h>
# include <sys/time.h>
# include <termios.h>
# include <signal.h>
# include <ftw.h>
# include <tqstring.h>
# include <tqstringlist.h>
// Maximum number of virtual terminals on this system
# define MAXIMUM_VTS 49
// The [secure] temporary directory for authentication
# define SECURE_DIRECTORY_PATH " / tmp / smartauth"
// The Trinity binary directory
# define TRINITY_BIN_PREFIX " / opt / trinity / bin / "
// Some internal constants
# define CREATE_LIFE_CYCLE "01"
# define tqarg arg
// In ckpass.o
extern " C " {
int check_password ( const char * username , const char * password ) ;
}
static TQString secure_directory ;
static TQString command_mode ;
static TQString select_file ;
static TQString read_binary ;
static TQString update_binary ;
static TQString delete_file ;
static TQString get_challenge ;
static TQString external_auth ;
static TQString activate_file ;
static TQString hexidecimal_key ;
static TQString darray [ MAXIMUM_VTS ] ;
static FILE * opensc_explorer_file ;
TQString readfile ( const char * filename ) {
FILE * fp ;
long len ;
char * buf ;
fp = fopen ( filename , " rb " ) ;
if ( fp = = NULL ) {
printf ( " [WARNING] Unable to read from file %s \n \r " , filename ) ;
return TQString ( ) ;
}
fseek ( fp , 0 , SEEK_END ) ; // Seek to end
len = ftell ( fp ) ; // Get position at end (length)
fseek ( fp , 0 , SEEK_SET ) ; // Seek to beginning
buf = ( char * ) malloc ( len ) ; // Malloc the buffer
fread ( buf , len , 1 , fp ) ; // Read file
fclose ( fp ) ;
buf [ len ] = 0 ;
TQString contents = TQString ( buf ) ;
free ( buf ) ; // Free the buffer
return contents ;
}
TQString exec ( const char * cmd ) {
TQString bashcommand = cmd ;
bashcommand = bashcommand . replace ( " \" " , " \\ \" " ) ;
bashcommand = TQString ( " /bin/bash -c \" %1 \" " ) . tqarg ( bashcommand ) ;
FILE * pipe = popen ( bashcommand . ascii ( ) , " r " ) ;
if ( ! pipe ) return " ERROR " ;
char buffer [ 128 ] ;
TQString result = " " ;
while ( ! feof ( pipe ) ) {
if ( fgets ( buffer , 128 , pipe ) ! = NULL ) {
result + = buffer ;
}
}
pclose ( pipe ) ;
result . remove ( result . length ( ) , 1 ) ;
return result ;
}
int systemexec ( const char * cmd ) {
TQString bashcommand = cmd ;
bashcommand = bashcommand . replace ( " \" " , " \\ \" " ) ;
bashcommand = TQString ( " /bin/bash -c \" %1 \" " ) . tqarg ( bashcommand ) ;
return system ( bashcommand . ascii ( ) ) > > 8 ;
}
TQString execret ( const char * cmd , int * retcode ) {
TQString bashcommand = cmd ;
bashcommand = bashcommand . replace ( " \" " , " \\ \" " ) ;
bashcommand = TQString ( " /bin/bash -c \" %1 \" " ) . tqarg ( bashcommand ) ;
FILE * pipe = popen ( bashcommand . ascii ( ) , " r " ) ;
if ( ! pipe ) return " ERROR " ;
char buffer [ 128 ] ;
TQString result = " " ;
while ( ! feof ( pipe ) ) {
if ( fgets ( buffer , 128 , pipe ) ! = NULL ) {
result + = buffer ;
}
}
* retcode = pclose ( pipe ) > > 8 ;
result . remove ( result . length ( ) , 1 ) ;
return result ;
}
int unlink_cb ( const char * fpath , const struct stat * sb , int typeflag , struct FTW * ftwbuf )
{
int rv = remove ( fpath ) ;
if ( rv )
perror ( fpath ) ;
return rv ;
}
int rmrf ( const char * path )
{
return nftw ( path , unlink_cb , 64 , FTW_DEPTH | FTW_PHYS ) ;
}
TQString get_file ( TQString prefix , TQString mode ) {
if ( command_mode = = " acos " ) {
// Select EF prefix under DF 1000
systemexec ( ( TQString ( " echo \" %1 %2 \" > %3/query " ) . tqarg ( select_file ) . tqarg ( prefix ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " scriptor %1/query 1> %2/response2 " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
// printf("[DEBUG 100.0] %s\n\r", readfile((TQString("%1/response2").tqarg(secure_directory))).ascii());
// Read binary
systemexec ( ( TQString ( " echo \" %1 \" > %2/query " ) . tqarg ( read_binary ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " scriptor %1/query 1> %2/response2 " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
TQString authokresponse = " 90 00 : Normal processing " ;
TQString response1 = exec ( ( TQString ( " cat %1/response2 | grep \" %2 \" " ) . tqarg ( secure_directory ) . tqarg ( authokresponse ) ) . ascii ( ) ) ;
if ( response1 ! = " " ) {
systemexec ( ( TQString ( " cat %1/response2 | tr -d ' \n ' > %2/response4 " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
TQString stringtoreplace = " Using T=0 protocol00 B0 00 00 FF> 00 B0 00 00 FF< " ;
TQString newstring = " " ;
systemexec ( ( TQString ( " sed -i \" s#%1#%2#g \" %3/response4 " ) . tqarg ( stringtoreplace ) . tqarg ( newstring ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
stringtoreplace = " 90 00 : Normal processing. " ;
newstring = " " ;
systemexec ( ( TQString ( " sed -i \" s#%1#%2#g \" %3/response4 " ) . tqarg ( stringtoreplace ) . tqarg ( newstring ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
if ( mode = = " text " ) {
stringtoreplace = " 00 " ;
newstring = " " ;
systemexec ( ( TQString ( " sed -i \" s#%1#%2#g \" %3/response4 " ) . tqarg ( stringtoreplace ) . tqarg ( newstring ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
}
// printf("[DEBUG 100.1] %s\n\r", readfile((TQString("%1/response4").tqarg(secure_directory))).ascii());
unlink ( ( TQString ( " %1/lukskey " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " xxd -r -p %1/response4 %2/lukskey " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
return ( TQString ( " %1/lukskey " ) . tqarg ( secure_directory ) ) ;
}
}
if ( command_mode = = " cryptoflex " ) {
TQString file = TQString ( prefix ) . replace ( ' ' , " " ) ;
unlink ( ( TQString ( " 3F00_%1 " ) . tqarg ( file ) ) . ascii ( ) ) ;
// systemexec((TQString("echo \"get %1\" | opensc-explorer").tqarg(file)).ascii());
fputs ( ( TQString ( " get %1 \n " ) . tqarg ( file ) ) . ascii ( ) , opensc_explorer_file ) ;
fflush ( opensc_explorer_file ) ;
int j ;
// Wait up to 2 seconds for the file to be written
for ( j = 0 ; j < 200 ; j + + ) {
FILE * fp1 = fopen ( ( TQString ( " 3F00_%1 " ) . tqarg ( file ) ) . ascii ( ) , " r " ) ;
if ( fp1 ) {
// file exists
fclose ( fp1 ) ;
break ;
}
usleep ( 10000 ) ;
}
usleep ( 100000 ) ; // [FIXME] Here I assume that the entire file will be written (after it was created) within 100us. This may not be correct in all cases!
return TQString ( " 3F00_%1 " ) . tqarg ( file ) ;
}
}
void createfile ( TQString prefix , TQString mode )
{
if ( command_mode = = " cryptoflex " ) {
// Create transparent file with permissions:
// delete, terminate, activate, deactivate, update, read for Key 1 and Key 2 only
systemexec ( ( TQString ( " echo \" F0 E0 00 FF 10 FF FF 00 %1 %2 01 3F 44 FF 44 01 03 11 FF 11 \" > %3/query " ) . tqarg ( prefix ) . tqarg ( mode ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " scriptor %1/query 1> %2/response2 2>/dev/null " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
}
if ( command_mode = = " acos " ) {
// Create transparent file with permissions:
// delete, terminate, activate, deactivate, update, read for Key 1, Key 2, and Key 3 only (SE 04)
// created in DF 1000 under MF, SE file is 10FE
// SIZE TRANSPARENT
systemexec ( ( TQString ( " echo \" 00 E0 00 00 1A 62 18 80 02 00 %1 82 01 01 83 02 %2 8A 01 %3 8C 08 7F 04 04 04 04 04 04 04 \" > %4/query " ) . tqarg ( prefix ) . tqarg ( mode ) . tqarg ( CREATE_LIFE_CYCLE ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " scriptor %1/query 1> %2/response2 2>/dev/null " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
printf ( " [DEBUG 300.0] %s \n \r " , readfile ( ( TQString ( " %1/response2 " ) . tqarg ( secure_directory ) ) ) . ascii ( ) ) ;
}
}
void update_file ( TQString prefix , TQString mode ) {
if ( command_mode = = " acos " ) {
// Select EF prefix under DF 1000
systemexec ( ( TQString ( " echo \" $SELECT_FILE %1 \" > %2/query " ) . tqarg ( prefix ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " scriptor %1/query 1> %2/response2 " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
printf ( " [DEBUG 200.0] %s \n \r " , readfile ( ( TQString ( " %1/response2 " ) . tqarg ( secure_directory ) ) ) . ascii ( ) ) ;
// Update existing file
// Zero pad input file
systemexec ( ( TQString ( " dd if=/dev/zero of=%1/response2 bs=1 count=255 2>/dev/null 1>/dev/null " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " dd if=%1 of=%2/response2 bs=1 count=255 conv=notrunc 2>/dev/null 1>/dev/null " ) . tqarg ( mode ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
// Truncate to 255 bytes and expand to standard hex listing format
systemexec ( ( TQString ( " xxd -l 255 -ps -c 1 %1/response2 > %2/response " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " cat %1/response | tr ' \n ' ' ' > %1/hexready " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
TQString hexready = readfile ( ( TQString ( " %1/hexready " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " echo \" %1 %2 \" > %3/query " ) . tqarg ( update_binary ) . tqarg ( hexready ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " scriptor %1/query 1> %2/response2 2>/dev/null " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
printf ( " [DEBUG 200.1] %s \n \r " , readfile ( ( TQString ( " %1/response2 " ) . tqarg ( secure_directory ) ) ) . ascii ( ) ) ;
}
if ( command_mode = = " cryptoflex " ) {
// Delete old file
systemexec ( ( TQString ( " echo \" %1 $1 \" > %2/query " ) . tqarg ( delete_file ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " scriptor %1/query 1> %2/response2 2>/dev/null " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
printf ( " [DEBUG 200.2] %s \n \r " , readfile ( ( TQString ( " %1/response2 " ) . tqarg ( secure_directory ) ) ) . ascii ( ) ) ;
// Create new file
createfile ( " FF " , prefix ) ;
TQString file = TQString ( prefix ) . replace ( ' ' , " " ) ;
systemexec ( ( TQString ( " echo \" put %1 %2 \" | opensc-explorer " ) . tqarg ( file ) . tqarg ( mode ) ) . ascii ( ) ) ;
}
}
int main ( int argc , char * argv [ ] )
{
TQString smartcard_username ;
TQString oldsmartcard_username ;
TQString smartcard_password ;
TQString smartcard_slave ;
TQString lverify ;
TQString cverify ;
TQString udisplay ;
TQString newdisplay ;
TQString logouttest ;
TQString blankresult ;
TQString smartcard_minutes_raw ;
int timer ;
int smartcard_minutes ;
int internet_minutes ;
int newdisplayint ;
// Create the secure directory and lock it down
secure_directory = SECURE_DIRECTORY_PATH ;
rmrf ( secure_directory . ascii ( ) ) ;
mkdir ( secure_directory . ascii ( ) , 600 ) ;
chown ( secure_directory . ascii ( ) , 0 , 0 ) ;
chmod ( secure_directory . ascii ( ) , 600 ) ;
secure_directory = exec ( " mktemp " SECURE_DIRECTORY_PATH " /smartauthmon.XXXXXXXXXX " ) ;
secure_directory . replace ( ' \n ' , " " ) ;
rmrf ( secure_directory . ascii ( ) ) ;
mkdir ( secure_directory . ascii ( ) , 600 ) ;
chown ( secure_directory . ascii ( ) , 0 , 0 ) ;
chmod ( secure_directory . ascii ( ) , 600 ) ;
// Restart PCSCD and kill spurious processes
systemexec ( " killall -9 pcscd 2>/dev/null 1>/dev/null " ) ;
systemexec ( " /etc/init.d/pcscd restart 2>/dev/null 1>/dev/null " ) ;
systemexec ( " /etc/init.d/pcscd-nodbus restart 2>/dev/null 1>/dev/null " ) ;
// See if required programs are installed
TQString scriptor = exec ( " whereis scriptor " ) ;
if ( scriptor = = " scriptor: " ) {
printf ( " ERROR: scriptor is not installed! This program cannot continue! \n \r " ) ;
return 1 ;
}
TQString opensc = exec ( " whereis opensc-explorer " ) ;
if ( opensc = = " opensc-explorer: " ) {
printf ( " ERROR: opensc-explorer is not installed! This program cannot continue! \n \r " ) ;
return 1 ;
}
// Read hexidecimal_key from the system crypto files
FILE * fpkey = fopen ( " /etc/smartauth/smartauthmon.key " , " rb " ) ;
if ( fpkey = = NULL ) {
printf ( " Smart card login has been disabled. Exiting... \n \r " ) ;
return 1 ;
}
else {
fclose ( fpkey ) ;
}
hexidecimal_key = readfile ( " /etc/smartauth/smartauthmon.key " ) ;
hexidecimal_key . replace ( ' \n ' , " " ) ;
oldsmartcard_username = " " ;
printf ( " [DEBUG 400.0] Ready... \n \r " ) ;
while ( 1 ) {
sleep ( 1 ) ;
int output = systemexec ( " echo \" exit \" | scriptor 2>/dev/null 1>/dev/null " ) ;
if ( output = = 0 ) {
printf ( " [DEBUG 400.1] Card inserted! \n \r " ) ;
systemexec ( " echo \" TAuthenticating SmartCard... \" > /tmp/ksocket-global/kdesktoplockcontrol & " ) ;
// Get card ATR
systemexec ( ( TQString ( " echo \" RESET \" > %1/query " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " scriptor %1/query 1> %2/response2 " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
TQString authokresponse = " OK: " ;
TQString response1 = exec ( ( TQString ( " cat %1/response2 | grep \" %2 \" " ) . tqarg ( secure_directory ) . tqarg ( authokresponse ) ) . ascii ( ) ) ;
if ( response1 ! = " " ) {
systemexec ( ( TQString ( " cat %1/response2 | tr -d ' \n ' > %2/response4 " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
TQString stringtoreplace = " Using T=0 protocolRESET> RESET< OK: " ;
TQString newstring = " " ;
systemexec ( ( TQString ( " sed -i \" s#%1#%2#g \" %3/response4 " ) . tqarg ( stringtoreplace ) . tqarg ( newstring ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
TQString smartatr = readfile ( ( TQString ( " %1/response4 " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
printf ( " [DEBUG 400.2] Got ATR: %s \n \r " , smartatr . ascii ( ) ) ;
if ( smartatr = = " 3B BE 18 00 00 41 05 10 00 00 00 00 00 00 00 00 00 90 00 " ) {
printf ( " [DEBUG 400.3] Detected ACOS5 card \n \r " ) ;
command_mode = " acos " ;
}
if ( smartatr = = " 3B 02 14 50 " ) {
printf ( " [DEBUG 400.3] Detected Schlumberger CryptoFlex card \n \r " ) ;
command_mode = " cryptoflex " ;
}
}
else {
printf ( " [DEBUG 400.3] No card detected! \n \r " ) ;
}
if ( command_mode = = " cryptoflex " ) {
get_challenge = " C0 84 00 00 08 " ;
external_auth = " C0 82 00 00 07 01 " ;
select_file = " C0 A4 00 00 02 " ;
delete_file = " F0 E4 00 00 02 " ;
}
if ( command_mode = = " acos " ) {
get_challenge = " 00 84 00 00 08 " ;
external_auth = " 00 82 00 82 08 " ; // Key 2
select_file = " 00 A4 00 00 02 " ;
delete_file = " 00 E4 00 00 00 " ;
read_binary = " 00 B0 00 00 FF " ;
update_binary = " 00 D6 00 00 FF " ;
activate_file = " 00 44 00 00 02 " ;
}
// Authenticate card
if ( command_mode = = " acos " ) {
// Select MF
systemexec ( ( TQString ( " echo \" 00 A4 00 00 00 \" > %1/query " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " scriptor %1/query 1> %2/response2 " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
printf ( " [DEBUG 400.4] %s \n \r " , readfile ( ( TQString ( " %1/response2 " ) . tqarg ( secure_directory ) ) ) . ascii ( ) ) ;
// Select DF 1000 under MF
systemexec ( ( TQString ( " echo \" %1 10 00 \" > %2/query " ) . tqarg ( select_file ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " scriptor %1/query 1> %2/response2 " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
printf ( " [DEBUG 400.5] %s \n \r " , readfile ( ( TQString ( " %1/response2 " ) . tqarg ( secure_directory ) ) ) . ascii ( ) ) ;
}
systemexec ( ( TQString ( " echo %1 > %2/authscript " ) . tqarg ( get_challenge ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " scriptor %1/authscript | grep 'Normal processing' > %2/challenge " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " perl -pi -e 's/ //g' %1/challenge " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " perl -pi -e 's/:Normalprocessing.//g' %1/challenge " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " perl -pi -e 's/<//g' %1/challenge " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " xxd -r -p %1/challenge %2/challenge " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
// Now DES encrypt the challenge
// Later, change the initialization vector to random if possible
// Create the response from the challenge
systemexec ( ( TQString ( " openssl des-ecb -in %1/challenge -out %2/response -K %3 -iv 1 " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) . tqarg ( hexidecimal_key ) ) . ascii ( ) ) ;
if ( command_mode = = " acos " ) {
// Truncate to 8 bytes
systemexec ( ( TQString ( " dd if=%1/response of=%2/response2 bs=1 count=8 2>/dev/null 1>/dev/null " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
// Expand to standard hex listing format
systemexec ( ( TQString ( " xxd -g 1 %1/response2 %2/response " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " dd if=%1/response of=%2/response2 bs=1 count=23 skip=9 2>/dev/null 1>/dev/null " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
}
if ( command_mode = = " cryptoflex " ) {
// Truncate to 6 bytes
systemexec ( ( TQString ( " dd if=%1/response of=%2/response2 bs=1 count=6 2>/dev/null 1>/dev/null " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
// Expand to standard hex listing format
systemexec ( ( TQString ( " xxd -g 1 %1/response2 %2/response " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " dd if=%1/response of=%2/response2 bs=1 count=17 skip=9 2>/dev/null 1>/dev/null " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
}
// Assemble the response file
TQString response2 = readfile ( ( TQString ( " %1/response2 " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
response1 = TQString ( " %1 %2 " ) . tqarg ( external_auth ) . tqarg ( response2 ) ;
systemexec ( ( TQString ( " echo %1 > %2/response " ) . tqarg ( response1 ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
// Send the response!
systemexec ( ( TQString ( " scriptor %1/response > %2/response2 " ) . tqarg ( secure_directory ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
// Get the result
authokresponse = " < 90 00 : Normal processing " ;
response1 = exec ( ( TQString ( " cat %1/response2 | grep \" %2 \" " ) . tqarg ( secure_directory ) . tqarg ( authokresponse ) ) . ascii ( ) ) ;
printf ( " [DEBUG 400.6] %s \n \r " , response1 . ascii ( ) ) ;
if ( response1 ! = " " ) {
printf ( " [DEBUG 400.7] Smart card validation successfull! \n \r " ) ;
if ( command_mode = = " cryptoflex " ) {
opensc_explorer_file = popen ( " opensc-explorer 2>/dev/null 1>/dev/null " , " w " ) ;
}
// Get username and password
TQString response = get_file ( " 10 02 " , " text " ) ;
smartcard_username = readfile ( response ) ;
smartcard_username = smartcard_username . replace ( ' \n ' , " " ) ;
unlink ( response . ascii ( ) ) ;
response = get_file ( " 10 03 " , " text " ) ;
smartcard_password = readfile ( response . ascii ( ) ) ;
smartcard_password = smartcard_password . replace ( ' \n ' , " " ) ;
unlink ( response . ascii ( ) ) ;
response = get_file ( " 10 04 " , " text " ) ;
smartcard_slave = readfile ( response ) ;
smartcard_slave = smartcard_slave . replace ( ' \n ' , " " ) ;
unlink ( response . ascii ( ) ) ;
if ( smartcard_slave = = " SLAVE " ) {
get_file ( " 10 05 " , " text " ) ;
smartcard_minutes_raw = readfile ( response ) ;
smartcard_minutes_raw = smartcard_minutes_raw . replace ( ' \n ' , " " ) ;
unlink ( response . ascii ( ) ) ;
get_file ( " 10 06 " , " text " ) ;
internet_minutes = readfile ( response ) . toInt ( ) ;
unlink ( response . ascii ( ) ) ;
}
}
else {
printf ( " [DEBUG 400.7] This card does not recognize this system! \n \r " ) ;
systemexec ( " echo \" EInvalid SmartCard Inserted \" > /tmp/ksocket-global/kdesktoplockcontrol & " ) ;
sleep ( 1 ) ;
smartcard_username = " " ;
unlink ( ( TQString ( " %1/password " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
smartcard_slave = " " ;
}
if ( smartcard_slave = = " SLAVE " ) {
if ( smartcard_minutes_raw = = " " ) {
smartcard_minutes = 1 ;
}
else {
smartcard_minutes = smartcard_minutes_raw . toInt ( ) ;
}
// Decrement minutes on card
if ( smartcard_minutes > 0 ) {
smartcard_minutes = smartcard_minutes - 1 ;
systemexec ( ( TQString ( " echo %1 > %2/minutes " ) . tqarg ( smartcard_minutes ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
update_file ( " 10 05 " , TQString ( " %1/minutes " ) . tqarg ( secure_directory ) ) ;
}
if ( smartcard_minutes = = 0 ) {
printf ( " [DEBUG 400.8] Minutes have been used up! \n \r " ) ;
// Prohibit logon
smartcard_username = " " ;
unlink ( ( TQString ( " %1/password " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
}
mkdir ( " /etc/smartmon " , 644 ) ;
systemexec ( ( TQString ( " echo %1 > /etc/smartmon/minutesremaining " ) . tqarg ( smartcard_minutes ) ) . ascii ( ) ) ;
chmod ( " /etc/smartmon/minutesremaining " , 755 ) ;
}
// Initialize variables
int loginok = 1 ;
// Try to do the authentication
TQString result = " " ;
int timeout = 0 ;
int errcode = 0 ;
int waserror = 0 ;
int noactivesessions = 0 ;
result = exec ( TRINITY_BIN_PREFIX " kdmctl -g list " ) ;
if ( result = = " ok " ) {
noactivesessions = 1 ;
result = " okbutempty " ;
}
printf ( " [DEBUG 400.9] %s \n \r " , result . ascii ( ) ) ;
TQString resultbkp = result ;
if ( errcode = = 0 ) {
// Allow KDM to finish starting
if ( waserror = = 1 ) {
sleep ( 10 ) ;
}
// Zero the desktop array
int index = 0 ;
while ( index < MAXIMUM_VTS ) {
darray [ index ] = " " ;
index + + ;
}
if ( result ! = " okbutempty " ) {
TQStringList sessionList = TQStringList : : split ( ' \t ' , result , false ) ;
for ( TQStringList : : Iterator it = sessionList . begin ( ) ; it ! = sessionList . end ( ) ; + + it ) {
TQStringList sessionInfoList = TQStringList : : split ( ' , ' , * it , true ) ;
if ( ( * ( sessionInfoList . at ( 0 ) ) ) . startsWith ( " : " ) ) {
darray [ ( * ( sessionInfoList . at ( 0 ) ) ) . mid ( 1 ) . toInt ( ) ] = ( * ( sessionInfoList . at ( 2 ) ) ) ;
}
}
}
// See if the desired user is already logged in
index = 0 ;
int foundsession = 0 ;
while ( index < MAXIMUM_VTS ) {
if ( darray [ index ] = = smartcard_username ) {
if ( darray [ index ] ! = " " ) {
printf ( " [DEBUG 400.a] Found existing session on desktop: %d \n \r " , index ) ;
foundsession = 1 ;
udisplay = TQString ( " :%1 " ) . tqarg ( index ) ;
// Check password
if ( check_password ( smartcard_username . ascii ( ) , smartcard_password . ascii ( ) ) = = 0 ) {
systemexec ( ( TQString ( " su %1 -c \" export DISPLAY=%2; " TRINITY_BIN_PREFIX " dcop kdesktop KScreensaverIface quit \" " ) . tqarg ( smartcard_username ) . tqarg ( udisplay ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " su %1 -c \" export DISPLAY=%2; " TRINITY_BIN_PREFIX " dcop kdesktop KScreensaverIface enable false \" " ) . tqarg ( smartcard_username ) . tqarg ( udisplay ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( TRINITY_BIN_PREFIX " kdmctl activate %1 " ) . tqarg ( udisplay ) ) . ascii ( ) ) ;
}
else {
systemexec ( " echo \" EUnauthorized SmartCard Inserted \" > /tmp/ksocket-global/kdesktoplockcontrol & " ) ;
}
}
else {
printf ( " [DEBUG 400.b] Username not specified \n \r " ) ;
foundsession = 2 ;
sleep ( 1 ) ;
}
}
index + + ;
}
if ( foundsession = = 0 ) {
printf ( " [DEBUG 400.c] Existing session not found, starting new... \n \r " ) ;
// 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 ( ) ) ;
if ( newdisplay ! = " " ) {
usebasedisplay = 1 ;
}
}
if ( ! resultbkp . contains ( " ,vt " ) ) {
newdisplay = exec ( " ls /var/run/xdmctl/ | grep 'xdmctl-:0' " ) ;
printf ( " [DEBUG 400.d] %s \n \r " , newdisplay . ascii ( ) ) ;
if ( newdisplay ! = " " ) {
usebasedisplay = 1 ;
}
}
printf ( " [DEBUG 400.e] Creating new session \n \r " ) ;
// Attempt login
// Find next sequential inactive display
// FIXME
// This assumes the original VT is on display 0 at all times
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 ;
}
}
newdisplay = TQString ( " :%1 " ) . tqarg ( newdisplayint ) ;
printf ( " [DEBUG 400.f] The next display to start will be %s \n \r " , newdisplay . ascii ( ) ) ;
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 ) ;
}
sleep ( 2 ) ;
systemexec ( ( TQString ( TRINITY_BIN_PREFIX " kdmctl -g activate %1 " ) . tqarg ( newdisplay ) ) . ascii ( ) ) ;
udisplay = newdisplay ;
}
if ( smartcard_slave = = " SLAVE " ) {
if ( smartcard_minutes < 5 ) {
systemexec ( ( TQString ( " su %1 -c \" export DISPLAY=%2; zenity --warning --text 'You have less than 5 minutes of computer time remaining' || exit 0 \" & " ) . tqarg ( smartcard_username ) . tqarg ( udisplay ) ) . ascii ( ) ) ;
}
}
unlink ( ( TQString ( " %1/password " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
// if (loginok == 1) {
// Wait for SmartCard removal
systemexec ( " echo \" C \" > /tmp/ksocket-global/kdesktoplockcontrol & " ) ;
timer = 60 ;
output = 0 ;
while ( output = = 0 ) {
sleep ( 1 ) ;
systemexec ( ( TQString ( " su %1 -c \" export DISPLAY=%2; " TRINITY_BIN_PREFIX " dcop kdesktop KScreensaverIface quit \" " ) . tqarg ( smartcard_username ) . tqarg ( udisplay ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " su %1 -c \" export DISPLAY=%2; " TRINITY_BIN_PREFIX " dcop kdesktop KScreensaverIface enable false \" " ) . tqarg ( smartcard_username ) . tqarg ( udisplay ) ) . ascii ( ) ) ;
output = systemexec ( " echo \" exit \" | scriptor 2>/dev/null 1>/dev/null " ) ;
if ( smartcard_slave = = " SLAVE " ) {
timer - - ;
if ( timer = = 0 ) {
// 60 seconds have passed, decrement minutes on card
smartcard_minutes - - ;
systemexec ( ( TQString ( " echo %1 > /etc/smartmon/minutesremaining " ) . tqarg ( smartcard_minutes ) ) . ascii ( ) ) ;
chmod ( " /etc/smartmon/minutesremaining " , 755 ) ;
timer = 60 ;
systemexec ( ( TQString ( " echo %1 > %2/minutes " ) . tqarg ( smartcard_minutes ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
update_file ( " 10 05 " , TQString ( " %1/minutes " ) . tqarg ( secure_directory ) ) ;
if ( smartcard_minutes = = 0 ) {
printf ( " [DEBUG 401.0] Minutes have been used up! \n \r " ) ;
// Prohibit logon
smartcard_username = " " ;
unlink ( ( TQString ( " %1/password " ) . tqarg ( secure_directory ) ) . ascii ( ) ) ;
}
mkdir ( " /etc/smartmon " , 644 ) ;
systemexec ( ( TQString ( " echo %1 > /etc/smartmon/minutesremaining " ) . tqarg ( smartcard_minutes ) ) . ascii ( ) ) ;
chmod ( " /etc/smartmon/minutesremaining " , 755 ) ;
if ( smartcard_minutes = = 5 ) {
systemexec ( ( TQString ( " su %1 -c \" export DISPLAY=%2; zenity --warning --text 'You have less than 5 minutes of computer time remaining' || exit 0 \" & " ) . tqarg ( smartcard_username ) . tqarg ( udisplay ) ) . ascii ( ) ) ;
}
if ( smartcard_minutes = = 0 ) {
printf ( " [DEBUG 401.1] Minutes have been used up! \n \r " ) ;
printf ( " [DEBUG 401.2] Beginning logoff process \n \r " ) ;
output = 254 ;
}
}
}
}
printf ( " [DEBUG 401.3] Card removed \n \r " ) ;
// Is the user still logged in?
result = " ok " ;
timeout = 0 ;
errcode = 0 ;
result = exec ( TRINITY_BIN_PREFIX " kdmctl -g list " ) ;
if ( result = = " ok " ) {
noactivesessions = 1 ;
result = " okbutempty " ;
}
printf ( " [DEBUG 401.4] %s \n \r " , result . ascii ( ) ) ;
// Zero the desktop array
index = 0 ;
while ( index < MAXIMUM_VTS ) {
darray [ index ] = " " ;
index + + ;
}
TQStringList sessionList = TQStringList : : split ( ' \t ' , result , false ) ;
for ( TQStringList : : Iterator it = sessionList . begin ( ) ; it ! = sessionList . end ( ) ; + + it ) {
TQStringList sessionInfoList = TQStringList : : split ( ' , ' , * it , true ) ;
if ( ( * ( sessionInfoList . at ( 0 ) ) ) . startsWith ( " : " ) ) {
darray [ ( * ( sessionInfoList . at ( 0 ) ) ) . mid ( 1 ) . toInt ( ) ] = ( * ( sessionInfoList . at ( 2 ) ) ) ;
}
}
// See if the desired user is still logged in
index = 0 ;
foundsession = 0 ;
while ( index ! = MAXIMUM_VTS ) {
if ( darray [ index ] = = smartcard_username ) {
if ( darray [ index ] ! = " " ) {
printf ( " [DEBUG 401.5] Found existing session on desktop: %d \n \r " , index ) ;
udisplay = TQString ( " :%1 " ) . tqarg ( index ) ;
foundsession = 1 ;
errcode = 1 ;
timeout = 0 ;
blankresult = " " ;
while ( blankresult ! = " true " ) {
systemexec ( ( TQString ( TRINITY_BIN_PREFIX " kdmctl -g activate %1 " ) . tqarg ( udisplay ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " su %1 -c \" export DISPLAY=%2; " TRINITY_BIN_PREFIX " dcop kdesktop KScreensaverIface enable true \" " ) . tqarg ( smartcard_username ) . tqarg ( udisplay ) ) . ascii ( ) ) ;
systemexec ( ( TQString ( " su %1 -c \" export DISPLAY=%2; " TRINITY_BIN_PREFIX " dcop kdesktop KScreensaverIface lock \" " ) . tqarg ( smartcard_username ) . tqarg ( udisplay ) ) . ascii ( ) ) ;
int retcode ;
blankresult = execret ( TQString ( " su %1 -c \" export DISPLAY=%2; " TRINITY_BIN_PREFIX " dcop kdesktop KScreensaverIface isBlanked \" " ) . tqarg ( smartcard_username ) . tqarg ( udisplay ) . ascii ( ) , & retcode ) ;
if ( retcode ! = 0 ) {
blankresult = " true " ;
}
blankresult = blankresult . replace ( ' \n ' , " " ) ;
logouttest = exec ( ( TQString ( " echo %1 | grep 'target display has no VT assigned' " ) . tqarg ( blankresult ) ) . ascii ( ) ) ;
if ( logouttest ! = " " ) {
printf ( " [DEBUG 401.6] User has logged out \n \r " ) ;
blankresult = " true " ;
}
}
}
else {
printf ( " [DEBUG 401.7] Username not specified! \n \r " ) ;
sleep ( 1 ) ;
}
}
index + + ;
}
// }
}
if ( command_mode = = " cryptoflex " ) {
pclose ( opensc_explorer_file ) ;
}
smartcard_username = " " ;
unlink ( " /etc/smartmon/minutesremaining " ) ;
systemexec ( " echo \" C \" > /tmp/ksocket-global/kdesktoplockcontrol & " ) ;
}
}
}