summaryrefslogtreecommitdiffstats
path: root/src/smartauthmon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/smartauthmon.cpp')
-rw-r--r--src/smartauthmon.cpp839
1 files changed, 0 insertions, 839 deletions
diff --git a/src/smartauthmon.cpp b/src/smartauthmon.cpp
deleted file mode 100644
index b83c402..0000000
--- a/src/smartauthmon.cpp
+++ /dev/null
@@ -1,839 +0,0 @@
-/* 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 <tqdir.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 TDM_CONTROL_FIFO_DIR "/tmp/tdesocket-global/tdm"
-#define TDM_CONTROL_FIFO_FILE "/tmp/tdesocket-global/tdm/tdmctl-%1"
-#define TDM_CONTROL_FIFO_SAK_FILE "/tmp/tdesocket-global/tdm/tdmctl-sak-%1"
-
-// 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;
-
-struct sigaction usr_action;
-sigset_t block_mask;
-
-void handle_sigpipe(int sig)
-{
- int uidnum;
- if (sig == SIGPIPE) {
- printf("Got SIGPIPE!\n"); fflush(stdout);
- }
-}
-
-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", filename); fflush(stdout);
- 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+1); // Malloc the buffer
- fread(buf,len,1,fp); // Read file
- fclose(fp);
- buf[len]=0;
- TQString contents(buf);
- free(buf); // Free the buffer
- 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", 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("\"", "\\\"");
- bashcommand = TQString("/bin/bash -c \"%1\"").arg(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\"").arg(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\"").arg(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").arg(select_file).arg(prefix).arg(secure_directory)).ascii());
- systemexec((TQString("scriptor %1/query 1> %2/response2").arg(secure_directory).arg(secure_directory)).ascii());
-// printf("[DEBUG 100.0] %s\n", readfile((TQString("%1/response2").arg(secure_directory))).ascii()); fflush(stdout);
-
- // Read binary
- systemexec((TQString("echo \"%1\" > %2/query").arg(read_binary).arg(secure_directory)).ascii());
- systemexec((TQString("scriptor %1/query 1> %2/response2").arg(secure_directory).arg(secure_directory)).ascii());
- TQString authokresponse="90 00 : Normal processing";
- TQString response1 = exec((TQString("cat %1/response2 | grep \"%2\"").arg(secure_directory).arg(authokresponse)).ascii());
- if (response1 != "") {
- systemexec((TQString("cat %1/response2 | tr -d '\n' > %2/response4").arg(secure_directory).arg(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").arg(stringtoreplace).arg(newstring).arg(secure_directory)).ascii());
- stringtoreplace=" 90 00 : Normal processing.";
- newstring="";
- systemexec((TQString("sed -i \"s#%1#%2#g\" %3/response4").arg(stringtoreplace).arg(newstring).arg(secure_directory)).ascii());
- if (mode == "text") {
- stringtoreplace=" 00";
- newstring="";
- systemexec((TQString("sed -i \"s#%1#%2#g\" %3/response4").arg(stringtoreplace).arg(newstring).arg(secure_directory)).ascii());
- }
-// printf("[DEBUG 100.1] %s\n", readfile((TQString("%1/response4").arg(secure_directory))).ascii()); fflush(stdout);
- unlink((TQString("%1/lukskey").arg(secure_directory)).ascii());
- systemexec((TQString("xxd -r -p %1/response4 %2/lukskey").arg(secure_directory).arg(secure_directory)).ascii());
- return(TQString("%1/lukskey").arg(secure_directory));
- }
- }
-
- if (command_mode == "cryptoflex") {
- TQString file = TQString(prefix).replace(' ', "");
- unlink((TQString("3F00_%1").arg(file)).ascii());
-// systemexec((TQString("echo \"get %1\" | opensc-explorer").arg(file)).ascii());
- fputs((TQString("get %1\n").arg(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").arg(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").arg(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").arg(prefix).arg(mode).arg(secure_directory)).ascii());
- systemexec((TQString("scriptor %1/query 1> %2/response2 2>/dev/null").arg(secure_directory).arg(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").arg(prefix).arg(mode).arg(CREATE_LIFE_CYCLE).arg(secure_directory)).ascii());
- systemexec((TQString("scriptor %1/query 1> %2/response2 2>/dev/null").arg(secure_directory)).ascii());
- printf("[DEBUG 300.0] %s\n", readfile((TQString("%1/response2").arg(secure_directory))).ascii()); fflush(stdout);
- }
-}
-
-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").arg(prefix).arg(secure_directory)).ascii());
- systemexec((TQString("scriptor %1/query 1> %2/response2").arg(secure_directory).arg(secure_directory)).ascii());
- printf("[DEBUG 200.0] %s\n", readfile((TQString("%1/response2").arg(secure_directory))).ascii()); fflush(stdout);
-
- // 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").arg(secure_directory)).ascii());
- systemexec((TQString("dd if=%1 of=%2/response2 bs=1 count=255 conv=notrunc 2>/dev/null 1>/dev/null").arg(mode).arg(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").arg(secure_directory).arg(secure_directory)).ascii());
- systemexec((TQString("cat %1/response | tr '\n' ' ' > %1/hexready").arg(secure_directory)).ascii());
- TQString hexready = readfile((TQString("%1/hexready").arg(secure_directory)).ascii());
- systemexec((TQString("echo \"%1 %2\" > %3/query").arg(update_binary).arg(hexready).arg(secure_directory)).ascii());
- systemexec((TQString("scriptor %1/query 1> %2/response2 2>/dev/null").arg(secure_directory).arg(secure_directory)).ascii());
- printf("[DEBUG 200.1] %s\n", readfile((TQString("%1/response2").arg(secure_directory))).ascii()); fflush(stdout);
- }
-
- if (command_mode == "cryptoflex") {
- // Delete old file
- systemexec((TQString("echo \"%1 $1\" > %2/query").arg(delete_file).arg(secure_directory)).ascii());
- systemexec((TQString("scriptor %1/query 1> %2/response2 2>/dev/null").arg(secure_directory).arg(secure_directory)).ascii());
- printf("[DEBUG 200.2] %s\n", readfile((TQString("%1/response2").arg(secure_directory))).ascii()); fflush(stdout);
-
- // Create new file
- createfile("FF", prefix);
- TQString file = TQString(prefix).replace(' ', "");
- systemexec((TQString("echo \"put %1 %2\" | opensc-explorer").arg(file).arg(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;
-
- printf("[DEBUG 390.0] Starting up\n"); 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());
- 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);
-
- // Terminate old pcscd process from initrd
- system("killall -9 pcscd");
-
- // 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"); fflush(stdout);
- return 1;
- }
- TQString opensc = exec("whereis opensc-explorer");
- if ( opensc == "opensc-explorer:" ) {
- printf("ERROR: opensc-explorer is not installed! This program cannot continue!\n"); fflush(stdout);
- return 1;
- }
-
- printf("[DEBUG 390.2] Reading keys\n"); fflush(stdout);
-
- // 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"); fflush(stdout);
- return 1;
- }
- else {
- fclose(fpkey);
- }
- hexidecimal_key = readfile("/etc/smartauth/smartauthmon.key");
- hexidecimal_key.replace('\n', "");
-
- oldsmartcard_username="";
- printf("[DEBUG 400.0] Ready...\n"); fflush(stdout);
- while (1) {
- sleep(1);
- int output = systemexec("echo \"exit\" | timeout 1 scriptor 2>/dev/null 1>/dev/null");
- if (output == 0) {
- printf("[DEBUG 400.1] Card inserted!\n"); fflush(stdout);
- systemexec("echo \"TAuthenticating SmartCard...\" > /tmp/tdesocket-global/kdesktoplockcontrol &");
-
- // Get card ATR
- systemexec((TQString("echo \"RESET\" > %1/query").arg(secure_directory)).ascii());
- systemexec((TQString("scriptor %1/query 1> %2/response2").arg(secure_directory).arg(secure_directory)).ascii());
- TQString authokresponse="OK: ";
- TQString response1 = exec((TQString("cat %1/response2 | grep \"%2\"").arg(secure_directory).arg(authokresponse)).ascii());
- if (response1 != "") {
- systemexec((TQString("cat %1/response2 | tr -d '\n' > %2/response4").arg(secure_directory).arg(secure_directory)).ascii());
- TQString stringtoreplace="Using T=0 protocolRESET> RESET< OK: ";
- TQString newstring="";
- systemexec((TQString("sed -i \"s#%1#%2#g\" %3/response4").arg(stringtoreplace).arg(newstring).arg(secure_directory)).ascii());
- TQString smartatr = readfile((TQString("%1/response4").arg(secure_directory)).ascii());
- printf("[DEBUG 400.2] Got ATR: %s\n", smartatr.ascii()); fflush(stdout);
- 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"); fflush(stdout);
- command_mode="acos";
- }
- if (smartatr == "3B 02 14 50 ") {
- printf("[DEBUG 400.3] Detected Schlumberger CryptoFlex card\n"); fflush(stdout);
- command_mode="cryptoflex";
- }
- }
- else {
- printf("[DEBUG 400.3] No card detected!\n"); fflush(stdout);
- }
-
- 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").arg(secure_directory)).ascii());
- systemexec((TQString("scriptor %1/query 1> %2/response2").arg(secure_directory).arg(secure_directory)).ascii());
- printf("[DEBUG 400.4] %s\n", readfile((TQString("%1/response2").arg(secure_directory))).ascii()); fflush(stdout);
-
- // Select DF 1000 under MF
- systemexec((TQString("echo \"%1 10 00\" > %2/query").arg(select_file).arg(secure_directory)).ascii());
- systemexec((TQString("scriptor %1/query 1> %2/response2").arg(secure_directory).arg(secure_directory)).ascii());
- printf("[DEBUG 400.5] %s\n", readfile((TQString("%1/response2").arg(secure_directory))).ascii()); fflush(stdout);
- }
-
- systemexec((TQString("echo %1 > %2/authscript").arg(get_challenge).arg(secure_directory)).ascii());
-
- systemexec((TQString("scriptor %1/authscript | grep 'Normal processing' > %2/challenge").arg(secure_directory).arg(secure_directory)).ascii());
- systemexec((TQString("perl -pi -e 's/ //g' %1/challenge").arg(secure_directory)).ascii());
- systemexec((TQString("perl -pi -e 's/:Normalprocessing.//g' %1/challenge").arg(secure_directory)).ascii());
- systemexec((TQString("perl -pi -e 's/<//g' %1/challenge").arg(secure_directory)).ascii());
- systemexec((TQString("xxd -r -p %1/challenge %2/challenge").arg(secure_directory).arg(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").arg(secure_directory).arg(secure_directory).arg(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").arg(secure_directory).arg(secure_directory)).ascii());
-
- // Expand to standard hex listing format
- systemexec((TQString("xxd -g 1 %1/response2 %2/response").arg(secure_directory).arg(secure_directory)).ascii());
- systemexec((TQString("dd if=%1/response of=%2/response2 bs=1 count=23 skip=9 2>/dev/null 1>/dev/null").arg(secure_directory).arg(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").arg(secure_directory).arg(secure_directory)).ascii());
-
- // Expand to standard hex listing format
- systemexec((TQString("xxd -g 1 %1/response2 %2/response").arg(secure_directory).arg(secure_directory)).ascii());
- systemexec((TQString("dd if=%1/response of=%2/response2 bs=1 count=17 skip=9 2>/dev/null 1>/dev/null").arg(secure_directory).arg(secure_directory)).ascii());
- }
-
- // Assemble the response file
- TQString response2 = readfile((TQString("%1/response2").arg(secure_directory)).ascii());
- response1 = TQString("%1 %2").arg(external_auth).arg(response2);
- systemexec((TQString("echo %1 > %2/response").arg(response1).arg(secure_directory)).ascii());
-
- // Send the response!
- systemexec((TQString("scriptor %1/response > %2/response2").arg(secure_directory).arg(secure_directory)).ascii());
-
- // Get the result
- authokresponse = "< 90 00 : Normal processing";
- response1 = exec((TQString("cat %1/response2 | grep \"%2\"").arg(secure_directory).arg(authokresponse)).ascii());
- printf("[DEBUG 400.6] %s\n", response1.ascii()); fflush(stdout);
- if (response1 != "") {
- printf("[DEBUG 400.7] Smart card validation successfull!\n"); fflush(stdout);
- 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"); fflush(stdout);
- systemexec("echo \"EInvalid SmartCard Inserted\" > /tmp/tdesocket-global/kdesktoplockcontrol &");
- sleep(1);
- smartcard_username="";
- unlink((TQString("%1/password").arg(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").arg(smartcard_minutes).arg(secure_directory)).ascii());
- update_file("10 05", TQString("%1/minutes").arg(secure_directory));
- }
-
- if (smartcard_minutes == 0) {
- printf("[DEBUG 400.8] Minutes have been used up!\n"); fflush(stdout);
- // Prohibit logon
- smartcard_username="";
- unlink((TQString("%1/password").arg(secure_directory)).ascii());
- }
-
- mkdir("/etc/smartmon", 644);
- systemexec((TQString("echo %1 > /etc/smartmon/minutesremaining").arg(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 "tdmctl -g list");
- if (result == "ok") {
- noactivesessions=1;
- result="okbutempty";
- }
- printf("[DEBUG 400.9] %s\n", result.ascii()); fflush(stdout);
- TQString resultbkp=result;
-
- if (errcode == 0) {
- // Allow TDM 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", index); fflush(stdout);
- foundsession=1;
- udisplay = TQString(":%1").arg(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\"").arg(smartcard_username).arg(udisplay)).ascii());
- systemexec((TQString("su %1 -c \"export DISPLAY=%2; " TRINITY_BIN_PREFIX "dcop kdesktop KScreensaverIface enable false\"").arg(smartcard_username).arg(udisplay)).ascii());
- systemexec((TQString(TRINITY_BIN_PREFIX "tdmctl activate %1").arg(udisplay)).ascii());
- }
- else {
- systemexec("echo \"EUnauthorized SmartCard Inserted\" > /tmp/tdesocket-global/kdesktoplockcontrol &");
- }
- }
- else {
- printf("[DEBUG 400.b] Username not specified\n"); fflush(stdout);
- foundsession=2;
- sleep(1);
- }
- }
- index++;
- }
-
- if (foundsession == 0) {
- printf("[DEBUG 400.c] Existing session not found, starting new...\n"); fflush(stdout);
-
- // Get directory listing of tdm 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(TDM_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().contains("tdmctl-sak-")) {
- tempdisplaystr = tempdisplaystr.replace("tdmctl-sak-", "");
- tempdisplayint = tempdisplaystr.toInt(&isint);
- if (isint) {
- if (tempdisplayint < newdisplayint) {
- newdisplayint = tempdisplayint;
- display_has_sak = true;
- }
- }
- }
- else if (fi->fileName().contains("tdmctl-")) {
- tempdisplaystr = tempdisplaystr.replace("tdmctl-", "");
- tempdisplayint = tempdisplaystr.toInt(&isint);
- if (isint) {
- if (tempdisplayint < newdisplayint) {
- newdisplayint = tempdisplayint;
- display_has_sak = false;
- }
- }
- }
- ++it;
- }
- if (display_has_sak) {
- if (writefile(TQString(TDM_CONTROL_FIFO_SAK_FILE).arg(newdisplayint), "CLOSE\n") < 0) {
- // Uh oh, something failed...
- printf("Unable to write to TDM control socket %s\n", (TQString(TDM_CONTROL_FIFO_SAK_FILE).arg(newdisplayint)).ascii()); fflush(stdout);
- unlink((TQString(TDM_CONTROL_FIFO_SAK_FILE).arg(newdisplayint)).ascii());
- writeerror = true;
- }
- else {
- struct stat buffer;
- int status = -1;
- int timeout_counter = 0;
- while ((status != 0) && (timeout_counter < 30)) {
- status = stat((TQString(TDM_CONTROL_FIFO_FILE).arg(newdisplayint)).ascii(), &buffer);
- timeout_counter++;
- usleep(100000);
- }
- }
- }
- else {
- // Make sure the control socket is writable
- if (writefile(TQString(TDM_CONTROL_FIFO_FILE).arg(newdisplayint), "PING\n") < 0) {
- // Uh oh, something failed...
- printf("Unable to write to TDM control socket %s\n", (TQString(TDM_CONTROL_FIFO_FILE).arg(newdisplayint)).ascii()); fflush(stdout);
- unlink((TQString(TDM_CONTROL_FIFO_FILE).arg(newdisplayint)).ascii());
- writeerror = true;
- }
- }
- if (newdisplayint == (MAXIMUM_VTS+1)) {
- writeerror = true;
- systemexec(TRINITY_BIN_PREFIX "tdmctl -g reserve");
- usleep(3000000);
- }
- if (writeerror)
- have_valid_display = false;
- else
- have_valid_display = true;
- }
- else
- {
- // TDM is probably not running yet, as its control directory does not exist
- // Wait for 10 seconds and try again
- usleep(10000000);
- }
- }
-
- newdisplay = TQString(":%1").arg(newdisplayint);
- printf("[DEBUG 400.f] Logging in on display %s\n", newdisplay.ascii()); fflush(stdout);
-
- // Construct login string
- TQString logincommand = TQString("LOGIN\t%1\t%2\n").arg(smartcard_username).arg(smartcard_password);
- if (writefile(TQString(TDM_CONTROL_FIFO_FILE).arg(newdisplayint), logincommand) < 0) {
- // Uh oh, something failed...
- printf("Unable to write to TDM control socket %s\n", (TQString(TDM_CONTROL_FIFO_FILE).arg(newdisplayint)).ascii()); fflush(stdout);
- }
-
- systemexec((TQString(TRINITY_BIN_PREFIX "tdmctl -g activate %1").arg(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\" &").arg(smartcard_username).arg(udisplay)).ascii());
- }
- }
-
- unlink((TQString("%1/password").arg(secure_directory)).ascii());
-
- // if (loginok == 1) {
- // Wait for SmartCard removal
- systemexec("echo \"C\" > /tmp/tdesocket-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\"").arg(smartcard_username).arg(udisplay)).ascii());
- systemexec((TQString("su %1 -c \"export DISPLAY=%2; " TRINITY_BIN_PREFIX "dcop kdesktop KScreensaverIface enable false\"").arg(smartcard_username).arg(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").arg(smartcard_minutes)).ascii());
- chmod("/etc/smartmon/minutesremaining", 755);
-
- timer=60;
-
- systemexec((TQString("echo %1 > %2/minutes").arg(smartcard_minutes).arg(secure_directory)).ascii());
- update_file("10 05", TQString("%1/minutes").arg(secure_directory));
-
- if (smartcard_minutes == 0) {
- printf("[DEBUG 401.0] Minutes have been used up!\n"); fflush(stdout);
- // Prohibit logon
- smartcard_username="";
- unlink((TQString("%1/password").arg(secure_directory)).ascii());
- }
-
- mkdir("/etc/smartmon", 644);
- systemexec((TQString("echo %1 > /etc/smartmon/minutesremaining").arg(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\" &").arg(smartcard_username).arg(udisplay)).ascii());
- }
-
- if (smartcard_minutes == 0) {
- printf("[DEBUG 401.1] Minutes have been used up!\n"); fflush(stdout);
- printf("[DEBUG 401.2] Beginning logoff process\n"); fflush(stdout);
- output=254;
- }
- }
- }
- }
-
- printf("[DEBUG 401.3] Card removed\n"); fflush(stdout);
-
- // Is the user still logged in?
- result="ok";
- timeout=0;
- errcode=0;
- result = exec(TRINITY_BIN_PREFIX "tdmctl -g list");
- if (result == "ok") {
- noactivesessions=1;
- result="okbutempty";
- }
- printf("[DEBUG 401.4] %s\n", result.ascii()); fflush(stdout);
-
- // 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", index); fflush(stdout);
- udisplay = TQString(":%1").arg(index);
- foundsession=1;
- errcode=1;
- timeout=0;
- blankresult="";
- while (blankresult != "true") {
- systemexec((TQString(TRINITY_BIN_PREFIX "tdmctl -g activate %1").arg(udisplay)).ascii());
- systemexec((TQString("su %1 -c \"export DISPLAY=%2; " TRINITY_BIN_PREFIX "dcop kdesktop KScreensaverIface enable true\"").arg(smartcard_username).arg(udisplay)).ascii());
- systemexec((TQString("su %1 -c \"export DISPLAY=%2; " TRINITY_BIN_PREFIX "dcop kdesktop KScreensaverIface lock\"").arg(smartcard_username).arg(udisplay)).ascii());
- int retcode;
- blankresult = execret(TQString("su %1 -c \"export DISPLAY=%2; " TRINITY_BIN_PREFIX "dcop kdesktop KScreensaverIface isBlanked\"").arg(smartcard_username).arg(udisplay).ascii(), &retcode);
- if (retcode != 0) {
- blankresult="true";
- }
- blankresult = blankresult.replace('\n', "");
-
- logouttest = exec((TQString("echo %1 | grep 'target display has no VT assigned'").arg(blankresult)).ascii());
- if (logouttest != "") {
- printf("[DEBUG 401.6] User has logged out\n"); fflush(stdout);
- blankresult="true";
- }
- }
- }
- else {
- printf("[DEBUG 401.7] Username not specified!\n"); fflush(stdout);
- sleep(1);
- }
- }
- index++;
- }
- // }
- }
-
- if (command_mode == "cryptoflex") {
- pclose(opensc_explorer_file);
- }
-
- smartcard_username="";
- unlink("/etc/smartmon/minutesremaining");
- systemexec("echo \"C\" > /tmp/tdesocket-global/kdesktoplockcontrol &");
- }
- }
-}