#!/bin/bash
# autopkgtest for chkrootkit and its cron.daily script
# nb, this edits /etc/chkrootkit.conf so take care
# Depends: chkrootkit, bash (arrays), grep, util-linux (ionice)
#
# nb: Open the output (eg via the .build file) in emacs' org-mode
# to make it easier to read.

set -ue

MY_DIR="$(realpath "$0")"
MY_DIR="${MY_DIR%/*}"

CONFIG="/etc/chkrootkit/chkrootkit.conf"

# some tests need to replace binaries with 'infected' variants, so we
# need to copy originals used by chkrootkit to $CLEAN
CLEAN=/tmp/clean
mkdir $CLEAN

# needs to contain eveything used by chkrootit via ${command} because when we use -p
# only $CLEAN will be on $PATH.
CMDS=(awk
	cut
	echo
	grep
	find
	head
	id
	ls
	ps
	sed
	strings
	uname
	ss
	netstat
	dirname
	xargs
	# wc and cat should really be in this list too
	dpkg-query
	)

for binary in "${CMDS[@]}"; do
	# 'which' finds echo unlike type -p
	b=$(realpath "$(which "$binary")")
	echo "copy: $binary from $b to $CLEAN"
	cp -a "$b" "$CLEAN/$binary"
done
$CLEAN/ls -la "$CLEAN"

echo "* Running ${0##*/} $* (from: $MY_DIR)..."
echo "** env"
env
MY_BUILD_DIR="$(dirname "${PWD%/src}")" # /tmp/autopkgtest.Xxxxxx
echo "MY_BUILD_DIR=$MY_BUILD_DIR"

echo "** other info"
for x in  /var/run/utmp /var/log/wtmp /var/log/lastlog ; do
	echo "ls $x"
	ls -laR "$x" 2>&1 ||:
done

overall_status="PASS"

### run a test of chkrootkit
#   $1 is the name for the test (any string)
#   debian/tests/$1.expected is a file of patterns (regexp):
#     expect pattern must appear in the the output (checked with grep -f)
#   $3 $4... are what we run
run_test(){
	local name="$1"
	shift
	local banner="Testing: $name ($*)"

	local expected="$MY_DIR/$name.expected"
	# $output needs to be stable across calls as the 'tee $output'
	# from the cron.daily script can be flagged by chkwtmp if the
	# build is run from inside sbuild inside tmux.
	local output="output"
	local result="ERROR" # overridden by first test in the while loop
	local missing=()
	local pattern

	echo "** $banner ..."
	echo "*** Output"
	"$@" 2>&1 | tee "$output"
	echo "**** Files in log"
"$CLEAN/ls" -lah /var/log/chkrootkit/ ||:
	echo "*** Test of content of output follows..."

	if [ ! -r "$expected" ]; then
		echo "**** SKIPPED: missing file: $expected"
		echo "No file $expected (issue with tests)" >&2
		result="FAIL"
		expected=/dev/null
	elif [ ! -s "$expected" ]; then
		# $expected_patterns is there but is empty (-s means size > 0) then we expect output to be empty too
		echo "**** Expected is empty, so output should be empty"
		if [ ! -s "$output" ]; then
			echo "Output is indeed empty: PASS"
			result="PASS"
		else
			echo "Output is non-empty: FAIL"
			result="FAIL"
			overall_status="FAIL"
			cat "$output"

			if [ "${1-}" = chkrootkit-daily ]; then
				echo "*** Raw output of $1 follows"
				ls -lah /var/log/chkrootkit/chkrootkit-daily.log || :
				cat /var/log/chkrootkit/chkrootkit-daily.log || :

				echo "*** Raw output of chkrootkit follows"
				ls -lah /var/log/chkrootkit/log.today.raw || :
				cat /var/log/chkrootkit/log.today.raw || :
			fi
		fi
	else
		# non-zero $expected_patterns, so we test each line
		while read -r pattern; do
			echo "**** Test for '$pattern'"
			if "$CLEAN/grep" --extended-regexp --regexp="$pattern" "$output"; then
				if [ "$result" = "ERROR" ]; then
					# first pattern
					result="PASS"
				fi
				echo "OK"
			else
				echo "<No match (FAIL)>"
				missing+=("$pattern")
				result="FAIL"
				overall_status="FAIL"
				echo ""
			fi
		done < "$expected"
	fi
	echo "** $result: $banner done: $result"
	if [ "$result" = FAIL ]; then
		echo "*** FAIL was with config set to:"
		cat $CONFIG || "$CLEAN/ls" -la /etc/chkrootkit

		echo "*** Reason(s) for failure follows"
		echo -e "Result: $result\n"
		for pattern in "${missing[@]}"; do
			echo "Missing: $pattern"
		done

		if [ "${1-}" = chkrootkit-daily ]; then
			echo "*** Raw output of $1 follows"
			ls -lah /var/log/chkrootkit/chkrootkit-daily.log || :
			cat /var/log/chkrootkit/chkrootkit-daily.log || :

			echo "*** Raw output of chkrootkit follows"
			ls -lah /var/log/chkrootkit/log.today.raw || :
			cat /var/log/chkrootkit/log.today.raw || :
		fi
	fi
	# Additional grep to avoid listing 'known' unmatched lines:
	# exactly which of the items below are output depends on how you
	# invoked autopkgtest, and what else is running at the time:
	#
	#   1. autopkgtest runs the test from
	#     PWD=/tmp/autopkgtest.GVTrJD/build.XXX/src and
	#     /tmp/autopkgtest.GVTrJD/build.XXX/src.pc/YYY.patch are
	#     flagged as 'suspicious'. (such lines could be included in
	#     the .expected file but presumably if we got rid of all
	#     patches they would disappear)
	#
	#   2. chkutmp flags anything running inside screen/tmux as
	#     lacking a tty. This can include the whole sbuild process
	#     (doesn't happen on salsa.debian.org) (chkutmp starts these
	#     lines with a !, and when DIFF_MODE=true you get an
	#     additional [+ -] if the filter was changed/invalid)
	#
	#   3. when running in a schroot, chkdirs thinks BTRFS is in use
	#     and gives a 'WARNING' (doesn't happen on salsa)
	#
	#   4. various tests do not filter out 'PACKET SNIFFER' reports
	#     from ifpromisc (produced when a network manager is running,
	#     eg salsa uses dhclient)
	#
	#   5. when running in lxc (as on salsa, but not within a
	#     schroot), /tmp/autopkgtest-reboot* scripts will be flagged
	#     as 'suspicious'
	local unmatched
	unmatched="$("$CLEAN/grep" -v --extended-regexp --file="$expected" "$output" \
		| "$CLEAN/grep" -v "$MY_BUILD_DIR" \
		| "$CLEAN/grep" -v --extended-regexp "^(> )?[+ -]?(!|The tty of the following process\(es\) was not found in /var/run/utmp:|WARNING: chkdirs: Possible LKM Trojan installed|WARNING: It seems you are using BTRFS, if this is true chkdirs can't help you to find hidden files/dirs$|WARNING: Output from ifpromisc:$|.+: PACKET SNIFFER|.+: not promisc and no packet sniffer sockets|/tmp/autopkgtest-reboot)" \
		|| true)"
		if [ -n "$unmatched" ]; then
			echo "*** Unexpected (unmatched) lines follow (for info):"
			echo "$unmatched"
		fi
		rm -f "$output"
		return 0
}
Xrun_test(){
	echo "SKIP: run_test $*"
}
Xcp(){
	echo "SKIP: cp $*"
}

echo "* Setting up the testsuite"
echo "** README"
echo "The purpose of this tests is to check that the actual output is as we expect.

This tests that both chkrootkit (directly invoked) and its chkrootkit-daily
(systemd timer/cronjob) work with various combinations of options.

- Each test has a file listing regexps: each listed regexp must match
  against the output or the test will fail: the 'fix' will often be
  to update the .expected file
- (these are in debian/test/*.expected)
- Output not matched by any such regexp is listed (with some known
  exceptions removed), but does not cause failure
- This testsuite is designed to run in a sbuild schroot or via the CI
  pipeline on salsa.debian.org: you might need to adjust the
  debian/test/*.expected files if running in some other way.
"

echo "** Ensuring chkrootkit finds as much to test as we can"
MADE=()
MOVED=()
TESTED=(
	amd biff cron crontab fingerd in.fingerd gpm hdparm \
	inetd in.identd inetdconf init killall \
	lsof mail mingetty named in.pop2d in.pop3d write \
	pstree rpcinfo rlogind in.rshd slogin sendmail sshd syslogd \
	tcpd tcpdump telnetd timed traceroute
)
# nb: in.rexedcs is not included as it is flagged as infected iff it is found
# nb: OSX_RSPLUG is omly tested under Darwin
for binary in "${TESTED[@]}"; do
	for path in "$(which "$binary" || echo "/usr/sbin/$binary")" "/etc/$binary.conf"; do
		if [ ! -e "$path" ]; then
			echo "Making $path"
			MADE+=("$path")
		else
			path="$(realpath "$path")"
			MOVED+=("$path")
			if [ ! -e "$path.orig" ]; then
				echo "$path: exists; mv to .orig"
				mv "$path" "$path.orig"
			else
				echo "already moved: $path"
			fi
		fi
		cat > "$path" <<-EOF
			#!/bin/sh
			echo "Fake $binary created for chkrootkit autopkgtest"
			exit 0
		EOF
		chmod +x "$path"
	done
done
echo "MADE: ${MADE[*]}"
echo "MOVED to .orig: ${MADE[*]}"

echo "Done"

## Make some false positives
# 1. something executable under /tmp
FALSE_POSITIVE=/tmp/test-chkrootkit-false-positive
echo "# chkrootkit thinks this could be a Linux.Xor.DDoS rootkit" > "$FALSE_POSITIVE"
chmod +x "$FALSE_POSITIVE"

# 2. some 'suspicious' dotfiles in /usr/lib
DOTFILES=(/usr/lib/.aaa /.aaa-this-is-not-flagged /usr/lib/.1 /lib/...)
DOTDIRS=(/usr/lib/.DIR-aaa /.DIR-aaa-this-is-not-flagged /usr/lib/.1DIR /lib/...DIR)

## Accident prevention:
# we are going to overwrite some paths - in theory this test is run
# in a chroot or other throwaway system, but in case it isn't (eg by accident), save (for later
# restoral) the system files we are about to overwrite.
SYSTEM_FILES=("$CONFIG" /etc/chkrootkit/chkrootkit.ignore
	/var/log/chkrootkit/log.expected /var/log/chkrootkit/log.today /var/log/chkrootkit/log.today.raw)
for f in "${SYSTEM_FILES[@]}"; do
	if [ -f "$f" ]; then
		echo "Preserving existing $f as $f.orig"
		mv "$f" "$f.orig"
	fi
done
####

echo "* Testing: the main binary"
# Standalone running of the main binary - all tests run
# no hidden files in /usr/lib
run_test "chkrootkit-0-full"  /usr/sbin/chkrootkit
# make some more false positives
touch "${DOTFILES[@]}"
mkdir "${DOTDIRS[@]}"
mkdir /usr/lib/.bbb

run_test "chkrootkit-1-full"  /usr/sbin/chkrootkit
run_test "chkrootkit-2-quiet" /usr/sbin/chkrootkit -q

# options
echo "* Testing: filtering of sniffer (-s)"
run_test "chkrootkit-sniffer-01-full" chkrootkit sniffer

# can't test 'chkrootkit -q' as output will be one "PACKET SNIFFER"
# line for any network manager that happens to be running, or empty if
# there are none.

# prints 'not found'
run_test "chkrootkit-sniffer-02-full-with-s" chkrootkit -s "(PACKET SNIFFER|not promisc)"  sniffer

# fully empty, whatever is running
run_test "chkrootkit-sniffer-03-quiet-with-s" chkrootkit -q -s "PACKET SNIFFER" sniffer


echo "* Testing: chkrootkit-daily - should give no output when disabled"
[ ! -e $CONFIG ] || echo >&2 "This should not happen - $CONFIG should have been moved above?"
run_test "cron-1-with-no-config" chkrootkit-daily

echo "RUN_DAILY=false" > $CONFIG
run_test "cron-2-disabled" chkrootkit-daily

echo "* Testing: chkrootkit-daily (without diff mode, full output, no MAILTO)"
echo "RUN_DAILY=true
DIFF_MODE=false
" > $CONFIG

run_test "cron-no-diff-mode-01-full" chkrootkit-daily

echo ".*" > /etc/chkrootkit/chkrootkit.ignore
echo ".aaa" > /etc/test-ignore # hides .aaa and .DIR-aaa
echo "FILTER='sed s!^/usr/lib/.b!CHANGED-IN-FILTER_!'
IGNORE_FILE=/etc/test-ignore
DIFF_MODE=false
" >> $CONFIG                   # $FILTER changes .bbb

run_test "cron-no-diff-mode-02-full-filter-and-ignore" chkrootkit-daily


echo "* Testing: chkrootkit-daily (without diff mode, quiet output, no MAILTO)"
echo "RUN_DAILY=true
DIFF_MODE=false
RUN_DAILY_OPTS=-q
" > $CONFIG
: > /etc/chkrootkit/chkrootkit.ignore
rm -f /etc/test-ignore
run_test "cron-no-diff-mode-03-quiet" chkrootkit-daily

# ionice => same output as previous
if [ ! -x /usr/bin/ionice ]; then
	echo >&2 "error - tests assume ionice is installed. update tests"
fi
echo "IONICE=\"\"
IGNORE_FILE=/nonexistant" >> $CONFIG
run_test "cron-no-diff-mode-04-quiet-no-ionice" chkrootkit-daily

echo ".*" > /etc/chkrootkit/chkrootkit.ignore
echo "\.aaa \[Not from a Debian package\]$" > /etc/test-ignore # hides .aaa but not .DIR-aaa
echo "FILTER='sed -re s,^\(/usr\)?/lib/.b,CHANGED-IN-FILTER_,'
IGNORE_FILE=/etc/test-ignore
" >> $CONFIG

run_test "cron-no-diff-mode-05-quiet-filter-and-ignore" chkrootkit-daily

echo "FILTER='sed s/this/is/invalid/sed/and/will/be/ignored'" >> $CONFIG
# results of 6 are
# - still subject to same IGNORE_FILE as 05
# - similar to 02 but with an extra 'warning' about invalid FILTER at the top
run_test "cron-no-diff-mode-06-quiet-invalid-filter-is-ignored"  chkrootkit-daily

echo "* Testing: chkrootkit-daily (with DIFF_MODE, full output, no MAILTO)"
echo "RUN_DAILY=true
DIFF_MODE=true
MAILTO=''
" > $CONFIG
: > /etc/chkrootkit/chkrootkit.ignore
rm /etc/test-ignore
run_test "cron-with-diff-mode-01-full" chkrootkit-daily

# Re-running gives the same output
run_test "cron-with-diff-mode-02-full-rerun" chkrootkit-daily

# ...until the admin updates log.expected
cp -f /var/log/chkrootkit/log.today /var/log/chkrootkit/log.expected
run_test "cron-with-diff-mode-03-full-after-update" chkrootkit-daily

# disabling ionice should not cause a change in output
echo "IONICE=\"\"" >> $CONFIG
run_test "cron-with-diff-mode-04-full-no-ionice" chkrootkit-daily

echo "\.aaa" > /etc/chkrootkit/chkrootkit.ignore
cat   >> $CONFIG <<EOF
FILTER="\$FILTER -e 's/.b \[.+\]$/CHANGED-IN-FILTER_/'"
EOF
run_test "cron-with-diff-mode-05-full-filter-and-ignore" chkrootkit-daily


echo "* Testing: chkrootkit-daily (diff mode, quiet output, no MAILTO)"
echo "RUN_DAILY=true
RUN_DAILY_OPTS='-q'
DIFF_MODE=true
" > $CONFIG
# reset as if started from scratch
rm -f /var/log/chkrootkit/log.expected
: > /etc/chkrootkit/chkrootkit.ignore
run_test "cron-with-diff-mode-06-quiet" chkrootkit-daily
run_test "cron-with-diff-mode-07-quiet-rerun" chkrootkit-daily
cp -f /var/log/chkrootkit/log.today /var/log/chkrootkit/log.expected
run_test "cron-with-diff-mode-08-quiet-after-update" chkrootkit-daily

echo "aa[a-z] \[.+\]$" > /etc/chkrootkit/chkrootkit.ignore
cat >> $CONFIG <<EOF
FILTER="\$FILTER -e 's/.b \[.+\]$/CHANGED-IN-FILTER_/'"
EOF

run_test "cron-with-diff-mode-09-quiet-filter-and-ignore" chkrootkit-daily

echo "FILTER='sed s/this/is/invalid/sed/and/will/be/ignored/with/diff/mode'" >> $CONFIG
run_test "cron-with-diff-mode-10-quiet-invalid-filter-is-ignored"  chkrootkit-daily

echo "* test MAILTO"
mail="$(which mail || echo "/usr/bin/mail")"
echo "** Mocking out 'mail' command: $mail"
ls -la "$mail" ||: # shld be zero as mocked at start
cat > "$mail" <<EOF
#!/bin/sh
echo "mail called with \$# args:"
for x in "\$@"; do
  echo "<\$x>"
done
while read -r line; do
  echo "> \$line"
done
exit 0
EOF
chmod +x "$mail"

echo "$mail":
cat "$mail"

echo stdin | mail test 1 2 3

echo "RUN_DAILY=true
RUN_DAILY_OPTS='-q'
DIFF_MODE=true
MAILTO=root
" > $CONFIG

# reset as if started from scratch
rm -f /var/log/chkrootkit/log.expected
: > /etc/chkrootkit/chkrootkit.ignore

run_test "chkrootkit-daily-mail-01" chkrootkit-daily

# re-run: should be the same output
run_test "chkrootkit-daily-mail-02-rerun" chkrootkit-daily

cp -f /var/log/chkrootkit/log.today /var/log/chkrootkit/log.expected
run_test "chkrootkit-daily-mail-03-no-diff-means-no-mail" chkrootkit-daily

echo "* Test chkrootkit tests report infected files"
echo "** setting up false positive 'fake rootkits' for every test"
ROOTKIT_LABEL="blah\nelite\n/dev/hda\n/dev/hda1\n/bin/sh\nfile.h\nmingetty\ngivemer"
ROOTKIT_LABEL="$ROOTKIT_LABEL\n/dev/ida\nvejeta\n/dev/tux\nUPXxxx\nproc.h"
ROOTKIT_LABEL="$ROOTKIT_LABEL\n/porcai\n/prof\nsh -i\nDimensioni\n/dev/ptyp"
ROOTKIT_LABEL="$ROOTKIT_LABEL\nHISTFILE\nhomo\nfuck\nr00t\nhack\n/lib/volc"
ROOTKIT_LABEL="$ROOTKIT_LABEL\nuname -a\npoop\n"

TO_DELETE=()
TO_REPLACE=()

# TROJAN
for binary in amd basename biff chfn chsh cron date du dirname echo egrep \
	env find fingerd gpm grep hdparm su ifconfig inetd in.identd init \
	killall login ls lsof mail mingetty netstat named passwd pidof \
	in.pop2d in.pop3d ps pstree rpcinfo in.rlogind slogin sendmail sshd syslogd tar tcpd \
	top telnetd timed traceroute vdir w write \
	asp  crontab epic; do
	echo "Ensuring $binary shows as INFECTED"
	b="$(which "$binary" 2>/dev/null ||:)"
	if [ -z "$b" ]; then
		b="/usr/sbin/$binary"
		echo "making new: $b"
		TO_DELETE+=("$b")
	else
		echo "mv $b $b.to_replace"
		b=$(realpath "$b")
		if [ -e "$b.to_replace" ]; then
			echo "Alread REPLACEd: $b"
		else
			mv "$b" "$b.to_replace"
			TO_REPLACE+=("$b")
		fi
	fi
	touch "$b"
	chmod +x "$b"
	echo "$b"

	echo -e "echo '$binary should not be called (arg: \$*)' >&2\nexit 2\n${ROOTKIT_LABEL}" > "$b"
done

# chk_crontab runs crontab
b=$(which crontab)
echo "for chk_crontab: mocking: crontab at $b"
cat > "$b" <<EOF
#!/bin/sh
echo 'crontab666 /dev/hda'
EOF

echo "modifying tar so chk-tar finds an issue"
b="$(which tar)"
chmod ugo+xs "$b"
$CLEAN/ls -l "$b"

echo "To delete: ${TO_DELETE[*]}"
echo "To replace (with .pre-rootkit): ${TO_REPLACE[*]}"

echo "modifying netstat for chk_netstat and bindshell"
cat > $CLEAN/netstat <<EOF
#!/bin/sh
echo '212.146.0.34:1963'
# bindshell
echo 'tcp LISTEN 127.0.0.1:600 ...'
echo 'udp UNCONN 127.0.0.1:31337 ...'
EOF
cp $CLEAN/netstat $CLEAN/ss

echo "modifying ls so syslogk and kovid are detected"
cp -a "$CLEAN/ls" "$CLEAN/ls.orig"
cat > "$CLEAN/ls" <<EOF
#!/bin/sh
case "\$*" in
*proc*) echo "\$*";;
*) exec $CLEAN/ls.orig "\$@" ;;
esac
EOF

echo "modifying grep so a Linux BPF Door is detected"
cp -a "$CLEAN/grep" "$CLEAN/grep.orig"
cat > "$CLEAN/grep" <<EOF
#!/bin/sh
case "\$*" in
*proc/*/stack*) echo "/proc/xx/stack";;
*) exec $CLEAN/grep.orig "\$@" ;;
esac
EOF


# aliens() - files flag as various rootkits
ROOTKIT_FILES=(/usr/bin/atm /tmp/tcp.log /var/lib/games/.k/foo
	/usr/src/.poop/foo /dev/.golf/foo /dev/tux/foo '/usr/include/. .'/foo
	/usr/lib/tcl5.3/foo /etc/ttyhash /usr/local/lib/libproc.a /bin/mjy
	/usr/bin/n3tstat /bin/lps "/usr/lib/.ark?" /usr/lib/number.cgi /www/httpd/cgi-bin/last.cgi
	/usr/bin/red.tar /bin/dy /dev/chr /dev/cucl /usr/include/chk.h
	/usr/bin/xsf /usr/lib/locale/uboot /tmp/xp /usr/bin/volc
	/usr/include/proc.h /etc/rc.d/init.d/network /usr/bin/ishit
	/usr/sbin/initcheck /usr/sbin/mech /etc/sysconfig/console/load.zk
	/etc/ld.so.hash /bin/imout /usr/include/icekey.h /sbin/xc
	/sbin/rootedoor /etc/.enyelkmOCULTAR.ko/foo /var/tmp/vuln.txt
	/usr/local/hide/foo /lib/modules/module_init.ko /tmp/ss0-0
	/usr/var/mediamgrs.jar /tmp/.ICE-unix/engine.so /etc/xig
	/var/tmp/.1/x /var/run/.tmp/y  /tmp/suterusu/pwnlnx6 /usr/share/libc.so.69 /tmp/kdevtmpfsi /bin/systemd-daemon
	/syslogk /root/.whatever.history /root/.whatever.history.hardlink
	/tmp/name.php /bin/.ps
	/usr/bin/mailrc /www/httpd/cgi-bin/bogus.cgi /bin/frgy
	/dev/cuc /usr/lib/libpikapp.a  /var/spool/cron/crontabs/foo /etc/rc.local /sbin/ssh /dev/bad-file /etc/passwd
	/etc/inetd.conf "/lib/x86_64-linux-gnu/libkeyutils.so.1"
	"/home/ ./tinyDNS" /tmp/by-content
	/bin/in.rexedcs
	/tmp/.uua
	/tmp/.bugtraq.c
	/tmp/.../r
	/bin/cls

	# see #1071377
	/tmp/sp\ ace/aaa\'\ exit\ 1\;\ \"
)

MOVED_ROOTKIT=()
MADE_ROOTKIT=()
for x in "${ROOTKIT_FILES[@]}"; do
	dir="$("$CLEAN"/dirname "$x")"
	echo "mk: $x in dir: $dir"
	if [ -e "$x" ]; then
		MOVED_ROOTKIT+=("$x")
		if [ -e "$x.pre-rootkit" ]; then
			echo "ALREADY REPLACED:rtkit file $x"
		else
			mv "$x" "$x.pre-rootkit"
		fi
	else
		mkdir -p "$dir" ||:
		touch "$x"||:
		MADE_ROOTKIT+=("$x")
	fi
done

echo "To move back to .pre-rootkit: ${MOVED_ROOTKIT[*]}"
echo "To rm: ${MADE_ROOTKIT[*]}"


echo "for chk_ldsopreload"
echo xxxxx >  /lib/libshow.so

echo "for chk_rshd"
echo -e "$ROOTKIT_LABEL" > /usr/sbin/in.rshd



echo susp dev
echo "1 foo" > /dev/bad-file

# hkrk
echo .hk >> /etc/rc.d/init.d/network

# mumblehard
echo var/tmp > /var/spool/cron/crontabs/foo

# suspicious php
echo '#!.php' > /tmp/by-content

# suspicious php with quote marks (#1071377)
echo '#!.php' > /tmp/sp\ ace/aaa\'\ exit\ 1\;\ \"



# id (used to check if we are root) needs /etc/passwd roughly normal
cp /etc/passwd.pre-rootkit /etc/passwd
# Linux.proxy
echo mother >> /etc/passwd

# ebury 1.4
cat > /sbin/ssh <<EOF
#!/bin/sh
# 1.4
echo OpenSSH_1.
EOF
chmod +x /sbin/ssh

# ebury 1.6
echo 'libpw5' > "/lib/x86_64-linux-gnu/libkeyutils.so.1"

# 64 but
echo module_init > /etc/rc.local


echo "for chk_inetdconf"
echo "stream tcp nowait /bin/sh" > /etc/inetd.conf
echo /etc/shells
cat /etc/shells

# asp()
echo "asp"
echo asp >> /etc/inetd.conf
cat /etc/inetd.conf

#zero-sized history
:>/root/.whatever.history
rm /root/.whatever.history.hardlink
ln /root/.whatever.history /root/.whatever.history.hardlink

# lkm ()
echo "dont know how to fake some lkms (cant make a file in /proc): not tested: sniffer, z2, chkutmp. OSX_RSPLUG never runs under linux. chk_ldsopreload seems to be broken"

run_test "all-tests-can-find-something-01" chkrootkit -p "$CLEAN"

run_test "all-tests-can-find-something-02-quiet" chkrootkit -p "$CLEAN" -q # -d

# use -e
run_test "exclude-results-with-minus-e-option" chkrootkit -p "$CLEAN" -e '/usr/*' aliens


echo "* Testing the -r option"
# -r lets you check a mounted directory (or container filesystem etc).
ROOT_DIR="/tmp/CHKROOTKIT_ROOT" # must be absolute and no spaces. chlastlog also limits path to 127 chars
ln -s / "$ROOT_DIR"
echo "Symlink ROOT_DIR created: $ROOT_DIR"
$CLEAN/ls -lad "$ROOT_DIR"

run_test "setting-rootdir" chkrootkit -p "$CLEAN" -r "$ROOT_DIR"

echo "* Resetting"
echo "Removing symlink: $ROOT_DIR"
rm "$ROOT_DIR"

for f in "${MOVED_ROOTKIT[@]}";do
	echo "replace $f with $f.pre-rootkit"
	mv "$f.pre-rootkit" "$f"
	$CLEAN/ls "$f"* 2>&1|| :
done
for f in "${MADE_ROOTKIT[@]}";do
	echo "kill: $f"
	rm "$f"
	$CLEAN/ls "$f"*  2>&1|| :
done

for f in "${TO_REPLACE[@]}";do
	echo "TO_REPLACE: restoring $f with $f.to_replace"
	mv "$f.to_replace" "$f"
	$CLEAN/ls "$f"*  2>&1||:
done
for f in "${TO_DELETE[@]}"; do
	echo "TO_DELETE: rm $f"
	rm "$f"
	$CLEAN/ls "$f"*  2>&1||:
done
for f in "${MOVED[@]}";do
	echo "MOVED: replace $f with $f.orig"
	mv "$f.orig" "$f"
	$CLEAN/ls "$f"*  2>&1||:
done
for f in "${MADE[@]}";do
	echo "MADE: rm $f"
	rm "$f"
	$CLEAN/ls "$f"*  2>&1||:
done



echo "done"

## test with all commands removed - output should be 'not found'














echo "* Closing down the testsuite"
for f in "${SYSTEM_FILES[@]}"; do
	if [ -f "$f.orig" ]; then
		echo "Restoring $f from $f.orig"
		mv -f "$f.orig" "$f" || echo "Failed to restore $f?"
	fi
done
rm -f "${DOTFILES[@]}" "$FALSE_POSITIVE" /etc/test-ignore "${MADE[@]}"
rmdir "${DOTDIRS[@]}" /usr/lib/.bbb
echo "DONE"
echo "* ${0##*/}: $overall_status"
if [ "$overall_status" = "PASS" ]; then
	exit 0
else
	exit 1
fi
