#!/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.
#
#################################################################################
#
# Category: Boot and services
#
#################################################################################
#
    InsertSection "Boot and services"

    Display --indent 2 --text "- Checking boot loaders"

    # Test        : BOOT-5121
    # Description : Check for GRUB boot loader
    Register --test-no BOOT-5121 --weight L --network NO --description "Check for GRUB boot loader presence"
    if [ ${SKIPTEST} -eq 0 ]; then
        FOUND=0
        logtext "Test: Checking for presence GRUB conf file (/boot/grub/grub.conf or /boot/grub/menu.lst)..."
	if [ -f /boot/grub/grub.conf -o -f /boot/grub/menu.lst ]; then
	    Display --indent 4 --text "- Checking presence GRUB... " --result "OK" --color GREEN
	    if [ -f /boot/grub/grub.conf ]; then GRUBCONFFILE="/boot/grub/grub.conf"; else GRUBCONFFILE="/boot/grub/menu.lst"; fi
	    logtext "Found file ${GRUBCONFFILE}, proceeding with tests."
	    FIND=`cat ${GRUBCONFFILE} | grep 'password --md5' | grep -v '^#'`
	    if [ "${FIND}" = "" ]; then
		FOUND=1
		Display --indent 6 --text "- Checking for password protection..." --result WARNING --color RED
		logtext "Result: Didn't find MD5 hashed password line in GRUB boot file!"
	        logtext "Risk: switching to single user mode due editing current menu items or bypassing them."
	        logtext "Suggestion: run grub-md5-crypt and create a hashed password. After"
	        logtext "that, add a line below the line saying timeout=<value>:"
	        logtext "password --md5 <password hash>"
	        logtext "Do NOT use a plaintext password, since the grub.conf or menu.lst"
	        logtext "file is most likely to be world readable!"
	        logtext "Suggestion: If an unsecured OS like DOS is used, add 'lock' below that entry and"
	        logtext "setup a password with the password option, to prevent direct system"
	        logtext "access."
		ReportWarning ${TEST_NO} "M" "No password set on GRUB bootloader"	
	        report "warning[]=GRUB configuration is not protected with a password"
	      else
	        Display --indent 6 --text "- Checking for password protection..." --result OK --color GREEN
	        logtext "GRUB has password protection."
	    fi
        fi

	# GRUB2 configuration file
	if [ -f /boot/grub/grub.cfg ]; then
	    FOUND=1
	    Display --indent 4 --text "- Checking presence GRUB... " --result "OK" --color GREEN	
	    logtext "Result: found GRUB2 configuration file (/boot/grub/grub.cfg)"
	    # YYY password check, when documentation of GRUB2 project is improved
	    # YYY Add check permission check (600)
	fi
	
	if [ ${FOUND} -eq 0 ]; then
	    Display --indent 4 --text "- Checking presence GRUB... " --result "NOT FOUND" --color WHITE
    	    logtext "Result: no GRUB configuration file found."
	fi    
    fi
#
#################################################################################
#
    # Test        : BOOT-5139
    # Description : Check for LILO boot loader
    Register --test-no BOOT-5139 --weight L --network NO --description "Check for LILO boot loader presence"
    if [ ${SKIPTEST} -eq 0 ]; then
        logtext "Test: checking for presence LILO configuration file..."
	if [ -f /etc/lilo.conf ]; then
	    Display --indent 4 --text "- Checking presence LILO... " --result "OK" --color GREEN
	    logtext "Checking password option LILO..."
	    FIND=`cat /etc/lilo.conf | grep 'password='`
	    if [ "${FIND}" = "" ]; then
	        Display --indent 6 --text "- Password option presence " --result "WARNING" --color RED
	        logtext "Result: no password set for LILO. Bootloader is unprotected to"
	        logtext "dropping to single user mode or unauthorized access to devices/data."
    	        logtext "Suggestion: Add a password to LILO, by adding a line to the lilo.conf file,"
	        logtext "above the first line saying 'image=<name>': password=<password>"
	        report "warning[]=LILO configuration is not protected with a password"
		ReportWarning ${TEST_NO} "M" "No password set on LILO bootloader"
	      else
	        Display --indent 6 --text "- Password option presence " --result "OK" --color GREEN
	        logtext "Result: LILO password option set"
	    fi
	    #YYY (making /etc/lilo.conf immutable is a good idea, chattr +i /etc/lilo.conf)
          else
            Display --indent 4 --text "- Checking presence LILO... " --result "NOT FOUND" --color WHITE
    	    logtext "Result: LILO configuration file not found."
        fi
    fi
#
#################################################################################
#
    # Test        : BOOT-5155
    # Description : Check for YABOOT boot loader
    Register --test-no BOOT-5155 --weight L --network NO --description "Check for YABOOT boot loader configuration file"
    if [ -f /etc/yaboot.conf ]; then
        logtext "Result: Found YABOOT configuration file (/etc/yaboot.conf)"
        Display --indent 4 --text "- Checking presence YABOOT..." --result "OK" --color GREEN
	#YYY add permission check
      else
        Display --indent 4 --text "- Checking presence YABOOT..." --result "NOT FOUND" --color WHITE
        logtext "Result: no YABOOT configuration file found."
    fi
#
#################################################################################
#
    # Test        : BOOT-5159
    # Description : Check for OpenBSD boot loader
    # More info   : only OpenBSD && i386 platform
    Register --test-no BOOT-5159 --os OpenBSD --platform i386 --weight L --network NO --description "Check for OpenBSD i386 boot loader presence"
    if [ ${SKIPTEST} -eq 0 ]; then
        if [ -f /etc/boot.conf ]; then
    	    Display --indent 2 --text "- Checking /etc/boot.conf..." --result "FOUND" --color GREEN
            FIND=`grep '^boot' /etc/boot.conf`
	    if [ "${FIND}" = "" ]; then
		Display --indent 4 --text "- Checking boot option..." --result WARNING --color RED
		logtext "Suggestion: add 'boot' to the /etc/boot.conf file to disable the default 5 seconds"
    	        logtext "waiting time, to disallow booting into single user mode."
		report "warning[]=System can be booted into single user mode without password"
	      else
		Display --indent 4 --text "- Checking boot option..." --result OK --color GREEN
		logtext "Ok, boot option is enabled."	
	    fi
	  else
    	    Display --indent 2 --text "- Checking /etc/boot.conf..." --result "NOT FOUND" --color YELLOW
	    logtext "Result: no /etc/boot.conf found. When using the default boot loader, physical"
	    logtext "access to the server can be used to possibly enter single user mode."
	    logtext "Suggestion: add 'boot' to the /etc/boot.conf file to disable the default 5 seconds"
	    logtext "waiting time."
	fi
    fi
#
#################################################################################
#
    # Test        : BOOT-5165
    # Description : Check for FreeBSD boot services
    Register --test-no BOOT-5165 --os FreeBSD --weight L --network NO --description "Check for FreeBSD boot services"
    if [ ${SKIPTEST} -eq 0 ]; then
	# FreeBSD (Read /etc/rc.conf file for enabled services)
        logtext "Searching for services at startup (rc.conf)..."
        FIND=`cat /etc/rc.conf | grep '_enable="YES"' | grep -v '^#' | sort | awk -F= '{ print $1 }' | sed 's/_enable//'`
        N=0	
	for I in ${FIND}; do	
            logtext "Found service (rc.conf): ${I}"
	    report "boottask[]=${I}"
            N=$(( $N + 1 ))
        done
        Display --indent 2 --text "- Checking services at startup (rc.conf)..." --result "DONE" --color GREEN
        Display --indent 6 --text "Result: found $N services/options set"
        logtext "Found $N services/options to run at startup"
    fi
#
#################################################################################
#
    # Test        : BOOT-5177
    # Description : Check for Linux boot services (Red Hat style)
    if [ ! "${CHKCONFIGBINARY}" = "" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no BOOT-5177 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --description "Check for Linux boot services (Red Hat style)"
    if [ ${SKIPTEST} -eq 0 ]; then
	# Linux (use only chkconfig for now)
        logtext "Searching for services at startup (chkconfig, runlevel 3 and 5)... "
        FIND=`${CHKCONFIGBINARY} --list | egrep '3:on|5:on' | awk '{ print $1 }'`
        N=0
        for I in ${FIND}; do
            logtext "Found service (at boot, runlevel 3 or 5): ${I}"
            N=$(( $N + 1 ))
        done
        logtext "Run chkconfig --list to see all services and disable unneeded services"
        Display --indent 2 --text "- Check services at startup (chkconfig)... " --result "DONE" --color GREEN
        Display --indent 8 --text "Result: found $N services"
    	logtext "Found $N services"
    fi
#
#################################################################################
#
    # Test        : BOOT-5180
    # Description : Check for Linux boot services (Debian style)
    if [ "${LINUX_VERSION}" = "Debian" -o "${LINUX_VERSION}" = "Ubuntu" ]; then PREQS_MET="YES"; else PREQS_MET="NO"; fi
    Register --test-no BOOT-5180 --os Linux --preqs-met ${PREQS_MET} --weight L --network NO --description "Check for Linux boot services (Debian style)"
    if [ ${SKIPTEST} -eq 0 ]; then
        # YYY runlevel check
	sRUNLEVEL=`runlevel | grep "N 2"`
	if [ ! "${sRUNLEVEL}" = "" ]; then
            FIND=`find /etc/rc2.d -type l -print | cut -d '/' -f4 | sed "s/S[0-9][0-9]//g"`
    	    if [ ! "${FIND}" = "" ]; then
        	N=0
	        for I in ${FIND}; do
    	            logtext "Found service (at boot, runlevel 2): ${I}"
        	    N=$(( $N + 1 ))
	        done
    	        Display --indent 2 --text "- Check services at startup (rc2.d)... " --result "DONE" --color WHITE
        	Display --indent 8 --text "Result: found $N services"
    		logtext "Found $N services"
	    fi
	fi
    fi
#
#################################################################################
#
    # Test        : BOOT-xxxx
    # Description : Check for SILO boot loader
#
#################################################################################
#
    # Test        : BOOT-5184
    # Description : Check world writable startup scripts
    Register --test-no BOOT-5184 --os Linux --weight L --network NO --description "Check for Linux boot services (Debian style)"
    if [ ${SKIPTEST} -eq 0 ]; then
	logtext "Result: Checking /etc/init.d scripts"
        if [ -d /etc/init.d ]; then
	    FILE=`find /etc/init.d -type f -print`
	    for I in ${FIND}; do
	        IsWorldWritable ${I}
		if [ "${FileIsWorldWritable}" = "TRUE" ]; then
		    ReportWarning ${TEST_NO} "H" "Found writable startup script ${I}"
		fi
	    done
	fi

        if [ -d /etc/rc.d ]; then
	    logtext "Test: Checking /etc/rc.d scripts"
	    FILE=`find /etc/rc.d -type f -print`
	    for I in ${FIND}; do
	        IsWorldWritable ${I}
		if [ "${FileIsWorldWritable}" = "TRUE" ]; then
		    ReportWarning ${TEST_NO} "H" "Found writable startup script ${I}"
		fi
	    done
	fi


        if [ -d /etc/rcS.d ]; then
	    logtext "Test: Checking /etc/rc.d scripts"
	    FILE=`find /etc/rcS.d -type f -print`
	    for I in ${FIND}; do
	        IsWorldWritable ${I}
		if [ "${FileIsWorldWritable}" = "TRUE" ]; then
		    ReportWarning ${TEST_NO} "H" "Found writable startup script ${I}"
		fi
	    done
	fi

	# /etc/rc[0-6].d
	for NO in 0 1 2 3 4 5 6; do
	    logtext "Test: Checking /etc/rc${NO}.d scripts"
	    if [ -d /etc/rc${NO}.d ]; then
		FILE=`find /etc/rc${NO}.d -type f -print`
		for I in ${FIND}; do
		    IsWorldWritable ${I}
		    if [ "${FileIsWorldWritable}" = "TRUE" ]; then
		        ReportWarning ${TEST_NO} "H" "Found writable startup script ${I}"
		    fi
	        done
	    fi
	done
	
	# Other files
	CHECKFILES="/etc/rc /etc/rc.local /etc/rc.d/rc.sysinit"
	for I in ${CHECKFILES}; do
	    if [ -f ${I} ]; then
		logtext "Test: Checking ${I} file"
	        IsWorldWritable ${I}
	        if [ "${FileIsWorldWritable}" = "TRUE" ]; then
	            ReportWarning ${TEST_NO} "H" "Found writable startup script ${I}"
	        fi
	    fi
	done
    fi
#
#################################################################################
#

wait_for_keypress

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