#!/bin/sh

#################################################################################
#
#   Lynis
# ------------------
#
# Copyright 2007-2009, Michael Boelen (michael@rootkit.nl), The Netherlands
# Web site: http://www.rootkit.nl
#
# Lynis 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 LICENSE file for usage of this software.
#
#################################################################################
#
# Ports and packages
#
#################################################################################
#
    InsertSection "Ports and packages"
    report "[Software]"
#
#################################################################################
#
    Display --indent 2 --text "- Searching package managers..."

    # Test        : PKGS-7302
    # Description : Query FreeBSD pkg_info
    if [ -x /usr/sbin/pkg_info ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PKGS-7302 --preqs-met ${PREQS_MET} --weight L --network NO --description "Query FreeBSD pkg_info"
    if [ ${SKIPTEST} -eq 0 ]; then    
	Display --indent 4 --text "- Searching pkg_info..." --result FOUND --color GREEN
	logtext "Result: Found pkg_info"
	logtext "Test: Querying pkg_info to get package list..."
	Display --indent 6 --text "- Querying pkg_info for installed packages..."
	logtext "Output:"; logtext "-----"
	SPACKAGES=`/usr/sbin/pkg_info | sort | tr -s ' ' | cut -d ' ' -f1 | sed -e 's/^\(.*\)-\([0-9].*\)$/\1,\2/g'`
	for J in ${SPACKAGES}; do
            sPKG_NAME=`echo ${J} | cut -d ',' -f1`
            sPKG_VERSION=`echo ${J} | cut -d ',' -f2`
	    logtext "Installed package: ${sPKG_NAME} (version: ${sPKG_VERSION})"
	    report "installed_package[]=${sPKG_NAME},${sPKG_VERSION},"
	done
    fi	    
#
#################################################################################
#
# Temporary disabled due false positives
# Packages like docbook, gcc, automake report multiple installed versions
#    # Test        : PKGS-7303
#    # Description : Query FreeBSD pkg_info
#    if [ -x /usr/sbin/pkg_info ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
#    Register --test-no PKGS-7303 --preqs-met ${PREQS_MET} --weight L --network NO --description "Query FreeBSD for double installed packages"
#    if [ ${SKIPTEST} -eq 0 ]; then    
#	SDOUBLEINSTALLED=`pkg_info | sort | sed -e 's/-[0-9].*$//' | uniq -c | grep -v '^[[:space:]]*1' | tr -s ' ' | cut -d ' ' -f3`
#	if [ "${SDOUBLEINSTALLED}" = "" ]; then
#	    Display --indent 6 --text "- Querying pkg_info for double installed packages..." --result OK --color GREEN	
#	    logtext "Ok, no packages show up twice or more in the package listing."
#	  else
#	    Display --indent 6 --text "- Querying pkg_info for double installed packages..." --result WARNING --color RED
#	    for J in ${SDOUBLEINSTALLED}; do
#	        ReportWarning ${TEST_NO} "M" "Found probably incorrect installed package (${J})"
#		logtext "This package ${J} is visible twice or more in the pkg_info listing."
#		ReportSuggestion ${TEST_NO} "(FreeBSD) run pkgdb -F and check this manually."
#	        ReportSuggestion ${TEST_NO} "(OpenBSD) check dependencies to see if one of the double "
#		logtext "installed packages is unneeded."
#		report "double_installed_package[]=${J}"
#	    done
#	fi
#      else
#        Display --indent 4 --text "- Searching pkg_info..." --result "NOT FOUND" --color WHITE
#	logtext "Result: pkg_info can NOT be found on this system"
#    fi    
#
#################################################################################
#
    # Test        : PKGS-7306
    # Description : Solaris packages
    if [ -x /usr/bin/pkginfo ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PKGS-7306 --os Solaris --preqs-met ${PREQS_MET} --weight L --network NO --description "Querying Solaris packages"
    if [ ${SKIPTEST} -eq 0 ]; then
	Display --indent 4 --text "- Searching pkginfo..." --result FOUND --color GREEN
	    logtext "Result: Found Solaris pkginfo"
	    logtext "Test: Querying pkginfo to get package list"
	    Display --indent 4 --text "- Querying pkginfo for installed packages..."
	    logtext "Output:"; logtext "-----"
	    # Strip SUNW from strings
	    SPACKAGES=`/usr/bin/pkginfo -i | tr -s ' ' | cut -d ' ' -f2 | sed "s#^SUNW##"`
	    for J in ${SPACKAGES}; do
	        logtext "Found package ${J}"
		report "installed_package[]=${J}"
	    done
      else
	logtext "Result: pkginfo can NOT be found on this system"
    fi
#
#
#################################################################################
#
    # Test        : PKGS-7308
    # Description : RPM package based systems
    if [ ! "${RPMBINARY}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PKGS-7308 --preqs-met ${PREQS_MET} --weight L --network NO --description "Checking package list with RPM"
    if [ ${SKIPTEST} -eq 0 ]; then
	Display --indent 4 --text "- Searching RPM package manager..." --result FOUND --color GREEN
	logtext "Result: Found rpm binary (${RPMBINARY})"
	logtext "Test: Querying 'rpm -qa' to get package list"
	Display --indent 6 --text "- Querying RPM package manager..."	    
	logtext "Output:"; logtext "--------"
	SPACKAGES=`${RPMBINARY} -qa | sort`
	for J in ${SPACKAGES}; do
	    logtext "Found package: ${J}"
	report "installed_package[]=${J}"
	done
      else
	logtext "Result: RPM binary NOT found on this system, test skipped"
    fi    
#
#################################################################################
#
    # Test        : PKGS-7345
    # Description : Debian package based systems (dpkg)
    if [ -x /usr/bin/dpkg ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PKGS-7345 --preqs-met ${PREQS_MET} --weight L --network NO --description "Querying dpkg"
    if [ ${SKIPTEST} -eq 0 ]; then
        Display --indent 4 --text "- Searching dpkg package manager..." --result FOUND --color GREEN
	logtext "Result: Found dpkg binary"
	logtext "Test: Querying dpkg -l to get package list"
	Display --indent 6 --text "- Querying package manager..."
	logtext "Output:"
	SPACKAGES=`dpkg -l 2>/dev/null | grep "^ii" | tr -s ' ' | tr ' ' '#' | sort`
	for J in ${SPACKAGES}; do
	    PACKAGE_NAME=`echo ${J} | cut -d '#' -f2`
	    PACKAGE_VERSION=`echo ${J} | cut -d '#' -f3`
	    logtext "Found package: ${PACKAGE_NAME} (version: ${PACKAGE_VERSION})"
	    report "installed_package[]=${PACKAGE_NAME},${PACKAGE_VERSION},"
	done
      else
	logtext "Result: dpkg can NOT be found on this system"
    fi    
#
#################################################################################
#
    # Test        : PKGS-7348
    # Description : Show unneeded distfiles if present
    Register --test-no PKGS-7348 --os FreeBSD --weight L --network NO --description "Check for old distfiles"
    if [ ${SKIPTEST} -eq 0 ]; then
        if [ -x /usr/local/sbin/portsclean ]; then
            FIND=`/usr/local/sbin/portsclean -n -DD | grep 'Delete' | wc -l | tr -d ' '`
	    if [ ${FIND} -eq 0 ]; then
    		Display --indent 2 --text "- Checking presence old distfiles..." --result OK --color GREEN
		logtext "Result: no unused distfiles found"
	      else
    	        Display --indent 2 --text "- Checking presence old distfiles..." --result WARNING --color YELLOW
		logtext "Result: found ${FIND} unused distfiles"
        	ReportSuggestion ${TEST_NO} "Unused distfiles found. Use portsclean to delete these files. For example: portsclean -DD."
            fi
          else
    	    Display --indent 2 --text "- Portsclean not installed" --result SUGGESTION --color YELLOW
    	    logtext "Result: Portsclean not installed"
	    ReportSuggestion ${TEST_NO} "Install package 'portsclean' to clean out old package versions"
	fi
    fi
#
#################################################################################
#
    # Test        : PKGS-7382
    # Description : Check for vulnerable FreeBSD packages
    Register --test-no PKGS-7382 --os FreeBSD --weight L --network NO --description "Check for vulnerable FreeBSD packages"
    if [ ${SKIPTEST} -eq 0 ]; then
        if [ -x /usr/local/sbin/portaudit ]; then
            FIND=`/usr/local/sbin/portaudit | grep 'problem(s) in your installed packages found' | grep -v '0 problem(s) in your installed packages found'`
            if [ "${FIND}" = "" ]; then
	        logtext "Result: Portaudit results are clean"
	      else
	        Display --indent 2 --text "- Checking portaudit to obtain vulnerabilities..." --result WARNING --color RED
	        logtext "Result: Portaudit found one or more installed packages which are vulnerable."
	        ReportWarning ${TEST_NO} "M" "Found one or more vulnerable packages."
	        ReportSuggestion ${TEST_NO} "Update your system with portupgrade or other tools"
	        logtext "List of vulnerable packages/version:"	    
	        for I in `/usr/local/sbin/portaudit | grep "Affected package" | cut -d ' ' -f3 | sort | uniq`; do
	            report "vulnerable_package[]=${I}"
	            logtext "Vulnerable package: ${I}"
		    # Decrease hardening points for every found vulnerable package
		    AddHP 1 2
	        done
            fi
          else
    	    Display --indent 2 --text "- Portaudit not installed" --result SUGGESTION --color YELLOW
	    logtext "Result: Portaudit not installed, can't perform vulnerability test."
	    ReportSuggestion "Install portaudit from the ports collection to query outdated (vulnerable) packages."
	fi
    fi
#
#################################################################################
#
    # Test        : PKGS-7384
    # Description : Search for YUM utils package
    if [ -x /usr/bin/yum ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PKGS-7384 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --description "Check for YUM utils package"
    if [ ${SKIPTEST} -eq 0 ]; then
        if [ -x /usr/bin/package-cleanup ]; then
	    logtext "Result: found YUM utils package (/usr/bin/package-cleanup)"
	    
	    # Check for duplicates
	    logtext "Test: Checking for duplicate packages"
	    FIND=`/usr/bin/package-cleanup -q --dupes > /dev/null; echo $?`
	    if [ "${FIND}" = "0" ]; then
	        logtext "Result: No duplicate packages found"
		Display --indent 2 --text "- Checking package database duplicates..." --result OK --color GREEN
	      else
	        logtext "Result: One or more duplicate packages found"
		Display --indent 2 --text "- Checking package database duplicates..." --result WARNING --color RED
		ReportWarning ${TEST_NO} "L" "Found one or more duplicate packages installed"
		ReportSuggestion ${TEST_NO} "Run package-cleanup to solve duplicate package problems"
	    fi

	    # Check for package database problems
	    logtext "Test: Checking for database problems"
            FIND=`/usr/bin/package-cleanup --problems > /dev/null; echo $?`
	    if [ "${FIND}" = "0" ]; then
	        logtext "Result: No package database problems found"
		Display --indent 2 --text "- Checking package database for problems..." --result OK --color GREEN
	      else
	        logtext "Result: One or more duplicate packages found"
		Display --indent 2 --text "- Checking package database for problems..." --result WARNING --color RED
		ReportWarning ${TEST_NO} "L" "Found one or more problems in the package database"
		ReportSuggestion ${TEST_NO} "Run package-cleanup to solve package problems"
	    fi
	  else
	    Display --indent 2 --text "- yum-utils package not installed" --result SUGGESTION --color YELLOW
	    logtext "Result: YUM utils package not found"
	    ReportSuggestion ${TEST_NO} "Install package 'yum-utils' for better consistency checking of the package database"
	fi
    fi
#
#################################################################################
#
    # Test        : PKGS-7386
    # Description : Search for YUM security package
    if [ -x /usr/bin/yum ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PKGS-7386 --preqs-met ${PREQS_MET} --os Linux --weight L --network NO --description "Check for YUM security package"
    if [ ${SKIPTEST} -eq 0 ]; then
        # Use yum-security package when possible (Fedora, RHEL, CentOS)
	logtext "Test: Determining if yum-security package installed"
	# Check if the option "list-sec" is available when retrieving help
	#FIND=`/usr/bin/yum -h | grep "list-sec" | wc -l | tr -s ' ' | tr -d ' '`
	FIND=`rpm -q yum-security`
	if [ ! "${FIND}" = "" ]; then
	    logtext "Result: found yum-security package"
	    logtext "Test: Checking for vulnerable packages"
            FIND2=`/usr/bin/yum list-sec security | awk '{ if($2=="security") print $3","$5 }'`
	    if [ "${FIND2}" = "" ]; then
	        logtext "Result: no vulnerable packages found"
	        Display --indent 6 --text "Result: no vulnerable packages found" --result OK --color GREEN
	      else
	        logtext "Result: found multiple vulnerable packages"
	        Display --indent 6 --text "Result: found multiple vulnerable packages" --result WARNING --color RED
	        for I in ${FIND2}; do
	            report "vulnerable_package[]=${I}"
	    	    logtext "Vulnerable package: ${I}"
		    AddHP 1 2
		done
    		ReportWarning ${TEST_NO} "M" "Found one or more vulnerable packages."
		ReportSuggestion ${TEST_NO} "Use 'yum --security update' to update your system"
	    fi
	  else
	    logtext "Result: yum-security package not found"
	    Display --indent 2 --text "- yum-security package not installed" --result SUGGESTION --color YELLOW
	    ReportSuggestion ${TEST_NO} "Install package yum-security if possible, to maintain security updates easier"
        fi
    fi
#
#################################################################################
#
    # Test        : PKGS-7388
    # Description : Check security repository in Debian/ubuntu apt sources.list file
    if [ "${LINUX_VERSION}" = "Debian" -o "${LINUX_VERSION}" = "Ubuntu" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PKGS-7388 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --description "Check security repository in Debian/ubuntu apt sources.list file"
    if [ $SKIPTEST -eq 0 ]; then
        if [ -f /etc/apt/sources.list -a ! "${OPTION_DEBIAN_SKIP_SECURITY_REPOSITORY}" = "yes" ]; then
            logtext "Searching for security.debian.org/ubuntu.com in /etc/apt/sources.list file"
            FIND=`egrep "security.debian.org|security.ubuntu.com" /etc/apt/sources.list | grep -v '#' | sed 's/ /!space!/g'`
            if [ ! "${FIND}" = "" ]; then
    	        Display --indent 2 --text "- Checking security repository in sources.list file... " --result OK --color GREEN
    		logtext "Result: Found security repository in /etc/apt/sources.list"
		for I in ${FIND}; do
		    I=`echo ${I} | sed 's/!space!/ /g'`
		    logtext "Output: ${I}"
		done
		AddHP 3 3
    	      else
	        Display --indent 2 --text "- Checking security repository in sources.list file... " --result WARNING --color RED
	        ReportWarning ${TEST_NO} "M" "Can't find security.debian.org/ubuntu.com in /etc/apt/sources.list."
		ReportSuggestion ${TEST_NO} "Check /etc/apt/sources.list for a security repository being used"
		AddHP 0 3
	    fi
	fi
    fi
#
#################################################################################
#
    # Test        : PKGS-7390
    # Description : Check Ubuntu database consistency
    if [ "${LINUX_VERSION}" = "Ubuntu" -a -x /usr/bin/apt-get ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PKGS-7390 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --description "Check Ubuntu database consistency"
    if [ ${SKIPTEST} -eq 0 ]; then
	logtext "Test: Package database consistency by running apt-get check"
	FIND=`/usr/bin/apt-get -q=2 check; echo $?`
	if [ "${FIND}" = "0" ]; then
	    Display --indent 2 --text "- Checking APT package database..." --result OK --color GREEN
	    logtext "Result: package database seems to be consistent."
	  else
	    logtext "Result: package database is most likely NOT consistent"
	    Display --indent 2 --text "- Checking APT package database..." --result WARNING --color RED
	    ReportWarning ${TEST_NO} "M" "apt-get check returned a non successful exit code."
	    ReportSuggestion ${TEST_NO} "Run apt-get to perform a manual package database consistency check."
	fi
    fi
#
#################################################################################
#
    # Test        : PKGS-7392
    # Description : Check Ubuntu database consistency
    if [ "${LINUX_VERSION}" = "Ubuntu" -a -x /usr/bin/apt-get ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PKGS-7392 --os Linux --preqs-met ${PREQS_MET} --weight L --network YES --description "Check for Ubuntu security updates"
    if [ ${SKIPTEST} -eq 0 ]; then
	# Update the repository, outdated repositories don't give much information
	logtext "Action: updating repository with apt-get"
        /usr/bin/apt-get -q=2 update
	logtext "Result: apt-get finished"
	# Show packages which would be upgraded and match 'security' in repository name
	FIND=`/usr/bin/apt-get --dry-run --show-upgraded upgrade | grep '-security' | grep "^Inst" | cut -d ' ' -f2 | sort | uniq`
	if [ ! "${FIND}" = "" ]; then
	    Display --indent 2 --text "- Checking vulnerable packages..." --result WARNING --color RED
	    for I in ${FIND}; do
		logtext "Found vulnerable package: ${I}"
	        report "vulnerable_package[]=${I}"
		# For every vulnerable package, decrease total of hardening points
		AddHP 1 2
	    done
    	    ReportWarning ${TEST_NO} "M" "Found one or more vulnerable packages."
	    ReportSuggestion ${TEST_NO} "Update your system with apt-get update, apt-get upgrade, apt-get dist-upgrade and/or unattended-upgrades"
	  else
	    Display --indent 2 --text "- Checking vulnerable packages..." --result OK --color GREEN
	fi
    fi
#
#################################################################################
#
# check for yum-changelog

wait_for_keypress

#
#================================================================================
# Lynis - Copyright 2007-2009, Michael Boelen - www.rootkit.nl - The Netherlands
