diff --git a/filesystem/create_user.sh b/filesystem/create_user.sh new file mode 100644 index 0000000..373b22a --- /dev/null +++ b/filesystem/create_user.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +useradd -m kitten + +echo "Cmnd_Alias GROOMER_CMDS = /home/kitten/kitten_mount_src, \ + /home/kitten/kitten_mount_dst, /home/kitten/kitten_umount" >> /etc/sudoers +echo "kitten ALL=(ALL) NOPASSWD: GROOMER_CMDS" >> /etc/sudoers diff --git a/filesystem/opt/groomer/constraint.sh b/filesystem/opt/groomer/constraint.sh index 36983af..81ec11a 100644 --- a/filesystem/opt/groomer/constraint.sh +++ b/filesystem/opt/groomer/constraint.sh @@ -1,21 +1,18 @@ -DEV_SRC='/dev/sdf' -DEV_DST='/dev/sdg1' -HOME='/home/kitten' +DEV_SRC='/dev/sdb' +DEV_DST='/dev/sdc1' # User allowed to do the following commands without password USERNAME='kitten' +HOME="/home/${USERNAME}" # commands SUDO='/usr/bin/sudo' -ID='/usr/bin/id -u' - -# root commands -MOUNT='/bin/mount' -UMOUNT='/bin/umount' +ID=`/usr/bin/id -u` SYNC='/bin/sync' -SHUTDOWN='/sbin/shutdown' - -# To put in /etc/sudoers -# Cmnd alias specification -#Cmnd_Alias GROOMER_CMDS = /bin/mount, /bin/umount, /bin/sync -#kitten ALL=(ALL) NOPASSWD: GROOMER_CMDS +# root commands. +# To avoid the risk that an attacker use -o remount on mount and other nasty +# commands, we use our own scripts to invoke mount and umount. +# NOTE: sync is safe, isn't it? Please prove me wrong. +MOUNT_DST="${HOME}/kitten_mount_dst" +MOUNT_SRC="${HOME}/kitten_mount_src" +UMOUNT="${HOME}/kitten_umount" diff --git a/filesystem/opt/groomer/g_function.sh b/filesystem/opt/groomer/g_function.sh index 73d18ed..142350c 100755 --- a/filesystem/opt/groomer/g_function.sh +++ b/filesystem/opt/groomer/g_function.sh @@ -3,15 +3,6 @@ set -e set -x -# groom da kitteh! - -SRC='/dev/sdb' -PARTITIONS=`ls '${SRC}' | grep '${SRC}[1-9][0-6]*'` -DST='/dev/sdc1' - -GH=/opt/groomer/ -JAVA=/usr/bin/java - pdfCopyDirty() { # copy all pdf's over to their relative same locations @@ -85,82 +76,3 @@ unpackZip() fi } -SRC=/src -DST=/dst -if [ ! -d $SRC ]; then - mkdir $SRC -fi -if [ ! -d $DST ]; then - mkdir $DST -fi - -TEMP=/dst/temp -ZIPTEMP=/dst/ziptemp -FL=${DST}/filelist.txt - -umount $DST 2> /dev/null -mount /dev/sdb1 $DST -if [ $? -ne 0 ]; then -# echo Could not mount target USB stick! - exit 1 -else - echo Target USB device mounted at $DST - rm -rf $DST/FROM_PARTITION_* - - # mount temp and make sure it's empty - mkdir -p $TEMP - mkdir -p $ZIPTEMP - - rm -rf ${TEMP}/* - rm -rf ${ZIPTEMP}/* - - echo Full file list from source USB > $FL -fi - -COPYDIRTYPDF=0 -PARTCOUNT=1 -PARTITIONS=`ls /dev/sda* | grep '/dev/sda[1-9][0-6]*'` -for partition in $PARTITIONS -do - echo Processing partition: ${PARTCOUNT} $partition - umount $SRC 2> /dev/null - mount -r $partition $SRC - if [ $? -ne 0 ]; then - echo could not mount $partition at /$SRC - else - echo $partition mounted at $SRC - - echo PARTITION $PARTCOUNT >> $FL - find $SRC/* -printf 'echo %p | sed s:$SRC:: >> $FL \n' | while read l; do eval $l; done - - # create a director on sdb named PARTION_n - targetDir=${DST}/FROM_PARTITION_${PARTCOUNT} - echo copying to: $targetDir - mkdir -p $targetDir - - if [ $COPYDIRTYPDF -eq 1 ]; then - pdfCopyDirty $SRC $targetDir - else - pdfCopyClean $SRC $targetDir - fi - - # copy stuff - copySafeFiles $SRC $targetDir - convertCopyFiles $SRC $targetDir $TEMP - rm -rf ${TEMP}/* - - # unpack and process archives - unpackZip $SRC $targetDir $TEMP - fi - let PARTCOUNT=$PARTCOUNT+1 -done - -#cleanup -rm -rf ${TEMP}* -rm -rf ${ZIPTEMP}* -sync -umount $SRC -umount $DST - -/sbin/shutdown -h now - diff --git a/filesystem/opt/groomer/groomer.sh b/filesystem/opt/groomer/groomer.sh index 7931207..d4d9d8f 100755 --- a/filesystem/opt/groomer/groomer.sh +++ b/filesystem/opt/groomer/groomer.sh @@ -4,28 +4,33 @@ set -e set -x source ./constraint.sh +if ! [ "${ID}" -ge "1000" ]; then + echo "This script cannot run as root." + exit +fi -SRC=${HOME}/src -DST=${HOME}/dst -TEMP=${DST}/temp -ZIPTEMP=${DST}/ziptemp -LOGS=${DST}/logs +SRC="${HOME}/src" +DST="${HOME}/dst" + +TEMP="${DST}/temp" +ZIPTEMP="${DST}/ziptemp" +LOGS="${DST}/logs" clean(){ echo Cleaning. - ${SUDO} ${SYNC} + ${SYNC} # Cleanup source - ${SUDO} ${UMOUNT} $SRC || true - rm -rf $SRC + ${SUDO} ${UMOUNT} ${SRC} || true + rm -rf ${SRC} # Cleanup destination rm -rf ${TEMP} rm -rf ${ZIPTEMP} - ${SUDO} ${UMOUNT} $DST || true - rm -rf $DST + ${SUDO} ${UMOUNT} ${DST} || true + rm -rf ${DST} exit } @@ -34,51 +39,51 @@ trap clean EXIT TERM INT # De we have a source device if [ ! -b ${DEV_SRC} ]; then - echo 'Source device ('${DEV_SRC}') does not exists.' + echo "Source device (${DEV_SRC}) does not exists." exit fi # Find the partition names on the source device -DEV_PARTITIONS=`ls ${DEV_SRC}* | grep ${DEV_SRC}'[1-9][0-6]*' || true` +DEV_PARTITIONS=`ls "${DEV_SRC}"* | grep "${DEV_SRC}[1-9][0-6]*" || true` if [ -z ${DEV_PARTITIONS} ]; then - echo ${DEV_SRC} 'does not have any partitions.' + echo "${DEV_SRC} does not have any partitions." exit fi # Do we have a destination device if [ ! -b ${DEV_DST} ]; then - echo 'Destination device ('${DEV_DST}') does not exists.' + echo "Destination device (${DEV_DST}) does not exists." exit fi # Prepare mount points -if [ ! -d $SRC ]; then - mkdir $SRC +if [ ! -d ${SRC} ]; then + mkdir ${SRC} fi -if [ ! -d $DST ]; then - mkdir $DST +if [ ! -d ${DST} ]; then + mkdir ${DST} fi # mount and prepare destination device -if ${MOUNT}|grep $DST; then - ${SUDO} ${UMOUNT} $DST || true +if ${MOUNT}|grep ${DST}; then + ${SUDO} ${UMOUNT} ${DST} || true fi # uid= only works on a vfat FS. What should wedo if we get an ext* FS ? -${SUDO} ${MOUNT} -t vfat -o user,noexec,nosuid,nodev,rw,uid=`${ID}` ${DEV_DST} ${DST} -if [ $? -ne 0 ]; then - echo Unable to ${MOUNT} ${DEV_DST} on ${DST} +${SUDO} ${MOUNT_DST} ${ID} ${DEV_DST} ${DST} +if [ ${?} -ne 0 ]; then + echo "Unable to mount ${DEV_DST} on ${DST}" exit else - echo 'Target USB device ('${DEV_DST}') mounted at '${DST} - rm -rf ${DST}/FROM_PARTITION_* + echo "Target USB device (${DEV_DST}) mounted at ${DST}" + rm -rf "${DST}/FROM_PARTITION_"* - # mount temp and make sure it's empty - mkdir -p ${TEMP} - mkdir -p ${ZIPTEMP} - mkdir -p ${LOGS} + # prepare temp dirs and make sure it's empty + mkdir -p "${TEMP}" + mkdir -p "${ZIPTEMP}" + mkdir -p "${LOGS}" - rm -rf ${TEMP}/* - rm -rf ${ZIPTEMP}/* - rm -rf ${LOGS}/* + rm -rf "${TEMP}/"* + rm -rf "${ZIPTEMP}/"* + rm -rf "${LOGS}/"* fi # Groom da kitteh! @@ -88,41 +93,41 @@ PARTCOUNT=1 for partition in ${DEV_PARTITIONS} do # Processing a partition - echo Processing partition: ${partition} - if ${MOUNT}|grep $SRC; then - ${SUDO} ${UMOUNT} $SRC + echo "Processing partition: ${partition}" + if ${MOUNT}|grep ${SRC}; then + ${SUDO} ${UMOUNT} ${SRC} fi - ${SUDO} ${MOUNT} -o noexec,nosuid,nodev -r $partition $SRC - if [ $? -ne 0 ]; then - echo Unable to ${MOUNT} ${partition} on $SRC + ${SUDO} ${MOUNT_SRC} ${partition} ${SRC} + if [ ${?} -ne 0 ]; then + echo "Unable to mount ${partition} on ${SRC}" else - echo $partition mounted at $SRC + echo "${partition} mounted at ${SRC}" # Print the filenames on the current partition in a logfile - find ${SRC} -fls ${LOGS}/${PARTCOUNT} + find "${SRC}" -fls "${LOGS}/${PARTCOUNT}" - # create a directory on $DST named PARTION_$PARTCOUNT - target_dir=${DST}/FROM_PARTITION_${PARTCOUNT} - echo copying to: $target_dir - mkdir -p $target_dir + # create a directory on ${DST} named PARTION_$PARTCOUNT + target_dir="${DST}/FROM_PARTITION_${PARTCOUNT}" + echo "copying to: ${target_dir}" + mkdir -p "${target_dir}" #if [ $COPYDIRTYPDF -eq 1 ]; then - # pdfCopyDirty $SRC $targetDir + # pdfCopyDirty ${SRC} $targetDir #else - # pdfCopyClean $SRC $targetDir + # pdfCopyClean ${SRC} $targetDir #fi # copy stuff - #copySafeFiles $SRC $targetDir - #convertCopyFiles $SRC $targetDir $TEMP + #copySafeFiles ${SRC} $targetDir + #convertCopyFiles ${SRC} $targetDir $TEMP #rm -rf ${TEMP}/* # unpack and process archives - #unpackZip $SRC $targetDir $TEMP + #unpackZip ${SRC} $targetDir $TEMP fi - let PARTCOUNT=$PARTCOUNT+1 + let PARTCOUNT=${PARTCOUNT}+1 done -# The cleanup is automatically done in the finction clean called when +# The cleanup is automatically done in the function clean called when # the program quits diff --git a/filesystem/opt/groomer/init.sh b/filesystem/opt/groomer/init.sh index 08d7b94..66ee243 100755 --- a/filesystem/opt/groomer/init.sh +++ b/filesystem/opt/groomer/init.sh @@ -3,11 +3,26 @@ set -e set -x -USERNAME='kitten' +source ./constraint.sh + +if [ ${ID} -ne 0 ]; then + echo "This script has to be run as root." + exit +fi + +clean(){ + echo Done, cleaning. + # Only if running on a rPi + # mount -o remount,rw / + ${SYNC} + # shutdown -h now +} + +trap clean EXIT TERM INT + +# Remount the root filesystem in RO mode +# mount -o remount,ro / su ${USERNAME} -c ./groomer.sh -echo 'Done.' -# Only if running on a rPi -# shutdown -h now diff --git a/filesystem/opt/groomer/kitten_mount_dst b/filesystem/opt/groomer/kitten_mount_dst new file mode 100755 index 0000000..1500cad --- /dev/null +++ b/filesystem/opt/groomer/kitten_mount_dst @@ -0,0 +1,20 @@ +#!/bin/bash + +set -e +set -x + +if [ $# -eq 3 ]; then + if ! [ "${1}" -ge "1000" ] ; then + # avoid the risk of passing other options to mount, and enforce uid >= 1000 + echo "$1 is not a valid uid (>= 1000)" + exit 1 + fi + # uid= only works on a vfat FS. What should we do if we get an ext* FS ? + # the main problem is that we need the rw rights on the dest key. + # It is not possible to ensure it on a non-vfat USB key. + mount -t vfat -o user,noexec,nosuid,nodev,rw,uid="${1}" "${2}" "${3}" + exit 0 +else + echo 'Invalid number of arguments.' + exit 1 +fi diff --git a/filesystem/opt/groomer/kitten_mount_src b/filesystem/opt/groomer/kitten_mount_src new file mode 100755 index 0000000..fee2561 --- /dev/null +++ b/filesystem/opt/groomer/kitten_mount_src @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e +set -x + +if [ $# -eq 2 ]; then + mount -o noexec,nosuid,nodev,ro "${1}" "${2}" + exit 0 +else + echo 'Invalid number of arguments.' + exit 1 +fi diff --git a/filesystem/opt/groomer/kitten_umount b/filesystem/opt/groomer/kitten_umount new file mode 100755 index 0000000..faef70b --- /dev/null +++ b/filesystem/opt/groomer/kitten_umount @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e +set -x + +if [ $# -eq 1 ]; then + umount $1 + exit 0 +else + echo "Invalid number of arguments." + exit 1 +fi