#!/bin/bash
# OSSEC Agent installer
# Name: ossec-installer.sh
# Copyright Atomicorp 2025
# License: Commercial. Unauthorized redistribution prohibited.

###################
# Global variables
###################

ROOT_UID=0
USE_AWS=0
VERSION=8.4.1
ATOMICORP_GPG_LEGACY_BASENAME="RPM-GPG-KEY.atomicorp.txt"
ATOMICORP_GPG_MODERN_BASENAME="RPM-GPG-KEY.atomicorp.2026.txt"
ATOMICORP_ALPINE_RSA_BASENAME="atomicorp-alpine.rsa.pub"
AWS_IP="169.254.169.254"
O_CONF="/var/ossec/etc/ossec.conf"
LOG=/var/log/atomicorp.log
HTTP="http"
HTTP_ENROLL="false"
UPGRADE=0
EXCLUDE_CLAMAV=0
OSSEC_CONF_BACKUP=""



###################
# Functions
###################

function show_help() {

	echo
	echo "Atomicorp OSSEC Agent installer ($VERSION)"
	echo "Usage: $0 <server_ip>"
	echo "  example: $0 10.11.12.13"
	echo "  or"
	echo "  example: $0 --server 10.11.12.13"

	echo
	echo
	echo "options (deprecated):"
	echo "	<server_ip>	          IP of server hub"
	echo "	<auth_ip>	optional. IP of registration service. Default: <server_ip>"
	echo "	<protocol>	optional. Protocol tcp or udp"
	echo "	<port>		optional. Port for remoted"
	echo "	<group>		optional. Group to assign agent"
	echo
	echo "command line parameters:"
	echo "	--server <server_ip>       		IP/Hostname of the server hub"
	echo "	--auth <auth_ip>           		IP/Hostname of the registration service. Default: <server_ip>"
	echo "	--password <password>      		Registration authentication password"
	echo "	--port <port>              		Port for remoted"
	echo "	--protocol <tcp|udp>       		Protocol for remoted"
	echo
	echo "	--agent-name <name>        		Set agent name [Default: hostname]"
	echo "	--enable-unattended-upgrades		Enable unattended upgrade support (Debian/Ubuntu only)"
	echo "	--exclude-clamav			Exclude ClamAV packages"
	echo "	--default-name             		Prepend the external IP of the agent to agent name"
	echo "	--group  <groupname>       		Group to assign agent"
	echo "	--https                    		Use https for installation"
	echo "	--install-only             		Only install the agent, do not register"
	echo "	--proxy <disable|url>      		Proxy settings. Proxy URL, or disable proxy for this installation"
	echo "	--use-aws                  		Use the AWS instance ID for the agent name"
	echo "	--version                  		Show Version"
	echo "	--https-enrollment         		Register agent over HTTPS"
	echo "	--upgrade                  		Upgrade existing installation (preserve config/registration)"
	echo
	echo "environment variables"
	echo "	example: export SERVER_IP=10.11.12.13 $0"
	echo
	echo "	AUTH_IP  	IP of server registration service. "
	echo "	GROUP	  	Group to assign agent"
	echo "	PASSWORD  	Registration authentication password"
	echo "	PROTOCOL  	Protocol tcp or udp"
	echo "	PORT	  	Port for remoted"
	echo "	SERVER_IP  	IP of server hub"
	echo

}

# log and messaging facility
# If type is set to log, and DEBUG is true, then the message will be echoed to the console
# if type is log, only write to the log file
# if type is debug, only write to the console
show_msg() {
	msg=$1

	if [[ $2 == "log" ]]; then
		if [[ $DEBUG ]]; then
			echo "$(date) DEBUG: $msg"
		fi
		echo "$(date) $msg" >> $LOG
	elif [[ $2 == "error" ]]; then
		echo $msg
		echo "$(date) $msg" >> $LOG
	elif [[ $2 == "debug" ]]; then
		echo "$(date) DEBUG: $msg"
		echo "$(date) DEBUG: $msg" >> $LOG
	else 
		echo $msg
	fi
}

# Reject OpenCSW (/opt/csw) and Sun Freeware (/usr/sfw) — often broken (e.g. libssl).
is_legacy_tool_path() {
	case "$1" in
		/opt/csw/*|/usr/sfw/*|/opt/csw|/usr/sfw) return 0 ;;
		*) return 1 ;;
	esac
}

# Smoke-test that a downloader binary runs. Legacy paths always fail.
tool_is_healthy() {
	local bin="$1"
	local name

	[ -n "$bin" ] && [ -x "$bin" ] || return 1
	if is_legacy_tool_path "$bin"; then
		return 1
	fi

	name=${bin##*/}
	case "$name" in
		curl|curl.real)
			"$bin" --version >/dev/null 2>&1
			;;
		wget)
			"$bin" --version >/dev/null 2>&1 || "$bin" -V >/dev/null 2>&1
			;;
		*)
			return 0
			;;
	esac
}

# Resolve a healthy tool: prefer explicit candidates, then PATH — never CSW/SFW.
# Usage: find_healthy_tool <name> [absolute-path ...]
find_healthy_tool() {
	local name="$1"
	local candidate
	shift

	for candidate in "$@"; do
		if tool_is_healthy "$candidate"; then
			printf '%s\n' "$candidate"
			return 0
		fi
	done

	candidate=$(command -v "$name" 2>/dev/null) || candidate=""
	if [ -n "$candidate" ] && tool_is_healthy "$candidate"; then
		printf '%s\n' "$candidate"
		return 0
	fi
	return 1
}

function detect_downloader() {
	local curl_bin wget_bin

	# Prefer system/AWP curl; never broken /usr/sfw or /opt/csw wget
	curl_bin=$(find_healthy_tool curl \
		/usr/bin/curl \
		/bin/curl \
		/usr/local/bin/curl \
		/opt/freeware/bin/curl \
		/opt/atomicorp/bin/curl.real \
		/opt/atomicorp/bin/curl) || curl_bin=""
	wget_bin=$(find_healthy_tool wget \
		/usr/bin/wget \
		/bin/wget \
		/opt/freeware/bin/wget \
		/opt/atomicorp/bin/wget) || wget_bin=""

	if [ -n "$curl_bin" ]; then
		GET="$curl_bin -s -O"
		DOWNLOADER="$curl_bin"
	elif [ -n "$wget_bin" ]; then
		GET="$wget_bin -q"
		DOWNLOADER="$wget_bin"
	else
		show_msg "ERROR: downloader not detected (no healthy curl/wget; /usr/sfw and /opt/csw ignored). Exiting" error
		exit 1
	fi
	show_msg "GET=$GET" log
}

# Download URL into the current directory (remote basename), using detect_downloader().
download_url() {
	local url="$1"

	if [[ "$DOWNLOADER" == *curl* ]]; then
		"$DOWNLOADER" -fsSL -O "$url"
	elif [[ "$DOWNLOADER" == *wget* ]]; then
		"$DOWNLOADER" -q "$url"
	else
		show_msg "ERROR: Unsupported downloader: $DOWNLOADER" error
		return 1
	fi
}

# Backup/restore helpers for --upgrade (preserve registration and manager settings).
backup_ossec_conf() {
	OSSEC_CONF_BACKUP=""
	if [ -f "$O_CONF" ]; then
		OSSEC_CONF_BACKUP="${O_CONF}.backup-$(date +%Y%m%d%H%M%S)"
		cp "$O_CONF" "$OSSEC_CONF_BACKUP"
		show_msg "Backed up existing configuration to ${OSSEC_CONF_BACKUP}" log
	fi
}

restore_ossec_conf() {
	if [ -n "$OSSEC_CONF_BACKUP" ] && [ -f "$OSSEC_CONF_BACKUP" ]; then
		cp "$OSSEC_CONF_BACKUP" "$O_CONF"
		show_msg "Restored configuration from backup" log
	fi
}

restart_ossec_agent() {
	show_msg "Restarting OSSEC Agent after upgrade" log
	if command -v systemctl >/dev/null 2>&1; then
		systemctl restart ossec-agent >/dev/null 2>&1 \
			|| systemctl restart ossec-hids >/dev/null 2>&1 \
			|| true
	fi
	if [ -f /var/ossec/bin/ossec-control ]; then
		/var/ossec/bin/ossec-control restart
	elif command -v rc-service >/dev/null 2>&1; then
		rc-service ossec restart 2>/dev/null || true
	elif command -v service >/dev/null 2>&1; then
		service ossec-agent restart 2>/dev/null || service ossec-hids restart 2>/dev/null || service ossec restart 2>/dev/null || true
	fi
}

function request_agent_key() {

	server_ip="$1"
	show_msg "Requesting agent key from $server_ip using request_agent_key" log


	if [ -n "$AGENT_NAME" ]; then
	    local url="https://${server_ip}:${PORT}/agent_register/?key=none&hostname=${agent_name}"
	else
	    local url="https://${server_ip}:${PORT}/agent_register/?key=none&hostname=$(hostname)"
	fi

	export PATH=/opt/csw/bin:/opt/freeware/bin:$PATH
    	cmd="curl -k -o /var/ossec/etc/client.keys.tmp \"$url\""

	eval "$cmd"
	local status=$?


	if [[ $status -eq 0 ]]; then
       		echo "Request successful. Response saved to $output_file."
		awk -F\' '{print $2}' /var/ossec/etc/client.keys.tmp > /var/ossec/etc/client.keys
        	return 0
	else
        	echo "ERROR: Request failed with status code $status."
        	return 1
	fi
}


# Smoketests
function smoketest() {
    # Log and attempt to download diag.sh
    show_msg "Downloading diag.sh for smoketest..." log

    if [[ "$DOWNLOADER" == *curl* ]]; then
        $DOWNLOADER -f -o diag.sh ${HTTP}://${SERVER_IP}/tests/diag.sh 2>>$LOG
    elif [[ "$DOWNLOADER" == *wget* ]]; then
        $DOWNLOADER -O diag.sh ${HTTP}://${SERVER_IP}/tests/diag.sh 2>>$LOG
    else
        show_msg "ERROR: Unsupported downloader: $DOWNLOADER" error
        exit 1
    fi

    # Check if the download command was successful
    if [[ $? -ne 0 ]]; then
		echo
        show_msg "ERROR: Failed to download diag.sh($DOWNLOADER ${HTTP}://${SERVER_IP}/tests/diag.sh)" error
		echo -n "  "
		show_msg "NOTE: If this is a new installation of the hub server it may still be initializing its repositories" error
		echo
        exit 1
    fi

    # Ensure the file exists and is not empty
    if [[ ! -f diag.sh || ! -s diag.sh ]]; then
		echo
        show_msg "ERROR: The downloaded diag.sh file is missing or empty." error
		echo
        exit 1
    fi

    # Move and set executable permissions
    mv diag.sh /var/ossec/bin/
    if [[ $? -ne 0 ]]; then
		echo
        show_msg "ERROR: Failed to move diag.sh to /var/ossec/bin/" error
		echo
        exit 1
    fi

    chmod +x /var/ossec/bin/diag.sh
    if [[ $? -ne 0 ]]; then
		echo
        show_msg "ERROR: Failed to set executable permissions for /var/ossec/bin/diag.sh" error
		echo
        exit 1
    fi

    # Run the diagnostic script and log the output
    show_msg "Running diag.sh..." log
    /var/ossec/bin/diag.sh agent | tee -a $LOG

    # Check if diag.sh ran successfully
    if [[ $? -ne 0 ]]; then
        show_msg "ERROR: diag.sh execution failed." error
        exit 1
    fi

    show_msg "Smoketest completed successfully." log
}


function password_auth() {
	if [ -n "$PASSWORD" ]; then
		echo "$PASSWORD" > /var/ossec/etc/authd.pass
		chmod 640 /var/ossec/etc/authd.pass
		chown root.ossec /var/ossec/etc/authd.pass
		show_msg "Password added to /var/ossec/etc/authd.pass" log
	fi
}

# Hub check
function hub_check() {
    # List of packages to check
    packages=("awp-hub-utils" "ossec-hids-server")
    
    for pkg in "${packages[@]}"; do
        if rpm -q $pkg &> /dev/null; then
            show_msg "ERROR: Package $pkg is installed. Are you attempting agent installation on a hub? Exiting."
            exit 1
        fi
    done

}

app_error() {
	RETVAL=$1
	MSG=$2
	if [ $RETVAL -ne 0 ];then
		echo
		show_msg "  ERROR: $MSG ($RETVAL)" error
		echo
		exit 1
   	fi
}

app_error_authd() {
	RETVAL=$1
	MSG=$2
	if [ $RETVAL -ne 0 ];then
		echo
		show_msg "  ERROR: $MSG ($RETVAL)" error
		echo
		show_msg "###############################################" error
		show_msg "Running Diagnostics: " error
		show_msg "###############################################" error
		show_msg
		show_msg "  Testing agent-auth validity: " error
		/var/ossec/bin/agent-auth -h | tee -a $LOG
		if [ $? -eq 0 ]; then
			echo
			show_msg "  Testing agent-auth connectivity: " error
			/var/ossec/bin/agent-auth -m ${AUTH_IP} | tee -a $LOG
			echo
		fi
		echo

		if [ -f /usr/sbin/getenforce ]; then
			echo -n "  Getting SELinux state: "  | tee -a $LOG
			getenforce | tee -a $LOG
		fi
		if [ -f /usr/bin/audit2allow ] ; then
			echo
			echo -n "  Running audit2allow please be patient: "	| tee -a $LOG
			audit2allow -a > /root/audit2allow-ossec.log
			echo "done"| tee -a $LOG
			echo
			cat /root/audit2allow-ossec.log| tee -a $LOG
		fi
		echo

		exit 1
		
	fi
}

aws_register () {
  echo ""
  echo "inside aws_register function."
  echo
  #this is held over from the previous version. IF this command works then it finishes method one. OTherwise, attempt method 2.
  echo "Attempting to determine instance id using IMDSv1 method..."
  curl -fs ${HTTP}://$AWS_IP/latest/meta-data/instance-id
  ret=$?
  if [ "$ret" -ne 0 ]; then
		echo
		#method 2 needs a token to my knowledge, so it gets one and does this curl.
		show_msg " ERROR: Could not determine instance-id using IMDSv1 method. Attempting IMDSv2 method..." error
		TOKEN=curl -fs http://169.254.169.254/latest/api/token -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"
		instance_id=$(curl -fs http://169.254.169.254/latest/meta-data/instance-id -H "X-aws-ec2-metadata-token: $TOKEN")
		ret=$?
		#if method 2 fails, just exit.
		if [ "$ret" -ne 0 ]; then 
			echo 
			show_msg " ERROR: Could not determine instance-id using IMDSv2 method. Exiting..." error
			exit 1
		else 
			#method 2 success block, similar to method 1.
			echo
			echo "Success, authenticating..."
			echo
			#register agent
			if [ "$HTTP_ENROLL" = true ]; then

				/var/ossec/bin/agent-auth -m ${AUTH_IP} -A ${instance_id} -G ${GROUP} -H | tee -a $LOG
				app_error_authd ${PIPESTATUS[0]} "  aws_register: agent authorization failed"
			else
				# Commands if HTTP_ENROLL is not true
				/var/ossec/bin/agent-auth -m ${AUTH_IP} -A ${instance_id} -G ${GROUP} | tee -a $LOG
      			app_error_authd ${PIPESTATUS[0]} "  aws_register: agent authorization failed"
			fi
  	   		show_msg "AGENT_NAME=$instance_id" log
		fi
  else 
		#method 1 success block
		echo
		echo "Success, authenticating..."
		echo
		#Obtain Agent Name
		AGENT_NAME=$(curl -fs ${HTTP}://$AWS_IP/latest/meta-data/instance-id)

		#Register the Agent
		if [ "$HTTP_ENROLL" = true ]; then
				# Commands to execute if HTTP_ENROLL is true
				/var/ossec/bin/agent-auth -m ${AUTH_IP} -A ${AGENT_NAME} -G ${GROUP} -H | tee -a $LOG
       			app_error_authd ${PIPESTATUS[0]} "  aws_register: agent authorization failed"
		else
			# Commands if HTTP_ENROLL is not true
			/var/ossec/bin/agent-auth -m ${AUTH_IP} -A ${AGENT_NAME} -G ${GROUP} | tee -a $LOG
			app_error_authd ${PIPESTATUS[0]} "  aws_register: agent authorization failed"
		fi
  	   show_msg "AGENT_NAME=$AGENT_NAME" log
  fi
}


ossec_conf_update(){
	MSG="configuration failed for Hub server destination"
	# Test for ossec.conf server-ip
	if ! grep  ${SERVER_IP} $O_CONF >/dev/null; then
	    if grep address $O_CONF >/dev/null; then
		    $SED -i "s/<address>.*/<address>${SERVER_IP}<\/address>\n      <port>${PORT}<\/port>/g" $O_CONF
		    app_error ${PIPESTATUS[0]} $MSG
		    $SED -i "s/<protocol>.*/<protocol>${PROTOCOL}<\/protocol>/g" $O_CONF
		    app_error ${PIPESTATUS[0]} $MSG
		    $SED -i "s/<manager_address>.*/<manager_address>${AUTH_IP}<\/manager_address>/g" $O_CONF
		    app_error ${PIPESTATUS[0]} $MSG
	    # Legacy
	    elif grep server-ip $O_CONF >/dev/null; then
		    $SED -i "s/<server-ip>.*/<server><address>${SERVER_IP}<\/address><port>${PORT}<\/port><protocol>${PROTOCOL}<\/protocol><\/server>/g" $O_CONF
		    app_error ${PIPESTATUS[0]} $MSG
	    fi
	fi

	# if the AGENT_NAME is set, then update the agent_name value in the config or add it if it doesn't exist
	if [ -n "$AGENT_NAME" ]; then
		if grep "<agent_name>" $O_CONF >/dev/null; then
			$SED -i "s/<agent_name>.*/<agent_name>${AGENT_NAME}<\/agent_name>/g" $O_CONF
			app_error ${PIPESTATUS[0]} "  ossec_conf_update: agent_name update failed"
		else
			# Look for the <enrollment> line and add <agent_name> after it
			$SED -i "/<enrollment>/a      <agent_name>${AGENT_NAME}<\/agent_name>" $O_CONF 
			$SED -i "/<agent_name>/s/^/      /" $O_CONF
			app_error ${PIPESTATUS[0]} "  ossec_conf_update: agent_name add failed"
		fi
	else
		$SED -i "/<agent_name>/d" "$O_CONF"
		app_error ${PIPESTATUS[0]} "  ossec_conf_update: groups remove failed"
	fi

	if [ -n "$GROUP" ]; then
		if grep "<groups>" $O_CONF >/dev/null; then
			$SED -i "s/<groups>.*/<groups>${GROUP}<\/groups>/g" $O_CONF
			app_error ${PIPESTATUS[0]} "  ossec_conf_update: groups update failed"
		else
	        $SED -i "/<enrollment>/a      <groups>${GROUP}<\/groups>" "$O_CONF" 
			$SED -i "/<groups>/s/^/      /" "$O_CONF"
			app_error ${PIPESTATUS[0]} "  ossec_conf_update: groups add failed"
		fi
	else
		$SED -i "/<groups>/d" "$O_CONF"
		app_error ${PIPESTATUS[0]} "  ossec_conf_update: groups remove failed"
	fi

}

# Solaris 10 support
ossec_conf_update_legacy() {
    MSG="configuration failed for Hub server destination"

    # Write the ed commands to update <address> and <port> within <server>
    printf "/<server>/,/<\/server>/s|<address>.*</address>|<address>%s</address>|\n" "$SERVER_IP" > /tmp/ed_commands
    printf "/<server>/,/<\/server>/s|<port>.*</port>|<port>%s</port>|\n" "$PORT" >> /tmp/ed_commands
    printf "/<server>/,/<\/server>/s|<protocol>.*</protocol>|<protocol>%s</protocol>|\n" "$PROTOCOL" >> /tmp/ed_commands
    printf "w\nq\n" >> /tmp/ed_commands

    # Run ed with the generated commands
    ed -s "$O_CONF" < /tmp/ed_commands

    # Capture error status
    if [ $? -ne 0 ]; then
        echo "ERROR: $MSG"
        return 2
    fi

    # Cleanup
    rm -f /tmp/ed_commands
}




key_generate() {
	if [[ $NO_REGISTER -eq 1 ]]; then
		show_msg "Agent registration skipped" log
	else
  		password_auth
		# Add agent key
		if [ ! -s /var/ossec/etc/client.keys ]; then
			if [ "$USE_AWS" -eq 1 ]; then
				aws_register
			else
				if [ -z "$AGENT_NAME" ]; then
					if [ "$HTTP_ENROLL" = true ]; then
						#if [[ $PKG == "aix" || $PKG == "pkg" ]]; then
							request_agent_key ${AUTH_IP} 
						#else
						#	/var/ossec/bin/agent-auth -m ${AUTH_IP} -G ${GROUP} -I any -H |tee -a $LOG
						#fi
						app_error_authd ${PIPESTATUS[0]} "  key_generate: agent authorization failed"
					else
						/var/ossec/bin/agent-auth -m ${AUTH_IP} -G ${GROUP} -I any |tee -a $LOG
						app_error_authd ${PIPESTATUS[0]} "  key_generate: agent authorization failed"
					fi
				else
					if [ "$HTTP_ENROLL" = true ]; then
						#if [[ $PKG == "aix" || $PKG == "pkg" ]]; then
							request_agent_key ${AUTH_IP} 
						#else
						#	/var/ossec/bin/agent-auth -m ${AUTH_IP} -A ${AGENT_NAME} -G ${GROUP} -I any -H |tee -a $LOG
						#fi
						app_error_authd ${PIPESTATUS[0]} "  key_generate[named agent]: agent authorization failed"
					else
						/var/ossec/bin/agent-auth -m ${AUTH_IP} -A ${AGENT_NAME} -G ${GROUP} -I any |tee -a $LOG
						app_error_authd ${PIPESTATUS[0]} "  key_generate[named agent]: agent authorization failed"
					fi
				fi
			fi
			show_msg "Agent registered successfully" log
		else
			show_msg "Skipping, agent is already registered" log
		fi

		chown ossec:ossec /var/ossec/etc/client.keys
		chmod 640 /var/ossec/etc/client.keys
		chown root:ossec /var/ossec/etc
		chmod 770 /var/ossec/etc
	fi
}

yum_install () {
	# Download and import GPG key before creating repo
	if [ ! -d /etc/pki/rpm-gpg ]; then
		mkdir -p /etc/pki/rpm-gpg/
	fi
	
	if [ ! -f /etc/pki/rpm-gpg/${GPG_KEY_FILE} ]; then
		show_msg "Downloading GPG key: ${GPG_KEY_FILE}" log
		pushd /etc/pki/rpm-gpg/ >/dev/null
		$GET ${HTTP}://${SERVER_IP}/${GPG_KEY_FILE} >> $LOG 2>&1
		popd >/dev/null
		
		if [ -f /etc/pki/rpm-gpg/${GPG_KEY_FILE} ]; then
			rpm --import /etc/pki/rpm-gpg/${GPG_KEY_FILE}
			show_msg "Imported GPG key: ${GPG_KEY_FILE}" log
		fi
	fi
	
	# check for repo
	cat  << EOF > /etc/yum.repos.d/atomicorp-ossec.repo
[atomicorp-ossec]
baseurl = ${HTTP}://${SERVER_IP}/channels/awp-hub-repo/${DIR}/\$basearch
gpgcheck = 1
gpgkey = ${HTTP}://${SERVER_IP}/${GPG_KEY_FILE}
name = Atomicorp Workload Protection
sslverify = 0
EOF

	if [[ $UPGRADE -eq 1 ]]; then
		show_msg "Performing upgrade of existing installation..." log
		if ! rpm -q ossec-hids-agent >/dev/null; then
			show_msg "ERROR: No existing OSSEC installation found to upgrade" error
			exit 1
		fi
		backup_ossec_conf
		local upgrade_pkgs="ossec-hids-agent"
		rpm -q awp-agent >/dev/null 2>&1 && upgrade_pkgs="${upgrade_pkgs} awp-agent"
		if [[ $EXCLUDE_CLAMAV -ne 1 ]]; then
			rpm -q AWPclamav >/dev/null 2>&1 && upgrade_pkgs="${upgrade_pkgs} AWPclamav"
			# Upgrade stock ClamAV packages only when already installed from the hub/repo.
			for p in clamav clamav-server clamav-update clamav-filesystem; do
				rpm -q "$p" >/dev/null 2>&1 && upgrade_pkgs="${upgrade_pkgs} $p"
			done
		fi
		show_msg "Upgrading packages: ${upgrade_pkgs}" log
		yum -y upgrade ${upgrade_pkgs} | tee -a $LOG
		app_error ${PIPESTATUS[0]} "yum failed during upgrade"
		restore_ossec_conf
		restart_ossec_agent
		show_msg "Upgrade completed successfully" log
		return 0
	fi


	# Test for selinux policy
	# Remove the SELinux policy, this handles the condition if /var/ossec was rm -rf'd
	if [ ! -d /var/ossec ]; then
		if command -v getenforce > /dev/null 2>&1 && command -v semodule > /dev/null 2>&1; then
		  if [ $(getenforce) != "Disabled" ]; then
		    if (semodule -l | grep ossec_agent > /dev/null); then
		      semodule -X 200 -r ossec_agent > /dev/null || :
		    fi
		  fi
		fi
	fi


	# Test for agent install
	if ! rpm -q ossec-hids-agent >/dev/null; then
		# If CLAMAV_EXCLUDE is set, exclude clamav packages
		if [[ $EXCLUDE_CLAMAV -eq 1 ]]; then
			yum --exclude=clamav* -y install ossec-hids-agent /usr/bin/curl| tee -a $LOG
		else
			yum -y install ossec-hids-agent /usr/bin/curl| tee -a $LOG	
		fi
    		app_error ${PIPESTATUS[0]} "yum failed during installation"
	else
    		show_msg "OSSEC Agent install detected"
	fi


	if [  ! -d /var/ossec/ ]; then
	    	echo
	    	show_msg "  ERROR: /var/ossec not detected. Client installation failure?"
	    	echo "  exiting..."
		echo
	    	exit 1
	fi

	ossec_conf_update
	key_generate

	if [[ $NO_REGISTER -eq 1 ]]; then
    		show_msg "Installation only: skipping start"
	else
		show_msg "Restarting OSSEC Agent"
		echo
		/var/ossec/bin/ossec-control restart
	fi
}

zypper_install () {

    # Add keys (openSUSE repo uses legacy RPM repomd signing on hub)
    if [ ! -f "/etc/pki/rpm-gpg/${ATOMICORP_GPG_LEGACY_BASENAME}" ]; then
        if [ ! -d /etc/pki/rpm-gpg ]; then
                mkdir -p /etc/pki/rpm-gpg/
        fi
	pushd /etc/pki/rpm-gpg/ >/dev/null
        	$GET "${HTTP}://${SERVER_IP}/${ATOMICORP_GPG_LEGACY_BASENAME}" >> $LOG 2>&1
	popd >/dev/null

        rpm --import "/etc/pki/rpm-gpg/${ATOMICORP_GPG_LEGACY_BASENAME}"
    fi

    # Add repo (ignore if already present)
    zypper ar ${HTTP}://${SERVER_IP}/channels/awp-hub-repo/opensuse/15.6/x86_64/ atomic-ossec 2>/dev/null || true

    if [[ $UPGRADE -eq 1 ]]; then
        show_msg "Performing upgrade of existing installation..." log
        if ! rpm -q ossec-hids-agent >/dev/null; then
            show_msg "ERROR: No existing OSSEC installation found to upgrade" error
            exit 1
        fi
        backup_ossec_conf
        local upgrade_pkgs="ossec-hids-agent"
        rpm -q awp-agent >/dev/null 2>&1 && upgrade_pkgs="${upgrade_pkgs} awp-agent"
        if [[ $EXCLUDE_CLAMAV -ne 1 ]] && rpm -q clamav >/dev/null 2>&1; then
            upgrade_pkgs="${upgrade_pkgs} clamav"
        fi
        show_msg "Upgrading packages: ${upgrade_pkgs}" log
        /usr/bin/zypper --gpg-auto-import-keys -n update ${upgrade_pkgs}
        if [ $? -ne 0 ]; then
            app_error $? "ERROR: zypper upgrade failed"
        fi
        restore_ossec_conf
        restart_ossec_agent
        show_msg "Upgrade completed successfully" log
        return 0
    fi

    # Install the customer agent stack. openSUSE provides clamd, clamonacc,
    # freshclam, and clamscan together in the clamav package.
    local install_pkgs=(curl ossec-hids-agent awp-agent)
    if [[ $EXCLUDE_CLAMAV -ne 1 ]]; then
        install_pkgs+=(clamav)
    fi
    show_msg "Installing packages: ${install_pkgs[*]}" log
    /usr/bin/zypper --gpg-auto-import-keys -n install "${install_pkgs[@]}"
    if [ $? -ne 0 ]; then
	    app_error ${PIPESTATUS[0]} "ERROR: openSUSE agent installation failed"
    fi

    ossec_conf_update
    key_generate

    if [[ $NO_REGISTER -eq 1 ]]; then
   	show_msg "Installation only: skipping start"
    else
	# Start service (systemd unit is ossec-agent; fall back to ossec-control)
	if command -v systemctl >/dev/null 2>&1; then
		systemctl enable ossec-agent >/dev/null 2>&1 || :
		systemctl restart ossec-agent >/dev/null 2>&1 || /var/ossec/bin/ossec-control restart
	else
		/var/ossec/bin/ossec-control restart
	fi
    fi


}

# This function will enable unattended upgrades on an apt based system
# ex: enable_unattended_upgrades_for_repo "Atomicorp Agent Repository" "stable"
enable_unattended_upgrades_for_repo() {
    local origin="$1"
    local label="$2"
    local config_file="/etc/apt/apt.conf.d/99atomicorp-unattended-upgrades"

    # Ensure both origin and label are provided
    if [[ -z "$origin" || -z "$label" ]]; then
        echo "Usage: enable_unattended_upgrades_for_repo <origin> <label>"
        exit 1
    fi

    # Create or append to the custom configuration file
    echo "Unattended-Upgrade::Allowed-Origins {" > "$config_file" 
    echo "    \"${origin}:${label}\";" >> "$config_file" 
    echo "};" >> "$config_file" 

    echo "Custom unattended-upgrades configuration added for ${origin}:${label}"
}
apt_install () {


	if [ ! -f /usr/bin/gpg ]; then
	  	apt -y update | tee -a $LOG
		app_error ${PIPESTATUS[0]} "apt failed to update repodata"
	  	apt -y install gpg | tee -a $LOG
		app_error ${PIPESTATUS[0]} "apt failed to install gpg"
  	fi

  	if [ ! -f "${APT_GPG_KEY_FILE}" ]; then
    	$GET "${HTTP}://${SERVER_IP}/${APT_GPG_KEY_FILE}"
		if [ $? -ne 0 ]; then
			$GET "https://www.atomicorp.com/${APT_GPG_KEY_FILE}" | tee -a $LOG
		fi
  	fi


    	if [ -d /etc/apt/trusted.gpg.d ]; then
		if [ ! -f /etc/apt/trusted.gpg.d/atomic.gpg ]; then
       			gpg --dearmor "${APT_GPG_KEY_FILE}"
       			app_error ${PIPESTATUS[0]} "could not dearmor GPG key, Exiting...."
			mv "${APT_GPG_KEY_FILE}.gpg" /etc/apt/trusted.gpg.d/atomic.gpg
			chmod 644 /etc/apt/trusted.gpg.d/atomic.gpg
       			app_error ${PIPESTATUS[0]} "could not install GPG key, Exiting...."
		fi
    	else
		# Legacy system
		cat "${APT_GPG_KEY_FILE}" | apt-key add -
		app_error ${PIPESTATUS[0]} "could not install GPG key (Legacy), Exiting...."
    	fi



  	if [ -d /etc/apt/sources.list.d/ ]; then
   		APT_SOURCES="/etc/apt/sources.list.d/atomicorp-ossec.list"
   		echo -n "Adding [atomicorp-ossec] to $APT_SOURCES: " | tee -a $LOG
   		echo "deb [arch=${ARCH} signed-by=/etc/apt/trusted.gpg.d/atomic.gpg] ${HTTP}://${SERVER_IP}/channels/awp-hub-repo/${DIST} ${DIR} main" > $APT_SOURCES
   		echo "OK" | tee -a $LOG
  	else
   		APT_SOURCES="/etc/apt/sources.list"
   		echo -n "Adding [atomicorp-ossec] to $APT_SOURCES: " | tee -a $LOG
   		echo "deb [arch=${ARCH} signed-by=/etc/apt/trusted.gpg.d/atomic.gpg] ${HTTP}://${SERVER_IP}/channels/awp-hub-repo/${DIST} ${DIR} main" >> /etc/apt/sources.list
   		echo "OK" | tee -a $LOG
  	fi


  	echo
  	show_msg "Updating system ... "
  	apt -y update | tee -a $LOG

	if [[ $UPGRADE -eq 1 ]]; then
		show_msg "Performing upgrade of existing installation..." log
		if ! dpkg -l ossec-hids-agent 2>/dev/null | grep -q '^ii'; then
			show_msg "ERROR: No existing OSSEC installation found to upgrade" error
			exit 1
		fi
		backup_ossec_conf
		local upgrade_pkgs="ossec-hids-agent"
		dpkg -l awp-agent 2>/dev/null | grep -q '^ii' && upgrade_pkgs="${upgrade_pkgs} awp-agent"
		if [[ $EXCLUDE_CLAMAV -ne 1 ]]; then
			dpkg -l clamav 2>/dev/null | grep -q '^ii' && upgrade_pkgs="${upgrade_pkgs} clamav"
			dpkg -l clamav-daemon 2>/dev/null | grep -q '^ii' && upgrade_pkgs="${upgrade_pkgs} clamav-daemon"
		fi
		show_msg "Upgrading packages: ${upgrade_pkgs}" log
		DEBIAN_FRONTEND=noninteractive apt install \
			-o Dpkg::Options::="--force-confdef" \
			-o Dpkg::Options::="--force-confold" \
			-y ${upgrade_pkgs} | tee -a $LOG
		app_error ${PIPESTATUS[0]} "Apt failed during upgrade."
		restore_ossec_conf
		restart_ossec_agent
		show_msg "Upgrade completed successfully" log
		return 0
	fi

  	if ! apt list --installed | grep -q ossec-hids-agent ; then
		DEBIAN_FRONTEND=noninteractive  apt install -o  Dpkg::Options::="--force-confmiss" -y libcurl4 libcurl4-openssl-dev ossec-hids-agent | tee -a $LOG
		app_error ${PIPESTATUS[0]} "Apt failed during installation."
  	else
   		show_msg "OSSEC Agent already installed."
  	fi

  	if [ ! -d /var/ossec/ ]; then
		echo
		show_msg "ERROR: /var/ossec not detected. Agent installation failure?"
  	fi

	ossec_conf_update
	key_generate

	if [[ $NO_REGISTER -eq 1 ]]; then
    	show_msg "Installation only: skipping start"
	else
		service ossec-hids restart >/dev/null 2>&1
		if [ $? -ne 0 ]; then
		    if [ -f /var/ossec/bin/ossec-control ]; then
				show_msg "Restarting OSSEC Agent"
				echo
				/var/ossec/bin/ossec-control restart > /dev/null 2>&1
			else
				service ossec start
		    fi
		fi
	fi

	# Enable unattended upgrades for the Atomicorp repository
	if [[ "$UNATTENDED_UPGRADES" -eq 1 ]]; then
		enable_unattended_upgrades_for_repo "Atomicorp Agent Repository" "stable"
	fi

}

apk_install () {
	mkdir -p /etc/apk/keys

	if [ ! -f "/etc/apk/keys/${ATOMICORP_ALPINE_RSA_BASENAME}" ]; then
		show_msg "Downloading Alpine signing key: ${ATOMICORP_ALPINE_RSA_BASENAME}" log
		pushd /etc/apk/keys/ >/dev/null
		$GET "${HTTP}://${SERVER_IP}/${ATOMICORP_ALPINE_RSA_BASENAME}" >> "$LOG" 2>&1
		popd >/dev/null
		if [ ! -f "/etc/apk/keys/${ATOMICORP_ALPINE_RSA_BASENAME}" ]; then
			app_error 1 "could not download Alpine signing key, Exiting...."
		fi
		chmod 644 "/etc/apk/keys/${ATOMICORP_ALPINE_RSA_BASENAME}"
	fi

	REPO_LINE="${HTTP}://${SERVER_IP}/channels/awp-hub-repo/${DIR}"
	if ! grep -q '# atomicorp-ossec' /etc/apk/repositories 2>/dev/null; then
		{
			echo '# atomicorp-ossec'
			echo "$REPO_LINE"
		} >> /etc/apk/repositories
		show_msg "Added Atomicorp Alpine repository to /etc/apk/repositories" log
	elif ! grep -qF "$REPO_LINE" /etc/apk/repositories; then
		echo "$REPO_LINE" >> /etc/apk/repositories
	fi

	show_msg "Updating apk indexes ..." log
	apk update | tee -a "$LOG"
	app_error ${PIPESTATUS[0]} "apk update failed"

	if [[ $UPGRADE -eq 1 ]]; then
		show_msg "Performing upgrade of existing installation..." log
		if ! apk info -e ossec-hids-agent >/dev/null 2>&1; then
			show_msg "ERROR: No existing OSSEC installation found to upgrade" error
			exit 1
		fi
		backup_ossec_conf
		local upgrade_pkgs="ossec-hids-agent"
		apk info -e awp-agent >/dev/null 2>&1 && upgrade_pkgs="${upgrade_pkgs} awp-agent"
		show_msg "Upgrading packages: ${upgrade_pkgs}" log
		apk add -u ${upgrade_pkgs} | tee -a "$LOG"
		app_error ${PIPESTATUS[0]} "apk failed during upgrade"
		restore_ossec_conf
		restart_ossec_agent
		show_msg "Upgrade completed successfully" log
		return 0
	fi

	if ! apk info -e ossec-hids-agent >/dev/null 2>&1; then
		apk add ossec-hids-agent curl | tee -a "$LOG"
		app_error ${PIPESTATUS[0]} "apk failed during installation"
	else
		show_msg "OSSEC Agent already installed."
	fi

	if [ ! -d /var/ossec/ ]; then
		echo
		show_msg "  ERROR: /var/ossec not detected. Client installation failure?"
		echo "  exiting..."
		echo
		exit 1
	fi

	ossec_conf_update
	key_generate

	if [[ $NO_REGISTER -eq 1 ]]; then
		show_msg "Installation only: skipping start"
	else
		show_msg "Restarting OSSEC Agent"
		echo
		if command -v rc-service >/dev/null 2>&1; then
			rc-service ossec restart 2>/dev/null || /var/ossec/bin/ossec-control restart
		else
			/var/ossec/bin/ossec-control restart
		fi
	fi
}

function proxy_config() {
	if [[ $PROXY == "disable" ]]; then
		show_msg "  Proxy disabled" 
		unset http_proxy
		unset https_proxy
		if [[ "$PKG" = "deb" ]]; then
			show_msg "Bypassing proxy settings from apt in /etc/apt/apt.conf.d/atomcorp-proxy.conf" debug
 			echo "Acquire::http::Proxy {" > /etc/apt/apt.conf.d/atomcorp-proxy.conf
    		echo "   $SERVER_IP DIRECT;" >> /etc/apt/apt.conf.d/atomcorp-proxy.conf
    		echo "};" >> /etc/apt/apt.conf.d/atomcorp-proxy.conf
		elif [[ "$PKG" = "rpm" ]]; then
			show_msg "Removing proxy settings from /etc/yum.conf or /etc/dnf/dnf.conf" debug
			sed -i "/^proxy/d" "$(readlink -f /etc/yum.conf)"
		elif [[ "$PKG" = "apk" ]]; then
			show_msg "apk uses http_proxy/https_proxy environment variables" debug
		fi
	elif [[ $PROXY ]]; then
		# verify that $PROXY is a valid URL
		URL_PATTERN="^(http|https|ftp)://(([^:/?#]+)(:([^/?#]*))?@)?([^/?#]+)(/[^?#]*)?(\?([^#]*))?(#(.*))?$"
		if [[ $PROXY =~ $URL_PATTERN ]]; then
			show_msg "  Proxy URL: $PROXY " 
			if [[ "$PKG" = "deb" ]]; then
				echo "Acquire::http::Proxy {" > /etc/apt/apt.conf.d/atomcorp-proxy.conf
				echo "   $PROXY;" >> /etc/apt/apt.conf.d/atomcorp-proxy.conf
				echo "};" >> /etc/apt/apt.conf.d/atomcorp-proxy.conf
			elif [[ "$PKG" = "rpm" ]]; then
				if ! grep -q "proxy.*$PROXY" /etc/yum.conf; then
					echo "proxy=$PROXY" >> "$(readlink -f /etc/yum.conf)"
				fi
			elif [[ "$PKG" = "apk" ]]; then
				export http_proxy="$PROXY"
				export https_proxy="$PROXY"
			fi
		else
			show_msg "Proxy URL is invalid" 
			show_msg "Exiting" log
			exit 1
		fi
	fi
}

# Hub layout: channels/awp-hub-repo/solaris/{10,11}/<i86pc|sparc>/...
# SVR4 package filenames stay *.sol11.art.* on both trees (legacy naming).
solaris_set_release() {
    case "$(uname -r)" in
        5.10)
            SOLARIS_VER=10
            ;;
        5.11*)
            SOLARIS_VER=11
            ;;
        *)
            show_msg "ERROR: Unsupported Solaris kernel release '$(uname -r)'. Supported: 5.10 (Solaris 10) and 5.11 (Solaris 11)." error
            exit 1
            ;;
    esac
}

solaris_write_admin() {
    local conflict_policy="${1:-quit}"
    local idepend_policy="${2:-quit}"

    echo "instance=overwrite"> /var/tmp/admin.pkg
    echo "mail=" >> /var/tmp/admin.pkg
    echo "partial=quit">> /var/tmp/admin.pkg
    echo "runlevel=quit" >> /var/tmp/admin.pkg
    echo "idepend=${idepend_policy}" >> /var/tmp/admin.pkg
    echo "rdepend=quit" >> /var/tmp/admin.pkg
    echo "space=quit" >> /var/tmp/admin.pkg
    echo "setuid=nocheck">> /var/tmp/admin.pkg
    echo "conflict=${conflict_policy}" >> /var/tmp/admin.pkg
    echo "action=nocheck" >> /var/tmp/admin.pkg
}

# Download a hub SVR4 package and pkgadd it. Uses current admin.pkg policy.
solaris_download_and_pkgadd() {
    local pkg_file=$1
    local url="${HTTP}://${SERVER_IP}/channels/awp-hub-repo/${DIR}/${PKG_ARCH}/${pkg_file}"

    if [ -f "${pkg_file}" ]; then
        show_msg "Removing existing package file ${pkg_file}" log
        rm -f "${pkg_file}"
    fi

    show_msg "Attempting to download package from ${url}" log
    download_url "${url}"
    if [[ $? -ne 0 ]]; then
        show_msg "ERROR: Failed to download package from ${url}. Check if the URL is correct or if the server is reachable." error
        exit 1
    fi
    if [[ ! -f "${pkg_file}" || ! -s "${pkg_file}" ]]; then
        show_msg "ERROR: The downloaded file (${pkg_file}) is either missing or empty." error
        exit 1
    fi
    show_msg "Successfully downloaded ${pkg_file}" log

    show_msg "Installing the package ${pkg_file}" log
    echo all | pkgadd -n -a /var/tmp/admin.pkg -d ./${pkg_file}
    if [[ $? -ne 0 ]]; then
        show_msg "ERROR: Failed to install package ${pkg_file} using pkgadd." error
        exit 1
    fi
    show_msg "Package ${pkg_file} installed successfully." log
    rm -f ./${pkg_file}
}

solaris_install() {
    solaris_set_release
    show_msg "Solaris ${SOLARIS_VER}, hub path solaris/${SOLARIS_VER}/ (package names unchanged: sol11)" log

    CPU_ARCH=$(uname -p)
    if [ "$CPU_ARCH" = "i386" ]; then
        CPU_ARCH="i386"
        PKG_ARCH="i86pc"
    else
        CPU_ARCH="sparc"
        PKG_ARCH="sparc"
    fi
    solaris_write_admin quit

    # Full-stack overwrite upgrade (ossec + AWPclamav + awp-agent when present)
    if [[ $UPGRADE -eq 1 ]]; then
        show_msg "Performing upgrade of existing installation..." log

        if ! pkginfo | grep ossec-hids-agent >/dev/null; then
            show_msg "ERROR: No existing OSSEC installation found to upgrade" error
            exit 1
        fi

        backup_ossec_conf

        # Overlapping /var/ossec ownership between ossec-hids-agent and awp-agent
        solaris_write_admin nocheck

        if [[ $EXCLUDE_CLAMAV -ne 1 ]] && pkginfo AWPclamav >/dev/null 2>&1; then
            solaris_download_and_pkgadd "AWPclamav-latest.sol11.art.${PKG_ARCH}.pkg"
        fi

        solaris_download_and_pkgadd "ossec-hids-agent-latest.sol11.art.${PKG_ARCH}.pkg"

        if pkginfo awp-agent >/dev/null 2>&1; then
            # Hub packages may still declare retired OpenCSW depends until rebuilt
            solaris_write_admin nocheck nocheck
            solaris_download_and_pkgadd "awp-agent-latest.sol11.art.all.pkg"
        fi

        restore_ossec_conf
        restart_ossec_agent
        show_msg "Upgrade completed successfully" log
        return 0
    fi

    if pkginfo | grep ossec-hids-agent >/dev/null; then
        echo "OSSEC Agent is already installed..."
    else
        solaris_download_and_pkgadd "ossec-hids-agent-latest.sol11.art.${PKG_ARCH}.pkg"
        if [ ! -f /var/ossec/bin/ossec-agentd ]; then
            show_msg "ERROR: Failed to install ossec-hids-agent (ossec-agentd missing)." error
            exit 1
        fi
    fi

    if [[ $EXCLUDE_CLAMAV -ne 1 ]]; then
        if pkginfo AWPclamav >/dev/null 2>&1; then
            echo "AWPclamav is already installed..."
        else
            solaris_download_and_pkgadd "AWPclamav-latest.sol11.art.${PKG_ARCH}.pkg"
        fi
    fi

    if pkginfo | grep awp-agent >/dev/null || [ "${EXCLUDE_CLAMAV}" = "1" ]; then
        echo "AWP Agent API is already installed, or installation skipped..."
    else
        # Shared /var/ossec dirs + hub packages may still list retired OpenCSW depends
        solaris_write_admin nocheck nocheck
        solaris_download_and_pkgadd "awp-agent-latest.sol11.art.all.pkg"
    fi

    # Update ossec.conf (IP, protocol, group/agent name)
    show_msg "Updating OSSEC configuration file (${O_CONF})" log
    ossec_conf_update_legacy
    if [[ $? -ne 0 ]]; then
        show_msg "ERROR: Failed to update ossec.conf with the new settings." error
        exit 1
    fi
    show_msg "OSSEC configuration updated successfully." log

    # Register agent with agent-auth
    show_msg "Registering agent with agent-auth" log
    key_generate

    # Start the OSSEC agent
    show_msg "Starting OSSEC Agent" log
    /var/ossec/bin/ossec-control restart
    if [[ $? -ne 0 ]]; then
        show_msg "ERROR: Failed to start the OSSEC agent." error
        exit 1
    fi
    show_msg "OSSEC Agent started successfully." log
}



###################
# Main
###################

if [[ $1 == -* ]]; then
    while [ $# -gt 0 ]; do
        case "$1" in
            --server)
                shift
                SERVER_IP=$1
                ;;
            --authserver)
                shift
                AUTH_IP=$1
                ;;
            --enable-unattended-upgrades)
                UNATTENDED_UPGRADES=1
                show_msg "called --enable-unattended-upgrades" log
                ;;
            --password)
                shift
                PASSWORD=$1
                ;;
            --protocol)
                shift
                PROTOCOL=$1
                ;;
            --port)
                shift
                PORT=$1
                ;;
            --proxy)
                shift
                PROXY=$1
                ;;
            --agent-name)
                shift
                AGENT_NAME=$1
                ;;
            --exclude-clamav)
                EXCLUDE_CLAMAV=1
                show_msg "called --exclude-clamav" log
                ;;
            --group)
                shift
                GROUP=$1
                ;;
            --debug|-d)
                DEBUG=1
                ;;
            --https)
                HTTP="https"
                show_msg "called --use-https" log
                ;;
            --version|-v)
                echo "Atomic OSSEC Installer Version: ${VERSION}"
                exit
                ;;
            --help|-h)
                show_help
                exit 0
                ;;
            --https-enrollment)
                HTTP_ENROLL="true"
                show_msg "called --https-enrollment" log
                ;;
            --upgrade)
                UPGRADE=1
                show_msg "called --upgrade" log
                ;;
            *)
                echo "Unknown option: $1"
                ;;
        esac
        shift
    done
fi


# Legacy method
if [ ! ${SERVER_IP} ]; then
	echo "WARNING: Deprecated mode detected"
    SERVER_IP=$1
fi

if [ ! ${AUTH_IP} ]; then
    if [[ "$2" != *--* ]]; then
        AUTH_IP=$2
    fi
fi

if [ ! ${PROTOCOL} ]; then
        if [[ "$3" != *--* ]]; then
                PROTOCOL=$3
        fi
fi
if [ ! ${PORT} ]; then
        if [[ "$4" != *--* ]]; then
                PORT=$4
        fi
        if [ ! ${PORT} ]; then
                PORT=1514
        fi
fi

if [ ! ${GROUP} ]; then
        if [[ "$5" != *--* ]]; then
		GROUP=$5
	fi
fi


if [ ! ${SERVER_IP} ]; then
	show_help
	exit 1
fi

# Set defaults
if [ ! ${AUTH_IP} ]; then
	AUTH_IP=$SERVER_IP
fi

if [ ! ${PROTOCOL} ]; then
	PROTOCOL=udp
fi

if [ ! ${GROUP} ]; then
	GROUP=default
fi

if [ ! "$UID" ]; then
	UID=$(id -u)
fi

if [ "$UID" -ne "$ROOT_UID" ] ; then
	echo
	echo "  ERROR: You must be root to run this program."
	echo "  exiting..."
	echo
	exit 1
fi

echo
show_msg "Atomicorp OSSEC Agent installer ($VERSION)" 
show_msg "SERVER_IP=${SERVER_IP} AUTH_IP=${AUTH_IP} PROTOCOL=${PROTOCOL} GROUP=${GROUP}" log

if [[ $* == *--default-name* ]]; then
	#install dig
	externIP="$(dig +short myip.opendns.com @resolver1.opendns.com)"
	hostname="$(hostname)"
	AGENT_NAME=$externIP"-"$hostname
	show_msg "called --default-name" log
	show_msg "externIP=${externIP} hostname=${hostname} AGENT_NAME=${AGENT_NAME}" log
fi

if [[ $* == *--install-only ]]; then
	NO_REGISTER=1	
	show_msg "called --install-only" log
fi

if [[ $* == *--use-aws ]]; then
	USE_AWS=1
	show_msg "called --use-aws" log
fi



# Detect release/package type
PKG=rpm
SED=sed
AWK=awk
if [ -f /etc/redhat-release ]; then
        RELEASE=/etc/redhat-release
elif [ -f /etc/release ]; then
    	RELEASE=/etc/release
    	DIST="solaris"
    	PKG=pkg
	SED=sed
	AWK=awk
elif [[ $OSTYPE == "aix"* ]]; then
	PKG=aix
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
else
    echo "Error: unable to identify operating system"
    exit 1
fi

# Fallback for solaris
if [[ $(uname -s) == "SunOS" ]]; then
    	RELEASE=/etc/release
    	DIST="solaris"
    	PKG=pkg
	SED=sed
	AWK=awk
fi

# RPM yum/dnf: legacy for EL ≤9 and non-EL10; modern for EL10/Rocky 10 (matches hub repomd signing).
GPG_KEY_FILE="$ATOMICORP_GPG_LEGACY_BASENAME"
APT_GPG_KEY_FILE="$ATOMICORP_GPG_LEGACY_BASENAME"

if [[ $OSTYPE == "aix"* ]]; then
	PKG=aix
elif [[ $DIST == "solaris" ]]; then
	solaris_set_release
	DIR=solaris/${SOLARIS_VER}
	PKG=pkg
	ARCH=$(arch)
elif grep -E -q "(release 5)" $RELEASE ; then
	DIST="el5"
	DIR=centos/5
elif grep -E -q "(release 6|release 2012)" $RELEASE ; then
	DIST="el6"
	DIR=centos/6
elif grep -E -q "(release 7|release 2014)" $RELEASE ; then
	DIST="el7"
	DIR=centos/7
elif grep -E -q "(release 8)" $RELEASE ; then
	DIST="el8"
	DIR=centos/8
elif grep -E -q "(release 9)" $RELEASE ; then
    	DIST="el9"
    	DIR=centos/9
elif grep -E -q "(release 10)" $RELEASE ; then
    	DIST="el10"
    	DIR=rocky/10
    	GPG_KEY_FILE="$ATOMICORP_GPG_MODERN_BASENAME"
elif grep -E -q "Red Hat Enterprise Linux.* 7" $RELEASE ; then
	DIST="el7"
	DIR=redhat/7
elif grep -E -q "Red Hat Enterprise Linux.* 8" $RELEASE ; then
	DIST="el8"
	DIR=redhat/8
elif grep -E -q "(Amazon Linux 2023)" $RELEASE; then
	DIST="amazon"
	DIR=amazon/2023
elif grep -E -q "(Amazon Linux 2)" $RELEASE; then
	DIST="amazon"
	DIR=amazon/2
elif grep -E -q "(Amazon Linux AMI|Amazon)" $RELEASE ; then
	DIST="el6"
	DIR=centos/6
elif grep -E -q "wheezy" $RELEASE ; then
	DIST="debian"
	DIR="wheezy"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "jessie" $RELEASE ; then
	DIST="debian"
	DIR="jessie"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "stretch" $RELEASE ; then
	DIST="debian"
	DIR="stretch"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "lucid" $RELEASE ; then
	DIST="debian"
	DIR="lucid"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "precise" $RELEASE ; then
	DIST="debian"
	DIR="precise"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "Raring Ringtail" $RELEASE ; then
	DIST="debian"
	DIR="raring"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "Trusty Tahr" $RELEASE ; then
	DIST="ubuntu"
	DIR="trusty"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "Xenial" $RELEASE ; then
	DIST="ubuntu"
	DIR="xenial"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "Bionic" $RELEASE ; then
	DIST="ubuntu"
	DIR="bionic"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "Focal Fossa" $RELEASE; then 
	DIST="ubuntu"
	DIR="focal"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "Jammy Jellyfish" $RELEASE; then 
	DIST="ubuntu"
	DIR="jammy"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "Noble Numbat" $RELEASE; then 
	DIST="ubuntu"
	DIR="noble"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "Resolute" $RELEASE; then
	DIST="ubuntu"
	DIR="resolute"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "buster" $RELEASE ; then
	DIST="debian"
	DIR="buster"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "bullseye" $RELEASE ; then
	DIST="debian"
	DIR="bullseye"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "bookworm" $RELEASE ; then
	DIST="debian"
	DIR="bookworm"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "trixie" $RELEASE ; then
	DIST="debian"
	DIR="trixie"
	PKG=deb
	ARCH=$(dpkg --print-architecture)
elif grep -E -q "SUSE Linux Enterprise Server 12" $RELEASE; then
	echo "Error: SLES 12 is no longer supported. Use SLES 15 / openSUSE Leap 15.x."
	exit 1
elif grep -E -qi 'SUSE Linux Enterprise Server 15|^ID=.sles.|^ID="sles"' $RELEASE; then
	DIST="suse15"
	DIR="opensuse/15.6"
	PKG=zypper
elif grep -E -qi 'openSUSE Leap|^ID=.opensuse-leap.|^ID="opensuse-leap"' $RELEASE; then
	DIST="suse15"
	DIR="opensuse/15.6"
	PKG=zypper
elif grep -E -q '^ID=alpine' "$RELEASE" || grep -E -q '^ID_LIKE=.*alpine' "$RELEASE"; then
	DIST="alpine"
	PKG=apk
	ALPINE_VER=$(grep -E '^VERSION_ID=' "$RELEASE" | cut -d= -f2 | tr -d '"' | cut -d. -f1,2)
	if [ "$ALPINE_VER" != "3.23" ]; then
		echo "Error: Unsupported Alpine version ${ALPINE_VER}. Supported: 3.23"
		exit 1
	fi
	DIR="alpine/${ALPINE_VER}"
	ARCH=$(uname -m)
else
	echo "Error: Unable to determine distribution type. Please send the contents of $RELEASE to support@atomicorp.com"
	exit 1
fi

# Debian trixie and Ubuntu resolute hub Release is signed with modern key (RPM-GPG-KEY.atomicorp.2026.txt).
if [ "$PKG" = "deb" ] && { [ "$DIR" = "trixie" ] || [ "$DIR" = "resolute" ]; }; then
	APT_GPG_KEY_FILE="$ATOMICORP_GPG_MODERN_BASENAME"
fi

show_msg "RELEASE=$RELEASE DIST=$DIST DIR=$DIR PKG=$PKG ARCH=${ARCH:-n/a} GPG_KEY_FILE=${GPG_KEY_FILE:-n/a} APT_GPG_KEY_FILE=${APT_GPG_KEY_FILE:-n/a} ALPINE_VER=${ALPINE_VER:-n/a}" log

echo
proxy_config
detect_downloader

if [ "$PKG" == "rpm" ]; then
	# Only run hubcheck for RPM based systems
	hub_check
    	yum_install
	if [[ $NO_REGISTER -eq 1 ]] || [[ $UPGRADE -eq 1 ]]; then
  		show_msg "Installation only: skipping smoketest"
	else
		smoketest
	fi
elif [ "$PKG" == "deb" ]; then
    apt_install
    if [[ $NO_REGISTER -eq 1 ]] || [[ $UPGRADE -eq 1 ]]; then
        show_msg "Installation only: skipping smoketest"
    else
        smoketest
    fi
elif [ "$PKG" == "zypper" ]; then
    zypper_install
    if [[ $NO_REGISTER -eq 1 ]] || [[ $UPGRADE -eq 1 ]]; then
        show_msg "Installation only: skipping smoketest"
    else
        smoketest
    fi
elif [ "$PKG" == "apk" ]; then
    apk_install
    if [[ $NO_REGISTER -eq 1 ]] || [[ $UPGRADE -eq 1 ]]; then
        show_msg "Installation only: skipping smoketest"
    else
        smoketest
    fi
elif [ "$PKG" == "pkg" ]; then
	solaris_install
elif [[ $PKG == "aix" ]]; then
  export PATH=$PATH:/opt/freeware/bin
  # Is RPM available
  if ! which rpm >/dev/null; then
    echo
    echo "Error: RPM not found. Exiting.... "
    exit 1
  fi

  # Is yum/dnf available
  if command -v dnf >/dev/null 2>&1; then
       PKG_MANAGER=dnf
  elif command -v yum >/dev/null 2>&1; then
       PKG_MANAGER=yum
  else
    echo
    echo "Error: dnf/yum not found. Exiting.... "
    exit 1
  fi

  # Check for repo, and add
  if [ ! -d /opt/freeware/etc/yum.repos.d/ ]; then
    echo "Error: Yum repos.d could not be found. Exiting.... "
    exit 1
  fi

  REPOPATH=/opt/freeware/etc/yum.repos.d/


  if [ ! -f  ${REPOPATH}/atomicorp-ossec.repo ]; then
  	cat  << EOF > ${REPOPATH}/atomicorp-ossec.repo
[atomicorp-ossec]
baseurl = ${HTTP}://${SERVER_IP}/channels/awp-hub-repo/aix/7/ppc/
gpgcheck = 0
gpgkey = ${HTTP}://${SERVER_IP}/${ATOMICORP_GPG_LEGACY_BASENAME}
name = Atomicorp OSSEC HIDS repo
sslverify = 0
EOF
  fi

  O_CONF="/var/ossec/etc/ossec-agent.conf"

  if [[ $UPGRADE -eq 1 ]]; then
    show_msg "Performing upgrade of existing installation..." log
    if ! rpm -q ossec-hids-agent >/dev/null; then
      show_msg "ERROR: No existing OSSEC installation found to upgrade" error
      exit 1
    fi
    backup_ossec_conf
    upgrade_pkgs="ossec-hids-agent"
    rpm -q awp-agent >/dev/null 2>&1 && upgrade_pkgs="${upgrade_pkgs} awp-agent"
    if [[ $EXCLUDE_CLAMAV -ne 1 ]] && rpm -q AWPclamav >/dev/null 2>&1; then
      upgrade_pkgs="${upgrade_pkgs} AWPclamav"
    fi
    show_msg "Upgrading packages: ${upgrade_pkgs}" log
    $PKG_MANAGER -y upgrade ${upgrade_pkgs}
    if [ $? -ne 0 ]; then
      echo "ERROR: $PKG_MANAGER failed during upgrade"
      exit 1
    fi
    restore_ossec_conf
    restart_ossec_agent
    show_msg "Upgrade completed successfully" log
  else

  # Test for agent install
  if ! rpm -q ossec-hids-agent >/dev/null; then
    # If CLAMAV_EXCLUDE is set, exclude clamav packages
	if [[ $EXCLUDE_CLAMAV -eq 1 ]]; then
		$PKG_MANAGER -y install ossec-hids-agent
	else
		$PKG_MANAGER -y install ossec-hids-agent AWPclamav awp-agent
	fi
    if [ $? -ne 0 ];then
      echo "ERROR: $PKG_MANAGER failed during installation"
      exit 1
    fi
  else
      echo
      echo "OSSEC Agent install detected"
      echo
  fi
  if [  ! -d /var/ossec/ ]; then
      echo
      echo "  ERROR: /var/ossec not detected. Client installation failure?"
      echo "  exiting..."
      echo
      exit 1
  fi


  password_auth
  # register with server
  if [ !  -f /var/ossec/etc/client.keys ]; then
	if [ "$HTTP_ENROLL" = true ]; then
		# if the platform is AIX or Solaris, use request_agent_key
		#if [[ $PKG == "aix" || $PKG == "pkg" ]]; then
			request_agent_key ${AUTH_IP} 
		#else
		#	/var/ossec/bin/agent-auth  -m ${AUTH_IP} -G ${GROUP} -H
		#fi
	else
		/var/ossec/bin/agent-auth  -m ${AUTH_IP} -G ${GROUP}
	fi

    if [ $? -ne 0 ]; then
      echo
      echo "  ERROR: agent-auth failed during registration"
      echo "  exiting..."
      exit 1
    fi
  fi

  # Update config
  if [ ! -f /opt/freeware/bin/sed ]; then
  	$PKG_MANAGER -y install sed
  fi
  export PATH=/opt/freeware/bin:$PATH
  ossec_conf_update

  # start service
  show_msg "Restarting OSSEC Agent"
  echo
  /var/ossec/bin/ossec-control restart

  # Add to startup
  fi
fi

show_msg "Installation Complete  . . . "
echo
