#!/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..."

    # pkg_info based systems, like FreeBSD

    counttests
    
    logtext "Searching pkg_info binary"
    if [ -x /usr/sbin/pkg_info ]; then        
	Display --indent 4 --text "- Searching pkg_info..." --result FOUND --color GREEN
	    counttests
	    logtext "Found pkg_info"
	    logtext "Querying pkg_info to get package list"
	    Display --indent 4 --text "- Querying pkg_info for installed packages..."
	    logtext "Output:"; logtext "-----"
	    SPACKAGES=`pkg_info | tr -s ' ' | cut -d ' ' -f1`
	    for J in ${SPACKAGES}; do
	        logtext "Found package ${J}"
		report "installed_package[]=${J}"
	    done
	    logtextbreak
	    counttests
	    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 4 --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 4 --text "- Querying pkg_info for double installed packages..." --result WARNING --color RED
	      	for J in ${SDOUBLEINSTALLED}; do
	    	    logtext "Warning: 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    
    logtextbreak

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

# Solaris

    if [ "${OS}" = "SunOS" -a -f /usr/bin/pkginfo ]; then
	Display --indent 4 --text "- Searching pkginfo..." --result FOUND --color GREEN
	    counttests
	    logtext "Found Solaris pkginfo"
	    logtext "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
	    logtextbreak
      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
    logtextbreak
#

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

# RPM based systems

    counttests
    logtext "Searching rpm binary"
    if [ ! "${RPMBINARY}" = "" ]; then
	Display --indent 4 --text "- Searching RPM package manager..." --result FOUND --color GREEN
	    logtext "Found rpm binary (${RPMBINARY})"
	    logtext "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
	Display --indent 4 --text "- Searching RPM package manager..." --result "NOT FOUND" --color WHITE
	logtext "Result: rpm can NOT be found on this system"
    fi    
    logtextbreak

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

# Debian based systems (dpkg)

    logtext "Searching dpkg binary"
    if [ -x /usr/bin/dpkg ]; then
        counttests
            Display --indent 4 --text "- Searching dpkg package manager..." --result FOUND --color GREEN
	    logtext "Found dpkg binary"
	    logtext "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    

logtextbreak

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

# Test: show unneeded distfiles is present
# Reason: these files can be old (vulnerable) versions of programs, which are not needed
#         anymore and should be deleted.

if [ "${OS}" = "FreeBSD" ]; then
    counttests
    logtext "Checking presence of old distfiles..."
    if [ -x /usr/local/sbin/portsclean ]; then
        FIND=`portsclean -n -DD | grep 'Delete' | wc -l | tr -s ' ' | 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 RED
            logtext "Suggestion: ${FIND} unused distfiles found. Use portsclean to delete"
	    logtext "these files. For example: portsclean -DD."
         fi
      else
         logtext "Portsclean not installed"
	 logtext "Suggestion: install portsclean to clean out old package versions"
    fi
    logtextbreak
fi

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

if [ "${OS}" = "FreeBSD" ]; then
    counttests
    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 "Portaudit results are clean"
	    logtext "Status: OK"
          else
	    Display --indent 2 --text "- Checking portaudit to obtain vulnerabilities..." --result WARNING --color RED
	    logtext "Warning: Portaudit found one or more installed packages which are vulnerable."
	    logtext "Suggestion: upgrade affected packages"
	    logtext "Status: BAD"
	    logtext "Impact: HIGH"
	    logtext "List of vulnerable packages/version:"	    
	    for I in `portaudit | grep "Affected package" | cut -d ' ' -f3`; do
	      report "vulnerable_package[]=${I}"
	      logtext "Vulnerable package: ${I}"
	    done
        fi
      else
	Display --indent 2 --text "- Portaudit not installed" --result SUGGESTION --color YELLOW
	logtext "Portaudit not installed, can't perform vulnerability test."
	logtext "Suggestion: install portaudit from the ports collection."
    fi
    logtextbreak
fi

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

# Test: check security repository in Debian apt

if [ -f /etc/apt/sources.list -a ! "${OPTION_DEBIAN_SKIP_SECURITY_REPOSITORY}" = "yes" ]; then
    counttests
    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
	logtext "Warning: can't find security.debian.org/ubuntu.com in /etc/apt/sources.list."
	logtext "Suggestion: Check this file and see if a security repository is used"
    fi
    logtextbreak
fi

# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

    # Ubuntu apt-get checks
    if [ "${LINUX_VERSION}" = "Ubuntu" -a -x /usr/bin/apt-get ]; then

        counttests
	logtext "Test: Package database consistency"
	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
	    logtext "Warning: apt-get check returned a non successful exit code."
	    logtext "Suggestion: run apt-get check manually."
	fi
	logtextbreak

	# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=

        counttests

	# Update the repository, outdated repository won't give much information
        /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
	  else
	    Display --indent 2 --text "- Checking vulnerable packages..." --result OK --color GREEN
	fi
	logtextbreak
    fi
    
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

wait_for_keypress


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