| # YesLogin |
| # Copyright 2015-2023 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 |
| [ -x "`which fakeroot-ng 2> /dev/null`" ] || return |
| [ -x "`which sudo 2> /dev/null`" ] || 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 |
| 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_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 |
| 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 |
| #[ -n "$PS1" ] || [ -t 0 ] && [ -z "$SUDO_USER" ] && [ -n "$BASH" ] && [ "$UID" = 0 ] && exec -a "" sudo /bin/bash |
| 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 UNPRIVILEGED_USER |
| export SHELL_DEF=1 |