Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

erf-dm prelim

1 view
Skip to first unread message

Douglas Mayne

unread,
May 18, 2007, 11:30:09 AM5/18/07
to
See this page for more details:
http://www.xmission.com/~ddmayne2/erf-dm/


#!/bin/bash
#
# Program Name: /linuxrc
# Version: 0.0.1.4-prelim
#
# special debug (why aren't devices created)
#
# First Version: 2006-09-07
# Last Change : 2007-03-06
#
# Purpose: linuxrc which is called at the first process by the Linux kernel.
# This version enables using an encrypted root file system, swap, etc.
#
# Copyright (C) 2006 Douglas D. Mayne
#
# This program is licensed under the General Public License. See this file
# for terms and conditions: http://www.gnu.org/licenses/gpl.txt
#
# Begin Source Code and Comments --
#
#
# Global Vars
#
REF_DIR=/erf-dm
PATH=/sbin:/bin:/usr/bin:/usr/sbin:$PATH
export PATH
START_DATE=$(date)
KV=$(uname -r)
# XDEBUG ne 0, debug development of this script
XDEBUG=0
#
# This file is required. It will be created if not existing
#
USER_INP_PARAM=/user.inp
[ ! -e $USER_INP_PARAM ] && touch $USER_INP_PARAM
if [ ! -e $USER_INP_PARAM ];then
clear
echo "Check some problem with initial environment."
echo "Probably press CTL-ATL-DEL to avoid kernel panic."
read
exit 1
fi
#
# Accept initial input vars from file
#
. $USER_INP_PARAM
FLAG_USING_GPG=${FLAG_USING_GPG:=0}
chown root:root -R . 2>/dev/null
chmod go-rwx -R . 2>/dev/null
#
# Tested with total system memory of 128M minimum, leaving approx
# this amount free
#
MIN_INIT_MEM_FREE=73500000

#Script to use: Load kernel modules
LKM=${REF_DIR}/misc/man_modprobe.scr
KM=/modules.init

# cryptsetup
CS=/usr/sbin/cryptsetup

# ETE: encryption table at entry
# This file contains input parameters for encryption as detailed below
ETE=/etab

# ET
# After removing comments and blank lines, the result will be called ET

# Fields within ET
# 0. device name, relative to /dev
# 1. device mapper name, relative to /dev/mapper
# 2. cipher type
# 3. type (root, swap, other)
# 4. mount point, relative to /tmpfs, if applicable (may be a temp mount point.)
# 5. filesystem, if applicable (not applicable for swap)


# SMET is a file which has the successfully encrypted mounted entries
SMET=/tmp/smtab

# LOGF is a file which logs script progress
LOGF=/tmp/startup.log
DMESG=/tmp/dmesg
#
#PASS is a file which holds a good passphrase. This will enable one pass phrase to be used to
#encrypt all partition types.
#
PASS=/tmp/phrase
#
# SLEEP_USB is the number of seconds to wait after loading the modules for USB
# to stabilize. If not using USB as root, swap, or other, value can be zero.
#
SLEEP_USB=0


EF=0
for TRY1 in 0 1;do
[ $TRY1 -ne 0 ] && continue
#
# Includes
#
for i in tmpfile yesno dm_setup enable_swapp enable_otherp enable_rootp shred_file;do
j=${REF_DIR}/misc/${i}.bash
if [ ! -e "$j" ];then
echo "Error: $j is a required file and is not found."
echo "- exiting."
EF=1
else
. $j
fi
done
[ $EF -ne 0 ] && continue
#
# Allocate some temp files for working environment
#
# T0: temp log
# T1: first parse of ETE
# T2: scratch

T0=$(tmpfile)
T1=$(tmpfile)
T2=$(tmpfile)
T3=$(tmpfile)
T4=$(tmpfile)
T5=$(tmpfile)
T6=$(tmpfile)
if [ ! -e $T0 ];then
echo "Error: Temp files cannot be allocated."
echo "- exiting."
continue
fi

LOG=$T0
[ $XDEBUG -ne 0 ] && echo "Status: using temp log file: $LOG"

# T10: list, specified swaps
# T11: list, specified root
# T12: list, specified others
# T13: list, partitions declared as using encryption
# T14: list, partitions declared as not using encryption
T10=$(tmpfile)
T11=$(tmpfile)
T12=$(tmpfile)
T13=$(tmpfile)
T14=$(tmpfile)

break
done
[ $XDEBUG -ne 0 ] && /bin/bash
if [ $TRY1 -ne 0 ];then
echo "Startup failed due to problem with environment."
[ $XDEBUG -ne 0 ] && /bin/bash
echo "Probably press CTL-ALT-DEL to avoid kernel panic."
read
exit 1
fi
#
# Main try loop, break is good- continue is error
#
for RV in 0 1;do
[ $RV -ne 0 ] && continue
echo "${START_DATE}: Welcome to erf-dm, linuxrc by Douglas Mayne" >$LOG
echo "Status: This is version: $(cat ${REF_DIR}/VERSION)" >>$LOG
echo "Status: Using kernel $KV" >>$LOG
#
# Begin by mounting proc
#
mount -n proc /proc -t proc
echo 0x0100 >/proc/sys/kernel/real-root-dev
CMD_LINE=$(cat /proc/cmdline)
#
# Check memory and get value of available swap...
# swap may be used to increase tmpfs max allocation in future versions of this script
#
cat /proc/meminfo >$T6
MEM_TOTAL=$(expr $(cat $T6 | grep "MemTotal:" | sed -e 's/^.*: *//' -e 's/ kB$//') "*" 1024)
INIT_MEM_FREE=$(expr $(cat $T6 | grep "MemFree:" | sed -e 's/^.*: *//' -e 's/ kB$//') "*" 1024)
SWAP_TOTAL=$(expr $(cat $T6 | grep "SwapTotal:" | sed -e 's/^.*: *//' -e 's/ kB$//') "*" 1024)
rm $T6
if [ $INIT_MEM_FREE -lt $MIN_INIT_MEM_FREE ];then
clear
head -3 <$LOG
echo "Warning: Your system reports current free memory: " $INIT_MEM_FREE
echo "- that amount is below the minimum tested."
yesno "Proceed anyway, yes or (no) ? " no
if [ $? -eq 0 ];then
echo "Status: User elects to abort startup (low memory)."
continue
else
echo "Status: User elects to continue startup (low memory)." | tee -a $T6
fi
fi
printf "Status: Initial free memory: %d kB\n" $(expr $INIT_MEM_FREE "/" 1024) | tee -a $T6
#
# Setup environment for mounts on /tmpfs
# Use tmpfs because it is very flexible. We won't have to worry about cleaning up initrd, etc.
# Note: tmpfs will use a maximum of half of RAM by default
#
[ ! -d /tmpfs ] && mkdir /tmpfs
mount -t tmpfs tmpfs /tmpfs
#
# Prelim. assumptions
#
EF=0
if [ $FLAG_USING_GPG -eq 0 ];then
[ ! -e $ETE ] && EF=1
else
[ -e $ETE ] && shred -n1 -u $ETE
[ -e $ETE ] && EF=1
fi
[ $EF -ne 0 ] && echo "Error: Check some problem with $ETE." >>$LOG
for i in $T0 $T1 $T2 $T3 $T4 $T5 $T6 \
$T10 $T11 $T12 $T13 $T14 \
$LKM $KM /sbin/dmsetup $CS \
${REF_DIR}/VERSION ${REF_DIR}/misc/MESSAGE.1 \
${REF_DIR}/misc/def_gpg_param.scr \
${REF_DIR}/misc/get_gpg_message.scr ;do
if [ ! -e "$i" ];then
echo "Error: Required file: $i is not found." >>$LOG
EF=1;
fi
done
#
# Check if kernel modules exist.
# Throw out if no kernel modules. User may edit out if not true.
#
if [ ! -d /lib/modules/${KV} ]; then
echo "Error: No kernel modules found for Linux $KV." >>$LOG
# Comment out next line if modules don't matter with your kernel
[ ${FLAG_USING_KM:=1} -ne 0 ] && EF=1
fi
#
# Load kernel modules
#
if [ -x $LKM ]; then
echo "Status: Loading kernel modules as specified in file, $KM" | tee -a $LOG
$LKM $KM
[ $SLEEP_USB -ne 0 ] && sleep $SLEEP_USB
fi
#
# Destroy existing dev/mapper devices to avoid conflict
#
rm -fr /dev/mapper
#
#
# Make sure dm-crypt is loaded
#
[ ! -e /dev/mapper/control ] && dmsetup ls >/dev/null
if [ -e /dev/mapper/control ];then
echo "Status: /device/mapper/control exists." >>$LOG
else
echo "Error: /device/mapper/control could not be initialized." | tee -a $LOG
EF=1
fi
if [ $EF -ne 0 ];then
cat $LOG
continue
fi
#
# First Message
#
[ $XDEBUG -ne 0 ] && /bin/bash
clear
cat $T6 >>$LOG
cat $LOG

cat ${REF_DIR}/misc/MESSAGE.1
read -n1 -s
#
# Optional: drive params as an encrypted message.
#
EF=0
if [ $FLAG_USING_GPG -ne 0 ];then
${REF_DIR}/misc/def_gpg_param.scr $USER_INP_PARAM $T6
while true;do
rm $T6;touch $T6
clear
[ -e $ETE ] && shred -n1 -u $ETE
${REF_DIR}/misc/get_gpg_message.scr $USER_INP_PARAM
EF=$?
if [ $EF -eq 0 ];then
cat $T6 >>$LOG
break;
elif [ $EF -eq 1 ];then
printf "Warning: Insufficient/incorrect user input.\n"
yesno "Try again, yes or (no) ?" "n"
[ $? -eq 1 ] && continue
break
else
printf "Error: get_gpg_message.scr returns $EF\n" | tee -a $LOG
break
fi
done
fi
[ $EF -ne 0 ] && continue
#
# Prelim. scan of ET
#
ET=$T1
cat $ETE | grep -v "^$" | grep -v "^#" | sort | uniq >$ET
LC=$(wc -l <$ET)
if [ $LC -eq 0 ];then
echo "Error: Configuration file, $ETE, does not contain required lines." >$T2
echo "- root is required at a minimum." >>$T2
cat $T2 | tee -a $LOG
continue
fi
EF=0
for i in $(seq 1 $LC);do
[ $i -eq 1 ] && echo "Status: Scanning specified mount table: $ETE." >>$LOG
EP=$(cat $ET | head -$i | tail -1);
read -a EPi <<HERE
$EP
HERE
if [ ! -e /dev/${EPi[0]} ];then
echo "Error: A specified device does not exist: /dev/${EPi[0]}." | tee -a $LOG
echo /dev/${EPi[3]} | grep "^root$"
if [ $? -eq 0 ];then
echo "- the root device must exist. Quitting." | tee -a $LOG
EF=1
break
else
echo "- attempting to proceed without /dev/${EPi[0]}" | tee -a $LOG
continue
fi
fi
echo ${EPi[2]} | grep -i "^none$" >/dev/null
if [ $? -eq 0 ];then
echo $EP >>$T14
else
echo $EP >>$T13
fi
echo ${EPi[3]} | grep "^swap$" >/dev/null
if [ $? -eq 0 ];then
echo $EP >>$T10
continue
fi
echo ${EPi[3]} | grep "^root$" >/dev/null
if [ $? -eq 0 ];then
echo $EP >>$T11
continue
fi
# other (not root, not swap)
echo $EP >>$T12
done
[ $EF -ne 0 ] && continue
#
# Better format for output if passed through expr (below)
#
ROOT_C=$( expr $(wc -l <$T11) + 0)
SWAP_C=$( expr $(wc -l <$T10) + 0)
OTHER_C=$(expr $(wc -l <$T12) + 0)
ENC_C=$( expr $(wc -l <$T13) + 0)
NONENC_C=$( expr $(wc -l <$T14) + 0)
if [ $ROOT_C -ne 1 ];then
echo "Error: Configuration file, $ETE, is not consistent." >$T2
[ $ROOT_C -eq 0 ] && echo "- root is a required entry." >>$T2
[ $ROOT_C -gt 1 ] && echo "- root may only appear once." >>$T2
cat $T2 | tee -a $LOG
continue
fi
echo -n "Status: $ETE partition type summary (root,swap,other): " >$T2
echo "(${ROOT_C},${SWAP_C},${OTHER_C})" >>$T2
echo -n "- encryption summary (encrypted,non-encrypted): " >>$T2
echo "(${ENC_C},${NONENC_C})" >>$T2
cat $T2 >>$LOG
#
# Give priority to mounting a swap partition first, if possible
#
cat $T13 | grep "swap" >$T6
cat $T13 | grep -v "swap" >>$T6
cat $T6 >$T13
#
# Allow multiple tries to get passphrase
#
GOOD_PWD=0
if [ $FLAG_USING_GPG -eq 0 ];then
PA=3
FLAG_PW_PROMPT=1
else
PA=1
FLAG_PW_PROMPT=0
fi
for j in $(seq 1 $PA);do
if [ $ENC_C -eq 0 ];then
echo "Warning: No partitions are using encryption." >$T2
echo "- Proceeding anyway." >>$T2
cat $T2 | tee -a $LOG
GOOD_PWD=1
touch $PASS; touch $SMET
break
fi
[ $j -eq 1 ] && echo "Status: Entering passphrase entry loop $PA tries maximum." >>$LOG
[ $j -ne 1 ] && clear
if [ $FLAG_PW_PROMPT -ne 0 ];then
echo "Ready to accept password (try $j of $PA)..."
(IFS=$'\n'; read -p "Passphrase: " -s;echo $REPLY >$PASS)
fi
for k in $(seq 1 $ENC_C);do
EP=$(head -$k <$T13 | tail -1 | tee $T5)
read -a EPi <<HERE
$EP
HERE
case ${EPi[3]} in
root) enable_rootp $PASS $T5 $T6 $T2 ;;
swap) enable_swapp $PASS $T5 $T6 $T2 ;;
*) enable_otherp $PASS $T5 $T6 $T2 ;;
esac
if [ $? -eq 0 ];then
GOOD_PWD=1
cat $T5 >>$SMET
echo "Status: User entered a good password on try $j." | tee -a $LOG
cat $T6 | tee -a $LOG
break
fi
done
#
# Was a good passphrase entered?
#
[ $GOOD_PWD -eq 1 ] && break
done
if [ $GOOD_PWD -eq 0 ];then
echo "Error: Failed password. Exiting." | tee -a $LOG
continue
fi
#
# With good passphrase, enable remaining swaps (as specified)
#
for i in $(seq 1 $SWAP_C);do
[ $i -eq 1 ] && echo "Status: Enabling remaining swap partitions." >>$LOG
EP=$(head -$i <$T10 | tail -1 | tee $T5)
cat $SMET | grep "^${EP}$" >/dev//null && continue
enable_swapp $PASS $T5 $T6 $T2
if [ $? -lt 2 ]; then
cat $T5 >>$SMET
cat $T6 >>$LOG
else
cat $T6 >>$LOG
fi
done
#
# With good passphrase, mount specified root
#
[ $XDEBUG -ne 0 ] && /bin/bash
for i in $(seq 1 $ROOT_C);do
[ $i -eq 1 ] && echo "Status: Attempting mount for new root." >>$LOG
EP=$(head -$i <$T11 | tail -1 | tee $T5)
read -a EPi <<HERE
$EP
HERE
#
# Is root using encryption
#
echo ${EPi[2]} | grep "^none$" >/dev/null
if [ $? -eq 0 ];then
FLAG_ROOT_USING_ENC=0
ROOTFS=${EPi[5]}
ROOTDEV=/dev/${EPi[1]}
ROOTFMP=/tmpfs/${EPi[4]}
else
FLAG_ROOT_USING_ENC=1
ROOTFS=${EPi[5]}
ROOTDEV=/dev/mapper/${EPi[1]}
ROOTFMP=/tmpfs/${EPi[4]}
fi
cat $SMET | grep "^${EP}$" >/dev//null && continue
enable_rootp $PASS $T5 $T6 $T2
if [ $? -lt 2 ]; then
cat $T5 >>$SMET
cat $T6 | tee -a $LOG
else
cat $T6 | tee -a $LOG
fi
done
[ $XDEBUG -ne 0 ] && /bin/bash
#
# Has root been mounted
#
cat $SMET | grep "^$(cat $T11)$" >/dev/null
[ $? -ne 0 ] && continue
#
# With good passphrase, mount specified others
#
for i in $(seq 1 $OTHER_C);do
[ $i -eq 1 ] && echo "Status: Attempting mount for specified others." >>$LOG
EP=$(head -$i <$T12 | tail -1 | tee $T5)
cat $SMET | grep "^${EP}$" >/dev//null && continue
enable_otherp $PASS $T5 $T6 $T2
if [ $? -lt 2 ]; then
cat $T5 >>$SMET
cat $T6 >>$LOG
else
cat $T6 >>$LOG
fi
done
[ $XDEBUG -ne 0 ] && /bin/bash
#
# umount other partitions.
# Let real /etc/fstab mount "other",
# /dev/mapper devices are left in place and should be ready to use at real root.
#
cat $SMET $T12 | sort | uniq -d >$T3
for i in $(seq 1 $(wc -l <$T3));do
[ $i -eq 1 ] && echo "Status: Attempting umount for specified others." >>$LOG
EP=$(head -$i <$T3 | tail -1)
read -a EPi <<HERE
$EP
HERE
umount /tmpfs/${EPi[4]}
if [ $? -eq 0 ];then
echo "Status: ${EPi[0]} umount successful." >>$LOG
else
echo "Error: unsuccessful umount ${EPi[0]}" >$T2
echo "- Proceeding anyway." >>$T2
cat $T2 | tee -a $LOG
fi
done
#
# shred passphrase, shred successful mounts, etc.
#
# Notes: 1. Don't need to shred ET (simple alias to T1)
#
printf "%s\t%s\n" \
$PASS $T2 \
$SMET $T2 \
$ETE $T2 \
$T1 $T2 \
$T3 $T2 \
$T5 $T2 \
$T6 $T2 \
$T10 $T2 \
$T11 $T2 \
$T12 $T2 \
$T13 $T2 \
$T14 $T2 \
$T2 $T12 >$T4
cat /dev/urandom | dd bs=4096 count=1 >$T2
for i in $(seq 1 $(wc -l <$T4));do
[ $i -eq 1 ] && echo "Status: Shredding working files." >>$LOG
j=$(head -$i <$T4 | tail -1)
k=$(echo $j | cut -f1 -d\ )
shred_file $j 4096
if [ $? -eq 0 ];then
echo "- Shredded $k" >>$LOG
else
echo "Error: Check some error shredding $k" | tee -a $LOG
fi
done
[ $XDEBUG -ne 0 ] && /bin/bash
for i in $(seq 1 $(wc -l <$T4));do
j=$(head -$i <$T4 | tail -1)
k=$(echo $j | cut -f1 -d\ )
rm $k
done
j=/message.zip.asc
[ -e $j ] && rm $j
echo "Status: Starting final fixups and cleanup before transferring to /sbin/init" | tee -a $LOG
#
# Some fixups at destination
#
[ ! -d ${ROOTFMP}/initrd ] && mkdir ${ROOTFMP}/initrd
#
# Could consider changing chmod command below for more restrictions
# -modified initrd 2006-09-11 to "lock" tools after boot
# -tools on initrd avail to root user only
# -the kernel modules will remain r-x for everyone, though.
#
chmod 755 ${ROOTFMP}/initrd
#
# Use kernel modules on initrd as definitive
#
KMD=lib/modules/${KV}
if [ -d ${ROOTFMP}/${KMD} ]; then
mv ${ROOTFMP}/${KMD} ${ROOTFMP}/${KMD}.save
elif [ -L /${ROOTFMP}/${KMD} ]; then
rm ${ROOTFMP}/${KMD}
fi
ln -s /initrd/${KMD} ${ROOTFMP}/${KMD}
#
# First, remove existing /dev/mapper devices on target
#
rm -fr ${ROOTFMP}/dev/mapper
#
# Then, populate some devices as created in initrd at real root
#
# (cd /dev && tar -cpf - mapper) | \
# (cd ${ROOTFMP}/dev && tar -xvf -) >/dev/null

#
# make sure chroot is consistent on initrd and new root.
#
CR=usr/bin/chroot
if [ -e ${ROOTFMP}/${CR} ];then
#
# favor user's chroot if it exists
# -will also avoid clobbering existing chroot on other system
cp ${ROOTFMP}/${CR} /${CR}
chmod 755 ${ROOTFMP}/${CR}
else
#
# else copy version from initrd to target,
# these appear to be the usual permissions for a slackware system
chmod 755 /${CR}
cp /${CR} ${ROOTFMP}/${CR}
fi
#
# From here on cannot exit loop, one last chance below
#
printf "Status: Looks good for startup...\n"
if [ ${FLAG_DISPLAY_ABORT_OPTION:=0} -ne 0 ];then
yesno "Review linuxrc's log now, yes or (no) ? " no
if [ $? -ne 0 ] ;then
echo "Press enter to start, q to quit..."
cat $LOG | less
fi
yesno "Abort startup, yes or (no) ? " no
if [ $? -ne 0 ];then
echo "Status: User selects to abort startup." | tee -a $LOG
continue
fi
fi

#
# Make temp log the final log.
# Available at /initrd/tmp/startup.log when boot completes.
#
mv $LOG $LOGF
dmesg >$DMESG
#
# Looks good for startup...
#
umount /proc
cd $ROOTFMP
echo "Status: Ready to chroot and call real init."
[ $XDEBUG -ne 0 ] && /bin/bash
cat - <<- HERE >$T2
mount -t proc proc /proc
(cd /initrd && chmod go-rwx -R .)
(cd /initrd && chmod ugo+rx -R lib)
([ -e /dev/mapper ] && cd /dev/mapper && rm -fr *)
/sbin/dmsetup mknodes
if [ ${FLAG_FREE_INITRD:=0} -eq 1 ];then
(cd /lib/modules && [ -e ${KV} ] && rm -fr ${KV})
(cd /initrd/lib/modules && tar -cpf - ${KV}) |\
(cd /lib/modules && tar -xvf -)
umount /initrd
rm -fr /initrd
blockdev --flushbufs /dev/ram0
fi
umount /proc
mount -o remount -o ro -t $ROOTFS $ROOTDEV /
# exec /sbin/init ${CMD_LINE} 1
exec /sbin/init ${CMD_LINE}
HERE
cd $ROOTFMP
pivot_root . initrd
exec /${CR} . /bin/bash </initrd/${T2} >/dev/console 2>&1
# mount -o remount -o ro -t $ROOTFS $ROOTDEV $ROOTFMP
break
done
#
# Never get here on good startup
#
if [ $RV -ne 0 ];then
echo "Startup failed..."
mv $LOG $LOGF
[ $XDEBUG -ne 0 ] && /bin/bash
echo "Probably press CTL-ALT-DEL to avoid kernel panic."
read
fi
exit $RV

Douglas Mayne

unread,
May 18, 2007, 11:36:58 AM5/18/07
to
On Fri, 18 May 2007 09:30:09 -0600, Douglas Mayne wrote:

> See this page for more details:
> http://www.xmission.com/~ddmayne2/erf-dm/

<snip>
>

#!/bin/bash
#
# Copyright (C) 2007 Douglas D. Mayne
#
# This program is licensed under the General Public License. See this file for
# terms and conditions: /erf-dm/COPYING
#
# Begin Source Code --
#
# Default variables
#
# Arguments:
#
# 1. file with user defined vars, will be updated to include all necessary
# variables
# 2. file for status log (optional)
#
D0=$(dirname $0)
. ${D0}/tmpfile.bash
T1=$(tmpfile);T2=$(tmpfile)


for RV in 0 1;do
[ $RV -ne 0 ] && continue

if [ $# -eq 1 ] || [ $# -eq 2 ];then
:
else
continue
fi
[ ! -w $1 ] && continue
cat $1 >$T1
. $T1
STATUS_LOG=${STATUS_LOG:=$T2}
if [ $# -eq 2 ];then
[ ! -r $2 ] && continue
STATUS_LOG=$2
fi


if [ $FLAG_USING_GPG -ne 0 ];then

UNLOCK_METHOD=gpg_message
ENC_MESSAGE=${ENC_MESSAGE:=/message.zip.asc}
ENC_MESSAGE_SIG=${ENC_MESSAGE_SIG:=/message.zip.asc.sig}
DEC_MESSAGE=${DEC_MESSAGE:=/message.zip}
TWD=${TWD:=/tmp/uz}
else
UNLOCK_METHOD=password
ENC_MESSAGE=NA
ENC_MESSAGE_SIG=NA
DEC_MESSAGE=NA
TWD=NA
fi
USERNAME=${USERNAME:=root}
PASS_ATT=${PASS_ATT:=3}
PHRASE_DEST=${PHRASE_DEST:=/tmp/phrase}
ETAB_DEST=${ETAB_DEST:=/etab}
printf "%s=%s\n" \
FLAG_USING_GPG $FLAG_USING_GPG \
UNLOCK_METHOD $UNLOCK_METHOD \
USERNAME $USERNAME \
PASS_ATT $PASS_ATT \
PHRASE_DEST $PHRASE_DEST \
ETAB_DEST $ETAB_DEST \
ENC_MESSAGE $ENC_MESSAGE \
ENC_MESSAGE_SIG $ENC_MESSAGE_SIG \
DEC_MESSAGE $DEC_MESSAGE \
TWD $TWD \
STATUS_LOG $STATUS_LOG >$1
[ $STATUS_LOG != $T2 ] && rm $T2
break
done
rm $T1
[ $RV -ne 0 ] && rm $T2
exit $RV

Douglas Mayne

unread,
May 18, 2007, 11:42:30 AM5/18/07
to
On Fri, 18 May 2007 09:30:09 -0600, Douglas Mayne wrote:

> See this page for more details:
> http://www.xmission.com/~ddmayne2/erf-dm/

<snip>


> # This program is licensed under the General Public License. See this file
> # for terms and conditions: http://www.gnu.org/licenses/gpl.txt

<snip>
>
#!/bin/bash
#
# Program Name: user_inp.scr
# Version: 0.0.1 for linuxrc for erf-dm
#
# Based on user_inp.scr, version: 0.0.2 for linuxrc for 10.2-live
#
# Copyright (C) 2005, 2006, 2007 Douglas D. Mayne
#


# This program is licensed under the General Public License. See this file for

# terms and conditions: /10.2-live/COPYING
#
# Begin Source Code --
#
entry() {
#
# 4 args: prompt string, variable name, current value, output file
#
[ $# -ne 4 ] && return 1
local def=$3
printf "%s (%s) " "$1" "$3"
read
CL=$(printf "%s=%s\n" "$2" "${REPLY:=${def}}")
echo $CL >>$4
# echo $CL | tee -a $4
}
#
#
# usage: user_inp.scr <param file>
#
# Arguments:
# 1. File with various parameters
#
#
# Return value:
# 0: good (passed all loops)
# 1: failed on loop1 (can try again)
# 2: failed on loop2 (don't try again)
# 3: failed on loop3 (don't try again)
# 4: problem with initial assumptions
#
D1=$(dirname $0)
. ${D1}/yesno.bash
. ${D1}/tmpfile.bash
T1=$(tmpfile);T2=$(tmpfile);T3=$(tmpfile);T4=$(tmpfile)

for TRY0 in 0 1;do
[ $TRY0 -ne 0 ] && continue
RV=4
[ $# -ne 1 ] && continue
[ ! -e "$1" ] && [ ! -f "$1" ] && continue


[ ! -w "$1" ] && continue

[ ! -e $T1 ] && continue
[ ! -e $T2 ] && continue
[ ! -e $T3 ] && continue
[ ! -e $T4 ] && continue
#
# T1, T2 used for variable evaluation
#
cat $1 >$T1
#
# Accept initial values for vars
#
. $T1
printf "Status: Initialized variables from file, %s\n" "$1" | tee -a $STATUS_LOG
#
# The following tests are for method using gpg encrypted message
# - quit if using a simple password
#


if [ $FLAG_USING_GPG -eq 0 ];then

printf "Status: Not using gpg unlock method.\n" | tee -a $STATUS_LOG
printf "- Skipping direct user input.\n" | tee -a $STATUS_LOG
RV=0
break
fi
RV=1


for TRY1 in 0 1;do
[ $TRY1 -ne 0 ] && continue

printf "Status: Begin input and verification loop.\n" | tee -a $STATUS_LOG
#
# Preliminary input and checks (make sure message is present, etc.)
#
EF=1;
while true;do
eval $(cat $T2 | grep "^USERNAME=")
entry "Username (for gpg key) :" USERNAME $USERNAME $T2
eval $(cat $T2 | grep "^USERNAME=")
GPG_DIR=/home/${USERNAME}/.gnupg
if [ -d $GPG_DIR ] && [ -r $GPG_DIR ];then
EF=0
break;
else
printf "Error: The directory $GPG does not exist.\n"
yesno "Try again with a different user name, (yes) or no ? " "y"


[ $? -eq 1 ] && continue
break

fi
done


if [ $EF -eq 0 ];then

printf "Status: Proceeding with gpg home directory, %s\n" $GPG_DIR >>$STATUS_LOG
else
printf "Warning: Username %s is not found.\n" $USERNAME >>$STATUS_LOG
continue
fi
EF=1;
while true;do
if [ -r $ENC_MESSAGE ];then
EF=0
break
else
printf "Warning: The specified encrypted message does not exist.\n"
yesno "Specify another message, (yes) or no ? " "y"
[ $? -eq 0 ] && break
entry "Encrypted message :" ENC_MESSAGE $ENC_MESSAGE $T2
eval $(cat $T2 | grep "^ENC_MESSAGE=")
continue
fi
done


if [ $EF -eq 0 ];then

printf "Status: Found encrypted message, %s\n" $ENC_MESSAGE >>$STATUS_LOG
else
printf "Warning: Encrypted message %s is not found.\n" $ENC_MESSAGE >>$STATUS_LOG
continue
fi
EF=1;
while true;do
if [ -r $ENC_MESSAGE_SIG ];then
EF=0
break
else
ENC_MESSAGE_SIG=${ENC_MESSAGE}.sig
[ -r $ENC_MESSAGE_SIG ] && continue
# eval $(cat $T2 | grep "^ENC_MESSAGE_SIG=")
printf "Warning: The specified encrypted message does not have a sig file.\n"
yesno "Specify another sig file, (yes) or no ? " "y"
[ $? -eq 0 ] && break
entry "Signature for encrypted message :" ENC_MESSAGE_SIG $ENC_MESSAGE_SIG $T2
eval $(cat $T2 | grep "^ENC_MESSAGE_SIG=")
continue
fi
done


if [ $EF -eq 0 ];then

printf "Status: Found encrypted message signature, %s\n" $ENC_MESSAGE_SIG >>$STATUS_LOG
else
printf "Warning: Signature for encrypted message %s is not found.\n" $ENC_MESSAGE_SIG >>$STATUS_LOG
continue
fi
#
# Check signature
#
EF=1
cat $ENC_MESSAGE | gpg --homedir=$GPG_DIR --no-tty --verify $ENC_MESSAGE_SIG -


EF=$?
if [ $EF -eq 0 ];then

printf "Status: Verified encrypted message is valid.\n" | tee -a $STATUS_LOG
else
printf "Error: Signature for encrypted message is not valid.\n" | tee -a $STATUS_LOG
continue
fi
break;
done


[ $TRY1 -ne 0 ] && continue
#

# Get Passphrase Loop (in try2 loop)
#
RV=2
for TRY2 in 0 1;do
[ $TRY2 -ne 0 ] && continue
# printf "Status: Begin Passphrase loop.\n" | tee -a $STATUS_LOG
[ -e $DEC_MESSAGE ] && shred -n1 -u $DEC_MESSAGE
FLAG_GOOD_PWD=0
for PA in $(seq 1 $PASS_ATT);do
[ $PA -eq 1 ] && echo "Status: Entering passphrase entry loop. $PASS_ATT tries maximum." | tee -a $STATUS_LOG
[ $PA -ne 1 ] && clear
echo "Ready to accept passphrase (try $PA of $PASS_ATT)..."
(IFS=$'\n'; read -p "Passphrase: " -s;echo $REPLY >$T4)
gpg --homedir=$GPG_DIR --no-tty --passphrase-file $T4 -o $DEC_MESSAGE $ENC_MESSAGE
if [ ! -e $DEC_MESSAGE ];then
# echo "Error: Bad passphrase."
:
else
FLAG_GOOD_PWD=1
fi
shred -n1 $T4
[ $FLAG_GOOD_PWD -eq 1 ] && break
done
if [ $FLAG_GOOD_PWD -eq 1 ];then
printf "Status: User entered a good passphrase on try $PA of $PASS_ATT.\n" | tee -a $STATUS_LOG
else
printf "Error: User did not enter a valid passphrase after $PASS_ATT attempts.\n" | tee -a $STATUS_LOG
continue
fi
break
done
[ $TRY2 -ne 0 ] && continue
#
# Unzip Message, etc (in try3 loop)
#
RV=3
ECWD=$(pwd)
for TRY3 in 0 1;do
cd $ECWD

#
# Use directory TWD, with care to shred its contents
#
if [ -e $TWD ];then
(IFS=$'\n'; cd $TWD && for i in $(find . -type f);do
shred -n1 -u $i
done)
rm -fr $TWD
fi
[ $TRY3 -ne 0 ] && continue
printf "Status: Begin using encrypted message.\n" | tee -a $STATUS_LOG
[ -e $PHRASE_DEST ] && shred -n1 -u $PHRASE_DEST
[ -e $ETAB_DEST ] && shred -n1 -u $ETAB_DEST
#
# message is assumed to be a zip file with the etab and passphrase for the disk
#
[ -e $TWD ] && continue
mkdir $TWD
[ ! -e $TWD ] && continue
F0=$(cd $(dirname $DEC_MESSAGE) && pwd)
F1=$(basename $DEC_MESSAGE);

cd $TWD || continue
unzip ${F0}/${F1} || continue
[ ! -e ./etab ] && continue
[ ! -e ./phrase ] && continue
mv ./etab $ETAB_DEST || continue
mv ./phrase $PHRASE_DEST || continue
break
done
cd $ECWD
if [ -e $TWD ];then
(IFS=$'\n'; cd $TWD && for i in $(find . -type f);do
shred -n1 -u $i
done)
rm -fr $TWD
fi
shred -n1 -u $DEC_MESSAGE
[ $TRY3 -ne 0 ] && continue
RV=0
break
done
rm $T1 $T2 $T3 $T4
exit $RV

0 new messages