# ~/virtual terminal
# 将此文件放在/etc/profile.d/目录下,并添加可执行权限。
# 如: -rwxr-xr-x 1 root root 7340 Oct 23 18:12 /etc/profile.d/vt.sh
############################################################################
# 本行直至文件末尾的代码,用于实现用户登录使用的虚拟终端
# 请勿删除或更改
# 如有疑问、请联系维护负责人: xiaoxi227(QQ451914397)
############################################################################
# 该文件存放用户名和密码 文件格式为==> 用户名:密码 (每行一个用户)
passwd_file=/etc/user.password
function red()
{
# 以红色显示
echo -e "\033[31;40m$*\033[0m\n"
}
function green()
{
# 以绿色显示
echo -e "\033[32;40m$*\033[0m\n"
}
# 忽略所有信号,以免用户使用Ctrl+C或者Ctrl+Z等操作退出Virtual Terminal(VT)
for signal in `seq 1 64`
do
trap : $signal &> /dev/null
done
clear
function getchar() # 关闭回显,用于输入密码
{
stty cbreak -echo
dd if=/dev/tty bs=1 count=1 2>/dev/null
stty -cbreak echo
}
###############################################################################
green "登录成功。" # 用户通过unix pam认证以后显示“登陆成功”,随后进行身份验证
while :
do
read -p "请输入用户名:" username
echo -n "请输入密码: "
while :
do
ret=$(getchar)
if [ x"$ret" = x"" ];then
echo
break
fi
passwd="$passwd$ret"
echo -n '*'
done
correct_passwd=$(gawk -F: "/$username/{ print \$2 }" $passwd_file)
if [ -z "$username" -o -z "$passwd" ];then
clear
red "用户名或密码不能为空"
continue
fi
input_password=$(echo $passwd | md5sum | gawk '{ print $1 }')
if [ x"$input_password" != x"$correct_passwd" ];then
clear
red "用户名或密码错误,请重新输入"
else
break
fi
done
title="
##################################################################################
############################## Virtual Terminal ##################################
##################################################################################
cat | more <<EOF
$title
使用说明:
欢迎使用虚拟终端(Virtual Terminal,以下简称VT).
在此模式下,用户只能执行少量被允许执行的命令,其他命令将会被拒绝执行。
本模式支持的命令及功能如下:
cd <DIR> 进入<DIR>目录,前提是用户有进入该目录的权限。
ls 功能和系统中的ls命令相同,但是只能显示有读取权限的目录下的文件。
本命令支持参数,系统中ls命令可以使用的选项都可以在VT模式下使用。
mv <SRC> <DST> 将文件<SRC>移至<DST>,如果路径相同则含义为改名。
用户必须同时对<SRC>和<DST>有读写权限。
rm <FILE> 将<FILE>从系统中删除。
当<FILE>是目录时,会递归删除所有子目录及子目录下的文件。
pwd 显示当前的工作路径。
download <FILELIST>
将<FILELIST>下载至本机
运行此命令时,用户使用的终端必须支持ZModem协议,如SecureCRT等。
下载多个文件需将各文件用空格隔开。
如果下载的文件是目录,系统会自动将其打包后再下载。
upload 向系统中上传文件,运行此命令后,终端会弹出一个对话框,按提示选择文件上传即可。
注意:运行此命令时,用户使用的终端必须支持ZModem协议,如SecureCRT等。
passwd 修改自己的登录口令
如需其他功能,请与管理员联系,VT维护负责人:xiaoxi227(QQ:451914397)
$title
EOF
echo -e "当前登录用户是:\033[32;40m$username\033[0m"
logfile=/var/log/vt.log
function run() # 本函数用于替用户执行命令,并记录log
{
local command="$@"
{
echo -n -e "\033[32;40m$username\033[0m\033[7G -- "
echo -n -e "\033[31;40m`date '+%Y-%m-%d %H:%M:%S'` -- \033[0m$comman d"
echo
} | sed 's/sz/download/g;s/rz/upload/g' >> $logfile
$command
}
# 通常开发人员需要部署的程序都在同一目录下,所以为其指定根目录,限定仅在该目录有权限。
ROOT_DIR=/usr # 本例中用/usr目录测试
cd $ROOT_DIR # 进入用户的“根目录”
while : # 死循环读取用户输入
do
# 这里的主机名写成“localhost”写死了,您也可以写成$HOSTNAME,这样就会显示主机名了。
read -e -p "[${username}localhost ${PWD##*/}]$ "
# 如上语句模拟产生shell提示符(其实是假的)
# 分隔命令和参数
COMMAND=$(echo $REPLY | gawk '{ print $1 }')
OPTION=$(echo $REPLY | sed -r "s/^$COMMAND//g;s/^[[:space:]]+//g")
# 判断要执行的命令是什么,根据不同命令设置不同的动作。如下是本例中实现的几个命令:
case $COMMAND in
cd|ls)
# 当执行cd命令且参数为空时,默认cd到根目录,行为要与系统中的cd命令保持一致。
if [ x"$OPTION" = x"" -a x"$COMMAND" = x"cd" ];then
cd $ROOT_DIR
continue
fi
# 判断参数的第一个字符是不是"/",如果不是,说明想要cd或ls的是相对路径。
# 也就是当前目录下的文件活目录,此时用户是有权限的。
first_char=${OPTION:0:1}
if [ x"$first_char" != x"/" ];then
run $REPLY
else
# 如果是绝对路径,那么判断路径是否以$ROOT_DIR开头,若否则提示用户没权限。
echo $OPTION | grep -q ^$ROOT_DIR
if [ $? -eq 0 ];then
run $REPLY
else
echo "$COMMAND: Permission denied." >&2
fi
fi
;;
# 其他支持的参数:rm、mv、pwd、passwd等等,就不写注释了,自己理解下吧。
rm|mv)
if [ x"$COMMAND" = x"rm" ];then RM='-rf';else RM='';fi
run='ok'
for _file in $OPTION
do
echo $_file | grep -q '-'
[ $? -eq 0 ] && {
red "本命令在VT模式下不支持参数";
continue;
}
echo $_file | grep -q ^$ROOT_DIR
ret=$?
first_char=${_file:0:1}
if [ x"$first_char" = x"/" ];then
if [ $ret -ne 0 ];then
run='not ok'
fi
fi
done
if [ x"$run" = x"ok" ];then
run $COMMAND $RM $OPTION
else
echo "$COMMAND: Permission denied." >&2
fi
;;
pwd)
run $REPLY
;;
upload)
run rz
;;
download)
for _file in $OPTION
do
if [ ! -d $_file ];then
echo "开始下载文件:$_file"
run sz $_file
[ $? -eq 0 ] && green "下载完成" || red "下载失败"
else
echo "${_file}是目录,正在将其打包成${_file}.tar"
tar -cf ${_file}.tar $_file
[ $? -eq 0 ] && green "打包完成,开始下载${_file}.tar" \
|| { red "打包失败,无法下载";continue; }
run sz ${_file}.tar
[ $? -eq 0 ] && {
green "下载完成"
echo "正在删除打包文件"
rm -rf ${_file}.tar
[ $? -eq 0 ] && green "删除成功" \
|| red "删除失败"
} || red "下载失败"
fi
done
;;
passwd)
read -e -s -p "请输入旧密码:" old_passwd
echo '******'
old_passwd=$(echo $old_passwd | md5sum | gawk '{ print $1 }')
if [ x"$old_passwd" != x"$correct_passwd" ];then
red "密码输入错误"
continue
else
read -e -s -p "请输入新密码:" new_passwd1
echo '******'
read -e -s -p "请重复新密码:" new_passwd2
echo '******'
if [ x"$new_passwd1" != x"$new_passwd2" ];then
red "两次输入的密码不一致"
continue
else
new_passwd=$(echo $new_passwd1 | md5sum | gawk '{ print $1 }')
sed -i "/$username/s/.*/$username:$new_passwd/g" $passwd_file
fi
fi
;;
"")
continue
;;
*)
echo "-bash: $COMMAND: command not found" >&2
;;
esac
done