From 8fbc0076a4827ddc6af92e0b9daa4c4c31450808 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 19 Jul 2013 01:10:32 -0700 Subject: Fri Jul 19 01:09:18 PDT 2013 --- community/scponly/setup_chroot.sh | 275 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 275 insertions(+) create mode 100644 community/scponly/setup_chroot.sh (limited to 'community/scponly/setup_chroot.sh') diff --git a/community/scponly/setup_chroot.sh b/community/scponly/setup_chroot.sh new file mode 100644 index 000000000..1af9807e0 --- /dev/null +++ b/community/scponly/setup_chroot.sh @@ -0,0 +1,275 @@ +#!/bin/sh +# +# handy functions: +# +# a function to display a failure message and then exit +fail ( ) { + echo -e $@ + exit 1 +} + +# "get with default" function +# this function prompts the user with a query and default reply +# it returns the user reply +getwd ( ) { + query="$1" + default="$2" + echo -en "$query [$default]" | cat >&2 + read response + if [ x$response = "x" ]; then + response=$default + fi + echo $response +} + +# "get yes no" function +# this function prompts the user with a query and will continue to do so +# until they reply with either "y" or "n" +getyn ( ) { + query="$@" + echo -en $query | cat >&2 + read response + while [ x$response != "xy" -a x$response != "xn" ]; do + echo -e "\n'y' or 'n' only please...\n" | cat >&2 + echo -en $query | cat >&2 + read response + done + echo $response +} + +# configuration +# +# set defaults +defaultusername="scponly" +defaulthomedirprefix="/home" +defaultwriteabledir="incoming" + +osname=`uname -s | tr ' ' '_'` +# pathname to platform/OS specific setup scripts +prescript="build_extras/arch/$osname.pre.sh" +postscript="build_extras/arch/$osname.post.sh" + +# the following is a list of binaries that will be staged in the target dir +BINARIES=`grep '#define PROG_' config.h | cut -f2 -d\" | grep -v ^cd$` + +# we set the install path in a variable so the presetup script can overwrite it on systems +# which require it +INSTALL_PATHNAME="install -c" + +# attempt a best guess at required libs, we can append things in the presetup script if we need to +LDSOFOUND=0 + +# default to useradd, not pw +USE_PW=0 + +if [ x/usr/bin/ldd = x ]; then + echo "this script requires the program ldd to determine which" + fail "shared libraries to copy into your chrooted dir..." +fi + +if [ x`uname -s` = "xOpenBSD" ]; then + for bin in $BINARIES; do + GREP_LIST="$GREP_LIST -e $bin" + done + LIB_LIST=`ldd $BINARIES 2> /dev/null | /usr/bin/tr -s " " | cut -f5 -d" " | /usrgrep -v "^Name" | /usrgrep -v $GREP_LIST | /usr/bin/sort -u` +else + LIB_LIST=`ldd $BINARIES 2> /dev/null | cut -f2 -d\> | cut -f1 -d\( | grep "^ " | sort -u` +fi + +# +# we also need to add some form of ld.so, here are some good guesses. +# +LDSO_LIST="/lib/ld.so /libexec/ld-elf.so /libexec/ld-elf.so.1 /usr/libexec/ld.so /lib64/ld-linux-x86-64.so.2 /lib/ld-linux-x86-64.so.2 /lib/ld-linux.so.2 /usr/libexec/ld-elf.so.1" +for lib in $LDSO_LIST; do + if [ -f $lib ]; then + LDSOFOUND=1; + LIB_LIST="$LIB_LIST $lib" + fi +done + +# +# TODO - i've since forgotten which OS this is for, it should be relocated to a presetup script +# +ls /lib/libnss_compat* > /dev/null 2>&1 +if [ $? -eq 0 ]; then + LIB_LIST="$LIB_LIST /lib/libnss_compat*" +fi + +ls /lib/libnss_files* > /dev/null 2>&1 +if [ $? -eq 0 ]; then + LIB_LIST="$LIB_LIST /lib/libnss_files*" +fi + +# check that the configure options are correct for chrooted operation: + +if [ x/usr/sbin/useradd = x ]; then + if [ x = x ]; then + echo "this script requires the program useradd or pw to add your" + fail "chrooted scponly user." + else + USE_PW=1; + fi +fi + +# we need to be root +if [ `id -u` != "0" ]; then + fail "you must be root to run this script\n" +fi + +echo +echo Next we need to set the home directory for this scponly user. +echo please note that the user\'s home directory MUST NOT be writeable +echo by the scponly user. this is important so that the scponly user +echo cannot subvert the .ssh configuration parameters. +echo +echo for this reason, a writeable subdirectory will be created that +echo the scponly user can write into. +echo + +if [ "$2" != "" ] ; then + targetuser=$2 +else +targetuser=`getwd "Username to install" "$defaultusername"` +fi +username_collision=`id $targetuser > /dev/null 2> /dev/null; echo $?` +if [ $username_collision -eq 0 ] ; then + fail "the user $targetuser already exists. please remove this user and their home directory and try again." +fi + +if [ "$1" != "" ] ; then + targetdir=$1 +else +targetdir=`getwd "home directory you wish to set for this user" "$defaulthomedirprefix/$targetuser"` +fi + +if [ "$3" != "" ] ; then + writeabledir=$3 +else +writeabledir=`getwd "name of the writeable subdirectory" "$defaultwriteabledir"` +fi + +# +# if you would like to overwrite/extend any of the variables above, do so in the system specific +# presetup script. +# +if [ -f "$prescript" ]; then +# +# this system has a pre-chroot setup script, lets run it +# + . "$prescript" +fi + +# if neither the presetup script or the best guess could find ld.so, we have to bail here +if [ $LDSOFOUND -eq 0 ]; then + fail i cant find your equivalent of ld.so +fi + +# +# ACTUAL MODIFICATIONS BEGIN HERE +# + +# this part shouldnt strictly be requried, but i'll leave it in until i'm sure of it +if [ ! -d $targetdir ]; then + $INSTALL_PATHNAME -d $targetdir + chmod 755 $targetdir +fi + +if [ ! -d $targetdir/etc ]; then + $INSTALL_PATHNAME -d $targetdir/etc + chown 0:0 $targetdir/etc + chmod 755 $targetdir/etc +fi + +# add all our binaries +for bin in $BINARIES; do + $INSTALL_PATHNAME -d $targetdir/`/usr/bin/dirname $bin` + $INSTALL_PATHNAME $bin $targetdir$bin +done + +# and the libs they require +if [ "x$LIB_LIST" != "x" ]; then + for lib in $LIB_LIST; do + $INSTALL_PATHNAME -d $targetdir/`/usr/bin/dirname $lib` + $INSTALL_PATHNAME $lib $targetdir/$lib + done +fi + +# /dev/null is needed inside the chroot +mkdir -p $targetdir/dev +mknod -m 666 $targetdir/dev/null c 1 3 + +if [ "x$USE_PW" = x0 ] ; then + /usr/sbin/useradd -d "$targetdir" -s "/usr/sbin/scponlyc" $targetuser + if [ $? -ne 0 ]; then + fail "if this user exists, remove it and try again" + fi +else + useradd -n $targetuser -s "/usr/sbin/scponlyc" -d "$targetdir" + if [ $? -ne 0 ]; then + fail "if this user exists, remove it and try again" + fi +fi + +# +# we must ensure certain directories are root owned. +# +chown 0:0 $targetdir +if [ -d $targetdir/.ssh ]; then + chown 0:0 $targetdir/.ssh +fi + +if [ ! -d $targetdir/$writeabledir ]; then + echo -e "\ncreating $targetdir/$writeabledir directory for uploading files" + $INSTALL_PATHNAME -o $targetuser -d $targetdir/$writeabledir +fi + +# +# set the perms on the writeable dir so that the new user owns it +# +newuid=`id -u $targetuser` +newgid=`id -g $targetuser` +chown $newuid:$newgid $targetdir/$writeabledir + +if [ -f "$postscript" ]; then +# +# this system has a post-chroot setup script, lets run it +# + . "$postscript" +else +# +# otherwise, revert to the old "best guess" system, which sucks +# + echo + echo "Your platform ($osname) does not have a platform specific setup script." + echo "This install script will attempt a best guess." + echo "If you perform customizations, please consider sending me your changes." + echo "Look to the templates in build_extras/arch." + echo " - joe at sublimation dot org" + echo + if [ x = x ]; then + # + # ok we dont have pwd_mkdb, lets improvise: + # + grep $targetuser /etc/passwd > $targetdir/etc/passwd + # Debian: copy /etc/group into the jail, for /usr/bin/groups to work + cp /etc/group $targetdir/etc/group + + else + # + # this is for systems which do have pwd_mkdb + # + grep $targetuser /etc/master.passwd > $targetdir/etc/master.passwd + -d "$targetdir/etc" $targetdir/etc/master.passwd + rm -rf $targetdir/etc/master.passwd $targetdir/etc/spwd.db + fi +fi + +# +# the final step is setting the password +# +echo "please set the password for $targetuser:" +passwd $targetuser + +echo "if you experience a warning with winscp regarding groups, please install" +echo "the provided hacked out fake groups program into your chroot, like so:" +echo "cp groups $targetdir/bin/groups" -- cgit v1.2.3-54-g00ecf