#!/bin/sh

#
# rkhunter -- Scan the system for rootkits and other known security issues.
#
# Copyright (c) 2003-2007, Michael Boelen ( michael AT rootkit DOT nl )
#
#     This program is free software; you can redistribute it and/or modify
#     it under the terms of the GNU General Public License as published by
#     the Free Software Foundation; either version 2 of the License, or
#     (at your option) any later version.
#
#     This program is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#     GNU General Public License for more details.
#
#     You should have received a copy of the GNU General Public License
#     along with this program; if not, write to the Free Software
#     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
#


#
# Unfortunately we must do some O/S checks at the very beginning.
# Otherwise SunOS will complain about some of the ksh/bash syntax.
#

OPERATING_SYSTEM=`uname 2>/dev/null`

if [ "${OPERATING_SYSTEM}" = "SunOS" ]; then
	if [ -z "$RANDOM" ]; then
		if [ -n "`which bash 2>/dev/null | grep '^/'`" ]; then
			exec bash $0 $*
		else
			exec ksh $0 $*
		fi

		exit 0
	fi
fi

if [ "$1" = "--debug" ]; then
	if [ -e "/tmp/rkhunter-debug" ]; then
		if [ -f "/tmp/rkhunter-debug" -a ! -h "/tmp/rkhunter-debug" ]; then
			rm -f /tmp/rkhunter-debug >/dev/null 2>&1
		else
			echo "Cannot use '--debug' option. /tmp/rkhunter-debug already exists, but it is not a file."
			exit 1
		fi
	fi

	DEBUG_OPT=1

	exec 1>/tmp/rkhunter-debug 2>&1
	set -x
else
	DEBUG_OPT=0
fi

case "${OPERATING_SYSTEM}" in
AIX|OpenBSD|SunOS|IRIX*)
	# What is the default shell?
	if print >/dev/null 2>&1; then
		alias echo='print'
		ECHOOPT="--"
		MYSHELL=ksh
	elif [ "${OPERATING_SYSTEM}" = "IRIX" -o "${OPERATING_SYSTEM}" = "IRIX64" ]; then
		ECHOOPT=""
		MYSHELL=sh
	else
		ECHOOPT="-e"
		MYSHELL=bash
	fi
	;;
*)
	ECHOOPT="-e"


	#
	# We want to get the actual shell used by this program, and
	# so we need to test /bin/sh.
	#

	MYSHELL=/bin/sh
	test -h ${MYSHELL} && MYSHELL=`readlink ${MYSHELL} 2>/dev/null`
	MYSHELL=`basename ${MYSHELL} 2>/dev/null`

	if [ -z "${MYSHELL}" ]; then
		MYSHELL=bash
	elif [ "${MYSHELL}" = "dash" -o "${MYSHELL}" = "ash" ]; then
		ECHOOPT=""
	fi
	;;
esac


######################################################################
#
# Global function definitions
#
######################################################################


display() {

	#
	# This function is used to display text messages on to the
	# users screen, as well as in to the log file. The same
	# message is written to both. However, the screen may have
	# a coloured result (green for good, red for bad, etc), and
	# the log file will have the time prefixed to the message and,
	# optionally, additional information messages after the main
	# message. All the messages are indexed in the language file.
	#
	# Syntax: display --to <destination> --type <type>
	#		  [--screen-indent <n>] [--log-indent <n>]
	#		  [--nl [<n>]] [--nl-after] [--log-nl]
	#		  [--result <result> --color <colour>]
	#		  <message index> [optional message arguments]
	#
	# where the destination can be one of SCREEN, LOG or SCREEN+LOG.
	# The type can be one of PLAIN, INFO or WARNING.
	# The language file will have all the current values.
	#
	# The --screen-indent and --log-indent options are used to
	# forcibly indent a message.
	# The --nl option causes a blank-line to be output before the
	# message both on the screen and in the log file. A following
	# number can be used to indicate how many blank lines should
	# be displayed on the screen.
	# The --log-nl option outputs a blank line only in the log file.
	# The --nl-after option outputs a blank line on the screen after
	# the message.
	#


	#
	# We first initialize some variables and then
	# process the switches used.
	#

	WARN_MSG=0; NL=0; NLAFTER=0; LOGINDENT=0; SCREENINDENT=0
	LOGNL=0
	WRITETO=''; TYPE=''; RESULT=''; COLOR=''; MSG=''
	LINE1=''; LOGLINE1=''; SPACES=''

	DISPLAY_LINE="display $*"

	if [ $# -le 0 ]; then
		echo "Error: Invalid display call - no arguments given"
		return
	fi

	while [ $# -ge 1 ]; do
		case "$1" in
		--to)
			case "$2" in
			SCREEN|LOG|SCREEN+LOG)
				WRITETO=$2
				;;
			*)
				echo "Error: Invalid display destination: $2   Display line: ${DISPLAY_LINE}"
				return
				;;
			esac

			shift
			;;
		--type)
			TYPE=`eval echo "\\$MSG_TYPE_$2"`

			if [ -z "${TYPE}" -a "$2" != "PLAIN" ]; then
				if [ $RKHLANGUPDT -eq 0 ]; then
					echo "Error: Invalid display type: $2   Display line: ${DISPLAY_LINE}"
					return
				fi
			fi

			test "$2" = "WARNING" && WARN_MSG=1

			shift
			;;
		--result)
			RESULT=`eval echo "\\$MSG_RESULT_$2"`

			if [ -z "${RESULT}" ]; then
				if [ $RKHLANGUPDT -eq 0 ]; then
					echo "Error: Invalid display result: $2   Display line: ${DISPLAY_LINE}"
					return
				fi
			fi

			shift
			;;
		--color)
			if [ $COLORS -eq 1 ]; then
				test -n "$2" && COLOR=`eval "echo \\${$2}"`

				if [ -z "${COLOR}" ]; then
					echo "Error: Invalid display color: $2   Display line: ${DISPLAY_LINE}"
					return
				fi
			fi

			shift
			;;
		--log-indent)
			LOGINDENT=$2

			if [ -z "${LOGINDENT}" ]; then
				echo "Error: No --log-indent value given.   Display line: ${DISPLAY_LINE}"
				return
			elif [ -z "`echo ${LOGINDENT} | grep '^[0-9]*$'`" ]; then
				echo "Error: Invalid --log-indent value given: $2   Display line: ${DISPLAY_LINE}"
				return
			fi

			shift
			;;
		--screen-indent)
			SCREENINDENT=$2

			if [ -z "${SCREENINDENT}" ]; then
				echo "Error: No --screen-indent value given.   Display line: ${DISPLAY_LINE}"
				return
			elif [ -z "`echo ${SCREENINDENT} | grep '^[0-9]*$'`" ]; then
				echo "Error: Invalid --screen-indent value given: $2   Display line: ${DISPLAY_LINE}"
				return
			fi

			shift
			;;
		--nl)
			NL=1

			case "$2" in
			[0-9])
				NL=$2
				shift
				;;
			esac
			;;
		--log-nl)
			LOGNL=1
			;;
		--nl-after)
			NLAFTER=1
			;;
		-*)
			echo "Error: Invalid display option given: $1   Display line: ${DISPLAY_LINE}"
			return
			;;
		*)
			MSG=$1
			shift
			break
			;;
		esac

		shift
	done


	#
	# Before anything we must record if this is a warning message.
	#

	test $WARN_MSG -eq 1 && WARNING_COUNT=`expr ${WARNING_COUNT} + 1`


	#
	# For simplicity we now set variables as to whether the output
	# goes to the screen and/or the log file. In some cases we do
	# not need to output anything, and so can just return.
	#

	if [ $NOLOG -eq 1 ]; then
		test "${WRITETO}" = "LOG" && return

		test "${WRITETO}" = "SCREEN+LOG" && WRITETO="SCREEN"
	fi

	if [ $NOTTY -eq 1 ]; then
		test "${WRITETO}" = "SCREEN" && return

		test "${WRITETO}" = "SCREEN+LOG" && WRITETO="LOG"
	fi


	test "${WRITETO}" = "SCREEN" -o "${WRITETO}" = "SCREEN+LOG" && WRITETOTTY=1 || WRITETOTTY=0

	test "${WRITETO}" = "LOG" -o "${WRITETO}" = "SCREEN+LOG" && WRITETOLOG=1 || WRITETOLOG=0


	#
	# Now check that the options we have been given make sense.
	#

	if [ $WRITETOTTY -eq 0 -a $WRITETOLOG -eq 0 ]; then
		echo "Error: Invalid display destination: Display line: ${DISPLAY_LINE}"
		return
	elif [ $WRITETOTTY -eq 1 -a $COLORS -eq 1 -a -n "${RESULT}" -a -z "${COLOR}" ]; then
		echo "Error: Invalid display - no color given: Display line: ${DISPLAY_LINE}"
		return
	fi


	#
	# We set the variable LINE1 to contain the first line of the message.
	# For the log file we use the variable LOGLINE1. We also set
	# where the language file is located. If a message cannot be found
	# in the file, then we look in the English file. This will allow RKH
	# to still work even when the language files change.
	#

	LANG_FILE="${DB_PATH}/i18n/${LANGUAGE}"

	if [ -n "${MSG}" ]; then
		LINE1=`grep "^${MSG}:" ${LANG_FILE} 2>/dev/null | head -n 1 | cut -d: -f2-`

		if [ -z "${LINE1}" ]; then
			LANG_FILE="${DB_PATH}/i18n/en"
			LINE1=`grep "^${MSG}:" ${LANG_FILE} 2>/dev/null | head -n 1 | cut -d: -f2-`

			if [ -z "${LINE1}" ]; then
				echo "Error: Invalid display - language keyword cannot be found: Display line: ${DISPLAY_LINE}"
				return
			fi
		else
			LINE1=`echo "${LINE1}" | sed -e 's/\`/\\\\\`/g'`
		fi

		test -n "${LINE1}" && LINE1=`eval "echo \"${LINE1}\" | sed -e 's/;/\\;/g'"`
	fi


	#
	# At this point LINE1 is the text of the message. We have to
	# see if the message is to be indented, and must prefix the
	# time to log file messages. We must do the log file first
	# because it uses LINE1.
	#

	if [ $WRITETOLOG -eq 1 ]; then
		LOGLINE1=`date '+[%H:%M:%S]'`

		test $NL -gt 0 -o $LOGNL -eq 1 && echo "${LOGLINE1}" >>${RKHLOGFILE}

		if [ -n "${TYPE}" ]; then
			LOGLINE1="${LOGLINE1} ${TYPE}: ${LINE1}"
		else
			test $LOGINDENT -gt 0 && SPACES=`echo "${BLANK_LINE}" | cut -c1-$LOGINDENT`

			LOGLINE1="${LOGLINE1} ${SPACES}${LINE1}"
		fi
	fi

	if [ $WRITETOTTY -eq 1 -a $SCREENINDENT -gt 0 ]; then
		SPACES=`echo "${BLANK_LINE}" | cut -c1-$SCREENINDENT`
		LINE1="${SPACES}${LINE1}"
	fi


	#
	# We now check to see if a result is to be output. If it is,
	# then we need to space-out the line and color the result.
	#
	if [ -n "${RESULT}" ]; then
		if [ $WRITETOTTY -eq 1 ]; then
			LINE1_NUM=`echo "${LINE1}" | wc -c | tr -d ' '`
			NUM_SPACES=`expr 62 - ${LINE1_NUM}`
			test $NUM_SPACES -lt 1 && NUM_SPACES=1

			if [ $COLORS -eq 0 ]; then
				SPACES=`echo "${BLANK_LINE}" | cut -c1-$NUM_SPACES`
				LINE1="${LINE1}${SPACES}[ ${RESULT} ]"
			else
				LINE1="${LINE1}\033[${NUM_SPACES}C[ ${COLOR}${RESULT}${NORMAL} ]"
			fi
		fi

		if [ $WRITETOLOG -eq 1 ]; then
			LOGLINE1_NUM=`echo "${LOGLINE1}" | wc -c | tr -d ' '`
			NUM_SPACES=`expr 62 - ${LOGLINE1_NUM}`
			test $NUM_SPACES -lt 1 && NUM_SPACES=1
			SPACES=`echo "${BLANK_LINE}" | cut -c1-$NUM_SPACES`

			LOGLINE1="${LOGLINE1}${SPACES}[ ${RESULT} ]"
		fi
	elif [ $WRITETOTTY -eq 1 -a -n "${COLOR}" ]; then
		LINE1="${COLOR}${LINE1}${NORMAL}"
	fi


	#
	# We can now output the message. We start with any required blank
	# lines, and then the first line. If this is a warning message we
	# write to the log file any additional lines.
	#

	if [ $WRITETOTTY -eq 1 ]; then
		NLLOOP=$NL
		while test $NLLOOP -gt 0; do
			echo ""
			NLLOOP=`expr ${NLLOOP} - 1`
		done

		echo $ECHOOPT "${LINE1}"
	fi

	if [ $WRITETOLOG -eq 1 ]; then
		echo $ECHOOPT "${LOGLINE1}" >>${RKHLOGFILE}

		if [ $WARN_MSG -eq 1 ]; then
			test $SHOWWARNINGSONLY -eq 1 && echo $ECHOOPT "${LOGLINE1}" | cut -d' ' -f2-

			LINE1=1
			OLDIFS="${IFS}"
			IFS=$IFSNL

			for LOGLINE1 in `grep "^${MSG}:" ${LANG_FILE} 2>/dev/null | cut -d: -f2-`; do
				if [ $LINE1 -eq 1 ]; then
					LINE1=0
					continue
				else
					test $SHOWWARNINGSONLY -eq 1 && echo $ECHOOPT "         ${LOGLINE1}"
					echo $ECHOOPT "           ${LOGLINE1}" >>${RKHLOGFILE}
				fi
			done

			IFS="${OLDIFS}"
		elif [ $SHOWWARNINGSONLY -eq 1 -a -n "`echo \"${LOGLINE1}\" | grep '^\[[0-9][0-9]:[0-9][0-9]:[0-9][0-9]\]         '`" ]; then
			echo $ECHOOPT "${LOGLINE1}" | cut -d' ' -f2-
		fi
	fi

	#
	# Output a final blank line if requested to do so.
	#

	test $WRITETOTTY -eq 1 -a $NLAFTER -eq 1 && echo ""

	return
}


keypresspause() {

	#
	# This function will display a prompt message to the user.
	#

	if [ $SKIP_KEY_PRESS -eq 0 -a $QUIET -eq 0 ]; then
		display --to SCREEN --type PLAIN --nl PRESSENTER
		read RKHTMPVAR

		test "${RKHTMPVAR}" = "s" -o "${RKHTMPVAR}" = "S" && SKIP_KEY_PRESS=1
	fi

	return
}


get_option() {

	#
	# This function is used to process configuration file options.
	#
	# Syntax: get_option <option type> [single | multi] <option name>
	#
	# Since different options require different needs, the first
	# argument is the 'type' of option we are processing. The second
	# argument is the word 'single' or 'multi'. This indicates if
	# the option can occur on one or more lines in the configuration
	# file. The third argument is the option name.
	#
	# There are currently three types defined:
	#
	# Type 1: A number, single word or pathname.
	# Type 2: A space-separated word list.
	#
	# Typically, single and double-quotes, spaces and tabs will be
	# removed. For type 2 options, tabs are converted to spaces, and
	# all spaces are squeezed into one. Leading and trailing spaces
	# are removed. All other types of options are processed separately.
	#
	# The function will output the final modified option.
	#
	# NOTE: This function is currently implemented such that if it returns
	# a non-zero code, then RKH will exit at the relevant point with a
	# return code of 1. However, the function does not currently return a
	# non-zero code at any time.
	#

	OPTTYPE="$1"
	OPTMULTI="$2"
	OPTV="$3"


	#
	# First see if the option is in the configuration file, and if
	# it is then process it according to the multi-line argument.
	#

	if [ -z "`grep \"^${OPTV}=\" ${CONFIGFILE}`" ]; then
		echo ""
		return 0
	else
		if [ "${OPTMULTI}" = "single" ]; then
			OPTVAR=`grep "^${OPTV}=" ${CONFIGFILE} | tail -1 | sed -e "s/${OPTV}=//"`
		elif [ "${OPTMULTI}" = "multi" ]; then
			OPTVAR=`grep "^${OPTV}=" ${CONFIGFILE} | sed -e "s/${OPTV}=//"`
		else
			echo "Error: Invalid multi-line argument in get_option function: $*" >&2
			# Treat this as a single-line option.
			OPTVAR=`grep "^${OPTV}=" ${CONFIGFILE} | tail -1 | sed -e "s/${OPTV}=//"`
		fi
	fi


	#
	# Now process the option.
	#

	case "$OPTTYPE" in
	1)
		OPTVAR=`echo "${OPTVAR}" | tr -d '" 	' | tr -d "'"`
		;;
	2)
		OPTVAR=`echo "${OPTVAR}" | tr ',' ' ' | tr '	' ' ' | tr -s '	'`
		OPTVAR=`echo "${OPTVAR}" | sed -e 's/^"\(.*\)"$/\1/' | sed -e "s/^'\(.*\)'$/\1/"`
		OPTVAR=`echo ${OPTVAR}`
		;;
	*)
		echo "Error: Invalid option type in get_option function: $*" >&2
		;;
	esac


	echo "${OPTVAR}"

	return 0
}


get_temp_file() {

	#
	# This function will create an empty, unique temporary file.
	#
	# It takes one argument which is the pathname for the file,
	# excluding the suffix. The function will return the pathname
	# in TEMPFILE.
	#

	TEMPFILE=""

	TEMPFILE_BASE=$1


	if [ -n "${MKTEMP_CMD}" ]; then
		TEMPFILE=`${MKTEMP_CMD} ${TEMPFILE_BASE}.XXXXXX`
	elif [ -n "$RANDOM" ]; then
		TEMPFILE="${TEMPFILE_BASE}.$RANDOM"
	elif [ $BSDOS -eq 1 ]; then
		TEMPFILE="${TEMPFILE_BASE}.`date +%s`"
	elif [ -n "`date +%N%s 2>/dev/null | grep '^[0-9][0-9]*$'`" ]; then
		TEMPFILE="${TEMPFILE_BASE}.`date +%N%s%N`"
	else
		TEMPFILE="${TEMPFILE_BASE}.`date +%Y%m%d%H%M%S`"
	fi


	#
	# Remove the file just in case it does already exist!
	#

	rm -f ${TEMPFILE} >/dev/null 2>&1

	return
}


suckit_extra_checks() {

	#
	# This function carries out some extra checks of the suckit rootkit.
	# There are 3 extra checks, but we only display the result after
	# all the checks have completed. As such we store the result of
	# each check in a variable, and display the final result based on
	# the value of those variables.
	#

	if [ $VERBOSE_LOGGING -eq 1 ]; then
		display --to LOG --type PLAIN --log-indent 2 --nl ROOTKIT_ADD_SUCKIT_LOG
	fi


	ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1`

	#
	# The first check tests the link count of the /sbin/init file.
	# We use the NLINKS variable to indicate the test result:
	#	-1 means that no stat command was available
	#	 0 means that the stat command gave an error
	#	 1 is okay
	#	>1 means that suckit may be installed
	#

	NLINKS=-1

	if [ -n "${STAT_CMD}" ]; then
		if [ -n "`echo \"${STAT_CMD}\" | grep '\.pl$'`" ]; then
			NLINKS=`${STAT_CMD} --nlink /sbin/init 2>/dev/null`
		else
			NLINKS=`${STAT_CMD} -t /sbin/init 2>/dev/null | cut -d' ' -f9`
		fi

		test -z "${NLINKS}" && NLINKS=0

		if [ $VERBOSE_LOGGING -eq 1 ]; then
			if [ $NLINKS -eq 0 ]; then
				display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_ADD_SUCKIT_LINK
			elif [ $NLINKS -eq 1 ]; then
				display --to LOG --type PLAIN --result OK --log-indent 4 ROOTKIT_ADD_SUCKIT_LINK
			else
				display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_ADD_SUCKIT_LINK
			fi
		fi
	else
		display --to LOG --type PLAIN --result SKIPPED --log-indent 4 ROOTKIT_ADD_SUCKIT_LINK
	fi


	#
	# The next test checks to see if certain files are being
	# hidden. These files have the '.xrk' or '.mem' suffix.
	# The HIDDEN variable will be used to indicate the result:
	#	<null> is okay
	#	'xrk' means that the 'xrk' suffix is hidden
	#	'mem' means that the 'mem' suffix is hidden
	#

	HIDDEN=""

	for EXT in xrk mem; do
		get_temp_file "${RKHTMPDIR}/suckitexttest"

		touch ${TEMPFILE}
		rm -f ${TEMPFILE}.${EXT} >/dev/null 2>&1
		mv ${TEMPFILE} ${TEMPFILE}.${EXT}

		if [ ! -f "${TEMPFILE}.${EXT}" ]; then
			if [ -n "${HIDDEN}" ]; then
				HIDDEN="${HIDDEN} and ${EXT}"
			else
				HIDDEN=${EXT}
			fi
		fi

		rm -f "${TEMPFILE}.${EXT}" >/dev/null 2>&1
	done

	if [ $VERBOSE_LOGGING -eq 1 ]; then
		if [ -z "${HIDDEN}" ]; then
			display --to LOG --type PLAIN --result NONE_FOUND --log-indent 4 ROOTKIT_ADD_SUCKIT_EXT
		else
			display --to LOG --type PLAIN --result FOUND --log-indent 4 ROOTKIT_ADD_SUCKIT_EXT
		fi
	fi


	#
	# Finally we perform a check using the skdet command, if it
	# is present. The SKDET variable will be used to indicate
	# the result:
	#	-1 means that skdet is not available
	#	 0 means that skdet found nothing
	#	 1 means that skdet found something
	#	 2 means that the version of skdet is unknown
	#
	# The variable SKDET_OUTPUT will contain any output from
	# the command.
	#

	SKDET=-1
	SKDET_OUTPUT=""
	SKDET_CMD=`find_cmd skdet`

	if [ -n "${SKDET_CMD}" ]; then
		#
		# We need to check the skdet version first.
		#

		SKDET=0
		SKDETOPT=""
		SKDETVER=`${SKDET_CMD} -v 2>&1 | grep '^skdet.v' | awk -F'.' '{ print $1 }'`

		case "${SKDETVER}" in
		*v0)
			SKDETOPT="-a"
			;;
		*v1)
			SKDETOPT="-c"
			;;
		*)
			SKDET=2
			SKDET_OUTPUT=`${SKDET_CMD} -v 2>&1`
			;;
		esac

		if [ $SKDET -eq 0 ]; then
			SKDET_OUTPUT=`${SKDET_CMD} ${SKDETOPT} 2>&1 | tr -s ' ' | grep -i 'invis'`

			test -n "${SKDET_OUTPUT}" && SKDET=1
		fi

		if [ $VERBOSE_LOGGING -eq 1 ]; then
			if [ $SKDET -eq 0 ]; then
				display --to LOG --type PLAIN --result OK --log-indent 4 ROOTKIT_ADD_SUCKIT_SKDET
			else
				display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_ADD_SUCKIT_SKDET
			fi
		fi
	elif [ $VERBOSE_LOGGING -eq 1 ]; then
		display --to LOG --type PLAIN --result SKIPPED --log-indent 4 ROOTKIT_ADD_SUCKIT_SKDET
		display --to LOG --type INFO NOT_FOUND_CMD "skdet"
	fi


	#
	# Now we can display the results.
	#

	if [ $NLINKS -eq 1 -a -z "${HIDDEN}" -a $SKDET -le 0 ]; then
		display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_ADD_SUCKIT
	else
		ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1`
		ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}Suckit Rookit (extra checks), "

		display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_ADD_SUCKIT

		if [ $NLINKS -eq -1 ]; then
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_ADD_SUCKIT_LINK_NOCMD
		elif [ $NLINKS -eq 0 ]; then
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_ADD_SUCKIT_LINK_ERR
		elif [ $NLINKS -gt 1 ]; then
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_ADD_SUCKIT_LINK_FOUND "$NLINKS"
		fi

		if [ -n "${HIDDEN}" ]; then
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_ADD_SUCKIT_EXT_FOUND "${HIDDEN}"
		fi

		if [ $SKDET -eq 1 ]; then
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_ADD_SUCKIT_SKDET_FOUND "${SKDET_OUTPUT}"
		elif [ $SKDET -eq 2 ]; then
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_ADD_SUCKIT_SKDET_VER "${SKDET_OUTPUT}"
		fi
	fi

	return
}


scanrootkit() {

	#
	# This function performs the actual check for a rootkit.
	# It uses the variables SCAN_ROOTKIT, SCAN_FILES, SCAN_DIRS
	# and SCAN_KSYMS. These will have been set before the
	# function is called.
	#

	SCAN_STATUS=0

	ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1`

	if [ $VERBOSE_LOGGING -eq 1 ]; then
		display --to LOG --type PLAIN --nl ROOTKIT_FILES_DIRS_NAME_LOG "${SCAN_ROOTKIT}"
	fi


	#
	# First check to see if any of the known files exist.
	#

	FILE_FOUND=""

	for RKHTMPVAR2 in ${SCAN_FILES}; do
		RKHTMPVAR=`echo "${RKHTMPVAR2}" | tr '%' ' '`

		if [ -f "${RKHTMPVAR}" ]; then
			#
			# We first check to see if the file is whitelisted. Note that we use
			# the un-translated file name. This allows us to check for filenames
			# with spaces, but without causing problems for our space-delimited test.
			#

			RKHTMPVAR3=`echo "${RKHTMPVAR2}" | sed -e 's/\./\\\./g'`

			if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \" ${RKHTMPVAR3} \"`" ]; then
				display --to LOG --type INFO FILE_PROP_WL "${RKHTMPVAR}" rootkit
			else
				SCAN_STATUS=1
				FILE_FOUND="${FILE_FOUND} ${RKHTMPVAR2}"
			fi

			test $VERBOSE_LOGGING -eq 1 && display --to LOG --type PLAIN --result FOUND --log-indent 2 ROOTKIT_FILES_DIRS_FILE "${RKHTMPVAR}"
		elif [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_FILE "${RKHTMPVAR}"
		fi
	done


	#
	# Next check to see if any of the directories exist.
	#

	DIR_FOUND=""

	for RKHTMPVAR2 in ${SCAN_DIRS}; do
		RKHTMPVAR=`echo "${RKHTMPVAR2}" | tr '%' ' '`

		if [ -d "${RKHTMPVAR}" ]; then
			#
			# We first check to see if the directory is whitelisted. Note that we use
			# the un-translated directory name. This allows us to check for directory
			# names with spaces, but without causing problems for our space-delimited test.
			#

			RKHTMPVAR3=`echo "${RKHTMPVAR2}" | sed -e 's/\./\\\./g'`

			if [ -n "`echo \"${RTKT_DIR_WHITELIST}\" | grep \" ${RKHTMPVAR3} \"`" ]; then
				display --to LOG --type INFO FILE_PROP_WL_DIR "${RKHTMPVAR}" rootkit
			else
				SCAN_STATUS=1
				DIR_FOUND="${DIR_FOUND} ${RKHTMPVAR2}"
			fi

			test $VERBOSE_LOGGING -eq 1 && display --to LOG --type PLAIN --result FOUND --log-indent 2 ROOTKIT_FILES_DIRS_DIR "${RKHTMPVAR}"
		elif [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_DIR "${RKHTMPVAR}"
		fi
	done


	#
	# Next check the ksyms or kallsyms file.
	#

	KSYM_FOUND=""

	if [ -n "${SCAN_KSYMS}" ]; then
		for KS in ${SCAN_KSYMS}; do
			if [ -n "${KSYMS_FILE}" ]; then
				KSYM=`echo "${KS}" | sed -e 's/\./\\\./g'`

				if [ -n "`grep \"${KSYM}\" ${KSYMS_FILE}`" ]; then
					SCAN_STATUS=1
					KSYM_FOUND="${KSYM_FOUND} ${KS}"

					test $VERBOSE_LOGGING -eq 1 && display --to LOG --type PLAIN --result FOUND  --log-indent 2 ROOTKIT_FILES_DIRS_KSYM "${KS}"
				elif [ $VERBOSE_LOGGING -eq 1 ]; then
					display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_KSYM "${KS}"
				fi
			elif [ $VERBOSE_LOGGING -eq 1 ]; then
				display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_FILES_DIRS_KSYM "${KS}"
			fi
		done
	fi


	#
	# Now display the results.
	#

	if [ $SCAN_STATUS -eq 0 ]; then
		display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --screen-indent 4 NAME "${SCAN_ROOTKIT}"
	else
		ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1`
		ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${SCAN_ROOTKIT}, "

		display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}"


		#
		# Log any files, directories or ksyms found.
		#

		for RKHTMPVAR in ${FILE_FOUND}; do
			RKHTMPVAR=`echo "${RKHTMPVAR}" | tr '%' ' '`
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_FILE_FOUND "${RKHTMPVAR}"
		done

		for RKHTMPVAR in ${DIR_FOUND}; do
			RKHTMPVAR=`echo "${RKHTMPVAR}" | tr '%' ' '`
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_DIR_FOUND "${RKHTMPVAR}"
		done

		for RKHTMPVAR in ${KSYM_FOUND}; do
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_KSYM_FOUND "${RKHTMPVAR}"
		done
	fi

	return
}


check_required_commands() {

	#
	# This function checks that some required commands are
	# present on the system. The function takes one argument
	# which is a list of directories to look in.
	#

	for CMD in ${REQCMDS}; do
		SEEN=0

		for DIR in $1; do
			if [ -f "${DIR}/${CMD}" -a -x "${DIR}/${CMD}" ]; then
				SEEN=1
				break
			fi
		done

		if [ $SEEN -eq 0 ]; then
			echo "The command '$CMD' must be present on the system in order to run rkhunter."
			exit 1
		fi
	done

	return
}


check_commands() {

	#
	# We check for some commands used in the tests. If the command
	# is found then a variable including the command name is set.
	# These commands are not 'required', so nothing happens if the
	# command is not found. The commands can be defined in the
	# configuration file, and a value of 'DISABLED' will cause a
	# command to not exist. A value of 'BUILTIN' may be used for
	# the 'stat' and 'readlink' commands, to indicate that the
	# supplied scripts should be used. We have to handle the 'stat'
	# command in a special way so that the perl module does not get
	# used if the command is to be disabled.
	#

	for CMD in ${CMDLIST}; do
		RKHTMPVAR=`echo ${CMD} | tr '[a-z]' '[A-Z]'`
		RKHTMPVAR="${RKHTMPVAR}_CMD"


		#
		# See if the user has defined the command in
		# the configuration file.
		#

		CFG_CMD=`get_option 2 single "${RKHTMPVAR}"` || exit 1

		if [ -n "${CFG_CMD}" ]; then
			if [ "${CFG_CMD}" = "DISABLED" -o "${CFG_CMD}" = "BUILTIN" ]; then
				eval ${RKHTMPVAR}=\"${CFG_CMD}\"
			else
				#
				# Check that the command is executable.
				#

				MCMD=`echo "${CFG_CMD}" | cut -d' ' -f1`

				if [ -n "`find_cmd ${MCMD}`" ]; then
					eval ${RKHTMPVAR}=\"${CFG_CMD}\"
				else
					CFG_CMD=""
				fi
			fi
		fi


		#
		# If the command has not been predefined, or is not
		# executable, then go find the command to use.
		#

		test -z "${CFG_CMD}" && eval ${RKHTMPVAR}=`find_cmd ${CMD}`
	done


	#
	# If we cannot find a 'stat' command, or the supplied script is to
	# be used, then we must check to see if perl is available. If it is,
	# then the supplied 'stat' script can be used.
	#

	if [ -n "${PERL_CMD}" -a "${PERL_CMD}" != "DISABLED" ]; then
		if [ -z "${STAT_CMD}" -o "${STAT_CMD}" = "BUILTIN" ]; then
			if [ -r "${SCRIPT_PATH}/check_modules.pl" ]; then
				MOD_INSTALLED=`${PERL_CMD} ${SCRIPT_PATH}/check_modules.pl File::stat Getopt::Long 2>&1 | grep 'NOT installed'`
			else
				MOD_INSTALLED="module not found"
			fi

			if [ -z "${MOD_INSTALLED}" -a -r "${SCRIPT_PATH}/stat.pl" ]; then
				STAT_CMD="${PERL_CMD} ${SCRIPT_PATH}/stat.pl"
			else
				STAT_CMD=""
			fi
		fi
	elif [ "${STAT_CMD}" = "BUILTIN" ]; then
		STAT_CMD=""
	fi


	#
	# If the readlink command cannot be found, or it does not support
	# the '-f' option, then we must use the supplied shell script.
	#

	if [ -z "${READLINK_CMD}" -o "${READLINK_CMD}" = "BUILTIN" ]; then
		test -x "${SCRIPT_PATH}/readlink.sh" && READLINK_CMD="${SCRIPT_PATH}/readlink.sh"
	elif [ -n "`${READLINK_CMD} -f ${SCRIPT_PATH}/readlink.sh 2>&1 >/dev/null`" ]; then
		if [ -x "${SCRIPT_PATH}/readlink.sh" ]; then
			READLINK_CMD="${SCRIPT_PATH}/readlink.sh"
		else
			READLINK_CMD=""
		fi
	fi


	#
	# Finally we must remove all the DISABLED commands.
	#

	for CMD in ${CMDLIST}; do
		RKHTMPVAR=`echo ${CMD} | tr '[a-z]' '[A-Z]'`
		RKHTMPVAR="${RKHTMPVAR}_CMD"
		RKHTMPVAR2=`eval echo "\\$${RKHTMPVAR}"`

		test "${RKHTMPVAR2}" = "DISABLED" -o "${RKHTMPVAR2}" = "BUILTIN" && eval ${RKHTMPVAR}=\"\"
	done

	return
}


get_installdir_option() {

	#
	# This function obtains the RKH installation directory. It must
	# be set by the installer script, and has no default.
	#

	RKHINSTALLDIR=`get_option 1 single INSTALLDIR` || exit 1

	if [ -z "${RKHINSTALLDIR}" ]; then
		echo "Invalid INSTALLDIR configuration option - no installation directory specified."
		exit 1
	elif [ ! -d "${RKHINSTALLDIR}" ]; then
		echo "Installation directory does not exist: ${RKHINSTALLDIR}"
		exit 1
	elif [ ! -r "${RKHINSTALLDIR}" ]; then
		echo "Installation directory is not readable: ${RKHINSTALLDIR}"
		exit 1
	fi

	return
}


get_language_option() {

	#
	# First get the option from the command-line or the
	# configuration file, and do a simple check on whether
	# it is empty or a space.
	#

	if [ -n "${LANGUAGE}" ]; then
		LANGUAGE=`echo "${LANGUAGE}" | tr -d '" 	' | tr -d "'"`

		if [ -z "${LANGUAGE}" ]; then
			echo "Invalid --language option - no language given."
			exit 1
		fi
	else
		LANGUAGE=`get_option 1 single LANGUAGE` || exit 1
	fi

	#
	# If no language has been set, then use English.
	#

	test -z "${LANGUAGE}" && LANGUAGE="en"


	#
	# Now check that the language is available.
	#

	if [ ! -d "${DB_PATH}/i18n" ]; then
		echo "The internationalisation directory does not exist: ${DB_PATH}/i18n"
		exit 1
	fi

	#
	# If we are using the '--update' option, then the language files
	# will be installed if they are missing. As such, we cannot check
	# them here.
	#

	if [ ! -s "${DB_PATH}/i18n/${LANGUAGE}" ]; then
		if [ $UPDATE_ONLY -eq 1 ]; then
			RKHLANGUPDT=1
		else
			echo "The language specified is not available: ${LANGUAGE}"
			echo "Use the command 'rkhunter --lang en --list languages' to see the list of available languages."
			exit 1
		fi
	elif [ ! -s "${DB_PATH}/i18n/en" ]; then
		if [ $UPDATE_ONLY -eq 1 ]; then
			RKHLANGUPDT=1
		else
			echo "The English language file must be present: ${DB_PATH}/i18n/en"
			echo "If it has been deleted, then you will need to run 'rkhunter --update' with no other options."
			exit 1
		fi
	fi

	return
}


get_logfile_option() {

	#
	# First get the option from the command-line or the
	# configuration file, and do a simple check on whether
	# it is empty or a space.
	#

	if [ -n "${RKHLOGFILE}" ]; then
		RKHLOGFILE=`echo "${RKHLOGFILE}" | tr -d '" 	' | tr -d "'"`

		if [ -z "${RKHLOGFILE}" ]; then
			echo "Invalid --logfile option - no logfile name given."
			exit 1
		fi
	else
		RKHLOGFILE=`get_option 1 single LOGFILE` || exit 1

		if [ -z "${RKHLOGFILE}" ]; then
			RKHLOGFILE="${DFLT_LOGFILE}"
			echo "Default logfile will be used (${RKHLOGFILE})."
		fi
	fi

	#
	# Now check that the given option is useable.
	#

	if [ "${RKHLOGFILE}" = "/dev/null" ]; then
		APPEND_LOG=0
	else
		LOGDIR=`echo "${RKHLOGFILE}" | sed -e 's/\/[^/][^/]*$//'`

		if [ -z "`echo \"${LOGDIR}\" | grep '/'`" ]; then
			LOGDIR="."
		fi

		if [ "${LOGDIR}" = "${RKHLOGFILE}" ]; then
			echo "No log filename given: ${RKHLOGFILE}"
			exit 1
		elif [ ! -d "${LOGDIR}" ]; then
			echo "Logfile directory does not exist: ${RKHLOGFILE}"
			exit 1
		elif [ ! -w "${LOGDIR}" ]; then
			echo "Logfile directory is not writable: ${RKHLOGFILE}"
			exit 1
		elif [ ! -r "${LOGDIR}" ]; then
			echo "Logfile directory is not readable: ${RKHLOGFILE}"
			exit 1
		elif [ -h "${RKHLOGFILE}" ]; then
			echo "Logfile is a symbolic link: ${RKHLOGFILE}"
			echo "This is a security problem. The link points to another file, and that file is about to be modified by rkhunter."
			exit 1
		elif [ -e "${RKHLOGFILE}" -a ! -f "${RKHLOGFILE}" ]; then
			echo "Logfile already exists but it is not a file: ${RKHLOGFILE}"
			exit 1
		fi

		#
		# Now check whether we should append to the logfile
		# or overwrite it. We check the configuration file
		# option, if it is given, and ensure that it is valid.
		#

		if [ $APPEND_OPT -eq 0 ]; then
			APPEND_LOG=`get_option 1 single APPEND_LOG` || exit 1

			if [ -n "${APPEND_LOG}" ]; then
				if [ "${APPEND_LOG}" != "0" -a "${APPEND_LOG}" != "1" ]; then
					echo "Invalid APPEND_LOG configuration option: not a number: ${APPEND_LOG}"
					exit 1
				fi
			else
				APPEND_LOG=0
			fi
		fi
	fi

	return
}


get_tmpdir_option() {

	#
	# First get the option from the command-line or the
	# configuration file, and do a simple check on whether
	# it is empty or a space.
	#

	if [ -n "${RKHTMPDIR}" ]; then
		RKHTMPDIR=`echo "${RKHTMPDIR}" | tr -d '" 	' | tr -d "'"`

		if [ -z "${RKHTMPDIR}" ]; then
			echo "Invalid --tmpdir option - no directory name given."
			exit 1
		fi
	else
		RKHTMPDIR=`get_option 1 single TMPDIR` || exit 1

		if [ -z "${RKHTMPDIR}" ]; then
			RKHTMPDIR="${RKHINSTALLDIR}/lib/rkhunter/tmp"
			echo "Default temporary directory will be used (${RKHTMPDIR})."
		fi
	fi

	#
	# Now check that the given option is useable.
	#

	if [ ! -d "${RKHTMPDIR}" ]; then
		echo "Temporary directory does not exist: ${RKHTMPDIR}"
		exit 1
	elif [ ! -w "${RKHTMPDIR}" ]; then
		echo "Temporary directory is not writable: ${RKHTMPDIR}"
		exit 1
	elif [ ! -r "${RKHTMPDIR}" ]; then
		echo "Temporary directory is not readable: ${RKHTMPDIR}"
		exit 1
	elif [ "${RKHTMPDIR}" = "${RKHROOTDIR}/tmp" -o "${RKHTMPDIR}" = "${RKHROOTDIR}/var/tmp" ]; then
		echo "Do not use ${RKHTMPDIR} as the temporary directory."
		echo "This directory will be used by rkhunter to contain system files, so it must be secure."
		exit 1
	elif [ "${RKHTMPDIR}" = "${RKHROOTDIR}/etc" ]; then
		echo "Do not use ${RKHTMPDIR} as the temporary directory."
		echo "This directory will be used by rkhunter to copy and delete certain system files."
		exit 1
	fi

	return
}


get_dbdir_option() {

	#
	# First get the option from the command-line or the
	# configuration file, and do a simple check on whether
	# it is empty or a space.
	#

	if [ -n "${DB_PATH}" ]; then
		DB_PATH=`echo "${DB_PATH}" | tr -d '" 	' | tr -d "'"`

		if [ -z "${DB_PATH}" ]; then
			echo "Invalid --dbdir option - no directory name given."
			exit 1
		fi
	else
		DB_PATH=`get_option 1 single DBDIR` || exit 1

		if [ -z "${DB_PATH}" ]; then
			DB_PATH="${RKHINSTALLDIR}/lib/rkhunter/db"
			echo "Default database directory will be used (${DB_PATH})."
		fi
	fi

	#
	# Now check that the given option is useable.
	#

	if [ ! -d "${DB_PATH}" ]; then
		echo "Database directory does not exist: ${DB_PATH}"
		exit 1
	elif [ ! -w "${DB_PATH}" ]; then
		echo "Database directory is not writable: ${DB_PATH}"
		exit 1
	elif [ ! -r "${DB_PATH}" ]; then
		echo "Database directory is not readable: ${DB_PATH}"
		exit 1
	fi

	return
}


add_extra_dirs() {

	#
	# This functions takes care of any additional directories
	# that may exist on some systems. After the function is called
	# the value of EXTRA_DIRS must be added to whatever variable
	# is being used.
	#

	EXTRA_DIRS=""

	if [ $SUNOS -eq 1 ]; then
		#
		# Add in some other directories, and those which
		# contain the Sun 'companion' software.
		#

		test -d /usr/sfw && EXTRA_DIRS="${EXTRA_DIRS} /usr/sfw/bin /usr/sfw/sbin /usr/sfw/libexec"
		test -d /opt/sfw && EXTRA_DIRS="${EXTRA_DIRS} /opt/sfw/bin /opt/sfw/sbin /opt/sfw/libexec"
		test -d /usr/xpg4/bin && EXTRA_DIRS="${EXTRA_DIRS} /usr/xpg4/bin"
		test -d /usr/ccs/bin && EXTRA_DIRS="${EXTRA_DIRS} /usr/ccs/bin"
		test -d /usr/5bin -a ! -h /usr/5bin && EXTRA_DIRS="${EXTRA_DIRS} /usr/5bin"
		test -d /usr/ucb && EXTRA_DIRS="${EXTRA_DIRS} /usr/ucb"


		#
		# OpenSolaris distributions (e.g. BeleniX) may use
		# other directories.
		#

		test -d /usr/foss && EXTRA_DIRS="${EXTRA_DIRS} /usr/foss/bin /usr/foss/sbin /usr/foss/libexec"
	elif [ $BSDOS -eq 1 ]; then
		test -d /usr/pkg/bin && EXTRA_DIRS="${EXTRA_DIRS} /usr/pkg/bin"
		test -d /usr/pkg/sbin && EXTRA_DIRS="${EXTRA_DIRS} /usr/pkg/sbin"
		test -d /usr/pkg/libexec && EXTRA_DIRS="${EXTRA_DIRS} /usr/pkg/libexec"
	elif [ "${OPERATING_SYSTEM}" = "Darwin" ]; then
		#
		# Cater for Fink (Mac OS X) additional software.
		#

		test -d /sw/bin && EXTRA_DIRS="${EXTRA_DIRS} /sw/bin"
		test -d /sw/sbin && EXTRA_DIRS="${EXTRA_DIRS} /sw/sbin"
	elif [ $IRIXOS -eq 1 ]; then
		test -d /usr/ucb && EXTRA_DIRS="${EXTRA_DIRS} /usr/ucb"
		test -d /usr/freeware/bin && EXTRA_DIRS="${EXTRA_DIRS} /usr/freeware/bin"
		test -d /usr/freeware/sbin && EXTRA_DIRS="${EXTRA_DIRS} /usr/freeware/sbin"
		test -d /usr/xpg4/bin && EXTRA_DIRS="${EXTRA_DIRS} /usr/xpg4/bin"
	elif [ -f "/etc/GoboLinuxVersion" ]; then
		#
		# We have no other easy way of detecting GoboLinux.
		# It has a peculiar filesystem layout, so we need to
		# add in this little bit of support to help it work
		# with RKH.
		#

		test -d "/System/Links/Executables" && EXTRA_DIRS="/System/Links/Executables"
	fi


	#
	# Finally check if there are any optional
	# bin and sbin directories present.
	#

	test -d /usr/opt/bin && EXTRA_DIRS="${EXTRA_DIRS} /usr/opt/bin"
	test -d /usr/opt/sbin && EXTRA_DIRS="${EXTRA_DIRS} /usr/opt/sbin"
	test -d /opt/bin && EXTRA_DIRS="${EXTRA_DIRS} /opt/bin"
	test -d /opt/sbin && EXTRA_DIRS="${EXTRA_DIRS} /opt/sbin"

	return
}


get_bindir_option() {

	#
	# First get the option from the command-line or the
	# configuration file, and do a simple check on whether
	# it is empty or a space.
	#

	USE_DFLT=0

	if [ -n "${BINPATHS}" ]; then
		BINPATHS=`echo "${BINPATHS}" | tr -d '"' | tr -d "'" | tr '	' ' ' | tr -s ' '`

		if [ "${BINPATHS}" = " " ]; then
			echo "Invalid --bindir option - no directory names given."
			exit 1
		fi
	else
		BINPATHS=`get_option 2 single BINDIR` || exit 1

		if [ -z "${BINPATHS}" ]; then
			USE_DFLT=1

			BINPATHS="${DFLT_BINPATHS}"


			#
			# Under some OS's /bin is a link to /usr/bin, so
			# there is no need to look in it.
			#

			if [ $SUNOS -eq 1 -o $IRIXOS -eq 1 -o "${OPERATING_SYSTEM}" = "AIX" ]; then
				if [ -h /bin ]; then
					RKHB=""

					for DIR in ${BINPATHS}; do
						test "${DIR}" != "/bin" && RKHB="${RKHB} ${DIR}"
					done

					BINPATHS=`echo ${RKHB}`
				fi
			fi


			add_extra_dirs
			BINPATHS="${BINPATHS}${EXTRA_DIRS}"
		fi
	fi


	#
	# This is a simple check that each directory begins with
	# a '.' or '/'. We allow non-existent directories because
	# this list may be used with RKHROOTDIR. As such the directory
	# may not exist on the local host, but may exist on a
	# remotely diagnosed system.
	#

	for DIR in ${BINPATHS}; do
		if [ -z "`echo ${DIR} | grep '^[./]'`" ]; then
			echo "Invalid BINDIR directory found: ${DIR}"
			exit 1
		fi
	done

	return
}


get_scriptdir_option() {

	#
	# Get the value from the configuration file, and do a simple
	# check on whether it is empty or a space.
	#
	# Note: The installer will set this option. As such there
	# is no default.
	#

	SCRIPT_PATH=`get_option 1 single SCRIPTDIR` || exit 1

	if [ -z "${SCRIPT_PATH}" ]; then
		echo "The SCRIPTDIR configuration option has not been set by the installer."
		exit 1
	fi

	#
	# Now check that the given option is useable.
	#

	if [ ! -d "${SCRIPT_PATH}" ]; then
		echo "Script directory does not exist: ${SCRIPT_PATH}"
		exit 1
	elif [ ! -r "${SCRIPT_PATH}" ]; then
		echo "Script directory is not readable: ${SCRIPT_PATH}"
		exit 1
	fi

	return
}


find_cmd() {

	#
	# This function performs a search of the PATH and BINPATHS
	# directories looking for the requested command. The full
	# pathname is returned if the command is found.
	#
	# If a full pathname is provided then we simply check that
	# it is executable.
	#

	CMD=$1

	test -z "${CMD}" && return

	if [ -n "`echo ${CMD} | grep '/'`" ]; then
		test -f "${CMD}" -a -x "${CMD}" && echo "${CMD}"
	else
		for CMDDIR in ${SPACEDPATH} ${BINPATHS}; do
			if [ -f "${CMDDIR}/${CMD}" -a -x "${CMDDIR}/${CMD}" ]; then
				echo "${CMDDIR}/${CMD}"
				return
			fi
		done
	fi

	return
}


get_rootdir_option() {

	#
	# First get the option from the command-line or the
	# configuration file, and do a simple check on whether
	# it is empty or a space.
	#

	if [ -n "${RKHROOTDIR}" ]; then
		RKHROOTDIR=`echo "${RKHROOTDIR}" | tr -d '" 	' | tr -d "'"`

		if [ -z "${RKHROOTDIR}" ]; then
			echo "Invalid --rootdir option - no directory name given."
			exit 1
		fi
	else
		RKHROOTDIR=`get_option 1 single ROOTDIR` || exit 1
	fi

	#
	# Now check that the given option is useable.
	#

	if [ -n "${RKHROOTDIR}" ]; then
		if [ ! -d "${RKHROOTDIR}" ]; then
			echo "The root directory does not exist: ${RKHROOTDIR}"
			exit 1
		elif [ ! -r "${RKHROOTDIR}" ]; then
			echo "The root directory is not readable: ${RKHROOTDIR}"
			exit 1
		fi
	fi

	return
}


get_mailonwarn_option() {

	#
	# Get the option from the configuration file. If it is set,
	# then we get the MAIL_CMD option as well.
	#

	MAILONWARNING=`get_option 2 single MAIL-ON-WARNING` || exit 1

	if [ -n "${MAILONWARNING}" ]; then
		MAIL_CMD=`get_option 2 single MAIL_CMD` || exit 1

		test -z "${MAIL_CMD}" && MAIL_CMD="mail -s \"[rkhunter] Warnings found for \${HOST_NAME}\""


		#
		# Check that the mail command is executable.
		#

		MCMD=`echo "${MAIL_CMD}" | cut -d' ' -f1`
		MC=`find_cmd ${MCMD}`

		if [ -n "${MC}" ]; then
			#
			# We rebuild the command to use the full pathname.
			#

			MCMD=`echo "${MAIL_CMD}" | cut -d' ' -f2-`

			if [ -z "${MCMD}" -o "${MCMD}" = "${MAIL_CMD}" ]; then
				MAIL_CMD=$MC
			else
				MAIL_CMD="${MC} ${MCMD}"
			fi
		else
			echo "Invalid MAIL_CMD configuration option - command '${MCMD}' is non-existent or not executable."
			exit 1
		fi
	fi

	return
}


get_syslog_option() {

	#
	# First see if we want to use syslog or not from the command-line
	# or configuration file.
	#

	if [ -n "${USE_SYSLOG}" ]; then
		USE_SYSLOG=`echo "${USE_SYSLOG}" | tr -d '" 	' | tr -d "'"`

		if [ -z "${USE_SYSLOG}" ]; then
			echo "Invalid --syslog option - no facility/priority names given."
			exit 1
		fi
	else
		USE_SYSLOG=`get_option 1 single USE_SYSLOG` || exit 1
	fi


	#
	# If we are to use syslog, then get the facility and priority levels.
	# Additionally, test that they are valid.
	#

	if [ -n "${USE_SYSLOG}" ]; then
		USE_SYSLOG=`echo "${USE_SYSLOG}" | tr '[A-Z]' '[a-z]'`

		if [ "${USE_SYSLOG}" = "none" ]; then
			# The value of 'none' will be processed later on.
			return
		elif [ -z "`echo \"${USE_SYSLOG}\" | grep '^[a-z][a-z0-7]*\.[a-z][a-z]*$'`" ]; then
			echo "Invalid syslog facility/priority value: ${USE_SYSLOG}"
			exit 1
		fi

		FOUND=0

		SYSLOG_F=`echo "${USE_SYSLOG}" | cut -d. -f1`
		SYSLOG_P=`echo "${USE_SYSLOG}" | cut -d. -f2`

		for RKHTMPVAR in auth authpriv cron daemon kern user local0 local1 local2 local3 local4 local5 local6 local7; do
			if [ "${SYSLOG_F}" = "${RKHTMPVAR}" ]; then
				FOUND=1
				break
			fi
		done

		if [ $FOUND -eq 0 ]; then
			echo "Invalid syslog facility name: ${SYSLOG_F}"
			exit 1
		fi


		FOUND=0

		for RKHTMPVAR in debug info notice warning err crit alert emerg; do
			if [ "${SYSLOG_P}" = "${RKHTMPVAR}" ]; then
				FOUND=1
				break
			fi
		done

		if [ $FOUND -eq 0 ]; then
			echo "Invalid syslog priority name: ${SYSLOG_P}"
			exit 1
		fi
	fi

	return
}


get_ssh_options() {

	#
	# We check some SSH options in this function. They can only
	# be set in the configuration file.
	#

	#
	# See if the ALLOW_SSH_ROOT_USER option is specified in the
	# configuration file. The value should match what has been set
	# in the SSH configuration file for the PermitRootLogin option.
	# As such it's value is not just zero or one.
	#

	ALLOW_SSH_ROOT_USER=`get_option 1 single ALLOW_SSH_ROOT_USER` || exit 1

	if [ -n "${ALLOW_SSH_ROOT_USER}" ]; then
		ALLOW_SSH_ROOT_USER=`echo "${ALLOW_SSH_ROOT_USER}" | tr '[A-Z]' '[a-z]'`
	else
		#
		# By default SSH tends to allow root access. However, we
		# do not. By setting this option to 'no', the user will
		# receive a warning unless they set the options the same.
		#

		ALLOW_SSH_ROOT_USER="no"
	fi


	#
	# See if the ALLOW_SSH_PROT_V1 option is specified in the
	# configuration file.
	#

	ALLOW_SSH_PROT_V1=`get_option 1 single ALLOW_SSH_PROT_V1` || exit 1

	if [ -n "${ALLOW_SSH_PROT_V1}" ]; then
		if [ "${ALLOW_SSH_PROT_V1}" != "0" -a "${ALLOW_SSH_PROT_V1}" != "1" -a "${ALLOW_SSH_PROT_V1}" != "2" ]; then
			echo "Invalid ALLOW_SSH_PROT_V1 configuration option: not a valid number: ${ALLOW_SSH_PROT_V1}"
			exit 1
		fi
	else
		ALLOW_SSH_PROT_V1=0
	fi


	#
	# See if the directory of the SSH configuration file has been set.
	#

	SSH_CONFIG_DIR=`get_option 1 single SSH_CONFIG_DIR` || exit 1

	if [ -n "${SSH_CONFIG_DIR}" ]; then
		if [ ! -d "${SSH_CONFIG_DIR}" ]; then
			echo "The SSH configuration file directory does not exist: ${SSH_CONFIG_DIR}"
			exit 1
		elif [ ! -r "${SSH_CONFIG_DIR}" ]; then
			echo "The SSH configuration file directory is not readable: ${SSH_CONFIG_DIR}"
			exit 1
		fi
	fi

	return
}


get_syslog_config_options() {

	#
	# We check some syslog configuration options in this function.
	# They can only be set in the configuration file.
	#

	#
	# See if the ALLOW_SYSLOG_REMOTE_LOGGING option is specified
	# in the configuration file.
	#

	ALLOW_SYSLOG_REMOTE_LOGGING=`get_option 1 single ALLOW_SYSLOG_REMOTE_LOGGING` || exit 1

	if [ -n "${ALLOW_SYSLOG_REMOTE_LOGGING}" ]; then
		if [ "${ALLOW_SYSLOG_REMOTE_LOGGING}" != "0" -a "${ALLOW_SYSLOG_REMOTE_LOGGING}" != "1" ]; then
			echo "Invalid ALLOW_SYSLOG_REMOTE_LOGGING configuration option: not a number: ${ALLOW_SYSLOG_REMOTE_LOGGING}"
			exit 1
		fi
	else
		ALLOW_SYSLOG_REMOTE_LOGGING=0
	fi


	#
	# See if the pathname to the syslog configuration file has been set.
	#

	SYSLOG_CONFIG_FILE=`get_option 1 single SYSLOG_CONFIG_FILE` || exit 1


	return
}


get_auto_x_option() {

	#
	# For the second colour set we first see if the auto X detect option
	# has been set. If it is set, and X is in use, then the second colour
	# set is used. If X is not in use, or the auto detect option is not
	# set, then we only use the second colour set if the command-line
	# option is used or it is configured in the configuration file.
	#

	if [ $AUTO_X_OPT -eq 0 ]; then
		AUTO_X_DTCT=`get_option 1 single AUTO_X_DETECT` || exit 1

		if [ -n "${AUTO_X_DTCT}" ]; then
			if [ "${AUTO_X_DTCT}" != "0" -a "${AUTO_X_DTCT}" != "1" ]; then
				echo "Invalid AUTO_X_DETECT configuration option: not a number: ${AUTO_X_DTCT}"
				exit 1
			fi
		else
			AUTO_X_DTCT=0
		fi
	fi


	if [ $AUTO_X_DTCT -eq 1 -a -n "$DISPLAY" ]; then
		CLRSET2=1
	fi


	if [ $CLRSET2 -eq 0 ]; then
		CLRSET2=`get_option 1 single COLOR_SET2` || exit 1

		if [ -n "${CLRSET2}" ]; then
			if [ "${CLRSET2}" != "0" -a "${CLRSET2}" != "1" ]; then
				echo "Invalid COLOR_SET2 configuration option: not a number: ${CLRSET2}"
				exit 1
			fi
		else
			CLRSET2=0
		fi
	fi

	return
}


get_enable_option() {

	#
	# If the option is not specified on the command-line, then
	# get it from the configuration file. We validate the test
	# names given against the list of known test names. By default
	# all tests are enabled.
	#

	if [ $ENDIS_OPT -eq 1 ]; then
		if [ -n "${ENABLE_TESTS}" ]; then
			ENABLE_TESTS=`echo "${ENABLE_TESTS}" | tr -d '"' | tr -d "'" | tr ',' ' ' | tr '	' ' ' | tr -s ' '`
			ENABLE_TESTS=`echo "${ENABLE_TESTS}" | sed -e 's/^ //' | sed -e 's/ $//'`

			if [ -z "${ENABLE_TESTS}" ]; then
				echo "Invalid --enable option - no test names given."
				exit 1
			else
				ENABLE_TESTS=`echo "${ENABLE_TESTS}" | tr '[A-Z]' '[a-z]'`
			fi


			#
			# We do a simple test here to see if just one test
			# name was given. If it was then we skip the key
			# press feature since it is most likely that the user
			# doesn't want that. We also check that only the
			# --enable option has been given, and that the test
			# name is not 'all'.
			#

			if [ "${ENABLE_TESTS}" != "all" -a -z "`echo \"${ENABLE_TESTS}\" | grep ' '`" ]; then
				SKIP_KEY_PRESS=1
			fi
		fi
	else
		ENABLE_TESTS=`get_option 2 single ENABLE_TESTS` || exit 1
		ENABLE_TESTS=`echo "${ENABLE_TESTS}" | tr '[A-Z]' '[a-z]'`
	fi

	test -z "${ENABLE_TESTS}" && ENABLE_TESTS="all"


	#
	# We now need to look for group names in our list, and expand
	# them to the individual test names. This allows us to then
	# check against specific test names as well as group names.
	# We also need to check if a given test name is part of a group.
	# If it is, then we must add the group name.
	#

	for TEST_NAME in ${ENABLE_TESTS}; do
		if [ "${TEST_NAME}" = "all" ]; then
			ENABLE_TESTS="all"
			break
		fi

		for RKHTMPVAR in ${GROUPED_TESTS}; do
			GROUP_NAME=`echo "${RKHTMPVAR}" | cut -d: -f1`

			if [ -n "`echo \"${RKHTMPVAR}\" | grep ':'`" ]; then
				GROUP_TESTS=`echo "${RKHTMPVAR}" | cut -d: -f2-`
			else
				GROUP_TESTS=""
			fi

			if [ "${TEST_NAME}" = "${GROUP_NAME}" ]; then
				ENABLE_TESTS="${ENABLE_TESTS} `echo \"${GROUP_TESTS}\" | tr ':' ' '`"
				break
			elif [ -z "${GROUP_TESTS}" ]; then
				continue
			elif [ -n "`echo \"${GROUP_TESTS}\" | egrep \"(^|:)${TEST_NAME}(:|$)\"`" ]; then
				ENABLE_TESTS="${ENABLE_TESTS} ${GROUP_NAME}"
			fi
		done
	done


	#
	# Check that the names we have been given are valid.
	#

	for TEST_NAME in ${ENABLE_TESTS}; do
		if [ "${TEST_NAME}" = "none" ]; then
			echo "'none' cannot be used in the enable test list."
			exit 1
		elif [ -z "`echo \"all ${KNOWN_TESTS}\" | egrep \"(^| )${TEST_NAME}( |$)\"`" ]; then
			echo "Unknown enable test name given: ${TEST_NAME}"
			exit 1
		fi
	done

	return
}


get_disable_option() {

	#
	# If the option is not specified on the command-line, then
	# get it from the configuration file. We validate the test
	# names given against the list of known test names. By default
	# no tests are disabled.
	#
	# Note: disabled tests are always compared against the list
	# of enabled tests. Hence, if we used
	#      'rkhunter -c --enable system_commands --disable apps'
	# then only the system command tests are run. Any other test is
	# not run because it is not in the '--enable' list. As such
	# the '--disable' option in the example above is not necessary.
	#

	if [ $ENDIS_OPT -eq 1 ]; then
		if [ -n "${DISABLE_TESTS}" ]; then
			DISABLE_TESTS=`echo "${DISABLE_TESTS}" | tr -d '"' | tr -d "'" | tr ',' ' ' | tr '	' ' ' | tr -s ' '`
			DISABLE_TESTS=`echo "${DISABLE_TESTS}" | sed -e 's/^ //' | sed -e 's/ $//'`

			if [ -z "${DISABLE_TESTS}" ]; then
				echo "Invalid --disable option - no test names given."
				exit 1
			fi
		fi
	else
		DISABLE_TESTS=`get_option 2 single DISABLE_TESTS` || exit 1
	fi

	if [ -z "${DISABLE_TESTS}" ]; then
		DISABLE_TESTS="none"
	else
		DISABLE_TESTS=`echo "${DISABLE_TESTS}" | tr '[A-Z]' '[a-z]'`
	fi


	#
	# Note that we do not need to check the disabled test names
	# against the group names. If a disabled test name does not appear
	# in the enabled list then it will, by default, be ignored. If
	# a group name appears in the enabled and disabled lists, then
	# it will be disabled.
	#
	# Check that the names we have been given are valid.
	#

	for TEST_NAME in ${DISABLE_TESTS}; do
		if [ "${TEST_NAME}" = "all" ]; then
			echo "'all' cannot be used in the disable test list."
			exit 1
		elif [ "${TEST_NAME}" = "none" ]; then
			DISABLE_TESTS="none"
			break
		elif [ -z "`echo \"all none ${KNOWN_TESTS}\" | egrep \"(^| )${TEST_NAME}( |$)\"`" ]; then
			echo "Unknown disable test name given: ${TEST_NAME}"
			exit 1
		fi
	done

	return
}


get_xinetd_option() {

	#
	# This function obtains the inetd and xinetd configuration
	# file pathnames from the config file. It also get the
	# whitelisted services.
	#

	FNAME=`get_option 1 single INETD_CONF_PATH` || exit 1

	if [ -n "${FNAME}" ]; then
		INETD_CONF_PATH="${FNAME}"

		if [ ! -f "${INETD_CONF_PATH}" ]; then
			echo "Invalid INETD_CONF_PATH configuration option - non-existent pathname specified."
			exit 1
		fi
	fi

	INETDALLOWEDSVCS=`get_option 1 multi INETD_ALLOWED_SVC` || exit 1


	#
	# Now do the same for xinetd.
	#

	FNAME=`get_option 1 single XINETD_CONF_PATH` || exit 1

	if [ -n "${FNAME}" ]; then
		XINETD_CONF_PATH="${FNAME}"

		if [ ! -f "${XINETD_CONF_PATH}" ]; then
			echo "Invalid XINETD_CONF_PATH configuration option - non-existent pathname specified."
			exit 1
		fi
	fi

	XINETDALLOWEDSVCS=`get_option 1 multi XINETD_ALLOWED_SVC` || exit 1

	return
}


get_ports_option() {

	#
	# Get the option from the configuration file, and do some
	# checks that it is valid.
	#

	RKHTMPVAR=`get_option 2 single PORT_WHITELIST` || exit 1

	if [ -n "${RKHTMPVAR}" ]; then
		#
		# Loop through the list checking that it all looks okay.
		#

		FOUND=0

		if [ -n "`echo \"${RKHTMPVAR}\" | grep '\*'`" ]; then
			PORT_WHITELIST_ALL_TRUSTED=1
			RKHTMPVAR=`echo "${RKHTMPVAR}" | tr -d '*'`
		fi

		for RKHTMPVAR2 in ${RKHTMPVAR}; do
			if [ -n "`echo \"${RKHTMPVAR2}\" | grep '^/'`" ]; then
				if [ ! -f "${RKHTMPVAR2}" ]; then
					FOUND=1
					echo "Non-existent pathname specified in PORT_WHITELIST configuration option: ${RKHTMPVAR2}"
				else
					PORT_WHITELIST_PATH="${PORT_WHITELIST_PATH} ${RKHTMPVAR2}"
				fi
			elif [ -n "`echo \"${RKHTMPVAR2}\" | egrep -i '^(TCP|UDP):[1-9][0-9]*$'`" ]; then
				PORT=`echo ${RKHTMPVAR2} | cut -d: -f2`

				if [ $PORT -gt 65535 ]; then
					FOUND=1
					echo "Invalid port specified in PORT_WHITELIST configuration option: ${RKHTMPVAR2}"
				else
					PORT_WHITELIST="${PORT_WHITELIST} ${RKHTMPVAR2}"
				fi
			else
				FOUND=1
				echo "Invalid entry specified in PORT_WHITELIST configuration option: ${RKHTMPVAR2}"
			fi
		done

		test $FOUND -eq 1 && exit 1

		PORT_WHITELIST=`echo " ${PORT_WHITELIST} " | tr '[a-z]' '[A-Z]'`
		PORT_WHITELIST_PATH=" ${PORT_WHITELIST_PATH} "
	fi

	return
}


get_if_prelinked() {

	#
	# If the system appears to be using prelinking, but no
	# prelink command can be found, then we simply skip the
	# file properties hash check.
	#

	LIBSAFE_TEST1=""
	LIBSAFE_TEST2=""

	if [ -f "${RKHROOTDIR}/etc/prelink.cache" ]; then
		PRELINK_CMD=`find_cmd prelink`

		#
		# Test (twice) for existance of Libsafe since this seems to
		# riddle prelink test results with "dependency cycle" errors.
		# Don't test for existance of /lib/libsafe since it may be
		# installed elsewhere.
		# If Libsafe is found *and* this is a prelink system, we'll
		# skip the prelink test.
		#

		if [ -f "${RKHROOTDIR}/etc/ld.so.preload" ]; then
			LIBSAFE_TEST1=`grep libsafe ${RKHROOTDIR}/etc/ld.so.preload 2>&1`
		fi

		if [ -n "${LDD_CMD}" -a -f "${RKHROOTDIR}/lib/libdl.so.?" ]; then
			LIBSAFE_TEST2=`${LDD_CMD} ${RKHROOTDIR}/lib/libdl.so.? | grep libsafe 2>&1`
		fi

		if [ -z "${PRELINK_CMD}" ]; then
			SKIP_HASH_MSG=1
		elif [ -z "${LIBSAFE_TEST1}" -a -z "${LIBSAFE_TEST2}" ]; then
			PRELINKED=1

			#
			# Only use 'runcon' if SELinux is enabled.
			#

			SESTATUS_CMD=`find_cmd sestatus`

			if [ -n "${SESTATUS_CMD}" ]; then
				if [ -n "`${SESTATUS_CMD} 2>/dev/null | grep ' status: *enabled$'`" ]; then
					SELINUX_ENABLED=1
					RUNCON_CMD=`find_cmd runcon`
					test -n "${RUNCON_CMD}" && USE_RUNCON=1
				fi
			fi
		elif [ -n "${LIBSAFE_TEST1}" -a -n "${LIBSAFE_TEST2}" ]; then
			SKIP_HASH_MSG=3
		fi
	fi

	return
}


get_md5_hash_function() {

	#
	# This is a short function to try and locate
	# an MD5 hash function command.
	#
	# The first parameter simply indicates if we are
	# setting the hash function (parameter is 1) or
	# just looking for an MD5 command to support a
	# package manager (parameter is 0).
	#

	if [ $PRELINKED -eq 1 ]; then
		test $1 -eq 1 && PRELINK_HASH="MD5"

		if [ $USE_RUNCON -eq 1 ]; then
			echo "${RUNCON_CMD} -t unconfined_t -- ${PRELINK_CMD} --verify --md5"
		else
			echo "${PRELINK_CMD} --verify --md5"
		fi
	else
		HFUNC=`find_cmd md5sum`

		test -z "${HFUNC}" && HFUNC=`find_cmd md5`

		if [ -z "${HFUNC}" -a -n "${PERL_CMD}" ]; then
			MOD_INSTALLED=`${PERL_CMD} ${SCRIPT_PATH}/check_modules.pl Digest::MD5 2>&1 | grep 'Digest::MD5 installed'`

			test -n "${MOD_INSTALLED}" && echo "${PERL_CMD} ${SCRIPT_PATH}/filehashmd5.pl"
		else
			echo "${HFUNC}"
			MD5_CMD="${HFUNC}"
		fi
	fi

	return
}


get_hash_function() {

	#
	# Get the option from the configuration file, and do a simple
	# check on whether it is empty or a space.
	#

	if [ -n "${HASH_FUNC}" ]; then
		HASH_FUNC=`echo "${HASH_FUNC}" | tr -d '"' | tr -d "'" | tr '	' ' ' | tr -s ' '`
		HASH_FUNC=`echo "${HASH_FUNC}" | sed -e 's/^ //' | sed -e 's/ $//'`

		if [ -z "${HASH_FUNC}" ]; then
			echo "Invalid --hash option - no hash function given."
			exit 1
		elif [ -n "`echo \"${HASH_FUNC}\" | egrep -i '^(MD5|SHA1|NONE)$'`" ]; then
			HASH_FUNC=`echo "${HASH_FUNC}" | tr '[a-z]' '[A-Z]'`
		fi
	else
		HASH_FUNC=`get_option 2 single HASH_FUNC` || exit 1
	fi


	#
	# At this point we have either been given a hash function
	# command, one of the reserved words 'SHA1', 'MD5' or 'NONE',
	# or nothing. For the SHA1 and MD5 reserved words we must
	# find the SHA1 or MD5 command or use the supplied perl scripts.
	#

	if [ -z "${HASH_FUNC}" -o "${HASH_FUNC}" = "SHA1" ]; then
		if [ $PRELINKED -eq 1 ]; then
			PRELINK_HASH="SHA1"

			if [ $USE_RUNCON -eq 1 ]; then
				HASH_FUNC="${RUNCON_CMD} -t unconfined_t -- ${PRELINK_CMD} --verify --sha"
			else
				HASH_FUNC="${PRELINK_CMD} --verify --sha"
			fi
		else
			HF=`find_cmd sha1sum`

			test -z "${HF}" && HF=`find_cmd sha1`

			if [ -z "${HF}" -a -n "${PERL_CMD}" ]; then
				MOD_INSTALLED=`${PERL_CMD} ${SCRIPT_PATH}/check_modules.pl Digest::SHA1 2>&1 | grep 'Digest::SHA1 installed'`

				if [ -n "${MOD_INSTALLED}" ]; then
					HASH_FUNC="${PERL_CMD} ${SCRIPT_PATH}/filehashsha1.pl"
				else
					HASH_FUNC=""
				fi
			else
				HASH_FUNC=$HF
			fi
		fi
	fi


	#
	# If we still have no hash function, then look for an MD5 command.
	#

	if [ -z "${HASH_FUNC}" -o "${HASH_FUNC}" = "MD5" ]; then
		HASH_FUNC=`get_md5_hash_function 1`
	fi


	#
	# A final check that the command is actually executable.
	# This will ensure that the sha1/md5 perl scripts have been
	# installed correctly, should they be needed.
	#

	if [ "${HASH_FUNC}" = "NONE" ]; then
		:
	elif [ -n "${HASH_FUNC}" ]; then
		HCMD=`echo "${HASH_FUNC}" | cut -d' ' -f1`
		HF=`find_cmd ${HCMD}`

		if [ -n "${HF}" ]; then
			#
			# We rebuild the command to use the full pathname.
			#

			HCMD=`echo "${HASH_FUNC}" | cut -d' ' -f2-`

			if [ -z "${HCMD}" -o "${HCMD}" = "${HASH_FUNC}" ]; then
				HASH_FUNC=$HF
			else
				HASH_FUNC="${HF} ${HCMD}"
			fi
		else
			echo "Invalid HASH_FUNC configuration option - command '${HCMD}' is non-existent or not executable."
			exit 1
		fi
	else
		echo "Invalid HASH_FUNC configuration option - option not specified and no hash command or perl modules could be found."
		exit 1
	fi


	#
	# Now we get the hash field index. We will assume a field value
	# of one, but this value must be configurable since we allow
	# the user to specify the hash function to use.
	#

	RKHTMPVAR=`get_option 1 single HASH_FLD_IDX` || exit 1

	if [ -n "${RKHTMPVAR}" ]; then
		if [ -z "`echo \"${RKHTMPVAR}\" | grep '^[1-9][0-9]*$'`" ]; then
			echo "Invalid HASH_FLD_IDX configuration option: not a number: ${RKHTMPVAR}"
			exit 1
		else
			HASH_FLD_IDX=${RKHTMPVAR}
		fi
	fi


	#
	# Next we get the package manager to use for the file
	# properties hash check and update. If a file is not owned
	# as part of a package, the hash function defined above
	# will be used instead.
	#

	if [ -n "${PKGMGR}" ]; then
		PKGMGR=`echo "${PKGMGR}" | tr -d '" 	' | tr -d "'"`

		if [ -z "${PKGMGR}" ]; then
			echo "Invalid --pkgmgr option - no package manager given."
			exit 1
		fi
	else
		PKGMGR=`get_option 1 single PKGMGR` || exit 1
	fi

	PKGMGR=`echo "${PKGMGR}" | tr '[a-z]' '[A-Z]'`

	test "${PKGMGR}" = "NONE" && PKGMGR=""


	#
	# Now check that the package manager we have been given is valid.
	#

	case "${PKGMGR}" in
	"")
		;;
	RPM)
		RPM_CMD=`find_cmd rpm`

		if [ -z "${RPM_CMD}" ]; then
			echo "Unable to find 'rpm' command for package manager 'RPM'."
			exit 1
		fi
		;;
	DPKG)
		DPKG_CMD=`find_cmd dpkg-query`

		test -z "${DPKG_CMD}" && DPKG_CMD=`find_cmd dpkg`

		if [ -z "${DPKG_CMD}" ]; then
			echo "Unable to find 'dpkg-query' or 'dpkg' commands for package manager 'DPKG'."
			exit 1
		fi

		if [ ! -d "/var/lib/dpkg/info" ]; then
			echo "Unable to find package database directory (/var/lib/dpkg/info) for package manager 'DPKG'."
			exit 1
		fi

		if [ $CHECK -eq 1 ]; then
			PKGMGR_MD5_HASH=`get_md5_hash_function 0`

			if [ -z "${PKGMGR_MD5_HASH}" ]; then
				echo "Unable to find an MD5 hash function command to assist package manager 'DPKG'."
				exit 1
			fi
		fi
		;;
	BSD)
		PKG_CMD=`find_cmd pkg_info`

		if [ -z "${PKG_CMD}" ]; then
			echo "Unable to find 'pkg_info' command for package manager 'BSD'."
			exit 1
		fi

		if [ ! -d "/var/db/pkg" ]; then
			echo "Unable to find package database directory (/var/db/pkg) for package manager 'BSD'."
			exit 1
		fi

		if [ $CHECK -eq 1 ]; then
			PKGMGR_MD5_HASH=`get_md5_hash_function 0`

			if [ -z "${PKGMGR_MD5_HASH}" ]; then
				echo "Unable to find an MD5 hash function command to assist package manager 'BSD'."
				exit 1
			fi
		fi
		;;
	*)
		echo "Invalid package manager given - ${PKGMGR}"
		exit 1
		;;
	esac

	return
}


get_scan_mode_dev_option() {

	#
	# SCAN_MODE_DEV governs how we scan /dev for suspicious files.
	# The two allowed options are "commented out" or LAZY.
	# If commented out, the default, we do a thorough scan which
	# will increase the runtime of rkhunter.
	#

	#
	# See if the option is specified in the configuration file.
	#

	SCAN_MODE_DEV=`get_option 1 single SCAN_MODE_DEV` || exit 1

	if [ -n "${SCAN_MODE_DEV}" ]; then
		SCAN_MODE_DEV=`echo "${SCAN_MODE_DEV}" | tr '[a-z]' '[A-Z]'`

		case "${SCAN_MODE_DEV}" in
		THOROUGH|LAZY)
			;;
		*)	# Don't make this fatal.
			echo "Invalid SCAN_MODE_DEV configuration option: ${SCAN_MODE_DEV}"
			echo "Defaulting to THOROUGH mode."

			SCAN_MODE_DEV="THOROUGH"
			;;
		esac
	else
		SCAN_MODE_DEV="THOROUGH"
	fi

	return
}


get_rc_options() {

	#
	# This function gets some of the system startup 'rc'
	# files and directories from the configuration file.
	# There are no defaults.
	#

	RC_FILE=`get_option 2 single LOCAL_RC_PATH` || exit 1

	if [ -n "${RC_FILE}" ]; then
		#
		# Check that the given files are useable.
		#

		for RKHTMPVAR in ${RC_FILE}; do
			if [ ! -f "${RKHROOTDIR}${RKHTMPVAR}" ]; then
				echo "Local system startup file does not exist: ${RKHROOTDIR}${RKHTMPVAR}"
				exit 1
			elif [ -h "${RKHROOTDIR}${RKHTMPVAR}" ]; then
				echo "Local system startup file is a symbolic link: ${RKHROOTDIR}${RKHTMPVAR}"
				exit 1
			elif [ ! -r "${RKHROOTDIR}${RKHTMPVAR}" ]; then
				echo "Local system startup file is not readable: ${RKHROOTDIR}${RKHTMPVAR}"
				exit 1
			elif [ ! -s "${RKHROOTDIR}${RKHTMPVAR}" ]; then
				echo "Local system startup file is empty: ${RKHROOTDIR}${RKHTMPVAR}"
				exit 1
			fi
		done
	fi


	RC_DIR=`get_option 1 single SYSTEM_RC_DIR` || exit 1

	if [ -n "${RC_DIR}" ]; then
		#
		# Check that the given directory is useable.
		#

		if [ ! -d "${RKHROOTDIR}${RC_DIR}" ]; then
			echo "Local system startup directory does not exist: ${RKHROOTDIR}${RC_DIR}"
			exit 1
		elif [ -h "${RKHROOTDIR}${RC_DIR}" ]; then
			echo "Local system startup directory is a symbolic link: ${RKHROOTDIR}${RC_DIR}"
			exit 1
		elif [ ! -r "${RKHROOTDIR}${RC_DIR}" ]; then
			echo "Local system startup directory is not readable: ${RKHROOTDIR}${RC_DIR}"
			exit 1
		fi
	fi

	return
}


get_rtkt_whitelist_options() {

	#
	# This function gets any whitelisted rootkit files
	# and directories from the configuration file.
	# There are no defaults.
	#

	RTKT_FILE_WHITELIST=`get_option 2 single RTKT_FILE_WHITELIST` || exit 1

	if [ -n "${RTKT_FILE_WHITELIST}" ]; then
		#
		# Check that the given files are useable.
		#

		FOUND=0

		for RKHTMPVAR2 in ${RTKT_FILE_WHITELIST}; do
			RKHTMPVAR=`echo "${RKHTMPVAR2}" | tr '%' ' '`

			if [ ! -f "${RKHTMPVAR}" ]; then
				FOUND=1
				echo "Whitelisted rootkit file does not exist: ${RKHTMPVAR2}"
			fi
		done

		test $FOUND -eq 1 && exit 1

		RTKT_FILE_WHITELIST=" ${RTKT_FILE_WHITELIST} "
	fi


	RTKT_DIR_WHITELIST=`get_option 2 single RTKT_DIR_WHITELIST` || exit 1

	if [ -n "${RTKT_DIR_WHITELIST}" ]; then
		#
		# Check that the given directories are useable.
		#

		FOUND=0

		for RKHTMPVAR2 in ${RTKT_DIR_WHITELIST}; do
			RKHTMPVAR=`echo "${RKHTMPVAR2}" | tr '%' ' '`

			if [ ! -d "${RKHTMPVAR}" ]; then
				FOUND=1
				echo "Whitelisted rootkit directory does not exist: ${RKHTMPVAR2}"
			fi
		done

		test $FOUND -eq 1 && exit 1

		RTKT_DIR_WHITELIST=" ${RTKT_DIR_WHITELIST} "
	fi

	return
}


get_mirror_options() {

	#
	# This function gets the mirror file options.
	#
	# First we see if the mirrors.dat file
	# should be rotated when it is used.
	#

	ROTATE_MIRRORS=`get_option 1 single ROTATE_MIRRORS` || exit 1

	if [ -n "${ROTATE_MIRRORS}" ]; then
		if [ "${ROTATE_MIRRORS}" != "0" -a "${ROTATE_MIRRORS}" != "1" ]; then
			echo "Invalid ROTATE_MIRRORS configuration option: not a number: ${ROTATE_MIRRORS}"
			exit 1
		fi
	else
		ROTATE_MIRRORS=1
	fi


	#
	# Next we see if the mirror file is to be updated when
	# we use the '--update' option.
	#

	if [ $UPDATE -eq 1 ]; then
		UPDATE_MIRRORS=`get_option 1 single UPDATE_MIRRORS` || exit 1

		if [ -n "${UPDATE_MIRRORS}" ]; then
			if [ "${UPDATE_MIRRORS}" != "0" -a "${UPDATE_MIRRORS}" != "1" ]; then
				echo "Invalid UPDATE_MIRRORS configuration option: not a number: ${UPDATE_MIRRORS}"
				exit 1
			fi
		else
			UPDATE_MIRRORS=1
		fi
	fi


	#
	# Finally, we see which mirrors are to be used.
	#

	MIRRORS_MODE=`get_option 1 single MIRRORS_MODE` || exit 1

	if [ -n "${MIRRORS_MODE}" ]; then
		if [ "${MIRRORS_MODE}" != "0" -a "${MIRRORS_MODE}" != "1" -a "${MIRRORS_MODE}" != "2" ]; then
			echo "Invalid MIRRORS_MODE configuration option: not a number: ${MIRRORS_MODE}"
			exit 1
		fi
	else
		MIRRORS_MODE=0
	fi

	return
}


get_os_version_option() {

	#
	# This function gets the O/S 'release' file pathname
	# from the configuration file. There is no default.
	#

	OS_VERSION_FILE=`get_option 1 single OS_VERSION_FILE` || exit 1

	if [ -n "${OS_VERSION_FILE}" ]; then
		#
		# Check that the given file is useable.
		#

		if [ ! -f "${RKHROOTDIR}${OS_VERSION_FILE}" ]; then
			echo "O/S release file does not exist: ${RKHROOTDIR}${OS_VERSION_FILE}"
			exit 1
		elif [ -h "${RKHROOTDIR}${OS_VERSION_FILE}" ]; then
			echo "O/S release file is a symbolic link: ${RKHROOTDIR}${OS_VERSION_FILE}"
			exit 1
		elif [ ! -r "${RKHROOTDIR}${OS_VERSION_FILE}" ]; then
			echo "O/S release file is not readable: ${RKHROOTDIR}${OS_VERSION_FILE}"
			exit 1
		elif [ ! -s "${RKHROOTDIR}${OS_VERSION_FILE}" ]; then
			echo "O/S release file is empty: ${RKHROOTDIR}${OS_VERSION_FILE}"
			exit 1
		fi
	fi

	return
}


get_configfile_options() {

	#
	# We call separate functions to process each option. The option
	# is checked first to see if it has been given on the command-line,
	# and, if not, then if it is specified in the configuration file.
	# Note that some of these functions are in a specific order. If you
	# change them around, then make sure the functions still work
	# correctly.
	#

	get_installdir_option

	get_rootdir_option

	get_bindir_option

	get_logfile_option

	get_tmpdir_option

	get_dbdir_option

	get_language_option

	get_scriptdir_option

	get_auto_x_option


	#
	# Now that we have processed BINDIR, we will recheck the
	# required commands.
	#
	# Before proceeding too far we also check that we have certain
	# commands available. Typically these are commands which might
	# not have been installed as part of the core system, but are
	# used by RKH. These commands are not 'required' though.
	#

	check_required_commands "${BINPATHS}"

	check_commands


	#
	# Some options are only required when checking the system.
	#

	if [ $CHECK -eq 1 -o $PROP_UPDATE -eq 1 ]; then
		#
		# See if we are only to perform specific tests.
		#

		get_enable_option
		get_disable_option
	fi

	if [ $CHECK -eq 1 ]; then
		test $NOMOW -eq 0 && get_mailonwarn_option

		get_ssh_options

		get_syslog_config_options

		get_syslog_option

		get_scan_mode_dev_option

		get_rc_options

		get_rtkt_whitelist_options

		check_test hashes && HASH_CHECK_ENABLED=1
		check_test attributes && HASH_CHECK_ENABLED=1

		check_test trojans && get_xinetd_option

		check_test ports && get_ports_option
	fi


	#
	# We only need the hash function option if we are going
	# to be checking the system or updating the file
	# properties database.
	#

	if `check_test properties` || test $PROP_UPDATE -eq 1; then
		#
		# For the file properties check we need to find out if
		# we are a prelinked system, and if so, then find out
		# which hash function to use. We also need to find the
		# 'stat' command.
		#

		get_if_prelinked

		test $SKIP_HASH_MSG -eq 0 && get_hash_function

		get_os_version_option
	fi


	#
	# Get the mirror file options if necessary.
	#

	if [ $UPDATE -eq 1 -o $VERSIONCHECK -eq 1 ]; then
		get_mirror_options
	fi

	return
}


rkh_dat_set_version() {

	#
	# This function calculates and writes out the 'Version:' value
	# for the rkhunter.dat file. It looks for an old value, and adds
	# one to it. If there is no value then simply start at zero.
	#

	TODAY=`date +%Y%m%d 2>/dev/null`

	OLDVER=`grep '^[Vv]ersion:' ${DB_PATH}/rkhunter.dat 2>/dev/null | tail -1 | cut -d: -f2`

	if [ -n "${OLDVER}" ]; then
		OLDDATE=`echo "${OLDVER}" | cut -c1-8`
		OLDVER=`echo "${OLDVER}" | cut -c9-10`

		if [ "${OLDVER}" = "99" -o "${OLDDATE}" != "${TODAY}" -o -z "${OLDVER}" -o -n "`echo \"${OLDVER}\" | grep '[^0-9]'`" ]; then
			NEWVER="00"
		else
			NEWVER=`expr ${OLDVER} + 1`
			test $NEWVER -lt 10 && NEWVER="0${NEWVER}"
		fi
	else
		NEWVER="00"
	fi

	echo "Version:${TODAY}${NEWVER}" >>${RKHDAT_FILE}

	return
}


rkh_dat_get_os_info() {

	#
	# This function obtains information about the local computer
	# system. This is then written into the rkhunter.dat file
	# using a simple 'keyword:<value>' format. The OSNAME and
	# ARCH values are not important, but are simply used to check
	# whether they have changed since RKH was last run.
	#
	# Obtaining the OSNAME is somewhat tricky. There is no sure
	# way of finding the information, so we have to use some tricks
	# to locate the correct file. First we look for certain specific
	# O/S release files, and then at the /etc/release file, but not
	# if it is a link. Next we look for a generic /etc/*-release
	# file, again not as a link. This should find most O/S versions.
	# Overall this should also save users having to ask us to support
	# their O/S. In other cases, we will have to ask what file does
	# contain their O/S release information.
	#

	ARCH=`uname -m 2>/dev/null`

	if [ -n "${OS_VERSION_FILE}" ]; then
		REL_FILES="${RKHROOTDIR}${OS_VERSION_FILE}"
	else
		REL_FILES="${RKHROOTDIR}/etc/lsb-release ${RKHROOTDIR}/etc/debian_version ${RKHROOTDIR}/etc/slackware-version ${RKHROOTDIR}/var/ipcop/general-functions.pl ${RKHROOTDIR}/etc/lunar.release ${RKHROOTDIR}/etc/ROCK-VERSION ${RKHROOTDIR}/etc/GoboLinuxVersion ${RKHROOTDIR}/etc/kanotix-version ${RKHROOTDIR}/etc/sidux-version ${RKHROOTDIR}/etc/knoppix-version ${RKHROOTDIR}/etc/zenwalk-version ${RKHROOTDIR}/etc/release ${RKHROOTDIR}/etc/*-release"
	fi

	for FNAME in ${REL_FILES}; do
		if [ -f "${FNAME}" -a ! -h "${FNAME}" ]; then
			RELEASE=$FNAME

			case "${RELEASE}" in
			${RKHROOTDIR}/etc/lsb-release)
				OSNAME=`grep '^DISTRIB_DESCRIPTION=' ${RELEASE} | sed -e 's/DISTRIB_DESCRIPTION=//' | tr -d '"'`
				;;
			${RKHROOTDIR}/etc/gentoo-release)
				GENTOO=1
				if [ -h ${RKHROOTDIR}/etc/make.profile ]; then
					OSNAME="Gentoo `ls -l ${RKHROOTDIR}/etc/make.profile 2>/dev/null | sed -e 's/^.*\/\([^\/]*\)$/\1/'`"
				fi
				;;
			${RKHROOTDIR}/var/ipcop/general-functions.pl)
				OSNAME=`grep 'version *=' ${RELEASE} | head -n 1`
				;;
			${RKHROOTDIR}/etc/debian_version)
				OSNAME="Debian `cat ${RELEASE}`"
				;;
			${RKHROOTDIR}/etc/GoboLinuxVersion)
				OSNAME="GoboLinux `cat ${RELEASE}`"
				;;
			${RKHROOTDIR}/etc/knoppix-version)
				OSNAME="Knoppix `cat ${RELEASE}`"
				;;
			${RKHROOTDIR}/etc/zenwalk-version)
				OSNAME="Zenwalk `cat ${RELEASE}`"
				;;
			*)
				OSNAME=`awk '/^[ 	]*[^ 	]/ { print $0 }' ${RELEASE} | head -n 1`
				;;
			esac


			#
			# Strip out any leading blanks and tabs
			# from the O/S version.
			#

			test -n "${OSNAME}" && OSNAME=`echo "${OSNAME}" | sed -e 's/^[ 	]*//'`


			#
			# If we have a release file but it seems to be blank,
			# we take a look for the first non-blank line. We
			# then, again, strip out any leading blanks and tabs.
			#

			if [ -z "${OSNAME}" ]; then
				OSNAME=`awk '/^[ 	]*[^ 	]/ { print $0 }' ${RELEASE} | head -n 1 | sed -e 's/^[ 	]*//'`
			fi

			test -n "${OSNAME}" && break
		fi
	done


	if [ -z "${OSNAME}" ]; then
		RELEASE=""

		if [ -d "${RKHROOTDIR}/var/smoothwall" ]; then
			OSNAME="Smoothwall Linux"
			RELEASE="${RKHROOTDIR}/var/smoothwall"
		elif `which sorcery gaze >/dev/null 2>&1`; then
			OSNAME="Source Mage Linux"
		fi
	fi

	case "${OPERATING_SYSTEM}" in
	SunOS)
		ARCH=`uname -p 2>/dev/null`
		;;
	FreeBSD)
		ARCH=`sysctl -n hw.machine_arch 2>/dev/null`
		OSNAME=`uname -v 2>/dev/null | cut -d' ' -f1,2`
		;;
	OpenBSD)
		OSNAME="OpenBSD `uname -r 2>/dev/null`"
		;;
	Darwin)
		OSNAME=`sw_vers 2>/dev/null | grep '^ProductName:' | sed -e 's/ProductName: *//'`
		OSNAME="${OSNAME} `sw_vers 2>/dev/null | grep '^ProductVersion:' | sed -e 's/ProductVersion: *//'`"
#		OSNAME="${OSNAME} `sysctl kern.version 2>/dev/null | sed -e 's/^kern.version = //' | cut -d: -f1`"
		;;
	AIX)
		ARCH=`uname -p 2>/dev/null`
		OSNAME="IBM AIX `oslevel 2>/dev/null`"
		;;
	IRIX*)
		OSNAME="${OPERATING_SYSTEM} `uname -r 2>/dev/null`"
		;;
	esac


	#
	# If we still have no O/S version information, then as a last
	# resort we will look to see if an 'issue' file exists. We test
	# this last because it is not necessarily reliable in providing
	# the O/S version.
	#

	if [ -z "${OSNAME}" -a -f "${RKHROOTDIR}/etc/issue" ]; then
		OSNAME=`awk '/^[ 	]*[^ 	]/ { print $0 }' ${RKHROOTDIR}/etc/issue | head -n 1 | sed -e 's/^[ 	]*//'`
		test -n "${OSNAME}" && RELEASE="${RKHROOTDIR}/etc/issue"
	fi

	return
}


rkh_dat_set_file_properties() {

	#
	# This function obtains various bits of information about the
	# files to be checked. The format in the rkhunter.dat file is:
	#
	#     File:<pathname>:<hash value>:<inode>:<permissions>:<uid>:<gid>:
	#          <file size>:<date/time modified>
	#
	# The format is actually governed by the stat.pl file, and the
	# output it produces. Changing the order of options does not
	# change the order of the output.
	#
	# To save time in the loops below, we determine the exact commands
	# required before entering them.
	#

	NOHASH_COUNT=0
	DIR_FILE_COUNT=0
	PROP_FILE_LIST_COUNT=0

	display --to LOG --type PLAIN SET_FILE_PROP_START


	if ! `check_test attributes`; then
		SCMD=""
	elif [ -z "${STAT_CMD}" ]; then
		SCMD=""
	else
		if [ -n "`echo \"${STAT_CMD}\" | grep '\.pl$'`" ]; then
			SCMD="${STAT_CMD} --modeoct --raw --ino --mode --uid --gid --size --Mtime"
		elif [ $BSDOS -eq 1 ]; then
			SCMD="${STAT_CMD} -f '%i %Mp%Lp %u %g %z %m:'"
		else
			SCMD="${STAT_CMD} --format='%i 0%a %u %g %s %Y:'"
		fi
	fi


	if ! `check_test hashes`; then
		HCMD=""
	elif [ -z "${PKGMGR}" -a "${HASH_FUNC}" = "NONE" ]; then
		HCMD=""
	else
		HCMD="${HASH_FUNC}"
	fi

	RDIR=`echo "${RKHROOTDIR}" | sed -e 's/\//\\\\\//g'`


	#
	# Now loop through the directories looking for the files.
	#

	for DIR in ${PROP_DIR_LIST}; do
		DIR_FILE_COUNT=0

		for FNAME in ${PROP_FILE_LIST}; do
			test ! -f "${DIR}/${FNAME}" && continue

			FDATA=""
			SYSHASH=""
			RPM_QUERY_RESULT=""
			FILE_IS_PKGD=0

			FILENAME=`echo "${DIR}/${FNAME}" | sed -e "s/^${RDIR}//"`

			DIR_FILE_COUNT=`expr ${DIR_FILE_COUNT} + 1`
			PROP_FILE_LIST_COUNT=`expr ${PROP_FILE_LIST_COUNT} + 1`

			if [ "${PKGMGR}" = "RPM" ]; then
				#
				# First see if the file belongs to a package.
				#

				PKGNAME=`${RPM_CMD} -qf ${FILENAME} 2>/dev/null`
				ERRCODE=$?

				if [ $ERRCODE -eq 0 ]; then
					#
					# Okay we have a package name.
					#

					FILE_IS_PKGD=1

					RPM_QUERY_RESULT=`${RPM_CMD} -qf --queryformat '[%{FILEINODES}:%{FILEMODES:octal}:%{FILEUSERNAME}:%{FILEGROUPNAME}:%{FILESIZES}:%{FILEMTIMES}:%{FILEMD5S}:%{FILENAMES}\n]' ${FILENAME} 2>/dev/null | grep ":${FILENAME}\$"`
					ERRCODE=$?

					if [ $ERRCODE -eq 0 ]; then
						#
						# If multiple versions of the same package
						# have been installed, we use the last one.
						#

						RPM_QUERY_RESULT=`echo "${RPM_QUERY_RESULT}" | tail -1`

						FPERM="0`echo \"${RPM_QUERY_RESULT}\" | cut -d: -f2 | cut -c 3-`"
						FPERM=`echo "${FPERM}" | sed -e 's/^00/0/'`

						RKHUID=`echo "${RPM_QUERY_RESULT}" | cut -d: -f3`
						RKHUID=`grep "^${RKHUID}:" /etc/passwd 2>/dev/null | cut -d: -f3`

						RKHGID=`echo "${RPM_QUERY_RESULT}" | cut -d: -f4`
						RKHGID=`grep "^${RKHGID}:" /etc/group 2>/dev/null | cut -d: -f3`

						RKHSIZE=`echo "${RPM_QUERY_RESULT}" | cut -d: -f5`

						RKHDTM=`echo "${RPM_QUERY_RESULT}" | cut -d: -f6`

						FDATA=`echo "${RPM_QUERY_RESULT}" | cut -d: -f1`
						FDATA="${FDATA}:${FPERM}:${RKHUID}:${RKHGID}:${RKHSIZE}:${RKHDTM}:"
					else
						display --to LOG --type INFO CMD_ERROR "rpm -qf --queryformat ${FILENAME}" $ERRCODE
					fi
				fi
			fi


			if [ -n "${HCMD}" ]; then
				if [ "${PKGMGR}" = "RPM" ]; then
					test $FILE_IS_PKGD -eq 1 && SYSHASH=`echo "${RPM_QUERY_RESULT}" | cut -d: -f7`
				elif [ "${PKGMGR}" = "DPKG" ]; then
					PKGNAME=`${DPKG_CMD} --search ${FILENAME} 2>/dev/null | cut -d: -f1`

					if [ -n "${PKGNAME}" -a -f "/var/lib/dpkg/info/${PKGNAME}.md5sums" ]; then
						FILNAM=`echo "${FILENAME}" | sed -e 's:^/::'`
						SYSHASH=`egrep "( |\./)${FILNAM}\$" /var/lib/dpkg/info/${PKGNAME}.md5sums | cut -d' ' -f1`
						test -n "${SYSHASH}" && FILE_IS_PKGD=1
					fi
				elif [ "${PKGMGR}" = "BSD" ]; then
					#
					# First see if the file is part of a known package.
					#

					RKHTMPVAR=`${PKG_CMD} -F -e ${FILENAME} 2>/dev/null`

					if [ -n "${RKHTMPVAR}" ]; then
						#
						# Next strip of the '/usr/pkg' from the pathname,
						# and then get the hash value.
						#

						FILNAM=`echo "${FILENAME}" | sed -e 's:^/usr/pkg/::'`
						SYSHASH=`${PKG_CMD} -v -L ${RKHTMPVAR} 2>/dev/null | grep -A 1 "File: ${FILNAM}\$" | tail -1 | cut -d: -f3`
						test -n "${SYSHASH}" && FILE_IS_PKGD=1
					fi
				fi

				if [ $FILE_IS_PKGD -eq 0 ]; then
					if [ "${HCMD}" != "NONE" ]; then
						SYSHASH=`${HCMD} ${DIR}/${FNAME} 2>/dev/null | cut -d' ' -f $HASH_FLD_IDX`
					fi

					if [ -z "${SYSHASH}" ]; then
						if [ "${HCMD}" = "NONE" ]; then
							if [ $VERBOSE_LOGGING -eq 1 ]; then
								display --to LOG --type INFO FILE_PROP_NO_PKGMGR_FILE "${DIR}/${FNAME}"
							fi
						else
							NOHASH_COUNT=`expr ${NOHASH_COUNT} + 1`

							display --to LOG --type WARNING FILE_PROP_NO_SYSHASH "${DIR}/${FNAME}"

							RKHTMPVAR=`${HCMD} ${DIR}/${FNAME} 2>&1 | tr '\n' ':' | sed -e 's/:$//'`

							display --to LOG --type PLAIN --log-indent 9 FILE_PROP_NO_SYSHASH_CMD "${RKHTMPVAR}"

							if [ -n "`echo \"${RKHTMPVAR}\" | grep 'prelink.* dependencies '`" ]; then
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_NO_SYSHASH_DEPENDENCY "${DIR}/${FNAME}"
							fi
						fi
					fi
				fi
			fi


			if [ -n "${SCMD}" ]; then
				if [ -z "${FDATA}" ]; then
					FDATA=`eval ${SCMD} ${DIR}/${FNAME} 2>/dev/null | tr ' ' ':'`
					test -z "${FDATA}" && FDATA="::::::"
				fi
			else
				FDATA="::::::"
			fi

			echo "File:${FILENAME}:${SYSHASH}:${FDATA}" >>${RKHDAT_FILE}
		done

		display --to LOG --type INFO SET_FILE_PROP_DIR_FILE_COUNT $DIR_FILE_COUNT "${DIR}"
	done


	if [ -f ${DB_PATH}/rkhunter.dat ]; then
		RKHTMPVAR="updated"
	else
		RKHTMPVAR="created"
	fi

	if [ $NOHASH_COUNT -eq 0 ]; then
		display --to SCREEN+LOG --type INFO SET_FILE_PROP_FILE_COUNT "${RKHTMPVAR}" $PROP_FILE_LIST_TOTAL $PROP_FILE_LIST_COUNT
	else
		RET_CODE=1
		display --to SCREEN+LOG --type INFO SET_FILE_PROP_FILE_COUNT_NOHASH "${RKHTMPVAR}" $PROP_FILE_LIST_TOTAL $PROP_FILE_LIST_COUNT $NOHASH_COUNT
	fi

	return
}


do_prop_update() {

	#
	# This function updates the local hosts rkhunter.dat file
	# with O/S information and file properties.
	#

	display --to LOG --type INFO --nl PROPUPD_START

	#
	# First we need to get a temporary file name to use.
	#

	get_temp_file "${RKHTMPDIR}/rkhunter.dat"
	RKHDAT_FILE=$TEMPFILE

	display --to LOG --type INFO CREATED_TEMP_FILE "${RKHDAT_FILE}"


	#
	# We now start to write out information about this system
	# to the file. Some information we already have available,
	# but for others we call functions to obtain what is wanted.
	#

	ARCH=""
	OSNAME=""
	RELEASE=""

	rkh_dat_set_version


	display --to LOG --type PLAIN PROPUPD_OSINFO_START

	rkh_dat_get_os_info

	echo "Host:${HOST_NAME}" >>${RKHDAT_FILE}

	if [ -n "${ARCH}" ]; then
		echo "Arch:${ARCH}" >>${RKHDAT_FILE}
		display --to LOG --type INFO PROPUPD_ARCH_FOUND "${ARCH}"
	fi

	if [ -n "${RELEASE}" ]; then
		display --to LOG --type INFO PROPUPD_REL_FILE "${RELEASE}"
	else
		display --to LOG --type INFO PROPUPD_NO_REL_FILE
		display --to LOG --type PLAIN NAME "      `ls -ld ${RKHROOTDIR}/etc/*release* ${RKHROOTDIR}/etc/*version* 2>/dev/null | tr '\n' ' '`"
	fi

	if [ -n "${OSNAME}" ]; then
		echo "OS:${OSNAME}" >>${RKHDAT_FILE}
		display --to LOG --type INFO PROPUPD_OSNAME_FOUND "${OSNAME}"
	fi

	if [ $PRELINKED -eq 0 ]; then
		echo "Prelinked:No" >>${RKHDAT_FILE}
	else
		echo "Prelinked:Yes" >>${RKHDAT_FILE}
	fi

	if ! `check_test hashes`; then
		echo "Hash:Disabled" >>${RKHDAT_FILE}
	elif [ -n "${PRELINK_HASH}" ]; then
		echo "Hash:${PRELINK_HASH}" >>${RKHDAT_FILE}
	else
		echo "Hash:${HASH_FUNC}" >>${RKHDAT_FILE}
	fi

	echo "Pkgmgr:${PKGMGR}" >>${RKHDAT_FILE}

	if ! `check_test attributes`; then
		echo "Attributes:Disabled" >>${RKHDAT_FILE}
	elif [ -z "${STAT_CMD}" ]; then
		echo "Attributes:Nostatcmd" >>${RKHDAT_FILE}
	else
		echo "Attributes:Stored" >>${RKHDAT_FILE}
	fi


	rkh_dat_set_file_properties


	#
	# Now put the new rkhunter.dat file in place.
	#

	cp -f -p ${DB_PATH}/rkhunter.dat ${DB_PATH}/rkhunter.dat.old >/dev/null 2>&1
	cp -f ${RKHDAT_FILE} ${DB_PATH}/rkhunter.dat >/dev/null 2>&1
	ERRCODE=$?

	if [ $ERRCODE -ne 0 ]; then
		RET_CODE=1
		display --to LOG --type INFO CMD_ERROR "cp ${RKHDAT_FILE} ${DB_PATH}/rkhunter.dat" $ERRCODE
		display --to SCREEN+LOG --type WARNING PROPUPD_ERROR $ERRCODE
	else
		display --to LOG --type INFO PROPUPD_NEW_DAT_FILE "${DB_PATH}"
	fi

	chmod 640 ${DB_PATH}/rkhunter.dat >/dev/null 2>&1

	rm -f ${RKHDAT_FILE} >/dev/null 2>&1

	return
}


get_next_mirror() {

	#
	# This function will obtain the next mirror in the mirrors file
	# if no mirror is currently being used. It then optionally
	# rotates the mirrors in the file.
	#


	#
	# Return if there is no mirrors file.
	#

	if [ ! -f "${DB_PATH}/mirrors.dat" ]; then
		display --to LOG --type INFO MIRRORS_NO_FILE "${DB_PATH}/mirrors.dat"
		return
	fi


	#
	# Return if there are no defined mirrors.
	#

	if [ $MIRRORS_MODE -eq 0 ]; then
		MIRROR=`egrep -i '^(local|remote|mirror)=' ${DB_PATH}/mirrors.dat | head -n 1`
	elif [ $MIRRORS_MODE -eq 1 ]; then
		MIRROR=`grep -i '^local=' ${DB_PATH}/mirrors.dat | head -n 1`
	elif [ $MIRRORS_MODE -eq 2 ]; then
		MIRROR=`grep -i '^remote=' ${DB_PATH}/mirrors.dat | head -n 1`
	fi

	if [ -z "${MIRROR}" ]; then
		display --to LOG --type INFO MIRRORS_NO_MIRRORS "${DB_PATH}/mirrors.dat"
		return
	fi


	#
	# If we are not rotating the mirrors, then we need to calculate
	# which one to use next in the list. Return when we have done that.
	#

	if [ $ROTATE_MIRRORS -eq 0 ]; then
		N=`expr $TOTAL_MIRRORS - $MIRROR_COUNT`

		if [ $MIRRORS_MODE -eq 0 ]; then
			MIRROR=`egrep -i '^(local|remote|mirror)=' ${DB_PATH}/mirrors.dat | head -n $N | tail -1 | cut -d= -f2-`
		elif [ $MIRRORS_MODE -eq 1 ]; then
			MIRROR=`grep -i '^local=' ${DB_PATH}/mirrors.dat | head -n $N | tail -1 | cut -d= -f2-`
		elif [ $MIRRORS_MODE -eq 2 ]; then
			MIRROR=`grep -i '^remote=' ${DB_PATH}/mirrors.dat | head -n $N | tail -1 | cut -d= -f2-`
		fi

		return
	fi


	#
	# Now get the version number of the mirrors file. If the version
	# does not exist or is corrupt, then we reset it to zero. This
	# then allows the file to be updated next time the '--update'
	# option is used.
	#

	MIRRORSVERSION=`grep '^[Vv]ersion:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' ${DB_PATH}/mirrors.dat | tail -1`

	if [ -z "${MIRRORSVERSION}" ]; then
		display --to LOG --type INFO MIRRORS_NO_VERSION "${DB_PATH}/mirrors.dat"
		MIRRORSVERSION="Version:0000000000"
	fi


	#
	# Next get the remaining mirrors.
	#

	OTHERMIRRORS=`egrep -i '^(local|remote|mirror)=' ${DB_PATH}/mirrors.dat | grep -v "^${MIRROR}\$"`


	#
	# We need to get a temporary file name to use.
	#

	get_temp_file "${RKHTMPDIR}/mirrors.dat"
	MIRRORS_FILE=$TEMPFILE

	display --to LOG --type INFO CREATED_TEMP_FILE "${MIRRORS_FILE}"


	#
	# Output to the temporary file the mirrors version, the other
	# mirrors, and finally the mirror we are about to use.
	#

	echo "${MIRRORSVERSION}" >${MIRRORS_FILE}

	for RKHM in ${OTHERMIRRORS}; do
		echo "${RKHM}" >>${MIRRORS_FILE}
	done;

	echo "${MIRROR}" >>${MIRRORS_FILE}

	MIRROR=`echo "${MIRROR}" | cut -d= -f2-`


	#
	# Move the new file into place, and delete the temporary file.
	#

	cat ${MIRRORS_FILE} >${DB_PATH}/mirrors.dat

	rm -f ${MIRRORS_FILE} >/dev/null 2>&1

	display --to LOG --type INFO MIRRORS_ROTATED "${DB_PATH}/mirrors.dat"

	return
}


download_file() {

	#
	# This function downloads a specified file. It takes three parameters:
	#     1=mirror, 2=url, 3=output file
	#
	# The URL is just the filename portion. The user will supply the
	# full URL, less the filename, to where the files are stored on
	# the local or remote server. For the SourceForge mirrors we will
	# provide the URL.
	#
	# The function sets a return code (DNLOADERR).
	#

	#
	# We loop round through the mirrors until the file is downloaded.
	# We do this by first seeing how many mirrors are available. Then
	# we call a function to get the next mirror, which also rotates
	# the mirror file. If a mirror has already been set, then that
	# mirror is used. That way, in effect, once we find a good mirror
	# then it will be used for all the downloads.
	#

	MIRROR=$1
	URL=$2
	OUTPUT_FILE=$3

	DNLOADERR=0
	MIRROR_COUNT=0
	TOTAL_MIRRORS=0

	if [ -f "${DB_PATH}/mirrors.dat" ]; then
		#
		# The version check will use both the
		# SF mirrors and remote mirrors.
		#

		if [ $MIRRORS_MODE -eq 0 ]; then
			MIRROR_COUNT=`egrep -i '^(local|remote|mirror)=' ${DB_PATH}/mirrors.dat | wc -l | tr -d ' '`
		elif [ $MIRRORS_MODE -eq 1 ]; then
			MIRROR_COUNT=`grep -i '^local=' ${DB_PATH}/mirrors.dat | wc -l | tr -d ' '`
		elif [ $MIRRORS_MODE -eq 2 ]; then
			MIRROR_COUNT=`grep -i '^remote=' ${DB_PATH}/mirrors.dat | wc -l | tr -d ' '`
		fi

		test -z "${MIRROR_COUNT}" && MIRROR_COUNT=0
	fi

	test $MIRROR_COUNT -eq 0 && MIRROR_COUNT=1

	TOTAL_MIRRORS=$MIRROR_COUNT


	while test $MIRROR_COUNT -gt 0; do
		MIRROR_COUNT=`expr $MIRROR_COUNT - 1`

		if [ -z "${MIRROR}" ]; then
			get_next_mirror

			if [ -z "${MIRROR}" ]; then
				if [ $MIRRORS_MODE -eq 0 ]; then
					MIRROR="http://rkhunter.sourceforge.net"
					display --to LOG --type INFO MIRRORS_SF_DEFAULT "${MIRROR}"
				else
					DNLOADERR=1
					break
				fi
			fi


			#
			# For the SF mirrors add on the final
			# part of the mirror URL.
			#

			if [ "${MIRROR}" = "http://rkhunter.sourceforge.net" ]; then
				MIRROR="${MIRROR}/1.3"
			fi
		fi


		#
		# Now we can download the data into the temporary file.
		#

		# uns - WGET_CMD (cmd, version tested, comments):
		#       wget, *, none.
		#       bget, 1.2, appends output.
		#       curl, 7.15.3: none.
		#       links/elinks, 0.4.2, decompresses output.
		#       lynx, 2.8.5dev.7, decompresses output.

		CMD=""
		DNLOADERR=0

		rm -f ${OUTPUT_FILE} >/dev/null 2>&1

		if [ -n "${WGET_CMD}" ]; then
			CMD="${WGET_CMD} -q -O ${OUTPUT_FILE} ${MIRROR}${URL}"
		elif [ -n "${CURL_CMD}" ]; then
			CMD="${CURL_CMD} --fail --output ${OUTPUT_FILE} ${MIRROR}${URL} 2>/dev/null"
		elif [ -n "${BGET_CMD}" ]; then
			CMD="${BGET_CMD} --out ${OUTPUT_FILE} ${MIRROR}${URL} 2>/dev/null"
		elif [ -n "${ELINKS_CMD}" ]; then
			CMD="${ELINKS_CMD} -no-home 1 -source ${MIRROR}${URL} >${OUTPUT_FILE}"
		elif [ -n "${LINKS_CMD}" ]; then
			CMD="${LINKS_CMD} -no-home 1 -source ${MIRROR}${URL} >${OUTPUT_FILE}"
		elif [ -n "${LYNX_CMD}" ]; then
			CMD="${LYNX_CMD} -source ${MIRROR}${URL} >${OUTPUT_FILE}"
		elif [ -n "${GET_CMD}" ]; then
			CMD="${GET_CMD} ${MIRROR}${URL} >${OUTPUT_FILE}"
		fi

		display --to LOG --type INFO DOWNLOAD_CMD "${CMD}"

		eval ${CMD}
		DNLOADERR=$?

		test $DNLOADERR -gt 1 && DNLOADERR=1


		#
		# Some of these commands do not set the return code. As such we
		# need to look in the output file to see if an error occurred.
		#

		if [ $DNLOADERR -eq 0 ]; then
			if [ -n "`echo \"${URL}\" | grep '/i18n\.ver$'`" ]; then
				#
				# The i18n.ver file is of a different
				# format from the other files.
				#

				:
			elif [ -n "`echo \"${URL}\" | grep '/rkhunter_latest\.dat$'`" ]; then
				#
				# The versioncheck file should just be a version number.
				#

				if [ -z "`grep '^[0-9][0-9]*\.[0-9][.0-9]*$' ${OUTPUT_FILE}`" ]; then
					DNLOADERR=1
				fi
			else
				#
				# All other files should have a normal
				# version number as the first line in them.
				#

				if [ -z "`grep '^[Vv]ersion:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' ${OUTPUT_FILE} | tail -1`" ]; then
					DNLOADERR=1
				fi
			fi
		fi

		test ! -s "${OUTPUT_FILE}" && DNLOADERR=1

		if [ $DNLOADERR -eq 0 ]; then
			break
		elif [ $MIRROR_COUNT -gt 0 ]; then
			MIRROR=""
			display --to LOG --type INFO DOWNLOAD_FAIL $MIRROR_COUNT
		fi
	done

	return $DNLOADERR
}


do_i18n_update() {

	#
	# This function updates the i18n language files.
	#
	# We do not know which i18n files should be checked until we
	# have downloaded the i18n/i18n.ver file. This file will tell
	# us which i18n files are available, and their latest version
	# number. We loop through the files, and check each version
	# number against the installed file.
	#

	download_file "${MIRROR}" "/i18n/${PROGRAM_version}/i18n.ver" "${RKHUPD_FILE}"
	ERRCODE=$?

	if [ $ERRCODE -eq 0 ]; then
		#
		# Check that we have some version numbers. There
		# should always be at least one, for the English
		# language! Once we have the list of files, we can
		# remove the temporary file and re-use it when
		# downloading the language files.
		#

		FOUNDFILES=`grep '^[a-zA-Z][a-zA-Z0-9._-]*:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' ${RKHUPD_FILE}`

		rm -f ${RKHUPD_FILE} >/dev/null 2>&1

		if [ -z "${FOUNDFILES}" ]; then
			RET_CODE=1
			UPD_ERROR=1

			display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color RED --result UPD_FAILED UPDATE_CHECKING_FILE "i18n versions"

			display --to LOG --type WARNING UPDATE_I18N_NO_VERS

			return
		fi


		#
		# Now loop through the language files checking their
		# version numbers.
		#

		for FNAME in ${FOUNDFILES}; do
			LANGFILE=`echo "${FNAME}" | cut -d: -f1`
			LATEST_VERS=`echo "${FNAME}" | cut -d: -f2`

			if [ -s "${DB_PATH}/i18n/${LANGFILE}" ]; then
				PROG_VERS=`grep '^[Vv]ersion:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' ${DB_PATH}/i18n/${LANGFILE} 2>/dev/null | tail -1 | cut -d: -f2`

				if [ -n "${PROG_VERS}" -a -z "`echo \"${PROG_VERS}\" | grep '^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$'`" ]; then
					PROG_VERS=`head -n 1 ${DB_PATH}/i18n/${LANGFILE} | grep '^[Vv]ersion:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' | cut -d: -f2`
				fi

				if [ -z "${PROG_VERS}" ]; then
					PROG_VERS=0
					display --to LOG --type INFO UPDATE_FILE_NO_VERS "${DB_PATH}/i18n/${LANGFILE}"
				fi
			else
				PROG_VERS=0

				touch ${DB_PATH}/i18n/${LANGFILE} >/dev/null 2>&1
				chmod 640 ${DB_PATH}/i18n/${LANGFILE} >/dev/null 2>&1

				display --to LOG --type INFO UPDATE_FILE_MISSING "${DB_PATH}/i18n/${LANGFILE}"
			fi


			display --to LOG --type INFO VERSIONCHECK_CURRENT "${PROG_VERS}"
			display --to LOG --type INFO VERSIONCHECK_LATEST "${LATEST_VERS}"


			if [ $PROG_VERS -lt $LATEST_VERS ]; then
				download_file "${MIRROR}" "/i18n/${PROGRAM_version}/${LANGFILE}" "${RKHUPD_FILE}"
				ERRCODE=$?

				if [ $ERRCODE -eq 0 ]; then
					test $RET_CODE -eq 0 && RET_CODE=2

					cat ${RKHUPD_FILE} >${DB_PATH}/i18n/${LANGFILE}

					display --to LOG --type INFO VERSIONCHECK_UPDT_AVAIL
					display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color GREEN --result UPD UPDATE_CHECKING_FILE "i18n/${LANGFILE}"
				else
					RET_CODE=1
					UPD_ERROR=1

					display --to LOG --type WARNING UPDATE_DOWNLOAD_FAIL "i18n/${LANGFILE}"
					display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color RED --result UPD_FAILED UPDATE_CHECKING_FILE "i18n/${LANGFILE}"
				fi

				rm -f ${RKHUPD_FILE} >/dev/null 2>&1
			else
				display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color GREEN --result NO_UPD UPDATE_CHECKING_FILE "i18n/${LANGFILE}"
			fi
		done
	else
		RET_CODE=1
		UPD_ERROR=1

		display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color RED --result UPD_FAILED UPDATE_CHECKING_FILE "i18n versions"

		display --to LOG --type WARNING UPDATE_DOWNLOAD_FAIL "i18n.ver"
	fi


	rm -f ${RKHUPD_FILE} >/dev/null 2>&1

	return
}


do_update() {

	#
	# This function checks to see if any of the supplied RKH
	# *.dat and i18n files needs updating. If it does, then the
	# file is overwritten with the new version.
	#

	display --to SCREEN+LOG --type PLAIN --color YELLOW --nl UPDATE_START


	#
	# First we need to get a temporary file name to use.
	#

	get_temp_file "${RKHTMPDIR}/rkhunter.upd"
	RKHUPD_FILE=$TEMPFILE

	display --to LOG --type INFO CREATED_TEMP_FILE "${RKHUPD_FILE}"


	#
	# Now we loop round through the files we need to check. Each file
	# will use the first mirror, and if necessary loop through the
	# remaining mirrors until the file is downloaded. In theory this
	# could take some time if the mirror sites are all experiencing
	# problems and this is affecting all the files.
	#
	# For each file we look at the current version number. If there
	# is a problem doing this, then we just try and download a new
	# copy of the file. If the version number is okay, then we
	# download the file to find the latest version number. If
	# that is successful, we then update the file if necessary.
	#

	UPD_ERROR=0
	MIRROR=""

	for UPDFILE in mirrors.dat programs_bad.dat backdoorports.dat suspscan.dat; do
		if [ $UPDATE_MIRRORS -eq 0 -a "${UPDFILE}" = "mirrors.dat" ]; then
			display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color GREEN --result SKIPPED UPDATE_CHECKING_FILE "${UPDFILE}"
			continue
		fi


		LATEST_VERS=0

		if [ -s "${DB_PATH}/${UPDFILE}" ]; then
			PROG_VERS=`grep '^[Vv]ersion:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' ${DB_PATH}/${UPDFILE} | tail -1 | cut -d: -f2`

			if [ -n "${PROG_VERS}" -a -z "`echo \"${PROG_VERS}\" | grep '^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$'`" ]; then
				PROG_VERS=`head -n 1 ${DB_PATH}/${UPDFILE} | grep '^[Vv]ersion:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' | cut -d: -f2`
			fi

			if [ -z "${PROG_VERS}" ]; then
				PROG_VERS=0
				display --to LOG --type INFO UPDATE_FILE_NO_VERS "${UPDFILE}"
			fi
		else
			PROG_VERS=0

			touch ${DB_PATH}/${UPDFILE} >/dev/null 2>&1
			chmod 640 ${DB_PATH}/${UPDFILE} >/dev/null 2>&1

			display --to LOG --type INFO UPDATE_FILE_MISSING "${UPDFILE}"
		fi


		#
		# Now download the file.
		#
		# Note: To avoid any backward incompatability we
		# get the files from a specific directory which
		# previous versions do not use.
		#

		download_file "${MIRROR}" "/${UPDFILE}" "${RKHUPD_FILE}"
		ERRCODE=$?


		#
		# Next we compare the current and downloaded
		# file version numbers.
		#

		if [ $ERRCODE -eq 0 ]; then
			LATEST_VERS=`grep '^[Vv]ersion:[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$' ${RKHUPD_FILE} | tail -1 | cut -d: -f2`

			if [ -z "${LATEST_VERS}" ]; then
				LATEST_VERS=0
			elif [ -z "`echo \"${LATEST_VERS}\" | grep '^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]$'`" ]; then
				LATEST_VERS=0
			fi


			display --to LOG --type INFO VERSIONCHECK_CURRENT "${PROG_VERS}"
			display --to LOG --type INFO VERSIONCHECK_LATEST "${LATEST_VERS}"

			if [ $LATEST_VERS -eq 0 ]; then
				RET_CODE=1
				UPD_ERROR=1

				display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color RED --result VCHK_FAILED UPDATE_CHECKING_FILE "${UPDFILE}"

				LATEST_VERS=`head -n 1 ${RKHUPD_FILE}`

				display --to LOG --type WARNING VERSIONCHECK_CONV_FAIL "${PROG_VERS}" "${LATEST_VERS}"
			elif [ $PROG_VERS -lt $LATEST_VERS ]; then
				test $RET_CODE -eq 0 && RET_CODE=2

				display --to LOG --type INFO VERSIONCHECK_UPDT_AVAIL

				cat ${RKHUPD_FILE} >${DB_PATH}/${UPDFILE}

				display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color GREEN --result UPD UPDATE_CHECKING_FILE "${UPDFILE}"
			else
				display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color GREEN --result NO_UPD UPDATE_CHECKING_FILE "${UPDFILE}"
			fi
		else
			RET_CODE=1
			UPD_ERROR=1

			display --to LOG --type WARNING UPDATE_DOWNLOAD_FAIL "${UPDFILE}"
			display --to SCREEN+LOG --type PLAIN --screen-indent 2 --color RED --result UPD_FAILED UPDATE_CHECKING_FILE "${UPDFILE}"
		fi

		rm -f ${RKHUPD_FILE} >/dev/null 2>&1
	done


	#
	# We now need to update the i18n files. Since this is a little
	# more complicated, it is handled in a separate function.
	#

	do_i18n_update


	if [ $UPD_ERROR -eq 1 ]; then
		if [ $NOLOG -eq 1 ]; then
			display --to SCREEN --type PLAIN --nl --nl-after CHECK_WARNINGS_FOUND_RERUN
		else
			display --to SCREEN --type PLAIN --nl --nl-after CHECK_WARNINGS_FOUND_CHK_LOG "${RKHLOGFILE}"
		fi
	fi

	return
}


do_versioncheck() {

	#
	# This function performs a program version check.
	#
	# It will set the return code in some instances:
	#       0 - (implied) no error, no new version available
	#	1 - a download (of the version number) error occurred
	#	2 - no error occurred, but a new version is available
	#

	MIRROR=""
	LATESTVERSION=""

	display --to SCREEN+LOG --type PLAIN --color YELLOW --nl VERSIONCHECK_START


	#
	# First we need to get a temporary file name to use.
	#

	get_temp_file "${RKHTMPDIR}/rkhunter.vc"
	RKHVC_FILE=$TEMPFILE

	display --to LOG --type INFO CREATED_TEMP_FILE "${RKHVC_FILE}"


	#
	# Next we get the current program version number.
	#

	PROG_VERS=`echo "${PROGRAM_version}" | cut -d. -f1-3 | sed -e 's/\.\([0-9]\)\./.0\1./' | sed -e 's/\.\([0-9]\)$/.0\1/' | tr -d '.'`

	test -z "${PROG_VERS}" && PROG_VERS=0

	display --to SCREEN+LOG --type PLAIN --screen-indent 2 VERSIONCHECK_CURRENT "${PROGRAM_version}"


	#
	# Download the file, and then compare the current value
	# with the downloaded one.
	#

	download_file "${MIRROR}" "/rkhunter_latest.dat" "${RKHVC_FILE}"
	ERRCODE=$?

	if [ $ERRCODE -eq 0 ]; then
		LATESTVERSION=`cat ${RKHVC_FILE} 2>/dev/null`

		#
		# Convert the version string to zero-spaced numbers.
		# This allows us to numerically compare the versions,
		# even when the numbers go above ten.
		#
		# E.g. '1.2.10' => 10210,   '1.3.2' => 10302.
		#

		LATEST_VERS=`echo "${LATESTVERSION}" | cut -d. -f1-3 | sed -e 's/\.\([0-9]\)\./.0\1./' | sed -e 's/\.\([0-9]\)$/.0\1/' | tr -d '.'`

		test -z "${LATEST_VERS}" && LATEST_VERS=0

		display --to SCREEN+LOG --type PLAIN --screen-indent 2 VERSIONCHECK_LATEST "${LATESTVERSION}"

		if [ $LATEST_VERS -eq 0 ]; then
			RET_CODE=1
			display --to SCREEN+LOG --type WARNING --screen-indent 2 VERSIONCHECK_CONV_FAIL "${PROGRAM_version}" "${LATESTVERSION}"
		elif [ $PROG_VERS -lt $LATEST_VERS ]; then
			test $RET_CODE -eq 0 && RET_CODE=2
			display --to SCREEN+LOG --type PLAIN --screen-indent 2 VERSIONCHECK_UPDT_AVAIL
		fi
	else
		RET_CODE=1

		display --to LOG --type WARNING VERSIONCHECK_FAIL_ALL
		display --to SCREEN+LOG --type PLAIN --screen-indent 2 VERSIONCHECK_LATEST_FAIL
	fi

	rm -f ${RKHVC_FILE} >/dev/null 2>&1

	return
}


do_system_check_initialisation() {

	#
	# This function simply initialises the default rootkit
	# files and directories.
	#


	# 55808 Variant A
	W55808A_FILES="${RKHROOTDIR}/tmp/.../r
		       ${RKHROOTDIR}/tmp/.../a"


	# AjaKit Rootkit
	AJAKIT_FILES="${RKHROOTDIR}/dev/tux/.addr
		      ${RKHROOTDIR}/dev/tux/.proc
		      ${RKHROOTDIR}/dev/tux/.file
		      ${RKHROOTDIR}/lib/.libgh-gh/cleaner
		      ${RKHROOTDIR}/lib/.libgh-gh/Patch/patch
		      ${RKHROOTDIR}/lib/.libgh-gh/sb0k"
	AJAKIT_DIRS="${RKHROOTDIR}/dev/tux
		     ${RKHROOTDIR}/lib/.libgh-gh"


	# aPa Kit Rootkit
	APAKIT_FILES="${RKHROOTDIR}/usr/share/.aPa"


	# Apache Worm
	APACHEWORM_FILES="${RKHROOTDIR}/bin/.log"


	# Ambient (ark) Rootkit
	ARK_FILES="${RKHROOTDIR}/usr/lib/.ark?
		   ${RKHROOTDIR}/dev/ptyxx/.log
		   ${RKHROOTDIR}/dev/ptyxx/.file"
	ARK_DIRS="${RKHROOTDIR}/dev/ptyxx"


	# Balaur Rootkit 2.0 (LRK5 based)
	BALAUR_FILES="${RKHROOTDIR}/usr/lib/liblog.o"
	BALAUR_DIRS="${RKHROOTDIR}/usr/lib/.kinetic
		     ${RKHROOTDIR}/usr/lib/.egcs
		     ${RKHROOTDIR}/usr/lib/.wormie"


	# Beastkit Rootkit
	BEASTKIT_FILES="${RKHROOTDIR}/usr/sbin/arobia
			${RKHROOTDIR}/usr/sbin/idrun
			${RKHROOTDIR}/usr/lib/elm/arobia/elm
			${RKHROOTDIR}/usr/lib/elm/arobia/elm/hk
			${RKHROOTDIR}/usr/lib/elm/arobia/elm/hk.pub
			${RKHROOTDIR}/usr/lib/elm/arobia/elm/sc
			${RKHROOTDIR}/usr/lib/elm/arobia/elm/sd.pp
			${RKHROOTDIR}/usr/lib/elm/arobia/elm/sdco
			${RKHROOTDIR}/usr/lib/elm/arobia/elm/srsd"
	BEASTKIT_DIRS="${RKHROOTDIR}/lib/ldd.so/bktools"


	# beX2 Rootkit
	BEX_DIRS="${RKHROOTDIR}/usr/include/bex"


	# BOBkit Rootkit
	BOBKIT_FILES="${RKHROOTDIR}/usr/sbin/ntpsx
		      ${RKHROOTDIR}/usr/lib/.../ls
		      ${RKHROOTDIR}/usr/lib/.../netstat
		      ${RKHROOTDIR}/usr/lib/.../lsof
		      ${RKHROOTDIR}/usr/lib/.../bkit-ssh/bkit-shdcfg
		      ${RKHROOTDIR}/usr/lib/.../bkit-ssh/bkit-shhk
		      ${RKHROOTDIR}/usr/lib/.../bkit-ssh/bkit-pw
		      ${RKHROOTDIR}/usr/lib/.../bkit-ssh/bkit-shrs
		      ${RKHROOTDIR}/usr/lib/.../uconf.inv
		      ${RKHROOTDIR}/usr/lib/.../psr
		      ${RKHROOTDIR}/usr/lib/.../find
		      ${RKHROOTDIR}/usr/lib/.../pstree
		      ${RKHROOTDIR}/usr/lib/.../slocate
		      ${RKHROOTDIR}/usr/lib/.../du
		      ${RKHROOTDIR}/usr/lib/.../top"
	BOBKIT_DIRS="${RKHROOTDIR}/usr/lib/...
		     ${RKHROOTDIR}/usr/lib/.../bkit-ssh
		     ${RKHROOTDIR}/usr/lib/.bkit-
		     ${RKHROOTDIR}/tmp/.bkp"


	# CiNIK Worm (Slapper.B variant)
	CINIK_FILES="${RKHROOTDIR}/tmp/.cinik"
	CINIK_DIRS="${RKHROOTDIR}/tmp/.font-unix/.cinik"


	# Danny-Boy's Abuse Kit
	DANNYBOYS_FILES="${RKHROOTDIR}/dev/mdev
			 ${RKHROOTDIR}/usr/lib/libX.a"


	# Devil Rootkit
	DEVIL_FILES="${RKHROOTDIR}/var/lib/games/.src
		     ${RKHROOTDIR}/dev/dsx
		     ${RKHROOTDIR}/dev/caca"


	# Dica-Kit (T0rn variant) Rootkit
	DICA_FILES="${RKHROOTDIR}/lib/.sso
		    ${RKHROOTDIR}/lib/.so
		    ${RKHROOTDIR}/var/run/...dica/clean
		    ${RKHROOTDIR}/var/run/...dica/xl
		    ${RKHROOTDIR}/var/run/...dica/xdr
		    ${RKHROOTDIR}/var/run/...dica/psg
		    ${RKHROOTDIR}/var/run/...dica/secure
		    ${RKHROOTDIR}/var/run/...dica/rdx
		    ${RKHROOTDIR}/var/run/...dica/va
		    ${RKHROOTDIR}/var/run/...dica/cl.sh
		    ${RKHROOTDIR}/usr/bin/.etc"
	DICA_DIRS="${RKHROOTDIR}/var/run/...dica
		   ${RKHROOTDIR}/var/run/...dica/mh
		   ${RKHROOTDIR}/var/run/...dica/scan"


	# Dreams Rootkit
	DREAMS_FILES="${RKHROOTDIR}/dev/ttyoa
		      ${RKHROOTDIR}/dev/ttyof
		      ${RKHROOTDIR}/dev/ttyop
		      ${RKHROOTDIR}/usr/bin/sense
		      ${RKHROOTDIR}/usr/bin/sl2
		      ${RKHROOTDIR}/usr/bin/logclear
		      ${RKHROOTDIR}/usr/bin/(swapd)
		      ${RKHROOTDIR}/usr/bin/snfs
		      ${RKHROOTDIR}/usr/lib/libsss"
	DREAMS_DIRS="${RKHROOTDIR}/dev/ida/.hpd"


	# Duarawkz Rootkit
	DUARAWKZ_FILES="${RKHROOTDIR}/usr/bin/duarawkz/loginpass"
	DUARAWKZ_DIRS="${RKHROOTDIR}/usr/bin/duarawkz"

	# ENYE LKM v1.1
	# Installer default.
	ENYELKM_FILES="${RKHROOTDIR}/etc/.enyelkmHIDE^IT.ko"

	# Flea Linux Rootkit
	FLEA_FILES="${RKHROOTDIR}/etc/ld.so.hash
		    ${RKHROOTDIR}/lib/security/.config/ssh/ssh_host_key
		    ${RKHROOTDIR}/lib/security/.config/ssh/ssh_host_key.pub
		    ${RKHROOTDIR}/lib/security/.config/ssh/ssh_random_seed
		    ${RKHROOTDIR}/usr/bin/ssh2d
		    ${RKHROOTDIR}/usr/lib/ldlibns.so
		    ${RKHROOTDIR}/usr/lib/ldlibpst.so
		    ${RKHROOTDIR}/usr/lib/ldlibdu.so
		    ${RKHROOTDIR}/usr/lib/ldlibct.so"
	FLEA_DIRS="${RKHROOTDIR}/lib/security/.config/ssh
		   ${RKHROOTDIR}/dev/..0
		   ${RKHROOTDIR}/dev/..0/backup"


	# FreeBSD Rootkit
	FREEBSD_RK_FILES="${RKHROOTDIR}/usr/lib/.fx/sched_host.2
			  ${RKHROOTDIR}/usr/lib/.fx/random_d.2
			  ${RKHROOTDIR}/usr/lib/.fx/set_pid.2
			  ${RKHROOTDIR}/usr/lib/.fx/cons.saver
			  ${RKHROOTDIR}/usr/lib/.fx/adore/adore/adore.ko
			  ${RKHROOTDIR}/bin/sysback
			  ${RKHROOTDIR}/usr/local/bin/sysback"
	FREEBSD_RK_DIRS="${RKHROOTDIR}/usr/lib/.fx
			 ${RKHROOTDIR}/usr/lib/.fx/adore"


	# Fuckit Rootkit
	FUCKIT_FILES="${RKHROOTDIR}/dev/proc/fuckit/hax0r
		      ${RKHROOTDIR}/dev/proc/fuckit/hax0rshell
		      ${RKHROOTDIR}/dev/proc/fuckit/config/lports
		      ${RKHROOTDIR}/dev/proc/fuckit/config/rports
		      ${RKHROOTDIR}/dev/proc/fuckit/config/rkconf
		      ${RKHROOTDIR}/dev/proc/fuckit/config/password
		      ${RKHROOTDIR}/dev/proc/fuckit/config/progs
		      ${RKHROOTDIR}/dev/proc/system-bins/init"


	# GasKit Rootkit
	GASKIT_FILES="${RKHROOTDIR}/dev/dev/gaskit/sshd/sshdd"
	GASKIT_DIRS="${RKHROOTDIR}/dev/dev
		     ${RKHROOTDIR}/dev/dev/gaskit
		     ${RKHROOTDIR}/dev/dev/gaskit/sshd"


	# Heroin LKM
	HEROIN_KSYMS="heroin"


	# HjC Kit Rootkit
	HJCKIT_DIRS="${RKHROOTDIR}/dev/.hijackerz"


	# ignoKit Rootkit
	IGNOKIT_FILES="${RKHROOTDIR}/lib/defs/p
		       ${RKHROOTDIR}/lib/defs/q
		       ${RKHROOTDIR}/lib/defs/r
		       ${RKHROOTDIR}/lib/defs/s
		       ${RKHROOTDIR}/lib/defs/t
		       ${RKHROOTDIR}/usr/lib/defs/p
		       ${RKHROOTDIR}/usr/lib/defs/q
		       ${RKHROOTDIR}/usr/lib/defs/r
		       ${RKHROOTDIR}/usr/lib/defs/s
		       ${RKHROOTDIR}/usr/lib/defs/t
		       ${RKHROOTDIR}/usr/lib/.libigno/pkunsec
		       ${RKHROOTDIR}/usr/lib/.libigno/.igno/psybnc/psybnc"
	IGNOKIT_DIRS="${RKHROOTDIR}/usr/lib/.libigno
		      ${RKHROOTDIR}/usr/lib/.libigno/.igno"


	# ImperalsS-FBRK (FreeBSD Rootkit)
	IMPFRB_DIRS="${RKHROOTDIR}/dev/fd/.88
		     ${RKHROOTDIR}/dev/fd/.99"


	# Irix Rootkit (for Irix 6.x)
	IRIXRK_DIRS="${RKHROOTDIR}/dev/pts/01
		     ${RKHROOTDIR}/dev/pts/01/backup
		     ${RKHROOTDIR}/dev/pts/01/etc
		     ${RKHROOTDIR}/dev/pts/01/tmp"


	# Kitko Rootkit
	KITKO_DIRS="${RKHROOTDIR}/usr/src/redhat/SRPMS/..."


	# Knark Rootkit
	KNARK_FILES="${RKHROOTDIR}/proc/knark/pids"
	KNARK_DIRS="${RKHROOTDIR}/proc/knark"


	# Lion Worm
	LION_FILES="${RKHROOTDIR}/bin/in.telnetd
		    ${RKHROOTDIR}/bin/mjy
		    ${RKHROOTDIR}/usr/man/man1/man1/lib/.lib/mjy
		    ${RKHROOTDIR}/usr/man/man1/man1/lib/.lib/in.telnetd
		    ${RKHROOTDIR}/usr/man/man1/man1/lib/.lib/.x
		    ${RKHROOTDIR}/dev/.lib/lib/scan/1i0n.sh
		    ${RKHROOTDIR}/dev/.lib/lib/scan/hack.sh
		    ${RKHROOTDIR}/dev/.lib/lib/scan/bind
		    ${RKHROOTDIR}/dev/.lib/lib/scan/randb
		    ${RKHROOTDIR}/dev/.lib/lib/scan/scan.sh
		    ${RKHROOTDIR}/dev/.lib/lib/scan/pscan
		    ${RKHROOTDIR}/dev/.lib/lib/scan/star.sh
		    ${RKHROOTDIR}/dev/.lib/lib/scan/bindx.sh
		    ${RKHROOTDIR}/dev/.lib/lib/scan/bindname.log
		    ${RKHROOTDIR}/dev/.lib/lib/1i0n.sh
		    ${RKHROOTDIR}/dev/.lib/lib/lib/netstat
		    ${RKHROOTDIR}/dev/.lib/lib/lib/dev/.1addr
		    ${RKHROOTDIR}/dev/.lib/lib/lib/dev/.1logz
		    ${RKHROOTDIR}/dev/.lib/lib/lib/dev/.1proc
		    ${RKHROOTDIR}/dev/.lib/lib/lib/dev/.1file"


	# Lockit (a.k.a. LJK2) Rootkit
	LOCKIT_FILES="${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/ssh_config
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/ssh_host_key
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/ssh_host_key.pub
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/ssh_random_seed*
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/sshd_config
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backdoor/RK1bd
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backup/du
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backup/ifconfig
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backup/inetd.conf
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backup/locate
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backup/login
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backup/ls
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backup/netstat
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backup/ps
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backup/pstree
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backup/rc.sysinit
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backup/syslogd
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backup/tcpd
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/backup/top
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/clean/RK1sauber
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/clean/RK1wted
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/hack/RK1parser
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/hack/RK1sniff
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/hide/.RK1addr
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/hide/.RK1dir
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/hide/.RK1log
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/hide/.RK1proc
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/hide/RK1phidemod.c
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/modules/README.modules
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/modules/RK1hidem.c
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/modules/RK1phide
		      ${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2/sshconfig/RK1ssh"
	LOCKIT_DIRS="${RKHROOTDIR}/usr/lib/libmen.oo/.LJK2"


	# MRK (MiCrobul?) RootKit (based on Devil RootKit)
	MRK_FILES="${RKHROOTDIR}/dev/ida/.inet/pid
		   ${RKHROOTDIR}/dev/ida/.inet/ssh_host_key
		   ${RKHROOTDIR}/dev/ida/.inet/ssh_random_seed
		   ${RKHROOTDIR}/dev/ida/.inet/tcp.log"
	MRK_DIRS="${RKHROOTDIR}/dev/ida/.inet
		  ${RKHROOTDIR}/var/spool/cron/.sh"


	# Mood-NT Rootkit
	# Binary is by default called "mood-nt" but can be anywhere.
	# Here we look for collaterals, from include/prefs.h defaults
	# until sig-based dirscan() is added.
	MOODNT_FILES="${RKHROOTDIR}/sbin/init__mood-nt-_-_cthulhu
		      ${RKHROOTDIR}/_cthulhu/mood-nt.init
		      ${RKHROOTDIR}/_cthulhu/mood-nt.conf
		      ${RKHROOTDIR}/_cthulhu/mood-nt.sniff"
	MOODNT_DIRS="${RKHROOTDIR}/_cthulhu"


	# Ni0 Rootkit
	NIO_FILES="${RKHROOTDIR}/var/lock/subsys/...datafile.../...net...
		   ${RKHROOTDIR}/var/lock/subsys/...datafile.../...port...
		   ${RKHROOTDIR}/var/lock/subsys/...datafile.../...ps...
		   ${RKHROOTDIR}/var/lock/subsys/...datafile.../...file..."
	NIO_DIRS="${RKHROOTDIR}/tmp/waza
		  ${RKHROOTDIR}/var/lock/subsys/...datafile...
		  ${RKHROOTDIR}/usr/sbin/es"


	# Ohhara Rootkit
	OHHARA_FILES="${RKHROOTDIR}/var/lock/subsys/...datafile.../...datafile.../in.smbd.log"
	OHHARA_DIRS="${RKHROOTDIR}/var/lock/subsys/...datafile...
		     ${RKHROOTDIR}/var/lock/subsys/...datafile.../...datafile...
		     ${RKHROOTDIR}/var/lock/subsys/...datafile.../...datafile.../bin
		     ${RKHROOTDIR}/var/lock/subsys/...datafile.../...datafile.../usr/bin
		     ${RKHROOTDIR}/var/lock/subsys/...datafile.../...datafile.../usr/sbin
		     ${RKHROOTDIR}/var/lock/subsys/...datafile.../...datafile.../lib/security"


	# Optic Kit (Tux variant) Rootkit
	OPTICKIT_DIRS="${RKHROOTDIR}/dev/tux
		       ${RKHROOTDIR}/usr/bin/xchk
		       ${RKHROOTDIR}/usr/bin/xsf
		       ${RKHROOTDIR}/usr/bin/ssh2d"


	# Oz Rootkit
	OZ_FILES="${RKHROOTDIR}/dev/.oz/.nap/rkit/terror"
	OZ_DIRS="${RKHROOTDIR}/dev/.oz"


	# PHALANX Rootkit
	PHALANX_FILES="${RKHROOTDIR}/usr/share/.home.ph1/cb
		       ${RKHROOTDIR}/etc/host.ph1
		       ${RKHROOTDIR}/bin/host.ph1
		       ${RKHROOTDIR}/usr/share/.home.ph1/phalanx"
	PHALANX_DIRS="${RKHROOTDIR}/usr/share/.home.ph1"


	# Portacelo Rootkit
	PORTACELO_FILES="${RKHROOTDIR}/var/lib/.../.ak
			 ${RKHROOTDIR}/var/lib/.../.hk
			 ${RKHROOTDIR}/var/lib/.../.rs
			 ${RKHROOTDIR}/var/lib/.../.p
			 ${RKHROOTDIR}/var/lib/.../getty
			 ${RKHROOTDIR}/var/lib/.../lkt.o
			 ${RKHROOTDIR}/var/lib/.../show
			 ${RKHROOTDIR}/var/lib/.../nlkt.o
			 ${RKHROOTDIR}/var/lib/.../ssshrc
			 ${RKHROOTDIR}/var/lib/.../sssh_equiv
			 ${RKHROOTDIR}/var/lib/.../sssh_known_hosts
			 ${RKHROOTDIR}/var/lib/.../sssh_pid ~/.sssh/known_hosts"


	# R3dstorm Toolkit
	REDSTORM_FILES="${RKHROOTDIR}/var/log/tk02/see_all
			${RKHROOTDIR}/bin/.../sshd/sbin/sshd1
			${RKHROOTDIR}/bin/.../hate/sk
			${RKHROOTDIR}/bin/.../see_all"
	REDSTORM_DIRS="${RKHROOTDIR}/var/log/tk02
		       ${RKHROOTDIR}/var/log/tk02/old
		       ${RKHROOTDIR}/bin/..."


	# RH-Sharpe's Rootkit
	RHSHARPES_FILES="${RKHROOTDIR}/bin/lps
			 ${RKHROOTDIR}/usr/bin/lpstree
			 ${RKHROOTDIR}/usr/bin/ltop
			 ${RKHROOTDIR}/usr/bin/lkillall
			 ${RKHROOTDIR}/usr/bin/ldu
			 ${RKHROOTDIR}/usr/bin/lnetstat
			 ${RKHROOTDIR}/usr/bin/wp
			 ${RKHROOTDIR}/usr/bin/shad
			 ${RKHROOTDIR}/usr/bin/vadim
			 ${RKHROOTDIR}/usr/bin/slice
			 ${RKHROOTDIR}/usr/bin/cleaner
			 ${RKHROOTDIR}/usr/include/rpcsvc/du"


	# RSHA's Rootkit
	RSHA_FILES="${RKHROOTDIR}/bin/kr4p
		    ${RKHROOTDIR}/usr/bin/n3tstat
		    ${RKHROOTDIR}/usr/bin/chsh2
		    ${RKHROOTDIR}/usr/bin/slice2
		    ${RKHROOTDIR}/usr/src/linux/arch/alpha/lib/.lib/.1proc
		    ${RKHROOTDIR}/etc/rc.d/arch/alpha/lib/.lib/.1addr"
	RSHA_DIRS="${RKHROOTDIR}/etc/rc.d/rsha
		   ${RKHROOTDIR}/etc/rc.d/arch/alpha/lib/.lib"


	# Shutdown Rootkit
	# The '%' character represents a space.
	SHUTDOWN_FILES="${RKHROOTDIR}/usr/man/man5/..%/.dir/scannah/asus
			${RKHROOTDIR}/usr/man/man5/..%/.dir/see
			${RKHROOTDIR}/usr/man/man5/..%/.dir/nscd
			${RKHROOTDIR}/usr/man/man5/..%/.dir/alpd
			${RKHROOTDIR}/etc/rc.d/rc.local%"
	SHUTDOWN_DIRS="${RKHROOTDIR}/usr/man/man5/..%/.dir
		       ${RKHROOTDIR}/usr/man/man5/..%/.dir/scannah
		       ${RKHROOTDIR}/etc/rc.d/rc0.d/..%/.dir"


	# Scalper (FreeBSD.Scalper.Worm) Worm
	SCALPER_FILES="${RKHROOTDIR}/tmp/.a
		       ${RKHROOTDIR}/tmp/.uua"


	# SHV4 Rootkit
	SHV4_FILES="${RKHROOTDIR}/etc/ld.so.hash
		    ${RKHROOTDIR}/lib/libext-2.so.7
		    ${RKHROOTDIR}/lib/lidps1.so
		    ${RKHROOTDIR}/usr/sbin/xntps"
	SHV4_DIRS="${RKHROOTDIR}/lib/security/.config
		   ${RKHROOTDIR}/lib/security/.config/ssh"


	# SHV5 Rootkit
	SHV5_FILES="${RKHROOTDIR}/etc/sh.conf
		    ${RKHROOTDIR}/dev/srd0"
	SHV5_DIRS="${RKHROOTDIR}/usr/lib/libsh"


	# Sin Rootkit
	SINROOTKIT_FILES="${RKHROOTDIR}/dev/.haos/haos1/.f/Denyed
			  ${RKHROOTDIR}/dev/ttyoa
			  ${RKHROOTDIR}/dev/ttyof
			  ${RKHROOTDIR}/dev/ttyop
			  ${RKHROOTDIR}/dev/ttyos
			  ${RKHROOTDIR}/usr/lib/.lib
			  ${RKHROOTDIR}/usr/lib/sn/.X
			  ${RKHROOTDIR}/usr/lib/sn/.sys
			  ${RKHROOTDIR}/usr/lib/ld/.X
			  ${RKHROOTDIR}/usr/man/man1/...
			  ${RKHROOTDIR}/usr/man/man1/.../.m
			  ${RKHROOTDIR}/usr/man/man1/.../.w"
	SINROOTKIT_DIRS="${RKHROOTDIR}/usr/lib/sn
			 ${RKHROOTDIR}/usr/lib/man1/...
			 ${RKHROOTDIR}/dev/.haos"


	# Slapper Worm
	SLAPPER_FILES="${RKHROOTDIR}/tmp/.bugtraq
		       ${RKHROOTDIR}/tmp/.uubugtraq
		       ${RKHROOTDIR}/tmp/.bugtraq.c
		       ${RKHROOTDIR}/tmp/httpd
		       ${RKHROOTDIR}/tmp/.unlock
		       ${RKHROOTDIR}/tmp/update
		       ${RKHROOTDIR}/tmp/.cinik
		       ${RKHROOTDIR}/tmp/.b"


	# Sneakin Rootkit
	SNEAKIN_DIRS="${RKHROOTDIR}/tmp/.X11-unix/.../rk"


	# Suckit Rootkit
	SUCKIT_FILES="${RKHROOTDIR}/sbin/initsk12
		      ${RKHROOTDIR}/sbin/initxrk
		      ${RKHROOTDIR}/usr/bin/null
		      ${RKHROOTDIR}/usr/share/locale/sk/.sk12/sk
		      ${RKHROOTDIR}/etc/rc.d/rc0.d/S23kmdac
		      ${RKHROOTDIR}/etc/rc.d/rc1.d/S23kmdac
		      ${RKHROOTDIR}/etc/rc.d/rc2.d/S23kmdac
		      ${RKHROOTDIR}/etc/rc.d/rc3.d/S23kmdac
		      ${RKHROOTDIR}/etc/rc.d/rc4.d/S23kmdac
		      ${RKHROOTDIR}/etc/rc.d/rc5.d/S23kmdac
		      ${RKHROOTDIR}/etc/rc.d/rc6.d/S23kmdac"
	SUCKIT_DIRS="${RKHROOTDIR}/dev/sdhu0/tehdrakg
		     ${RKHROOTDIR}/etc/.MG
		     ${RKHROOTDIR}/usr/share/locale/sk/.sk12
		     ${RKHROOTDIR}/usr/lib/perl5/site_perl/i386-linux/auto/TimeDate/.packlist"


	# SunOS / NSDAP Rootkit
	NSDAP_FILES="${RKHROOTDIR}/usr/lib/vold/nsdap/.kit
		     ${RKHROOTDIR}/usr/lib/vold/nsdap/defines
		     ${RKHROOTDIR}/usr/lib/vold/nsdap/patcher
		     ${RKHROOTDIR}/usr/lib/vold/nsdap/pg
		     ${RKHROOTDIR}/usr/lib/vold/nsdap/cleaner
		     ${RKHROOTDIR}/usr/lib/vold/nsdap/utime
		     ${RKHROOTDIR}/usr/lib/vold/nsdap/crypt
		     ${RKHROOTDIR}/usr/lib/vold/nsdap/findkit
		     ${RKHROOTDIR}/usr/lib/vold/nsdap/sn2
		     ${RKHROOTDIR}/usr/lib/vold/nsdap/sniffload
		     ${RKHROOTDIR}/usr/lib/vold/nsdap/runsniff
		     ${RKHROOTDIR}/usr/lib/lpset"
	NSDAP_DIRS="${RKHROOTDIR}/usr/lib/vold/nsdap"


	# SunOS Rootkit
	SUNOSROOTKIT_FILES="${RKHROOTDIR}/etc/ld.so.hash
			    ${RKHROOTDIR}/lib/libext-2.so.7
			    ${RKHROOTDIR}/usr/bin/ssh2d
			    ${RKHROOTDIR}/bin/xlogin
			    ${RKHROOTDIR}/usr/lib/crth.o
			    ${RKHROOTDIR}/usr/lib/crtz.o
			    ${RKHROOTDIR}/sbin/login
			    ${RKHROOTDIR}/lib/security/.config/sn
			    ${RKHROOTDIR}/lib/security/.config/lpsched
			    ${RKHROOTDIR}/dev/kmod
			    ${RKHROOTDIR}/dev/dos"


	# Superkit Rootkit
	SUPERKIT_FILES="${RKHROOTDIR}/usr/man/.sman/sk"


	# Telnet Backdoor
	TBD_FILES="${RKHROOTDIR}/usr/lib/.tbd"


	# TeLeKiT Rootkit
	TELEKIT_FILES="${RKHROOTDIR}/usr/man/man3/.../TeLeKiT/bin/sniff
		       ${RKHROOTDIR}/usr/man/man3/.../TeLeKiT/bin/telnetd
		       ${RKHROOTDIR}/usr/man/man3/.../TeLeKiT/bin/teleulo
		       ${RKHROOTDIR}/usr/man/man3/.../cl
		       ${RKHROOTDIR}/dev/ptyr
		       ${RKHROOTDIR}/dev/ptyp
		       ${RKHROOTDIR}/dev/ptyq
		       ${RKHROOTDIR}/dev/hda06
		       ${RKHROOTDIR}/usr/info/libc1.so"
	TELEKIT_DIRS="${RKHROOTDIR}/usr/man/man3/...
		      ${RKHROOTDIR}/usr/man/man3/.../lsniff
		      ${RKHROOTDIR}/usr/man/man3/.../TeLeKiT"


	# T0rn (and misc) Rootkit
	TORN_FILES="${RKHROOTDIR}/dev/.lib/lib/lib/t0rns
		    ${RKHROOTDIR}/dev/.lib/lib/lib/du
		    ${RKHROOTDIR}/dev/.lib/lib/lib/ls
		    ${RKHROOTDIR}/dev/.lib/lib/lib/t0rnsb
		    ${RKHROOTDIR}/dev/.lib/lib/lib/ps
		    ${RKHROOTDIR}/dev/.lib/lib/lib/t0rnp
		    ${RKHROOTDIR}/dev/.lib/lib/lib/find
		    ${RKHROOTDIR}/dev/.lib/lib/lib/ifconfig
		    ${RKHROOTDIR}/dev/.lib/lib/lib/pg
		    ${RKHROOTDIR}/dev/.lib/lib/lib/ssh.tgz
		    ${RKHROOTDIR}/dev/.lib/lib/lib/top
		    ${RKHROOTDIR}/dev/.lib/lib/lib/sz
		    ${RKHROOTDIR}/dev/.lib/lib/lib/login
		    ${RKHROOTDIR}/dev/.lib/lib/lib/in.fingerd
		    ${RKHROOTDIR}/dev/.lib/lib/lib/1i0n.sh
		    ${RKHROOTDIR}/dev/.lib/lib/lib/pstree
		    ${RKHROOTDIR}/dev/.lib/lib/lib/in.telnetd
		    ${RKHROOTDIR}/dev/.lib/lib/lib/mjy
		    ${RKHROOTDIR}/dev/.lib/lib/lib/sush
		    ${RKHROOTDIR}/dev/.lib/lib/lib/tfn
		    ${RKHROOTDIR}/dev/.lib/lib/lib/name
		    ${RKHROOTDIR}/dev/.lib/lib/lib/getip.sh
		    ${RKHROOTDIR}/usr/info/.torn/sh*
		    ${RKHROOTDIR}/usr/src/.puta/.1addr
		    ${RKHROOTDIR}/usr/src/.puta/.1file
		    ${RKHROOTDIR}/usr/src/.puta/.1proc
		    ${RKHROOTDIR}/usr/src/.puta/.1logz
		    ${RKHROOTDIR}/usr/info/.t0rn"
	TORN_DIRS="${RKHROOTDIR}/dev/.lib
		   ${RKHROOTDIR}/dev/.lib/lib
		   ${RKHROOTDIR}/dev/.lib/lib/lib
		   ${RKHROOTDIR}/dev/.lib/lib/lib/dev
		   ${RKHROOTDIR}/dev/.lib/lib/scan
		   ${RKHROOTDIR}/usr/src/.puta
		   ${RKHROOTDIR}/usr/man/man1/man1
		   ${RKHROOTDIR}/usr/man/man1/man1/lib
		   ${RKHROOTDIR}/usr/man/man1/man1/lib/.lib
		   ${RKHROOTDIR}/usr/man/man1/man1/lib/.lib/.backup"


	# Trojanit Kit Rootkit
	TROJANIT_FILES="${RKHROOTDIR}/bin/.ls
			${RKHROOTDIR}/bin/.ps
			${RKHROOTDIR}/bin/.netstat
			${RKHROOTDIR}/usr/bin/.nop
			${RKHROOTDIR}/usr/bin/.who"


	# Tuxtendo (Tuxkit) Rootkit
	TUXTENDO_FILES="${RKHROOTDIR}/dev/tux/.addr
			${RKHROOTDIR}/dev/tux/.cron
			${RKHROOTDIR}/dev/tux/.file
			${RKHROOTDIR}/dev/tux/.log
			${RKHROOTDIR}/dev/tux/.proc
			${RKHROOTDIR}/dev/tux/backup/crontab
			${RKHROOTDIR}/dev/tux/backup/df
			${RKHROOTDIR}/dev/tux/backup/dir
			${RKHROOTDIR}/dev/tux/backup/find
			${RKHROOTDIR}/dev/tux/backup/ifconfig
			${RKHROOTDIR}/dev/tux/backup/locate
			${RKHROOTDIR}/dev/tux/backup/netstat
			${RKHROOTDIR}/dev/tux/backup/ps
			${RKHROOTDIR}/dev/tux/backup/pstree
			${RKHROOTDIR}/dev/tux/backup/syslogd
			${RKHROOTDIR}/dev/tux/backup/tcpd
			${RKHROOTDIR}/dev/tux/backup/top
			${RKHROOTDIR}/dev/tux/backup/updatedb
			${RKHROOTDIR}/dev/tux/backup/vdir"
	TUXTENDO_DIRS="${RKHROOTDIR}/dev/tux
		       ${RKHROOTDIR}/dev/tux/ssh2
		       ${RKHROOTDIR}/dev/tux/backup"


	# URK - Universal Rootkit
	URK_FILES="${RKHROOTDIR}/usr/man/man1/xxxxxxbin/find
		   ${RKHROOTDIR}/usr/man/man1/xxxxxxbin/du
		   ${RKHROOTDIR}/usr/man/man1/xxxxxxbin/ps
		   ${RKHROOTDIR}/tmp/conf.inf"
	URK_DIRS="${RKHROOTDIR}/usr/man/man1/xxxxxxbin"


	# VcKit Rootkit
	VCKIT_DIRS="${RKHROOTDIR}/usr/include/linux/modules/lib.so
		    ${RKHROOTDIR}/usr/include/linux/modules/lib.so/bin"


	# Volc Rootkit
	VOLC_DIRS="${RKHROOTDIR}/var/spool/.recent
		   ${RKHROOTDIR}/var/spool/.recent/.files
		   ${RKHROOTDIR}/usr/lib/volc
		   ${RKHROOTDIR}/usr/lib/volc/backup"


	# X-Org SunOS Rootkit
	XORGSUNOS_FILES="${RKHROOTDIR}/usr/lib/libX.a/bin/tmpfl
			 ${RKHROOTDIR}/usr/lib/libX.a/bin/rps
			 ${RKHROOTDIR}/usr/bin/srload
			 ${RKHROOTDIR}/usr/lib/libX.a/bin/sparcv7/rps
			 ${RKHROOTDIR}/usr/sbin/modcheck"
	XORGSUNOS_DIRS="${RKHROOTDIR}/usr/lib/libX.a
			${RKHROOTDIR}/usr/lib/libX.a/bin
			${RKHROOTDIR}/usr/lib/libX.a/bin/sparcv7
			${RKHROOTDIR}/usr/share/man..."


	# zaRwT.KiT Rootkit
	ZARWT_FILES="${RKHROOTDIR}/dev/rd/s/sendmeil
		     ${RKHROOTDIR}/dev/ttyf
		     ${RKHROOTDIR}/dev/ttyp
		     ${RKHROOTDIR}/dev/ttyn
		     ${RKHROOTDIR}/rk/tulz"
	ZARWT_DIRS="${RKHROOTDIR}/rk
		    ${RKHROOTDIR}/dev/rd/s"


	# Miscellaneous login backdoors
	LOGIN_BACKDOOR_FILES="${RKHROOTDIR}/bin/.login
			      ${RKHROOTDIR}/sbin/.login"


	# Suspicious directories
	SUSPICIOUS_DIRS="${RKHROOTDIR}/usr/X11R6/bin/.,/copy
			 ${RKHROOTDIR}/dev/rd/cdb"


	# Evil strings
	STRINGSCAN="init:/dev/proc/fuckit:Fuckit Rootkit
		    init:FUCK:Possible Suckit Rootkit found
		    init:backdoor:Possible backdoored init file (Suckit)
		    login:vt200:Possible Linux Rootkit (LRK4)
		    login:/usr/bin/xstat:Possible Linux Rootkit (LRK4)
		    login:/bin/envpc:Possible Linux Rootkit (LRK4)
		    login:L4m3r0x:Possible Linux Rootkit (LRK4)
		    login:/usr/lib/.tbd:TBD Rootkit
		    ls:/dev/ptyxx/.file:Dica-Kit Rootkit
		    ls:/dev/sgk:Possible Linux Rootkit (LRK4)
		    ls:/var/lock/subsys/...datafile...:Ohhara Rootkit
		    ls:/usr/lib/.tbd:TBD Rootkit
		    netstat:/dev/proc/fuckit:Fuckit Rootkit
		    netstat:/lib/.sso:Dica-Kit Rootkit
		    netstat:/var/lock/subsys/...datafile...:Ohhara Rootkit
		    netstat:/dev/caca:MRK Rootkit
		    netstat:/dev/ttyoa:Sin Rootkit
		    netstat:syg:Possible trojaned netstat
		    nscd:sshd_config:Possible backdoor shell installed (SSH)
		    ps:/dev/pts/01:SunOS Rootkit
		    ps:tw33dl3:SunOS Rootkit
		    ps:psniff:SunOS Rootkit
		    ps:/var/lock/subsys/...datafile...:Ohhara Rootkit or Ni0 Rootkit
		    rpc.nfsd:cant open log:Possible sniffer installed
		    rpc.nfsd:sniff.pid:Possible sniffer installed
		    rpc.nfsd:tcp.log:Possible sniffer installed
		    sshd:/dev/ptyxx:OpenBSD Rootkit
		    syslogd:promiscuous:Possible sniffer installed
		    syslogd:/usr/lib/.tbd:TBD Rootkit
		    tcpd:/dev/xdta:Dica-Kit Rootkit
		    top:/usr/lib/.tbd:TBD Rootkit
		    xtty:/bin/sh:Possible backdoor shell installed
		    rcfile:in.inetd:SHV4 Rootkit
		    rcfile:#<HIDE_.*>:Enye LKM
		    rcfile:bin/xchk:Optic Kit (Tux) Worm
		    rcfile:bin/xsf:Optic Kit (Tux) Worm"


	# Possible rootkit files and directories
	FILESCAN="file:${RKHROOTDIR}/dev/sdr0:Possible T0rn Rootkit MD5 hash database
		  file:${RKHROOTDIR}/tmp/.syshackfile:Trojaned syslog daemon
		  file:${RKHROOTDIR}/tmp/.bash_history:Possible Lite5-r Rootkit
		  file:${RKHROOTDIR}/usr/info/.clib:Possible backdoor
		  file:${RKHROOTDIR}/usr/sbin/tcp.log:Possible sniffer
		  file:${RKHROOTDIR}/usr/bin/take/pid:Trojaned SSH daemon
		  file:${RKHROOTDIR}/sbin/create:MzOzD Local backdoor
		  file:${RKHROOTDIR}/dev/ttypz:spwn login backdoor
		  dir:${RKHROOTDIR}/usr/bin/take:Trojaned SSH daemon
		  dir:${RKHROOTDIR}/usr/src/.lib:Unusual directory
		  dir:${RKHROOTDIR}/usr/share/man/man1/.1c:Possible Eggdrop installed
		  dir:${RKHROOTDIR}/lib/lblip.tk:Possible T0rn Rootkit directory with backdoored SSH-configuration
		  dir:${RKHROOTDIR}/usr/sbin/...:Unusual directory
		  dir:${RKHROOTDIR}/usr/share/.gun:Unusual directory"


	# Evil strings for FreeBSD KLD (Dynamic Kernel Linker modules)
	KLDSTATKEYWORDS="backd00r backdoor"


	# Suspicious startup file strings
	RCLOCAL_STRINGS="/usr/bin/rpc.wall:Possible Linux Rootkit (LRK4)
			 sshdd:Possible GasKit rootkit
			 hidef:Possible part of Knark rootkit"


	# Suspicious open files
	SUSP_FILES_INFO="backdoor:Generic backdoor
			 adore.o:Adore LKM rootkit
			 mod_rootme.so:Apache mod_rootme backdoor
			 phide_mod.o:PID hider LKM
			 lbk.ko:LBK FreeBSD kernel module
			 vlogger.o:THC-Vlogger kernel module
			 cleaner.o:Cleaner kernel module
			 mod_klgr.o:klgr, keyboard logger (kernel module)
			 hydra:THC-Hydra (password capture)
			 hydra.restore:THC-Hydra (password capture)"


	# System startup file pathnames
	RCLOCATIONS="/etc/rc.local
		     /etc/rc.d/rc.local
		     /usr/local/etc/rc.local
		     /usr/local/etc/rc.d/rc.local
		     /etc/conf.d/local.start
		     /etc/init.d/boot.local
		     /etc/rc.d/rc.sysinit
		     /etc/inittab"


	# Integrity tests
	STRINGS_INTEGRITY="${BOBKIT_FILES} ${BOBKIT_DIRS} ${CINIK_FILES}
			   ${CINIK_DIRS} ${DICA_FILES} ${FREEBSD_RK_FILES}
			   ${TBD_FILES} ${TORN_FILES} ${TORN_DIRS}"


	SNIFFER_FILES="${RKHROOTDIR}/usr/lib/libice.log"


	# Known bad Linux kernel modules
	LKM_BADNAMES="adore.o
		      cleaner.o
		      flkm.o
		      phide_mod.o
		      vlogger.o"

	return
}


strings_check() {

	#
	# This function carries out the 'strings' command check.
	# It passes specific strings through the strings command to
	# see if they are missing. If so, then it can indicate that
	# the command has been modified to hide information.
	#

	if `check_test strings`; then
		display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 STRINGS_CHECK_START
		display --to LOG --type INFO STARTING_TEST strings
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST strings
		return
	fi


	#
	# First check to see if we have a 'strings' command.
	#

	if [ -z "${STRINGS_CMD}" ]; then
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 STRINGS_CHECK
		display --to LOG --type INFO NOT_FOUND_CMD "strings"
		return
	fi


	#
	# The pathnames to check will have the RKHROOTDIR at
	# the front. We need to strip this off before passing
	# it through the 'strings' command. If we didn't then
	# we would be looking for the wrong pathname.
	#

	STRINGSFAILED=0

	RDIR=`echo "${RKHROOTDIR}" | sed -e 's/\//\\\\\//g'`

	for STRING in ${STRINGS_INTEGRITY}; do
		STRING=`echo "${STRING}" | sed -e "s/^${RDIR}//"`

		STRINGNAME=`echo "${STRING}" | sed -e 's/\./\\\./g'`
		STRING_SEEN=`echo "${STRING}" | ${STRINGS_CMD} | grep "${STRINGNAME}" | tr -d ' '`

		if [ -z "${STRING_SEEN}" ]; then
			STRINGSFAILED=1
			display --to LOG --type WARNING --result WARNING STRINGS_SCANNING_BAD "${STRING}"
		elif [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --result OK STRINGS_SCANNING_OK "${STRING}"
		fi
	done


	if [ $STRINGSFAILED -eq 0 ]; then
		RKHTMPVAR="SCREEN"
		test $VERBOSE_LOGGING -eq 0 && RKHTMPVAR="SCREEN+LOG"

		display --to "${RKHTMPVAR}" --type PLAIN --result OK --color GREEN --screen-indent 4 STRINGS_CHECK
	else
		display --to SCREEN --type PLAIN --result WARNING --color RED --screen-indent 4 STRINGS_CHECK
	fi

	return
}


shared_libs_check() {

	#
	# This function checks shared library loading problems.
	# It is part of do_system_commands_checks and should precede or run
	# just after strings_check if enabled.
	#

	#
	# Remarks:
	# Oracle-10.1.0.3 on RHEL3 needs /etc/libcwait.so,
	# F-PROT Antivirus for GNU/Linux needs f-prot.so,
	# AVAYA Labs "stack overflow protection" uses libsafe.
	#

	if `check_test shared_libs`; then
		display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 SHARED_LIBS_START
		display --to LOG --type INFO STARTING_TEST shared_libs
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST shared_libs
		return
	fi


	#
	# First check for preloading exported variables.
	#

	VARFOUND=""

	for RKHTMPVAR in LD_PRELOAD LD_AOUT_PRELOAD LD_ELF_PRELOAD; do
		RKHTMPVAR_RES=`eval echo "\\$${RKHTMPVAR}"`

		test -n "${RKHTMPVAR_RES}" && VARFOUND="${VARFOUND} ${RKHTMPVAR}"
	done

	if [ -z "${VARFOUND}" ]; then
		display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 SHARED_LIBS_PRELOAD_VAR
	else
		display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 SHARED_LIBS_PRELOAD_VAR
		display --to LOG --type WARNING SHARED_LIBS_PRELOAD_VAR_FOUND "${VARFOUND}"
	fi


	#
	# Next check for a preload file.
	#

	RKHTMPVAR=${RKHROOTDIR}/etc/ld.so.preload

	if [ -f ${RKHTMPVAR} ]; then
		display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 SHARED_LIBS_PRELOAD_FILE
		display --to LOG --type WARNING SHARED_LIBS_PRELOAD_FILE_FOUND "${RKHTMPVAR}"
	else
		display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --screen-indent 4 SHARED_LIBS_PRELOAD_FILE
	fi


	#
	# Finally we check the LD_LIBRARY_PATH. This check may be
	# disabled by the user if the 'ldd' command is not available.
	#

	if `check_test shared_libs_path`; then
		display --to LOG --type INFO STARTING_TEST shared_libs_path

		if [ -n "${LDD_CMD}" ]; then
			if [ -n "${LD_LIBRARY_PATH}" ]; then
				LD_LIBR_FAILED=0
				RKHTMPVAR_BIN=""
				LD_LIBRARY_PATH_SAVED="${LD_LIBRARY_PATH}"

				if [ -z "${MD5_CMD}" ]; then
					MD5_CMD=`find_cmd md5sum`
					test -z "${MD5_CMD}" && MD5_CMD=`find_cmd md5`
				fi

				LS_CMD=`find_cmd ls`

				for RKHTMPVAR in FIND PS STRINGS MD5 LS STAT; do
					RKHTMPVAR=`eval echo "\\$${RKHTMPVAR}_CMD"`
					RKHTMPVAR=`echo "${RKHTMPVAR}" | cut -d' ' -f1`

					RKHTMPVAR_BIN="${RKHTMPVAR_BIN} ${RKHTMPVAR}"
				done

				for RKHTMPVAR in ${RKHTMPVAR_BIN}; do
					LD_LIBRARY_PATH="${LD_LIBRARY_PATH_SAVED}"
					export LD_LIBRARY_PATH
					RKHTMPVAR_WITH=`${LDD_CMD} ${RKHTMPVAR} 2>&1`

					unset LD_LIBRARY_PATH
					RKHTMPVAR_WITHOUT=`${LDD_CMD} ${RKHTMPVAR} 2>&1`

					if [ "${RKHTMPVAR_WITH}" != "${RKHTMPVAR_WITHOUT}" ]; then
						#
						# Testing one command should be "evidence" enough.
						#

						LD_LIBR_FAILED=1
						break
					fi
				done


				#
				# Reset things to the way they were before.
				#

				LD_LIBRARY_PATH="${LD_LIBRARY_PATH_SAVED}"
				export LD_LIBRARY_PATH


				if [ $LD_LIBR_FAILED -eq 0 ]; then
					display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --screen-indent 4 SHARED_LIBS_PATH
				else
					display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 SHARED_LIBS_PATH
					display --to LOG --type WARNING SHARED_LIBS_PATH_BAD "${LD_LIBRARY_PATH}"
				fi
			else
				display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --screen-indent 4 SHARED_LIBS_PATH
			fi
		else
			display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 SHARED_LIBS_PATH
			display --to LOG --type INFO NOT_FOUND_CMD "ldd"
		fi
	else
		display --to LOG --type INFO USER_DISABLED_TEST shared_libs_path
	fi

	return
}


file_properties_check() {

	#
	# This function carries out a check of system command property
	# values checked against their previous value, which is stored
	# in the rkhunter.dat file. Other checks work on the current
	# file, and do not use any previously stored value (for example,
	# the immutable-bit check).
	#

	#
	# Each test will set the variable TEST_RESULT, and use it to
	# display the actual result. Typically a null string indicates
	# 'OK', and anything else is a 'Warning'.
	#

	TEST_RESULT=""
	WHITELIST_RESULT=""
	SKIP_ATTR=0; SKIP_HASH=0; SKIP_IMMUT=0; SKIP_SCRIPT=0
	USE_DAT_FILE=1
	SKIP_IMMUT_OS=0
	PROP_FILE_LIST_COUNT=0

	#
	# In order to disable the whole test we have to check if
	# each specific test has been disabled.
	#

	for RKHTMPVAR in attributes hashes immutable scripts; do
		if ! `check_test ${RKHTMPVAR}`; then
			case "${RKHTMPVAR}" in
			attributes)
				SKIP_ATTR=1
				;;
			hashes)
				SKIP_HASH=1
				;;
			immutable)
				SKIP_IMMUT=1
				;;
			scripts)
				SKIP_SCRIPT=1
				;;
			esac
		fi
	done

	#
	# The immutable-bit test is only applicable to Linux and
	# BSD systems. We need to disable the test, but not have
	# it logged as if the user had disabled it (that would be
	# confusing).
	#

	if [ $BSDOS -eq 0 -a "${OPERATING_SYSTEM}" != "Linux" ]; then
		if [ $SKIP_IMMUT -eq 0 ]; then
			SKIP_IMMUT=1
			SKIP_IMMUT_OS=1
		fi
	fi

	if ! `check_test properties`; then
		display --to LOG --type INFO --nl USER_DISABLED_TEST properties
		return
	elif [ $SKIP_ATTR -eq 1 -a $SKIP_HASH -eq 1 -a $SKIP_IMMUT -eq 1 -a $SKIP_SCRIPT -eq 1 ]; then
		display --to LOG --type INFO --nl USER_DISABLED_TEST properties
		return
	else
		display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 FILE_PROP_START
		display --to LOG --type INFO STARTING_TEST properties
	fi


	#
	# If the user wants to skip a test then log it.
	#

	for RKHTMPVAR in attributes hashes immutable scripts; do
		case "${RKHTMPVAR}" in
		attributes)
			TEST_NAME=$SKIP_ATTR
			;;
		hashes)
			TEST_NAME=$SKIP_HASH
			;;
		scripts)
			TEST_NAME=$SKIP_SCRIPT
			;;
		immutable)
			TEST_NAME=0
			test $SKIP_IMMUT_OS -eq 0 && TEST_NAME=$SKIP_IMMUT
			;;
		esac

		test $TEST_NAME -eq 1 && display --to LOG --type INFO USER_DISABLED_TEST ${RKHTMPVAR}
	done


	#
	# The first test we do is on the commands needed to
	# perform all the file checks. If the user has not
	# disabled any test, and a command is missing, then
	# we must let them know that without marking each file
	# test as a 'Warning' (because that could hide a real
	# problem). We include checks on the rkhunter.dat file
	# as well.
	#

	RKHTMPVAR=""

	if [ $SKIP_ATTR -eq 0 -a -z "${STAT_CMD}" ]; then
		SKIP_ATTR=1
		RKHTMPVAR="${RKHTMPVAR} attr"
	fi

	if [ $SKIP_HASH -eq 0 ]; then
		# Not sure about this one...!
		if [ -z "${OLD_PKGMGR}" -a -s "${DB_PATH}/rkhunter.dat" -a "${HASH_FUNC}" != "NONE" -a \( "${OLD_HASH_FUNC}" = "NONE" -o "${OLD_HASH_FUNC}" = "Disabled" -o -z "${OLD_HASH_FUNC}" \) ]; then
			SKIP_HASH=1
			RKHTMPVAR="${RKHTMPVAR} hash"

			if [ -n "${PRELINK_HASH}" ]; then
				HASH_FUNC_ERR="prelink with ${PRELINK_HASH}"
			else
				HASH_FUNC_ERR="${HASH_FUNC}"
			fi

			if [ -z "${OLD_HASH_FUNC}" ]; then
				OLD_HASH_FUNC_ERR="Unset"
			else
				if [ "${OLD_HASH_FUNC}" = "MD5" -o "${OLD_HASH_FUNC}" = "SHA1" ]; then
					OLD_HASH_FUNC_ERR="prelink with ${OLD_HASH_FUNC}"
				else
					OLD_HASH_FUNC_ERR="${OLD_HASH_FUNC}"
				fi
			fi

			if [ -z "${PKGMGR}" ]; then
				PKGMGR_ERR="Unset"
			else
				PKGMGR_ERR="${PKGMGR}"
			fi

			if [ -z "${OLD_PKGMGR}" ]; then
				OLD_PKGMGR_ERR="Unset"
			else
				OLD_PKGMGR_ERR="${OLD_PKGMGR}"
			fi
		fi

		if [ $PRELINKED -eq 1 ]; then
			if [ $SKIP_HASH_MSG -eq 1 ]; then
				SKIP_HASH=1
				RKHTMPVAR="${RKHTMPVAR} prelink"
			elif [ $SKIP_HASH_MSG -eq 2 ]; then
				SKIP_HASH=1
				RKHTMPVAR="${RKHTMPVAR} sha1"
			elif [ $SKIP_HASH_MSG -eq 3 ]; then
				SKIP_HASH=1
				RKHTMPVAR="${RKHTMPVAR} libsafe"
			fi
		fi

		if [ $OS_CHANGED -eq 1 -a $SHOWWARNINGSONLY -eq 0 ]; then
			RKHTMPVAR="${RKHTMPVAR} os_changed"
		fi
	fi

	if [ $SKIP_IMMUT -eq 0 -a $BSDOS -eq 0 -a -z "${LSATTR_CMD}" ]; then
		SKIP_IMMUT=1
		RKHTMPVAR="${RKHTMPVAR} immutable"
	fi

	if [ $SKIP_SCRIPT -eq 0 -a -z "${FILE_CMD}" ]; then
		SKIP_SCRIPT=1
		RKHTMPVAR="${RKHTMPVAR} script"
	fi

	if [ $SKIP_ATTR -eq 0 -o $SKIP_HASH -eq 0 ]; then
		if [ ! -f "${DB_PATH}/rkhunter.dat" ]; then
			SKIP_HASH=1
			SKIP_ATTR=1
			USE_DAT_FILE=0
			RKHTMPVAR="${RKHTMPVAR} missing"
		fi

		if [ $USE_DAT_FILE -eq 1 -a ! -s "${DB_PATH}/rkhunter.dat" ]; then
			SKIP_HASH=1
			SKIP_ATTR=1
			USE_DAT_FILE=0
			RKHTMPVAR="${RKHTMPVAR} empty"
		fi
	else
		#
		# If we are not checking the file attributes or
		# the hash value, then we don't need to look at
		# the rkhunter.dat file. The other tests can be
		# done without the file.
		#

		USE_DAT_FILE=0
	fi

	#
	# If all the previous checks have disabled all the tests,
	# then we tell the user and then return.
	#

	if [ $SKIP_ATTR -eq 1 -a $SKIP_HASH -eq 1 -a $SKIP_IMMUT -eq 1 -a $SKIP_SCRIPT -eq 1 ]; then
		RKHTMPVAR="${RKHTMPVAR} notests"
	fi


	#
	# Display the results.
	#

	if [ $SKIP_IMMUT_OS -eq 1 ]; then
		display --to LOG --type INFO FILE_PROP_IMMUT_OS
	fi

	if [ -z "${RKHTMPVAR}" ]; then
		display --to SCREEN+LOG --type PLAIN --screen-indent 4 --result OK --color GREEN FILE_PROP_CMDS
	else
		SUMMARY_PROP_REQCMDS=1

		display --to SCREEN+LOG --type WARNING --screen-indent 4 --result WARNING --color RED FILE_PROP_CMDS


		RKHTMPVAR2=0
		for TEST_RESULT in ${RKHTMPVAR}; do
			case "${TEST_RESULT}" in
			attr)
				display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_ATTR
				;;
			hash|prelink|sha1|libsafe)
				if [ $RKHTMPVAR2 -eq 0 ]; then
					RKHTMPVAR2=1
					display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_HASH
				fi

				case "${TEST_RESULT}" in
				hash)
					display --to LOG --type PLAIN --log-indent 13 FILE_PROP_SKIP_HASH_FUNC "${HASH_FUNC_ERR}" "${PKGMGR_ERR}" "${OLD_HASH_FUNC_ERR}" "${OLD_PKGMGR_ERR}"
					;;
				prelink)
					display --to LOG --type PLAIN --log-indent 13 FILE_PROP_SKIP_HASH_PRELINK
					;;
				sha1)
					display --to LOG --type PLAIN --log-indent 13 FILE_PROP_SKIP_HASH_SHA1
					;;
				libsafe)
					display --to LOG --type PLAIN --log-indent 13 FILE_PROP_SKIP_HASH_LIBSAFE
					;;
				esac
				;;
			immutable)
				display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_IMMUT
				;;
			script)
				display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SKIP_SCRIPT
				;;
			os_changed)
				display --to LOG --type PLAIN --log-indent 9 FILE_PROP_OS_CHANGED
				;;
			missing)
				display --to LOG --type PLAIN --log-indent 9 FILE_PROP_DAT_MISSING
				;;
			empty)
				display --to LOG --type PLAIN --log-indent 9 FILE_PROP_DAT_EMPTY
				;;
			esac
		done


		if [ -n "`echo \"${RKHTMPVAR}\" | egrep 'libsafe|missing|empty'`" ]; then
			display --to LOG --type WARNING --nl PROPUPD_WARN
		fi

		if [ -n "`echo \"${RKHTMPVAR}\" | grep 'notests'`" ]; then
			display --to LOG --type WARNING --nl FILE_PROP_SKIP_ALL
			return
		fi
	fi


	#
	# Set up some local variables depending on what
	# commands we have available.
	#

	if [ $SKIP_ATTR -eq 1 ]; then
		SCMD=""
	else
		if [ -n "`echo \"${STAT_CMD}\" | grep '\.pl$'`" ]; then
			SCMD="${STAT_CMD} --modeoct --raw --ino --mode --uid --gid --size --Mtime"
		elif [ $BSDOS -eq 1 ]; then
			SCMD="${STAT_CMD} -f '%i %Mp%Lp %u %g %z %m:'"
		else
			SCMD="${STAT_CMD} --format='%i 0%a %u %g %s %Y:'"
		fi
	fi

	if [ $SKIP_HASH -eq 1 ]; then
		HCMD=""
		SYSHASH=""
	else
		HCMD="${HASH_FUNC}"
	fi

	RDIR=`echo "${RKHROOTDIR}" | sed -e 's/\//\\\\\//g'`


	#
	# Set up some whitelist variables. There is no point
	# recalculating the (static) whitelist as we look at
	# each file. We may as well just do it the once here.
	#

	if [ $SKIP_ATTR -eq 0 ]; then
		ATTRWHITELIST=`get_option 1 multi ATTRWHITELIST` || exit 1
		WRITEWHITELIST=`get_option 1 multi WRITEWHITELIST` || exit 1
	fi

	if [ $SKIP_IMMUT -eq 0 ]; then
		IMMUTWHITELIST=`get_option 1 multi IMMUTWHITELIST` || exit 1
	fi

	if [ $SKIP_SCRIPT -eq 0 ]; then
		SCRIPTWHITELIST=`get_option 1 multi SCRIPTWHITELIST` || exit 1
	fi


	#
	# Now loop through each of the files and
	# perform the tests on each one.
	#

	VERIFIED_PKG_LIST=""

	for DIR in ${PROP_DIR_LIST}; do
		for FNAME in ${PROP_FILE_LIST}; do
			TEST_RESULT=""
			WHITELIST_RESULT=""

			FILE_IS_PKGD=0
			DEPENDENCY_ERR=0
			HASH_TEST_PASSED=0
			SIZE_TEST_PASSED=0


			#
			# We first need to test if the file exists or not,
			# and if the file is listed in the rkhunter.dat
			# file or not. This can indicate files that have
			# appeared on or disappeared from the system.
			#

			if [ -f "${DIR}/${FNAME}" ]; then
				FILE_EXISTS=1
				PROP_FILE_LIST_COUNT=`expr ${PROP_FILE_LIST_COUNT} + 1`
			else
				FILE_EXISTS=0
			fi

			if [ $USE_DAT_FILE -eq 1 ]; then
				#
				# When checking the filename against the rkhunter.dat
				# file, we must use the real filename and not one with
				# the root directory.
				#

				FILENAME=`echo "${DIR}/${FNAME}" | sed -e "s/^${RDIR}//"`

				RKHLINE=`grep "^File:${FILENAME}:" ${DB_PATH}/rkhunter.dat`

				if [ $FILE_EXISTS -eq 1 -a -z "${RKHLINE}" ]; then
					TEST_RESULT="${TEST_RESULT} norkhline"
				elif [ $FILE_EXISTS -eq 0 ]; then
					if [ -n "${RKHLINE}" ]; then
						PROP_FAILED_COUNT=`expr ${PROP_FAILED_COUNT} + 1`

						display --to SCREEN+LOG --type PLAIN --screen-indent 4 --result WARNING --color RED NAME "${DIR}/${FNAME}"
						display --to LOG --type WARNING FILE_PROP_FILE_NOT_EXIST "${DIR}/${FNAME}"
					fi

					continue
				fi
			elif [ $FILE_EXISTS -eq 1 ]; then
				RKHLINE=""
			else
				continue
			fi


			#
			# Start the tests.
			#

			if [ $USE_DAT_FILE -eq 1 -a -n "${RKHLINE}" ]; then
				FDATA=""
				RPM_QUERY_RESULT=""
				PKGMGR_VERIFY_RESULT=""


				#
				# Because the RPM package manager can verify most
				# of the tests we are doing, we obtain the verified
				# data now. The other package managers, at present,
				# only provide the MD5 checksum. As such we simply
				# handle them within the hash test.
				#

				if [ "${PKGMGR}" = "RPM" ]; then
					#
					# First we see if the file is part of a package.
					#

					PKGNAME=`${RPM_CMD} -qf ${FILENAME} 2>/dev/null`
					ERRCODE=$?

					if [ $ERRCODE -eq 0 ]; then
						#
						# Okay we have a package name. Is it in the list
						# of packages we have already tested as verified?
						#
						# If multiple versions of the same package
						# have been installed, we use the last one.
						#

						FILE_IS_PKGD=1

						PKGNAME=`echo "${PKGNAME}" | tail -1`

						if [ -z "`echo \"${VERIFIED_PKG_LIST}\" | grep \" ${PKGNAME} \"`" ]; then
							#
							# No, it isn't in the list. So we verify the package
							# and either add it to the list if it verifies okay,
							# or get the verification result for the file.
							#

							PKGMGR_VERIFY_RESULT=`${RPM_CMD} -Vf ${FILENAME} 2>&1`

							if [ -z "${PKGMGR_VERIFY_RESULT}" ]; then
								VERIFIED_PKG_LIST="${VERIFIED_PKG_LIST} ${PKGNAME} "
							else
								if [ -n "`echo \"${PKGMGR_VERIFY_RESULT}\" | grep " ${FILENAME}:" | grep 'prelink.* dependencies '`" ]; then
									DEPENDENCY_ERR=1
								fi

								PKGMGR_VERIFY_RESULT=`echo "${PKGMGR_VERIFY_RESULT}" | grep " ${FILENAME}\$" | cut -d' ' -f1`
							fi
						fi


						#
						# The package manager check does not verify all the items
						# we check. So we still need to dig out the rest of the
						# information about this file from the package manager database.
						#

						RPM_QUERY_RESULT=`${RPM_CMD} -qf --queryformat '[%{FILEINODES}:%{FILEMODES:octal}:%{FILEUSERNAME}:%{FILEGROUPNAME}:%{FILESIZES}:%{FILEMTIMES}:%{FILEMD5S}:%{FILENAMES}\n]' ${FILENAME} 2>/dev/null | grep ":${FILENAME}\$"`
						ERRCODE=$?

						if [ $ERRCODE -eq 0 ]; then
							RPM_QUERY_RESULT=`echo "${RPM_QUERY_RESULT}" | tail -1`

							FPERM="0`echo \"${RPM_QUERY_RESULT}\" | cut -d: -f2 | cut -c 3-`"
							FPERM=`echo "${FPERM}" | sed -e 's/^00/0/'`

							RKHUID=`echo "${RPM_QUERY_RESULT}" | cut -d: -f3`
							RKHUID=`grep "^${RKHUID}:" /etc/passwd 2>/dev/null | cut -d: -f3`

							RKHGID=`echo "${RPM_QUERY_RESULT}" | cut -d: -f4`
							RKHGID=`grep "^${RKHGID}:" /etc/group 2>/dev/null | cut -d: -f3`

							RKHSIZE=`echo "${RPM_QUERY_RESULT}" | cut -d: -f5`

							RKHDTM=`echo "${RPM_QUERY_RESULT}" | cut -d: -f6`

							FDATA=`echo "${RPM_QUERY_RESULT}" | cut -d: -f1`
							FDATA="${FDATA}:${FPERM}:${RKHUID}:${RKHGID}:${RKHSIZE}:${RKHDTM}:"
						else
							#
							# If, for some reason, we cannot get the package information,
							# then treat it as if it returned all null values.
							#

							FDATA="::::::"
							display --to LOG --type INFO CMD_ERROR "rpm -qf --queryformat ${FILENAME}" $ERRCODE
						fi
					fi
				fi


				#
				# Do the file hash value check.
				#

				if [ $SKIP_HASH -eq 0 ]; then
					#
					# First we get all the package manager results.
					#

					if [ "${PKGMGR}" = "RPM" ]; then
						:
					elif [ "${PKGMGR}" = "DPKG" ]; then
						PKGNAME=`${DPKG_CMD} --search ${FILENAME} 2>/dev/null | cut -d: -f1`

						if [ -n "${PKGNAME}" -a -f "/var/lib/dpkg/info/${PKGNAME}.md5sums" ]; then
							FILENAME=`echo "${FILENAME}" | sed -e 's:^/::'`
							SYSHASH=`egrep "( |\./)${FILENAME}\$" /var/lib/dpkg/info/${PKGNAME}.md5sums | cut -d' ' -f1`

							if [ -n "${SYSHASH}" ]; then
								FILE_IS_PKGD=1
								RKHTMPVAR2=`${PKGMGR_MD5_HASH} ${DIR}/${FNAME} 2>/dev/null | cut -d' ' -f $HASH_FLD_IDX`

								if [ "${RKHTMPVAR2}" != "${SYSHASH}" ]; then
									PKGMGR_VERIFY_RESULT="5"

									if [ -n "`${PKGMGR_MD5_HASH} ${DIR}/${FNAME} 2>&1 | grep 'prelink.* dependencies '`" ]; then
										DEPENDENCY_ERR=1
									fi
								fi
							fi
						fi
					elif [ "${PKGMGR}" = "BSD" ]; then
						#
						# First see if the file is part of a known package.
						#

						PKGNAME=`${PKG_CMD} -F -e ${FILENAME} 2>/dev/null`

						if [ -n "${PKGNAME}" ]; then
							#
							# Next strip of the '/usr/pkg' from the
							# pathname, and then get the hash value.
							#

							FILENAME=`echo "${FILENAME}" | sed -e 's:^/usr/pkg/::'`
							SYSHASH=`${PKG_CMD} -v -L ${PKGNAME} 2>/dev/null | grep -A 1 "File: ${FILENAME}\$" | tail -1 | cut -d: -f3`

							if [ -n "${SYSHASH}" ]; then
								FILE_IS_PKGD=1
								RKHTMPVAR2=`${PKGMGR_MD5_HASH} ${DIR}/${FNAME} 2>/dev/null | cut -d' ' -f $HASH_FLD_IDX`

								if [ "${RKHTMPVAR2}" != "${SYSHASH}" ]; then
									PKGMGR_VERIFY_RESULT="5"

									if [ -n "`${PKGMGR_MD5_HASH} ${DIR}/${FNAME} 2>&1 | grep 'prelink.* dependencies '`" ]; then
										DEPENDENCY_ERR=1
									fi
								fi
							fi
						fi
					fi


					#
					# Now see if we need to work out the hash value or not.
					#

					if [ $FILE_IS_PKGD -eq 1 ]; then
						if [ -z "`echo \"${PKGMGR_VERIFY_RESULT}\" | egrep '5|(^..\?)'`" ]; then
							HASH_TEST_PASSED=1
						else
							TEST_RESULT="${TEST_RESULT} verify:hashchanged"
						fi
					else
						#
						# The file is not part of a package. So we need
						# to compare the on-disk hash value against the
						# value in the rkhunter.dat file.
						#
						# First see if we have a stored hash value.
						#

						RKHHASH=`echo ${RKHLINE} | cut -d: -f3`

						test -z "${RKHHASH}" && TEST_RESULT="${TEST_RESULT} norkhhash"

						if [ -z "${TEST_RESULT}" ]; then
							if [ "${HCMD}" = "NONE" ]; then
								SYSHASH=""
							else
								SYSHASH=`${HCMD} ${DIR}/${FNAME} 2>/dev/null | cut -d' ' -f $HASH_FLD_IDX`

								if [ -z "${SYSHASH}" ]; then
									if [ -n "`${HCMD} ${DIR}/${FNAME} 2>&1 | grep 'prelink.* dependencies '`" ]; then
										DEPENDENCY_ERR=1
									fi
								fi
							fi

							test "${RKHHASH}" != "${SYSHASH}" && TEST_RESULT="${TEST_RESULT} hashchanged"
						fi
					fi


					#
					# Because the BSD and DPKG package managers only provide the
					# MD5 checksum, we can assume that any file which is part of
					# a package after this test must be an RPM file.
					#

					test "${PKGMGR}" != "RPM" && FILE_IS_PKGD=0
				fi


				#
				# Do the file attributes checks.
				#
				# This checks the files permissions, and the uid/gid.
				# The file permissions are also checked to see if 'w'
				# has been allowed for all users. If prelinking is not
				# in use then the inode, file size, and modification
				# date-time are checked as well.
				#

				if [ $SKIP_ATTR -eq 0 ]; then
					#
					# First check to see if the file is whitelisted here,
					# just the once. It is better than checking after
					# each individual attribute test.
					#

					WL_FILE=""

					for WHITELISTFILE in ${ATTRWHITELIST}; do
						if [ "${RKHROOTDIR}${WHITELISTFILE}" = "${DIR}/${FNAME}" ]; then
							WL_FILE="whitelisted"
							WHITELIST_RESULT="${WHITELIST_RESULT} attr"
							break
						fi
					done

					test -z "${FDATA}" && FDATA=`eval ${SCMD} ${DIR}/${FNAME} 2>/dev/null | tr ' ' ':'`

					if [ -z "${WL_FILE}" -a -n "${FDATA}" ]; then
						#
						# Check the file permissions.
						#

						if [ $FILE_IS_PKGD -eq 1 ]; then
							echo "${PKGMGR_VERIFY_RESULT}" | egrep 'M|(^.\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:permchanged"
						else
							RKHPERM=`echo ${RKHLINE} | cut -d: -f5`
							SYSPERM=`echo ${FDATA} | cut -d: -f2`

							if [ -n "${RKHPERM}" ]; then
								test "${RKHPERM}" != "${SYSPERM}" && TEST_RESULT="${TEST_RESULT} permchanged"
							else
								TEST_RESULT="${TEST_RESULT} norkhperm"
							fi
						fi


						#
						# Check the file user-id.
						#

						if [ $FILE_IS_PKGD -eq 1 ]; then
							echo "${PKGMGR_VERIFY_RESULT}" | egrep 'U|(^.....\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:uidchanged"
						else
							RKHUID=`echo ${RKHLINE} | cut -d: -f6`
							SYSUID=`echo ${FDATA} | cut -d: -f3`

							if [ -n "${RKHUID}" ]; then
								test "${RKHUID}" != "${SYSUID}" && TEST_RESULT="${TEST_RESULT} uidchanged"
							else
								TEST_RESULT="${TEST_RESULT} norkhuid"
							fi
						fi


						#
						# Check the file group-id.
						#

						if [ $FILE_IS_PKGD -eq 1 ]; then
							echo "${PKGMGR_VERIFY_RESULT}" | egrep 'G|(^......\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:gidchanged"
						else
							RKHGID=`echo ${RKHLINE} | cut -d: -f7`
							SYSGID=`echo ${FDATA} | cut -d: -f4`

							if [ -n "${RKHGID}" ]; then
								test "${RKHGID}" != "${SYSGID}" && TEST_RESULT="${TEST_RESULT} gidchanged"
							else
								TEST_RESULT="${TEST_RESULT} norkhgid"
							fi
						fi


						#
						# Check the file inode number.
						#

						if [ $PRELINKED -eq 0 -o $FILE_IS_PKGD -eq 0 ]; then
							RKHINODE=`echo ${RKHLINE} | cut -d: -f4`
							SYSINODE=`echo ${FDATA} | cut -d: -f1`

							if [ -n "${RKHINODE}" ]; then
								test "${RKHINODE}" != "${SYSINODE}" && TEST_RESULT="${TEST_RESULT} inodechanged"
							else
								TEST_RESULT="${TEST_RESULT} norkhinode"
							fi
						fi


						#
						# Check the file size.
						#

						if [ $FILE_IS_PKGD -eq 1 ]; then
							if [ -z "`echo \"${PKGMGR_VERIFY_RESULT}\" | egrep 'S|(^\?)'`" ]; then
								SIZE_TEST_PASSED=1
							else
								TEST_RESULT="${TEST_RESULT} verify:sizechanged"
							fi
						elif [ $PRELINKED -eq 0 -o $FILE_IS_PKGD -eq 0 ]; then
							RKHSIZE=`echo ${RKHLINE} | cut -d: -f8`
							SYSSIZE=`echo ${FDATA} | cut -d: -f5`

							if [ -n "${RKHSIZE}" ]; then
								if [ "${RKHSIZE}" = "${SYSSIZE}" ]; then
									SIZE_TEST_PASSED=1
								else
									TEST_RESULT="${TEST_RESULT} sizechanged"
								fi
							else
								TEST_RESULT="${TEST_RESULT} norkhsize"
							fi
						fi


						#
						# Check the file modification date-time.
						#

						if [ $FILE_IS_PKGD -eq 1 ]; then
							echo "${PKGMGR_VERIFY_RESULT}" | egrep 'T|(^.......\?)' >/dev/null && TEST_RESULT="${TEST_RESULT} verify:dtmchanged"
						elif [ $PRELINKED -eq 0 -o $FILE_IS_PKGD -eq 0 ]; then
							RKHDTM=`echo ${RKHLINE} | cut -d: -f9`
							SYSDTM=`echo ${FDATA} | cut -d: -f6`

							if [ -n "${RKHDTM}" ]; then
								test "${RKHDTM}" != "${SYSDTM}" && TEST_RESULT="${TEST_RESULT} dtmchanged"
							else
								TEST_RESULT="${TEST_RESULT} norkhdtm"
							fi
						fi
					elif [ -z "${WL_FILE}" ]; then
						TEST_RESULT="${TEST_RESULT} sysattrunavail"
					fi


					#
					# Check the file permissions here to see if the 'other' permission
					# contains a 'w'. The check is against the octal value. Symbolic
					# links are ignored.
					#

					if [ ! -h "${DIR}/${FNAME}" -a $FILE_IS_PKGD -eq 0 ]; then
						WL_FILE=""

						for WHITELISTFILE in ${WRITEWHITELIST}; do
							if [ "${RKHROOTDIR}${WHITELISTFILE}" = "${DIR}/${FNAME}" ]; then
								WL_FILE="whitelisted"
								WHITELIST_RESULT="${WHITELIST_RESULT} write"
								break
							fi
						done

						if [ -z "${WL_FILE}" ]; then
							SYSPERM=`echo ${FDATA} | cut -d: -f2`

							if [ -n "`echo ${SYSPERM} | grep '[2367]\$'`" ]; then
								TEST_RESULT="${TEST_RESULT} write"
							elif [ -z "${SYSPERM}" ]; then
								TEST_RESULT="${TEST_RESULT} syspermunavail"
							fi
						fi
					fi
				fi
			fi


			#
			# We can now carry out the tests which do not
			# require the rkhunter.dat file.
			#

			#
			# Do the file immutable-bit check.
			#

			if [ $SKIP_IMMUT -eq 0 ]; then
				#
				# Test if the file is whitelisted.
				#

				WL_FILE=""
				RKHTMPVAR=""

				for WHITELISTFILE in ${IMMUTWHITELIST}; do
					if [ "${RKHROOTDIR}${WHITELISTFILE}" = "${DIR}/${FNAME}" ]; then
						WL_FILE="whitelisted"
						WHITELIST_RESULT="${WHITELIST_RESULT} immutable"
						break
					fi
				done

				if [ -z "${WL_FILE}" ]; then
					if [ $BSDOS -eq 0 ]; then
						RKHTMPVAR=`${LSATTR_CMD} ${DIR}/${FNAME} 2>/dev/null | cut -d' ' -f1 | grep 'i'`
					else
						RKHTMPVAR=`ls -lno ${DIR}/${FNAME} 2>/dev/null | awk '{ print $5 }' | egrep 'uchg|schg|sappnd|uappnd|sunlnk|sunlink|schange|simmutable|sappend|uappend|uchange|uimmutable'`
					fi

					test -n "${RKHTMPVAR}" && TEST_RESULT="${TEST_RESULT} immutable"
				fi
			fi


			#
			# Do the file script replacement check.
			#

			if [ $SKIP_SCRIPT -eq 0 ]; then
				#
				# If we are using a package manager, and both the hash test
				# and the file size test have passed, then we skip the script
				# replacement check. The assumption is that to change a file
				# with one value remaining the same is possible, but to change
				# it such that both are the same is improbable. It would also
				# require the package manager database having being corrupted
				# as well.
				#

				if [ $HASH_TEST_PASSED -eq 0 -o $SIZE_TEST_PASSED -eq 0 ]; then
					#
					# See if the file is whitelisted.
					#

					WL_FILE=""
					SYSSCRIPT=""

					for WHITELISTFILE in ${SCRIPTWHITELIST}; do
						if [ "${RKHROOTDIR}${WHITELISTFILE}" = "${DIR}/${FNAME}" ]; then
							WL_FILE="whitelisted"
							WHITELIST_RESULT="${WHITELIST_RESULT} script"
							break
						fi
					done

					if [ -z "${WL_FILE}" ]; then
						if [ "${FNAME}" = "rkhunter" ]; then
							SYSSCRIPT=`${FILE_CMD} ${DIR}/${FNAME} 2>&1 | cat -v | egrep -i -v 'shell script( |$)'`
						else
							SYSSCRIPT=`${FILE_CMD} ${DIR}/${FNAME} 2>&1 | cat -v | egrep -i ' script( |$)'`
						fi

						test -n "${SYSSCRIPT}" && TEST_RESULT="${TEST_RESULT} script"
					fi
				fi
			fi


			#
			# Now output the results.
			#

			if [ -z "${TEST_RESULT}" ]; then
				display --to SCREEN+LOG --type PLAIN --screen-indent 4 --result OK --color GREEN NAME "${DIR}/${FNAME}"
			else
				display --to SCREEN+LOG --type PLAIN --screen-indent 4 --result WARNING --color RED NAME "${DIR}/${FNAME}"

				PROP_FAILED_COUNT=`expr ${PROP_FAILED_COUNT} + 1`

				RKHTMPVAR2=0
				RKHTMPVAR3=0
				for RKHTMPVAR in ${TEST_RESULT}; do
					case "${RKHTMPVAR}" in
					hashchanged|permchanged|uidchanged|gidchanged|inodechanged|sizechanged|dtmchanged)
						if [ $RKHTMPVAR2 -eq 0 ]; then
							RKHTMPVAR2=1
							display --to LOG --type WARNING FILE_PROP_CHANGED
							display --to LOG --type PLAIN --log-indent 9 FILE_PROP_CHANGED2 "${DIR}/${FNAME}"
						fi

						case "${RKHTMPVAR}" in
						hashchanged)
							if [ -z "${SYSHASH}" ]; then
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SYSHASH_UNAVAIL
							else
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SYSHASH "${SYSHASH}"
							fi

							display --to LOG --type PLAIN --log-indent 9 FILE_PROP_RKHHASH "${RKHHASH}"

							test $DEPENDENCY_ERR -eq 1 && display --to LOG --type PLAIN --log-indent 9 FILE_PROP_NO_SYSHASH_DEPENDENCY "${DIR}/${FNAME}"
							;;
						permchanged)
							if [ -z "${SYSPERM}" ]; then
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_PERM_UNAVAIL "${RKHPERM}"
							else
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_PERM "${SYSPERM}" "${RKHPERM}"
							fi
							;;
						uidchanged)
							if [ -z "${SYSUID}" ]; then
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_UID_UNAVAIL "${RKHUID}"
							else
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_UID "${SYSUID}" "${RKHUID}"
							fi
							;;
						gidchanged)
							if [ -z "${SYSGID}" ]; then
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_GID_UNAVAIL "${RKHGID}"
							else
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_GID "${SYSGID}" "${RKHGID}"
							fi
							;;
						inodechanged)
							if [ -z "${SYSINODE}" ]; then
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_INODE_UNAVAIL "${RKHINODE}"
							else
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_INODE "${SYSINODE}" "${RKHINODE}"
							fi
							;;
						sizechanged)
							if [ -z "${SYSSIZE}" ]; then
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SIZE_UNAVAIL "${RKHSIZE}"
							else
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SIZE "${SYSSIZE}" "${RKHSIZE}"
							fi
							;;
						dtmchanged)
							if [ -z "${SYSDTM}" ]; then
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SYSDTM_UNAVAIL
							else
								display --to LOG --type PLAIN --log-indent 9 FILE_PROP_SYSDTM "${SYSDTM}"
							fi

							display --to LOG --type PLAIN --log-indent 9 FILE_PROP_RKHDTM "${RKHDTM}"
							;;
						esac
						;;
					verify:hashchanged|verify:permchanged|verify:uidchanged|verify:gidchanged|verify:sizechanged|verify:dtmchanged)
						if [ $RKHTMPVAR3 -eq 0 ]; then
							RKHTMPVAR3=1
							display --to LOG --type WARNING FILE_PROP_VRFY
							display --to LOG --type PLAIN --log-indent 9 FILE_PROP_CHANGED2 "${DIR}/${FNAME}"

							test $DEPENDENCY_ERR -eq 1 && display --to LOG --type PLAIN --log-indent 9 FILE_PROP_NO_SYSHASH_DEPENDENCY "${DIR}/${FNAME}"
						fi

						case "${RKHTMPVAR}" in
						verify:hashchanged)
							display --to LOG --type PLAIN --log-indent 9 FILE_PROP_VRFY_HASH
							;;
						verify:permchanged)
							display --to LOG --type PLAIN --log-indent 9 FILE_PROP_VRFY_PERM
							;;
						verify:uidchanged)
							display --to LOG --type PLAIN --log-indent 9 FILE_PROP_VRFY_UID
							;;
						verify:gidchanged)
							display --to LOG --type PLAIN --log-indent 9 FILE_PROP_VRFY_GID
							;;
						verify:sizechanged)
							display --to LOG --type PLAIN --log-indent 9 FILE_PROP_VRFY_SIZE
							;;
						verify:dtmchanged)
							display --to LOG --type PLAIN --log-indent 9 FILE_PROP_VRFY_DTM
							;;
						esac
						;;
					norkhline)
						display --to LOG --type WARNING FILE_PROP_NO_RKH_REC "${DIR}/${FNAME}"
						;;
					norkhhash)
						display --to LOG --type WARNING FILE_PROP_NO_RKHHASH "${DIR}/${FNAME}"
						;;
					norkhperm)
						display --to LOG --type WARNING FILE_PROP_NO_RKHPERM "${DIR}/${FNAME}"
						;;
					norkhuid)
						display --to LOG --type WARNING FILE_PROP_NO_RKHUID "${DIR}/${FNAME}"
						;;
					norkhgid)
						display --to LOG --type WARNING FILE_PROP_NO_RKHGID "${DIR}/${FNAME}"
						;;
					norkhinode)
						display --to LOG --type WARNING FILE_PROP_NO_RKHINODE "${DIR}/${FNAME}"
						;;
					norkhsize)
						display --to LOG --type WARNING FILE_PROP_NO_RKHSIZE "${DIR}/${FNAME}"
						;;
					norkhdtm)
						display --to LOG --type WARNING FILE_PROP_NO_RKHDTM "${DIR}/${FNAME}"
						;;
					sysattrunavail)
						display --to LOG --type WARNING FILE_PROP_NO_SYSATTR "${DIR}/${FNAME}"
						;;
					write)
						display --to LOG --type WARNING FILE_PROP_WRITE "${DIR}/${FNAME}"
						;;
					syspermunavail)
						display --to LOG --type WARNING FILE_PROP_SYSPERM_UNAVAIL "${DIR}/${FNAME}"
						;;
					immutable)
						display --to LOG --type WARNING FILE_PROP_IMMUT "${DIR}/${FNAME}"
						;;
					script)
						if [ "${FNAME}" = "rkhunter" ]; then
							display --to LOG --type WARNING FILE_PROP_SCRIPT_RKH "${DIR}/${FNAME}" "${SYSSCRIPT}"
						else
							display --to LOG --type WARNING FILE_PROP_SCRIPT "${DIR}/${FNAME}" "${SYSSCRIPT}"
						fi
						;;
					esac
				done
			fi

			if [ -n "${WHITELIST_RESULT}" ]; then
				for WL_FILE in ${WHITELIST_RESULT}; do
					case "${WL_FILE}" in
					hash)
						RKHTMPVAR="file hash"
						;;
					attr)
						RKHTMPVAR="file attributes"
						;;
					write)
						RKHTMPVAR="file write permission"
						;;
					immutable)
						RKHTMPVAR="file immutable-bit"
						;;
					script)
						RKHTMPVAR="script replacement"
						;;
					esac

					display --to LOG --type INFO FILE_PROP_WL "${DIR}/${FNAME}" "${RKHTMPVAR}"
				done
			fi
		done
	done

	return
}


suspscan() {

	#
	# Purpose: scan directory for files with suspicious contents
	# suspscan hogs CPU and I/O. It should NOT BE ENABLED BY DEFAULT!
	# Args: directoryname(s) from rkhunter.conf
	#
	# CAVEATS
	# - We should use a relatively fast tempdir for this like /dev/shm
	# - We should check for availability of and writability of tempdir
	#
	# TODO
	# - Guard against running on legitmate (system) dirs
	# - Check binary dependencies?
	# - Alert and break off on: DAC rights, Filetype, Filesize, UPX / archives?
	#
	# Other
	# - Get dirs from rkhunter.conf setting
	# - Allow custom multipliers and relations
	# - Take terms from sources like ClamAV, Mod_security and Snort rules
	# - Do not rely on or incorporate region specific language stuff, think {cn,tw,id,ru,es,br,it,ro}
	# - Exclude OSes?
	# - Check config defaults. If one is missing, don't run.

	if `check_test suspscan`; then
		display --to LOG --type PLAIN --log-indent 2 --nl SUSPSCAN_START
		display --to LOG --type INFO STARTING_TEST suspscan
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST suspscan
		return
	fi


	#
	# First check that we have the commands we need.
	#

	if [ -z "${FILE_CMD}" ]; then
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 SUSPSCAN_CHECK
		display --to LOG --type INFO NOT_FOUND_CMD "file"
		return
	elif [ -z "${STRINGS_CMD}" ]; then
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 SUSPSCAN_CHECK
		display --to LOG --type INFO NOT_FOUND_CMD "strings"
		return
	fi

	#
	# Get the directories to scan.
	#

	SUSPSCAN_DIRS=`get_option 2 single SUSPSCAN_DIRS` || exit 1

	if [ -z "${SUSPSCAN_DIRS}" ]; then
		SUSPSCAN_DIRS="/tmp /var/tmp"
		display --to LOG --type PLAIN --log-indent 4 SUSPSCAN_NO_DIRS "${SUSPSCAN_DIRS}"
	else
		display --to LOG --type PLAIN --log-indent 4 SUSPSCAN_DIRS "${SUSPSCAN_DIRS}"
	fi

	#
	# Get the tempdir. Should be a /dev/shm type.
	#

	SUSPSCAN_TEMP=`get_option 1 single SUSPSCAN_TEMP` || exit 1

	if [ -z "${SUSPSCAN_TEMP}" ]; then
		SUSPSCAN_TEMP="/dev/shm"
		display --to LOG --type PLAIN --log-indent 4 SUSPSCAN_NO_TEMP "${SUSPSCAN_TEMP}"
	else
		display --to LOG --type PLAIN --log-indent 4 SUSPSCAN_TEMP "${SUSPSCAN_TEMP}"
	fi

	if [ ! -d "${SUSPSCAN_TEMP}" ]; then
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 SUSPSCAN_CHECK
		display --to LOG --type WARNING SUSPSCAN_TEMP_NOT_EXIST "${SUSPSCAN_TEMP}"
		return
	elif [ ! -w "${SUSPSCAN_TEMP}" ]; then
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 SUSPSCAN_CHECK
		display --to LOG --type WARNING SUSPSCAN_TEMP_NO_WRITE "${SUSPSCAN_TEMP}"
		return
	fi

	#
	# Get the max filesize to handle, say 1024000.
	#

	SUSPSCAN_MAXSIZE=`get_option 1 single SUSPSCAN_MAXSIZE` || exit 1

	if [ -z "${SUSPSCAN_MAXSIZE}" ]; then
		SUSPSCAN_MAXSIZE=1024000
		display --to LOG --type PLAIN --log-indent 4 SUSPSCAN_NO_SIZE "${SUSPSCAN_MAXSIZE}"
	elif [ -z "`echo \"${SUSPSCAN_MAXSIZE}\" | grep '^[1-9][0-9]*$'`" ]; then
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 SUSPSCAN_CHECK
		display --to LOG --type WARNING SUSPSCAN_SIZE_INVALID "${SUSPSCAN_MAXSIZE}"
		return
	else
		display --to LOG --type PLAIN --log-indent 4 SUSPSCAN_SIZE "${SUSPSCAN_MAXSIZE}"
	fi

	#
	# Get the score threshold, 600 seems sensible.
	#

	SUSPSCAN_THRESH=`get_option 1 single SUSPSCAN_THRESH` || exit 1

	if [ -z "${SUSPSCAN_THRESH}" ]; then
		SUSPSCAN_THRESH=600
		display --to LOG --type PLAIN --log-indent 4 SUSPSCAN_NO_THRESH "${SUSPSCAN_THRESH}"
	elif [ -z "`echo \"${SUSPSCAN_THRESH}\" | grep '^[1-9][0-9]*$'`" ]; then
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 SUSPSCAN_CHECK
		display --to LOG --type WARNING SUSPSCAN_THRESH_INVALID "${SUSPSCAN_THRESH}"
		return
	else
		display --to LOG --type PLAIN --log-indent 4 SUSPSCAN_THRESH "${SUSPSCAN_THRESH}"
	fi


	#
	# Start the test.
	#

	FOUND=0
	FOUNDDIRS=""
	FILENAME="${SUSPSCAN_TEMP}/suspscan.$$.strings"

	rm -f ${FILENAME} >/dev/null 2>&1

	for DIR in ${SUSPSCAN_DIRS}; do
		SUSPSCAN_DIR="${RKHROOTDIR}${DIR}"

		if [ -d "${SUSPSCAN_DIR}" ]; then
			FOUND=0

			if [ $VERBOSE_LOGGING -eq 1 ]; then
				display --to LOG --type PLAIN --log-indent 4 SUSPSCAN_DIR_CHECK "${SUSPSCAN_DIR}"
			fi

			$FIND_CMD "${SUSPSCAN_DIR}" -type f -o -type l 2>/dev/null | while read SUSPSCAN_ITEM; do
				#
				# If the file is a link, then find
				# what it points to.
				#

				if [ -h "${SUSPSCAN_ITEM}" ]; then
					if [ -n "${READLINK_CMD}" ]; then
						RKHTMPVAR="${SUSPSCAN_ITEM}"

						SUSPSCAN_ITEM=`${READLINK_CMD} -f ${RKHTMPVAR}`

						if [ $VERBOSE_LOGGING -eq 1 ]; then
							display --to LOG --type PLAIN --log-indent 6 SUSPSCAN_FILE_LINK_CHANGE "${RKHTMPVAR}" "${SUSPSCAN_ITEM}"
						fi
					else
						if [ $VERBOSE_LOGGING -eq 1 ]; then
							display --to LOG --type PLAIN --log-indent 6 SUSPSCAN_FILE_SKIPPED_LINK "${SUSPSCAN_ITEM}"
						fi

						continue
					fi
				fi


				#
				# Next check the size of the file.
				#

				if [ ! -s "${SUSPSCAN_ITEM}" ]; then
					if [ $VERBOSE_LOGGING -eq 1 ]; then
						display --to LOG --type PLAIN --log-indent 6 SUSPSCAN_FILE_SKIPPED_EMPTY "${SUSPSCAN_ITEM}"
					fi

					continue
				elif [ -z "`${FIND_CMD} "${SUSPSCAN_ITEM}" -size -${SUSPSCAN_MAXSIZE}c 2>/dev/null`" ]; then
					if [ $VERBOSE_LOGGING -eq 1 ]; then
						display --to LOG --type PLAIN --log-indent 6 SUSPSCAN_FILE_SKIPPED_SIZE "${SUSPSCAN_ITEM}"
					fi

					continue
				fi


				#
				# Finally, test the file type.
				#

				FTYPE=`${FILE_CMD} "${SUSPSCAN_ITEM}" 2>&1 | cat -v | cut -d' ' -f2-`
				# Adding "text" to the egrep below widens scope at the expense of more false positives and extending running time:
				if [ -n "`echo \"${FTYPE}\" | grep -vi compres | egrep -i 'execu|reloc|shell|libr|data|obj|text'`" ]; then
					FOUND=1
					SUSPSCAN_NUM=1; SUSPSCAN_SCORE=0; SUSPSCAN_HITCOUNT=0
					SUSPSCAN_STRINGS=""

					$STRINGS_CMD -n 10 "${SUSPSCAN_ITEM}" >${FILENAME} 2>&1

					# Too short, need extended regex or influence relation only on these: dcc irc bot ban chan
					# False positives: memory
					# The list below should be broken out to a .dat file or rkhunter.conf.

					for SUSPSCAN_STRING in `grep -v "^Version" ${DB_PATH}/suspscan.dat | tail -1` ; do

						# Break off if the score already exceeds threshold
						if [ $SUSPSCAN_SCORE -ge $SUSPSCAN_THRESH ]; then
							break
						fi

						SUSPSCAN_TERM="${SUSPSCAN_STRING}"

						#
						# Searchterm with class
						#

						case "${SUSPSCAN_STRING}" in
						[a-z]:*) # I mean: term=${s//*:}
							 # Class as in asm, text, networking, IRC
							 SUSPSCAN_CLASS=`echo "${SUSPSCAN_STRING}" | cut -d: -f1`
							 SUSPSCAN_TERM=`echo "${SUSPSCAN_STRING}" | cut -d: -f2-`
							 ;;
						esac

						#
						# Searchterm with multiplier
						#

						case "${SUSPSCAN_STRING}" in
						*+[0-9][0-9]*) # I mean: term="${s%%+*}";
							  SUSPSCAN_TERM=`echo "${SUSPSCAN_TERM}" | cut -d'+' -f1`
							  SUSPSCAN_MULTIPLIER=`echo "${SUSPSCAN_STRING}" | cut -d'+' -f2`
							  ;;
						esac

						grep -i ${SUSPSCAN_TERM} ${FILENAME} >/dev/null 2>&1
						ERRCODE=$?

						if [ $ERRCODE -eq 0 ]; then
							#
							# Use hitlist to find relationship with other terms and influence multiplier. Examples:
							# {opcode,jmpcode} + {disclosure,privat,kernel}
							# {bin/sh,tmp/sh} + {setuid,setgid,drop}
							# irc + {server,nick,iroffer,?dcc}
							# This implies the "more serious" terms need to be moved to the front of the table.
							# We could also prefix a class along the lines of:
							# a: (asm) e: (exploit) to help classification: e:jmp+100 e:%e[cx,si]+100
							# This way when say SUSPSCAN_CLASS -gt 4, we could SUSPSCAN_MULTIPLIER + n

							if [ "$SUSPSCAN_CLASS" = "$SUSPSCAN_CLASS_PREV" ]; then
								SUSPSCAN_SCORE=`expr ${SUSPSCAN_SCORE} + 10`
							fi

							# to further up the score for this file.

							SUSPSCAN_HITS="$SUSPSCAN_NUM ${SUSPSCAN_HITS}"

							if [ -n "$SUSPSCAN_MULTIPLIER" ]; then
								SUSPSCAN_SCORE=`expr ${SUSPSCAN_SCORE} + ${SUSPSCAN_MULTIPLIER}` 
								unset SUSPSCAN_MULTIPLIER
							else
								SUSPSCAN_SCORE=`expr ${SUSPSCAN_SCORE} + 1`
							fi

							SUSPSCAN_HITCOUNT=`expr $SUSPSCAN_HITCOUNT + 1`

							SUSPSCAN_STRINGS="${SUSPSCAN_STRINGS} ${SUSPSCAN_TERM}"

							SUSPSCAN_CLASS_PREV="$SUSPSCAN_CLASS"
						fi

						SUSPSCAN_NUM=`expr ${SUSPSCAN_NUM} + 1`
					done

					# Yes, this is not set!
					if [ $SUSPSCAN_DEBUG -eq 1 ]; then
						display --to LOG --type PLAIN --log-indent 6 SUSPSCAN_FILE_CHECK_DEBUG "${SUSPSCAN_ITEM}" "$SUSPSCAN_SCORE" "$SUSPSCAN_HITCOUNT" "${SUSPSCAN_STRINGS}"
					else
						if [ $VERBOSE_LOGGING -eq 1 ]; then
							display --to LOG --type PLAIN --log-indent 6 SUSPSCAN_FILE_CHECK "${SUSPSCAN_ITEM}" "$SUSPSCAN_SCORE"
						fi
					fi

					if [ $SUSPSCAN_SCORE -ge $SUSPSCAN_THRESH ]; then
						display --to LOG --type WARNING SUSPSCAN_INSPECT "${SUSPSCAN_ITEM}" "$SUSPSCAN_SCORE"
					fi

					unset SUSPSCAN_TERM

				# Compressed or obfuscated:
				elif [ -n "`echo \"${FTYPE}\" | grep 'corrupted section header size'`" ]; then
					display --to LOG --type PLAIN --log-indent 6 SUSPSCAN_FILE_SKIPPED_TYPE "Possible UPX-compressed or obfuscated binary" "${SUSPSCAN_ITEM}"
				# ELF ultimate compression kit (ELFuck)
				elif [ -n "`echo \"${FTYPE}\" | grep 'invalid class invalid byte order'`" ]; then
					display --to LOG --type PLAIN --log-indent 6 SUSPSCAN_FILE_SKIPPED_TYPE "Possible ELFuck obfuscated binary" "${SUSPSCAN_ITEM}"
				elif [ $VERBOSE_LOGGING -eq 1 ]; then
					display --to LOG --type PLAIN --log-indent 6 SUSPSCAN_FILE_SKIPPED_TYPE "${FTYPE}" "${SUSPSCAN_ITEM}"
				fi # test file type
			done # find dir

			# FOUND will always be 0 here because the loop prevents the variable value being exported.
			if [ $VERBOSE_LOGGING -eq 1 -a $FOUND -eq 0 ]; then
				display --to LOG --type PLAIN --log-indent 6 SUSPSCAN_DIR_CHECK_NO_FILES
			fi
		else
			display --to LOG --type PLAIN --log-indent 4 SUSPSCAN_DIR_NOT_EXIST "${SUSPSCAN_DIR}"
		fi # test dir exists
	done # outer loop dirs

	rm -f ${FILENAME} >/dev/null 2>&1


	#
	# Now display the results.
	#

	# Cruel hack due to looping

	FOUNDDIRS=`grep '.score:.*contains' "${RKHLOGFILE}" | head -n 1`
	if [ -z "${FOUNDDIRS}" ]; then
		display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 SUSPSCAN_CHECK
	else
		# The 'type' here should be PLAIN, but the loop prevents RKH from seeing that a warning has occurred.
		display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 SUSPSCAN_CHECK
	fi

	return
}


do_system_commands_checks() {

	#
	# This function carries out a sequence of tests on
	# system commands. These consist of the 'strings' command
	# check, library checks and the file properties checks.
	#

	if `check_test system_commands`; then
		display --to SCREEN+LOG --type PLAIN --color YELLOW --nl CHECK_SYS_COMMANDS
		display --to LOG --type INFO STARTING_TEST system_commands
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST system_commands
		return
	fi


	strings_check

	shared_libs_check

	file_properties_check

	keypresspause

	return
}


rootkit_file_dir_checks() {

	#
	# This function performs the check for known rootkit
	# files and directories.
	#

	if `check_test known_rkts`; then
		display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 ROOTKIT_FILES_DIRS_START
		display --to LOG --type INFO STARTING_TEST known_rkts
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST known_rkts
		return
	fi


	# 55808 Trojan - Variant A

	SCAN_ROOTKIT="55808 Trojan - Variant A"
	SCAN_FILES=${W55808A_FILES}
	SCAN_DIRS=${W55808A_DIRS}
	SCAN_KSYMS=${W55808A_KSYMS}
	scanrootkit

	# ADM Worm

	SCAN_ROOTKIT="ADM Worm"

	ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1`

	if [ $VERBOSE_LOGGING -eq 1 ]; then
		display --to LOG --type PLAIN --nl ROOTKIT_FILES_DIRS_NAME_LOG "${SCAN_ROOTKIT}"
	fi

	if [ -f "${RKHROOTDIR}/etc/passwd" ]; then
		RKHTMPVAR=`grep 'w0rm' ${RKHROOTDIR}/etc/passwd`

		if [ -z "${RKHTMPVAR}" ]; then
			if [ $VERBOSE_LOGGING -eq 1 ]; then
				display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_STR "w0rm"
			fi

			display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --screen-indent 4 NAME "${SCAN_ROOTKIT}"
		else
			ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1`
			ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${SCAN_ROOTKIT}, "

			if [ $VERBOSE_LOGGING -eq 1 ]; then
				display --to LOG --type PLAIN --result FOUND --log-indent 2 ROOTKIT_FILES_DIRS_STR "w0rm"
			fi

			display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}"
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_STR_FOUND "w0rm" "${RKHROOTDIR}/etc/passwd"
		fi
	else
		display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}"
		display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_NOFILE "${RKHROOTDIR}/etc/passwd"
	fi

	# AjaKit Rootkit

	SCAN_ROOTKIT="AjaKit Rootkit"
	SCAN_FILES=${AJAKIT_FILES}
	SCAN_DIRS=${AJAKIT_DIRS}
	SCAN_KSYMS=${AJAKIT_KSYMS}
	scanrootkit

	# aPa Kit

	SCAN_ROOTKIT="aPa Kit"
	SCAN_FILES=${APAKIT_FILES}
	SCAN_DIRS=${APAKIT_DIRS}
	SCAN_KSYMS=${APAKIT_KSYMS}
	scanrootkit

	# Apache worm

	SCAN_ROOTKIT="Apache Worm"
	SCAN_FILES=${APACHEWORM_FILES}
	SCAN_DIRS=${APACHEWORM_DIRS}
	SCAN_KSYMS=${APACHEWORM_KSYMS}
	scanrootkit

	# Ambient (ark) Rootkit

	SCAN_ROOTKIT="Ambient (ark) Rootkit"
	SCAN_FILES=${ARK_FILES}
	SCAN_DIRS=${ARK_DIRS}
	SCAN_KSYMS=${ARK_KSYMS}
	scanrootkit

	# Balaur Rootkit

	SCAN_ROOTKIT="Balaur Rootkit"
	SCAN_FILES=${BALAUR_FILES}
	SCAN_DIRS=${BALAUR_DIRS}
	SCAN_KSYMS=${BALAUR_KSYMS}
	scanrootkit

	# BeastKit Rootkit

	SCAN_ROOTKIT="BeastKit Rootkit"
	SCAN_FILES=${BEASTKIT_FILES}
	SCAN_DIRS=${BEASTKIT_DIRS}
	SCAN_KSYMS=${BEASTKIT_KSYMS}
	scanrootkit

	# beX2 Rootkit

	SCAN_ROOTKIT="beX2 Rootkit"
	SCAN_FILES=${BEX_FILES}
	SCAN_DIRS=${BEX_DIRS}
	SCAN_KSYMS=${BEX_KSYMS}
	scanrootkit

	# BOBKit Rootkit

	SCAN_ROOTKIT="BOBKit Rootkit"
	SCAN_FILES=${BOBKIT_FILES}
	SCAN_DIRS=${BOBKIT_DIRS}
	SCAN_KSYMS=${BOBKIT_KSYMS}
	scanrootkit

	# CiNIK Worm (Slapper.B variant)

	SCAN_ROOTKIT="CiNIK Worm (Slapper.B variant)"
	SCAN_FILES=${CINIK_FILES}
	SCAN_DIRS=${CINIK_DIRS}
	SCAN_KSYMS=${CINIK_KSYMS}
	scanrootkit

	# Danny-Boy's Abuse Kit

	SCAN_ROOTKIT="Danny-Boy's Abuse Kit"
	SCAN_FILES=${DANNYBOYS_FILES}
	SCAN_DIRS=${DANNYBOYS_DIRS}
	SCAN_KSYMS=${DANNYBOYS_KSYMS}
	scanrootkit

	# Devil RootKit

	SCAN_ROOTKIT="Devil RootKit"
	SCAN_FILES=${DEVIL_FILES}
	SCAN_DIRS=${DEVIL_DIRS}
	SCAN_KSYMS=${DEVIL_KSYMS}
	scanrootkit

	# Dica-Kit Rootkit

	SCAN_ROOTKIT="Dica-Kit Rootkit"
	SCAN_FILES=${DICA_FILES}
	SCAN_DIRS=${DICA_DIRS}
	SCAN_KSYMS=${DICA_KSYMS}
	scanrootkit

	# Dreams RootKit

	SCAN_ROOTKIT="Dreams Rootkit"
	SCAN_FILES=${DREAMS_FILES}
	SCAN_DIRS=${DREAMS_DIRS}
	SCAN_KSYMS=${DREAMS_KSYMS}
	scanrootkit

	# Duarawkz Rootkit

	SCAN_ROOTKIT="Duarawkz Rootkit"
	SCAN_FILES=${DUARAWKZ_FILES}
	SCAN_DIRS=${DUARAWKZ_DIRS}
	SCAN_KSYMS=${DUARAWKZ_KSYMS}
	scanrootkit

	# Enye LKM

	SCAN_ROOTKIT="Enye LKM"
	SCAN_FILES=${ENYELKM_FILES}
	SCAN_DIRS=${ENYELKM_DIRS}
	SCAN_KSYMS=${ENYELKM_KSYMS}
	scanrootkit

	# Flea Linux Rootkit

	SCAN_ROOTKIT="Flea Linux Rootkit"
	SCAN_FILES=${FLEA_FILES}
	SCAN_DIRS=${FLEA_DIRS}
	SCAN_KSYMS=${FLEA_KSYMS}
	scanrootkit

	# FreeBSD Rootkit

	SCAN_ROOTKIT="FreeBSD Rootkit"
	SCAN_FILES=${FREEBSD_RK_FILES}
	SCAN_DIRS=${FREEBSD_RK_DIRS}
	SCAN_KSYMS=${FREEBSD_RK_KSYMS}
	scanrootkit

	# Fuck`it Rootkit

	SCAN_ROOTKIT="Fuck\`it Rootkit"
	SCAN_FILES=${FUCKIT_FILES}
	SCAN_DIRS=${FUCKIT_DIRS}
	SCAN_KSYMS=${FUCKIT_KSYMS}
	scanrootkit

	# GasKit Rootkit

	SCAN_ROOTKIT="GasKit Rootkit"
	SCAN_FILES=${GASKIT_FILES}
	SCAN_DIRS=${GASKIT_DIRS}
	SCAN_KSYMS=${GASKIT_KSYMS}
	scanrootkit

	# Heroin LKM

	SCAN_ROOTKIT="Heroin LKM"
	SCAN_FILES=${HEROIN_FILES}
	SCAN_DIRS=${HEROIN_DIRS}
	SCAN_KSYMS=${HEROIN_KSYMS}
	scanrootkit

	# HjC Kit

	SCAN_ROOTKIT="HjC Kit"
	SCAN_FILES=${HJCKIT_FILES}
	SCAN_DIRS=${HJCKIT_DIRS}
	SCAN_KSYMS=${HJCKIT_KSYMS}
	scanrootkit

	# ignoKit Rootkit

	SCAN_ROOTKIT="ignoKit Rootkit"
	SCAN_FILES=${IGNOKIT_FILES}
	SCAN_DIRS=${IGNOKIT_DIRS}
	SCAN_KSYMS=${IGNOKIT_KSYMS}
	scanrootkit

	# ImperalsS-FBRK Rootkit

	SCAN_ROOTKIT="ImperalsS-FBRK Rootkit"
	SCAN_FILES=${IMPFRB_FILES}
	SCAN_DIRS=${IMPFRB_DIRS}
	SCAN_KSYMS=${IMPFRB_KSYMS}
	scanrootkit

	# Irix Rootkit

	SCAN_ROOTKIT="Irix Rootkit"
	SCAN_FILES=${IRIXRK_FILES}
	SCAN_DIRS=${IRIXRK_DIRS}
	SCAN_KSYMS=${IRIXRK_KSYMS}
	scanrootkit

	# Kitko Rootkit

	SCAN_ROOTKIT="Kitko Rootkit"
	SCAN_FILES=${KITKO_FILES}
	SCAN_DIRS=${KITKO_DIRS}
	SCAN_KSYMS=${KITKO_KSYMS}
	scanrootkit

	# Knark Rootkit

	SCAN_ROOTKIT="Knark Rootkit"
	SCAN_FILES=${KNARK_FILES}
	SCAN_DIRS=${KNARK_DIRS}
	SCAN_KSYMS=${KNARK_KSYMS}
	scanrootkit

	# Li0n Worm

	SCAN_ROOTKIT="Li0n Worm"
	SCAN_FILES=${LION_FILES}
	SCAN_DIRS=${LION_DIRS}
	SCAN_KSYMS=${LION_KSYMS}
	scanrootkit

	# Lockit / LJK2 Rootkit

	SCAN_ROOTKIT="Lockit / LJK2 Rootkit"
	SCAN_FILES=${LOCKIT_FILES}
	SCAN_DIRS=${LOCKIT_DIRS}
	SCAN_KSYMS=${LOCKIT_KSYMS}
	scanrootkit

	# Mood-NT Rootkit

	SCAN_ROOTKIT="Mood-NT Rootkit"
	SCAN_FILES=${MOODNT_FILES}
	SCAN_DIRS=${MOODNT_DIRS}
	SCAN_KSYMS=${MOODNT_KSYMS}
	scanrootkit

	# MRK (MiCrobul?) RootKit

	SCAN_ROOTKIT="MRK Rootkit"
	SCAN_FILES=${MRK_FILES}
	SCAN_DIRS=${MRK_DIRS}
	SCAN_KSYMS=${MRK_KSYMS}
	scanrootkit

	# Ni0 Rootkit

	SCAN_ROOTKIT="Ni0 Rootkit"
	SCAN_FILES=${NIO_FILES}
	SCAN_DIRS=${NIO_DIRS}
	SCAN_KSYMS=${NIO_KSYMS}
	scanrootkit

	# Ohhara Rootkit

	SCAN_ROOTKIT="Ohhara Rootkit"
	SCAN_FILES=${OHHARA_FILES}
	SCAN_DIRS=${OHHARA_DIRS}
	SCAN_KSYMS=${OHHARA_KSYMS}
	scanrootkit

	# Optic Kit Worm

	SCAN_ROOTKIT="Optic Kit (Tux) Worm"
	SCAN_FILES=${OPTICKIT_FILES}
	SCAN_DIRS=${OPTICKIT_DIRS}
	SCAN_KSYMS=${OPTICKIT_KSYMS}
	scanrootkit

	# Oz Rootkit

	SCAN_ROOTKIT="Oz Rootkit"
	SCAN_FILES=${OZ_FILES}
	SCAN_DIRS=${OZ_DIRS}
	SCAN_KSYMS=${OZ_KSYMS}
	scanrootkit

	# Phalanx Rootkit

	SCAN_ROOTKIT="Phalanx Rootkit"
	SCAN_FILES=${PHALANX_FILES}
	SCAN_DIRS="${PHALANX_DIRS}"
	SCAN_KSYMS="${PHALANX_KSYMS}"
	scanrootkit

	# Phalanx Rootkit (strings)

	if [ "${OPERATING_SYSTEM}" = "Linux" ]; then
		SCAN_ROOTKIT="Phalanx Rootkit (strings)"

		ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1`

		if [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --nl ROOTKIT_FILES_DIRS_NAME_LOG "${SCAN_ROOTKIT}"
		fi

		if [ -f "${RKHROOTDIR}/bin/hostname" ]; then
			if `grep -q 'phalanx' ${RKHROOTDIR}/bin/hostname >/dev/null 2>&1`; then
				ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1`
				ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${SCAN_ROOTKIT}, "

				if [ $VERBOSE_LOGGING -eq 1 ]; then
					display --to LOG --type PLAIN --result FOUND --log-indent 2 ROOTKIT_FILES_DIRS_STR "phalanx"
				fi

				display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}"
				display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_STR_FOUND "phalanx" "${RKHROOTDIR}/bin/hostname"
			else
				if [ $VERBOSE_LOGGING -eq 1 ]; then
					display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_STR "phalanx"
				fi

				display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --screen-indent 4 NAME "${SCAN_ROOTKIT}"
			fi
		else
			display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}"
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_NOFILE "${RKHROOTDIR}/bin/hostname"
		fi
	fi

	# Portacelo Rootkit

	SCAN_ROOTKIT="Portacelo Rootkit"
	SCAN_FILES=${PORTACELO_FILES}
	SCAN_DIRS=${PORTACELO_DIRS}
	SCAN_KSYMS=${PORTACELO_KSYMS}
	scanrootkit

	# R3dstorm Toolkit

	SCAN_ROOTKIT="R3dstorm Toolkit"
	SCAN_FILES=${REDSTORM_FILES}
	SCAN_DIRS=${REDSTORM_DIRS}
	SCAN_KSYMS=${REDSTORM_KSYMS}
	scanrootkit

	# RH-Sharpe's Rootkit

	SCAN_ROOTKIT="RH-Sharpe's Rootkit"
	SCAN_FILES=${RHSHARPES_FILES}
	SCAN_DIRS=${RHSHARPES_DIRS}
	SCAN_KSYMS=${RHSHARPES_KSYMS}
	scanrootkit

	# RSHA's Rootkit

	SCAN_ROOTKIT="RSHA's Rootkit"
	SCAN_FILES=${RSHA_FILES}
	SCAN_DIRS=${RSHA_DIRS}
	SCAN_KSYMS=${RSHA_KSYMS}
	scanrootkit

	# Scalper Worm

	SCAN_ROOTKIT="Scalper Worm"
	SCAN_FILES=${SCALPER_FILES}
	SCAN_DIRS=${SCALPER_DIRS}
	SCAN_KSYMS=${SCALPER_KSYMS}
	scanrootkit

	# Sebek LKM (Honeypot)

	SCAN_ROOTKIT="Sebek LKM"

	ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1`

	if [ $VERBOSE_LOGGING -eq 1 ]; then
		display --to LOG --type PLAIN --nl ROOTKIT_FILES_DIRS_NAME_LOG "${SCAN_ROOTKIT}"
	fi

	FOUND=0

	if [ -n "${KSYMS_FILE}" ]; then
		egrep -i 'adore|sebek' ${KSYMS_FILE} >/dev/null 2>&1 && FOUND=1
	fi

	if [ $FOUND -eq 0 ]; then
		if [ $VERBOSE_LOGGING -eq 1 ]; then
			if [ -n "${KSYMS_FILE}" ]; then
				display --to LOG --type PLAIN --result NOT_FOUND --log-indent 2 ROOTKIT_FILES_DIRS_KSYM "adore or sebek"
			else
				display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_FILES_DIRS_KSYM "adore or sebek"
			fi
		fi

		display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --screen-indent 4 NAME "${SCAN_ROOTKIT}"
	else
		ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1`
		ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${SCAN_ROOTKIT}, "

		if [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --result FOUND --log-indent 2 ROOTKIT_FILES_DIRS_KSYM "adore or sebek"
		fi

		display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}"
		display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_KSYM_FOUND "adore or sebek"
	fi

	# Shutdown Rootkit

	SCAN_ROOTKIT="Shutdown Rootkit"
	SCAN_FILES=${SHUTDOWN_FILES}
	SCAN_DIRS=${SHUTDOWN_DIRS}
	SCAN_KSYMS=${SHUTDOWN_KSYMS}
	scanrootkit

	# SHV4 Rootkit

	SCAN_ROOTKIT="SHV4 Rootkit"
	SCAN_FILES=${SHV4_FILES}
	SCAN_DIRS=${SHV4_DIRS}
	SCAN_KSYMS=${SHV4_KSYMS}
	scanrootkit

	# SHV5 Rootkit

	SCAN_ROOTKIT="SHV5 Rootkit"
	SCAN_FILES=${SHV5_FILES}
	SCAN_DIRS=${SHV5_DIRS}
	SCAN_KSYMS=${SHV5_KSYMS}
	scanrootkit

	# Sin Rootkit

	SCAN_ROOTKIT="Sin Rootkit"
	SCAN_FILES=${SINROOTKIT_FILES}
	SCAN_DIRS=${SINROOTKIT_DIRS}
	SCAN_KSYMS=${SINROOTKIT_KSYMS}
	scanrootkit

	# SInAR Rootkit

	if [ $SUNOS -eq 1 ]; then
		FOUND=0
		SINARFILES=""

		SCAN_ROOTKIT="SInAR Rootkit"

		ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1`

		if [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --nl ROOTKIT_FILES_DIRS_NAME_LOG "${SCAN_ROOTKIT}"
		fi

		if [ -n "${FIND_CMD}" ]; then
			for DIR in ${BINPATHS}; do
				test ! -d "${RKHROOTDIR}${DIR}" && continue

				FOUNDINDIR="NOT_FOUND"

				for FNAME in `${FIND_CMD} "${RKHROOTDIR}${DIR}" -type f -name "*[sS][iI][nN][aA][rR]*" 2>/dev/null`; do
					if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \" ${FNAME} \"`" ]; then
						display --to LOG --type INFO FILE_PROP_WL "${FNAME}" rootkit
					elif `grep -i 'sinar' ${FNAME} >/dev/null 2>&1`; then
						FOUND=1
						FOUNDINDIR="FOUND"
						SINARFILES="${SINARFILES} ${FNAME}"
					fi
				done

				if [ $VERBOSE_LOGGING -eq 1 ]; then
					display --to LOG --type PLAIN --result "${FOUNDINDIR}" --log-indent 2 ROOTKIT_FILES_DIRS_SINAR_DIR "${RKHROOTDIR}${DIR}"
				fi
			done


			#
			# Now display the result.
			#

			if [ $FOUND -eq 0 ]; then
				display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --screen-indent 4 NAME "${SCAN_ROOTKIT}"
			else
				ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1`
				ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${SCAN_ROOTKIT}, "

				display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 NAME "${SCAN_ROOTKIT}"
				display --to LOG --type PLAIN --log-indent 9 ROOTKIT_FILES_DIRS_SINAR "${SINARFILES}"
			fi
		else
			display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 NAME "${SCAN_ROOTKIT}"
			display --to LOG --type INFO NOT_FOUND_CMD "find"
		fi
	fi

	# Slapper Worm

	SCAN_ROOTKIT="Slapper Worm"
	SCAN_FILES=${SLAPPER_FILES}
	SCAN_DIRS=${SLAPPER_DIRS}
	SCAN_KSYMS=${SLAPPER_KSYMS}
	scanrootkit

	# Sneakin Rootkit

	SCAN_ROOTKIT="Sneakin Rootkit"
	SCAN_FILES=${SNEAKIN_FILES}
	SCAN_DIRS=${SNEAKIN_DIRS}
	SCAN_KSYMS=${SNEAKIN_KSYMS}
	scanrootkit

	# Suckit Rootkit

	SCAN_ROOTKIT="Suckit Rootkit"
	SCAN_FILES=${SUCKIT_FILES}
	SCAN_DIRS=${SUCKIT_DIRS}
	SCAN_KSYMS=${SUCKIT_KSYMS}
	scanrootkit

	# SunOS Rootkit

	SCAN_ROOTKIT="SunOS Rootkit"
	SCAN_FILES=${SUNOSROOTKIT_FILES}
	SCAN_DIRS=${SUNOSROOTKIT_DIRS}
	SCAN_KSYMS=${SUNOSROOTKIT_KSYMS}
	scanrootkit

	# SunOS / NSDAP Rootkit

	SCAN_ROOTKIT="SunOS / NSDAP Rootkit"
	SCAN_FILES=${NSDAP_FILES}
	SCAN_DIRS=${NSDAP_DIRS}
	SCAN_KSYMS=${NSDAP_KSYMS}
	scanrootkit

	# Superkit Rootkit

	SCAN_ROOTKIT="Superkit Rootkit"
	SCAN_FILES=${SUPERKIT_FILES}
	SCAN_DIRS=${SUPERKIT_DIRS}
	SCAN_KSYMS=${SUPERKIT_KSYMS}
	scanrootkit

	# TBD (Telnet BackDoor)

	SCAN_ROOTKIT="TBD (Telnet BackDoor)"
	SCAN_FILES=${TBD_FILES}
	SCAN_DIRS=${TBD_DIRS}
	SCAN_KSYMS=${TBD_KSYMS}
	scanrootkit

	# TeLeKiT Rootkit

	SCAN_ROOTKIT="TeLeKiT Rootkit"
	SCAN_FILES=${TELEKIT_FILES}
	SCAN_DIRS=${TELEKIT_DIRS}
	SCAN_KSYMS=${TELEKIT_KSYMS}
	scanrootkit


	# T0rn Rootkit

	SCAN_ROOTKIT="T0rn Rootkit"
	SCAN_FILES=${TORN_FILES}
	SCAN_DIRS=${TORN_DIRS}
	SCAN_KSYMS=${TORN_KSYMS}
	scanrootkit

	# Trojanit Kit

	SCAN_ROOTKIT="Trojanit Kit"
	SCAN_FILES=${TROJANIT_FILES}
	SCAN_DIRS=${TROJANIT_DIRS}
	SCAN_KSYMS=${TROJANIT_KSYMS}
	scanrootkit

	# Tuxtendo Rootkit

	SCAN_ROOTKIT="Tuxtendo Rootkit"
	SCAN_FILES=${TUXTENDO_FILES}
	SCAN_DIRS=${TUXTENDO_DIRS}
	SCAN_KSYMS=${TUXTENDO_KSYMS}
	scanrootkit

	# URK - Universal RootKit

	SCAN_ROOTKIT="URK Rootkit"
	SCAN_FILES=${URK_FILES}
	SCAN_DIRS=${URK_DIRS}
	SCAN_KSYMS=${URK_KSYMS}
	scanrootkit

	# VcKit Rootkit

	SCAN_ROOTKIT="VcKit Rootkit"
	SCAN_FILES=${VCKIT_FILES}
	SCAN_DIRS=${VCKIT_DIRS}
	SCAN_KSYMS=${VCKIT_KSYMS}
	scanrootkit

	# Volc Rootkit

	SCAN_ROOTKIT="Volc Rootkit"
	SCAN_FILES=${VOLC_FILES}
	SCAN_DIRS=${VOLC_DIRS}
	SCAN_KSYMS=${VOLC_KSYMS}
	scanrootkit

	# X-Org SunOS Rootkit

	SCAN_ROOTKIT="X-Org SunOS Rootkit"
	SCAN_FILES=${XORGSUNOS_FILES}
	SCAN_DIRS=${XORGSUNOS_DIRS}
	SCAN_KSYMS=${XORGSUNOS_KSYMS}
	scanrootkit

	# zaRwT.KiT Rootkit

	SCAN_ROOTKIT="zaRwT.KiT Rootkit"
	SCAN_FILES=${ZARWT_FILES}
	SCAN_DIRS=${ZARWT_DIRS}
	SCAN_KSYMS=${ZARWT_KSYMS}
	scanrootkit

	return
}


possible_rootkit_file_dir_checks() {

	#
	# This function performs the check for possible rootkit
	# files and directories.
	#

	if `check_test possible_rkt_files`; then
		if [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --nl --log-indent 2 ROOTKIT_POSS_FILES_DIRS_LOG
		fi

		display --to LOG --type INFO STARTING_TEST possible_rkt_files
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST possible_rkt_files
		return
	fi

	FOUND=0
	FOUNDFILES=""
	FOUNDDIRS=""
	IFS=$IFSNL

	for RKHTMPVAR in ${FILESCAN}; do
		ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1`

		RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/^[ 	]*//'`
		TYPE=`echo "${RKHTMPVAR}" | cut -d: -f1`
		FILE=`echo "${RKHTMPVAR}" | cut -d: -f2`
		INFO=`echo "${RKHTMPVAR}" | cut -d: -f3`

		case "${TYPE}" in
		dir)
			if [ -d "${FILE}" ]; then
				RKHTMPVAR2=`echo "${FILE}" | sed -e 's/\./\\\./g'`

				if [ -n "`echo \"${RTKT_DIR_WHITELIST}\" | grep \" ${RKHTMPVAR2} \"`" ]; then
					display --to LOG --type INFO FILE_PROP_WL_DIR "${FILE}" possible_rkt_files
					test $VERBOSE_LOGGING -eq 1 && display --to LOG --type PLAIN --result FOUND --log-indent 4 ROOTKIT_FILES_DIRS_DIR "${FILE}"
				else
					FOUND=1
					FOUNDDIRS="${FOUNDDIRS}%${FILE}:${INFO}"

					if [ $VERBOSE_LOGGING -eq 1 ]; then
						display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_FILES_DIRS_DIR "${FILE}"
					fi
				fi
			elif [ $VERBOSE_LOGGING -eq 1 ]; then
				display --to LOG --type PLAIN --result NOT_FOUND --log-indent 4 ROOTKIT_FILES_DIRS_DIR "${FILE}"
			fi
			;;
		file)
			if [ -f "${FILE}" ]; then
				RKHTMPVAR2=`echo "${FILE}" | sed -e 's/\./\\\./g'`

				if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \" ${RKHTMPVAR2} \"`" ]; then
					display --to LOG --type INFO FILE_PROP_WL "${FILE}" possible_rkt_files
					test $VERBOSE_LOGGING -eq 1 && display --to LOG --type PLAIN --result FOUND --log-indent 4 ROOTKIT_FILES_DIRS_FILE "${FILE}"
				else
					FOUND=1
					FOUNDFILES="${FOUNDFILES}%${FILE}:${INFO}"

					if [ $VERBOSE_LOGGING -eq 1 ]; then
						display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_FILES_DIRS_FILE "${FILE}"
					fi
				fi
			elif [ $VERBOSE_LOGGING -eq 1 ]; then
				display --to LOG --type PLAIN --result NOT_FOUND --log-indent 4 ROOTKIT_FILES_DIRS_FILE "${FILE}"
			fi
			;;
		*)
			echo "Error: Unknown file type in possible rootkit check: FILESCAN contains: ${TYPE}"
			;;
		esac
	done

	IFS=$RKHIFS


	#
	# Now display the results.
	#

	if [ $FOUND -eq 0 ]; then
		display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_POSS_FILES_DIRS
	else
		display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_POSS_FILES_DIRS

		IFS="%"

		for RKHTMPVAR in ${FOUNDFILES}; do
			FILE=`echo "${RKHTMPVAR}" | cut -d: -f1`
			INFO=`echo "${RKHTMPVAR}" | cut -d: -f2`

			test -z "${FILE}" && continue

			ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1`
			ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${INFO}, "

			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_POSS_FILES_FILE_FOUND "${FILE}" "${INFO}"
		done

		for RKHTMPVAR in ${FOUNDDIRS}; do
			FILE=`echo "${RKHTMPVAR}" | cut -d: -f1`
			INFO=`echo "${RKHTMPVAR}" | cut -d: -f2`

			test -z "${FILE}" && continue

			ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1`
			ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${INFO}, "

			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_POSS_FILES_DIR_FOUND "${FILE}" "${INFO}"
		done

		IFS=$RKHIFS
	fi

	return
}


possible_rootkit_string_checks() {

	#
	# This function performs the check for possible rootkit
	# strings in files.
	#

	if `check_test possible_rkt_strings`; then
		if [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --nl --log-indent 2 ROOTKIT_POSS_STRINGS_LOG
		fi

		display --to LOG --type INFO STARTING_TEST possible_rkt_strings
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST possible_rkt_strings
		return
	fi

	#
	# First check to see if we have a 'strings' command.
	#

	if [ -z "${STRINGS_CMD}" ]; then
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --screen-indent 4 ROOTKIT_POSS_STRINGS
		display --to LOG --type INFO NOT_FOUND_CMD "strings"
		return
	fi


	#
	# Set and check that the local system 'rc' file is okay.
	#

	RC_PATHS=""

	if [ -n "${RC_FILE}" ]; then
		FILENAMES="${RC_FILE}"
	else
		FILENAMES="${RCLOCATIONS}"
	fi

	for FNAME in ${FILENAMES}; do
		if [ -f "${RKHROOTDIR}${FNAME}" -a ! -h "${RKHROOTDIR}${FNAME}" ]; then
			RC_PATHS="${RC_PATHS}
${RKHROOTDIR}${FNAME}"
		fi
	done

	if [ -n "${RC_PATHS}" ]; then
		if [ -z "${RC_FILE}" ]; then
			for FNAME in ${RC_PATHS}; do
				display --to LOG --type INFO STARTUP_FOUND_LOCAL_RC_FILE "${FNAME}"
			done
		fi
	else
		display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 ROOTKIT_POSS_STRINGS
		display --to LOG --type PLAIN --log-indent 9 STARTUP_CHECK_SYSTEM_RC_NONE
		return
	fi


	FOUND=0
	FOUNDFILES=""
	IFS=$IFSNL

	for RKHTMPVAR in ${STRINGSCAN}; do
		FOUNDFILE=0
		FOUNDSTRING=""

		RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/^[ 	]*//'`
		FILE=`echo "${RKHTMPVAR}" | cut -d: -f1`
		FILESTRING=`echo "${RKHTMPVAR}" | cut -d: -f2`
		STRING=`echo "${FILESTRING}" | sed -e 's/\./\\\./g'`
		INFO=`echo "${RKHTMPVAR}" | cut -d: -f3`

		if [ "${FILE}" = "rcfile" ]; then
			FOUNDFILE=1

			for FNAME in ${RC_PATHS}; do
				FOUNDSTRING=`${STRINGS_CMD} ${FNAME} | grep "${STRING}"`

				if [ -n "${FOUNDSTRING}" ]; then
					FOUND=1
					FOUNDSTRINGS="${FOUNDSTRINGS}%${FNAME}:${FILESTRING}:${INFO}"
				fi
			done
		else
			#
			# We cannot use the 'find_cmd' function here because we
			# are looking at the command binaries themselves, not
			# executing them as commands from the local system.
			#
			# We need to jiggle with IFS here because we are in
			# two loops which are using different field separators.
			#

			IFS=$RKHIFS

			for DIR in ${BINPATHS}; do
				FILENAME="${RKHROOTDIR}${DIR}/${FILE}"

				if [ -f "${FILENAME}" ]; then
					FOUNDFILE=1
					FOUNDSTRING=`${STRINGS_CMD} ${FILENAME} | grep "${STRING}"`

					if [ -n "${FOUNDSTRING}" ]; then
						FOUND=1
						FOUNDSTRINGS="${FOUNDSTRINGS}%${FILENAME}:${FILESTRING}:${INFO}"
					fi

					break
				fi
			done
		fi

		if [ $FOUNDFILE -eq 1 ]; then
			ROOTKIT_COUNT=`expr ${ROOTKIT_COUNT} + 1`

			if [ $VERBOSE_LOGGING -eq 1 ]; then
				if [ -z "${FOUNDSTRING}" ]; then
					display --to LOG --type PLAIN --result NOT_FOUND --log-indent 4 ROOTKIT_FILES_DIRS_STR "${FILESTRING}"
				else
					display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_FILES_DIRS_STR "${FILESTRING}"
				fi
			fi
		fi

		IFS=$IFSNL
	done

	IFS=$RKHIFS


	#
	# Now display the results.
	#

	if [ $FOUND -eq 0 ]; then
		display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_POSS_STRINGS
	else
		display --to SCREEN+LOG --type WARNING --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_POSS_STRINGS

		IFS="%"

		for RKHTMPVAR in ${FOUNDSTRINGS}; do
			FILE=`echo "${RKHTMPVAR}" | cut -d: -f1`

			test -z "${FILE}" && continue

			FILESTRING=`echo "${RKHTMPVAR}" | cut -d: -f2`
			INFO=`echo "${RKHTMPVAR}" | cut -d: -f3`

			ROOTKIT_FAILED_COUNT=`expr ${ROOTKIT_FAILED_COUNT} + 1`
			ROOTKIT_FAILED_NAMES="${ROOTKIT_FAILED_NAMES}${INFO}, "

			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_POSS_STRINGS_FOUND "${FILESTRING}" "${FILE}" "${INFO}"
		done

		IFS=$RKHIFS
	fi

	return
}


additional_rootkit_checks() {

	#
	# This function performs additional rootkit checks.
	# These include checks for possible rootkits.
	#

	if `check_test additional_rkts`; then
		display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 ROOTKIT_ADD_START
		display --to LOG --type INFO STARTING_TEST additional_rkts
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST additional_rkts
		return
	fi

	if [ "${OPERATING_SYSTEM}" = "Linux" ]; then
		suckit_extra_checks
	fi

	possible_rootkit_file_dir_checks

	possible_rootkit_string_checks

	return
}



malware_checks() {

	#
	# This function performs malware checks.
	#

	if `check_test malware`; then
		display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 ROOTKIT_MALWARE_START
		display --to LOG --type INFO STARTING_TEST malware
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST malware
		return
	fi


	#
	# First we check for processes using deleted files.
	#

	if `check_test deleted_files`; then
		display --to LOG --type INFO STARTING_TEST deleted_files

		if [ -n "${LSOF_CMD}" ]; then
			FOUND=0
			WHITEPROC=""; BLACKPROC=""

			DELE_FILES=`${LSOF_CMD} -n -l -w ${SOLARISX} | grep '(dele' | head -n 1`

			if [ -n "${DELE_FILES}" ]; then
				PIDLIST=" "

				ALLOWPROCDELFILES=`get_option 1 multi ALLOWPROCDELFILE` || exit 1

				IFS=$IFSNL

				for LINE in `${LSOF_CMD} -wnl ${SOLARISX} | grep '(dele'`; do
					PROC=""

					PID=`echo "${LINE}" | awk '{ print $2 }'`
					NODE=`echo "${LINE}" | awk '{ print $8 }'`
					FNAME=`echo "${LINE}" | awk '{ print $9 }'`

					#
					# Skip any PID's we have already seen.
					#

					test -n "`echo \"${PIDLIST}\" | grep \" $PID \"`" && continue

					#
					# Try and get the running process name.
					#

					if [ -n "${READLINK_CMD}" ]; then
						RKHTMPVAR=""

						if [ $SOL_PROC -eq 1 ]; then
							test -h "/proc/${PID}/path/a.out" && RKHTMPVAR=`${READLINK_CMD} -f /proc/${PID}/path/a.out`
						elif [ $SUNOS -eq 0 -o -h "/proc/${PID}/exe" ]; then
							test -h "/proc/${PID}/exe" && RKHTMPVAR=`${READLINK_CMD} -f /proc/${PID}/exe`
						fi

						test -n "${RKHTMPVAR}" && PROC=`echo "${RKHTMPVAR}" | cut -d' ' -f1`
					fi

					if [ -z "${PROC}" ]; then
						if [ $SUNOS -eq 1 ]; then
							PROC=`${LSOF_CMD} -wnl -p $PID | grep '[ 	]txt[ 	][ 	]*VREG[ 	]' | head -n 1 | awk '{ print $NF }'`
						else
							PROC=`${LSOF_CMD} -wnl -p $PID | grep '[ 	]txt[ 	][ 	]*REG[ 	]' | awk '{ print $NF }'`
						fi

						test -z "${PROC}" && PROC=`echo "${LINE}" | awk '{ print $1 }'`
					fi

					#
					# If FNAME is not a pathname then look at the NODE.
					#

					if [ -z "`echo \"${FNAME}\" | grep '^/'`" ]; then
						if [ -n "`echo \"${NODE}\" | grep '^/'`" ]; then
							FNAME="${NODE}"
						fi
					fi

					#
					# Strip anything after the pathname.
					#

					if [ -n "`echo \"${FNAME}\" | grep '^/'`" ]; then
						FNAME=`echo "${FNAME}" | cut -d' ' -f1`
					fi

					#
					# Now see if the process is whitelisted.
					#

					PROCWHITELISTED=0

					for RKHTMPVAR in $ALLOWPROCDELFILES; do
						if [ "${PROC}" = "${RKHTMPVAR}" ]; then
							PROCWHITELISTED=1
							break
						fi
					done

					test -z "${READLINK_CMD}" && PROC="\"${PROC}\""

					if [ $PROCWHITELISTED -eq 1 ]; then
						if [ -z "`echo \"${WHITEPROC}\" | egrep \"${PROC}( |$)\"`" ]; then
							WHITEPROC="${WHITEPROC} ${PROC}"
						fi
					else
						FOUND=1
						BLACKPROC="${BLACKPROC}
${PROC} ${PID} ${FNAME}"
					fi


					#
					# Finally add the PID to the seen PID list.
					#

					PIDLIST="$PIDLIST $PID "
				done
			fi


			#
			# Now display the results.
			#

			if [ $FOUND -eq 0 ]; then
				display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_DELETED_FILES
			else
				display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_DELETED_FILES

				display --to LOG --type WARNING ROOTKIT_MALWARE_DELETED_FILES_FOUND

				for LINE in ${BLACKPROC}; do
					PROC=`echo "$LINE" | cut -d' ' -f1`
					PID=`echo "$LINE" | cut -d' ' -f2`
					FNAME=`echo "$LINE" | cut -d' ' -f3`

					test -z "${PROC}" && continue

					display --to LOG --type PLAIN --log-indent 9 ROOTKIT_MALWARE_DELETED_FILES_FOUND_DATA "${PROC}" "${PID}" "${FNAME}"
				done
			fi

			IFS=$RKHIFS

			for RKHTMPVAR in $WHITEPROC; do
				display --to LOG --type INFO NETWORK_PACKET_CAP_WL "${RKHTMPVAR}"
			done
		else
			display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_DELETED_FILES
			display --to LOG --type INFO NOT_FOUND_CMD "lsof"
		fi
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST deleted_files
	fi


	#
	# Next we check to see if there any running processes
	# using suspicious files.
	#

	if `check_test running_procs`; then
		display --to LOG --type INFO STARTING_TEST running_procs

		if [ -n "${LSOF_CMD}" ]; then
			SUSP_FILES=""
			IFS=$IFSNL

			for RKHTMPVAR in ${SUSP_FILES_INFO}; do
				RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/^[ 	]*//'`
				FILENAME=`echo "${RKHTMPVAR}" | cut -d: -f1 | sed -e 's/\./\\\./g'`
				SUSP_FILES="${SUSP_FILES}|${FILENAME}"
			done

			IFS=$RKHIFS

			SUSP_FILES=`echo "${SUSP_FILES}" | sed -e 's/^|//'`

			#
			# If we have the 'sort' and 'uniq' commands available,
			# then the output will be less and avoids listing any
			# duplicate processes.
			#

			if [ -n "${SORT_CMD}" -a -n "${UNIQ_CMD}" ]; then
				FILENAME=`${LSOF_CMD} -F n -w -n | grep '^n/' | sed -e 's/^n//' | ${SORT_CMD} | ${UNIQ_CMD} | egrep "/(${SUSP_FILES})\$"`
			else
				FILENAME=`${LSOF_CMD} -F n -w -n | grep '^n/' | sed -e 's/^n//' | egrep "/(${SUSP_FILES})\$"`
			fi

			if [ -z "${FILENAME}" ]; then
				display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_SUSP_FILES
			else
				display --to SCREEN+LOG --type WARNING --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_SUSP_FILES

				SUSP_FILES=`echo "${SUSP_FILES}" | sed -e 's/|/, /g'`
				SUSP_FILES=`echo "${SUSP_FILES}" | sed -e 's/\\\././g'`
				display --to LOG --type WARNING --log-indent 2 ROOTKIT_MALWARE_SUSP_FILES_FOUND "${SUSP_FILES}"
			fi
		else
			display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_SUSP_FILES
			display --to LOG --type INFO NOT_FOUND_CMD "lsof"
		fi
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST running_procs
	fi


	#
	# Next we check for any hidden processes.
	#

	if `check_test hidden_procs`; then
		display --to LOG --type INFO STARTING_TEST hidden_procs

		UNHIDE_CMD=`find_cmd unhide`

		if [ -n "${UNHIDE_CMD}" ]; then
			HIDDEN_PROCS=`${UNHIDE_CMD} sys | grep '^F' | awk -F':' '{ print $2 }'`

			if [ -z "${HIDDEN_PROCS}" ]; then
				display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_HIDDEN_PROCS
			else
				display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_HIDDEN_PROCS
				display --to LOG --type WARNING --log-indent 2 ROOTKIT_MALWARE_HIDDEN_PROCS_FOUND "${HIDDEN_PROCS}"
			fi
		else
			display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_MALWARE_HIDDEN_PROCS
			display --to LOG --type INFO NOT_FOUND_CMD "unhide"
		fi
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST hidden_procs
	fi


	# 
	# Next we run the check for suspicious file contents.
	# 

	suspscan


	#
	# We have completed the checks which can be enabled/disabled,
	# but we need to be able to exclude or include the rest of the
	# malware checks. As such we do a simple test for 'other_malware'
	# as a test name, and only proceed if it is enabled.
	#

	if `check_test other_malware`; then
		if [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --nl --log-indent 2 ROOTKIT_MALWARE_LOGIN_BDOOR_LOG
		fi

		display --to LOG --type INFO STARTING_TEST other_malware
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST other_malware
		return
	fi


	#
	# Next we check for login backdoors.
	#

	FOUND=0
	FOUNDFILES=""

	for FILE in ${LOGIN_BACKDOOR_FILES}; do
		if [ -e "${FILE}" ]; then
			RKHTMPVAR=`echo "${FILE}" | sed -e 's/\./\\\./g'`

			if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \" ${RKHTMPVAR} \"`" ]; then
				display --to LOG --type INFO FILE_PROP_WL "${FILE}" other_malware
			else
				FOUND=1
				FOUNDFILES="${FOUNDFILES} ${FILE}"
			fi

			test $VERBOSE_LOGGING -eq 1 && display --to LOG --type PLAIN --result FOUND --log-indent 4 ROOTKIT_MALWARE_LOGIN_BDOOR_CHK "${FILE}"
		elif [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --result NOT_FOUND --log-indent 4 ROOTKIT_MALWARE_LOGIN_BDOOR_CHK "${FILE}"
		fi
	done


	#
	# Now display the results.
	#

	if [ $FOUND -eq 0 ]; then
		display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_LOGIN_BDOOR
	else
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_LOGIN_BDOOR

		for FILE in ${FOUNDFILES}; do
			display --to LOG --type WARNING ROOTKIT_MALWARE_LOGIN_BDOOR_FOUND "${FILE}"
		done
	fi


	#
	# Next check for any suspicious directories.
	#

	FOUND=0
	FOUNDDIRS=""

	if [ $VERBOSE_LOGGING -eq 1 ]; then
		display --to LOG --type PLAIN --nl --log-indent 2 ROOTKIT_MALWARE_SUSP_DIR_LOG
	fi

	for DIR in ${SUSPICIOUS_DIRS}; do
		if [ -d "${DIR}" ]; then
			RKHTMPVAR=`echo "${DIR}" | sed -e 's/\./\\\./g'`

			if [ -n "`echo \"${RTKT_DIR_WHITELIST}\" | grep \" ${RKHTMPVAR} \"`" ]; then
				display --to LOG --type INFO FILE_PROP_WL_DIR "${DIR}" other_malware
			else
				FOUND=1
				FOUNDDIRS="${FOUNDDIRS} ${DIR}"
			fi

			test $VERBOSE_LOGGING -eq 1 && display --to LOG --type PLAIN --result FOUND --log-indent 4 ROOTKIT_FILES_DIRS_DIR "${DIR}"
		elif [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --result NOT_FOUND --log-indent 4 ROOTKIT_FILES_DIRS_DIR "${DIR}"
		fi
	done


	#
	# Now display the results.
	#

	if [ $FOUND -eq 0 ]; then
		display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_SUSP_DIR
	else
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_SUSP_DIR

		for DIR in ${FOUNDDIRS}; do
			display --to LOG --type WARNING ROOTKIT_MALWARE_SUSP_DIR_FOUND "${DIR}"
		done
	fi


	#
	# Next we check for any software intrusions.
	#

	TRIPWIREFILE="${RKHROOTDIR}/var/lib/tripwire/`uname -n 2>/dev/null`.twd"

	if [ -f "${TRIPWIREFILE}" ]; then
		if [ -z "`grep 'Tripwire segment-faulted !' ${TRIPWIREFILE}`" ]; then
			display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 --log-nl ROOTKIT_MALWARE_SFW_INTRUSION
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 --log-nl ROOTKIT_MALWARE_SFW_INTRUSION
			display --to LOG --type WARNING --log-indent 2 ROOTKIT_MALWARE_SFW_INTRUSION_FOUND "${TRIPWIREFILE}" "Tripwire segment-faulted"
		fi
	else
		display --to LOG --type PLAIN --result SKIPPED --log-indent 2 --log-nl ROOTKIT_MALWARE_SFW_INTRUSION
		display --to LOG --type INFO ROOTKIT_MALWARE_SFW_INTRUSION_SKIP
	fi


	#
	# Next, check for sniffer log files.
	#

	FOUND=0
	FOUNDFILES=""

	if [ $VERBOSE_LOGGING -eq 1 ]; then
		display --to LOG --type PLAIN --nl --log-indent 2 ROOTKIT_MALWARE_SNIFFER_LOG
	fi

	for FNAME in ${SNIFFER_FILES}; do
		if [ -f "${FNAME}" ]; then
			RKHTMPVAR=`echo "${FNAME}" | sed -e 's/\./\\\./g'`

			if [ -n "`echo \"${RTKT_FILE_WHITELIST}\" | grep \" ${RKHTMPVAR} \"`" ]; then
				display --to LOG --type INFO FILE_PROP_WL "${FNAME}" other_malware
			else
				FOUND=1
				FOUNDFILES="${FOUNDFILES} ${FNAME}"
			fi

			test $VERBOSE_LOGGING -eq 1 && display --to LOG --type PLAIN --result FOUND --log-indent 4 ROOTKIT_FILES_DIRS_FILE "${FNAME}"
		elif [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --result NOT_FOUND --log-indent 4 ROOTKIT_FILES_DIRS_FILE "${FNAME}"
		fi
	done


	#
	# Now display the results.
	#

	if [ $FOUND -eq 0 ]; then
		display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_SNIFFER
	else
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_MALWARE_SNIFFER

		for FNAME in ${FOUNDFILES}; do
			display --to LOG --type WARNING ROOTKIT_MALWARE_SNIFFER_FOUND "${FNAME}"
		done
	fi

	return
}


xinetd_include() {

	#
	# This function handles the xinetd 'include' directive.
	# It is also used to initially process the xinetd.conf
	# file, and to process any files within an 'includedir'
	# directory.
	#
	# Any filename containing a dot or ending in a tilde (~)
	# is ignored. Also absolute pathnames must be used.
	#

	test -z "$1" -o ! -f "${RKHROOTDIR}$1" && return
	test -z "`echo \"$1\" | grep '^/'`" && return

	test -n "`echo \"$1\" | grep '/[^/]*\.[^/]*$'`" -a "$1" != "${XINETD_CONF_PATH}" && return
	test -n "`echo \"$1\" | grep '~$'`" && return


	#
	# First see if any services have been enabled.
	#

	if [ -n "`grep '^[ 	]*disable[ 	]*=[ 	]*no' ${RKHROOTDIR}$1`" ]; then
		#
		# See if the file is whitelisted.
		#

		RKHTMPVAR=0

		for FNAME in ${XINETDALLOWEDSVCS}; do
			if [ "${FNAME}" = "$1" ]; then
				RKHTMPVAR=1
				break
			fi
		done

		if [ $RKHTMPVAR -eq 0 ]; then
			FOUND=1
			FOUNDFILES="${FOUNDFILES} ${RKHROOTDIR}$1"

			if [ $VERBOSE_LOGGING -eq 1 ]; then
				display --to LOG --type PLAIN --result WARNING --log-indent 4 ROOTKIT_TROJAN_XINETD_ENABLED "${RKHROOTDIR}$1"
			fi
		elif [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --result NONE_FOUND --log-indent 4 ROOTKIT_TROJAN_XINETD_ENABLED "${RKHROOTDIR}$1"
			display --to LOG --type INFO ROOTKIT_TROJAN_XINETD_WHITELIST "$1" "xinetd"
		fi
	elif [ $VERBOSE_LOGGING -eq 1 ]; then
		display --to LOG --type PLAIN --result NONE_FOUND --log-indent 4 ROOTKIT_TROJAN_XINETD_ENABLED "${RKHROOTDIR}$1"
	fi


	#
	# Next we look for any 'include' directives.
	#

	for FNAME in `grep '^[ 	]*include[ 	]' ${RKHROOTDIR}$1 | awk '{ print $2 }'`; do
		if [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --log-indent 6 ROOTKIT_TROJAN_XINETD_INCLUDE "${FNAME}"
		fi

		xinetd_include "${FNAME}"
	done


	#
	# Finally we look for any 'includedir' directives.
	#

	for DIR in `grep '^[ 	]*includedir[ 	]' ${RKHROOTDIR}$1 | awk '{ print $2 }'`; do
		if [ $VERBOSE_LOGGING -eq 1 ]; then
			display --to LOG --type PLAIN --log-indent 6 ROOTKIT_TROJAN_XINETD_INCLUDEDIR "${DIR}"
		fi

		xinetd_includedir "${DIR}"
	done

	return
}


xinetd_includedir() {

	#
	# This function handles the xinetd 'includedir' directive.
	#
	# Absolute pathnames must be used.
	#

	test -z "$1" -o ! -d "${RKHROOTDIR}$1" && return
	test -z "`echo \"$1\" | grep '^/'`" && return


	for FNAME in `ls ${RKHROOTDIR}$1`; do
		xinetd_include "$1/${FNAME}"
	done

	return
}


sol10_inetd() {

	#
	# This function handles the Solaris 10, and later, inetd
	# configuration. Because the original inetd.conf file may
	# well exist, we look in there as well for any enabled services.
	#
	# This function sets the FOUNDSTRING variable, which will
	# be used later.
	#

	FOUNDSTRING=`${INETADM_CMD} | grep '^enabled' | cut -d: -f2`

	if [ -f "${RKHROOTDIR}${INETD_CONF_PATH}" ]; then
		STR=`grep -v '^#' ${RKHROOTDIR}${INETD_CONF_PATH} | awk '{ print $1 }'`

		#
		# Remove any inetd services which we already know
		# about from inetadm.
		#

		for RKHTMPVAR in ${STR}; do
			if [ -z "`echo \"${FOUNDSTRING}\" | grep \"/${RKHTMPVAR}/\"`" ]; then
				FOUNDSTRING="${FOUNDSTRING} ${RKHTMPVAR}"
			fi
		done
	fi

	return
}


trojan_checks() {

	#
	# This function performs some trojan specific checks.
	#

	if ! `check_test trojans`; then
		display --to LOG --type INFO --nl USER_DISABLED_TEST trojans
		return
	fi


	#
	# We first need to see if we are running Solaris 10 or later.
	# Earlier versions of Solaris used the standard inetd configuration
	# file, but later versions use a different mechanism. The 'inetadm'
	# command can be used on these later Solaris versions.
	#

	if [ $SUNOS -eq 1 ]; then
		INETADM_CMD=`find_cmd inetadm`

		test -n "${INETADM_CMD}" && sol10_inetd
	else
		INETADM_CMD=""
	fi


	if [ -f "${RKHROOTDIR}${INETD_CONF_PATH}" -o -f "${RKHROOTDIR}${XINETD_CONF_PATH}" -o -n "${INETADM_CMD}" ]; then
		RKHTMPVAR="SCREEN+LOG"
	else
		RKHTMPVAR="LOG"
	fi

	display --to "${RKHTMPVAR}" --type PLAIN --nl --screen-indent 2 ROOTKIT_TROJAN_START

	display --to LOG --type INFO STARTING_TEST trojans


	#
	# We first check the inetd.conf file. This includes the
	# Solaris 10 inetd services as well.
	#

	if [ -f "${RKHROOTDIR}${INETD_CONF_PATH}" -o -n "${INETADM_CMD}" ]; then
		if [ -z "${INETADM_CMD}" ]; then
			display --to LOG --type INFO CONFIG_XINETD_PATH "inetd" "${INETD_CONF_PATH}"

			FOUNDSTRING=`grep -v '^#' ${RKHROOTDIR}${INETD_CONF_PATH} | awk '{ print $1 }'`
		else
			display --to LOG --type INFO CONFIG_SOL10_INETD
		fi

		#
		# We now need to see if any of the services are whitelisted.
		#

		RKHTMPVAR=""

		for STR in ${FOUNDSTRING}; do
			FOUND=0

			for SVC in ${INETDALLOWEDSVCS}; do
				if [ "${STR}" = "${SVC}" ]; then
					FOUND=1
					display --to LOG --type INFO ROOTKIT_TROJAN_XINETD_WHITELIST "${SVC}" "inetd"
					break
				fi
			done

			if [ $FOUND -eq 0 ]; then
				#
				# We want to change any RPC services into
				# an actual executable name, if we can. The
				# executable is the sixth field. If the
				# sixth field is empty or this is an internal
				# service, then we just use the service name.
				#

				if [ -n "`echo \"${STR}\" | grep '^[0-9/_-]*$'`" ]; then
					EXECNAME=`grep "^${STR}" ${RKHROOTDIR}${INETD_CONF_PATH} | awk '{ print $6 }'`

					test -z "${EXECNAME}" -o "${EXECNAME}" = "internal" && EXECNAME="${STR}"

					STR="${EXECNAME}"


					#
					# Now check if the executable has been whitelisted.
					#

					for SVC in ${INETDALLOWEDSVCS}; do
						if [ "${STR}" = "${SVC}" ]; then
							FOUND=1
							display --to LOG --type INFO ROOTKIT_TROJAN_XINETD_WHITELIST "${SVC}" "inetd"
							break
						fi
					done
				fi

				test $FOUND -eq 0 && RKHTMPVAR="${RKHTMPVAR} ${STR}"
			fi
		done

		FOUNDSTRING="${RKHTMPVAR}"


		#
		# Now display the results.
		#

		if [ -z "${FOUNDSTRING}" ]; then
			display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --screen-indent 4 --log-indent 2 ROOTKIT_TROJAN_INETD
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --screen-indent 4 --log-indent 2 ROOTKIT_TROJAN_INETD

			for STR in ${FOUNDSTRING}; do
				display --to LOG --type WARNING ROOTKIT_TROJAN_INETD_FOUND "${STR}"
			done
		fi
	else
		display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_TROJAN_INETD
		display --to LOG --type INFO ROOTKIT_TROJAN_INETD_SKIP "${RKHROOTDIR}${INETD_CONF_PATH}"
	fi


	#
	# Next we check the xinetd.conf file.
	#

	FOUND=0
	FOUNDFILES=""

	if [ $VERBOSE_LOGGING -eq 1 ]; then
		display --to LOG --type PLAIN --nl --log-indent 2 ROOTKIT_TROJAN_XINETD_LOG
	fi

	if [ -f "${RKHROOTDIR}${XINETD_CONF_PATH}" ]; then
		display --to LOG --type INFO CONFIG_XINETD_PATH "xinetd" "${XINETD_CONF_PATH}"

		xinetd_include "${XINETD_CONF_PATH}"


		#
		# Now display the results.
		#

		if [ $FOUND -eq 0 ]; then
			display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_TROJAN_XINETD
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_TROJAN_XINETD

			for FNAME in ${FOUNDFILES}; do
				display --to LOG --type WARNING ROOTKIT_TROJAN_XINETD_ENABLED_FOUND "${FNAME}"
			done
		fi
	else
		display --to LOG --type PLAIN --result SKIPPED --log-indent 2 ROOTKIT_TROJAN_XINETD
		display --to LOG --type INFO ROOTKIT_TROJAN_INETD_SKIP "${RKHROOTDIR}${XINETD_CONF_PATH}"
	fi


	#
	# Finally we check for an Apache backdoor module.
	#

	FOUND=0
	FOUNDFILES=""

	MOD_DIRS="${RKHROOTDIR}/etc/apache2/mods-enabled ${RKHROOTDIR}/etc/httpd/modules ${RKHROOTDIR}/usr/apache/libexec ${RKHROOTDIR}/usr/lib/modules ${RKHROOTDIR}/usr/local/apache/modules"

	HTTPDDIRS="${RKHROOTDIR}/usr/local/apache/conf ${RKHROOTDIR}/usr/local/etc/apache ${RKHROOTDIR}/etc/apache ${RKHROOTDIR}/etc/httpd/conf"

	for DIR in ${MOD_DIRS} ${HTTPDDIRS}; do
		if [ -d "${DIR}" ]; then
			FOUND=1

			test -f "${DIR}/mod_rootme.so" && FOUNDFILES="${FOUNDFILES} ${DIR}/mod_rootme.so"
			test -f "${DIR}/mod_rootme2.so" && FOUNDFILES="${FOUNDFILES} ${DIR}/mod_rootme2.so"

			if [ -f "${DIR}/httpd.conf" ]; then
				if [ -n "`egrep 'mod_rootme2?\.so' ${DIR}/httpd.conf`" ]; then
					FOUNDFILES="${FOUNDFILES} ${DIR}/httpd.conf"
				fi
			fi
		fi
	done


	#
	# Now display the results.
	#

	if [ $FOUND -eq 0 ]; then
		display --to LOG --type INFO ROOTKIT_TROJAN_APACHE_SKIPPED
	elif [ -z "${FOUNDFILES}" ]; then
		display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_TROJAN_APACHE
	else
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_TROJAN_APACHE

		for FILE in ${FOUNDFILES}; do
			display --to LOG --type WARNING ROOTKIT_TROJAN_APACHE_FOUND "${FILE}"
		done
	fi

	return
}


bsd_specific_checks() {

	#
	# This function performs tests specific to the BSD O/S.
	#


	SOCKSTAT_CMD=`find_cmd sockstat`

	if [ -n "${SOCKSTAT_CMD}" -a -n "${NETSTAT_CMD}" -a -n "${SORT_CMD}" -a -n "${UNIQ_CMD}" ]; then
		SOCKSTAT_OUTPUT=`${SOCKSTAT_CMD} -n | grep '\*[:.]\*' | cut -c1-55 | grep '\*[:.]' | cut -c39-47 | grep -v '\*' | tr -d ' ' | ${SORT_CMD} | ${UNIQ_CMD}`
		NETSTAT_OUTPUT=`${NETSTAT_CMD} -an | egrep -v 'TIME_WAIT|ESTABLISHED|SYN_SENT|CLOSE_WAIT|LAST_ACK|SYN_RECV|CLOSING' | cut -c1-44 | grep '\*\.' | cut -c24-32 | grep -v '\*' | tr -d ' ' | tr -d '\t' | ${SORT_CMD} | ${UNIQ_CMD}`

		if [ "${SOCKSTAT_OUTPUT}" = "${NETSTAT_OUTPUT}" ]; then
			display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_OS_BSD_SOCKNET
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_OS_BSD_SOCKNET

			display --to LOG --type WARNING ROOTKIT_OS_BSD_SOCKNET_FOUND
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_OS_BSD_SOCKNET_OUTPUT "Sockstat" "${SOCKSTAT_OUTPUT}"
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_OS_BSD_SOCKNET_OUTPUT "Netstat" "${NETSTAT_OUTPUT}"
		fi
	else
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_OS_BSD_SOCKNET

		test -z "${SOCKSTAT_CMD}" && display --to LOG --type INFO NOT_FOUND_CMD "sockstat"
		test -z "${NETSTAT_CMD}" && display --to LOG --type INFO NOT_FOUND_CMD "netstat"
		test -z "${SORT_CMD}" && display --to LOG --type INFO NOT_FOUND_CMD "sort"
		test -z "${UNIQ_CMD}" && display --to LOG --type INFO NOT_FOUND_CMD "uniq"
	fi

	return
}


freebsd_specific_checks() {

	#
	# This function performs tests specific to the FreeBSD O/S.
	#


	#
	# First we check for KLD backdoors.
	#

	KLDSTAT_CMD=`find_cmd kldstat`

	if [ -n "${KLDSTAT_CMD}" ]; then
		FOUND=0
		FOUNDKEYS=""

		for RKHTMPVAR in ${KLDSTATKEYWORDS}; do
			RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/^[ 	]*//'`
			KLDKEYWD=`echo "${RKHTMPVAR}" | sed -e 's/\./\\\./g'`

			if [ -n "`${KLDSTAT_CMD} -v | grep \"${KLDKEYWD}\"`" ]; then
				FOUND=1
				FOUNDKEYS="${FOUNDKEYS} ${RKHTMPVAR} "
			fi
		done


		if [ $FOUND -eq 0 ]; then
			display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_OS_FREEBSD_KLD
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_OS_FREEBSD_KLD

			for RKHTMPVAR in ${FOUNDKEYS}; do
				display --to LOG --type WARNING ROOTKIT_OS_FREEBSD_KLD_FOUND "${RKHTMPVAR}"
			done
		fi
	else
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_OS_FREEBSD_KLD

		display --to LOG --type INFO NOT_FOUND_CMD "kldstat"
	fi


	#
	# Next we check that the package database is okay.
	#

	PKGDB_CMD=`find_cmd pkgdb`

	if [ -n "${PKGDB_CMD}" ]; then
		RKHTMPVAR=`${PKGDB_CMD} -Fa -v | grep 'Skipped\.'`

		if [ -z "${RKHTMPVAR}" ]; then
			display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_OS_FREEBSD_PKGDB
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_OS_FREEBSD_PKGDB

			display --to LOG --type WARNING ROOTKIT_OS_FREEBSD_PKGDB_NOTOK
		fi
	else
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_OS_FREEBSD_PKGDB

		display --to LOG --type INFO NOT_FOUND_CMD "pkgdb"
	fi

	return
}


linux_specific_checks() {

	#
	# This function performs tests specific to the Linux O/S.
	#


	#
	# First we check the currently loaded kernel modules.
	#

	if [ -f "${RKHROOTDIR}/proc/modules" -a -n "${LSMOD_CMD}" -a -n "${SORT_CMD}" ]; then
		PROC_OUTPUT=`cat ${RKHROOTDIR}/proc/modules | cut -d' ' -f1 | ${SORT_CMD}`
		LSMOD_OUTPUT=`${LSMOD_CMD} | grep -v 'Size *Used *by' | cut -d' ' -f1 | ${SORT_CMD}`


		if [ -n "${PROC_OUTPUT}" -a -n "${LSMOD_OUTPUT}" ]; then
			if [ "${PROC_OUTPUT}" = "${LSMOD_OUTPUT}" ]; then
				display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_OS_LINUX_LKM
			else
				display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_OS_LINUX_LKM

				display --to LOG --type WARNING ROOTKIT_OS_LINUX_LKM_FOUND
				display --to LOG --type PLAIN --log-indent 9 ROOTKIT_OS_LINUX_LKM_OUTPUT "/proc/modules" "${PROC_OUTPUT}"
				display --to LOG --type PLAIN --log-indent 9 ROOTKIT_OS_LINUX_LKM_OUTPUT "lsmod" "${LSMOD_OUTPUT}"
			fi
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_OS_LINUX_LKM

			display --to LOG --type WARNING ROOTKIT_OS_LINUX_LKM_EMPTY
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_OS_LINUX_LKM_OUTPUT "/proc/modules" "${PROC_OUTPUT}"
			display --to LOG --type PLAIN --log-indent 9 ROOTKIT_OS_LINUX_LKM_OUTPUT "lsmod" "${LSMOD_OUTPUT}"
		fi
	elif [ ! -f "${RKHROOTDIR}/proc/modules" ]; then
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_OS_LINUX_LKM

		display --to LOG --type WARNING ROOTKIT_OS_LINUX_LKM_MOD_MISSING "${RKHROOTDIR}/proc/modules"
	else
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_OS_LINUX_LKM

		test -z "${LSMOD_CMD}" && display --to LOG --type INFO NOT_FOUND_CMD "lsmod"
		test -z "${SORT_CMD}" && display --to LOG --type INFO NOT_FOUND_CMD "sort"
	fi


	#
	# Next we check for any known bad modules.
	#

	FOUND=0
	FOUNDFILES=""
	LKM_NAMES=""


	#
	# First obtain and log where the modules are kept. Generally
	# rkhunter will determine the location based on the kernel
	# version. However, in the case of remote diagnostics the
	# diagnosing and diagnosed kernel versions may be different.
	# In this case we simply look in '/lib/modules'.
	#

	if [ -z "${RKHROOTDIR}" ]; then
		LKMPATH="/lib/modules/`uname -r 2>/dev/null`"
		test ! -d "${LKMPATH}" && LKMPATH="/lib/modules"
	else
		LKMPATH="${RKHROOTDIR}/lib/modules"
	fi

	display --to LOG --type INFO ROOTKIT_OS_LINUX_LKMNAMES_PATH "${LKMPATH}"


	#
	# Next, we reformat the LKM names at this point since
	# we only need to do it once.
	#

	for RKHTMPVAR in ${LKM_BADNAMES}; do
		RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/^[ 	]*//' | sed -e 's/\./\\\./g'`
		LKM_NAMES="${LKM_NAMES} ${RKHTMPVAR}"
	done


	#
	# Now do the test.
	#

	if [ -d "${LKMPATH}" -a -n "${FIND_CMD}" ]; then
		for FNAME in `${FIND_CMD} ${LKMPATH} -type f -name "*.o" 2>/dev/null`; do
			for RKHTMPVAR in ${LKM_NAMES}; do
				if [ -n "`echo ${FNAME} | grep \"/${RKHTMPVAR}\$\"`" ]; then
					FOUND=1
					FOUNDFILES="${FOUNDFILES} ${RKHTMPVAR}"
				fi
			done
		done


		if [ $FOUND -eq 0 ]; then
			display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 2 --screen-indent 4 ROOTKIT_OS_LINUX_LKMNAMES
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_OS_LINUX_LKMNAMES

			for RKHTMPVAR in ${FOUNDFILES}; do
				RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/\\\././g'`

				display --to LOG --type WARNING ROOTKIT_OS_LINUX_LKMNAMES_FOUND "${LKMPATH}" "${RKHTMPVAR}"
			done
		fi
	elif [ ! -d "${LKMPATH}" ]; then
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ROOTKIT_OS_LINUX_LKMNAMES

		display --to LOG --type WARNING ROOTKIT_OS_LINUX_LKMNAMES_PATH_MISSING "${LKMPATH}"
	else
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ROOTKIT_OS_LINUX_LKMNAMES

		display --to LOG --type INFO NOT_FOUND_CMD "find"
	fi

	return
}


os_specific_checks() {

	#
	# This function performs any O/S specific tests.
	#

	if ! `check_test os_specific`; then
		display --to LOG --type INFO --nl USER_DISABLED_TEST os_specific
		return
	fi


	#
	# Run the relevant O/S specific tests.
	#

	case "${OPERATING_SYSTEM}" in
	*BSD)
		display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 ROOTKIT_OS_START "${OPERATING_SYSTEM}"
		display --to LOG --type INFO STARTING_TEST os_specific

		bsd_specific_checks

		test "${OPERATING_SYSTEM}" = "FreeBSD" && freebsd_specific_checks
		;;
	Linux)
		display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 ROOTKIT_OS_START "${OPERATING_SYSTEM}"
		display --to LOG --type INFO STARTING_TEST os_specific

		linux_specific_checks
		;;
	*)
		display --to LOG --type PLAIN --nl ROOTKIT_OS_START "${OPERATING_SYSTEM}"
		display --to LOG --type INFO STARTING_TEST os_specific

		display --to LOG --type INFO ROOTKIT_OS_SKIPPED
		;;
	esac

	return
}


do_rootkit_checks() {

	#
	# This function carries out a sequence of tests for rootkits.
	# This consists of the default files and directories check,
	# possible rootkit checks, and checks for malware.
	#

	if `check_test rootkits`; then
		display --to SCREEN+LOG --type PLAIN --color YELLOW --nl CHECK_ROOTKITS
		display --to LOG --type INFO STARTING_TEST rootkits
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST rootkits
		return
	fi


	rootkit_file_dir_checks

	test `check_test known_rkts || check_test all` && keypresspause

	additional_rootkit_checks

	malware_checks

	trojan_checks

	os_specific_checks

	keypresspause

	return
}


do_network_port_checks() {

	#
	# This function will check the network ports to see
	# if any known backdoor ports are being used.
	#

	if `check_test ports`; then
		display --to LOG --type INFO STARTING_TEST ports
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST ports
		return
	fi


	#
	# We must first check to see if we can perform this test.
	#

	if [ -z "${LSOF_CMD}" -a -z "${NETSTAT_CMD}" ]; then
		display --to LOG --type INFO TEST_SKIPPED_OS "network port checks" "lsof or netstat command required"
		return
	fi

	#
	# Systems with a modified kernel must also skip this test.
	#

	test $GRSECINSTALLED -eq 1 && return


	#
	# Next we do some further testing and the initial logging.
	#

	display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 NETWORK_PORTS_START

	if [ ! -s "${DB_PATH}/backdoorports.dat" ]; then
		display --to SCREEN+LOG --type WARNING --screen-indent 4 NETWORK_PORTS_FILE_MISSING
		return
	elif [ -z "${LSOF_CMD}" ]; then
		case "${OPERATING_SYSTEM}" in
		*BSD|Linux|AIX|SunOS|Darwin|IRIX*)
			#
			# We can only use pathnames if we have the 'lsof' command.
			#

			PORT_WHITELIST_PATH=""
			PORT_WHITELIST_ALL_TRUSTED=0
			display --to LOG --type INFO NETWORK_PORTS_DISABLE_PATHS
			;;
		*)
			display --to SCREEN+LOG --type WARNING --screen-indent 4 NETWORK_PORTS_UNKNOWN_NETSTAT
			return
			;;
		esac
	fi

	test $PORT_WHITELIST_ALL_TRUSTED -eq 1 && display --to LOG --type INFO NETWORK_PORTS_ENABLE_TRUSTED


	#
	# Now do the test.
	#

	IFS=$IFSNL

	for LINE in `cat ${DB_PATH}/backdoorports.dat`; do
		if [ -n "`echo \"${LINE}\" | egrep '^(#|[Vv]ersion:)'`" ]; then
			continue
		elif [ -z "${LINE}" ]; then
			continue
		fi

		PORT=`echo "${LINE}" | cut -d: -f1`
		DESCRIPTION=`echo "${LINE}" | cut -d: -f2`
		PROTO=`echo "${LINE}" | cut -d: -f3 | tr '[a-z]' '[A-Z]'`

		if [ -z "`echo \"${PORT}\" | grep '^[1-9][0-9]*$'`" ]; then
			echo "Error: Invalid port in backdoorports.dat file: $LINE"
			continue
		elif [ "${PROTO}" != "UDP" -a "${PROTO}" != "TCP" ]; then
			echo "Error: Invalid protocol in backdoorports.dat file: $LINE"
			continue
		fi

		FOUND=""

		if [ -n "${LSOF_CMD}" ]; then
			FNAME=""
			PID_SEEN=0
			IFS=$RKHIFS

			for PID in `${LSOF_CMD} -wnl -i ${PROTO}:${PORT} | grep -v '^COMMAND' | awk '{ print $2 }'`; do
				FNAME=""
				PID_SEEN=1

				#
				# Try and get the running process name.
				#

				if [ -n "${READLINK_CMD}" ]; then
					RKHTMPVAR=""

					if [ $SOL_PROC -eq 1 ]; then
						test -h "/proc/${PID}/path/a.out" && RKHTMPVAR=`${READLINK_CMD} -f /proc/${PID}/path/a.out`
					elif [ $SUNOS -eq 0 -o -h "/proc/${PID}/exe" ]; then
						test -h "/proc/${PID}/exe" && RKHTMPVAR=`${READLINK_CMD} -f /proc/${PID}/exe`
					fi

					test -n "${RKHTMPVAR}" && FNAME=`echo "${RKHTMPVAR}" | cut -d' ' -f1`
				fi

				if [ -z "${FNAME}" ]; then
					if [ $SUNOS -eq 1 ]; then
						FNAME=`${LSOF_CMD} -wnl -p $PID | grep '[ 	]txt[ 	][ 	]*VREG[ 	]' | head -n 1 | awk '{ print $NF }'`
					else
						FNAME=`${LSOF_CMD} -wnl -p $PID | grep '[ 	]txt[ 	][ 	]*REG[ 	]' | awk '{ print $NF }'`
					fi
				fi

				if [ -n "`echo \"${FNAME}\" | grep '^/'`" ]; then
					FOUND="${FNAME}"
					break
				fi
			done

			if [ -z "${FOUND}" -a $PID_SEEN -eq 1 ]; then
				FNAME=""
				FOUND="${PROTO}:${PORT}"
			fi

			IFS=$IFSNL
		else
			case "${OPERATING_SYSTEM}" in
			Linux)
				FOUND=`${NETSTAT_CMD} -an | grep -i "^${PROTO}.*:${PORT} " | awk '{ print $4 }' | grep ":${PORT}\$"`
				;;
			*BSD|Darwin|IRIX*)
				FOUND=`${NETSTAT_CMD} -an | grep -i "^${PROTO}.*\.${PORT} " | awk '{ print $4 }' | grep "\.${PORT}\$"`
				;;
			AIX)
				if [ "${PROTO}" = "UDP" ]; then
					FOUND=`${NETSTAT_CMD} -an | grep -i "^udp.*\.${PORT} " | awk '{ print $4 }' | grep "\.${PORT}\$"`
				elif [ "${PROTO}" = "TCP" ]; then
					FOUND=`${NETSTAT_CMD} -an | egrep -i "^tcp.*\.${PORT} .*(BOUND|ESTABLISH|LISTEN)" | awk '{ print $4 }' | grep "\.${PORT}\$"`
				fi
				;;
			SunOS)
				if [ "${PROTO}" = "UDP" ]; then
					FOUND=`${NETSTAT_CMD} -an | awk '/^UDP: IPv4/, /^$/ { print $1 }' | grep "\.${PORT}\$"`

					if [ -z "${FOUND}" ]; then
						FOUND=`${NETSTAT_CMD} -an | awk '/^UDP: IPv6/, /^$/ { print $1 }' | grep "\.${PORT}\$"`
					fi
				elif [ "${PROTO}" = "TCP" ]; then
					FOUND=`${NETSTAT_CMD} -an | awk '/^TCP: IPv4/, /^$/ { print $0 }' | egrep 'BOUND|ESTABLISH|LISTEN' | awk '{ print $1 }' | grep "\.${PORT}\$"`

					if [ -z "${FOUND}" ]; then
						FOUND=`${NETSTAT_CMD} -an | awk '/^TCP: IPv6/, /^$/ { print $0 }' | egrep 'BOUND|ESTABLISH|LISTEN' | awk '{ print $1 }' | grep "\.${PORT}\$"`
					fi
				fi
				;;
			esac
		fi


		#
		# If we have found something, then see if it is whitelisted.
		#

		if [ -n "${FOUND}" ]; then
			RKHTMPVAR2=0

			if [ -n "${LSOF_CMD}" ]; then
				if [ -n "${FNAME}" ]; then
					if [ -n "`echo \"${PORT_WHITELIST_PATH}\" | grep \" ${FNAME} \"`" ]; then
						RKHTMPVAR2=1
						FOUND="path_whitelisted"
					elif [ $PORT_WHITELIST_ALL_TRUSTED -eq 1 ]; then
						RKHTMPVAR=`basename ${FNAME}`
						RKHTMPVAR=`IFS=$RKHIFS find_cmd ${RKHTMPVAR}`

						if [ "${RKHTMPVAR}" = "${FNAME}" ]; then
							RKHTMPVAR2=1
							FOUND="trusted_whitelisted"
						fi
					fi
				fi
			fi

			if [ $RKHTMPVAR2 -eq 0 -a -n "`echo \"${PORT_WHITELIST}\" | grep \" ${PROTO}:${PORT} \"`" ]; then
				FOUND="port_whitelisted"
			fi
		fi


		#
		# Now display the result.
		#

		if [ -z "${FOUND}" ]; then
			display --to SCREEN+LOG --type PLAIN --log-indent 2 --screen-indent 4 --result NOT_FOUND --color GREEN NETWORK_PORTS "${PROTO}" "${PORT}"
		elif [ "${FOUND}" = "path_whitelisted" ]; then
			display --to LOG --type INFO NETWORK_PORTS_PATH_WHITELIST "${PROTO}" "${PORT}" "${FNAME}"
			display --to SCREEN+LOG --type PLAIN --log-indent 2 --screen-indent 4 --result NOT_FOUND --color GREEN NETWORK_PORTS "${PROTO}" "${PORT}"
		elif [ "${FOUND}" = "trusted_whitelisted" ]; then
			display --to LOG --type INFO NETWORK_PORTS_TRUSTED_WHITELIST "${PROTO}" "${PORT}" "${FNAME}"
			display --to SCREEN+LOG --type PLAIN --log-indent 2 --screen-indent 4 --result NOT_FOUND --color GREEN NETWORK_PORTS "${PROTO}" "${PORT}"
		elif [ "${FOUND}" = "port_whitelisted" ]; then
			display --to LOG --type INFO NETWORK_PORTS_PORT_WHITELIST "${PROTO}" "${PORT}"
			display --to SCREEN+LOG --type PLAIN --log-indent 2 --screen-indent 4 --result NOT_FOUND --color GREEN NETWORK_PORTS "${PROTO}" "${PORT}"
		else
			display --to SCREEN+LOG --type PLAIN --log-indent 2 --screen-indent 4 --result WARNING --color RED NETWORK_PORTS "${PROTO}" "${PORT}"

			if [ -n "${FNAME}" ]; then
				display --to LOG --type WARNING NETWORK_PORTS_FOUND "${PROTO}" "${PORT}" " by ${FNAME}" "${DESCRIPTION}"
			else
				display --to LOG --type WARNING NETWORK_PORTS_FOUND "${PROTO}" "${PORT}" "" "${DESCRIPTION}"
			fi
		fi
	done

	IFS=$RKHIFS

	return
}


do_network_interface_checks() {

	#
	# This function will check the network interfaces to see
	# if any are in promiscuous mode. It will also check to see
	# if there are any applications running which are capturing
	# network interface packets.
	#

	if `check_test promisc`; then
		display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 NETWORK_INTERFACE_START
		display --to LOG --type INFO STARTING_TEST promisc


		if [ -n "${IFCONFIG_CMD}" ]; then
			PROMISCSCAN1=""; PROMISCSCAN2=""

			case "${OPERATING_SYSTEM}" in
			*BSD|AIX)
				PROMISCSCAN1=`${IFCONFIG_CMD} -a 2>&1 | grep -v 'pflog' | grep 'PROMISC'`
				;;
			SunOS|IRIX*)
				PROMISCSCAN1=`${IFCONFIG_CMD} -a 2>&1 | grep 'PROMISC'`
				;;
			*)
				PROMISCSCAN1=`${IFCONFIG_CMD} 2>&1 | grep 'PROMISC'`
				;;
			esac

			if [ "${OPERATING_SYSTEM}" = "Linux" ]; then
				if [ -n "${IP_CMD}" ]; then
					PROMISCSCAN2=`${IP_CMD} -s link | grep 'PROMISC'`
				else
					display --to LOG --type INFO NETWORK_PROMISC_NO_IP
				fi
			fi


			#
			# Now show the results of the interface check.
			#

			if [ -z "${PROMISCSCAN1}" -a -z "${PROMISCSCAN2}" ]; then
				display --to SCREEN+LOG --type PLAIN --color GREEN --result NONE_FOUND --log-indent 2 --screen-indent 4 NETWORK_PROMISC_CHECK
			else
				display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 NETWORK_PROMISC_CHECK

				display --to LOG --type WARNING NETWORK_PROMISC_IF

				display --to LOG --type PLAIN --log-indent 9 NETWORK_PROMISC_IF_1 "${PROMISCSCAN1}"

				if [ "${OPERATING_SYSTEM}" = "Linux" -a -n "${PROMISCSCAN2}" ]; then
					PROMISCSCAN2=`echo "${PROMISCSCAN2}" | cut -d: -f2`

					for IFACE in ${PROMISCSCAN2}; do
						display --to LOG --type PLAIN --log-indent 9 NETWORK_PROMISC_IF_2 "${IFACE}"
					done
				fi
			fi
		else
			display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --screen-indent 4 NETWORK_PROMISC_CHECK
			display --to LOG --type WARNING NETWORK_PROMISC_NO_IFCONFIG
		fi
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST promisc
	fi


	#
	# For the packet capturing check, we must first see if we
	# are able to run the test. We let the user know if the test
	# was disabled, or if the lsof command is not present.
	#

	if [ "${OPERATING_SYSTEM}" != "Linux" ]; then
		display --to LOG --type INFO TEST_SKIPPED_OS 'packet_cap_apps' '/proc/net/packet required'
		return
	fi

	if `check_test packet_cap_apps`; then
		display --to LOG --type INFO STARTING_TEST packet_cap_apps
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST packet_cap_apps
		return
	fi

	if [ ! -f "/proc/net/packet" ]; then
		display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 NETWORK_PACKET_CAP_CHECK
		display --to LOG --type WARNING NETWORK_PACKET_CAP_CHECK_NO_FILE "/proc/net/packet"
		return
	elif [ -z "${LSOF_CMD}" ]; then
		display --to SCREEN+LOG --type PLAIN --color YELLOW --result SKIPPED --log-indent 2 --screen-indent 4 NETWORK_PACKET_CAP_CHECK
		display --to LOG --type INFO NOT_FOUND_CMD "lsof"
		return
	fi


	#
	# Now run the test.
	#

	FOUND=0
	WHITEPROC=""; BLACKPROC=""

	LIBPCAPRES=`egrep -v '^sk|888e' /proc/net/packet | head -n 1`

	if [ -n "${LIBPCAPRES}" ]; then
		#
		# We only need to get the whitelisted processes once.
		#

		ALLOWPROCLISTENERS=`get_option 1 multi ALLOWPROCLISTEN` || exit 1


		INODE_LIST=""

		for INODE in `egrep -v '^sk|888e' /proc/net/packet | awk '{ print $9 }'`; do
			INODE_LIST="${INODE_LIST}|$INODE"
		done

		INODE_LIST=`echo "${INODE_LIST}" | sed -e 's/^|//'`
		test -z "${INODE_LIST}" && INODE_LIST="RKHunterPktCapture"


		for PID in `${LSOF_CMD} -lMnPw -d 1-20 | egrep "[ 	](${INODE_LIST})[ 	]" | awk '{ print $2 }'`; do
			NAME=""

			if [ -n "${READLINK_CMD}" -a -h "/proc/$PID/exe" ]; then
				NAME=`${READLINK_CMD} -f /proc/$PID/exe | cut -d' ' -f1`
			elif [ -f "/proc/$PID/status" ]; then
				NAME=`grep '^Name:.' /proc/$PID/status | sed -e 's/^Name:.//'`
			fi


			test -z "${NAME}" && continue

			AMATCH=1

			for RKHTMPVAR in ${ALLOWPROCLISTENERS}; do
				if [ "${NAME}" = "${RKHTMPVAR}" ]; then
					AMATCH=0; break
				fi
			done

			if [ $AMATCH -eq 0 ]; then
				FNAME=`echo "${NAME}" | sed -e 's/\./\\\./g'`
				if [ -z "`echo ${WHITEPROC} | egrep \"${FNAME}( |$)\"`" ]; then
					WHITEPROC="${WHITEPROC} ${NAME}"
				fi
			else
				FOUND=1
				BLACKPROC="${BLACKPROC}
${NAME} ${PID}"
			fi
		done
	fi


	#
	# Now display the results.
	#

	if [ $FOUND -eq 0 ]; then
		display --to SCREEN+LOG --type PLAIN --color GREEN --result NONE_FOUND --log-indent 2 --screen-indent 4 NETWORK_PACKET_CAP_CHECK
	else
		display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 NETWORK_PACKET_CAP_CHECK


		IFS=$IFSNL

		for RKHTMPVAR in ${BLACKPROC}; do
			test -z "${RKHTMPVAR}" && continue

			NAME=`echo "${RKHTMPVAR}" | cut -d' ' -f1`
			PID=`echo "${RKHTMPVAR}" | cut -d' ' -f2`

			display --to LOG --type WARNING NETWORK_PACKET_CAP_FOUND "${NAME}" "${PID}"
		done

		IFS=$RKHIFS
	fi

	for NAME in $WHITEPROC; do
		display --to LOG --type INFO NETWORK_PACKET_CAP_WL "${NAME}"
	done

	return
}


do_network_checks() {

	#
	# This function carries out some network checks. This consists
	# of port checks, and some interface checks.
	#

	if `check_test network`; then
		display --to SCREEN+LOG --type PLAIN --color YELLOW --nl CHECK_NETWORK
		display --to LOG --type INFO STARTING_TEST network
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST network
		return
	fi


	do_network_port_checks

	do_network_interface_checks

	keypresspause

	return
}


do_system_startup_file_checks() {

	#
	# This function carries out checks on the system startup files.
	#

	if `check_test startup_files`; then
		display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 STARTUP_FILES_START
		display --to LOG --type INFO STARTING_TEST startup_files
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST startup_files
		return
	fi

	#
	# First we check that the local host name has been set.
	#

	if [ -n "${HOST_NAME}" ]; then
		display --to SCREEN+LOG --type PLAIN --color GREEN --result FOUND --log-indent 2 --screen-indent 4 STARTUP_HOSTNAME
	else
		display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 STARTUP_HOSTNAME
		display --to LOG --type WARNING STARTUP_NO_HOSTNAME
	fi


	#
	# Check that the startup file malware checks are to be done.
	#

	if `check_test startup_malware`; then
		display --to LOG --type INFO STARTING_TEST startup_malware
	else
		display --to LOG --type INFO USER_DISABLED_TEST startup_malware
		return
	fi


	#
	# Next, check that a local startup file exists. This will be some
	# sort of 'rc' file. We check if the user has set a pathname in
	# the config file, and use that or the default list.
	#

	RC_PATHS=""

	if [ -n "${RC_FILE}" ]; then
		FILENAMES="${RC_FILE}"
	else
		FILENAMES="${RCLOCATIONS}"
	fi

	for FNAME in ${FILENAMES}; do
		if [ -f "${RKHROOTDIR}${FNAME}" -a ! -h "${RKHROOTDIR}${FNAME}" ]; then
			RC_PATHS="${RC_PATHS}
${RKHROOTDIR}${FNAME}"
		fi
	done

	if [ -n "${RC_PATHS}" ]; then
		if [ -z "${RC_FILE}" ]; then
			for FNAME in ${RC_PATHS}; do
				display --to LOG --type INFO STARTUP_FOUND_LOCAL_RC_FILE "${FNAME}"
			done
		fi

		display --to SCREEN+LOG --type PLAIN --color GREEN --result FOUND --log-indent 2 --screen-indent 4 STARTUP_LOCAL_RC_FILE
	else
		display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 STARTUP_LOCAL_RC_FILE
		display --to LOG --type WARNING STARTUP_NO_LOCAL_RC_FILE
	fi


	#
	# Next we check all the startup files for any suspicious
	# strings in them.
	#
	# First check the local startup files.
	#

	if [ -n "${RC_PATHS}" ]; then
		FOUND=0
		FOUNDSTRINGS=""

		IFS=$IFSNL

		for FNAME in ${RC_PATHS}; do
			for RKHTMPVAR in ${RCLOCAL_STRINGS}; do
				RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/^[ 	]*//'`
				STR=`echo "${RKHTMPVAR}" | cut -d: -f1`
				STRING=`echo "${STR}" | sed -e 's/\./\\\./g'`
				INFO=`echo "${RKHTMPVAR}" | cut -d: -f2`

				if [ -n "`grep "${STRING}" ${FNAME} | grep -v '^#'`" ]; then
					FOUND=1
					FOUNDSTRINGS="${FOUNDSTRINGS}%${FNAME}:${STR}:${INFO}"
				fi
			done
		done

		IFS=$RKHIFS


		#
		# Now display the results.
		#

		if [ $FOUND -eq 0 ]; then
			display --to SCREEN+LOG --type PLAIN --color GREEN --result NONE_FOUND --log-indent 2 --screen-indent 4 STARTUP_CHECK_LOCAL_RC
		else
			display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 STARTUP_CHECK_LOCAL_RC

			IFS="%"

			for RKHTMPVAR in ${FOUNDSTRINGS}; do
				STRING=`echo "${RKHTMPVAR}" | cut -d: -f2`

				test -z "${STRING}" && continue

				FNAME=`echo "${RKHTMPVAR}" | cut -d: -f1`
				INFO=`echo "${RKHTMPVAR}" | cut -d: -f3`

				display --to LOG --type WARNING ROOTKIT_POSS_STRINGS_FOUND "${STRING}" "${FNAME}" "${INFO}"
			done

			IFS=$RKHIFS
		fi
	else
		display --to SCREEN+LOG --type PLAIN --color YELLOW --result SKIPPED --log-indent 2 --screen-indent 4 STARTUP_CHECK_LOCAL_RC
		display --to LOG --type WARNING STARTUP_NO_LOCAL_RC_FILE
	fi


	#
	# Next check the system startup files.
	# We look in either /etc/rc.d, /etc/init.d or the directory
	# specified in the config file.
	#

	if [ -n "${FIND_CMD}" ]; then
		DIR=""

		if [ -n "${RC_DIR}" ]; then
			DIR="${RKHROOTDIR}${RC_DIR}"
		elif [ -d "${RKHROOTDIR}/etc/rc.d" ]; then
			DIR="${RKHROOTDIR}/etc/rc.d"
		elif [ -d "${RKHROOTDIR}/etc/init.d" ]; then
			DIR="${RKHROOTDIR}/etc/init.d"
		fi


		if [ -n "${DIR}" ]; then
			FOUND=0
			FOUNDSTRINGS=""

			test -z "${RC_DIR}" && display --to LOG --type INFO STARTUP_CHECK_SYSTEM_RC_FOUND "${DIR}"


			#
			# Since we are going to be checking a lot of files
			# for strings that are static, we may as well do
			# some pre-processing of the string, and then we
			# only need to spend time if a string is found.
			#

			RCSTRINGS=""

			IFS=$IFSNL

			for RKHTMPVAR in ${RCLOCAL_STRINGS}; do
				RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/^[ 	]*//'`
				STR=`echo "${RKHTMPVAR}" | cut -d: -f1`
				STRING=`echo "${STR}" | sed -e 's/\./\\\./g'`
				RCSTRINGS="${RCSTRINGS} ${STRING}"
			done

			IFS=$RKHIFS

			RCSTRINGS=`echo "${RCSTRINGS}" | sed -e 's/^ //'`


			for FILE in `${FIND_CMD} ${DIR} -type f -a ! -type l 2>/dev/null`; do
				for STRING in ${RCSTRINGS}; do
					if [ -n "`grep "${STRING}" ${FILE} | grep -v '^#'`" ]; then
						FOUND=1
						FOUNDSTRINGS="${FOUNDSTRINGS}%${FILE}:${STRING}"
					fi
				done
			done


			#
			# Now display the results.
			#

			if [ $FOUND -eq 0 ]; then
				display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 STARTUP_CHECK_SYSTEM_RC
			else
				display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 STARTUP_CHECK_SYSTEM_RC

				IFS="%"

				for RKHTMPVAR in ${FOUNDSTRINGS}; do
					FILE=`echo "${RKHTMPVAR}" | cut -d: -f1`

					test -z "${FILE}" && continue

					STRING=`echo "${RKHTMPVAR}" | cut -d: -f2`
					STRING=`echo "${STRING}" | sed -e 's/\\\././g'`

					#
					# Having obtained the original string,
					# we now need to find the original
					# information about it.
					#

					IFS=$IFSNL

					for RKHTMPVAR2 in ${RCLOCAL_STRINGS}; do
						RKHTMPVAR2=`echo "${RKHTMPVAR2}" | sed -e 's/^[ 	]*//'`
						STR=`echo "${RKHTMPVAR2}" | cut -d: -f1`

						if [ "${STR}" = "${STRING}" ]; then
							INFO=`echo "${RKHTMPVAR2}" | cut -d: -f2`
							break
						fi
					done

					IFS="%"

					display --to LOG --type WARNING ROOTKIT_POSS_STRINGS_FOUND "${STRING}" "${FILE}" "${INFO}"
				done

				IFS=$RKHIFS
			fi
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 STARTUP_CHECK_SYSTEM_RC
			display --to LOG --type WARNING STARTUP_CHECK_SYSTEM_RC_NONE
		fi
	else
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 STARTUP_CHECK_SYSTEM_RC
		display --to LOG --type INFO NOT_FOUND_CMD "find"
	fi

	return
}


do_group_accounts_check() {

	#
	# This function carries out checks on the /etc/passwd and
	# /etc/group files.
	#

	if `check_test group_accounts`; then
		display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 ACCOUNTS_START
		display --to LOG --type INFO STARTING_TEST group_accounts
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST group_accounts
		return
	fi

	#
	# First check that /etc/passwd exists.
	#

	if [ -s "${RKHROOTDIR}/etc/passwd" ]; then
		display --to SCREEN+LOG --type PLAIN --color GREEN --result FOUND --log-indent 2 --screen-indent 4 ACCOUNTS_PWD_FILE_CHECK
		display --to LOG --type INFO ACCOUNTS_FOUND_PWD_FILE "${RKHROOTDIR}/etc/passwd"
	else
		display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 ACCOUNTS_PWD_FILE_CHECK
		display --to LOG --type WARNING ACCOUNTS_NO_PWD_FILE "${RKHROOTDIR}/etc/passwd"
	fi


	#
	# Next, check for root equivalent accounts. These will have
	# a UID of zero.
	#

	if [ -s "${RKHROOTDIR}/etc/passwd" ]; then
		#
		# We need to remove any whitelisted UID 0 accounts.
		#

		UID0_WHITELIST=`get_option 2 single UID0_ACCOUNTS` || exit 1
		UID0_WHITELIST=" root ${UID0_WHITELIST} "

		UID_LIST=""

		IFS=$IFSNL

		for RKHTMPVAR in `grep '^[^:]*:[^:]*:0:' ${RKHROOTDIR}/etc/passwd | cut -d: -f1`; do
			RKHUSERID=`echo "${RKHTMPVAR}" | sed -e 's/\./\\\./g'`

			if [ -z "`echo \"${UID0_WHITELIST}\" | grep \" ${RKHUSERID} \"`" ]; then
				UID_LIST="${UID_LIST}
${RKHTMPVAR}"
			elif [ "${RKHTMPVAR}" != "root" ]; then
				display --to LOG --type INFO ACCOUNTS_UID0_WL "${RKHTMPVAR}"
			fi
		done

		IFS=$RKHIFS


		#
		# Now display the results.
		#

		if [ -z "${UID_LIST}" ]; then
			display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 ACCOUNTS_UID0
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 ACCOUNTS_UID0

			IFS=$IFSNL

			for RKHTMPVAR in ${UID_LIST}; do
				test -z "${RKHTMPVAR}" && continue
				display --to LOG --type WARNING ACCOUNTS_UID0_FOUND "${RKHTMPVAR}"
			done

			IFS=$RKHIFS
		fi
	else
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 ACCOUNTS_UID0
		display --to LOG --type WARNING ACCOUNTS_NO_PWD_FILE "${RKHROOTDIR}/etc/passwd"
	fi


	#
	# Now check for any passwordless accounts. We must, however,
	# first find where the passwords are kept. If the user has
	# provided this in the config file, then we use that.
	#

	SHADOW_FILE=`get_option 1 single PASSWORD_FILE` || exit 1

	test -n "${SHADOW_FILE}" -a ! -s "${RKHROOTDIR}${SHADOW_FILE}" && SHADOW_FILE=""

	if [ -n "${SHADOW_FILE}" ]; then
		SHADOW_FILE="${RKHROOTDIR}${SHADOW_FILE}"
	elif [ -s "${RKHROOTDIR}/etc/shadow" ]; then
		SHADOW_FILE="${RKHROOTDIR}/etc/shadow"
	elif [ $BSDOS -eq 1 -a -s "${RKHROOTDIR}/etc/master.passwd" ]; then
		SHADOW_FILE="${RKHROOTDIR}/etc/master.passwd"
	elif [ -s "${RKHROOTDIR}/etc/passwd" ]; then
		#
		# If the passwords are stored in the passwd file, then
		# it should contain at least 3 non-colon characters in the
		# second field. Checking for 3 characters allows for normal
		# shadow entries such as 'x', '!!' or '*'. It is assumed
		# that at least one account will have a password.
		#

		if [ -n "`grep '^[^:]*:[^:][^:][^:]' ${RKHROOTDIR}/etc/passwd`" ]; then
			SHADOW_FILE="${RKHROOTDIR}/etc/passwd"
		fi
	fi


	if [ -n "${SHADOW_FILE}" ]; then
		display --to LOG --type INFO ACCOUNTS_SHADOW_FILE "${SHADOW_FILE}"

		#
		# We need to remove any whitelisted passwordless accounts.
		#

		PWD_WHITELIST=`get_option 2 single PWDLESS_ACCOUNTS` || exit 1
		PWD_WHITELIST=" ${PWD_WHITELIST} "

		UID_LIST=""

		IFS=$IFSNL

		for RKHTMPVAR in `grep '^[^:]*::' ${SHADOW_FILE} | cut -d: -f1`; do
			# Ignore any NIS/YP entries
			test "${RKHTMPVAR}" = "+" && continue

			RKHUSERID=`echo "${RKHTMPVAR}" | sed -e 's/\./\\\./g'`

			if [ -z "`echo \"${PWD_WHITELIST}\" | grep \" ${RKHUSERID} \"`" ]; then
				UID_LIST="${UID_LIST}
${RKHTMPVAR}"
			else
				display --to LOG --type INFO ACCOUNTS_PWDLESS_WL "${RKHTMPVAR}"
			fi
		done

		IFS=$RKHIFS


		#
		# Now display the results.
		#

		if [ -z "${UID_LIST}" ]; then
			display --to SCREEN+LOG --type PLAIN --color GREEN --result NONE_FOUND --log-indent 2 --screen-indent 4 ACCOUNTS_PWDLESS
		else
			display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 ACCOUNTS_PWDLESS

			IFS=$IFSNL

			for RKHTMPVAR in ${UID_LIST}; do
				test -z "${RKHTMPVAR}" && continue
				display --to LOG --type WARNING ACCOUNTS_PWDLESS_FOUND "${RKHTMPVAR}"
			done

			IFS=$RKHIFS
		fi
	else
		display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 ACCOUNTS_PWDLESS
		display --to LOG --type WARNING ACCOUNTS_NO_SHADOW_FILE
	fi


	#
	# Now we check for any changes that have occurred to the passwd
	# file since rkhunter was last run.
	#

	DIFF_CMD=`find_cmd diff`

	if `check_test passwd_changes`; then
		RKHTMPVAR=0
		display --to LOG --type INFO STARTING_TEST passwd_changes
	else
		RKHTMPVAR=1
		display --to LOG --type INFO USER_DISABLED_TEST passwd_changes
	fi

	if [ $RKHTMPVAR -eq 1 ]; then
		:
	elif [ ! -f "${RKHROOTDIR}/etc/passwd" ]; then
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 PASSWD_CHANGES
		display --to LOG --type WARNING ACCOUNTS_NO_PWD_FILE "${RKHROOTDIR}/etc/passwd"
	elif [ -z "${DIFF_CMD}" ]; then
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 PASSWD_CHANGES
		display --to LOG --type INFO NOT_FOUND_CMD "diff"

		cp -f -p ${RKHROOTDIR}/etc/passwd ${RKHTMPDIR}/passwd
	elif [ ! -f "${RKHTMPDIR}/passwd" ]; then
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 PASSWD_CHANGES
		display --to LOG --type WARNING PASSWD_CHANGES_NO_TMP

		cp -f -p ${RKHROOTDIR}/etc/passwd ${RKHTMPDIR}/passwd
	else
		DIFFS=`${DIFF_CMD} ${RKHROOTDIR}/etc/passwd ${RKHTMPDIR}/passwd 2>/dev/null | grep '^[<>]'`

		if [ -z "${DIFFS}" ]; then
			display --to SCREEN+LOG --type PLAIN --color GREEN --result NONE_FOUND --log-indent 2 --screen-indent 4 PASSWD_CHANGES
		else
			DIFFS_ADDED=`echo "${DIFFS}" | grep '^< '`
			DIFFS_REMOVED=`echo "${DIFFS}" | grep '^> '`

			display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 PASSWD_CHANGES

			if [ -n "${DIFFS_ADDED}" ]; then
				display --to LOG --type WARNING PASSWD_CHANGES_ADDED

				IFS=$IFSNL

				for RKHTMPVAR in ${DIFFS_ADDED}; do
					RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/^< //'`
					display --to LOG --type PLAIN --log-indent 9 NAME "${RKHTMPVAR}"
				done

				IFS=$RKHIFS
			fi

			if [ -n "${DIFFS_REMOVED}" ]; then
				display --to LOG --type WARNING PASSWD_CHANGES_REMOVED

				IFS=$IFSNL

				for RKHTMPVAR in ${DIFFS_REMOVED}; do
					RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/^> //'`
					display --to LOG --type PLAIN --log-indent 9 NAME "${RKHTMPVAR}"
				done

				IFS=$RKHIFS
			fi

			#
			# Finally, move the current copy of the passwd file out
			# of the way, and take a new copy of the passwd file.
			# This allows the user to look back to see what the
			# last changes were, even if RKH is run again.
			#

			mv -f ${RKHTMPDIR}/passwd ${RKHTMPDIR}/passwd.old >/dev/null 2>&1
			cp -f -p ${RKHROOTDIR}/etc/passwd ${RKHTMPDIR}/passwd
		fi
	fi


	#
	# Next check for any changes that have occurred to the group
	# file since rkhunter was last run.
	#

	if `check_test group_changes`; then
		RKHTMPVAR=0
		display --to LOG --type INFO STARTING_TEST group_changes
	else
		RKHTMPVAR=1
		display --to LOG --type INFO USER_DISABLED_TEST group_changes
	fi

	if [ $RKHTMPVAR -eq 1 ]; then
		:
	elif [ ! -f "${RKHROOTDIR}/etc/group" ]; then
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 GROUP_CHANGES
		display --to LOG --type WARNING GROUP_CHANGES_NO_FILE "${RKHROOTDIR}/etc/group"
	elif [ -z "${DIFF_CMD}" ]; then
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 GROUP_CHANGES
		display --to LOG --type INFO NOT_FOUND_CMD "diff"

		cp -f -p ${RKHROOTDIR}/etc/group ${RKHTMPDIR}/group
	elif [ ! -f "${RKHTMPDIR}/group" ]; then
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 GROUP_CHANGES
		display --to LOG --type WARNING GROUP_CHANGES_NO_TMP

		cp -f -p ${RKHROOTDIR}/etc/group ${RKHTMPDIR}/group
	else
		DIFFS=`${DIFF_CMD} ${RKHROOTDIR}/etc/group ${RKHTMPDIR}/group 2>/dev/null | grep '^[<>]'`

		if [ -z "${DIFFS}" ]; then
			display --to SCREEN+LOG --type PLAIN --color GREEN --result NONE_FOUND --log-indent 2 --screen-indent 4 GROUP_CHANGES
		else
			DIFFS_ADDED=`echo "${DIFFS}" | grep '^< '`
			DIFFS_REMOVED=`echo "${DIFFS}" | grep '^> '`

			display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 GROUP_CHANGES

			if [ -n "${DIFFS_ADDED}" ]; then
				display --to LOG --type WARNING GROUP_CHANGES_ADDED

				IFS=$IFSNL

				for RKHTMPVAR in ${DIFFS_ADDED}; do
					RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/^< //'`
					display --to LOG --type PLAIN --log-indent 9 NAME "${RKHTMPVAR}"
				done

				IFS=$RKHIFS
			fi

			if [ -n "${DIFFS_REMOVED}" ]; then
				display --to LOG --type WARNING GROUP_CHANGES_REMOVED

				IFS=$IFSNL

				for RKHTMPVAR in ${DIFFS_REMOVED}; do
					RKHTMPVAR=`echo "${RKHTMPVAR}" | sed -e 's/^> //'`
					display --to LOG --type PLAIN --log-indent 9 NAME "${RKHTMPVAR}"
				done

				IFS=$RKHIFS
			fi

			#
			# Finally, move the current copy of the group file out
			# of the way, and take a new copy of the group file.
			# This allows the user to look back to see what the
			# last changes were, even if RKH is run again.
			#

			mv -f ${RKHTMPDIR}/group ${RKHTMPDIR}/group.old >/dev/null 2>&1
			cp -f -p ${RKHROOTDIR}/etc/group ${RKHTMPDIR}/group
		fi
	fi


	#
	# Finally we do a check on the root account shell history files.
	# We check for bash, Korn, C-shell and zsh history files.
	#

	FOUND=0
	FOUNDFILES=""

	if [ -f "${RKHROOTDIR}/root/.bash_history" ]; then
		FOUND=1

		if [ -h "${RKHROOTDIR}/root/.bash_history" ]; then
			FOUNDFILES="${FOUNDFILES} bash:${RKHROOTDIR}/root/.bash_history"
		fi
	fi

	if [ -f "${RKHROOTDIR}/root/.sh_history" ]; then
		FOUND=1

		if [ -h "${RKHROOTDIR}/root/.sh_history" ]; then
			FOUNDFILES="${FOUNDFILES} Korn:${RKHROOTDIR}/root/.sh_history"
		fi
	fi

	if [ -f "${RKHROOTDIR}/root/.history" ]; then
		FOUND=1

		if [ -h "${RKHROOTDIR}/root/.history" ]; then
			FOUNDFILES="${FOUNDFILES} C-shell:${RKHROOTDIR}/root/.history"
		fi
	fi

	if [ -f "${RKHROOTDIR}/root/.zhistory" ]; then
		FOUND=1

		if [ -h "${RKHROOTDIR}/root/.zhistory" ]; then
			FOUNDFILES="${FOUNDFILES} zsh:${RKHROOTDIR}/root/.zhistory"
		fi
	fi


	#
	# Now display the results.
	#

	if [ -z "${FOUNDFILES}" ]; then
		test $FOUND -eq 1 && RKHTMPVAR="OK" || RKHTMPVAR="NONE_FOUND"

		display --to SCREEN+LOG --type PLAIN --color GREEN --result ${RKHTMPVAR} --log-indent 2 --screen-indent 4 HISTORY_CHECK
	else
		display --to SCREEN+LOG --type PLAIN --color RED --result WARNING --log-indent 2 --screen-indent 4 HISTORY_CHECK

		for RKHTMPVAR in ${FOUNDFILES}; do
			SHELLNAME=`echo "${RKHTMPVAR}" | cut -d: -f1`
			FILENAME=`echo "${RKHTMPVAR}" | cut -d: -f2`

			display --to LOG --type WARNING HISTORY_CHECK_FOUND "SHELLNAME" "FILENAME"
		done
	fi

	return
}


do_system_config_files_check() {

	#
	# This function carries out checks on some of the system
	# software configurations. At present this checks the SSH
	# and syslog configurations.
	#

	if `check_test system_configs`; then
		display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 SYSTEM_CONFIGS_START
		display --to LOG --type INFO STARTING_TEST system_configs
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST system_configs
		return
	fi

	#
	# First find out where the SSH configuration file is located.
	#

	SSH_CONFIG_FILE=""

	if [ -n "${SSH_CONFIG_DIR}" ]; then
		RKHTMPVAR="${SSH_CONFIG_DIR}"
	else
		RKHTMPVAR="/etc /etc/ssh /usr/local/etc /usr/local/etc/ssh"
	fi

	for DIR in ${RKHTMPVAR}; do
		if [ -f "${RKHROOTDIR}${DIR}/sshd_config" ]; then
			SSH_CONFIG_FILE="${RKHROOTDIR}${DIR}/sshd_config"
			break
		fi
	done

	if [ -n "${SSH_CONFIG_FILE}" ]; then
		display --to SCREEN+LOG --type PLAIN --result FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE "SSH"

		display --to LOG --type INFO SYSTEM_CONFIGS_FILE_FOUND "SSH" "${SSH_CONFIG_FILE}"

		display --to LOG --type INFO CONFIG_SSH_ROOT "${ALLOW_SSH_ROOT_USER}"
		display --to LOG --type INFO CONFIG_SSH_PROTV1 $ALLOW_SSH_PROT_V1


		#
		# Now we check some of the configuration options.
		#
		# First we check for allowed root access.
		#

		RKHTMPVAR=`grep -i '^PermitRootLogin[ 	]' ${SSH_CONFIG_FILE} | tail -1`

		if [ -n "${RKHTMPVAR}" ]; then
			#
			# Get the value that has been set.
			#

			RKHTMPVAR2=`echo "${RKHTMPVAR}" | awk '{ print $2 }' | tr '[A-Z]' '[a-z]'`

			if [ "${RKHTMPVAR2}" = "${ALLOW_SSH_ROOT_USER}" ]; then
				test "${RKHTMPVAR2}" = "no" && RKHTMPVAR="NOT_ALLOWED" || RKHTMPVAR="ALLOWED"
				display --to SCREEN+LOG --type PLAIN --result ${RKHTMPVAR} --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_ROOT
			else
				display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_ROOT

				display --to LOG --type WARNING SYSTEM_CONFIGS_SSH_ROOT_FOUND
				display --to LOG --type PLAIN --log-indent 9 SYSTEM_CONFIGS_SSH_ROOT_FOUND1 "${RKHTMPVAR2}"
				display --to LOG --type PLAIN --log-indent 9 SYSTEM_CONFIGS_SSH_ROOT_FOUND2 "${ALLOW_SSH_ROOT_USER}"
			fi
		elif [ "${ALLOW_SSH_ROOT_USER}" = "yes" ]; then
			display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_ROOT
		elif [ "${ALLOW_SSH_ROOT_USER}" = "unset" ]; then
			display --to SCREEN+LOG --type PLAIN --result UNSET --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_ROOT
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_ROOT
			display --to LOG --type WARNING SYSTEM_CONFIGS_SSH_ROOT_NOTFOUND
		fi


		#
		# Next we check to see if protocol version 1 is allowed.
		#

		RKHTMPVAR=`grep -i '^Protocol[ 	]' ${SSH_CONFIG_FILE} | tail -1`

		if [ -n "${RKHTMPVAR}" ]; then
			#
			# Get the value that has been set.
			#

			RKHTMPVAR2=`echo "${RKHTMPVAR}" | awk '{ print $2 }' | grep '1'`

			if [ -z "${RKHTMPVAR2}" ]; then
				display --to SCREEN+LOG --type PLAIN --result NOT_ALLOWED --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_PROTO
			elif [ $ALLOW_SSH_PROT_V1 -eq 1 ]; then
				display --to SCREEN+LOG --type PLAIN --result ALLOWED --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_PROTO
			else
				display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_PROTO

				display --to LOG --type WARNING SYSTEM_CONFIGS_SSH_PROTO_FOUND "${SSH_CONFIG_FILE}"
			fi
		elif [ $ALLOW_SSH_PROT_V1 -eq 1 ]; then
			display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_PROTO
		elif [ $ALLOW_SSH_PROT_V1 -eq 2 ]; then
			display --to SCREEN+LOG --type PLAIN --result UNSET --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_PROTO
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SSH_PROTO
			display --to LOG --type WARNING SYSTEM_CONFIGS_SSH_PROTO_NOTFOUND
		fi
	else
		display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE "SSH"
	fi


	#
	# Next we find out if the syslog daemon is running.
	#

	SYSLOG_SEEN=0
	METALOG_SEEN=0; SOCKLOG_SEEN=0

	if [ -n "${PS_CMD}" ]; then
		PS_ARGS="ax"

		test $SUNOS -eq 1 -o $IRIXOS -eq 1 && PS_ARGS="-ef"

		RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | egrep '(syslogd|syslog-ng)( |$)' | grep -v 'egrep'`

		if [ -n "${RKHTMPVAR}" ]; then
			SYSLOG_SEEN=1

			display --to SCREEN+LOG --type PLAIN --result FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG
		else
			RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | egrep 'metalog( |$)' | grep -v 'egrep'`

			if [ -n "${RKHTMPVAR}" ]; then
				METALOG_SEEN=1

				display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG
				display --to LOG --type INFO --log-indent 2 SYSTEM_CONFIGS_SYSLOG_METALOG_RUNNING
			else
				RKHTMPVAR=`${PS_CMD} ${PS_ARGS} | egrep 'socklog( |$)' | grep -v 'egrep'`

				if [ -n "${RKHTMPVAR}" ]; then
					SOCKLOG_SEEN=1

					display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG
					display --to LOG --type INFO --log-indent 2 SYSTEM_CONFIGS_SYSLOG_SOCKLOG_RUNNING
				else
					display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG
					display --to LOG --type WARNING SYSTEM_CONFIGS_SYSLOG_NOT_RUNNING
				fi
			fi
		fi
	else
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG
		display --to LOG --type INFO NOT_FOUND_CMD "ps"
	fi


	#
	# Now find out where the syslog configuration file is located.
	#

	if [ -n "${SYSLOG_CONFIG_FILE}" ]; then
		RKHTMPVAR="${SYSLOG_CONFIG_FILE}"
	else
		RKHTMPVAR="/etc/syslog.conf /etc/rsyslog.conf /etc/syslog-ng/syslog-ng.conf"
	fi

	for FILE in ${RKHTMPVAR}; do
		if [ -f "${RKHROOTDIR}${FILE}" ]; then
			SYSLOG_CONFIG_FILE="${RKHROOTDIR}${FILE}"
			break
		fi
	done

	if [ -n "${SYSLOG_CONFIG_FILE}" ]; then
		display --to SCREEN+LOG --type PLAIN --result FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE "syslog"
		display --to LOG --type INFO SYSTEM_CONFIGS_FILE_FOUND "syslog" "${SYSLOG_CONFIG_FILE}"
	elif [ $METALOG_SEEN -eq 1 -o $SOCKLOG_SEEN -eq 1 ]; then
		display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE "syslog"
	elif [ $SYSLOG_SEEN -eq 1 ]; then
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE "syslog"
		display --to LOG --type WARNING SYSTEM_CONFIGS_SYSLOG_NO_FILE
	else
		display --to SCREEN+LOG --type PLAIN --result NOT_FOUND --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_FILE "syslog"
	fi


	#
	# Next we find out if syslog allows remote logging.
	#

	if [ -n "${SYSLOG_CONFIG_FILE}" ]; then
		test $ALLOW_SYSLOG_REMOTE_LOGGING -eq 1 && display --to LOG --type INFO SYSTEM_CONFIGS_SYSLOG_REMOTE_ALLOWED

		if [ -n "`echo \"${SYSLOG_CONFIG_FILE}\" | egrep '/r?syslog\.conf$'`" ]; then
			RKHTMPVAR=`grep '^[^#].*[ 	]@.' ${SYSLOG_CONFIG_FILE}`
		else
			#
			# For syslog-ng we must look for a destination
			# block which uses TCP or UDP.
			#

			RKHTMPVAR=`awk '/^[ 	]*destination( |	|$)/, /}/ { print $0 }' ${SYSLOG_CONFIG_FILE} | egrep -i '( |	|\{|^)(tcp|udp)6?( |	|\(|$)'`
		fi

		if [ -z "${RKHTMPVAR}" ]; then
			display --to SCREEN+LOG --type PLAIN --result NOT_ALLOWED --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG_REMOTE
		elif [ $ALLOW_SYSLOG_REMOTE_LOGGING -eq 1 ]; then
			display --to SCREEN+LOG --type PLAIN --result ALLOWED --color GREEN --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG_REMOTE
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 SYSTEM_CONFIGS_SYSLOG_REMOTE
			display --to LOG --type WARNING SYSTEM_CONFIGS_SYSLOG_REMOTE_FOUND "${RKHTMPVAR}"
		fi
	fi

	return
}


do_dev_whitelist_check() {

	#
	# The check of /dev files has two methods. One uses a simple
	# top-level file check, the other is more thorough and does a
	# complete 'find' on the /dev directory. However, the check on
	# whether the given file is whitelisted is the same for both
	# methods. As such, it makes sense to use a function rather than
	# repeating the code for each method.
	#


	FNAME=`${FILE_CMD} "${RKHTMPVAR}" 2>/dev/null | cat -v | tr '	' ' ' | egrep -v '( character special| block special| socket| fifo \(named pipe\)| symbolic link to| empty| directory|/MAKEDEV:)'`

	test -z "${FNAME}" && return

	FILE=`echo "${FNAME}" | cut -d: -f1 | sed -e "s/^${RKHROOTDIR}//"`

	if [ -n "`echo \"${ALLOWDEVFILES}\" | grep \" ${FILE} \"`" ]; then
		display --to LOG --type INFO FILESYSTEM_DEV_FILE_WL "${FILE}"
	else
		FOUNDFILES="${FOUNDFILES}
${FNAME}"
	fi

	return
}


do_filesystem_check() {

	#
	# This function carries out checks on the filesystem
	# for suspicious files.
	#

	if `check_test filesystem`; then
		display --to SCREEN+LOG --type PLAIN --nl --screen-indent 2 FILESYSTEM_START
		display --to LOG --type INFO STARTING_TEST filesystem
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST filesystem
		return
	fi


	if [ ! -d "${RKHROOTDIR}/dev" ]; then
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 FILESYSTEM_DEV_CHECK
		display --to LOG --type WARNING FILESYSTEM_DEV_CHECK_NO_DEV
	elif [ -z "${FILE_CMD}" ]; then
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 FILESYSTEM_DEV_CHECK
		display --to LOG --type INFO NOT_FOUND_CMD "file"
	elif [ "${SCAN_MODE_DEV}" = "THOROUGH" -a -z "${FIND_CMD}" ]; then
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 FILESYSTEM_DEV_CHECK
		display --to LOG --type INFO NOT_FOUND_CMD "find"
	else
		#
		# Now we can run the check on /dev.
		#

		display --to LOG --type INFO CONFIG_SCAN_MODE_DEV "${SCAN_MODE_DEV}"


		#
		# Note: We do not look for hidden files here - that is,
		# those beginning with a dot. Any hidden files will be
		# picked up in the next check.
		# Note2: Filenames can contain a colon (:), so we need to
		# be careful in separating the filename from the file type.
		# Note3: We have to cater for *BSD systems which may have
		# fdesc/fdescfs mounted. If it is, then we must skip over
		# any detected file descriptors.
		#

		FDESCFS=0
		FOUNDFILES=""
		ALLOWDEVFILES=" "

		if [ $BSDOS -eq 1 ]; then
			RKHTMPVAR=`find_cmd mount`

			if [ -n "${RKHTMPVAR}" ]; then
				test -n "`${RKHTMPVAR} 2>/dev/null | egrep '^fdesc(fs)? .*type fdesc'`" && FDESCFS=1
			else
				display --to LOG --type INFO NOT_FOUND_CMD "mount"
			fi
		fi

		for FNAME in `get_option 1 multi ALLOWDEVFILE`; do
			ALLOWDEVFILES="${ALLOWDEVFILES} ${FNAME}"
		done

		ALLOWDEVFILES="${ALLOWDEVFILES} "


		if [ "${SCAN_MODE_DEV}" = "LAZY" ]; then
			for RKHTMPVAR in ${RKHROOTDIR}/dev/*; do
				test -s "${RKHTMPVAR}" -a ! -d "${RKHTMPVAR}" -a ! -h "${RKHTMPVAR}" || continue

				if [ $FDESCFS -eq 1 ]; then
					test -n "`echo \"${RKHTMPVAR}\" | egrep \"^${RKHROOTDIR}/dev/fd/[0-9][0-9]*(/|$)\"`" && continue
				fi

				do_dev_whitelist_check
			done
		else
			for RKHTMPVAR in `${FIND_CMD} ${RKHROOTDIR}/dev ! -type d -a ! -type l 2>/dev/null`; do
				test -s "${RKHTMPVAR}" || continue

				if [ $FDESCFS -eq 1 ]; then
					test -n "`echo \"${RKHTMPVAR}\" | egrep \"^${RKHROOTDIR}/dev/fd/[0-9][0-9]*(/|$)\"`" && continue
				fi

				test -z "`echo \"${RKHTMPVAR}\" | grep '/\.'`" && do_dev_whitelist_check
			done
		fi


		#
		# Now display the results.
		#

		if [ -z "${FOUNDFILES}" ]; then
			display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 FILESYSTEM_DEV_CHECK
		else
			display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 FILESYSTEM_DEV_CHECK

			display --to LOG --type WARNING FILESYSTEM_DEV_FILE_FOUND "${RKHROOTDIR}/dev"

			IFS=$IFSNL

			for RKHTMPVAR in ${FOUNDFILES}; do
				test -z "${RKHTMPVAR}" && continue
				display --to LOG --type PLAIN --log-indent 9 NAME "${RKHTMPVAR}"
			done

			IFS=$RKHIFS
		fi
	fi


	#
	# Now we check various directories for hidden files and
	# directories. We must have the 'file' command for this
	# test to run.
	#
	# First we look in two sets of directories. One set we search
	# recursively, using 'find', the other set we only search to
	# one-level. If we have no 'find' command, then all the
	# directories are only searched to one-level.
	#

	if [ -z "${FILE_CMD}" ]; then
		display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 FILESYSTEM_HIDDEN_CHECK
		display --to LOG --type INFO NOT_FOUND_CMD "file"
		return
	fi


	FOUNDDIRS=""
	FOUNDFILES=""
	LOOKINDIRS=""

	SHORTSEARCHDIRS="${RKHROOTDIR}/usr ${RKHROOTDIR}/etc"

	LONGSEARCHDIRS="${RKHROOTDIR}/dev ${RKHROOTDIR}/bin ${RKHROOTDIR}/usr/man ${RKHROOTDIR}/usr/share/man ${RKHROOTDIR}/usr/bin ${RKHROOTDIR}/usr/sbin ${RKHROOTDIR}/sbin"

	if [ -z "${FIND_CMD}" ]; then
		SHORTSEARCHDIRS="${SHORTSEARCHDIRS} ${LONGSEARCHDIRS}"
		LONGSEARCHDIRS=""
	fi

	for DIR in ${SHORTSEARCHDIRS}; do
		if [ -d ${DIR} ]; then
			RKHTMPVAR=`ls -1d ${DIR}/.* 2>/dev/null | egrep -v '/\.\.?$'`
			test -n "${RKHTMPVAR}" && LOOKINDIRS="${LOOKINDIRS} ${RKHTMPVAR}"
		fi
	done

	for DIR in ${LONGSEARCHDIRS}; do
		if [ -d ${DIR} ]; then
			RKHTMPVAR=`${FIND_CMD} ${DIR} -name ".*" 2>/dev/null`
			test -n "${RKHTMPVAR}" && LOOKINDIRS="${LOOKINDIRS} ${RKHTMPVAR}"
		fi
	done


	#
	# Get the whitelisted files and directories.
	#

	ALLOWHIDDENDIRS=" "
	ALLOWHIDDENFILES=" "

	if [ -n "${LOOKINDIRS}" ]; then
		for DIR in `get_option 1 multi ALLOWHIDDENDIR`; do
			ALLOWHIDDENDIRS="${ALLOWHIDDENDIRS} ${DIR}"
		done

		ALLOWHIDDENDIRS="${ALLOWHIDDENDIRS} "

		for FNAME in `get_option 1 multi ALLOWHIDDENFILE`; do
			ALLOWHIDDENFILES="${ALLOWHIDDENFILES} ${FNAME}"
		done

		ALLOWHIDDENFILES="${ALLOWHIDDENFILES} "
	fi


	#
	# Next we look for any whitelisted files and directories. We also
	# exclude certain types of files, and Gentoo zero-sized files.
	#

	for FNAME in ${LOOKINDIRS}; do
		if [ $GENTOO -eq 1 ]; then
			test ! -s "${FNAME}" -a -n "`echo \"${FNAME}\" | grep '/\.keep$'`" && continue
		fi

		if [ $FDESCFS -eq 1 ]; then
			test -n "`echo \"${FNAME}\" | egrep \"^${RKHROOTDIR}/dev/fd/[0-9][0-9]*(/|$)\"`" && continue
		fi

		if [ -f "${FNAME}" ]; then
			FTYPE=`${FILE_CMD} ${FNAME} 2>/dev/null | cat -v | tr '	' ' ' | tr -s ' ' | cut -d' ' -f2-`
		else
			continue
		fi

		test -z "${FTYPE}" -o -n "`echo \"${FTYPE}\" | egrep 'character special|TDB database|empty'`" && continue


		FILE=`echo "${FNAME}" | sed -e "s/^${RKHROOTDIR}//"`

		if [ "${FTYPE}" = "directory" ]; then
			if [ -n "`echo \"${ALLOWHIDDENDIRS}\" | grep \" ${FILE} \"`" ]; then
				display --to LOG --type INFO FILESYSTEM_HIDDEN_DIR_WL "${FNAME}"
			else
				FOUNDDIRS="${FOUNDDIRS}
${FNAME}"
			fi
		else
			if [ -n "`echo \"${ALLOWHIDDENFILES}\" | grep \" ${FILE} \"`" ]; then
				display --to LOG --type INFO FILESYSTEM_HIDDEN_FILE_WL "${FNAME}"
			else
				FOUNDFILES="${FOUNDFILES}
${FNAME}: ${FTYPE}"
			fi
		fi
	done


	#
	# Now display the results.
	#

	if [ -z "${FOUNDDIRS}" -a -z "${FOUNDFILES}" ]; then
		display --to SCREEN+LOG --type PLAIN --result NONE_FOUND --color GREEN --log-indent 2 --screen-indent 4 FILESYSTEM_HIDDEN_CHECK
	else
		display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 FILESYSTEM_HIDDEN_CHECK

		IFS=$IFSNL

		for RKHTMPVAR in ${FOUNDDIRS}; do
			test -z "${RKHTMPVAR}" && continue
			display --to LOG --type WARNING FILESYSTEM_HIDDEN_DIR_FOUND "${RKHTMPVAR}"
		done

		for RKHTMPVAR in ${FOUNDFILES}; do
			test -z "${RKHTMPVAR}" && continue
			display --to LOG --type WARNING FILESYSTEM_HIDDEN_FILE_FOUND "${RKHTMPVAR}"
		done

		IFS=$RKHIFS
	fi

	return
}


do_local_host_checks() {

	#
	# This function carries out a sequence of tests on the local
	# host.
	#

	if `check_test local_host`; then
		display --to SCREEN+LOG --type PLAIN --color YELLOW --nl CHECK_LOCALHOST
		display --to LOG --type INFO STARTING_TEST local_host
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST local_host
		return
	fi


	#
	# We start by performing checks on the startup files.
	#

	do_system_startup_file_checks


	#
	# Now we check the /etc/passwd file, and run some checks
	# on the accounts and groups.
	#

	do_group_accounts_check


	#
	# Next check some of the system configuration files.
	#

	do_system_config_files_check


	#
	# Finally check the filesystem for suspicious files.
	#

	do_filesystem_check

	keypresspause

	return
}


do_app_checks() {

	#
	# This function carries out a sequence of application checks.
	#

	if `check_test apps`; then
		display --to SCREEN+LOG --type PLAIN --color YELLOW --nl --nl-after CHECK_APPS
		display --to LOG --type INFO STARTING_TEST apps
	else
		display --to LOG --type INFO --nl USER_DISABLED_TEST apps
		return
	fi


	#
	# First we check that our apps data file is present.
	#

	if [ ! -s "${DB_PATH}/programs_bad.dat" ]; then
		display --to SCREEN+LOG --type WARNING --screen-indent 2 APPS_DAT_MISSING
		return
	fi


	#
	# We loop through the applications and obtain the version number.
	# This is then checked against the file of known bad versions.
	# We build up a list of application names, the version number,
	# and whether it is known to be bad or not. When this has all
	# been done, we then display the results.
	#
	# The results line for each application is made up of percent (%)
	# delimited fields. They are:
	#
	#   application%description%version%if known bad%whole version number
	#
	# A 'version' number of '-1' means the application was not found.
	#
	# An 'if known bad' number of:
	#
	#	'-1' means a specific version of the application is whitelisted,
	#	'-2' means the application is whitelisted, regardless of version.
	#

	APPS_COUNT=0
	APP_RESULTS=""

	APP_NAMES="exim:Exim MTA
		   gpg:GnuPG
		   httpd:Apache
		   named:Bind DNS
		   openssl:OpenSSL
		   php:PHP
		   procmail:Procmail MTA
		   proftpd:ProFTPd
		   sshd:OpenSSH"

	APPS_TOTAL_COUNT=`echo "${APP_NAMES}" | wc -l | tr -d ' '`


	#
	# Get the list of whitelisted application versions.
	#

	APP_WHITELIST=""

	RKHTMVAR=`get_option 2 single APP_WHITELIST` || exit 1

	test -n "${RKHTMVAR}" && APP_WHITELIST=`echo " ${RKHTMVAR} " | tr '[A-Z]' '[a-z]'`


	IFS=$IFSNL

	for APP in ${APP_NAMES}; do
		APP=`echo "${APP}" | sed -e 's/^[ 	]*//'`

		APPLICATION=`echo "${APP}" | cut -d: -f1`
		APPLICATION_DESC=`echo "${APP}" | cut -d: -f2-`

		IFS=$RKHIFS
		APP_CMD_FOUND=`find_cmd ${APPLICATION}`
		IFS=$IFSNL

		if [ -z "${APP_CMD_FOUND}" ]; then
			APP_RESULTS="${APP_RESULTS}
${APPLICATION}%${APPLICATION_DESC}%-1"
			continue
		fi


		#
		# Find out the version of the application.
		#

		APPS_COUNT=`expr ${APPS_COUNT} + 1`

		VERSION=""
		WHOLE_VERSION=""

		#
		# Applications which are whitelisted completely (no specific
		# version number), are handled first.
		#

		if [ -n "`echo \"${APP_WHITELIST}\" | grep \" ${APPLICATION} \"`" ]; then
			APP_RESULTS="${APP_RESULTS}
${APPLICATION}%${APPLICATION_DESC}%0%-2"
		else
			case "${APPLICATION}" in
			exim)
				WHOLE_VERSION=`${APP_CMD_FOUND} -bV 2>/dev/null`
				VERSION=`echo "${WHOLE_VERSION}" | grep '^Exim version [0-9]' | awk '{ print $3 }'`
				;;
			gpg)
				WHOLE_VERSION=`${APP_CMD_FOUND} --version --homedir / 2>/dev/null`
				VERSION=`echo "${WHOLE_VERSION}" | grep 'GnuPG' | awk '{ print $3 }'`
				;;
			httpd)
				WHOLE_VERSION=`${APP_CMD_FOUND} -v 2>/dev/null`
				VERSION=`echo "${WHOLE_VERSION}" | grep -i '^Server version:[ 	][ 	]*Apache/[0-9]' | cut -d' ' -f3 | cut -d'/' -f2`
				;;
			named)
				WHOLE_VERSION=`${APP_CMD_FOUND} -v 2>/dev/null`
				VERSION=`echo "${WHOLE_VERSION}" | egrep '^(named|BIND)[ 	][ 	]*[0-9]' | grep -v '/' | awk '{ print $2 }'`

				if [ -n "`echo \"${VERSION}\" | grep '-'`" ]; then
					VERSION=`echo "${VERSION}" | cut -d'-' -f1`
				fi

				if [ -z "${VERSION}" ]; then
					VERSION=`${APP_CMD_FOUND} -v | awk '{ print $2 }'`
				fi
				;;
			openssl)
				WHOLE_VERSION=`${APP_CMD_FOUND} version 2>/dev/null`
				VERSION=`echo "${WHOLE_VERSION}" | grep '^OpenSSL[ 	][ 	]*[0-9]' | cut -d' ' -f2`
				;;
			php)
				WHOLE_VERSION=`${APP_CMD_FOUND} -v 2>/dev/null`
				VERSION=`echo "${WHOLE_VERSION}" | grep '^PHP[ 	][ 	]*[0-9]' | awk '{ print $2 }' | cut -d'-' -f1`
				;;
			procmail)
				WHOLE_VERSION=`${APP_CMD_FOUND} -v 2>&1`
				VERSION=`echo "${WHOLE_VERSION}" | grep '^procmail[ 	][ 	]*v[0-9]' | awk '{ print $2 }' | sed -e 's/^v//'`
				;;
			proftpd)
				WHOLE_VERSION=`${APP_CMD_FOUND} -v 2>&1`
				VERSION=`echo "${WHOLE_VERSION}" | grep 'ProFTPD[ 	][ 	]*Version[ 	][ 	]*[0-9]' | awk '{ print $4 }'`
				;;
			sshd)
				WHOLE_VERSION=`${APP_CMD_FOUND} -t -d 2>&1`
				VERSION=`echo "${WHOLE_VERSION}" | grep 'sshd version OpenSSH' | sed -e 's/^.*sshd version OpenSSH_//' | cut -d' ' -f1`

				if [ -n "`echo \"${VERSION}\" | grep '+'`" ]; then
					VERSION=`echo "${VERSION}" | cut -d'+' -f1`
				fi
				;;
			esac


			VERSION=`echo "${VERSION}" | tr -d '\r'`
			WHOLE_VERSION=`echo "${WHOLE_VERSION}" | tr -d '\r'`

			if [ -z "${VERSION}" ]; then
				WHOLE_VERSION=`echo "${WHOLE_VERSION}" | tr '\n' '%'`

				APP_RESULTS="${APP_RESULTS}
${APPLICATION}%${APPLICATION_DESC}%%0%${WHOLE_VERSION}"
				continue
			fi


			#
			# Now see if the application version is known to be bad.
			#

			RKHTMPVAR=`echo "${VERSION}" | sed -e 's/\./\\\./g'`

			if [ -n "`echo \"${APP_WHITELIST}\" | grep \" ${APPLICATION}:${RKHTMPVAR} \"`" ]; then
				APP_RESULTS="${APP_RESULTS}
${APPLICATION}%${APPLICATION_DESC}%${VERSION}%-1"
			elif [ -n "`egrep \"^${APPLICATION}:.* ${RKHTMPVAR}( |$)\" ${DB_PATH}/programs_bad.dat 2>&1`" ]; then
				APPS_FAILED_COUNT=`expr ${APPS_FAILED_COUNT} + 1`

				APP_RESULTS="${APP_RESULTS}
${APPLICATION}%${APPLICATION_DESC}%${VERSION}%1"
			else
				APP_RESULTS="${APP_RESULTS}
${APPLICATION}%${APPLICATION_DESC}%${VERSION}%0"
			fi
		fi
	done

	IFS=$RKHIFS


	#
	# Now display the results.
	#

	if [ $APPS_COUNT -eq 0 ]; then
		display --to SCREEN+LOG --type WARNING APPS_NONE_FOUND
	else
		IFS=$IFSNL

		for RKHTMPVAR in ${APP_RESULTS}; do
			APPLICATION=`echo "${RKHTMPVAR}" | cut -d% -f1`
			APPLICATION_DESC=`echo "${RKHTMPVAR}" | cut -d% -f2`
			VERSION=`echo "${RKHTMPVAR}" | cut -d% -f3`

			if [ -z "${VERSION}" ]; then
				WHOLE_VERSION=`echo "${RKHTMPVAR}" | cut -d% -f5- | tr '%' '\n'`

				display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 APPS_CHECK "${APPLICATION_DESC}"

				if [ -n "${WHOLE_VERSION}" ]; then
					display --to LOG --type INFO APPS_CHECK_WHOLE_VERSION_USED "${APPLICATION}" "${WHOLE_VERSION}"
				else
					display --to LOG --type INFO APPS_CHECK_VERSION_UNKNOWN "${APPLICATION}"
				fi
			elif [ "${VERSION}" = "-1" ]; then
				display --to LOG --type INFO APPS_NOT_FOUND "${APPLICATION}"
			else
				ISBAD=`echo "${RKHTMPVAR}" | cut -d% -f4`

				if [ -n "`echo \"${ISBAD}\" | grep '[^-0-9]'`" ]; then
					display --to SCREEN+LOG --type PLAIN --result SKIPPED --color YELLOW --log-indent 2 --screen-indent 4 APPS_CHECK "${APPLICATION_DESC}"
					display --to LOG --type INFO APPS_CHECK_VERSION_UNKNOWN "${APPLICATION}"
				elif [ $ISBAD -eq -2 ]; then
					display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 2 --screen-indent 4 APPS_CHECK "${APPLICATION_DESC}"
					display --to LOG --type INFO APPS_CHECK_WL "${APPLICATION}"
				elif [ $ISBAD -eq -1 ]; then
					display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 2 --screen-indent 4 APPS_CHECK "${APPLICATION_DESC}"
					display --to LOG --type INFO APPS_CHECK_VERSION_WL "${APPLICATION}" "${VERSION}"
				elif [ $ISBAD -eq 1 ]; then
					display --to SCREEN+LOG --type PLAIN --result WARNING --color RED --log-indent 2 --screen-indent 4 APPS_CHECK "${APPLICATION_DESC}"
					display --to LOG --type WARNING APPS_CHECK_FOUND "${APPLICATION}" "${VERSION}"
				else
					display --to SCREEN+LOG --type PLAIN --result OK --color GREEN --log-indent 2 --screen-indent 4 APPS_CHECK "${APPLICATION_DESC}"
					display --to LOG --type INFO APPS_CHECK_VERSION_FOUND "${APPLICATION}" "${VERSION}"
				fi
			fi
		done

		IFS=$RKHIFS
	fi


	display --to LOG --type INFO APPS_TOTAL_COUNT $APPS_COUNT $APPS_TOTAL_COUNT

	return
}


display_check_summary() {

	#
	# This function displays a short summary of some of the
	# groups of checks performed.
	#

	if [ $QUIET -eq 0 -o \( $SHOWWARNINGSONLY -eq 1 -a $WARNING_COUNT -gt 0 \) ]; then
		RKHTMPVAR=2
	else
		RKHTMPVAR=1
	fi

	display --to SCREEN+LOG --type PLAIN --nl ${RKHTMPVAR} SUMMARY_TITLE1
	display --to SCREEN+LOG --type PLAIN SUMMARY_TITLE2


	#
	# Do file properties summary.
	#

	display --to SCREEN+LOG --type PLAIN --nl SUMMARY_PROP_SCAN

	if `check_test properties`; then
		if [ $SUMMARY_PROP_REQCMDS -eq 1 ]; then
			display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_PROP_REQCMDS
		fi

		display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_PROP_COUNT $PROP_FILE_LIST_COUNT
		display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_PROP_FAILED $PROP_FAILED_COUNT
	else
		display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_CHKS_SKIPPED
	fi


	#
	# Do rootkit check summary.
	#

	display --to SCREEN+LOG --type PLAIN --nl SUMMARY_RKT_SCAN

	if `check_test rootkits`; then
		display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_RKT_COUNT $ROOTKIT_COUNT
		display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_RKT_FAILED $ROOTKIT_FAILED_COUNT

		if [ -n "${ROOTKIT_FAILED_NAMES}" ]; then
			ROOTKIT_FAILED_NAMES=`echo "${ROOTKIT_FAILED_NAMES}" | sed -e 's/, $//'`
			display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_RKT_NAMES "${ROOTKIT_FAILED_NAMES}"
		fi
	else
		display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_CHKS_SKIPPED
	fi


	#
	# Do application check summary.
	#

	display --to SCREEN+LOG --type PLAIN --nl SUMMARY_APPS_SCAN

	if `check_test apps`; then
		display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_APPS_COUNT $APPS_COUNT
		display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_APPS_FAILED $APPS_FAILED_COUNT
	else
		display --to SCREEN+LOG --type PLAIN --screen-indent 4 SUMMARY_CHKS_SKIPPED
	fi


	#
	# Display the amount of time the system checking took.
	#

	if [ $BEGINTIME -eq 0 ]; then
		display --to SCREEN+LOG --type PLAIN --nl SUMMARY_NO_SCAN_TIME
	else
		display --to SCREEN+LOG --type PLAIN --nl SUMMARY_SCAN_TIME "${TOTAL_SCANTIME}"
	fi


	#
	# Display where the log file is located, if there is one.
	#

	if [ $NOLOG -eq 0 ]; then
		display --to SCREEN --type PLAIN --nl --nl-after SUMMARY_LOGFILE "${RKHLOGFILE}"
	else
		display --to SCREEN --type PLAIN --nl --nl-after SUMMARY_NO_LOGFILE
	fi

	return
}


do_system_check() {

	#
	# This function performs the various rootkit and security checks
	# for the program. We start by initialising variables used for
	# the rootkit checks.
	#

	display --to LOG --type PLAIN --nl CHECK_START

	do_system_check_initialisation


	#
	# Next, for Solaris we see if we are running Solaris 10 or not.
	# This can be useful to know in some of the tests since we will
	# use different mechanisms on Solaris 10 from those on Solaris
	# 9 and before.
	#

	SOL_PROC=0
	SOLARISX=""

	if [ $SUNOS -eq 1 ]; then
		#
		# If we are running Solaris 10, then see if we have the
		# command pathname available.
		#
		# Solaris 10 and above should have the 'a.out' file
		# present. We use the PID of 1 here since it should exist
		# on all systems.
		#
		# If we are running Solaris 10 (or above), then we add
		# the '-X' option to the 'lsof' command in order to get
		# the deleted files.
		#

		if [ -h "/proc/1/path/a.out" ]; then
			SOLARISX='-X'
			test -n "${READLINK_CMD}" && SOL_PROC=1
		fi
	fi


	#
	# Record the start time if we can. The total time taken for
	# scanning will only be calculated and displayed if the
	# start time can be set.
	#

	BEGINTIME=0
	ENDTIME=0

	if [ -n "$SECONDS" ]; then
		BEGINTIME=$SECONDS
	elif [ $BSDOS -eq 1 ]; then
		BEGINTIME=`date +%s`
	elif [ -n "${PERL_CMD}" ]; then
		BEGINTIME=`${PERL_CMD} -e 'printf "%d\n", time;'`
	fi


	#
	# Send a start message to syslog if the user requested that.
	#

	if [ -n "${USE_SYSLOG}" ]; then
		${LOGGER_CMD} -t "${PROGRAM_NAME}" -p ${USE_SYSLOG} "Rootkit hunter check started (version ${PROGRAM_version})"
	fi


	#
	# We start with checks of some of the commands (binaries) and 
	# libraries on the system, to make sure that they have not
	# been tampered with.
	#

	do_system_commands_checks


	#
	# Next are the rootkit checks.
	#

	do_rootkit_checks


	#
	# Next are some network port, and interface checks.
	#

	do_network_checks


	#
	# Next are checks of the files for the local host.
	#

	do_local_host_checks


	#
	# Next are checks on specific applications.
	#

	do_app_checks


	#
	# Now record the end time.
	#

	if [ $BEGINTIME -ne 0 ]; then
		if [ -n "$SECONDS" ]; then
			ENDTIME=$SECONDS
		elif [ $BSDOS -eq 1 ]; then
			ENDTIME=`date +%s`
		else
			ENDTIME=`${PERL_CMD} -e 'printf "%d\n", time;'`
		fi

		TOTAL_SCANTIME=`expr ${ENDTIME} - ${BEGINTIME}`
		TOTALMINS=`expr ${TOTAL_SCANTIME} / 60`
		TOTALSECS=`expr ${TOTAL_SCANTIME} % 60`

		if [ $TOTALMINS -gt 0 ]; then
			if [ $TOTALMINS -eq 1 ]; then
				TOTAL_SCANTIME="${TOTALMINS} minute and "
			else
				TOTAL_SCANTIME="${TOTALMINS} minutes and "
			fi
		else
			TOTAL_SCANTIME=""
		fi

		if [ $TOTALSECS -eq 1 ]; then
			TOTAL_SCANTIME="${TOTAL_SCANTIME}${TOTALSECS} second"
		else
			TOTAL_SCANTIME="${TOTAL_SCANTIME}${TOTALSECS} seconds"
		fi
	fi


	#
	# Display the summary of the results.
	#

	if [ $SHOW_SUMMARY -eq 1 ]; then
		#
		# Unfortunately we need to do a kludge here!
		# The user may have used the '--quiet' option,
		# so we need to force the summary to be displayed.
		# By resetting the NOTTY variable we can get
		# the output shown.
		#

		OLD_NOTTY=$NOTTY
		test $SHOW_SUMMARY_OPT -eq 1 && NOTTY=0

		display_check_summary

		if [ $WARNING_COUNT -eq 0 ]; then
			display --to SCREEN --type PLAIN --nl-after CHECK_WARNINGS_NOT_FOUND
		else
			display --to SCREEN --type PLAIN CHECK_WARNINGS_FOUND

			if [ $NOLOG -eq 1 ]; then
				display --to SCREEN --type PLAIN --nl-after CHECK_WARNINGS_FOUND_RERUN
			else
				display --to SCREEN --type PLAIN --nl-after CHECK_WARNINGS_FOUND_CHK_LOG "${RKHLOGFILE}"
			fi
		fi

		NOTTY=$OLD_NOTTY
	fi


	#
	# Send a finish message to syslog if the user requested that.
	#

	if [ -n "${USE_SYSLOG}" ]; then
		${LOGGER_CMD} -t "${PROGRAM_NAME}" -p ${USE_SYSLOG} "Scanning took ${TOTAL_SCANTIME}"
	fi


	#
	# If some warning or error has been seen, then make sure the
	# user is told about it. We also set the return code, to allow
	# the user to detect it being non-zero.
	#

	if [ $WARNING_COUNT -gt 0 ]; then
		if [ $SHOWWARNINGSONLY -eq 1 ]; then
			#
			# Unfortunately we need to do a kludge again!
			# By requesting that only warnings are shown,
			# the following output would not normally be
			# displayed (because they are not warnings).
			#

			OLD_NOTTY=$NOTTY
			NOTTY=0

			display --to SCREEN --type PLAIN --nl CHECK_WARNINGS_FOUND

			if [ $NOLOG -eq 1 ]; then
				display --to SCREEN --type PLAIN CHECK_WARNINGS_FOUND_RERUN
			else
				display --to SCREEN --type PLAIN CHECK_WARNINGS_FOUND_CHK_LOG "${RKHLOGFILE}"
			fi

			NOTTY=$OLD_NOTTY
		fi


		if [ -n "${USE_SYSLOG}" ]; then
			${LOGGER_CMD} -t "${PROGRAM_NAME}" -p ${USE_SYSLOG} "Please inspect this machine, because it may be infected."
		fi


		if [ -n "${MAILONWARNING}" ]; then
			eval "echo 'Please inspect this machine, because it may be infected.' | ${MAIL_CMD} ${MAILONWARNING}"
		fi

		RET_CODE=1
	fi

	return
}


check_os_info() {

	#
	# This function checks the current O/S information against
	# that stored in the rkhunter.dat file. Any change could
	# mean that the file properties checks could give several
	# false-positive answers. As such we warn users that
	# a change has occurred.
	#

	#
	# First check if the host name has changed.
	#

	OS_CHANGED=0

	display --to LOG --type PLAIN --nl OSINFO_START


	OLD_HOST=`grep '^Host:' ${DB_PATH}/rkhunter.dat | cut -d: -f2-`

	if [ "${HOST_NAME}" != "${OLD_HOST}" ]; then
		OS_CHANGED=1
		display --to LOG --type WARNING OSINFO_HOST_CHANGE1
		display --to LOG --type PLAIN --log-indent 9 OSINFO_HOST_CHANGE2 "${OLD_HOST}" "${HOST_NAME}"
	fi


	#
	# Next check if the O/S name has changed.
	#

	OLD_OSNAME=`grep '^OS:' ${DB_PATH}/rkhunter.dat | cut -d: -f2-`

	if [ "${OSNAME}" != "${OLD_OSNAME}" ]; then
		OS_CHANGED=1
		display --to LOG --type WARNING OSINFO_OSVER_CHANGE1
		display --to LOG --type PLAIN --log-indent 9 OSINFO_OSVER_CHANGE2 "${OLD_OSNAME}" "${OSNAME}"
	fi


	#
	# Check if the prelinking status has changed.
	#

	if [ -z "`grep '^Prelinked:Yes' ${DB_PATH}/rkhunter.dat`" ]; then
		OLD_PRELINK=0
	else
		OLD_PRELINK=1
	fi

	if [ $PRELINKED -ne $OLD_PRELINK ]; then
		OS_CHANGED=1
		if [ $PRELINKED -eq 1 ]; then
			display --to LOG --type WARNING OSINFO_PRELINK_CHANGE ''
		else
			display --to LOG --type WARNING OSINFO_PRELINK_CHANGE 'not '
		fi
	fi


	#
	# Check if the system architecture has changed. We treat
	# the i386-type architectures as the same. We also treat
	# the sun-type archictures the same as 'sparc'.
	#

	OLD_ARCH=`grep '^Arch:' ${DB_PATH}/rkhunter.dat | cut -d: -f2-`

	if [ -n "`echo ${OLD_ARCH} | grep 'i[0-9]86'`" ]; then
		OLD_ARCH_TYPE="i386"
	elif [ -n "`echo ${OLD_ARCH} | grep 'sun[0-9][a-z]'`" -o -n "`echo ${OLD_ARCH} | grep 'sparc'`" ]; then
		OLD_ARCH_TYPE="sparc"
	else
		OLD_ARCH_TYPE=$OLD_ARCH
	fi

	if [ -n "`echo ${ARCH} | grep 'i[0-9]86'`" ]; then
		ARCH_TYPE="i386"
	elif [ -n "`echo ${ARCH} | grep 'sun[0-9][a-z]'`" -o -n "`echo ${ARCH} | grep 'sparc'`" ]; then
		ARCH_TYPE="sparc"
	else
		ARCH_TYPE=$ARCH
	fi

	if [ "${OLD_ARCH_TYPE}" != "${ARCH_TYPE}" ]; then
		OS_CHANGED=1
		display --to LOG --type WARNING OSINFO_ARCH_CHANGE1
		display --to LOG --type PLAIN --log-indent 9 OSINFO_ARCH_CHANGE2 "${OLD_ARCH}" "${ARCH}"
	fi

	if [ $OS_CHANGED -eq 1 ]; then
		display --to LOG --type PLAIN --log-indent 9 OSINFO_MSG1
		display --to LOG --type PLAIN --log-indent 9 OSINFO_MSG2
		display --to LOG --type WARNING --nl PROPUPD_WARN
	else
		display --to LOG --type INFO OSINFO_END
	fi

	return
}


set_file_prop_dirs_files() {

	#
	# This function sets up the list of directories we look in,
	# and the list of files we look for, in order to perform
	# the file properties checks.
	#
	# Any non-existent files are simply left in for the checks
	# to skip over. However, any symbolic links are expanded and
	# the result of the link is added to the list. This avoids
	# any attempt to simply replace a link, and avoid it being
	# detected by the file hash value check.
	#
	# We also check to see if any of the directories are links.
	# If it is then we add the link target directory.
	#

	PROP_DIR_LIST=""

	for DIR in ${BINPATHS}; do
		if [ -d "${RKHROOTDIR}${DIR}" ]; then
			LINKDIR="${RKHROOTDIR}${DIR}"

			if [ -n "${READLINK_CMD}" -a -h "${LINKDIR}" ]; then
				LINKDIR=`${READLINK_CMD} -f ${LINKDIR}`

				#
				# If the link target directory does not start
				# with the RKHROOTDIR, then prepend it.
				#

				if [ -z "`echo \"${LINKDIR}\" | grep \"^${RKHROOTDIR}/\"`" ]; then
					LINKDIR="${RKHROOTDIR}${LINKDIR}"
				fi
			fi

			if [ -z "`echo \"${PROP_DIR_LIST}\" | egrep \"(^| )${LINKDIR}( |$)\"`" ]; then
				PROP_DIR_LIST="${PROP_DIR_LIST} ${LINKDIR}"
			fi
		fi
	done

	PROP_FILE_LIST="adduser amd awk basename bash bget cat chattr checkproc
	    chkconfig chmod chown chroot cp cron csh curl cut date depmod df
	    diff dirname dmesg dpkg dpkg-query du echo ed egrep elinks env fgrep
	    file find fuser GET grep groupadd groupdel groupmod groups grpck head id
	    ifconfig ifdown ifstatus ifup inetd init insmod ip kallsyms kill
	    killall ksyms kudzu last lastlog ldd less links locate logger login
	    ls lsattr lsmod lsof lynx mail md5 md5sum mktemp mlocate modinfo
	    modload modprobe modstat modunload more mount mv netstat newgrp
	    newsyslog nologin passwd perl pkgdb pkg_info prelink ps pstree pwck
	    pwd readlink rkhunter rmmod rpm rsyslogd runcon runlevel sed sestatus sh
	    sha1 sha1sum size skdet slocate sockstat sort stat strace strings su sudo
	    sulogin sysctl syslogd systat tail tcpd test top touch tr uname unhide
	    uniq useradd userdel usermod users vipw vmstat w watch wc wget whatis
	    whereis which who whoami xinetd"


	#
	# We add in some extra commands to check depending on the O/S.
	#

	if [ $SUNOS -eq 1 ]; then
		PROP_FILE_LIST="${PROP_FILE_LIST} gbasename gcat gchmod gchown
		    gdate gdirname gecho gfind gfile ggroups ghead gid glocate
		    gmd5sum gsize gtail gtest gtouch guname gusers inetadm truss"
	elif [ "${OPERATING_SYSTEM}" = "FreeBSD" ]; then
		PROP_FILE_LIST="${PROP_FILE_LIST} kldload kldstat kldunload"
	fi


	#
	# Now loop through the file list and look for symbolic links.
	# If a link is found, then add on the file and directory that
	# the link points to.
	#

	if [ -n "${READLINK_CMD}" ]; then
		EXTRA_DIRS=""
		EXTRA_FILES=""

		for DIR in ${PROP_DIR_LIST}; do
			for FNAME in ${PROP_FILE_LIST}; do
				if [ -h "${DIR}/${FNAME}" ]; then
					RKHTMPVAR=`${READLINK_CMD} -f ${DIR}/${FNAME}`

					test ! -f "${RKHTMPVAR}" && continue

					#
					# Get the link target directory name.
					#

					LINKDIR=`echo "${RKHTMPVAR}" | sed -e 's:/[^/]*$::'`

					#
					# We need to see if the target directory
					# starts with the RKHROOTDIR. If it
					# does not, then we prepend it.
					#

					if [ -z "`echo \"${LINKDIR}\" | grep \"^${RKHROOTDIR}/\"`" ]; then
						LINKDIR="${RKHROOTDIR}${LINKDIR}"
					fi

					#
					# Now see if we already have the directory listed.
					# If not, then we add it on.
					#

					if [ -z "`echo \"${PROP_DIR_LIST} ${EXTRA_DIRS}\" | egrep \"(^| )${LINKDIR}( |$)\"`" ]; then
						EXTRA_DIRS="${EXTRA_DIRS} ${LINKDIR}"
					fi


					#
					# Now get the link target file name.
					#

					LINKFNAME=`echo "${RKHTMPVAR}" | sed -e 's:^.*/\([^/]*\)$:\1:'`

					#
					# And finally check if we already have it listed.
					#

					if [ -z "`echo \"${PROP_FILE_LIST} ${EXTRA_FILES}\" | egrep \"(^| )${LINKFNAME}( |$)\"`" ]; then
						EXTRA_FILES="${EXTRA_FILES} ${LINKFNAME}"
					fi
				fi
			done
		done

		test -n "${EXTRA_DIRS}" && PROP_DIR_LIST="${PROP_DIR_LIST} ${EXTRA_DIRS}"
		test -n "${EXTRA_FILES}" && PROP_FILE_LIST="${PROP_FILE_LIST} ${EXTRA_FILES}"
	fi

	PROP_FILE_LIST_TOTAL=`echo ${PROP_FILE_LIST} | wc -w | tr -d ' '`

	return
}


check_test() {

	#
	# This function will check whether a given test name should
	# be run or not. It returns 0 if the test is to be run,
	# and 1 if it is not.
	#

	if [ "${ENABLE_TESTS}" = "all" -o -n "`echo \"${ENABLE_TESTS}\" | egrep \"(^| )${1}( |$)\"`" ]; then
		if [ "${DISABLE_TESTS}" = "none" -o -z "`echo \"${DISABLE_TESTS}\" | egrep \"(^| )${1}( |$)\"`" ]; then
			return 0
		fi
	fi

	return 1
}


display_tests() {

	#
	# This function is used to simply output all the available
	# tests and test group names. If a group name itself contains
	# a group name, then that second group name is omitted. It
	# could be confusing if it was included.
	#

	KNOWN_TESTS="all none ${KNOWN_TESTS}"

	if [ -n "${SORT_CMD}" ]; then
		KNOWN_TESTS=`echo "${KNOWN_TESTS}" | tr ' ' '\n' | ${SORT_CMD} | tr '\n' ' '`
		GROUPED_TESTS=`echo "${GROUPED_TESTS}" | tr ' ' '\n' | ${SORT_CMD} | tr '\n' ' '`
	fi


	display --to SCREEN --type PLAIN --nl LIST_TESTS

	while test -n "${KNOWN_TESTS}"; do
		STR=`echo ${KNOWN_TESTS} | cut -d' ' -f1-6`
		KNOWN_TESTS=`echo ${KNOWN_TESTS} | cut -d' ' -f7-`

		echo "    ${STR}"

		test "${STR}" = "${KNOWN_TESTS}" && KNOWN_TESTS=""
	done


	display --to SCREEN --type PLAIN --nl LIST_GROUPED_TESTS

	#
	# Sort out the maximum group name length, so we can do some
	# simple formatting of the output.
	#

	MAX=0

	for STR in ${GROUPED_TESTS}; do
		LEN=`echo "${STR}" | cut -d: -f1 | wc -c | tr -d ' '`
		test $LEN -gt $MAX && MAX=$LEN
	done


	#
	# Now loop through the group names.
	#

	for STR in ${GROUPED_TESTS}; do
		TEST_NAMES=""
		GROUP_NAME=`echo "${STR}" | cut -d: -f1`

		#
		# Add on spaces to expand the group name to the maximum.
		#

		LEN=`echo "${GROUP_NAME}" | wc -c | tr -d ' '`
		LEN=`expr $MAX - $LEN`

		test $LEN -gt 0 && GROUP_NAME="${GROUP_NAME} `echo \"${BLANK_LINE}\" | cut -d' ' -f1-$LEN`"


		#
		# Check through the list of tests for this group name.
		# If the test name is a group name itself, then go to
		# the next test name, otherwise add it to our list of
		# test names.
		#

		for TEST in `echo "${STR}" | cut -d: -f2- | tr ':' ' '`; do
			RKHTMPVAR=`echo "${GROUPED_TESTS}" | egrep "(^| )${TEST}:"`

			if [ -z "${RKHTMPVAR}" ]; then
				TEST_NAMES="${TEST_NAMES}:${TEST}"
			else
				continue
			fi
		done


		#
		# Finally, sort our list of test names and display them.
		#

		TEST_NAMES=`echo "${TEST_NAMES}" | sed -e 's/^://'`

		if [ -n "${SORT_CMD}" ]; then
			TEST_NAMES=`echo "${TEST_NAMES}" | tr ':' '\n' | ${SORT_CMD} | tr '\n' ' '`
		else
			TEST_NAMES=`echo "${TEST_NAMES}" | tr ':' ' '`
		fi

		echo "    ${GROUP_NAME} => ${TEST_NAMES}"
	done

	return
}


display_languages() {

	#
	# This function is used to simply output all the available
	# languages in a basic format of 10 per line.
	#

	KNOWN_LANGS=`ls -1 ${DB_PATH}/i18n 2>/dev/null`

	if [ -n "${SORT_CMD}" ]; then
		KNOWN_LANGS=`echo "${KNOWN_LANGS}" | ${SORT_CMD}`
	fi


	display --to SCREEN --type PLAIN --nl LIST_LANGS

	while test -n "${KNOWN_LANGS}"; do
		STR=`echo ${KNOWN_LANGS} | cut -d' ' -f1-10`
		KNOWN_LANGS=`echo ${KNOWN_LANGS} | cut -d' ' -f11-`

		echo "    ${STR}"

		test "${STR}" = "${KNOWN_LANGS}" && KNOWN_LANGS=""
	done

	return
}


display_rootkits() {

	#
	# This function is used to simply output all the rootkit
	# names which rkhunter will check for.
	#

	if [ -n "${SORT_CMD}" ]; then
		KNOWN_ROOTKITS=`echo " ${KNOWN_ROOTKITS}" | tr ',' '\n' | ${SORT_CMD} | tr '\n' ','`
	fi

	KNOWN_ROOTKITS=`echo "${KNOWN_ROOTKITS}" | sed -e 's/,$//' | sed -e 's/^,*//'`


	display --to SCREEN --type PLAIN --nl LIST_RTKTS

	while test -n "${KNOWN_ROOTKITS}"; do
		STR=`echo ${KNOWN_ROOTKITS} | cut -d',' -f1-6`
		KNOWN_ROOTKITS=`echo ${KNOWN_ROOTKITS} | cut -d',' -f7-`

		if [ "${STR}" = "${KNOWN_ROOTKITS}" -o -z "${KNOWN_ROOTKITS}" ]; then
			KNOWN_ROOTKITS=""
		else
			STR="${STR},"
		fi

		echo "    ${STR}"
	done

	return
}


help() {

	#
	# This function outputs the help menu.
	#

	echo $ECHOOPT ""
	echo $ECHOOPT "Usage: rkhunter {--check | --update | --propupd | --versioncheck |"
	echo $ECHOOPT "                 --list [tests | languages | rootkits] |"
	echo $ECHOOPT "                 --version | --help} [options]"
	echo $ECHOOPT ""

	echo $ECHOOPT "Current options are:"
	echo $ECHOOPT "         --append-log                  Append to the logfile, do not overwrite"
	echo $ECHOOPT "         --bindir <directory>...       Use the specified command directories"
	echo $ECHOOPT "     -c, --check                       Check the local system"
	echo $ECHOOPT "  --cs2, --color-set2                  Use the second color set for output"
	echo $ECHOOPT "         --configfile <file>           Use the specified configuration file"
	echo $ECHOOPT "         --cronjob                     Run as a cron job"
	echo $ECHOOPT "                                       (implies -c, --sk and --nocolors options)"
	echo $ECHOOPT "         --dbdir <directory>           Use the specified database directory"
	echo $ECHOOPT "         --debug                       Debug mode"
	echo $ECHOOPT "                                       (Do not use unless asked to do so)"
	echo $ECHOOPT "         --disable <test>[,<test>...]  Disable specific tests"
	echo $ECHOOPT "                                       (Default is to disable no tests)"
	echo $ECHOOPT "         --display-logfile             Display the logfile at the end"
	echo $ECHOOPT "         --enable  <test>[,<test>...]  Enable specific tests"
	echo $ECHOOPT "                                       (Default is to enable all tests)"
	echo $ECHOOPT "         --hash {MD5 | SHA1 | NONE |   Use the specified file hash function"
	echo $ECHOOPT "                 <command>}            (Default is SHA1)"
	echo $ECHOOPT "     -h, --help                        Display this help menu, then exit"
	echo $ECHOOPT " --lang, --language <language>         Specify the language to use"
	echo $ECHOOPT "                                       (Default is English)"
	echo $ECHOOPT "         --list [tests | languages |   List the available test names, languages,"
	echo $ECHOOPT "                 rootkits]             or checked for rootkits, then exit"
	echo $ECHOOPT "     -l, --logfile [file]              Write to a logfile"
	echo $ECHOOPT "                                       (Default is $DFLT_LOGFILE)"
	echo $ECHOOPT "         --noappend-log                Do not append to the logfile, overwrite it"
	echo $ECHOOPT "         --nocolors                    Use black and white output"
	echo $ECHOOPT "         --nolog                       Do not write to a logfile"
	echo $ECHOOPT "--nomow, --no-mail-on-warning          Do not send a message if warnings occur"
	echo $ECHOOPT "   --ns, --nosummary                   Do not show the summary of check results"
	echo $ECHOOPT " --novl, --no-verbose-logging          No verbose logging"
	echo $ECHOOPT "         --pkgmgr {RPM | DPKG | BSD |  Use the specified package manager to obtain or"
	echo $ECHOOPT "                   NONE}               verify file hash values. (Default is NONE)"
	echo $ECHOOPT "         --propupd                     Update the file properties database"
	echo $ECHOOPT "     -q, --quiet                       Quiet mode (no output at all)"
	echo $ECHOOPT "  --rwo, --report-warnings-only        Show only warning messages"
	echo $ECHOOPT "     -r, --rootdir <directory>         Use the specified root directory"
	echo $ECHOOPT "   --sk, --skip-keypress               Don't wait for a keypress after each test"
	echo $ECHOOPT "         --summary                     Show the summary of system check results"
	echo $ECHOOPT "                                       (This is the default)"
	echo $ECHOOPT "         --syslog [facility.priority]  Log the check start and finish times to syslog"
	echo $ECHOOPT "                                       (Default level is $SYSLOG_DFLT_PRIO)"
	echo $ECHOOPT "         --tmpdir <directory>          Use the specified temporary directory"
	echo $ECHOOPT "         --update                      Check for updates to database files"
	echo $ECHOOPT "   --vl, --verbose-logging             Use verbose logging (on by default)"
	echo $ECHOOPT "     -V, --version                     Display the version number, then exit"
	echo $ECHOOPT "         --versioncheck                Check for latest version of program"
	echo $ECHOOPT "     -x, --autox                       Automatically detect if X is in use"
	echo $ECHOOPT "     -X, --no-autox                    Do not automatically detect if X is in use"
	echo $ECHOOPT ""

	return
}


######################################################################
#
# Initialisation
#
######################################################################


#
# Unfortunately, for the Korn shell if we are debugging then
# we need to enable tracing in each of the functions.
#

if [ $DEBUG_OPT -eq 1 -a "${MYSHELL}" = "ksh" ]; then
	typeset +f | while read RKHTMPVAR; do
		typeset -ft ${RKHTMPVAR}
	done
fi

#
# We reset the SIGPIPE signal to its default
# to try and avoid any output write errors.
#

trap - 13 >/dev/null 2>&1


#
# Initialise the variables used throughout the program.
#

PROGRAM_NAME="Rootkit Hunter"
PROGRAM_version="1.3.2"
PROGRAM_copyright_owner="Michael Boelen"
PROGRAM_copyright="Copyright (c) 2003-2007, ${PROGRAM_copyright_owner}"
PROGRAM_blurb="
Currently under active development by the ${PROGRAM_NAME} project team.
Please review your rkhunter.conf before using.
Please review the documentation before posting bug reports or questions.
To report bugs, obtain updates, or provide patches or comments, please go to:
http://rkhunter.sourceforge.net

To ask questions about rkhunter, please use the rkhunter-users mailing list.
Note this is a moderated list: please subscribe before posting.

${PROGRAM_NAME} comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it under the
terms of the GNU General Public License. See the LICENSE file for details.
"
PROGRAM_license="
${PROGRAM_NAME} ${PROGRAM_version}, ${PROGRAM_copyright}
${PROGRAM_blurb}
"

# Set to run as a cron job.
CRONJOB=0
CHECK=0

# Set to display the logfile at the end.
CATLOGFILE=0

NOLOG=0
RKHLOGFILE=""
DFLT_LOGFILE="/var/log/rkhunter.log"

# Set to have the logfile appended to rather than overwritten.
APPEND_LOG=0
APPEND_OPT=0

# Set to have rkhunter start/finish messages, and warnings,
# logged to syslog. The priority/severity can be set on the
# command-line or in the configuration file.
USE_SYSLOG=""
SYSLOG_DFLT_PRIO="authpriv.notice"

DFLT_BINPATHS="/bin /usr/bin /sbin /usr/sbin /usr/local/bin /usr/local/sbin /usr/libexec /usr/local/libexec"

# By default do not send a mail-on-warning message.
NOMOW=0
MAILONWARNING=""

HASH_FUNC=""
OLD_HASH_FUNC=""
PKGMGR=""
OLD_PKGMGR=""
OLD_ATTRUPD=""
HASH_FLD_IDX=1
PROP_DIR_LIST=""
PROP_FILE_LIST=""
PROP_FILE_LIST_COUNT=0
PROP_FILE_LIST_TOTAL=0

PRELINKED=0
PRELINK_CMD=""
PRELINK_HASH=""
PKGMGR_MD5_HASH=""
MD5_CMD=""

UPDATE=0
PROP_UPDATE=0
VERSIONCHECK=0

# By default use coloured output.
COLORS=1
CLRSET2=0

# Set to automatically detect if X is in use, and
# hence use the second colour set.
AUTO_X_DTCT=0
AUTO_X_OPT=0

PREVIOUSTEXT=""

# Set to be quiet. No output, but the return code will be set.
QUIET=0

# Set to only show warnings.
SHOWWARNINGSONLY=0

# This will be set if the file properties hash value check
# or the file attributes check is to be performed.
HASH_CHECK_ENABLED=0
SKIP_HASH_MSG=0

# Users can reset this to a new root directory.
RKHROOTDIR=""

# Default 'id' command. Solaris will reset this.
ID_CMD="id"

# Set if we don't want to wait for a keypress after each test.
SKIP_KEY_PRESS=0

# Is this the Gentoo operating system?
GENTOO=0

# Set the O/S type if necessary.
BSDOS=0
SUNOS=0
IRIXOS=0

case "${OPERATING_SYSTEM}" in
*BSD)
	BSDOS=1
	HASH_FLD_IDX=4
	;;
SunOS)
	SUNOS=1
	;;
IRIX*)
	IRIXOS=1
	;;
esac

# This will be set if the local host or O/S has changed in some way.
OS_CHANGED=0

# These SSH options can only be set in the configuration file.
ALLOW_SSH_PROT_V1=0
ALLOW_SSH_ROOT_USER=""
SSH_CONFIG_DIR=""

# These syslog options can only be set in the configuration file.
ALLOW_SYSLOG_REMOTE_LOGGING=0
SYSLOG_CONFIG_FILE=""

# Set check counters to be used by the summary.
ROOTKIT_COUNT=0
ROOTKIT_FAILED_COUNT=0
ROOTKIT_FAILED_NAMES=""

PROP_FAILED_COUNT=0
SUMMARY_PROP_REQCMDS=0

APPS_COUNT=0
APPS_TOTAL_COUNT=0
APPS_FAILED_COUNT=0

# Timers for the system check.
BEGINTIME=0
TOTAL_SCANTIME=""

# This will be set if a warning message is logged.
WARNING_COUNT=0

# Set if grsecurity is installed.
GRSECINSTALLED=0

# Ksyms or kallsyms file used in some checks.
KSYMS_FILE=""

# Record for logging the command-line being used.
CMD_LINE="$0 $*"

# Create a spaced-separated PATH variable.
SPACEDPATH=`echo ${PATH} | tr ':' ' '`

# List of commands used during RKH. If a command does not exist, then
# the code may use an alternative method.
CMDLIST="diff file find ifconfig ip ldd lsattr lsmod lsof mktemp netstat perl ps pwd readlink sort stat strings uniq"

# Commands that are required to exist for RKH to run.
REQCMDS="awk cat chmod chown cp cut date egrep grep head ls mv sed tail touch tr uname wc"

# List of commands used to download files from the web. This list is 
# used by the '--update' and '--versioncheck' options. Preferred commands
# are listed first.
WEBCMDLIST="wget curl elinks links lynx bget GET"

HOST_NAME=""

# This is the return code for the program actions - update, check, etc.
# Its value may either be 0 (no error) or 1 (an error occurred).
# The '--versioncheck' option may set the return code to 2 to
# indicate that an update is available.
# The '--update' option may set the return code to 2 to
# indicate that an update occurred.
RET_CODE=0

# Initially there is no language, this will be set later.
LANGUAGE=""

# A space-separated list of test names we recognise.
KNOWN_TESTS="strings properties hashes scripts immutable attributes
	     deleted_files packet_cap_apps apps rootkits known_rkts
	     additional_rkts malware local_host network passwd_changes
	     group_changes possible_rkts possible_rkt_files possible_rkt_strings
	     system_commands shared_libs shared_libs_path running_procs
	     hidden_procs trojans other_malware os_specific startup_malware
	     startup_files group_accounts system_configs filesystem suspscan
	     ports promisc"

# A space-separated list of test 'group names'. This list allows test
# names to be grouped together. For example, 'system_commands' can include
# the specific tests of 'strings' and 'hashes'. Both test
# group names, and specific test names, can be used with the test
# enable/disable options. In this list group names are colon-separated
# from the specific test names.
#
GROUPED_TESTS="system_commands:properties:strings:hashes:scripts:shared_libs:shared_libs_path:immutable:attributes
	       properties:hashes:scripts:immutable:attributes
	       shared_libs:shared_libs_path
	       rootkits:known_rkts:additional_rkts:possible_rkts:possible_rkt_files:possible_rkt_strings:malware:running_procs:hidden_procs:deleted_files:trojans:other_malware:os_specific:suspscan
	       additional_rkts:possible_rkts:possible_rkt_files:possible_rkt_strings
	       possible_rkts:possible_rkt_files:possible_rkt_strings
	       network:packet_cap_apps:ports:promisc
	       malware:running_procs:hidden_procs:deleted_files:suspscan:other_malware
	       local_host:startup_files:passwd_changes:group_changes:startup_malware:group_accounts:system_configs:filesystem
	       startup_files:startup_malware
	       group_accounts:passwd_changes:group_changes"

# A comma-separated list of rootkits we check for.
# NOTE: This is a COMMA separated list. Any single quotes need to be handled specially - i.e.
# put between double-quotes.
KNOWN_ROOTKITS='55808 Trojan - Variant A, AjaKit, aPa Kit, Apache Worm, Ambient (ark),
  Balaur, BeastKit, beX2, BOBKit, CiNIK Worm (Slapper.B variant), Danny-Boy'"'"'s Abuse Kit,
  Devil, Dica, Dreams, Duarawkz, Enye LKM, Flea Linux, FreeBSD,
  Fuck`it, GasKit, Heroin LKM, HjC Kit, ignoKit, ImperalsS-FBRK, Irix, Kitko,
  Knark, Li0n Worm, Lockit / LJK2, Mood-NT, MRK, Ni0, Ohhara,
  Optic Kit (Tux), Oz, Phalanx, Portacelo, R3dstorm Toolkit, RH-Sharpe'"'"'s,
  RSHA'"'"'s, Scalper Worm, Shutdown, SHV4, SHV5, Sin, SInAR, Slapper, Sneakin,
  Suckit, SunOS / NSDAP, SunOS Rootkit, Superkit, TBD (Telnet BackDoor),
  TeLeKiT, T0rn, Trojanit Kit, Tuxtendo, URK, VcKit, Volc, X-Org SunOS,
  zaRwT.KiT'

# The program defaults of which tests to perform will be set later.
ENABLE_TESTS=""
DISABLE_TESTS=""

# Set if the command-line options --enable or --disable have been used.
ENDIS_OPT=0

# Set if the --list option has been used.
LIST_OPT=""

# Space-filled line used for the display function.
BLANK_LINE="                                                              "

# Initially say that we are connected to a terminal.
NOTTY=0

# By default show the system check summary.
SHOW_SUMMARY=1
SHOW_SUMMARY_OPT=0

# By default log most things that are checked.
VERBOSE_LOGGING=1

# We copy the original IFS value, and set RKHIFS to space, tab, newline.
# IFSNL is set to just a newline.
ORIGIFS=$IFS
RKHIFS=" 	
"
IFSNL="
"
IFS=$RKHIFS

# No defaults set for the'rc' local system startup files and directory.
RC_DIR=""
RC_FILE=""

# Set a default for the inetd configuration file.
INETD_CONF_PATH="/etc/inetd.conf"
INETDALLOWEDSVCS=""

# Set a default for the xinetd configuration file.
XINETD_CONF_PATH="/etc/xinetd.conf"
XINETDALLOWEDSVCS=""

# Set if only the '--update' option is used.
UPDATE_ONLY=0

# Set if UPDATE_ONLY is set, and some language files are missing.
RKHLANGUPDT=0

# By default we rotate the mirrors in the mirrors.dat file,
# and we update the file when the '--update' option is used.
# The default MIRRORS_MODE is set such that we use both local
# and remote mirrors.
ROTATE_MIRRORS=1
UPDATE_MIRRORS=1
MIRRORS_MODE=0

# By default suspscan verbose logging should be initialised and off.
SUSPSCAN_DEBUG=0

# SELinux runcon usage as determined by get_if_prelinked.
USE_RUNCON=0
SELINUX_ENABLED=0

# These get set if any network ports are to be whitelisted.
PORT_WHITELIST=""
PORT_WHITELIST_PATH=""
PORT_WHITELIST_ALL_TRUSTED=0

# The O/S 'release' file location.
OS_VERSION_FILE=""

# By default no rootkit files or directories are whitelisted.
RTKT_DIR_WHITELIST=""
RTKT_FILE_WHITELIST=""


######################################################################
#
# Command-line option processing
#
######################################################################


#
# Display the help menu if no options were given.
#

if [ $# -eq 0 ]; then
	help
	exit 0
fi


#
# Check the command-line options. If set, these will override the
# configuration file options.
#

while [ $# -ge 1 ]; do
	FOUND=0

	case "$1" in
	--append-log | --appendlog)
		APPEND_LOG=1
		APPEND_OPT=1
		;;
	--bindir)
		case "$2" in
		"")
			;;
		-*)
			;;
		*)
			shift
			BINPATHS="$1"
			FOUND=1
			;;
		esac

		if [ $FOUND -eq 0 ]; then
			echo "No command directories specified."
			exit 1
		fi
		;;
	-c | --check | --checkall)
		CHECK=1
		;;
	--configfile)
		case "$2" in
		"")
			;;
		-*)
			;;
		*)
			shift
			CONFIGFILE="$1"
			FOUND=1
			;;
		esac

		if [ $FOUND -eq 0 ]; then
			echo "No configuration file specified."
			exit 1
		fi
		;;
	--cronjob)
		CHECK=1
		CRONJOB=1
		COLORS=0
		SKIP_KEY_PRESS=1
		;;
	--cs2 | --colorset2 | --color-set2)
		CLRSET2=1
		;;
	--dbdir)
		case "$2" in
		"")
			;;
		-*)
			;;
		*)
			shift
			DB_PATH="$1"
			FOUND=1
			;;
		esac

		if [ $FOUND -eq 0 ]; then
			echo "No database directory specified."
			exit 1
		fi
		;;
	--debug)
		SKIP_KEY_PRESS=1
		;;
	--display-logfile | --displaylogfile | --display-log | --displaylog)
		CATLOGFILE=1
		;;
	--disable)
		case "$2" in
		"")
			;;
		-*)
			;;
		*)
			shift
			ENDIS_OPT=1
			DISABLE_TESTS=$1
			FOUND=1
			;;
		esac

		if [ $FOUND -eq 0 ]; then
			echo "No tests specified to disable."
			exit 1
		fi
		;;
	--enable)
		case "$2" in
		"")
			;;
		-*)
			;;
		*)
			shift
			ENDIS_OPT=1
			ENABLE_TESTS=$1
			FOUND=1
			;;
		esac

		if [ $FOUND -eq 0 ]; then
			echo "No tests specified to enable."
			exit 1
		fi
		;;
	--hash)
		case "$2" in
		"")
			;;
		-*)
			;;
		*)
			shift
			HASH_FUNC="$1"
			FOUND=1
			;;
		esac

		if [ $FOUND -eq 0 ]; then
			echo "No hash function specified."
			exit 1
		fi
		;;
	-h | --help)
		help
		exit 0
		;;
	-l | --log | --logfile | --createlogfile | --createlog | --create-log | --create-logfile)
		RKHLOGFILE="${DFLT_LOGFILE}"

		case "$2" in
		"")
			;;
		-*)
			;;
		*)
			shift
			RKHLOGFILE="$1"
			;;
		esac
		;;
	--lang | --language)
		case "$2" in
		"")
			;;
		-*)
			;;
		*)
			shift
			LANGUAGE="$1"
			FOUND=1
			;;
		esac

		if [ $FOUND -eq 0 ]; then
			echo "No language specified."
			exit 1
		fi
		;;
	--list)
		case "$2" in
		test | tests | check | checks)
			shift
			LIST_OPT="${LIST_OPT} tests "
			;;
		lang | langs | language | languages)
			shift
			LIST_OPT="${LIST_OPT} languages "
			;;
		rootkit | rootkits)
			shift
			LIST_OPT="${LIST_OPT} rootkits "
			;;
		"")
			LIST_OPT="${LIST_OPT} tests languages rootkits "
			;;
		-*)
			LIST_OPT="${LIST_OPT} tests languages rootkits "
			;;
		*)
			echo "Invalid --list option specified: $2"
			exit 1
			;;
		esac
		;;
	--noappend-log | --no-append-log | --noappendlog)
		APPEND_LOG=0
		APPEND_OPT=1
		;;
	--nocolors | --no-colors | --nocolor | --no-color)
		COLORS=0
		;;
	--nolog | --no-log)
		RKHLOGFILE="/dev/null"
		;;
	--nomow | --no-mow | --no-mailonwarning | --no-mail-on-warning)
		NOMOW=1
		;;
	--novl | --noverboselogging | --no-verbose-logging)
		VERBOSE_LOGGING=0
		;;
	--ns | --nosummary | --no-summary)
		SHOW_SUMMARY=0
		SHOW_SUMMARY_OPT=1
		;;
	--pkgmgr)
		case "$2" in
		"")
			;;
		-*)
			;;
		*)
			shift
			PKGMGR=$1
			FOUND=1
			;;
		esac

		if [ $FOUND -eq 0 ]; then
			echo "No package manager specified."
			exit 1
		fi
		;;
	--propupd | --prop-update | --propupdate | --properties-update | --hashupd)
		PROP_UPDATE=1
		;;
	-q | --quiet)
		QUIET=1
		;;
	--rwo | --swo | --report-warnings-only | --show-warnings-only)
		QUIET=1
		SHOWWARNINGSONLY=1
		;;
	-r | --rootdir)
		case "$2" in
		"")
			;;
		-*)
			;;
		*)
			shift
			RKHROOTDIR="$1"
			FOUND=1
			;;
		esac

		if [ $FOUND -eq 0 ]; then
			echo "No root directory specified."
			exit 1
		fi
		;;
	-sk | --sk | --skip-keypress | --skipkeypress)
		SKIP_KEY_PRESS=1
		;;
	--summary)
		SHOW_SUMMARY=1
		SHOW_SUMMARY_OPT=1
		;;
	--syslog)
		USE_SYSLOG="${SYSLOG_DFLT_PRIO}"

		case "$2" in
		"")
			;;
		-*)
			;;
		*)
			shift
			USE_SYSLOG="$1"
			;;
		esac
		;;
	--tmpdir)
		case "$2" in
		"")
			;;
		-*)
			;;
		*)
			shift
			RKHTMPDIR="$1"
			FOUND=1
			;;
		esac

		if [ $FOUND -eq 0 ]; then
			echo "No temporary directory specified."
			exit 1
		fi
		;;
	--update)
		UPDATE=1
		;;
	--vl | --verboselogging | --verbose-logging)
		VERBOSE_LOGGING=1
		;;
	-V | --version)
		echo "${PROGRAM_NAME} ${PROGRAM_version}"
		echo "${PROGRAM_blurb}"
		exit 0
		;;
	--versioncheck)
		VERSIONCHECK=1
		;;
	-x | --autox)
		AUTO_X_OPT=1
		AUTO_X_DTCT=1
		;;
	-X | --no-autox)
		AUTO_X_OPT=1
		AUTO_X_DTCT=0
		;;
	*)
		echo "Invalid option specified: $1"
		exit 1
		;;
	esac

	shift
done


#
# We check that we are root. If we are not, then only the
# help and version command-line options are valid.
#

if [ $SUNOS -eq 1 ]; then
	test -x "/usr/xpg4/bin/id" && ID_CMD="/usr/xpg4/bin/id"
fi

if [ "`${ID_CMD} -u 2>/dev/null`" != "0" ]; then
	echo "You must be the root user to run this program."
	exit 1
fi


#
# We need to see if we are to run a check before we get to the
# configuration file processing. Basically if either of the
# --enable or --disable options are used, and this is not a
# property update run, then we will do a check. For update runs
# only the 'hashes' or 'attributes' tests are likely to be named.
#

test $ENDIS_OPT -eq 1 -a $PROP_UPDATE -eq 0 && CHECK=1


#
# See if only the '--update' option has been used.
#

test $UPDATE -eq 1 -a $CHECK -eq 0 -a $PROP_UPDATE -eq 0 -a $VERSIONCHECK -eq 0 && UPDATE_ONLY=1


#
# Before going too much further we need to ensure that some basic
# commands are present on the system. We cannot do this using
# the BINDIR option because that requires processing the configuration
# file, which in turn requires the commands we want to check on. As
# such we use the default command directory list. We do not assign
# these commands to variables, but will do for other commands which we
# look for later on.
#

check_required_commands "${SPACEDPATH} ${DFLT_BINPATHS}"


######################################################################
#
# Configuration file processing
#
######################################################################


#
# Now we check for the configuration file, and then check the various
# options within it.
#
# NOTE: Do not change the format of the following 'if' statement.
# The installer script will modify it directly during installation.
#

if [ -z "${CONFIGFILE}" ]; then
	if [ -f /etc/rkhunter.conf ]; then
		CONFIGFILE="/etc/rkhunter.conf"
	else
		CONFIGFILE="/usr/local/etc/rkhunter.conf"
	fi
fi

if [ ! -f "${CONFIGFILE}" ]; then
	echo "Unable to find configuration file: ${CONFIGFILE}"
	exit 1
elif [ ! -r "${CONFIGFILE}" ]; then
	echo "Configuration file is not readable: ${CONFIGFILE}"
	exit 1
elif [ ! -s "${CONFIGFILE}" ]; then
	echo "Configuration file is empty: ${CONFIGFILE}"
	exit 1
fi


get_configfile_options


######################################################################
#
# Option processing
#
######################################################################


#
# Next we check some of the options to make sure we can proceed. We
# also set up some final variables based on the combination of options
# we have been given.
#

#
# First we process the '--list' option if it has been given.
#

if [ -n "${LIST_OPT}" ]; then
	for RKHTMPVAR in ${LIST_OPT}; do
		if [ "${RKHTMPVAR}" = "tests" ]; then
			display_tests
		elif [ "${RKHTMPVAR}" = "languages" ]; then
			display_languages
		else
			display_rootkits
		fi
	done

	exit 0
fi


#
# Next we must see if we are doing an update only, and if there were
# some language file problems. If so, then we must not log or display
# anything.
#

if [ $RKHLANGUPDT -eq 1 ]; then
	QUIET=1
	COLORS=0
	RKHLOGFILE="/dev/null"
fi


#
# If the logfile has been disabled, then we cannot let the
# program run when certain options are used. If we did, the user
# would see no output and might assume that all was well.
#

if [ "${RKHLOGFILE}" = "/dev/null" ]; then
	NOLOG=1
	VERBOSE_LOGGING=0

	if [ $SHOWWARNINGSONLY -eq 1 ]; then
		echo "The logfile has been disabled - unable to report warnings."
		exit 1
	elif [ $CATLOGFILE -eq 1 ]; then
		echo "The logfile has been disabled - unable to display the log file."
		exit 1
	fi
fi


#
# Set up the colors to be used.
#

if [ $COLORS -eq 1 ]; then
	NORMAL="[0;39m"		# Foreground colour to default

	if [ $CLRSET2 -eq 0 ]; then
		RED="[1;31m"		# Bright red
		GREEN="[1;32m"	# Bright green
		YELLOW="[1;33m"	# Bright yellow
		WHITE="[1;37m"	# White
	else
		RED="[1;31m"		# Bright red
		GREEN="[0;32m"	# Green
		YELLOW="[0;35m"	# Purple
		WHITE="[0;30m"	# Black
	fi
fi


if [ $CHECK -eq 1 ]; then
	#
	# Check if we have a ksyms or kallsyms file.
	#

	if [ -f "${RKHROOTDIR}/proc/ksyms" ]; then
		KSYMS_FILE="${RKHROOTDIR}/proc/ksyms"
	elif [ -f "${RKHROOTDIR}/proc/kallsyms" ]; then
		KSYMS_FILE="${RKHROOTDIR}/proc/kallsyms"
	fi
fi


if [ $CHECK -eq 1 -o $PROP_UPDATE -eq 1 ]; then
	if [ -e "${DB_PATH}/rkhunter.dat" ]; then
		if [ -h "${DB_PATH}/rkhunter.dat" ]; then
			echo "The rkhunter.dat file is a symbolic link: ${DB_PATH}/rkhunter.dat"
			echo "This is a security problem. The link points to another file, and that file may be modified by rkhunter."
			exit 1
		elif [ ! -f "${DB_PATH}/rkhunter.dat" ]; then
			echo "The rkhunter.dat file is not a file: ${DB_PATH}/rkhunter.dat"
			exit 1
		fi
	fi


	#
	# Set up the file properties checks directories and file names.
	#

	set_file_prop_dirs_files


	#
	# We need to record the previously used
	# hash function and package manager.
	#

	if [ -s "${DB_PATH}/rkhunter.dat" ]; then
		OLD_HASH_FUNC=`grep '^Hash:' ${DB_PATH}/rkhunter.dat | cut -d: -f2-`

		OLD_PKGMGR=`grep '^Pkgmgr:' ${DB_PATH}/rkhunter.dat | cut -d: -f2`

		OLD_ATTRUPD=`grep '^Attributes:' ${DB_PATH}/rkhunter.dat | cut -d: -f2`
	fi
fi


if [ $PROP_UPDATE -eq 1 -a $PRELINKED -eq 1 -a -z "${PKGMGR}" -a "${HASH_FUNC}" != "NONE" ]; then
	#
	# For a hash update on a prelinked system, we must have
	# a valid hash function to use. The package managers use
	# an MD5 hash function by default.
	#

	if [ -z "${PRELINK_HASH}" ]; then
		RKHTMPVAR=`echo "${HASH_FUNC}" | cut -d' ' -f1`

		if [ -z "`echo ${RKHTMPVAR} | egrep -i 'sha1|md5'`" ]; then
			echo "This system uses prelinking, but the hash function (${HASH_FUNC}) does not look like SHA1 or MD5."
			exit 1
		fi
	fi
fi


#
# For the update and versioncheck options, we need to make sure
# we have a command capable of downloading files from the web.
# The first command found is used.
#

if [ $UPDATE -eq 1 -o $VERSIONCHECK -eq 1 ]; then
	FOUND=0

	for CMD in ${WEBCMDLIST}; do
		#
		# Ignore perl commands if perl is not present, or if
		# certain modules are not present.
		#

		if [ "${CMD}" = "GET" ]; then
			test -z "${PERL_CMD}" && continue

			MOD_INSTALLED=`${PERL_CMD} ${SCRIPT_PATH}/check_modules.pl LWP URI HTTP::Status HTTP::Date Getopt::Long 2>&1 | grep 'NOT'`

			test -n "${MOD_INSTALLED}" && continue
		elif [ "${CMD}" = "bget" ]; then
			test -z "${PERL_CMD}" && continue

			MOD_INSTALLED=`${PERL_CMD} ${SCRIPT_PATH}/check_modules.pl Socket Carp 2>&1 | grep 'NOT'`

			test -n "${MOD_INSTALLED}" && continue
		fi


		RKHTMPVAR=`echo ${CMD} | tr '[a-z]' '[A-Z]'`

		eval ${RKHTMPVAR}_CMD=`find_cmd ${CMD}`

		if [ -n "`eval echo \"\\$${RKHTMPVAR}_CMD\"`" ]; then
			FOUND=1
			break
		fi
	done

	if [ $FOUND -eq 0 ]; then
		echo "The '--update' and '--versioncheck' options require a command able to"
		echo "download files from the web. No such command can be found on the system."
		echo "Examples of commands that could be used are: ${WEBCMDLIST}"
		exit 1
	fi
fi


#
# If no option is given for the program to action, then say so and exit.
#

if [ $CHECK -eq 0 -a $VERSIONCHECK -eq 0 -a $UPDATE -eq 0 -a $PROP_UPDATE -eq 0 ]; then
	echo "You must enter an option for the program to perform."
	echo "Type in 'rkhunter --help' to see the available options,"
	echo "or read the rkhunter man page."
	exit 1
fi


#
# See if we have grsecurity installed.
#

if [ "${OPERATING_SYSTEM}" = "Linux" -a -n "`uname -a | grep 'grsec'`" ]; then
	GRSECINSTALLED=1
fi


#
# Before writing anything to the screen or log file, we need to
# set some variables.
#
# First we set whether we should be displaying anything on the
# screen or not.
#
test $CRONJOB -eq 1 -o $QUIET -eq 1 && NOTTY=1

#
# Next we get the message types and results from the language file,
# and set them to variables. We have to look in the English file since
# that is the definitive one. We then look for the corresponding keyword
# in the actual language file. This allows the language files to work
# even if we add or remove any of the TYPE or RESULT keywords.
#
IFS=$IFSNL

for LINE in `egrep '^MSG_(TYPE|RESULT)_' ${DB_PATH}/i18n/en 2>/dev/null`; do
	TYPE=`echo "${LINE}" | cut -d: -f1`

	if [ "${LANGUAGE}" != "en" ]; then
		RKHTMPVAR=`grep "^${TYPE}:" ${DB_PATH}/i18n/${LANGUAGE} 2>/dev/null`
		test -n "${RKHTMPVAR}" && LINE=`echo "${RKHTMPVAR}" | sed -e 's/\`/\\\\\`/g'`
	fi

	RKHTMPVAR=`echo "${LINE}" | cut -d: -f2-`

	eval $TYPE=\"${RKHTMPVAR}\"
done

IFS=$RKHIFS


#
# Sort out the logfile before we write to it.
#

if [ $NOLOG -eq 0 ]; then
	if [ $APPEND_LOG -eq 0 ]; then
		mv -f ${RKHLOGFILE} ${RKHLOGFILE}.old >/dev/null 2>&1
		touch ${RKHLOGFILE} >/dev/null 2>&1
		chmod 600 ${RKHLOGFILE} >/dev/null 2>&1
	else
		echo "" >>${RKHLOGFILE}
		echo "" >>${RKHLOGFILE}
	fi
fi


#
# Record the hostname. This will be used at several points
# throughout the program. A specific test will specify if
# a hostname has been found or not, so we don't need to
# do anything special here.
#

HOST_NAME=`hostname 2>/dev/null`
test -z "${HOST_NAME}" && HOST_NAME=`uname -n 2>/dev/null`
test -z "${HOST_NAME}" && HOST_NAME="${HOSTNAME}"
HOST_NAME=`echo ${HOST_NAME} | cut -d. -f1`


######################################################################
#
# Initial logging
#
######################################################################


#
# Write out various information messages to the logfile. The first
# set of messages can be skipped if no logfile is to be created.
#

display --to SCREEN --type PLAIN VERSIONLINE "${PROGRAM_NAME}" "${PROGRAM_version}"

if [ $NOLOG -eq 0 ]; then
	if [ -n "${HOST_NAME}" ]; then
		display --to LOG --type PLAIN VERSIONLINE2 "${PROGRAM_NAME}" "${PROGRAM_version}" ${HOST_NAME}
	else
		display --to LOG --type PLAIN VERSIONLINE3 "${PROGRAM_NAME}" "${PROGRAM_version}"
	fi

	display --to LOG --type INFO --nl RKH_STARTDATE "`date`"

	display --to LOG --type PLAIN --nl CONFIG_CHECK_START

	display --to LOG --type INFO OPSYS "${OPERATING_SYSTEM}"

	if [ -s "${DB_PATH}/rkhunter.dat" ]; then
		RKHTMPVAR=`grep '^OS:' ${DB_PATH}/rkhunter.dat 2>/dev/null | sed -e 's/^OS://'`

		if [ -n "${RKHTMPVAR}" ]; then
			display --to LOG --type INFO PROPUPD_OSNAME_FOUND "${RKHTMPVAR}"
		else
			display --to LOG --type INFO UNAME "`uname -a`"
		fi
	else
		display --to LOG --type INFO UNAME "`uname -a`"
	fi

	display --to LOG --type INFO CONFIG_CMDLINE "${CMD_LINE}"

	display --to LOG --type INFO CONFIG_ENVSHELL ${SHELL} ${MYSHELL}

	display --to LOG --type INFO CONFIG_CONFIGFILE "${CONFIGFILE}"

	display --to LOG --type INFO CONFIG_INSTALLDIR "${RKHINSTALLDIR}"

	display --to LOG --type INFO CONFIG_LANGUAGE "${LANGUAGE}"

	display --to LOG --type INFO CONFIG_DBDIR "${DB_PATH}"

	display --to LOG --type INFO CONFIG_SCRIPTDIR "${SCRIPT_PATH}"

	display --to LOG --type INFO CONFIG_BINDIR "${SPACEDPATH} ${BINPATHS}"

	if [ -z "${RKHROOTDIR}" ]; then
		display --to LOG --type INFO CONFIG_ROOTDIR "/"
	else
		display --to LOG --type INFO CONFIG_ROOTDIR "${RKHROOTDIR}"
	fi

	display --to LOG --type INFO CONFIG_TMPDIR "${RKHTMPDIR}"

	if [ $CHECK -eq 1 ]; then
		if [ $NOMOW -eq 1 ]; then
			display --to LOG --type INFO CONFIG_MOW_DISABLED
		else
			if [ -z "${MAILONWARNING}" ]; then
				display --to LOG --type INFO CONFIG_NO_MAIL_ON_WARN
			else
				display --to LOG --type INFO CONFIG_MAIL_ON_WARN "${MAILONWARNING}" "${MAIL_CMD}"
			fi
		fi
	fi

	test $AUTO_X_DTCT -eq 1 && display --to LOG --type INFO CONFIG_X_AUTO
	test $CLRSET2 -eq 1 && display --to LOG --type INFO CONFIG_CLRSET2

	for CMD in ${CMDLIST}; do
		RKHTMPVAR=`echo ${CMD} | tr '[a-z]' '[A-Z]'`
		RKHTMPVAR=`eval echo "\\$${RKHTMPVAR}_CMD"`

		if [ -n "${RKHTMPVAR}" ]; then
			display --to LOG --type INFO FOUND_CMD "${CMD}" "${RKHTMPVAR}"
		else
			display --to LOG --type INFO NOT_FOUND_CMD "${CMD}"
		fi
	done

	for CMD in ${WEBCMDLIST}; do
		RKHTMPVAR=`echo ${CMD} | tr '[a-z]' '[A-Z]'`
		RKHTMPVAR=`eval echo "\\$${RKHTMPVAR}_CMD"`

		if [ -n "${RKHTMPVAR}" ]; then
			display --to LOG --type INFO FOUND_CMD "${CMD}" "${RKHTMPVAR}"
		fi
	done

	test $GRSECINSTALLED -eq 1 && display --to LOG --type INFO GRSECINSTALLED
fi

if [ $PROP_UPDATE -eq 1 -o $HASH_CHECK_ENABLED -eq 1 ]; then
	if [ -z "${PKGMGR}" -a "${HASH_FUNC}" = "NONE" ]; then
		HASH_CHECK_ENABLED=0
		DISABLE_TESTS="${DISABLE_TESTS} hashes"
		display --to LOG --type INFO HASH_FUNC_DISABLED
	fi

	if [ $PRELINKED -eq 1 ]; then
		display --to LOG --type INFO SYS_PRELINK

		display --to LOG --type INFO FOUND_CMD 'prelink' "${PRELINK_CMD}"

		if [ -n "${SESTATUS_CMD}" ]; then
			display --to LOG --type INFO FOUND_CMD 'sestatus' "${SESTATUS_CMD}"

			if [ $SELINUX_ENABLED -eq 1 ]; then
				display --to LOG --type INFO SYS_SELINUX

				if [ $USE_RUNCON -eq 1 ]; then
					display --to LOG --type INFO FOUND_CMD 'runcon' "${RUNCON_CMD}"
				else
					display --to LOG --type INFO NOT_FOUND_CMD 'runcon'
				fi
			else
				display --to LOG --type INFO SYS_NO_SELINUX
			fi
		else
			display --to LOG --type INFO NOT_FOUND_CMD 'sestatus'
		fi

		if [ "${HASH_FUNC}" = "NONE" ]; then
			if [ -n "${PKGMGR}" ]; then
				display --to LOG --type INFO HASH_FUNC_NONE_PKGMGR
			else
				display --to LOG --type INFO HASH_FUNC_NONE
			fi
		elif [ -n "${PRELINK_HASH}" ]; then
			display --to LOG --type INFO HASH_FUNC_PRELINK "${PRELINK_HASH}"
		elif [ -z "`echo \"${HASH_FUNC}\" | egrep -i 'sha1|md5'`" ]; then
			SKIP_HASH_MSG=2
		else
			display --to LOG --type INFO HASH_FUNC "${HASH_FUNC}"
		fi
	else
		display --to LOG --type INFO SYS_NO_PRELINK

		if [ "${HASH_FUNC}" = "NONE" ]; then
			if [ -n "${PKGMGR}" ]; then
				display --to LOG --type INFO HASH_FUNC_NONE_PKGMGR
			else
				display --to LOG --type INFO HASH_FUNC_NONE
			fi
		elif [ -n "`echo "${HASH_FUNC}" | grep '/filehashsha1\.pl$'`" ]; then
			display --to LOG --type INFO HASH_FUNC_PERL 'SHA1'
		elif [ -n "`echo "${HASH_FUNC}" | grep '/filehashmd5\.pl$'`" ]; then
			display --to LOG --type INFO HASH_FUNC_PERL 'MD5'
		else
			display --to LOG --type INFO HASH_FUNC "${HASH_FUNC}"
		fi
	fi

	if [ -s "${DB_PATH}/rkhunter.dat" ]; then
		if [ "${OLD_HASH_FUNC}" = "Disabled" ]; then
			display --to LOG --type INFO HASH_FUNC_OLD_DISABLED
		else
			display --to LOG --type INFO HASH_FUNC_OLD "${OLD_HASH_FUNC}"
		fi

		if [ -z "${OLD_PKGMGR}" ]; then
			display --to LOG --type INFO HASH_PKGMGR_OLD_UNSET
		else
			display --to LOG --type INFO HASH_PKGMGR_OLD "${OLD_PKGMGR}"
		fi
	fi

	display --to LOG --type INFO HASH_FIELD_INDEX "$HASH_FLD_IDX"

	if [ $PROP_UPDATE -eq 1 ]; then
		if ! `check_test hashes`; then
			display --to LOG --type INFO HASHUPD_DISABLED
		elif [ -z "${PKGMGR}" ]; then
			if [ $PRELINKED -eq 1 ]; then
				if [ -n "${PRELINK_HASH}" ]; then
					display --to LOG --type INFO HASHUPD_PKGMGR_NOT_SPEC_PRELINKED "${PRELINK_HASH}"
				else
					display --to LOG --type INFO HASHUPD_PKGMGR_NOT_SPEC "${HASH_FUNC}"
				fi
			else
				display --to LOG --type INFO HASHUPD_PKGMGR_NOT_SPEC "${HASH_FUNC}"
			fi
		elif [ -n "${PKGMGR}" ]; then
			display --to LOG --type INFO HASHUPD_PKGMGR "${PKGMGR}"

			if [ "${PKGMGR}" = "RPM" ]; then
				display --to LOG --type INFO FOUND_CMD "rpm" "${RPM_CMD}"
			elif [ "${PKGMGR}" = "DPKG" ]; then
				if [ -z "`echo \"${DPKG_CMD}\" | grep '/dpkg$'`" ]; then
					display --to LOG --type INFO FOUND_CMD "dpkg-query" "${DPKG_CMD}"
				else
					display --to LOG --type INFO FOUND_CMD "dpkg" "${DPKG_CMD}"
				fi
			elif [ "${PKGMGR}" = "BSD" ]; then
				display --to LOG --type INFO FOUND_CMD "pkg-info" "${PKG_CMD}"
			fi
		fi
	fi

	if [ $HASH_CHECK_ENABLED -eq 1 ]; then
		if [ -z "${PKGMGR}" ]; then
			if [ $PRELINKED -eq 1 ]; then
				if [ -n "${PRELINK_HASH}" ]; then
					display --to LOG --type INFO HASH_PKGMGR_NOT_SPEC_PRELINKED "${PRELINK_HASH}"
				else
					display --to LOG --type INFO HASH_PKGMGR_NOT_SPEC "${HASH_FUNC}"
				fi
			else
				display --to LOG --type INFO HASH_PKGMGR_NOT_SPEC "${HASH_FUNC}"
			fi
		elif [ -n "${PKGMGR}" ]; then
			display --to LOG --type INFO HASH_PKGMGR "${PKGMGR}"

			if [ "${PKGMGR}" = "RPM" ]; then
				display --to LOG --type INFO FOUND_CMD "rpm" "${RPM_CMD}"
			elif [ "${PKGMGR}" = "DPKG" ]; then
				if [ -z "`echo \"${DPKG_CMD}\" | grep '/dpkg$'`" ]; then
					display --to LOG --type INFO FOUND_CMD "dpkg-query" "${DPKG_CMD}"
				else
					display --to LOG --type INFO FOUND_CMD "dpkg" "${DPKG_CMD}"
				fi

				display --to LOG --type INFO HASH_PKGMGR_MD5 "${PKGMGR_MD5_HASH}"
			elif [ "${PKGMGR}" = "BSD" ]; then
				display --to LOG --type INFO FOUND_CMD "pkg-info" "${PKG_CMD}"
				display --to LOG --type INFO HASH_PKGMGR_MD5 "${PKGMGR_MD5_HASH}"
			fi
		fi
	fi
fi

RKHTMPVAR=0
test $CHECK -eq 1 && `check_test attributes` && RKHTMPVAR=1

if [ $RKHTMPVAR -eq 1 ]; then
	if [ "${OLD_ATTRUPD}" = "Disabled" ]; then
		display --to LOG --type INFO ATTRUPD_OLD_DISABLED
	elif [ "${OLD_ATTRUPD}" = "Nostatcmd" ]; then
		display --to LOG --type INFO ATTRUPD_OLD_NOSTATCMD
	else
		display --to LOG --type INFO ATTRUPD_OLD_OK
	fi
fi

if [ $PROP_UPDATE -eq 1 ]; then
	if ! `check_test attributes`; then
		display --to LOG --type INFO ATTRUPD_DISABLED
	elif [ -z "${STAT_CMD}" ]; then
		display --to LOG --type INFO ATTRUPD_NOSTATCMD
	else
		display --to LOG --type INFO ATTRUPD_OK
	fi
fi

if [ $CHECK -eq 1 -o $PROP_UPDATE -eq 1 ]; then
	display --to LOG --type INFO ENABLED_TESTS "${ENABLE_TESTS}"
	display --to LOG --type INFO DISABLED_TESTS "${DISABLE_TESTS}"
fi

if [ $UPDATE -eq 1 -o $VERSIONCHECK -eq 1 ]; then
	if [ $ROTATE_MIRRORS -eq 0 ]; then
		display --to LOG --type INFO CONFIG_NO_ROTATE_MIRRORS
	else
		display --to LOG --type INFO CONFIG_ROTATE_MIRRORS
	fi

	if [ $MIRRORS_MODE -eq 0 ]; then
		display --to LOG --type INFO CONFIG_MIRRORS_MODE0
	elif [ $MIRRORS_MODE -eq 1 ]; then
		display --to LOG --type INFO CONFIG_MIRRORS_MODE1
	else
		display --to LOG --type INFO CONFIG_MIRRORS_MODE2
	fi

	if [ $UPDATE -eq 1 ]; then
		if [ $UPDATE_MIRRORS -eq 0 ]; then
			display --to LOG --type INFO CONFIG_NO_UPDATE_MIRRORS
		else
			display --to LOG --type INFO CONFIG_UPDATE_MIRRORS
		fi
	fi
fi

if [ $CHECK -eq 1 ]; then
	test $VERBOSE_LOGGING -eq 0 && display --to LOG --type INFO CONFIG_NO_VL

	test -n "${RC_FILE}" && display --to LOG --type INFO CONFIG_LOCAL_RC_FILE "${RKHROOTDIR}${RC_FILE}"

	test -n "${RC_DIR}" && display --to LOG --type INFO CONFIG_LOCAL_RC_DIR "${RKHROOTDIR}${RC_DIR}"

	if [ -n "${KSYMS_FILE}" ]; then
		display --to LOG --type INFO KSYMS_FOUND "${KSYMS_FILE}"
	else
		display --to LOG --type INFO KSYMS_MISSING
	fi

	test $SHOW_SUMMARY -eq 0 && display --to LOG --type INFO CONFIG_NO_SHOW_SUMMARY


	#
	# To use syslog we must have the logger command present.
	#

	if [ -n "${USE_SYSLOG}" ]; then
		if [ "${USE_SYSLOG}" = "none" ]; then
			USE_SYSLOG=""
			display --to LOG --type INFO SYSLOG_DISABLED
		else
			LOGGER_CMD=`find_cmd logger`

			if [ -n "${LOGGER_CMD}" ]; then
				display --to LOG --type INFO SYSLOG_ENABLED "${USE_SYSLOG}"
			else
				USE_SYSLOG=""
				display --to LOG --type INFO SYSLOG_NO_LOGGER
			fi
		fi
	fi


	#
	# If the user wants to run the file properties checks, and the
	# rkhunter.dat file exists, then check the O/S info. If the
	# rkhunter.dat file does not exist, then this will be logged
	# later on.
	#

	if `check_test properties`; then
		if [ -s "${DB_PATH}/rkhunter.dat" ]; then
			#
			# We perform a simple check on some of the stored
			# O/S information, and compare it to the current
			# info. Basically we are just seeing if the system
			# has changed at all because it could affect the
			# file properties checks.
			#

			rkh_dat_get_os_info

			check_os_info
		fi
	fi
fi


######################################################################
#
# Start of program actions and checks
#
######################################################################


#
# We can now start to run the actions the user has requested on
# the command-line. We run the update type commands first before
# doing any full system check.
#


#
# The user wants to update the O/S and the file properties data.
#

test $PROP_UPDATE -eq 1 && do_prop_update


#
# The user wants to update the supplied RKH *.dat files.
#

test $UPDATE -eq 1 && do_update


#
# The user wants to check for the latest program version.
#

test $VERSIONCHECK -eq 1 && do_versioncheck


#
# The user wants to check the local system for anomalies.
#

test $CHECK -eq 1 && do_system_check

display --to LOG --type INFO --nl RKH_ENDDATE "`date`"


#
# If the user asked to see the logfile, then show it.
#

test $CATLOGFILE -eq 1 && cat ${RKHLOGFILE}


IFS=$ORIGIFS

exit $RET_CODE
