blob: e3c646e8edc7391ea3d2eddede894290d9686431 [file] [log] [blame] [raw]
# YesLogin
# Copyright 2015-2024 Rivoreo
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
mask_args() {
if [ -n "$1" ]; then
pid=$1
else
mount --no-mtab --bind /proc/$PPID /proc/$$ > /dev/null 2>&1 && return
pid=$$
fi
#[ -n "$1" ] && pid=$1 || pid=$$
for f in /dev/crash /dev/null; do
mount --no-mtab --bind $f /proc/$pid/cmdline && break
done 0<> /dev/null 1>&0 2>&0
unset pid
}
UNPRIVILEGED_USER=
switch_to_unprivileged() {
[ -z "$UNPRIVILEGED_USER" ] && return
fakeroot-ng -v > /dev/null 2>&1 || return
sudo -V > /dev/null 2>&1 || return
changed_selinux=
[ "`getenforce 2> /dev/null`" = Enforcing ] && setenforce 0 > /dev/null 2>&1 && changed_selinux=1
mask_args
[ -n "$changed_selinux" ] && setenforce 1 > /dev/null 2>&1
unset changed_selinux
if [ ! -f /usr/sbin/sec ] && [ "`dd if=/bin/bash bs=4 count=1 2> /dev/null`" = "ELF" ]; then
if [ -f /usr/bin/sec ] && LD_PRELOAD=/usr/bin/sec bash -c "[ -f /usr/sbin/sec ]"; then
preload=LD_PRELOAD=/usr/bin/sec
elif LD_PRELOAD=libsec.so.1 bash -c "[ -f /usr/sbin/sec ]"; then
preload=LD_PRELOAD=libsec.so.1
else
preload=
fi
else
preload=
fi > /dev/null 2>&1
[ -n "$BASH_EXECUTION_STRING" ] && set -- -c "$BASH_EXECUTION_STRING"
exec sudo -u "$UNPRIVILEGED_USER" HOME=/root LOGNAME=root USER=root $preload fakeroot-ng /bin/bash "$@"
}
from_be_uint32_bin_len() {
case "$1" in
0)
echo 0
;;
1)
echo 128
;;
2)
echo 192
;;
3)
echo 224
;;
4)
echo 240
;;
5)
echo 248
;;
6)
echo 252
;;
7)
echo 254
;;
8)
echo 255
;;
esac
}
is_host_in_network() {
[ $# != 2 ] && return 1
case "$2" in
*.*.*.*/[0-9][0-9]|*.*.*.*/[0-9])
prefix_len="${2##*/}"
[ "$prefix_len" -lt 0 -o "$prefix_len" -gt 32 ] && return 1
addr1="$1"
addr2="${2%/*}"
ORIG_IFS="$IFS"
IFS=.
set -- $addr2
if [ "$prefix_len" -gt 24 -a "$prefix_len" -le 32 ]; then
addr2_a1=$1
addr2_a2=$2
addr2_a3=$3
mask="`from_be_uint32_bin_len $((prefix_len-24))`"
addr2_a4=$4
[ $addr2_a4 -gt $mask ] && addr2_a4=$mask
elif [ "$prefix_len" -gt 16 -a "$prefix_len" -le 24 ]; then
addr2_a1=$1
addr2_a2=$2
mask="`from_be_uint32_bin_len $((prefix_len-16))`"
addr2_a3=$3
[ $addr2_a3 -gt $mask ] && addr2_a3=$mask
addr2_a4=0
elif [ "$prefix_len" -gt 8 -a "$prefix_len" -le 16 ]; then
addr2_a1=$1
mask="`from_be_uint32_bin_len $((prefix_len-8))`"
addr2_a2=$2
[ $addr2_a2 -gt $mask ] && addr2_a2=$mask
addr2_a3=0
addr2_a4=0
elif [ "$prefix_len" -gt 0 -a "$prefix_len" -le 8 ]; then
mask="`from_be_uint32_bin_len $prefix_len`"
addr2_a1=$1
[ $addr2_a1 -gt $mask ] && addr2_a1=$mask
addr2_a2=0
addr2_a3=0
addr2_a4=0
else
unset prefix_len addr1 addr2 ORIG_IFS
return 1
fi
set -- $addr1
IFS="$ORIG_IFS"
if [ "$prefix_len" -gt 24 -a "$prefix_len" -le 32 ]; then
[ $1 = $addr2_a1 ] && [ $2 = $addr2_a2 ] && [ $3 = $addr2_a3 ] || return 1
[ $4 -lt $addr2_a4 ] && return 1
[ $(($4-addr2_a4)) -lt $((256-mask)) ]
elif [ "$prefix_len" -gt 16 -a "$prefix_len" -le 24 ]; then
[ $1 = $addr2_a1 ] && [ $2 = $addr2_a2 ] || return 1
[ $3 -lt $addr2_a3 ] && return 1
[ $(($3-addr2_a3)) -lt $((256-mask)) ]
elif [ "$prefix_len" -gt 8 -a "$prefix_len" -le 16 ]; then
[ $1 = $addr2_a1 ] || return 1
[ $2 -lt $addr2_a2 ] && return 1
[ $(($2-addr2_a2)) -lt $((256-mask)) ]
elif [ "$prefix_len" -gt 0 -a "$prefix_len" -le 8 ]; then
[ $1 -lt $addr2_a1 ] && return 1
[ $(($1-addr2_a1)) -lt $((256-mask)) ]
else
false
fi
;;
*.*.*.*)
[ "$1" = "$2" ]
;;
*)
false
;;
esac
}
is_loopback_ssh() {
set -- $SSH_CONNECTION
[ $# -ge 4 ] && [ "$1" = "$3" ]
}
is_blacklisted() {
[ $# != 1 ] && return 1
h="$1"
if [ -f /etc/hosts.allow ] && [ -r /etc/hosts.allow ]; then
ORIG_IFS="$IFS"
while IFS= read entry; do
IFS=:
set -- ${entry%%\#*}
[ $# -lt 3 ] && continue
IFS="$ORIG_IFS,"
case "$1" in
\*)
;;
*ALL*)
;;
*sshd*)
;;
*)
continue
;;
esac
#set -f
for entry in $2; do
is_host_in_network "$h" "$entry" || continue
for option in $3; do case "$option" in
[Aa][Ll][Ll][Oo][Ww])
IFS="$ORIG_IFS"
return 1
;;
[Dd][Ee][Nn][Yy])
IFS="$ORIG_IFS"
return 0
;;
esac done
break 2 # No explicit allow, continue to check '.blacklist'
done
done < /etc/hosts.allow
IFS="$ORIG_IFS"
fi
[ -f "$HOME/.blacklist" ] || return 1
while read entry; do
is_host_in_network "$h" "$entry" && return 0
done < "$HOME/.blacklist" > /dev/null 2>&1
#is_loopback_ssh && return
false
}
#[ "$SUDO_USER" = "$UNPRIVILEGED_USER" ] && switch_to_unprivileged
#[ "`ps -p $PPID -o comm= 2> /dev/null`" = su ] && switch_to_unprivileged
if [ -n "$SSH_CLIENT" ]; then
ipaddr=${SSH_CLIENT%% *}
{ printf "[%s] %s %s\\n" "`date +%F.%T.%Z`" "$USER" "$SSH_CLIENT" | tee -a /var/log/shd.log >> "$HOME/.login.log"; } 2> /dev/null
if is_blacklisted "$ipaddr"; then
{
printf "Login from %s denied\\n" "$ipaddr" >> "$HOME/.login.log"
printf "%s login from %s denied\\n" "$USER" "$ipaddr" >> /var/log/shd.log
} 2> /dev/null
#switch_to_unprivileged
exec /bin/noshellhere
fi
if false && [ -z "$SUDO_USER" ] && [ -n "$BASH" ] && myctty="`ps -p $$ -o tty= 2> /dev/null`" && { [ "$myctty" = \? ] || [ "$myctty" != "`ps -p $PPID -o tty= 2> /dev/null`" ]; }; then
[ -f "$BASH" ] || BASH=/bin/bash
[ -n "$PS1" ] || [ "$myctty" != \? ] && [ -f "$BASH" ] && [ "$UID" = 0 ] && exec -a "" sudo "$BASH"
fi
unset myctty
need_regular_file() {
[ -f "$1" ] && return
rm -f -- "$1"
true > "$1"
}
write_history() {
_tty="`tty`" && _tty="${_tty#/dev/}" || _tty=\?
eval "write_history() { need_regular_file '$HOME/.ash_commands'; { printf '[%s] [%s] [%s] ' \"\`date +%F.%T.%Z\`\" '$ipaddr' '$_tty'; history 1; } >> '$HOME/.ash_commands'; } 2> /dev/null"
unset _tty
}
if [ -n "$PROMPT_COMMAND" ]; then
PROMPT_COMMAND="$PROMPT_COMMAND
write_history 2> /dev/null"
else
PROMPT_COMMAND="write_history 2> /dev/null"
fi
if [ -n "$BASH" ]; then
if [ "$HISTFILE" != "$HOME/.bash_history" ]; then
if [ ! -f "$HISTFILE" ] || [ ! -w "$HISTFILE" ] || ! true >> "$HISTFILE"; then
HISTFILE="$HOME/.bash_history"
fi
fi
need_regular_file "$HISTFILE" > /dev/null 2>&1
declare +x -r HISTSIZE=100000
declare +x -r HISTFILE
declare +x -r HISTFILESIZE=5000000
declare +x -r PROMPT_COMMAND
fi
fi
[ -f "$HOME/.login.log" ] && chmod 600 "$HOME/.login.log" > /dev/null 2>&1
[ -f "$HOME/.ash_commands" ] || touch "$HOME/.ash_commands" > /dev/null 2>&1
chmod 600 "$HOME/.ash_commands" > /dev/null 2>&1
unset prefix_len addr1 addr2 ORIG_IFS
unset mask addr2_a1 addr2_a2 addr2_a3 addr2_a4
unset h entry option
unset mask_args
unset switch_to_unprivileged
unset from_be_uint32_bin_len
unset is_host_in_network
unset is_loopback_ssh
unset is_blacklisted
unset UNPRIVILEGED_USER
export SHELL_DEF=1