diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:47:14 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:47:14 +0000 |
commit | 3eaf4237194e25804f221af93c269d3d97e2809d (patch) | |
tree | cdedf3fc954b0727b0b34aa9b0b211cc18f854eb /etc | |
download | smartcardauth-3eaf4237194e25804f221af93c269d3d97e2809d.tar.gz smartcardauth-3eaf4237194e25804f221af93c269d3d97e2809d.zip |
Added my SmartCard login/session lock/unlock utility
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/smartcardauth@1097604 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'etc')
-rwxr-xr-x | etc/init/smartauthlogin.conf | 14 | ||||
-rw-r--r-- | etc/smartauth/smartauth.sh.in | 177 | ||||
-rw-r--r-- | etc/smartauth/smartauthmon.sh.in | 608 |
3 files changed, 799 insertions, 0 deletions
diff --git a/etc/init/smartauthlogin.conf b/etc/init/smartauthlogin.conf new file mode 100755 index 0000000..89852d5 --- /dev/null +++ b/etc/init/smartauthlogin.conf @@ -0,0 +1,14 @@ +# smartauthlogin - smart card login manager +# + +description "smart card login monitor" + +start on (filesystem + and started kdm-kde3) +stop on stopping kdm-kde3 + +script + if [ -e /usr/bin/smartauthmon.sh ]; then + /usr/bin/smartauthmon.sh + fi +end script diff --git a/etc/smartauth/smartauth.sh.in b/etc/smartauth/smartauth.sh.in new file mode 100644 index 0000000..92a9c56 --- /dev/null +++ b/etc/smartauth/smartauth.sh.in @@ -0,0 +1,177 @@ +#!/bin/bash + +# Smart Card Authentication Helper (c) 2009 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 3 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/>. + +get_file () { + if [[ $COMMAND_MODE == "acos" ]]; then + # Select EF $1 under DF 1000 + echo "$SELECT_FILE $1" > query + scriptor_standalone query 1> response2 + echo $(cat response2) + + # Read binary + echo "$READ_BINARY" > query + scriptor_standalone query 1> response2 + authokresponse="90 00 : Normal processing" + response1=$(cat response2 | grep "$authokresponse") + if [[ $response1 != "" ]]; then + cat response2 | tr -d '\n' > response4 + stringtoreplace="Using T=0 protocol00 B0 00 00 FF> 00 B0 00 00 FF< " + newstring="" + sed -i "s#${stringtoreplace}#${newstring}#g" response4 + stringtoreplace=" 90 00 : Normal processing." + newstring="" + sed -i "s#${stringtoreplace}#${newstring}#g" response4 + if [[ $2 == "text" ]]; then + stringtoreplace=" 00" + newstring="" + sed -i "s#${stringtoreplace}#${newstring}#g" response4 + fi + echo $(cat response4) + rm -f lukskey + xxd -r -p response4 lukskey + RESPONSE=lukskey + fi + fi + + if [[ $COMMAND_MODE == "cryptoflex" ]]; then + echo "get $1" | opensc-explorer + RESPONSE="3F00_$1" + fi +} + +# Initialize pcscd +killall pcscd & +sleep 1 +pcscd & +sleep 1 + +# Get card ATR +echo "RESET" > query +scriptor_standalone query 1> response2 +authokresponse="OK: " +response1=$(cat response2 | grep "$authokresponse") +if [[ $response1 != "" ]]; then + cat response2 | tr -d '\n' > response4 + stringtoreplace="Using T=0 protocolRESET> RESET< OK: " + newstring="" + sed -i "s#${stringtoreplace}#${newstring}#g" response4 + smartatr=$(cat response4) + echo "Got ATR: $smartatr" + if [[ $smartatr == "3B BE 18 00 00 41 05 10 00 00 00 00 00 00 00 00 00 90 00 " ]]; then + echo "Detected ACOS5 card" + COMMAND_MODE="acos" + fi + if [[ $smartatr == "3B 02 14 50 " ]]; then + echo "Detected Schlumberger CryptoFlex card" + COMMAND_MODE="cryptoflex" + fi +else + echo "No card detected!" + exit 1 +fi + +if [[ $COMMAND_MODE == "cryptoflex" ]]; then + 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" +fi + +if [[ $COMMAND_MODE == "acos" ]]; then + GET_CHALLENGE="00 84 00 00 08" + EXTERNAL_AUTH="00 82 00 83 08" # Key 3 + 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" +fi + +# Authenticate card +if [[ $COMMAND_MODE == "acos" ]]; then + # Select MF + echo "00 A4 00 00 00" > query + scriptor_standalone query 1> response2 + echo $(cat response2) + + # Select DF 1000 under MF + echo "$SELECT_FILE 10 00" > query + scriptor_standalone query 1> response2 + echo $(cat response2) +fi + +echo $GET_CHALLENGE > authscript + +scriptor_standalone authscript | grep 'Normal processing' > challenge +perl -pi -e 's/ //g' challenge +perl -pi -e 's/:Normalprocessing.//g' challenge +perl -pi -e 's/<//g' challenge +xxd -r -p challenge challenge + +# Now DES encrypt the challenge +# Later, change the initialization vector to random if possible +openssl des-ecb -in challenge -out response -K <your key in hexidecimal> -iv 1 + +if [[ $COMMAND_MODE == "acos" ]]; then + # Truncate to 8 bytes + dd if=response of=response2 bs=1 count=8 + + # Expand to standard hex listing format + xxd -g 1 response2 response + dd if=response of=response2 bs=1 count=23 skip=9 +fi + +if [[ $COMMAND_MODE == "cryptoflex" ]]; then + # Truncate to 6 bytes + dd if=response of=response2 bs=1 count=6 + + # Expand to standard hex listing format + xxd -g 1 response2 response + dd if=response of=response2 bs=1 count=17 skip=9 +fi + +# Assemble the response file +response2=$(cat response2) +response1="$EXTERNAL_AUTH ${response2}" +echo $response1 > response + +# Send the response! +scriptor_standalone response > response2 + +# Get the result +authokresponse="< 90 00 : Normal processing" +response1=$(cat response2 | grep "$authokresponse") +echo $response1 +if [[ $response1 != "" ]]; then + echo "Smart card validation successfull!" + # Get encryption key + if [[ $COMMAND_MODE == "acos" ]]; then + get_file "10 01" + fi + + if [[ $COMMAND_MODE == "cryptoflex" ]]; then + get_file "1001" + fi + mv $RESPONSE smart.key +else + echo "Authentication failed!" +fi + +rm authscript & +rm response & +rm response2 & +rm challenge & diff --git a/etc/smartauth/smartauthmon.sh.in b/etc/smartauth/smartauthmon.sh.in new file mode 100644 index 0000000..219e89e --- /dev/null +++ b/etc/smartauth/smartauthmon.sh.in @@ -0,0 +1,608 @@ +#!/bin/bash + +# Smart Card KDE3.5 Authentication Script (c) 2009 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 3 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/>. + +# Maximum number of virtual terminals on this system +MAXIMUM_VTS=49 + +# The [secure] temporary directory for authentication +SECURE_DIRECTORY=/tmp/smartauth + +hexcvt () +{ + echo ""$1" "16" o p" | dc +} + +# Create the secure directory and lock it down +rm -rf $SECURE_DIRECTORY +mkdir -p $SECURE_DIRECTORY +chown root $SECURE_DIRECTORY +chgrp root $SECURE_DIRECTORY +chmod 600 $SECURE_DIRECTORY +SECURE_DIRECTORY=$(mktemp /tmp/smartauth/smartauthmon.XXXXXXXXXX) +rm -rf $SECURE_DIRECTORY +mkdir -p $SECURE_DIRECTORY +chown root $SECURE_DIRECTORY +chgrp root $SECURE_DIRECTORY +chmod 600 $SECURE_DIRECTORY + +# Restart PCSCD and kill spurious processes +killall -9 pcscd +/etc/init.d/pcscd restart +/etc/init.d/pcscd-nodbus restart + +# See if required programs are installed +scriptor=$(whereis scriptor) +if [[ $scriptor == "scriptor:" ]]; then + echo "ERROR: scriptor is not installed! This program cannot continue!" + exit +fi +opensc=$(whereis opensc-explorer) +if [[ $opensc == "opensc-explorer:" ]]; then + echo "ERROR: opensc-explorer is not installed! This program cannot continue!" + exit +fi + +get_file () { + if [[ $COMMAND_MODE == "acos" ]]; then + # Select EF $1 under DF 1000 + echo "$SELECT_FILE $1" > $SECURE_DIRECTORY/query + scriptor $SECURE_DIRECTORY/query 1> $SECURE_DIRECTORY/response2 + echo $(cat $SECURE_DIRECTORY/response2) + + # Read binary + echo "$READ_BINARY" > $SECURE_DIRECTORY/query + scriptor $SECURE_DIRECTORY/query 1> $SECURE_DIRECTORY/response2 + authokresponse="90 00 : Normal processing" + response1=$(cat $SECURE_DIRECTORY/response2 | grep "$authokresponse") + if [[ $response1 != "" ]]; then + cat $SECURE_DIRECTORY/response2 | tr -d '\n' > $SECURE_DIRECTORY/response4 + stringtoreplace="Using T=0 protocol00 B0 00 00 FF> 00 B0 00 00 FF< " + newstring="" + sed -i "s#${stringtoreplace}#${newstring}#g" $SECURE_DIRECTORY/response4 + stringtoreplace=" 90 00 : Normal processing." + newstring="" + sed -i "s#${stringtoreplace}#${newstring}#g" $SECURE_DIRECTORY/response4 + if [[ $2 == "text" ]]; then + stringtoreplace=" 00" + newstring="" + sed -i "s#${stringtoreplace}#${newstring}#g" $SECURE_DIRECTORY/response4 + fi + echo $(cat $SECURE_DIRECTORY/response4) + rm -f $SECURE_DIRECTORY/lukskey + xxd -r -p $SECURE_DIRECTORY/response4 $SECURE_DIRECTORY/lukskey + RESPONSE=$SECURE_DIRECTORY/lukskey + fi + fi + + if [[ $COMMAND_MODE == "cryptoflex" ]]; then + FILE=${1/ /} + echo "get $FILE" | opensc-explorer + RESPONSE="3F00_$FILE" + fi +} + +update_file () { + if [[ $COMMAND_MODE == "acos" ]]; then + # Select EF $1 under DF 1000 + echo "$SELECT_FILE $1" > $SECURE_DIRECTORY/query + scriptor $SECURE_DIRECTORY/query 1> $SECURE_DIRECTORY/response2 + echo $(cat $SECURE_DIRECTORY/response2) + + # Update existing file + # Zero pad input file + dd if=/dev/zero of=$SECURE_DIRECTORY/response2 bs=1 count=255 + dd if=$2 of=$SECURE_DIRECTORY/response2 bs=1 count=255 conv=notrunc + + # Truncate to 255 bytes and expand to standard hex listing format + xxd -l 255 -ps -c 1 $SECURE_DIRECTORY/response2 > $SECURE_DIRECTORY/response + cat $SECURE_DIRECTORY/response | tr '\n' ' ' > $SECURE_DIRECTORY/hexready + echo "$UPDATE_BINARY $(cat $SECURE_DIRECTORY/hexready)" > $SECURE_DIRECTORY/query + scriptor $SECURE_DIRECTORY/query 1> $SECURE_DIRECTORY/response2 2>/dev/null + echo $(cat $SECURE_DIRECTORY/response2) + fi + + if [[ $COMMAND_MODE == "cryptoflex" ]]; then + # Delete old file + echo "$DELETE_FILE $1" > $SECURE_DIRECTORY/query + scriptor $SECURE_DIRECTORY/query 1> $SECURE_DIRECTORY/response2 2>/dev/null + echo $(cat $SECURE_DIRECTORY/response2) + + # Create new file + createfile "FF" $1 + FILE=${1/ /} + echo "put $FILE $2" | opensc-explorer + fi +} + +oldsmartcard_username="" +echo "Ready..." +while [[ 1 == 1 ]]; do + sleep 1 + echo "exit" | scriptor 2>/dev/null 1>/dev/null + OUTPUT=$? + if [[ $OUTPUT -eq 0 ]]; then + echo "Card inserted!" + + # Get card ATR + echo "RESET" > $SECURE_DIRECTORY/query + scriptor $SECURE_DIRECTORY/query 1> $SECURE_DIRECTORY/response2 + authokresponse="OK: " + response1=$(cat $SECURE_DIRECTORY/response2 | grep "$authokresponse") + if [[ $response1 != "" ]]; then + cat $SECURE_DIRECTORY/response2 | tr -d '\n' > $SECURE_DIRECTORY/response4 + stringtoreplace="Using T=0 protocolRESET> RESET< OK: " + newstring="" + sed -i "s#${stringtoreplace}#${newstring}#g" $SECURE_DIRECTORY/response4 + smartatr=$(cat $SECURE_DIRECTORY/response4) + echo "Got ATR: $smartatr" + if [[ $smartatr == "3B BE 18 00 00 41 05 10 00 00 00 00 00 00 00 00 00 90 00 " ]]; then + echo "Detected ACOS5 card" + COMMAND_MODE="acos" + fi + if [[ $smartatr == "3B 02 14 50 " ]]; then + echo "Detected Schlumberger CryptoFlex card" + COMMAND_MODE="cryptoflex" + fi + else + echo "No card detected!" + fi + + if [[ $COMMAND_MODE == "cryptoflex" ]]; then + 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" + fi + + if [[ $COMMAND_MODE == "acos" ]]; then + 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" + fi + + # Authenticate card + + if [[ $COMMAND_MODE == "acos" ]]; then + # Select MF + echo "00 A4 00 00 00" > $SECURE_DIRECTORY/query + scriptor $SECURE_DIRECTORY/query 1> $SECURE_DIRECTORY/response2 + echo $(cat $SECURE_DIRECTORY/response2) + + # Select DF 1000 under MF + echo "$SELECT_FILE 10 00" > $SECURE_DIRECTORY/query + scriptor $SECURE_DIRECTORY/query 1> $SECURE_DIRECTORY/response2 + echo $(cat $SECURE_DIRECTORY/response2) + fi + + echo $GET_CHALLENGE > $SECURE_DIRECTORY/authscript + + scriptor $SECURE_DIRECTORY/authscript | grep 'Normal processing' > $SECURE_DIRECTORY/challenge + perl -pi -e 's/ //g' $SECURE_DIRECTORY/challenge + perl -pi -e 's/:Normalprocessing.//g' $SECURE_DIRECTORY/challenge + perl -pi -e 's/<//g' $SECURE_DIRECTORY/challenge + xxd -r -p $SECURE_DIRECTORY/challenge $SECURE_DIRECTORY/challenge + + # Now DES encrypt the challenge + # Later, change the initialization vector to random if possible + openssl des-ecb -in $SECURE_DIRECTORY/challenge -out $SECURE_DIRECTORY/response -K <your key in hexadecimal> -iv 1 + + if [[ $COMMAND_MODE == "acos" ]]; then + # Truncate to 8 bytes + dd if=$SECURE_DIRECTORY/response of=$SECURE_DIRECTORY/response2 bs=1 count=8 + + # Expand to standard hex listing format + xxd -g 1 $SECURE_DIRECTORY/response2 $SECURE_DIRECTORY/response + dd if=$SECURE_DIRECTORY/response of=$SECURE_DIRECTORY/response2 bs=1 count=23 skip=9 + fi + + if [[ $COMMAND_MODE == "cryptoflex" ]]; then + # Truncate to 6 bytes + dd if=$SECURE_DIRECTORY/response of=$SECURE_DIRECTORY/response2 bs=1 count=6 + + # Expand to standard hex listing format + xxd -g 1 $SECURE_DIRECTORY/response2 $SECURE_DIRECTORY/response + dd if=$SECURE_DIRECTORY/response of=$SECURE_DIRECTORY/response2 bs=1 count=17 skip=9 + fi + + # Assemble the response file + response2=$(cat $SECURE_DIRECTORY/response2) + response1="$EXTERNAL_AUTH ${response2}" + echo $response1 > $SECURE_DIRECTORY/response + + # Send the response! + scriptor $SECURE_DIRECTORY/response > $SECURE_DIRECTORY/response2 + + # Get the result + authokresponse="< 90 00 : Normal processing" + response1=$(cat $SECURE_DIRECTORY/response2 | grep "$authokresponse") + echo $response1 + if [[ $response1 != "" ]]; then + echo "Smart card validation successfull!" + # Get username and password + get_file "10 02" "text" + smartcard_username=$(cat $RESPONSE) + get_file "10 03" "text" + mv $RESPONSE $SECURE_DIRECTORY/password + get_file "10 04" "text" + smartcard_slave=$(cat $RESPONSE) + if [[ $smartcard_slave == "SLAVE" ]]; then + get_file "10 05" "text" + smartcard_minutes=$(cat $RESPONSE) + get_file "10 06" "text" + internet_minutes=$(cat $RESPONSE) + fi + else + echo "This card does not recognize this system!" + sleep 1 + smartcard_username="" + rm -f $SECURE_DIRECTORY/password + smartcard_slave="" + fi + + if [[ $smartcard_slave == "SLAVE" ]]; then + if [[ $smartcard_minutes == "" ]]; then + smartcard_minutes=1 + fi + + # Decrement minutes on card + if [[ $smartcard_minutes -gt 0 ]]; then + let "smartcard_minutes=smartcard_minutes-1" + echo $smartcard_minutes > $SECURE_DIRECTORY/minutes + update_file "10 05" "$SECURE_DIRECTORY/minutes" + fi + + if [[ $smartcard_minutes -eq 0 ]]; then + echo "Minutes have been used up!" + # Prohibit logon + smartcard_username="" + rm $SECURE_DIRECTORY/password + fi + + mkdir -p /etc/smartmon + echo $smartcard_minutes > /etc/smartmon/minutesremaining + chmod 755 /etc/smartmon/minutesremaining + fi + + # Initialize variables + loginok=1 + + # Try to do the authentication + result="" + timeout=0 + errcode=0 + waserror=0 + noactivesessions=0 + + result_is_consistent=0 + while [[ $result_is_consistent == 0 ]]; do + result_one=$(/opt/kde3/bin/kdmctl -g list) + sleep 0.1 + result_two=$(/opt/kde3/bin/kdmctl -g list) + sleep 0.1 + result_three=$(/opt/kde3/bin/kdmctl -g list) + sleep 0.1 + result_four=$(/opt/kde3/bin/kdmctl -g list) + if [[ $result_one == $result_two ]]; then + if [[ $result_one == $result_three ]]; then + if [[ $result_one == $result_four ]]; then + result=$result_one + result_is_consistent=1 + fi + fi + fi + done + if [[ $result == "ok" ]]; then + noactivesessions=1 + result="okbutempty" + fi + echo $result + resultbkp=$result + + if [[ $errcode -eq 0 ]]; then + # Allow KDM to finish starting + if [[ $waserror -eq 1 ]]; then + sleep 10 + fi + + # Zero the desktop array + index=0 + while [[ $index != $MAXIMUM_VTS ]]; do + darray[index]="" + index=$((index+1)) + done + + if [[ result != "okbutempty" ]]; then + posone="0" + posone=$(expr index "$result" " :") + postwo="0" + postwo=$(expr index "$result" ",") + while [[ $posone != "0" ]]; do + length=$((postwo-posone-1)) + terminals="${result:posone:length}" + echo $terminals + + # Delete the terminal we just got from the list of terminals + result="${result:postwo}" + postwo=$(expr index "$result" ",") + result="${result:postwo}" + postwo=$(expr index "$result" ",") + length=$((postwo-1)) + username="${result:0:length}" + darray[terminals]=$username # Save username of this terminal + echo $username + result="${result:postwo}" + postwo=$(expr index "$result" ",") + result="${result:postwo}" + + # Now see if there might be ANOTHER terminal active or not + posone="0" + posone=$(expr index "$result" " :") + postwo="0" + postwo=$(expr index "$result" ",") + done + fi + + # See if the desired user is already logged in + index=0 + foundsession=0 + while [[ $index != $MAXIMUM_VTS ]]; do + if [[ ${darray[index]} == $smartcard_username ]]; then + if [[ ${darray[index]} != "" ]]; then + echo "Found existing session on desktop: ${index}" + foundsession=1 + # Check password + lverify=$(/usr/bin/smartauthckpasswd -u ${darray[index]} -p $(cat $SECURE_DIRECTORY/password)) + cverify="User:${darray[index]}" + udisplay=":${index}" + if [[ $lverify == $cverify ]]; then + su $smartcard_username -c "export DISPLAY=$udisplay; /opt/kde3/bin/dcop kdesktop KScreensaverIface quit" + /opt/kde3/bin/kdmctl activate $udisplay + fi + else + echo "Username not specified" + foundsession=2 + sleep 1 + fi + fi + index=$((index+1)) + done + + if [[ $foundsession == "0" ]]; then + echo "Existing session not found, starting new..." + + # Make sure that this is not display :0 (default login screen). + # If it is, execute login. If not, create new session, then execute login + usebasedisplay=0 + if [[ $noactivesessions -eq 1 ]]; then + newdisplay=$(ls /var/run/xdmctl/ | grep 'xdmctl-:0') + echo $newdisplay + if [[ $newdisplay != "" ]]; then + usebasedisplay=1 + fi + fi + vtsessions=$(echo "$resultbkp" | grep ',vt') + if [[ $vtsessions == "" ]]; then + newdisplay=$(ls /var/run/xdmctl/ | grep 'xdmctl-:0') + echo $newdisplay + if [[ $newdisplay != "" ]]; then + usebasedisplay=1 + fi + fi + + echo "Creating new session" + # Attempt login + ls /var/run/xdmctl > $SECURE_DIRECTORY/originalxdm + + # Set loop separator to end of line + BAKIFS=$IFS + IFS=$(echo -en "\n\b") + exec 3<&0 + exec 0<"$SECURE_DIRECTORY/originalxdm" + newdisplayfound=0 + newdisplay=-1 + while read -r line + do + # use $line variable to process lines + line=$(echo $line | grep 'xdmctl-:' | sed -e 's/xdmctl-://') + if [ "`expr $line - $line 2>/dev/null`" == "0" ]; then + echo "Found active display on $line" + if [[ $newdisplayfound -eq 0 ]]; then + tempnewdisplay=$((newdisplay + 1)) + if [[ $line -eq $tempnewdisplay ]]; then + echo "Sequential display $line found after display $newdisplay..." + newdisplay=$line + fi + fi + fi + done + exec 0<&3 + newdisplay=$(($newdisplay + 1)) + newdisplay=":$newdisplay" + echo "The next display to start will be $newdisplay" + rm $SECURE_DIRECTORY/originalxdm + + /opt/kde3/bin/kdmctl -g reserve + /opt/kde3/bin/kdmctl -g login $newdisplay now $smartcard_username $(cat $SECURE_DIRECTORY/password) + sleep 2 + /opt/kde3/bin/kdmctl -g activate $newdisplay + udisplay=$newdisplay + fi + + if [[ $smartcard_slave == "SLAVE" ]]; then + if [[ $smartcard_minutes -lt 5 ]]; then + su $smartcard_username -c "export DISPLAY=$udisplay; zenity --warning --text 'You have less than 5 minutes of computer time remaining' || exit 0" & + fi + fi + + rm -f $SECURE_DIRECTORY/password + + #if [[ loginok -eq 1 ]]; then + # Wait for SmartCard removal + TIMER=60 + OUTPUT=0 + + while [[ $OUTPUT -eq 0 ]]; do + sleep 1 + su $smartcard_username -c "export DISPLAY=$udisplay; /opt/kde3/bin/dcop kdesktop KScreensaverIface quit" + echo "exit" | scriptor 2>/dev/null 1>/dev/null + OUTPUT=$? + if [[ $smartcard_slave == "SLAVE" ]]; then + TIMER=$(( TIMER - 1 )) + if [[ $TIMER -eq 0 ]]; then + # 60 seconds have passed, decrement minutes on card + let "smartcard_minutes=smartcard_minutes-1" + echo $smartcard_minutes > /etc/smartmon/minutesremaining + chmod 755 /etc/smartmon/minutesremaining + + TIMER=60 + + echo $smartcard_minutes > $SECURE_DIRECTORY/minutes + update_file "10 05" "$SECURE_DIRECTORY/minutes" + + if [[ $smartcard_minutes -eq 0 ]]; then + echo "Minutes have been used up!" + # Prohibit logon + smartcard_username="" + rm $SECURE_DIRECTORY/password + fi + + mkdir -p /etc/smartmon + echo $smartcard_minutes > /etc/smartmon/minutesremaining + chmod 755 /etc/smartmon/minutesremaining + + if [[ $smartcard_minutes -eq 5 ]]; then + su $smartcard_username -c "export DISPLAY=$udisplay; zenity --warning --text 'You have less than 5 minutes of computer time remaining' || exit 0" & + fi + + if [[ $smartcard_minutes -eq 0 ]]; then + echo "Minutes have been used up!" + echo "Beginning logoff process" + OUTPUT=254 + fi + fi + fi + done + + echo "Card removed!" + + # Is the user still logged in? + result="ok" + timeout=0 + errcode=0 + result_is_consistent=0 + while [[ $result_is_consistent == 0 ]]; do + result_one=$(/opt/kde3/bin/kdmctl -g list) + sleep 0.1 + result_two=$(/opt/kde3/bin/kdmctl -g list) + sleep 0.1 + result_three=$(/opt/kde3/bin/kdmctl -g list) + sleep 0.1 + result_four=$(/opt/kde3/bin/kdmctl -g list) + if [[ $result_one == $result_two ]]; then + if [[ $result_one == $result_three ]]; then + if [[ $result_one == $result_four ]]; then + result=$result_one + result_is_consistent=1 + fi + fi + fi + done + if [[ $result == "ok" ]]; then + noactivesessions=1 + result="okbutempty" + fi + echo $result + + # Zero the desktop array + index=0 + while [[ $index != $MAXIMUM_VTS ]]; do + darray[index]="" + index=$((index+1)) + done + + posone="0" + posone=$(expr index "$result" " :") + postwo="0" + postwo=$(expr index "$result" ",") + while [[ $posone != "0" ]]; do + length=$((postwo-posone-1)) + terminals="${result:posone:length}" + echo $terminals + + # Delete the terminal we just got from the list of terminals + result="${result:postwo}" + postwo=$(expr index "$result" ",") + result="${result:postwo}" + postwo=$(expr index "$result" ",") + length=$((postwo-1)) + username="${result:0:length}" + darray[terminals]=$username # Save username of this terminal + echo $username + result="${result:postwo}" + postwo=$(expr index "$result" ",") + result="${result:postwo}" + + # Now see if there might be ANOTHER terminal active or not + posone="0" + posone=$(expr index "$result" " :") + postwo="0" + postwo=$(expr index "$result" ",") + done + + # See if the desired user is still logged in + index=0 + foundsession=0 + while [[ $index != $MAXIMUM_VTS ]]; do + if [[ ${darray[index]} == $smartcard_username ]]; then + if [[ ${darray[index]} != "" ]]; then + echo "Found existing session on desktop: ${index}" + udisplay=":${index}" + foundsession=1 + errcode=1 + timeout=0 + blankresult="" + while [[ $blankresult != "true" ]]; do + /opt/kde3/bin/kdmctl -g activate $udisplay + su $smartcard_username -c "export DISPLAY=$udisplay; /opt/kde3/bin/dcop kdesktop KScreensaverIface lock" + blankresult=$(su $smartcard_username -c "export DISPLAY=$udisplay; /opt/kde3/bin/dcop kdesktop KScreensaverIface isBlanked") + if [[ $? != 0 ]]; then + blankresult="true" + fi + logouttest=$(echo $blankresult | grep 'target display has no VT assigned') + if [[ "$logouttest" != "" ]]; then + echo "User has logged out" + blankresult="true" + fi + done + else + echo "Username not specified!" + sleep 1 + fi + fi + index=$((index+1)) + done + #fi + fi + + smartcard_username="" + rm -rf /etc/smartmon/minutesremaining + fi +done |