#!/bin/sh

#################################################################################
#
#   Lynis
# ------------------
#
# Copyright 2007-2008, 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 "Found package ${sPKG_NAME} (version: ${sPKG_VERSION})"
	    report "installed_package[]=${sPKG_NAME},${sPKG_VERSION},"
	done
    fi	    
#
#################################################################################
#
    # 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."
		logtext "Suggestion: (FreeBSD) run pkgdb -F and check this manually."
	        logtext "Suggestion: (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 SunOS --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
	Display --indent 4 --text "- Searching Solaris package manager..." --result "NOT FOUND" --color WHITE
	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        : PKG-7345
    # Description : Debian package based systems (dpkg)
    if [ -x /usr/bin/dpkg ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PKG-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 | 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
	Display --indent 4 --text "- Searching dpkg package manager... " --result "NOT FOUND" --color WHITE
	logtext "Result: dpkg can NOT be found on this system"
    fi    
#
#################################################################################
#
    # Test        : PKGS-7348
    # Description : Show unneeded distfiles if present
    if [ -x /usr/local/sbin/portsclean ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PKGS-7348 --os FreeBSD --weight L --network NO --description "Check for old distfiles"
    if [ ${SKIPTEST} -eq 0 ]; then
        FIND=`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
          else
            Display --indent 2 --text "- Checking presence old distfiles..." --result WARNING --color YELLOW
	    logtext "Result: found ${FIND} unused distfiles"
            ReportSuggestion ${TEST_NO} "Suggestion: unused distfiles found. Use portsclean to delete these files. For example: portsclean -DD."
         fi
      else
         logtext "Portsclean not installed"
	 ReportSuggestion ${TEST_NO} "Suggestion: install package 'portsclean' to clean out old package versions"
    fi
#
#################################################################################
#
    # Test        : PKGS-7382
    # Description : Check for vulnerable FreeBSD packages
    if [ -x /usr/local/sbin/portaudit ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no PKGS-7382 --preqs-met ${PREQS_MET} --os FreeBSD --weight L --network NO --description "Check for vulnerable FreeBSD packages"
    if [ ${SKIPTEST} -eq 0 ]; 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}"
	    done
        fi
      else
        if [ "${OS}" = "FreeBSD" ]; then
    	    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
	    FIND=`/usr/bin/package-cleanup -q --dupes; 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
            FIND=`/usr/bin/package-cleanup --problems > /dev/null; echo $?`
	    if [ "${FIND}" = "0" ]; then
	        logtext "Result: No duplicate packages 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 ' '`
	if [ "${FIND}" = "1" ]; then
	    logtext "Result: found yum-security package"
	    logtext "Test: Checking for vulnerable packages"
            FIND=`/usr/bin/yum list-sec security | awk '{ if($2=="security") print $3","$5 }'`
	    if [ "${FIND}" = "" ]; then
	        Display --indent 6 --text "Result: no vulnerable packages found" --result OK --color GREEN
	      else
	        Display --indent 6 --text "Result: found multiple vulnerable packages" --result WARNING --color RED
	        for I in ${FIND}; do
	            report "vulnerable_package[]=${I}"
	    	    logtext "Vulnerable package: ${I}"
		    ReportSuggestion ${TEST_NO} "Use 'yum --security update' to update your system"
		done
    		ReportWarning ${TEST_NO} "M" "Found one or more vulnerable packages."
	    fi
	  else
	    Display --indent 2 --text "- yum-security package not installed" --result SUGGESTION --color YELLOW
	    logtext "Result: yum-security package not found"
	    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 '#'`
            if [ ! "${FIND}" = "" ]; then
    	        Display --indent 2 --text "- Checking security repository in sources.list file... " --result OK --color GREEN
    		logtext "Found ${FIND} in /etc/apt/sources.list"
    		logtext "Status: OK"
    	      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"
	    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 "Package database seems to be consistent."
	  else
	    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 check manually."
	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"
        /usr/bin/apt-get -q=2 update

	# 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}"
	    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
#
#################################################################################
#

wait_for_keypress

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