diff --git a/README b/README new file mode 100644 index 0000000..02f6835 --- /dev/null +++ b/README @@ -0,0 +1,15 @@ +Yubikey login: +^^^^^^^^^^^^^^ + +-please create /etc/udev/rules.d/92-yubikey.rules with the following content: + ACTION=="add", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0010", RUN+="/etc/door/door.sh" + + + +SSH login: +^^^^^^^^^^ + +-in ~/.ssh/authorized_keys add to the first line: + no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty + +-in /etc/passwd change the the default shell to door_ssh_login.sh diff --git a/door.sh b/door.sh index 9661a2a..b24fc29 100755 --- a/door.sh +++ b/door.sh @@ -1,28 +1,106 @@ -#! /bin/sh +#! /bin/bash -cd /etc/door/ export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin OPEN_INDICATOR=/tmp/door_status_open CLOSED_INDICATOR=/tmp/door_status_closed +GPIO_SWITCH=21 +WATCHDOG_PID=/tmp/door_watchdog_pid +DELAY=10 +DATE_STRING="$(date +%s)#$(date +"%F %X")" +TIMEOUT=30 +LOCKDIR="/var/lock" + +lock_file() { + OUTFILE=$1 + OUTFILE_LOCK="${LOCKDIR}/$(readlink -f $OUTFILE | sed -e "s/\//\!/g").lock" + TIMEOUT_LOCK=$TIMEOUT + while [ $(mkdir "$OUTFILE_LOCK" 2> /dev/null; echo $? ) -ne 0 -a $TIMEOUT_LOCK -gt 0 ]; do + TIMEOUT_LOCK=$(($TIMEOUT_LOCK-1)) + if [ -f "$OUTFILE_LOCK/lastaction" -a ! -d "$OUTFILE_LOCK/timeout" ] >> /dev/null 2>&1; then + FILEAGE=$(($(date +%s) - $(stat -c '%Y' "$OUTFILE_LOCK/lastaction" || echo $(date +%s) 2> /dev/null ))) + TIMEOUT_LOCK=$(($TIMEOUT-$FILEAGE)) + fi + if [ $TIMEOUT_LOCK -le 0 ]; then + if [ $(mkdir "$OUTFILE_LOCK/timeout" >> /dev/null 2>&1; echo $? ) -ne 0 ]; then + TIMEOUTAGE_LOCK=$(($(date +%s) - $(stat -c '%Y' "$OUTFILE_LOCK/timeout"))) + if [ $TIMEOUTAGE_LOCK -gt $TIMEOUT ]; then + if [ $(rm -rf "$OUTFILE_LOCK/timeout" >> /dev/null 2>&1; echo $? ) -ne 0 ]; then + TIMEOUT_LOCK=$TIMEOUT + else + TIMEOUT_LOCK=1 + fi + else + TIMEOUT_LOCK=$(($TIMEOUT-$TIMEOUTAGE_LOCK)) + fi + fi + fi + sleep 1 + done + if [ $TIMEOUT_LOCK -le 0 ]; then + echo "Timeout! Ignoring old \"$OUTFILE_LOCK\"." >&2 + fi + touch "$OUTFILE_LOCK/lastaction" +} + +unlock_file() { + OUTFILE=${1} + OUTFILE_LOCK="${LOCKDIR}/$(readlink -f $OUTFILE | sed -e "s/\//\!/g").lock" + rm -rf "$OUTFILE_LOCK" +} + +cd $(dirname $0) || { + echo "konnte verzeichniss nicht wechseln" + exit 1 +} + +if ! kill -0 $(cat $WATCHDOG_PID 2> /dev/null) > /dev/null 2>&1; then +{ + ( while true; do + { + if [ $(cat /sys/class/gpio/gpio${GPIO_SWITCH}/value) -ne 1 -a -f $CLOSED_INDICATOR ]; then + { + lock_file $OPEN_INDICATOR + lock_file $CLOSED_INDICATOR + touch $OPEN_INDICATOR + rm -f $CLOSED_INDICATOR >> /dev/null 2>&1 + unlock_file $OPEN_INDICATOR + unlock_file $CLOSED_INDICATOR + } + fi + sleep .5 + } + done ) & + echo $! > $WATCHDOG_PID + cat $WATCHDOG_PID +} +fi + +lock_file $OPEN_INDICATOR +lock_file $CLOSED_INDICATOR if [ -f $OPEN_INDICATOR ]; then LOCK_AGE=$(( $(date +%s)-$(stat -c %X $OPEN_INDICATOR) )) elif [ -f $CLOSED_INDICATOR ]; then LOCK_AGE=$(( $(date +%s)-$(stat -c %X $CLOSED_INDICATOR) )) else - LOCK_AGE=15 + LOCK_AGE=$DELAY fi -if [ $LOCK_AGE -lt 15 ]; then - echo "please wait at least 15 seconds befor a second run of this script" >&2 +if [ $LOCK_AGE -lt $DELAY ]; then + echo "please wait at least $DELAY seconds before a second run of this script" >&2 + unlock_file $OPEN_INDICATOR + unlock_file $CLOSED_INDICATOR exit 1 fi -./door_verify.sh -STATUS=$? +if [ "$1" == "noverify" ]; then + STATUS=0 +else + ./door_verify.sh + STATUS=$? +fi if [ $STATUS -eq 0 ]; then - echo "opening door" if [ -f $OPEN_INDICATOR ]; then echo "closing door" ./door_lock.sh close @@ -34,8 +112,17 @@ if [ $STATUS -eq 0 ]; then rm $CLOSED_INDICATOR touch $OPEN_INDICATOR fi + unlock_file $OPEN_INDICATOR + unlock_file $CLOSED_INDICATOR exit 0 else echo "the lock won't move" >&2 + if [ -f $OPEN_INDICATOR ]; then + touch $OPEN_INDICATOR + else + touch $CLOSED_INDICATOR + fi + unlock_file $OPEN_INDICATOR + unlock_file $CLOSED_INDICATOR exit 1 fi diff --git a/door_lock.sh b/door_lock.sh index 4884e5b..48d02d3 100755 --- a/door_lock.sh +++ b/door_lock.sh @@ -3,13 +3,18 @@ GPIO_OPEN=23 GPIO_CLOSE=24 GPIO_CLIP=22 -SLEEP=2 +GPIO_SWITCH=21 +SLEEP=4 +CLOSE_TIMEOUT=15 for i in $GPIO_OPEN $GPIO_CLOSE $GPIO_CLIP; do echo "$i" > /sys/class/gpio/export echo "out" > /sys/class/gpio/gpio${i}/direction done +echo "$GPIO_SWITCH" > /sys/class/gpio/export +echo "in" > /sys/class/gpio/gpio${GPIO_SWITCH}/direction + case $1 in open) echo "1" > /sys/class/gpio/gpio${GPIO_OPEN}/value @@ -17,9 +22,22 @@ case $1 in echo "0" > /sys/class/gpio/gpio${GPIO_OPEN}/value ;; close) - echo "1" > /sys/class/gpio/gpio${GPIO_CLOSE}/value - sleep $SLEEP - echo "0" > /sys/class/gpio/gpio${GPIO_CLOSE}/value + TIMER=$(($CLOSE_TIMEOUT*10)) + while [ $TIMER -ge 0 ]; do + { + SWITCH=$(cat /sys/class/gpio/gpio${GPIO_SWITCH}/value) + if [ $SWITCH -eq 1 ]; then + { + echo "1" > /sys/class/gpio/gpio${GPIO_CLOSE}/value + sleep $SLEEP + echo "0" > /sys/class/gpio/gpio${GPIO_CLOSE}/value + break + } + fi + sleep .1 + TIMER=$(($TIMER-1)) + } + done ;; clip) echo "1" > /sys/class/gpio/gpio${GPIO_CLIP}/value diff --git a/door_ssh_login.sh b/door_ssh_login.sh new file mode 100755 index 0000000..5761eed --- /dev/null +++ b/door_ssh_login.sh @@ -0,0 +1,10 @@ +#! /bin/bash -- + +ping -c1 -t3 $(echo $SSH_CONNECTION | cut -d" " -f 1) >> /dev/null 2>&1 +STATUS=$? +if [ $STATUS -ne 0 ]; then + echo "come closer... ;-)" + exit 1 +fi + +sudo $(dirname $0)/door.sh noverify diff --git a/door_verify.sh b/door_verify.sh index 2832cc2..c270aea 100755 --- a/door_verify.sh +++ b/door_verify.sh @@ -20,9 +20,7 @@ aes_decrypt() { echo "$1" | xxd -ps -r | openssl enc -aes256 -d -k "$2" >> /dev/null 2>&1 DECRYPT_OK=$? DECRYPTED_TEXT="$(echo "$1" | xxd -ps -r | openssl enc -aes256 -d -k "$2" 2>&1)" -if [ $DECRYPT_OK -ne 0 ]; then - DECRYPTED_TEXT="DEADBEEF" -fi +[ $DECRYPT_OK -ne 0 ] && DECRYPTED_TEXT="DEADBEEF" echo $DECRYPTED_TEXT } @@ -35,7 +33,7 @@ if [ ! -f $KEYFILE ]; then exit 1 fi -if [ ! -f $LOGFILE ]; then +if [ ! -f "$LOGFILE" ]; then echo "generating new logfile" >&2 echo "# DATE:ID:SIGNED_DATE:STATUS" > $LOGFILE chmod 600 $LOGFILE diff --git a/etc_udev_rules.d_92-yubikey.rules b/etc_udev_rules.d_92-yubikey.rules deleted file mode 100644 index 812f95a..0000000 --- a/etc_udev_rules.d_92-yubikey.rules +++ /dev/null @@ -1 +0,0 @@ -ACTION=="add", ATTRS{idVendor}=="1050", ATTRS{idProduct}=="0010", RUN+="/etc/door/door.sh"