#!/bin/bash
# Atomicorp API: Agent
# Copyright Atomicorp 2022
# All Rights reserved

VERSION=0.5
HOSTNAME=$(hostname)
AGENT_NAME=$(sed '1q;d' /var/ossec/queue/ossec/.agent_info)
AGENT_ID=$(sed '3q;d' /var/ossec/queue/ossec/.agent_info)


# NOTES
	# libopenscap8 - u20 scap



###########################
# Logging
###########################
LOG_FILE="/var/ossec/logs/atomicorp-api.log"



###########################
#functions
###########################
function log_event () {
        MSG=$1
        echo "`date "+%b %d %H:%M:%S"` ${HOSTNAME} atomicorp-api: ${MSG}" >> ${LOG_FILE}
	logger -t atomicorp-api "${MSG} Agent: ${AGENT_NAME} ID: ${AGENT_ID} scanid:${SCANID}"
}

function detect_dist () {
	#log_event "detect_dist: start"
	if [ -f /etc/redhat-release ]; then
		RELEASE=/etc/redhat-release
	elif [ -f /etc/os-release ]; then
		RELEASE=/etc/os-release
	elif [ -f /etc/openvz-release ]; then
		RELEASE=/etc/openvz-release
	elif [ -f /etc/SuSE-release ]; then
		RELEASE=/etc/SuSE-release
	elif [ -f /etc/os-release ]; then
		RELEASE=/etc/os-release
	elif [ -f /etc/lsb-release ]; then
		RELEASE=/etc/lsb-release
	elif [ -f /etc/debian_version ]; then
		RELEASE=/etc/debian_version
	elif [ -f /etc/openvz-release ]; then
		RELEASE=/etc/openvz-release
	elif [ -f /etc/virtuozzo-release ]; then
		RELEASE=/etc/virtuozzo-release
	elif [[ $OSTYPE == "aix"* ]]; then
		PKG=aix
	else
		echo "Error: unable to identify operating system"
		exit 1
	fi

	if [[ $OSTYPE == "aix"* ]]; then
		PKG=aix
	elif egrep -q "(release 5)" $RELEASE ; then
		DIST="el5"
		DIR=centos/5
		PKG=rpm
	elif egrep -q "(release 6|release 2012)" $RELEASE ; then
		DIST="el6"
		DIR=centos/6
		PKG=rpm
	elif egrep -q "(release 7|release 2014)" $RELEASE ; then
		DIST="el7"
		DIR=centos/7
		PKG=rpm
	elif egrep -q "(release 8)" $RELEASE ; then
		DIST="el8"
		DIR=centos/8
		PKG=rpm
	elif egrep -q "Red Hat Enterprise Linux.* 7" $RELEASE ; then
		DIST="el7"
		DIR=redhat/7
		PKG=rpm
	elif egrep -q "Red Hat Enterprise Linux.* 8" $RELEASE ; then
		DIST="el8"
		DIR=redhat/8
		PKG=rpm
	elif egrep -q "(Amazon Linux 2)" $RELEASE; then
		DIST="amazon"
		DIR=amazon/2
		PKG=rpm
	elif egrep -q "(Amazon Linux AMI|Amazon)" $RELEASE ; then
		DIST="el6"
		DIR=centos/6
		PKG=rpm
	elif egrep -q "wheezy" $RELEASE ; then
		DIST="debian"
		DIR="wheezy"
		PKG=deb
		ARCH=$(dpkg --print-architecture)
	elif egrep -q "jessie" $RELEASE ; then
		DIST="debian"
		DIR="jessie"
		PKG=deb
		ARCH=$(dpkg --print-architecture)
	elif egrep -q "stretch" $RELEASE ; then
		DIST="debian"
		DIR="stretch"
		PKG=deb
		ARCH=$(dpkg --print-architecture)
	elif egrep -q "lucid" $RELEASE ; then
		DIST="debian"
		DIR="lucid"
		PKG=deb
		ARCH=$(dpkg --print-architecture)
	elif egrep -q "precise" $RELEASE ; then
		DIST="debian"
		DIR="precise"
		PKG=deb
		ARCH=$(dpkg --print-architecture)
	elif egrep -q "Raring Ringtail" $RELEASE ; then
		DIST="debian"
		DIR="raring"
		PKG=deb
		ARCH=$(dpkg --print-architecture)
	elif egrep -q "Trusty Tahr" $RELEASE ; then
		DIST="ubuntu"
		DIR="trusty"
		PKG=deb
		ARCH=$(dpkg --print-architecture)
	elif egrep -q "Xenial" $RELEASE ; then
		DIST="ubuntu"
		DIR="xenial"
		PKG=deb
		ARCH=$(dpkg --print-architecture)
	elif egrep -q "Bionic" $RELEASE ; then
		DIST="ubuntu"
		DIR="bionic"
		PKG=deb
		ARCH=$(dpkg --print-architecture)
	elif egrep -q "Focal Fossa" $RELEASE; then
		DIST="ubuntu"
		DIR="focal"
		PKG=deb
		ARCH=$(dpkg --print-architecture)
	elif egrep -q "buster" $RELEASE ; then
		DIST="debian"
		DIR="buster"
		PKG=deb
		ARCH=$(dpkg --print-architecture)
	elif egrep -q "bullseye" $RELEASE ; then
		DIST="debian"
		DIR="bullseye"
		PKG=deb
		ARCH=$(dpkg --print-architecture)
	elif egrep -q "openSUSE Leap" $RELEASE; then
		DIST="suse15"
		DIR="opensuse/15.1"
		PKG=zypper

	else
		echo "Error: Unable to determine distribution type. Please send the contents of $RELEASE to support@atomicorp.com"
		exit 1
	fi

	#log_event "detect_dist: DIST:($DIST) DIR:($DIR) PKG:($PKG)"


}

function install_package () {

	PACKAGE=$1
	log_event "install: ${PACKAGE} install_package start"
	if [[ $PKG == "rpm" ]]; then
		yum -y install ${PACKAGE}
		if [ $? -eq 0 ]; then
			log_event "install: ${PACKAGE} install_package:success"
		else
			log_event "install: ${PACKAGE} install_package:failure"
			return 1
		fi
		
	elif [[ $PKG == "deb" ]]; then
		# Update data
		apt -y update
		if [ $? -ne 0 ]; then
			log_event "install: ${PACKAGE} install_package:apt update failed"
			return 1
		fi

		# Install
		DEBIAN_FRONTEND=noninteractive  apt install -o  Dpkg::Options::="--force-confmiss" -y ${PACKAGE}
		if [ $? -eq 0 ]; then
			log_event "install: ${PACKAGE} install_package:success"
		else
			log_event "install: ${PACKAGE} install_package:failure"
			return 1
		fi
	else
		echo "ERROR: $DIST Not supported"
		exit 1
	fi 
}

function update_package() {
	if [[ $PKG == "rpm" ]]; then
		yum -y upgrade ${PACKAGE}
		RETVAL=$?
	elif [[ $PKG == "deb" ]]; then
		apt update
		DEBIAN_FRONTEND=noninteractive  apt upgrade -o  Dpkg::Options::="--force-confmiss" -y ${PACKAGE}
		RETVAL=$?
	else
		echo "ERROR: $DIST Not supported"
		exit 1
	fi

	if [ $RETVAL -eq 0 ]; then
		log_event "upgrade: ${PACKAGE} upgrade_package:success"
	else
		log_event "upgrade: ${PACKAGE} upgrade_package:failure"
	fi
}

function update_clamav_signatures() {
	if [ ! -d /var/lib/clamav ]; then
		mkdir -p /var/lib/clamav
	fi
	/usr/bin/freshclam 
	RETVAL=$?
	if [ $RETVAL -eq 0 ]; then
		log_event "upgrade: clamav signature update: success"
	else
		log_event "upgrade: clamav signature update: failure"
	fi

}
function init_clamav() {
	if [[ $PKG == "rpm" ]]; then
		# EPEL version
		if [ -f /etc/clamd.d/scan.conf ]; then
			cp /var/ossec/modules/clamav/template/clamd.conf.template /etc/clamd.d/scan.conf
			EPEL=1
			sed -i "s/^LogFile/#LogFile/g" /etc/clamd.d/scan.conf
			sed -i "s/^PidFile/#PidFile/g" /etc/clamd.d/scan.conf
			# This only needs the TCP settings for the default to work
		elif [ -f /etc/clamd.conf ]; then
			cp /var/ossec/modules/clamav/template/clamd.conf.template /etc/clamd.conf
			cp -f /var/ossec/modules/clamav/template/freshclam.conf.template /etc/freshclam.conf
		fi

		update_clamav_signatures
		# TODO: real-time 
		# /var/ossec/modules/clamav/clam-module.sh

		if [[ $EPEL -eq 1 ]]; then
			systemctl enable clamd@scan
			systemctl start clamd@scan
		else
			systemctl enable clamav-daemon
			systemctl start clamav-daemon
		fi
		
	elif [[ $PKG == "deb" ]]; then
		cp -f /var/ossec/modules/clamav/template/clamd.conf.template /etc/clamav/clamd.conf
		cp -f /var/ossec/modules/clamav/template/freshclam.conf.template /etc/freshclam.conf /etc/clamav/freshclam.conf
		update_clamav_signatures
		systemctl enable clamav-daemon
		systemctl start clamav-daemon

	else
		log_event "init_clamav: platform not supported "
		exit 1
	fi
}


function install_clamav() {
	# This isnt super important since  awp-agent has a Requires on clam now
	if [[ $PKG == "rpm" ]]; then
		if [[ "$DIST" != "amazon" ]]; then
			install_package epel-release  
			if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
				exit 1
			fi
			
		fi
		install_package "clamav clamd clamav-update"
		if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
			exit 1
		fi
		
	elif [[ $PKG == "deb" ]]; then
		install_package clamav-daemon
	else
		log_event "install: ${PACKAGE} platform not supported ($PKG)"
		exit 1
	fi

}


function init_module () {
	MODULE=$1
	log_event "init: ${MODULE} start"

	if [[ "${MODULE}" == "auditd" ]]; then
		echo
	fi

	if [[ "${MODULE}" == "clamav" ]]; then
		init_clamav
	fi

	if [[ "${MODULE}" == "fapolicyd" ]]; then
		init_fapolicyd
	fi
	log_event "init: ${MODULE} end"
}

function detect_webserver() {
	WEBSERVER=none
	if [[ $PKG == "rpm" ]]; then
		# Stub	
		if rpm -q httpd; then
			WEBSERVER=apache
		fi
		# TODO: is it running

	
	elif [[ $PKG == "deb" ]]; then
	
		# Stub
		if dpkg -s apache2 >/dev/null ; then
			WEBSERVER=apache
		fi
		# TODO: is it running
	fi


}

#function download_waf_rules() {
#	
#}
#
#function init_waf() {
#
#	# Set top level config
#
#}

function install_waf() {

	# Detect webserver type
	detect_webserver

	if  [[ $WEBSERVER == "none" ]]; then
		log_event "install: ${PACKAGE} webserver not detected"
		exit
	else
		log_event "install: ${PACKAGE} ${WEBSERVER} detected"
	fi


	
	# TODO: Test webserver, apachectl test, if its OK continue

        if [[ $PKG == "rpm" ]]; then
		if [[ $WEBSERVER == "apache" ]]; then
			install_package mod_security
		fi
		WEB_CONF_DIR=/etc/httpd/conf.d/
		
        elif [[ $PKG == "deb" ]]; then
		if [[ $WEBSERVER == "apache" ]]; then
			install_package libapache2-mod-security2
		fi
		WEB_CONF_DIR=/etc/apache2/conf-enabled/
        fi

	
	# el7
		# apache 2.4.6
			# mod_security.x86_64 2.9.2-1.el7
		# nginx 1.20.1
			# libmodsecurity.x86_64 3.0.2-6.el7, no configs
	# el8
		# apache 2.4.37
			# mod_security.x86_64 2.9.2-9.el8
		# module nginx, no libmodsecurity
		
	# el9
		# apache 2.4.51
			# mod_security 2.9.3-12

		# module nginx, no libmodsecurity

	# amzn2

		# apache 2.4.54
			# mod_security 2.9.3

		# nginx 1.20.0 - no modsecurity
			# Weird setup to get the repo too, it adds repos
			#amazon-linux-extras enable nginx1
			
	# u16
		# apache 2.4.18 
			# libapache2-mod-security2  2.9.0-1
		# nginx 1.10.3, no libmodsec

	# u18
		# apache 2.4.29
			# libapache2-mod-security2 2.9.2-1
		# nginx 1.14.0, no libmodsec

	# u20 
		# apache2-bin 2.4.41
			# libapache2-mod-security2 2.9.3
		# nginx 1.18.0
			# libmodsecurity 3.0.4-1, no configs

	# u22
		# apache 2.4.52
			# libapache2-mod-security2 2.9.5-1
		# nginx 1.18.0
			# libmodsecurity3 3.0.6-1 , no configs
}

# Create a restart_ossec function
function restart_ossec() {
	log_event "restart: ${PACKAGE} start"
	/var/ossec/bin/ossec-control reload
	log_event "restart: ${PACKAGE} end Exit Code: ($?)"
}


# Create restart_module function for  the values of clamav or ossec-hids
function restart_module() {
	MODULE=$1
	if [[ "${MODULE}" == "clamav" ]]; then
		log_event "restart: ${MODULE} start"
		restart_clamav
		log_event "restart: ${MODULE} end"
	elif [[ "${MODULE}" == "ossec-hids" ]]; then
		log_event "restart: ${MODULE} start"
		restart_ossec
		log_event "restart: ${MODULE} end"
	fi

}

# createa function that backs up ossec.conf to a random filename, changes <start-on-scan>yes</start-on-scan> to <start-on-scan>no</start-on-scan> in ossec.conf, and then restores it
function disable_ossec_on_scan() {
	log_event "disable: ${PACKAGE} start"
	# backup ossec.conf
	cp /var/ossec/etc/ossec.conf /var/ossec/etc/ossec.conf.$(date +%s)
	# change <start-on-scan>yes</start-on-scan> to <start-on-scan>no</start-on-scan>
	sed -i 's/<start-on-scan>yes<\/start-on-scan>/<start-on-scan>no<\/start-on-scan>/g' /var/ossec/etc/ossec.conf
	# restore ossec.conf
	cp /var/ossec/etc/ossec.conf.$(date +%s) /var/ossec/etc/ossec.conf
	log_event "disable: ${PACKAGE} end"
}


# Centos 7 hardening

# Create function to install fapolicyd
function install_fapolicyd() {
	log_event "install: ${PACKAGE} start"
	install_package fapolicyd
	log_event "install: ${PACKAGE} end"
}

# Create function to initalize fapolicyd
function init_fapolicyd() {
	log_event "init: ${PACKAGE} start"
	# Change /etc/fapolicyd/rules.d/90-deny-execute.rules deny_audit to deny_log
	sed -i 's/deny_audit/deny_log/g' /etc/fapolicyd/rules.d/90-deny-execute.rules
	# start fapolicyd
	systemctl start fapolicyd
	# enable fapolicyd
	systemctl enable fapolicyd
}


function show_help() {
	echo
	echo "Atomicorp-API Version: ${VERSION}"
	echo
	echo "Actions"
	echo "  install  - install module"
	echo "  upgrade  - upgrade module"
	echo "  init     - initialize module"
	echo "  restart  - restart module"
	echo
}


#############
# Main
#############
detect_dist

# Command line variables
ACTION=$1
shift
shift
ARGS="$@"

if [[ "$ARGS" == "install"* ]]; then

	PACKAGE=$(echo $ARGS | awk -F: '{print $2}' |awk '{print $1}')
	SCANID=$(echo $ARGS |awk -Fscanid: '{print $2}' |awk '{print $1}')

	#Allowed package list
	if [[ ${PACKAGE} =~ auditd* ]]; then
		log_event "install: ${PACKAGE} start"
		install_package auditd
	fi

	if [[ ${PACKAGE} =~ clamav ]]; then
		log_event "install: ${PACKAGE} start"
		install_clamav
	fi

	if [[ ${PACKAGE} =~ waf ]]; then
		log_event "install: ${PACKAGE} start"
		install_waf apache
	fi

	# if PACKAGE is fapolicyd, install fapolicyd
	if [[ ${PACKAGE} =~ fapolicyd ]]; then
		log_event "install: ${PACKAGE} start"
		install_fapolicyd
	fi

elif [[  "$ARGS" == "init"* ]]; then

	PACKAGE=$(echo $ARGS | awk -F: '{print $2}' |awk '{print $1}')
	MODULE=$(echo $ARGS | awk -F: '{print $2}' |awk '{print $1}')
	init_module ${MODULE} 

elif [[  "$ARGS" == "upgrade"* ]]; then
	PACKAGE=$(echo $ARGS | awk -F: '{print $2}' |awk '{print $1}')

	if [[ ${PACKAGE} =~ ossec-hids* ]]; then
        log_event "upgrade: ${PACKAGE} start"
        upgrade_package ossec-hids-agent awp-agent
        fi
	if [[ ${PACKAGE} =~ clamav* ]]; then
        log_event "upgrade: ${PACKAGE} start"
		update_clamav_signatures
	fi

# Restart module
elif [[  "$ARGS" == "restart"* ]]; then
	PACKAGE=$(echo $ARGS | awk -F: '{print $2}' |awk '{print $1}')
	if [[ ${PACKAGE} =~ ossec-hids* ]]; then
		log_event "restart: ${PACKAGE} start"
		restart_module ossec-hids-agent
	fi

fi

else
	show_help

fi
